Created
April 18, 2013 23:52
-
-
Save syzdek/5417109 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Program to strip comments and strings from a C file | |
// | |
// Answer to StackOverflow question: | |
// http://stackoverflow.com/questions/16086617/c-removing-comments-with-a-sliding-window-without-nested-while-loops | |
// | |
// Build: | |
// gcc -o strip-comments strip-comments.c | |
// | |
// Test: | |
// ./strip-comments strip-comments.c | |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <sys/uio.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
/* The following is a block of strings, and comments for testing | |
* the code. | |
*/ | |
/* test if three comments *//* chained together */// will be removed. | |
const char * test1 = "This is a test of \" processing"; /* testing inline comment */ | |
const char * test2 = "this is a test of \n within strings."; // testing inline comment | |
// this is a the last test | |
int strip_c_code(FILE * in, FILE * out) | |
{ | |
char buff[2]; | |
char skipping; | |
skipping = '\0'; | |
buff[0] = '\0'; | |
buff[1] = '\0'; | |
// loop through the file | |
while((buff[0] = fgetc(in)) != EOF) | |
{ | |
// checking for start of comment or string block | |
if (!(skipping)) | |
{ | |
// start skipping in "//" comments | |
if ((buff[1] == '/') && (buff[0] == '/')) | |
skipping = '/'; | |
// start skipping in "/*" comments | |
else if ((buff[1] == '/') && (buff[0] == '*')) | |
skipping = '*'; | |
// start skipping at start of strings, but not character assignments | |
else if ( ((buff[1] != '\'') && (buff[0] == '"')) && | |
((buff[1] != '\\') && (buff[0] == '"')) ) | |
{ | |
fputc(buff[1], out); | |
skipping = '"'; | |
}; | |
// clear buffer so that processed characters are not interpreted as | |
// end of skip characters. | |
if ((skipping)) | |
{ | |
buff[0] = '\0'; | |
buff[1] = '\0'; | |
}; | |
}; | |
// check for characters which terminate skip block | |
if ((skipping)) | |
{ | |
switch(skipping) | |
{ | |
// if skipping "//" comments, look for new line | |
case '/': | |
if (buff[1] == '\n') | |
skipping = '\0'; | |
break; | |
// if skipping "/*" comments, look for "*/" terminating string | |
case '*': | |
if ((buff[1] == '*') && (buff[0] == '/')) | |
{ | |
buff[0] = '\0'; | |
buff[1] = '\0'; | |
skipping = '\0'; | |
}; | |
break; | |
// if skipping strings, look for terminating '"' character | |
case '"': | |
if ((buff[1] != '\\') && (buff[0] == '"')) | |
{ | |
skipping = '\0'; | |
buff[0] = '\0'; | |
buff[1] = '\0'; | |
fprintf(out, "NULL"); // replace string with NULL | |
}; | |
break; | |
default: | |
break; | |
}; | |
}; | |
// if not skipping, write character out | |
if ( (!(skipping)) && ((buff[1])) ) | |
fputc(buff[1], out); | |
// shift new character to old character position | |
buff[1] = buff[0]; | |
}; | |
// verify that the comment or string was terminated properly | |
if ((skipping)) | |
{ | |
fprintf(stderr, "Unterminated comment or string\n"); | |
return(-1); | |
}; | |
// write last character | |
fputc(buff[1], out); | |
return(0); | |
} | |
int main(int argc, char * argv[]) | |
{ | |
FILE * fs; | |
if (argc != 2) | |
{ | |
fprintf(stderr, "Usage: %s <filename>\n", argv[0]); | |
return(1); | |
}; | |
if ((fs = fopen(argv[1], "r")) == NULL) | |
{ | |
perror("fopen()"); | |
return(1); | |
}; | |
strip_c_code(fs, stdout); | |
fclose(fs); | |
return(0); | |
} | |
/* end of source file */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment