/* Mike Sullivan */ /* Write a program to remove all comments from a C program. Don't * forget to handle quoted strings and character constants properly. C * comments do not nest */ /* This is based on a program I wrote for one of the examples in The C * Programming Language. It's been improved a little. It's not * perfect, but it works. It sometimes leaves extra whitespace, but * life goes on. It also supports C++ comments. */ #include #include #include int decomment(FILE *f); int main(int argc, char *argv[]) { FILE *f; if (argc < 2 || strcmp(argv[1], "-") == 0) f = stdin; else if (!(f = fopen(argv[1], "r"))) { fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], strerror(errno)); return 1; } decomment(f); return 0; } int decomment(FILE *f) { int escape; /* escape char is up */ int in_comment; /* whether it is currently inside a comment */ int in_cpp_comment; /* whether it is currently inside a c++ comment */ int in_quote; /* whether it is currently inside quotes */ char quote_type; /* whether it's a double or single quote */ int c, tmp; c = escape = quote_type = in_quote = in_comment = in_cpp_comment = 0; while ((c = getc(f)) != EOF) { if (in_cpp_comment && c != '\n') continue; if (in_cpp_comment && c == '\n') in_cpp_comment = 0; if (!in_quote && !in_cpp_comment && c == '/') { if ((tmp = getc(f)) == '/') { in_cpp_comment = 1; continue; } else { ungetc(tmp, f); } } if (!in_quote && c == '/') { if ((tmp = getc(f)) == '*') in_comment = 1; else ungetc(tmp, f); } if (in_comment && c == '*') { if ((tmp = getc(f)) == '/') { in_comment = 0; continue; } else ungetc(tmp, f); } if (in_quote && !escape && c == quote_type) quote_type = in_quote = 0; else if (!in_quote && !in_comment && (c == '\'' || c == '"')) { in_quote = 1; quote_type = c; } if (in_quote && c == '\\' && !escape) escape = 1; else escape = 0; if (!in_comment) putchar(c); } return 0; }