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

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /* Extract comments from a C program source file.
  4. **
  5. ** This program acts as a filter to copy comments in a C source
  6. ** file to the output.  Each comment includes the starting and
  7. ** ending delimiters and is followed by a newline.
  8. **
  9. ** Three #ifdef options are defined:
  10. **   INHIBIT_TRIGRAPHS prevents recognition of trigraphs, which
  11. **      can affect detection of escaped characters,
  12. **      i.e., ??/" is an escaped quote.
  13. **   TRANSLATE_TRIGRAPHS causes the output to have trigraphs
  14. **      converted to the normal C characters.
  15. **   CPP_MODE causes "//" to start a comment.
  16. ** The default for these symbols is undefined, resulting in
  17. ** operation on strict ANSI source, except as noted below.
  18. **
  19. ** What makes this program interesting is that comment detection
  20. ** should be inhibited within strings and character constants.
  21. **
  22. ** Note: The name of a header following #include can, under ANSI,
  23. ** contain any sequence of characters, except \n and the closing
  24. ** > or ".  This program doesn't inhibit comment, string, or character
  25. ** constant detection within the header name, as an ANSI parser must.
  26. **
  27. ** Written by and contributed to the public domain by
  28. ** Thad Smith III,   Boulder, CO,  October 1990.
  29. */
  30.  
  31. #include <stdio.h>
  32.  
  33. #ifndef INHIBIT_TRIGRAPHS        /* default: recognize trigraphs */
  34.  #define getnc()  getnsc(1)       /* get char with trigraph xlate */
  35.  #ifdef TRANSLATE_TRIGRAPHS
  36.   #define getcmtc() getnsc(1)     /* get comment char w/ t.g. xlate */
  37.  #else
  38.   #define getcmtc() getnsc(0)     /* default: no comment t.g. xlate */
  39.  #endif
  40.  
  41. /*
  42. **  get next source character or EOF
  43. */
  44.  
  45. int getnsc(int cvtg)             /* boolean: convert trigraphs */
  46. {
  47.       static int c, nc, nnc;     /* next 3 characters */
  48.  
  49.       /* shift in next source character */
  50.  
  51.       c = nc;  nc = nnc;   nnc = getchar();
  52.  
  53.       /* perform trigraph substitution */
  54.  
  55.       if (cvtg && c == '?' && nc == '?')
  56.       {
  57.             switch (nnc)
  58.             {
  59.             case '=' :
  60.                   c = '#' ;
  61.                   break;
  62.             case '(' :
  63.                   c = '[' ;
  64.                   break;
  65.             case '/' :
  66.                   c = '\\';
  67.                   break;
  68.             case ')' :
  69.                   c = ']' ;
  70.                   break;
  71.             case '\'':
  72.                   c = '^' ;
  73.                   break;
  74.             case '<' :
  75.                   c = '{' ;
  76.                   break;
  77.             case '!' :
  78.                   c = '|' ;
  79.                   break;
  80.             case '>' :
  81.                   c = '}' ;
  82.                   break;
  83.             case '-' :
  84.                   c = '~' ;
  85.                   break;
  86.             default  :
  87.                   return c;        /* no substitution */
  88.             }
  89.             nc = getchar();   nnc = getchar();
  90.       }
  91.       return c;
  92. }
  93.  
  94. #else       /* don't process trigraphs */
  95.  
  96.  #define getnc()   getchar()
  97.  #define getcmtc() getchar()
  98. #endif
  99.  
  100. int main(void)
  101. {
  102.       int pc;  /* previous character      */
  103.       int c;   /* current input character */
  104.  
  105. #ifndef INHIBIT_TRIGRAPHS
  106.       getnc();                                        /* prime the pump */
  107.       getnc();
  108. #endif
  109.       c = getnc();                                    /* get first char */
  110.  
  111.       for (;;)                                  /* in non-comment area */
  112.       {
  113.             switch (c)
  114.             {
  115.             case '/':                     /* possible start of comment */
  116.                   if ((c= getnc()) == '*')      /* process comment */
  117.                   {
  118.                         putchar('/');
  119.                         putchar('*');
  120.  
  121.                         /* copy comment to stdout */
  122.  
  123.                         for (pc = 0; (c = getcmtc()) != EOF &&
  124.                               (putchar(c) != '/' || pc != '*'); pc=c)
  125.                                     ;
  126.                               putchar('\n');
  127. #ifdef CPP_MODE
  128.                   }
  129.                   else if (c == '/')      /*  '//' comment */
  130.                   {
  131.                         putchar('/');
  132.                         putchar('/');
  133.                         while ((c = getcmtc()) != EOF && putchar(c) != '\n')
  134.                               ;
  135. #endif
  136.                   }
  137.                   else  continue;         /* test current char */
  138.                   break;
  139.  
  140.             case '\"':                                /* start of string */
  141.             case '\'':    /* start of (possibly multi-byte) char constant */
  142.                   pc = c;                             /* save delimiter */
  143.                   do                      /* scan through character constant,
  144.                                           ** discarding escape chars
  145.                                           */
  146.                   {
  147.                         while ((c = getnc()) == '\\')
  148.                               getnc();
  149.                   } while (c != pc && c != EOF);
  150.                   break;
  151.             }
  152.             if (c == EOF)
  153.                   return 0;
  154.             else  c = getnc();
  155.       }
  156. }
  157.