/* dient zum Umwandeln von Kommentaren: Input: text # comment Output: text / * comment * / Bruno Haible 9.7.1990, 6.8.1990, 15.8.1990, 22.9.1990, 17.1.1991, 31.8.1991 Aufrufmöglichkeiten, um program.d in program.c umzuwandeln: comment program comment und dann von Hand 'program' eingeben comment program.d program.c comment program.d > program.c Methode: Das Inputfile wird Zeile für Zeile umgewandelt. Ein '#', gefolgt von ' ', leitet einen Kommentar ein, der bis Zeilenende geht. '#'' ' wird durch '/''*'' ' ersetzt, und vors Zeilenende kommt ' ''*''/'. Ein '\' unmittelbar am Ende einer Zeile wird dabei zum Zeilenende gerechnet. Als erste Zeile wird '#line 1 "sourcefile"' eingefügt. Syntax eines Inputfile: -------> Char ----> '#' -> ' ' ----> Char ----> '\\' ---> '\n' -----> / / \ / \ \ / \ | \ / \ / --->--- | \ --<------ --<------ / -------------------<----------------------------------------- */ #include #include #define fopen_read_ascii "r" #define fopen_write_ascii "w" #define fputc putc #define fgetc getc int main (int argc, char* argv[]) { char infilenamebuffer[1000]; char outfilenamebuffer[1000] = "stdout"; FILE * infile; FILE * outfile; if (argc==3) { /* Aufruf der Form 'comment source destination' */ { char* p1 = argv[1]; char* p2 = infilenamebuffer; while ((*p2++ = *p1++) != '\0') {} } { char* p1 = argv[2]; char* p2 = outfilenamebuffer; while ((*p2++ = *p1++) != '\0') {} } } else { char filenamebuffer[1000]; char* filename; if (argc==2) { filename = argv[1]; } else { printf("Filename: "); filename = fgets(filenamebuffer,sizeof(filenamebuffer),stdin); if (filename==NULL) { exit(__LINE__); } } { /* infilename basteln: filename+".d" */ char* p = infilenamebuffer; { char* p2 = filename; char c; while ((c = *p2++) != '\0') { *p++ = c; } } /* Endet filename bereits mit ".d" ? */ if ((&p[-2] >= infilenamebuffer) && (p[-2]=='.') && (p[-1]=='d')) { *p++ = '\0'; goto to_stdout; } /* ja -> Output nach stdout */ *p++ = '.'; *p++ = 'd'; *p++ = '\0'; } { /* outfilename basteln: filename+".c" */ char* p = outfilenamebuffer; { char* p2 = filename; char c; while ((c = *p2++) != '\0') { *p++ = c; } } *p++ = '.'; *p++ = 'c'; *p++ = '\0'; } } if ((infile = fopen(infilenamebuffer,fopen_read_ascii))==NULL) { perror(infilenamebuffer); exit(__LINE__); } if ((outfile = fopen(outfilenamebuffer,fopen_write_ascii))==NULL) { fclose(infile); perror(outfilenamebuffer); exit(__LINE__); } if (0) { to_stdout: if ((infile = fopen(infilenamebuffer,fopen_read_ascii))==NULL) { perror(infilenamebuffer); exit(__LINE__); } outfile = stdout; /* outfile = Standard-Output */ } { /* write header in outfile: */ fputs("#line 1 \"",outfile); fputs(infilenamebuffer,outfile); fputs("\"\n",outfile); } /* infile in outfile kopieren: */ #define fput_startcomment(outfile) \ { fputc('/',outfile); fputc('*',outfile); fputc(' ',outfile); } #define fput_endcomment(outfile) \ { fputc(' ',outfile); fputc('*',outfile); fputc('/',outfile); } { register int c; L1: /* innerhalb einer Zeile, vor Kommentar */ c = fgetc(infile) ; L1a: if (c==EOF){ goto L3; } if (!(c=='#')) goto L4a; /* innerhalb einer Zeile, nach '#', vor ' ' */ c = fgetc(infile) ; if (!(c==' ')) { fputc('#',outfile); goto L1a; } fput_startcomment(outfile); L2: /* innerhalb eines Kommentars */ /* inside '#' comment */ c = fgetc(infile) ; L2a: if (c==EOF) { fput_endcomment(outfile); goto L3; } if (c=='\n') { fput_endcomment(outfile); fputc(c,outfile); goto L1; } if (!(c=='\\')) { fputc(c,outfile); goto L2; } /* innerhalb eines Kommentars, nach '\\' */ c = fgetc(infile) ; if (!(c=='\n')) { fputc('\\',outfile); goto L2a; } fput_endcomment(outfile); fputc('\\',outfile); fputc(c,outfile); goto L1; L4a: /* possibly start of '/*' comment */ /* EOF impossible */ fputc(c,outfile); if (!(c=='/')) { goto L1; } c = fgetc(infile) ; if (c==EOF){ goto L3; } fputc(c,outfile); if (!(c=='*')) goto L1; L5: /* Inside '/*' comment */ c = fgetc(infile) ; L5a: if (c==EOF){ goto L3; } /* do not fix programmer errors */ fputc(c,outfile); if (c=='*') goto L6; goto L5; L6: /* after asterisk in '/*' comment */ c = fgetc(infile) ; L6a: if (c==EOF){ goto L3; } fputc(c,outfile); if (c=='/') goto L1; goto L5; L3: ; /* am File-Ende */ } /* error checking should work after file closing, but it does not */ if (ferror(infile) || fclose(infile)) { perror(infilenamebuffer); exit(__LINE__); } if (ferror(outfile) || fclose(outfile)) { perror(outfilenamebuffer); exit(__LINE__); } exit(0); /* OK */ }