123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720 |
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include <stdio.h>
- #include <ctype.h>
- #if HAVE_CONFIG_H
- # if STDC_HEADERS || HAVE_STRING_H
- # include <string.h>
- # else
- # include <strings.h>
- # endif
- #else
- # ifdef BSD
- # include <strings.h>
- # else
- # ifdef VMS
- extern int strlen(), strncmp();
- # else
- # include <string.h>
- # endif
- # endif
- #endif
- #if STDC_HEADERS
- # include <stdlib.h>
- #else
- # ifdef MSDOS
- # include <malloc.h>
- # else
- # ifdef VMS
- extern char *malloc();
- extern void free();
- # else
- extern char *malloc();
- extern int free();
- # endif
- # endif
- #endif
- #ifndef NULL
- # define NULL (0)
- #endif
- #ifdef isascii
- # undef HAVE_ISASCII
- # define HAVE_ISASCII 1
- #else
- #endif
- #if STDC_HEADERS || !HAVE_ISASCII
- # define is_ascii(c) 1
- #else
- # define is_ascii(c) isascii(c)
- #endif
- #define is_space(c) (is_ascii(c) && isspace(c))
- #define is_alpha(c) (is_ascii(c) && isalpha(c))
- #define is_alnum(c) (is_ascii(c) && isalnum(c))
- #define isidchar(ch) (is_alnum(ch) || (ch) == '_')
- #define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
- char *ppdirforward();
- char *ppdirbackward();
- char *skipspace();
- char *scanstring();
- int writeblanks();
- int test1();
- int convert1();
- int
- main(argc, argv)
- int argc;
- char *argv[];
- { FILE *in = stdin;
- FILE *out = stdout;
- char *filename = 0;
- char *program_name = argv[0];
- char *output_name = 0;
- #define bufsize 5000
- char *buf;
- char *line;
- char *more;
- char *usage =
- "Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
-
- int convert_varargs = 1;
- int output_error;
- while ( argc > 1 && argv[1][0] == '-' ) {
- if ( !strcmp(argv[1], "--varargs") ) {
- convert_varargs = 1;
- argc--;
- argv++;
- continue;
- }
- if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
- filename = argv[2];
- argc -= 2;
- argv += 2;
- continue;
- }
- fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
- argv[1]);
- fprintf(stderr, usage);
- exit(1);
- }
- switch ( argc )
- {
- default:
- fprintf(stderr, usage);
- exit(0);
- case 3:
- output_name = argv[2];
- out = fopen(output_name, "w");
- if ( out == NULL ) {
- fprintf(stderr, "%s: Cannot open output file %s\n",
- program_name, output_name);
- exit(1);
- }
-
- case 2:
- in = fopen(argv[1], "r");
- if ( in == NULL ) {
- fprintf(stderr, "%s: Cannot open input file %s\n",
- program_name, argv[1]);
- exit(1);
- }
- if ( filename == 0 )
- filename = argv[1];
-
- case 1:
- break;
- }
- if ( filename )
- fprintf(out, "#line 1 \"%s\"\n", filename);
- buf = malloc(bufsize);
- if ( buf == NULL )
- {
- fprintf(stderr, "Unable to allocate read buffer!\n");
- exit(1);
- }
- line = buf;
- while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
- {
- test: line += strlen(line);
- switch ( test1(buf) )
- {
- case 2:
- convert1(buf, out, 1, convert_varargs);
- break;
- case 1:
-
- more = ++line;
- f: if ( line >= buf + (bufsize - 1) )
- goto wl;
- if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
- goto wl;
- switch ( *skipspace(ppdirforward(more), 1) )
- {
- case '{':
-
- convert1(buf, out, 0, convert_varargs);
- fputs(more, out);
- break;
- case 0:
-
-
- line += strlen(line);
- goto f;
- default:
-
-
- fputs(buf, out);
- strcpy(buf, more);
- line = buf;
- goto test;
- }
- break;
- case -1:
- if ( line != buf + (bufsize - 1) )
- continue;
-
- default:
- wl: fputs(buf, out);
- break;
- }
- line = buf;
- }
- if ( line != buf )
- fputs(buf, out);
- free(buf);
- if ( output_name ) {
- output_error = ferror(out);
- output_error |= fclose(out);
- } else {
- fflush(out);
- output_error = ferror(out);
- }
- if ( output_error ) {
- fprintf(stderr, "%s: error writing to %s\n", program_name,
- (output_name ? output_name : "stdout"));
- exit(1);
- }
- if ( in != stdin )
- fclose(in);
- return 0;
- }
- char *
- ppdirforward(p)
- char *p;
- {
- for (; *p == '#'; ++p) {
- for (; *p != '\r' && *p != '\n'; ++p)
- if (*p == 0)
- return p;
- if (*p == '\r' && p[1] == '\n')
- ++p;
- }
- return p;
- }
- char *
- ppdirbackward(p, limit)
- char *p;
- char *limit;
- {
- char *np = p;
- for (;; p = --np) {
- if (*np == '\n' && np[-1] == '\r')
- --np;
- for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
- if (np[-1] == 0)
- return np;
- if (*np != '#')
- return p;
- }
- }
- char *
- skipspace(p, dir)
- char *p;
- int dir;
- {
- for ( ; ; ) {
- while ( is_space(*p) )
- p += dir;
- if ( !(*p == '/' && p[dir] == '*') )
- break;
- p += dir; p += dir;
- while ( !(*p == '*' && p[dir] == '/') ) {
- if ( *p == 0 )
- return p;
- p += dir;
- }
- p += dir; p += dir;
- }
- return p;
- }
- char *
- scanstring(p, dir)
- char *p;
- int dir;
- {
- for (p += dir; ; p += dir)
- if (*p == '"' && p[-dir] != '\\')
- return p + dir;
- }
- int
- writeblanks(start, end)
- char *start;
- char *end;
- { char *p;
- for ( p = start; p < end; p++ )
- if ( *p != '\r' && *p != '\n' )
- *p = ' ';
- return 0;
- }
- int
- test1(buf)
- char *buf;
- { char *p = buf;
- char *bend;
- char *endfn;
- int contin;
- if ( !isidfirstchar(*p) )
- return 0;
- bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
- switch ( *bend )
- {
- case ';': contin = 0 ; break;
- case ')': contin = 1; break;
- case '{': return 0;
- case '}': return 0;
- default: contin = -1;
- }
- while ( isidchar(*p) )
- p++;
- endfn = p;
- p = skipspace(p, 1);
- if ( *p++ != '(' )
- return 0;
- p = skipspace(p, 1);
- if ( *p == ')' )
- return 0;
-
-
-
- { static char *words[] =
- { "asm", "auto", "case", "char", "const", "double",
- "extern", "float", "for", "if", "int", "long",
- "register", "return", "short", "signed", "sizeof",
- "static", "switch", "typedef", "unsigned",
- "void", "volatile", "while", 0
- };
- char **key = words;
- char *kp;
- unsigned len = endfn - buf;
- while ( (kp = *key) != 0 )
- { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
- return 0;
- key++;
- }
- }
- {
- char *id = p;
- int len;
-
- while ( isidchar(*p) )
- p++;
- len = p - id;
- p = skipspace(p, 1);
- if (*p == ',' ||
- (*p == ')' && (len != 4 || strncmp(id, "void", 4)))
- )
- return 0;
- }
-
- if (contin > 0) {
- int level = 0;
- for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
- level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
- if (level > 0)
- contin = -1;
- }
- return contin;
- }
- int
- convert1(buf, out, header, convert_varargs)
- char *buf;
- FILE *out;
- int header;
- int convert_varargs;
- { char *endfn;
- char *p;
-
- char **breaks;
- unsigned num_breaks = 2;
- char **btop;
- char **bp;
- char **ap;
- char *vararg = 0;
-
-
- for ( endfn = buf; *(endfn++) != '('; )
- ;
- top: p = endfn;
- breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
- if ( breaks == NULL )
- {
- fprintf(stderr, "Unable to allocate break table!\n");
- fputs(buf, out);
- return -1;
- }
- btop = breaks + num_breaks * 2 - 2;
- bp = breaks;
-
- do
- { int level = 0;
- char *lp = NULL;
- char *rp = NULL;
- char *end = NULL;
- if ( bp >= btop )
- {
-
- free((char *)breaks);
- num_breaks <<= 1;
- goto top;
- }
- *bp++ = p;
-
- for ( ; end == NULL; p++ )
- { switch(*p)
- {
- case ',':
- if ( !level ) end = p;
- break;
- case '(':
- if ( !level ) lp = p;
- level++;
- break;
- case ')':
- if ( --level < 0 ) end = p;
- else rp = p;
- break;
- case '/':
- if (p[1] == '*')
- p = skipspace(p, 1) - 1;
- break;
- case '"':
- p = scanstring(p, 1) - 1;
- break;
- default:
- ;
- }
- }
-
- if ( lp && rp )
- writeblanks(lp + 1, rp);
- p--;
-
-
-
- for ( ; ; )
- { p = skipspace(p - 1, -1);
- switch ( *p )
- {
- case ']':
- case ')':
- { int level = 1;
- while ( level )
- switch ( *--p )
- {
- case ']': case ')':
- level++;
- break;
- case '[': case '(':
- level--;
- break;
- case '/':
- if (p > buf && p[-1] == '*')
- p = skipspace(p, -1) + 1;
- break;
- case '"':
- p = scanstring(p, -1) + 1;
- break;
- default: ;
- }
- }
- if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
- {
- while ( !isidfirstchar(*p) )
- p = skipspace(p, 1) + 1;
- goto found;
- }
- break;
- default:
- goto found;
- }
- }
- found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
- { if ( convert_varargs )
- { *bp++ = "va_alist";
- vararg = p-2;
- }
- else
- { p++;
- if ( bp == breaks + 1 )
- writeblanks(breaks[0], p);
- else
- writeblanks(bp[-1] - 1, p);
- bp--;
- }
- }
- else
- { while ( isidchar(*p) ) p--;
- *bp++ = p+1;
- }
- p = end;
- }
- while ( *p++ == ',' );
- *bp = p;
-
- if ( bp == breaks+2 )
- { p = skipspace(breaks[0], 1);
- if ( !strncmp(p, "void", 4) )
- { p = skipspace(p+4, 1);
- if ( p == breaks[2] - 1 )
- { bp = breaks;
- writeblanks(breaks[0], p + 1);
- }
- }
- }
-
- p = buf;
- while ( p != endfn ) putc(*p, out), p++;
-
- if ( header )
- { fputs(");", out);
- for ( p = breaks[0]; *p; p++ )
- if ( *p == '\r' || *p == '\n' )
- putc(*p, out);
- }
- else
- { for ( ap = breaks+1; ap < bp; ap += 2 )
- { p = *ap;
- while ( isidchar(*p) )
- putc(*p, out), p++;
- if ( ap < bp - 1 )
- fputs(", ", out);
- }
- fputs(") ", out);
-
- for ( ap = breaks+2; ap <= bp; ap += 2 )
- (*ap)[-1] = ';';
- if ( vararg != 0 )
- { *vararg = 0;
- fputs(breaks[0], out);
- fputs("va_dcl", out);
- fputs(bp[0], out);
- }
- else
- fputs(breaks[0], out);
- }
- free((char *)breaks);
- return 0;
- }
|