home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / cpp.zoo / src / comment.c next >
C/C++ Source or Header  |  1993-06-03  |  5KB  |  207 lines

  1.  
  2. #include <stddef.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include "global.h"
  6.  
  7. #define SPC_GRAN 16
  8. #define LINEBUF 128
  9.  
  10. char *the_comment;
  11. size_t len_comment;
  12.  
  13. /*
  14.    find_start_comment() -- return a pointer to the first comment-start
  15.    sequence after |s|, or |NULL| if none is found
  16. */
  17. static char *find_start_comment(s)
  18.   register char *s;
  19. {
  20.   int in_dq = 0, in_sq = 0;
  21.  
  22.   for (;;) {
  23.     switch (*s++) {
  24.     case '\0':
  25.       return NULL;
  26.     case '\\':
  27.       s++;
  28.       continue;
  29.     case '"':
  30.       if (!in_sq)
  31.     in_dq ^= 1;
  32.       break;
  33.     case '\'':
  34.       if (!in_dq)
  35.     in_sq ^= 1;
  36.       break;
  37.     case '/':
  38.       if (!in_dq && !in_sq && *s == '*')
  39.     return s - 1;
  40.     }
  41.   }
  42. }
  43.  
  44. /*
  45.    find_end_comment() -- return a pointer to the first character after the
  46.    current comment, or end of line if the comment does not end on this line.
  47.    Modifies |in_comment| appropriately.
  48. */
  49. static char *find_end_comment(s)
  50.   register char *s;
  51. {
  52.   for (; *s; s++) {
  53.     if (*s == '*' && s[1] == '/')
  54.       return s + 2;
  55.   }
  56.   return NULL;
  57. }
  58.  
  59. /*
  60.    nest_check() -- examine the body of a comment for comment-start sequences.
  61.    Return 1 if one is found, 0 if not.
  62. */
  63. static int nest_check(s, t)
  64.   char *s, *t;
  65. {
  66.   register char *u;
  67.  
  68.   if (!t)
  69.     t = s + strlen(s);
  70.   if (f_cpp_cmts) {
  71.     for (u = s; u < t - 1; u++)
  72.       if (*u == '/' && (u[1] == '*' || u[1] == '/'))
  73.     return 1;
  74.   } else {
  75.     for (u = s; u < t - 1; u++)
  76.       if (*u == '/' && u[1] == '*')
  77.     return 1;
  78.   }
  79.   return 0;
  80. }
  81.  
  82. /*
  83.    copy_comment() -- place a malloc()'ed copy of the comment beginning at |s|
  84.    into the global pointer |the_comment|.  Return a pointer to the first
  85.    character after the comment.
  86. */
  87. static char *copy_comment(s)
  88.   char *s;
  89. {
  90.   register char *in_com, *t;
  91.   int n;
  92.   unsigned long in_comment;
  93.  
  94.   in_comment = this_line;
  95.   in_com = the_comment = mallok(len_comment = LINEBUF);
  96.   if (s[1] == '/') {
  97.     free(the_comment);
  98.     the_comment = strdup(s);
  99.     if (w_nest_cmts && nest_check(s + 2, NULL))
  100.       warning("nested comment (began at line %lu)", in_comment);
  101.     return s + strlen(s);
  102.   }
  103.   for (;;) {
  104.     t = find_end_comment(s);
  105.     n = (!t ? strlen(s) + 2 : (int)(t - s) + 1);
  106.     in_com = grow(&the_comment, &len_comment, in_com, n);
  107.     strncpy(in_com, s, n);
  108.     in_com += n;
  109.     if (!t)
  110.       *in_com++ = '\n';
  111.     *in_com = '\0';
  112.     if (w_nest_cmts && nest_check(s, t))
  113.       warning("nested comment (began at line %lu)", in_comment);
  114.     if (t)
  115.       break;
  116.     s = getline();
  117.     if (!s) {
  118.       error("unterminated comment (began at line %ld)", in_comment);
  119.       in_com = grow(&the_comment, &len_comment, in_com, 3);
  120.       *in_com++ = '*';
  121.       *in_com++ = '/';
  122.       *in_com = '\0';
  123.       t = NULL;
  124.       break;
  125.     }
  126.   }
  127.   return t;
  128. }
  129.  
  130. /*
  131.    suck_comment() -- Skip over the comment beginning at |s|.  Return a
  132.    pointer to the first character after the comment.
  133. */
  134. static char *suck_comment(s)
  135.   char *s;
  136. {
  137.   register char *t;
  138.   unsigned long in_comment;
  139.  
  140.   if (keep_comments)
  141.     return copy_comment(s);
  142.   in_comment = this_line;
  143.   /* C++ comments end at the end of the line */
  144.   if (s[1] == '/') {
  145.     if (w_nest_cmts && nest_check(s + 2, NULL))
  146.       warning("nested comment (began at line %lu)", in_comment);
  147.     return s + strlen(s);
  148.   }
  149.   for (;;) {
  150.     t = find_end_comment(s);
  151.     if (w_nest_cmts && nest_check(s, t))
  152.       warning("nested comment (began at line %lu)", in_comment);
  153.     if (t) {
  154.       return t;
  155.     }
  156.     s = getline();
  157.     if (!s) {
  158.       error("unterminated comment (began at line %ld)", in_comment);
  159.       return NULL;
  160.     }
  161.   }
  162. }
  163.  
  164. /*
  165.    suck_ws() -- skip over whitespace characters after |S|, placing a
  166.    malloc()'ed copy of same in |*spc|.  Return a pointer to the first
  167.    non-whitespace character after |s|.
  168. */
  169. char *suck_ws(s, spc)
  170.   register char *s;
  171.   char **spc;
  172. {
  173.   register char *t, *u;
  174.   char *spc_buf;
  175.   size_t sz_spc_buf;
  176.   int n;
  177.   extern char *the_comment;
  178.  
  179.   u = spc_buf = mallok(sz_spc_buf = SPC_GRAN);
  180.   for (;;) {
  181.     t = s;
  182.     while (isspace(*s))
  183.       *s++;
  184.     n = s - t;
  185.     u = grow(&spc_buf, &sz_spc_buf, u, n + 2);
  186.     strncpy(u, t, n);
  187.     u += n;
  188.     *u = '\0';
  189.     if (!(*s == '/' && (s[1] == '*' || (f_cpp_cmts && s[1] == '/'))))
  190.       break;
  191.     s = suck_comment(s);
  192.     if (!keep_comments)
  193.       *u++ = ' ';
  194.     else {
  195.       n = strlen(the_comment);
  196.       u = grow(&spc_buf, &sz_spc_buf, u, n + 1);
  197.       strcpy(u, the_comment);
  198.       u += n;
  199.     }
  200.     if (!s)
  201.       break;
  202.   }
  203.   *u = '\0';
  204.   *spc = spc_buf;
  205.   return s;
  206. }
  207.