allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/21/89)
Posting-number: Volume 6, Issue 68 Submitted-by: lupton@uhccux.uhcc.Hawaii.Edu (Robert Lupton ) Archive-name: deansi [Also see "agcpp", as posted to comp.os.minix. ++bsa] My postnews spat this out (`error 11' -- ?), so here it is by mail. [Ummm, sounds like a segmentation violation. Contact your local guru. ++bsa] Here is a simple-minded Lex programme to convert ANSI to Classic C, or at least to try. It will convert prototypes external to functions to extern declarations, convert function declarations from the form "foo(int a,char *b)" to "foo(a,b) int a; char *b;" and remove a couple of keywords (volatile, const). No attempt is made to deal with pre-processor incompatibilities. You are welcome to copy, modify, or (even |-) improve the code, providing that my name remains on it, you don't make money, and these conditions remain on the fruits of your labours. Also, please post any significant improvements. Robert Lupton : =-=-=-=-=-=-=-=-=-=-= Cut Here =-=-=-=-=-=-=-=-=-=-= PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH echo Extracting Makefile if [ -w Makefile ]; then echo File already exists - saving as Makefile.old mv Makefile Makefile.old chmod 444 Makefile.old fi sed 's/^X//' <<'//go.sysin dd *' >Makefile # # Take an ansi programme, and prepare it for a K&R1 compiler. # No attempt is made to deal with preprocessor differences, # but some keywords are deleted (volatile, const), and declarations # are modified to be acceptable # CFLAGS = -g # deansi : deansi.o cc -o deansi deansi.o -ll @- rm -f deansi.o # tidy : rm -f *~ deansi.c *.o core a.out empty : tidy rm -f deansi //go.sysin dd * if [ `wc -c < Makefile` != 374 ]; then made=FALSE echo error transmitting Makefile -- echo length should be 374, not `wc -c < Makefile` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 Makefile echo -n ; ls -ld Makefile fi echo Extracting deansi.l if [ -w deansi.l ]; then echo File already exists - saving as deansi.l.old mv deansi.l deansi.l.old chmod 444 deansi.l.old fi sed 's/^X//' <<'//go.sysin dd *' >deansi.l %% %{ X/* * Syntax: deansi [ file ] * * This lex programme takes an ANSI style (prototyped) function declaration, * and makes it acceptable to a K&R-1 style (`Classic') compiler. It assumes * that the last valid name in a declaration is the name of the variable. * * Varargs functions (with ...) are not understood. * * Prototypes ending in a ; are converted to old-style declarations * * A couple of ANSI keywords are deleted (const, volatile) * * No attempt is made to deal with preprocessor directives * * Anyone is permitted to copy, modify, or improve this programme, * providing that this notice appears on the final result, and that * they don't make any money out of it. * * Robert Lupton */ #include <ctype.h> #define isok(C) (isalnum(C) || (C) == '_') int brace = 0, /* level of {} grouping */ in_comment = 0; /* am I in a comment? */ %} \([ \t]*void[ \t]*\) { /* functions declared (void) */ if(brace == 0) { printf("()"); } else { REJECT; } } \([^{};]*\)[ \t]*; { /* prototypes */ int i, paren = 0; /* level of parens */ if(brace == 0 && !in_comment) { for(i = 0;i < yyleng;i++) { if(paren == 0) putchar(yytext[i]); if(yytext[i] == '(') paren++; if(yytext[i] == ')') { paren--; if(paren == 0) putchar(')'); } } } else { REJECT; } } \([^{};]*\) { /* declarations */ char *decl; int i,j,k; if(brace == 0 && !in_comment) { /* printf("<%s>",yytext); */ yytext[--yyleng] = '\0'; /* strip closing ')' */ putchar('('); for(j = 1;j < yyleng;) { for(i = 0,decl = &yytext[j]; decl[i] != '\0' && decl[i] != ',';i++) ; j += i + 1; for(;!isok(decl[i]);i--) ; for(k = 0;isok(decl[i - k]);k++) ; printf("%.*s",k,&decl[i - k + 1]); if(j < yyleng - 1) putchar(','); } printf(")\n"); for(j = 1;j < yyleng;) { for(i = 0,decl = &yytext[j]; decl[i] != ',' && decl[i] != '\0';i++) ; printf("%.*s;",i,decl); j += i + 1; if(j < yyleng - 1) putchar('\n'); } } else { REJECT; } } "/*" { in_comment = 1; ECHO; } "*/" { in_comment = 0; ECHO; } \"[^"]*\" { ECHO; } "{" { if(!in_comment) brace++; ECHO; } "}" { if(!in_comment) brace--; ECHO; } const[ \t]* | volatile[ \t]* ; [a-z]* | .|\n ECHO; %% #include <stdio.h> main(ac,av) int ac; char **av; { if(ac > 1) { if(freopen(av[1],"r",stdin) == NULL) { fprintf(stderr,"Can't open %s\n",av[1]); exit(-1); } } yylex(); } //go.sysin dd * if [ `wc -c < deansi.l` != 2666 ]; then made=FALSE echo error transmitting deansi.l -- echo length should be 2666, not `wc -c < deansi.l` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 deansi.l echo -n ; ls -ld deansi.l fi echo Extracting tst.c if [ -w tst.c ]; then echo File already exists - saving as tst.c.old mv tst.c tst.c.old chmod 444 tst.c.old fi sed 's/^X//' <<'//go.sysin dd *' >tst.c X/* * A test (with parentheses) */ extern int main(register int,char **), func(void); static int func2(void (*my_func)(),const char *); main(register int ac,char **av) { volatile int interrupt; const char *ptr = "World\n"; (void)func2(func,ptr); } int func(void) { printf("Hello "); } static int func2(void (*my_func)(),const char *s) { (*my_func)(); return(printf("%s",s)); } //go.sysin dd * if [ `wc -c < tst.c` != 404 ]; then made=FALSE echo error transmitting tst.c -- echo length should be 404, not `wc -c < tst.c` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 tst.c echo -n ; ls -ld tst.c fi