home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / REMCMMNT.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  176 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4.  * REMCMMNT.C
  5.  * Remove comments from C or C++ source
  6.  *
  7.  * ver 1.1, 14 Jun 1995
  8.  *   - changed multiline C++ comment handling
  9.  *
  10.  * ver 1.2, 8 Nov 1995
  11.  *   - bug: if file was ended with // comment with no CR/LF,
  12.  *          program jammed in an endless loop.
  13.  *
  14.  * ver 1.3, 21 Nov 1995
  15.  *   - bug: did not handle empty strings ""
  16.  *   - bug: did not handle escape character \" inside strings
  17.  *   - bug: did not catch an end of comment that ended with two or more '*'s
  18.  *
  19.  * Public domain by:
  20.  *   Jari Laaksonen
  21.  *   Arkkitehdinkatu 30 A 2
  22.  *   FIN-33720 Tampere
  23.  *   FINLAND
  24.  *
  25.  *   Fidonet : 2:221/360.20
  26.  *   Internet: jla@to.icl.fi
  27.  */
  28.  
  29. #include <stdio.h>
  30.  
  31. int main (int argc, char **argv)
  32. {
  33.   int  Char,
  34.        Char2,
  35.        cpp_comment   = 0,
  36.        c_comment     = 0,
  37.        in_string     = 0,
  38.        cpp_multiline = 0;
  39.   char CannotOpen[] = "Cannot open %s\n\n";
  40.   FILE *InFile, *OutFile = stdout;
  41.  
  42.   if (argc < 2)
  43.   {
  44.     fprintf (stderr, "USAGE: REMCMMNT InFile [OutFile]\n");
  45.     return 1;
  46.   }
  47.   if ((InFile = fopen (argv[1], "r")) == NULL)
  48.   {
  49.     fprintf (stderr, CannotOpen, argv[1]);
  50.     return 2;
  51.   }
  52.  
  53.   if (argc == 3)
  54.   {
  55.     if ((OutFile = fopen (argv[2], "w")) == NULL)
  56.     {
  57.       fprintf (stderr, CannotOpen, argv[2]);
  58.       OutFile = stdout;  /* if can't open, output goes to stdout instead */
  59.     }
  60.   }
  61.  
  62.   while ((Char = fgetc (InFile)) != EOF)
  63.   {
  64.     /* do we have excape characters \", \\ etc. inside string ? */
  65.     if (in_string && Char == '\\')
  66.     {
  67.       Char2 = fgetc (InFile);
  68.  
  69.       fputc (Char,  OutFile);
  70.       fputc (Char2, OutFile);
  71.       continue;
  72.     }
  73.  
  74.     if (Char == '\"')
  75.     {
  76.       Char2 = fgetc (InFile);
  77.  
  78.       /* do we have a character constant '\"' or an empty string "" ? */
  79.       if (Char2 != '\'' && Char2 != '\"')
  80.         in_string = ! in_string;    /* if not, we are in a string */
  81.  
  82.       if (c_comment == 0 && cpp_comment == 0)
  83.       {
  84.         fputc (Char,  OutFile);
  85.         fputc (Char2, OutFile);
  86.         continue;
  87.       }
  88.     }
  89.  
  90.     if (! in_string)
  91.     {
  92.       if (Char == '/')
  93.       {
  94.         Char2 = fgetc (InFile);     /* check next char */
  95.         if (Char2 == '/')           /* is it start of C++ comment? */
  96.           cpp_comment = 1;
  97.         else if (Char2 == '*')      /* is it start of C comment? */
  98.           c_comment = 1;
  99.  
  100.         if (c_comment == 0 && cpp_comment == 0)
  101.         {
  102.           fputc (Char,  OutFile);
  103.           fputc (Char2, OutFile);
  104.           continue;
  105.         }
  106.       }
  107.       else if (Char == '*' && c_comment)
  108.       {
  109.         Char2 = fgetc (InFile);
  110.         if (Char2 == '/')                   /* is it end of C comment? */
  111.         {
  112.           c_comment = 0;
  113.           Char = fgetc (InFile);
  114.         }
  115.       }
  116.  
  117.       if (c_comment || cpp_comment) /* are we inside C or C++ comment? */
  118.       {
  119.         Char = '\n'; /* print newline after comment line is processed */
  120.         while ((Char2 = fgetc (InFile)) != '\n') /* rest of the line */
  121.         {
  122.           if (Char2 == EOF)
  123.             break;
  124.  
  125.           if (cpp_multiline)
  126.           {
  127.             if (Char2 != ' ' && Char2 != '\t') /* if not white space => */
  128.               cpp_multiline = 0;             /* ...not C++ multiline comment */
  129.           }
  130.  
  131.           if (Char2 == '\\' && cpp_comment)
  132.             cpp_multiline = 1;
  133.  
  134.           if (Char2 == '*' && c_comment)
  135.           {
  136.             Char2 = fgetc (InFile); /* check next char */
  137.             if (Char2 == '/')       /* is it end of C comment? */
  138.             {
  139.               c_comment = 0;
  140.               Char = fgetc (InFile);
  141.               break;
  142.             }
  143.             else
  144.               ungetc (Char2, InFile);        /* put it back to stream */
  145.             if (Char2 == '\n')
  146.               break;
  147.           }
  148.         }
  149.         if (cpp_comment && cpp_multiline == 0)
  150.           cpp_comment = 0;
  151.         if (c_comment || cpp_comment)
  152.           fputc (Char,  OutFile);
  153.  
  154.         /* clear flag for the next round. if it is still clear after
  155.            next C++ comment line is processed, multiline C++ comment
  156.            is ended.
  157.         */
  158.         cpp_multiline = 0;
  159.       }
  160.  
  161.     }
  162.     if (c_comment == 0 && cpp_comment == 0)
  163.       fputc (Char,  OutFile);
  164.  
  165.   } /* while end */
  166.  
  167.   if (argc == 3)
  168.     fclose (OutFile);
  169.   fclose (InFile);
  170.  
  171.   fflush (stdout);
  172.   fprintf (stderr, "\nOK!\n");
  173.  
  174.   return 0;
  175. }
  176.