On Sun, 2 Nov 2003, CBFalconer wrote:
Stephen Samuel wrote: Timex wrote:
I want to delete all comments in .c file.
#!/usr/bin/perl
$s=join("",<>);
# printf "[[%s]]\n\n",$s;
$s=~ s/("(\\\\|\\"|[^"])*")|(\/\*([^*]|\*(?=[^\/]))*\*\/)|(\/\/.*)/[[$1 ]]/g;
printf "[[%s]]\n\n",$s;
/* File uncmntc.c - demo of a text filter
Strips C comments. Tested to strip itself
by C.B. Falconer. 2002-08-15
Public Domain. Attribution appreciated
report bugs to <mailto:cb***** ***@worldnet.at t.net>
*/
<snip code>
I ran your program through some hurdles, and found that
it couldn't handle multibyte character constants for some
reason. I didn't bother to track down why; I just re-wrote
the filter from scratch. ;-) Here's my version, whose
algorithm may be completely different from yours.
This algorithm, on the other hand, completely fails to
handle line-splicing in the middle of comment delimiters: /\
* this is a comment */ does not work, nor does /* this either *\
/. Comment removal really is tricky in the most general case!
Proper error-checking on getc() and putc(), and a good
command-line interface, left as exercises for the interested
reader.
/* File uncmntc2.c - demo of a different text filter
Strips C comments. Tested to strip itself
Improves on CBFalconer's design by correctly handling '/*'
and by having a C89/C99 switch, but doesn't handle the /\
* delimiter correctly.
by Arthur O'Dwyer, 2002-11-03
Public Domain. Attribution appreciated
don't bother reporting bugs, just fix 'em...
*/
#include <stdio.h>
#include <stdlib.h>
/* Strip C99-style end-of-line comments? */
int AllowEOLComment s = 1;
int strip_comments( FILE *fp, FILE *outfp);
static int put_carefully(i nt lastch, int ch, FILE *outfp);
int main(void)
{
strip_comments( stdin, stdout);
return 0;
}
int strip_comments( FILE *fp, FILE *outfp)
{
int ch;
int lastch;
int inchotes = 0;
int inquotes = 0;
int incomment = 0;
int ineolcomment = 0;
for (lastch = ' '; (ch = getc(fp)) != EOF; lastch = ch)
{
if (!incomment && !ineolcomment)
{
if (inquotes || inchotes)
putc(ch, outfp);
else
put_carefully(l astch, ch, outfp);
}
if (inchotes) {
if (ch == '\'' && lastch != '\\')
inchotes = 0;
} else if (inquotes) {
if (ch == '"' && lastch != '\\')
inquotes = 0;
} else if (incomment) {
if (ch == '/' && lastch == '*')
incomment = 0, ch = ' ';
} else if (ineolcomment) {
if (ch == '\n' && lastch != '\\')
ineolcomment = 0;
} else {
if (ch == '\'')
inchotes = 1;
else if (ch == '"')
inquotes = 1;
else if (lastch == '/' && ch == '*') {
putc(' ', outfp);
incomment = 1;
}
else if (AllowEOLCommen ts && lastch == '/' && ch == '/')
ineolcomment = 1;
}
}
if (lastch == '/')
putc(lastch, outfp);
return 0;
}
static int put_carefully(i nt lastch, int ch, FILE *outfp)
{
/* Print out 'ch', but be very careful not to print
* any characters that might be part of a comment
* delimiter. Contrariwise, if 'lastch' is now
* definitely *not* a comment delimiter, we must now
* print it, too.
*/
if (AllowEOLCommen ts) {
if (lastch == '/' && ch == '/')
return 0;
}
if (lastch == '/' && ch == '*')
return 0;
if (lastch == '/')
putc(lastch, outfp);
if (ch != '/')
putc(ch, outfp);
return 0;
}