#include <stdio.h>
#include <assert.h>
#include <string.h>
#if 1
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:\t",__FILE__,__LINE__); \
printf pfexp; \
} while(0)
#else#endif
struct {
FILE * input;
FILE * output;
int rc;
int keepFirst;
} App = {
0,
0,
0,
0
};
void do_it_all(void){
enum states {
S_NONE = 0 ,
S_SLASH1 = 1 ,
S_CPP = 2 ,
S_C = 3
};
int ch, prev = EOF;
FILE * out = App.output;
int const slash = '/';
int const star = '*';
int line = 1;
int col = 0;
enum states state = S_NONE ;
int elide = 0 ;
int state3Col = -99
;
for( ; EOF != (ch = fgetc(App.input)); prev = ch,
++col){
switch(state){
case S_NONE:
if('\''==ch || '"'==ch || '`'==ch){
int const quote = ch,
startLine = line, startCol = col;
int ch2, escaped = 0, endOfString = 0;
fputc(ch, out);
for( ++col; !endOfString && EOF != (ch2 = fgetc(App.input));
++col ){
switch(ch2){
case '\\': escaped = !escaped;
break;
case '`':
case '\'':
case '"':
if(!escaped && quote == ch2) endOfString = 1;
escaped = 0;
break;
default:
escaped = 0;
break;
}
if('\n'==ch2){
++line;
col = 0;
}
fputc(ch2, out);
}
if(EOF == ch2){
fprintf(stderr, "Unexpected EOF while reading %s literal "
"on line %d column %d.\n",
('\''==ch) ? "char" : "string",
startLine, startCol);
App.rc = 1;
return;
}
break;
}
else if(slash == ch){
state = S_SLASH1;
break;
}
fputc(ch, out);
break;
case S_SLASH1:
switch(ch){
case '*':
if(App.keepFirst>0){
elide = 0;
--App.keepFirst;
}else{
elide = 1;
}
state = S_C;
state3Col = col-1;
if(!elide){
fputc(prev, out);
fputc(ch, out);
}
break;
case '/':
if(App.keepFirst>0){
elide = 0;
--App.keepFirst;
}else{
elide = 1;
}
state = S_CPP;
if(!elide){
fputc(prev, out);
fputc(ch, out);
}
break;
default:
state = S_NONE;
if(!elide){
fputc(prev, out);
fputc(ch, out);
}
}
break;
case S_CPP:
if('\n' == ch){
state = S_NONE;
elide = 0;
}
if(!elide){
fputc(ch, out);
}
break;
case S_C:
if(!elide){
fputc(ch, out);
}
if(slash == ch){
if(star == prev){
if(col!=state3Col+2){
state = S_NONE;
elide = 0;
state3Col = -99;
}
}
}
break;
default:
assert(!"impossible!");
break;
}
if('\n' == ch){
++line;
col = 0;
state3Col = -99;
}
}
}
static void usage(char const *zAppName){
fprintf(stderr, "Strips C- and C++-style comments from stdin and sends "
"the results to stdout.\n");
fprintf(stderr, "Usage: %s [--keep-first|-k] < input > output\n", zAppName);
}
int main( int argc, char const * const * argv ){
int i;
for(i = 1; i < argc; ++i){
char const * zArg = argv[i];
while( '-'==*zArg ) ++zArg;
if( 0==strcmp(zArg,"k")
|| 0==strcmp(zArg,"keep-first") ){
++App.keepFirst;
}else{
usage(argv[0]);
return 1;
}
}
App.input = stdin;
App.output = stdout;
do_it_all();
return App.rc ? 1 : 0;
}