home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 329_01 / cs_main.c < prev    next >
C/C++ Source or Header  |  1990-11-29  |  8KB  |  300 lines

  1. /* cs_main.c */
  2. /*************************************************************************
  3. This programme is shareware.
  4. If you found this programme useful then send me a colourful postcard
  5. with the words "Happy Birthday" (or equivalent) so that it arrives
  6. at my address around the first of January 1991. After that there
  7. is no restriction.
  8.  
  9. Henri de Feraudy
  10. 27 rue Chef de Ville
  11. 92140 Clamart 
  12. France
  13. **************************************************************************/
  14. /*************************************************************************
  15.  22/10/90, changed file names
  16.  22/10/90, bug fix: added rule to deal with hexa numbers in csubst.l -HdeF
  17.  22/10/90, added types to symbols with corresponding effect on csubst.l
  18.     and sorting and printing -HdeF
  19.  22/10/90  added the truncated output feature -HdeF
  20.  23/10/90 bugfix in output of extracted names if no macros defined -HdeF
  21.  29/10/90 bugfix in read_comment for comments with odd number of stars
  22.  10/11/90 bugfix in sort_and_print concerning p_next_symbol
  23.  29/11/90 removed unnecessary redefinition of NULL in csubst.h
  24. **************************************************************************/
  25. #include <stdio.h>
  26. #include <assert.h>
  27. #include "csubst.h"
  28.  
  29. extern void fatal(), fatal1(), trunc_error();
  30. extern FILE *yyin;/* this is defined in the lex-generated file */
  31.  
  32. int Mode;        /* indicates what feature is being used */
  33. static char *Workfile = NULL; /* this is for a file of filenames */
  34. static char *Ignore_file = NULL; /* file of identifiers to ignore */
  35. static FILE *Wfp = NULL;      /* this is the workfile pointer */
  36. int Truncation = 0;        /* this says how much of 
  37.                    identifiers we 
  38.                    truncate in output
  39.                  */
  40. /* 
  41.    The following are used to communicate argc,argv and an index
  42.    to the function next_yyin() which is needed by   yylex()
  43.  */
  44. static int Arg_index, Arg_count;
  45. static char **ArgV;
  46.  
  47. void main(argc, argv)
  48. int argc;
  49. char *argv[];
  50. {
  51.     extern FILE *try_r_open();
  52.     int i;
  53.     char *subst_filename = NULL;
  54.     if(argc == 1)
  55.     {
  56.     puts("Usage :\ncsubst subst_file source_files ... (applies substitutions)");
  57.     puts("or csubst substfile -F workfile (contains filenames)");
  58.     puts("or csubst -S subst_file source_files.");
  59.     puts("or csubst -X source_files (extracts names and strings)");
  60.     puts("or csubst -F workfile -X (extracts names and strings)");
  61.     puts("(In substitution mode all is sent to stdout.)");
  62.     puts("or csubst -nTruncation -Mignore_file source_file");
  63.     puts("  -in this mode all is sent to stdout, identifiers are truncated.");
  64.     exit(1);
  65.     }
  66.  
  67.     Mode = READ_SUBSTS; /* default mode */
  68.  
  69. /*  First, a loop that looks for options */
  70.     for(i = 1; i < argc; i++)
  71.     {
  72.     if(*argv[i] == '-')
  73.     {
  74.         switch(argv[i][1])
  75.         {
  76.         case 'n': /* use next argument as Truncation for printing */
  77.         Mode = PRINT_TRUNCATED;
  78.         if(argv[i][2])/* argument is right next to option, no space */
  79.         {
  80.             if(EOF == sscanf(&argv[i][2], "%d", &Truncation))
  81.             trunc_error();
  82.             if(!Truncation)
  83.             trunc_error();
  84.             break;
  85.         }
  86.         i++;
  87.         if(i == argc)
  88.             fatal("missing truncation parametrer");
  89.         else
  90.             if(EOF == sscanf(argv[i], "%d", &Truncation))
  91.             trunc_error();
  92.             if(!Truncation)
  93.             trunc_error();
  94.         break;
  95.  
  96.         case 'M': /* use next argument as file of names not to be truncated */
  97.         case 'm':
  98.         Mode = READ_IGNORES;
  99.         if(argv[i][2])/* argument is right next to option, no space */
  100.         {
  101.             Ignore_file = &argv[i][2];
  102.             break;
  103.         }
  104.         i++;
  105.         if(i == argc)
  106.             fatal("missing Ignore_file");
  107.         else
  108.             Ignore_file = argv[i];
  109.         break;
  110.  
  111.         case 'F': /* use next argument as "workfile" */
  112.         case 'f':
  113.         if(argv[i][2])/* argument is right next to option, no space */
  114.         {
  115.             Workfile = &argv[i][2];
  116.             break;
  117.         }
  118.         i++;
  119.         if(i == argc)
  120.             fatal("missing workfile");
  121.         else
  122.             Workfile = argv[i];
  123.         break;
  124.  
  125.         case 'S': /* use next  argument as subst file */
  126.         case 's':
  127.         if(argv[i][2])/* argument is right next to option, no space */
  128.         {
  129.             subst_filename = &argv[i][2];
  130.             break;
  131.         }
  132.         i++;
  133.         if(i == argc)
  134.             fatal("missing substitutions file");
  135.         else
  136.             subst_filename = argv[i];
  137.         break;
  138.  
  139.         case 'X': /* extract  names from arguments */
  140.         case 'x': 
  141.         Mode = EXTRACT_SYMBOLS;
  142.         break;
  143.  
  144.         default:
  145.         fatal("Unrecognised option");
  146.         }      /* end switch */
  147.     }   /* end if */
  148.     }/* end for */
  149.  
  150.     if(Workfile != NULL)
  151.     Wfp = try_r_open(Workfile);
  152.     else
  153.     {
  154.     Arg_index = 1;
  155.     Arg_count = argc;
  156.     ArgV = argv;
  157.     }
  158.  
  159.     if(Mode == READ_IGNORES)
  160.     {
  161.         init_extract(); /* and use that hash table to store ignorable identifiers */
  162.     if(Truncation == 0)
  163.         fatal("Cannot have -M option without -n option");
  164.     yyin = try_r_open(Ignore_file);
  165.     yylex(); /* next_yyin() switches input file in the middle */
  166.     return;
  167.     }
  168.     else
  169.     if(Mode == PRINT_TRUNCATED)
  170.       {
  171.       if(!next_yyin())
  172.     return;
  173.       yylex();
  174.       return;
  175.       }
  176.  
  177.  
  178.     if(Mode == EXTRACT_SYMBOLS) /* i.e. extracting names */
  179.     {
  180.     if(subst_filename != NULL)
  181.         fatal("incompatible options: -s and -X");
  182.  
  183.     init_extract();
  184.     if(!next_yyin())/* sets initial yyin */
  185.         return;
  186.     yylex();
  187.     sort_and_print();
  188.     return;
  189.     }
  190.     else
  191.     if(Mode == READ_SUBSTS ){
  192.     if(subst_filename == NULL){
  193. /* take the first argument to be the substitution file */
  194.         if(argv[1][0] == '-')
  195.         fatal("Missing substitution file");
  196.         subst_filename = argv[1];
  197.         Arg_index = 2;
  198.     }
  199.  
  200.     yyin = try_r_open(subst_filename);
  201.     init_csubst();
  202.     yylex();
  203.     exit(0);
  204.     }
  205. }
  206.  
  207. /* This tries to open the file as an input file and brings the programme
  208.    down if this is not possible 
  209.  */
  210. FILE *try_r_open(filename)
  211. char *filename;
  212. {
  213.     FILE *ifp;
  214.  
  215.     ifp = fopen(filename, "r");
  216.     if(ifp == NULL){
  217.     fatal1("could not open %s\n", filename);
  218.     return NULL; /* for lint */
  219.     }
  220.     else
  221.     return ifp;
  222. }
  223.  
  224. /* Issues an error message and forces the programe to abort  */
  225. void fatal(msg)
  226. char *msg;
  227. {  
  228.     fprintf(stderr,"%s\n", msg);
  229.     exit(1);
  230. }
  231.  
  232. /* This is a small variant of the above - see how it is used */
  233. void fatal1(fmt, str)
  234. char *fmt, *str;
  235. {      
  236.     fprintf(stderr, fmt, str);
  237.     fputc('\n',stderr);
  238.     exit(1);
  239. }     
  240.  
  241. void trunc_error()
  242. {
  243.     fatal("argument after -n should be positive integer");
  244. }
  245.  
  246. /* This function is called by yywrap inside yylex() when 
  247.    yyin reaches the end of the file. It makes yyin point to
  248.    the next file to read if possible and returns 1 iff
  249.    such a file existed. Does not handle wildcards yet.
  250.    This function is too complicated (it's been modified too many 
  251.    times)
  252.  */
  253. int next_yyin()
  254. {     
  255.     char source_filename[256];
  256.  
  257.     if((yyin != NULL) && (yyin != stdin))
  258.     fclose(yyin);
  259.  
  260.     if(Mode == READ_SUBSTS)
  261.     {
  262.     Mode = APPLY_SUBSTS;
  263.     }
  264.     else
  265.     if(Mode == READ_IGNORES)
  266.     {
  267.      Mode = PRINT_TRUNCATED;
  268.     }
  269.     if(Workfile != NULL)
  270.     {
  271.     if (EOF != fscanf(Wfp, "%s", source_filename))
  272.     {
  273.         yyin = try_r_open(source_filename);
  274.         return 1;
  275.     }
  276.     else
  277.         return 0;
  278.     }       
  279.     else while (Arg_index  < Arg_count && ( ArgV [Arg_index][0] == '-'))
  280.     {/* skip options */
  281.         if( ArgV [Arg_index][1] == 'X' &&  ArgV [Arg_index][2] != '\0')
  282.         { /* the filename is in close contact with the option */
  283.         yyin = try_r_open(& ArgV [Arg_index][2]);
  284.         Arg_index++;
  285.         return 1;
  286.         }
  287.         else
  288.         Arg_index ++;
  289.     }
  290.     if(Arg_index == Arg_count)
  291.     return 0;
  292.     else
  293.     yyin = try_r_open(ArgV[Arg_index]);
  294.     Arg_index++;
  295.     return 1;
  296.  
  297. }
  298. /* end of file */
  299.  
  300.