robert@duttnph.tudelft.nl (Robert de Vries) (10/10/89)
Richard O'Keefe posted recently an article with the source of a program to highlight comments in a C program. I liked it, so I enhanced it a little bit and made it a little more intelligent about strings. It also highlights the comments by reversing the text and background colors. There is one catch to this program: scarcely documented sources are VERY easily spotted. Obfuscated C programmers beware! :-) Robert. ---------------------- Cut here ------------------------------------ /* seecom.c -- highlight comments in C programs Usage: seecom <foobaz.c | more Original version by: Richard O'Keefe (ok@cs.mu.oz.au) Changed to highlight using reversed characters and to handle quoted strings with comment. Changed by: Robert de Vries (robert@duttnph.tudelft.nl) Compile: cc -o seecom seecom.c -ltermcap */ #include <stdio.h> main() { int state = 0; int c, prev_c = 0; char bp[1024], area[100], *parea, *start, *end, *term; extern char *tgetstr(), *getenv(); term = getenv("TERM"); if (term == NULL) { fprintf(stderr, "No TERM environment variable.\n"); exit(1); } if (tgetent(bp, term) != 1) { fprintf(stderr, "tgetent failed.\n"); exit(1); } parea = area; start = tgetstr("so", &parea); end = tgetstr("se", &parea); if ((start == NULL) || (end == NULL)) { fprintf(stderr, "This terminal type cannot highlight.\n"); exit(1); } while (c = getchar(), c != EOF) { switch (state) { case 0: /* we are not inside a comment */ /* check for '/*' '"' and ''' */ switch(c) { case '/': c = getchar(); if (c == '*') { printf("%s/*", start); state = 1; } else { ungetc(c, stdin); putchar('/'); } break; case '"': putchar(c); if (prev_c != '\\') state = 2; break; case '\'': putchar(c); if (prev_c != '\\') state = 3; break; default: putchar(c); break; } break; case 1: /* we are inside a comment */ /* check for '*' '/' */ putchar(c); if (c == '*') { c = getchar(); if (c == '/') { printf("/%s", end); state = 0; } else ungetc(c, stdin); } break; case 2: /* we are inside double quotes */ putchar(c); if ((c == '"') && (prev_c != '\\')) state = 0; break; case 3: /* we are inside single quotes */ putchar(c); if ((c == '\'') && (prev_c != '\\')) state = 0; break; } /* in case the backslash is an escape one, put a dummy character in prev_c */ if ((prev_c == '\\') && (c == '\\')) prev_c = ' '; else prev_c = c; } switch (state) { case 1: fprintf(stderr, "Unterminated comment.\n"); exit(1); break; case 2: fprintf(stderr, "Unterminated string (missing \").\n"); exit(1); break; case 3: fprintf(stderr, "Unterminated character constant (missing ').\n"); exit(1); break; } exit(0); }