Comment viewer (was Re: This one bit me today)
Robert de Vries
robert at duttnph.tudelft.nl
Wed Oct 11 01:57:47 AEST 1989
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 at cs.mu.oz.au)
Changed to highlight using reversed characters and to handle
quoted strings with comment.
Changed by: Robert de Vries (robert at 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);
}
More information about the Comp.lang.c
mailing list