home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d172 / spiff.lha / Spiff / spiff.c < prev    next >
C/C++ Source or Header  |  1988-11-22  |  7KB  |  343 lines

  1. /*                        Copyright (c) 1988 Bellcore
  2. **                            All Rights Reserved
  3. **       Permission is granted to copy or use this program, EXCEPT that it
  4. **       may not be sold for profit, the copyright notice must be reproduced
  5. **       on copies, and credit should be given to Bellcore where it is due.
  6. **       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7. */
  8.  
  9.  
  10. #ifndef lint
  11. static char rcsid[]= "$Header: spiff.c,v 1.1 88/09/15 11:33:51 daniel Rel $";
  12. #endif
  13.  
  14.  
  15. #include <stdio.h>
  16. #include "misc.h"
  17. #include "flagdefs.h"
  18. #include "parse.h"
  19. #include "edit.h"
  20. #include "line.h"
  21. #include "token.h"
  22. #include "tol.h"
  23. #include "command.h"
  24. #include "compare.h"
  25. #include "exact.h"
  26. #include "miller.h"
  27. #include "visual.h"
  28. #include "output.h"
  29.  
  30. extern void _Y_doargs();
  31.  
  32. static int _Y_eflag = 0;    /* use exact match algorithm */
  33. static int _Y_vflag = 0;    /* use visual mode */
  34.  
  35. /*
  36. **    this is the set of flags that gets used throughout the top module
  37. **    as well as being used to communicate between modules.
  38. */
  39. static int _Y_flags;
  40.  
  41. main(argc,argv)
  42. int argc;
  43. char *argv[];
  44. {
  45.     E_edit edit_end;
  46.     char *filename[2];
  47.  
  48.     int max_d;     /* max number of differences allowed */
  49.     int i;        /* loop counter */
  50.  
  51.     /*
  52.     **    parse the command line
  53.     */
  54.     _Y_doargs(argc,argv,&(filename[0]),&(filename[1]),&max_d);
  55.  
  56.     /*
  57.     **    initialize the default tolerance if it
  58.     **        hasn't been set already.
  59.     */
  60.     T_initdefault();
  61.  
  62.     /*
  63.     **    read and then parse the files
  64.     */
  65.  
  66.     /*
  67.     **    L_initfile return a code that indicates if the
  68.     **    entire file was read or not
  69.     **
  70.     **    P_fileparse also knows how to start at someplace other
  71.     **        than the first line of file
  72.     **
  73.     **    Taken together, this is enough to do step our way
  74.     **        through the file using an exact match algorithm.
  75.     **
  76.     **    Oh well, someday . . .
  77.     */
  78.     for(i=0;i<=1;i++)
  79.     {
  80.         /*
  81.         **    read the file into core
  82.         */
  83.         (void) L_init_file(i,filename[i]);
  84.         K_settmax(i,0);        /* start tokens at 0 */
  85.         /*
  86.         **    and parse the files into tokens
  87.         */
  88.         P_file_parse(i,0,L_getrlmax(i),_Y_flags);
  89.     }
  90.  
  91.     if (_Y_vflag)
  92.     {
  93.         return(V_visual(_Y_flags));
  94.     }
  95.  
  96.     /*
  97.     **    if max_d was not set on the command line
  98.     **        set it to be as large as is possible
  99.     **        since the most changes possible would
  100.     **        be to delete all the tokens in the
  101.     **        first file and add all the tokens from
  102.     **        the second, the max possible is the
  103.     **        sum of the number of tokens in the
  104.     **        two files.
  105.     */
  106.     if (-1 == max_d)
  107.         max_d = K_gettmax(0) + K_gettmax(1);
  108.  
  109.     if (_Y_eflag)
  110.     {
  111.         edit_end = Q_do_exact(K_gettmax(0),K_gettmax(1),
  112.                     max_d,_Y_flags);
  113.     }
  114.     else
  115.     {
  116.         edit_end = G_do_miller(K_gettmax(0), K_gettmax(1),
  117.                      max_d,_Y_flags);
  118.     }
  119.  
  120.     if (E_NULL != edit_end)
  121.     {
  122.         O_output(edit_end,_Y_flags);
  123.         return(1);
  124.     }
  125.     return(0);
  126. }
  127.  
  128. /*
  129. **    break a string into individual lines and feed
  130. **        them to the command module
  131. */
  132. static void
  133. _Y_cmdlines(from)
  134. char *from;
  135. {
  136.     char buf[Z_LINELEN]; 
  137.     char *to;
  138.     while ('\0' != *from)
  139.     {
  140.         /*
  141.         **    copy line into buf
  142.         */
  143.         to = buf;
  144.         while (('\0' != *from) && ('\n' != *from))
  145.         {
  146.             *to++ = *from++;
  147.         }
  148.         *to = '\0';    /* terminate the line */
  149.  
  150.         /*
  151.         **    hand the line to the command module
  152.         */
  153.         C_addcmd(buf);
  154.         /*
  155.         **    skip the newline
  156.         */
  157.         if ('\n' == *from)
  158.         {
  159.             from++;
  160.         }
  161.     }
  162. }
  163.  
  164. /*
  165. **    this useful macro handle arguements that are adjacent
  166. **    to a flag or in the following word e.g --
  167. **
  168. **        -a XXX 
  169. **    and
  170. **        -aXXX 
  171. **
  172. **    both work when SETPTR is used. 
  173. */
  174. #define SETPTR    {if(strlen(argv[1]) == 2) {argv++;argc--;ptr=argv[1];}else ptr=(&argv[1][2]);}
  175.  
  176. static void
  177. _Y_doargs(argc,argv,file1,file2,max_d)
  178. int argc;
  179. char *argv[];
  180. char **file1,**file2;
  181. int *max_d;
  182. {
  183.     char *ptr;
  184.     extern char *fgets ();
  185.  
  186.     /*
  187.     **    mark maximum number of tokens as being unset
  188.     */
  189.     *max_d = -1;
  190.  
  191.     while (argc > 1 && argv[1][0] == '-')
  192.     {
  193.         switch (argv[1][1])
  194.         {
  195.             case 't':
  196.                 _Y_flags |= U_TOKENS;
  197.                 break;
  198.             case 'w':
  199.                 _Y_flags |= U_INCLUDE_WS;
  200.                 break;
  201.  
  202.             case 'b':
  203.                 _Y_flags |= U_BYTE_COMPARE;
  204.                 break;
  205.  
  206.             case 'c':
  207.                 _Y_flags |= U_NO_CASE;
  208.                 break;
  209.             case 'd' :
  210.                 _Y_flags |= U_NEED_DECIMAL;
  211.                 break;
  212.             case 'm' :
  213.                 _Y_flags |= U_INC_SIGN;
  214.                 break;
  215.             case 'a':
  216.                 SETPTR;
  217.                 T_defatol(ptr);
  218.                 break;
  219.             case 'r':
  220.                 SETPTR;
  221.                 T_defrtol(ptr);
  222.                 break;
  223.             case 'i':
  224.                 T_defitol();
  225.                 break;
  226.             case 'e' :
  227.                 _Y_eflag = 1;
  228.                 break;
  229.             case 'v' :
  230.                 _Y_vflag = 1;
  231.                 break;
  232.             case 'q' :
  233.                 Z_setquiet();
  234.                 break;
  235.             case 's' :
  236.                 SETPTR;
  237.                 _Y_cmdlines(ptr);
  238.                 break;
  239.             case 'f' :
  240.             {
  241.                 extern FILE *fopen();
  242.                 char buf[Z_LINELEN];
  243.                 FILE *cmdfile;
  244.                 SETPTR;
  245.                 if ((FILE*) NULL ==
  246.                     (cmdfile = fopen(ptr,"r")))
  247.                 {
  248.                     Z_fatal("can't open command file\n");
  249.                 }
  250.                 while ((char*) NULL !=
  251.                     (char*) fgets(buf,Z_LINELEN,cmdfile))
  252.                 {
  253.                     C_addcmd(buf);
  254.                 }
  255.                 (void) fclose(cmdfile);
  256.                 break;
  257.             }
  258.             /*
  259.             **    useful commands for
  260.             **     the C programming language
  261.             */
  262.             case 'C' :
  263.                 C_addcmd("literal  \"   \"    \\ ");
  264.                 C_addcmd("comment  /*  */     ");
  265.                 C_addcmd("literal  &&         ");
  266.                 C_addcmd("literal  ||         ");
  267.                 C_addcmd("literal  <=         ");
  268.                 C_addcmd("literal  >=         ");
  269.                 C_addcmd("literal  !=         ");
  270.                 C_addcmd("literal  ==         ");
  271.                 C_addcmd("literal  --         ");
  272.                 C_addcmd("literal  ++         ");
  273.                 C_addcmd("literal  <<         ");
  274.                 C_addcmd("literal  >>         ");
  275.                 C_addcmd("literal  ->         ");
  276.                 C_addcmd("addalpha _         ");
  277.                 C_addcmd("tol      a0          ");
  278.                 break;
  279.             /*
  280.             **    useful commands for
  281.             **     the Bourne shell programming language
  282.             */
  283.             case 'S' :
  284.                 C_addcmd("literal  '    '    \\    ");
  285.                 C_addcmd("comment  #    $    ");
  286.                 C_addcmd("tol      a0         ");
  287.                 break;
  288.             /*
  289.             **    useful commands for
  290.             **     the Fortran programming language
  291.             */
  292.             case 'F' :
  293.                 C_addcmd("literal  '    '     ' ");
  294.                 C_addcmd("comment  ^C   $    ");
  295.                 C_addcmd("tol      a0         ");
  296.                 break;
  297.             /*
  298.             **    useful commands for
  299.             **     the Lisp programming language
  300.             */
  301.             case 'L' :
  302.                 C_addcmd("literal  \"     \"    ");
  303.                 C_addcmd("comment  ;     $    ");
  304.                 C_addcmd("tol      a0         ");
  305.                 break;
  306.             /*
  307.             **    useful commands for
  308.             **     the Modula-2 programming language
  309.             */
  310.             case 'M' :
  311.                 C_addcmd("literal '     '    ");
  312.                 C_addcmd("literal \"    \"    ");
  313.                 C_addcmd("comment (*    *)    ");
  314.                 C_addcmd("literal :=        ");
  315.                 C_addcmd("literal <>        ");
  316.                 C_addcmd("literal <=        ");
  317.                 C_addcmd("literal >=        ");
  318.                 C_addcmd("tol      a0         ");
  319.                 break;
  320.             case '0':
  321.             case '1':
  322.             case '2':
  323.             case '3':
  324.             case '4':
  325.             case '5':
  326.             case '6':
  327.             case '7':
  328.             case '8':
  329.             case '9':
  330.                 *max_d = atoi(&argv[1][1]);
  331.                 break;
  332.             default:
  333.                 Z_fatal("don't understand arguments\n");
  334.         }
  335.         ++argv;
  336.         --argc;
  337.     }
  338.     if (argc != 3)
  339.         Z_fatal ("spiff requires two file names.\n");
  340.     *file1 = argv[1];
  341.     *file2 = argv[2];
  342. }
  343.