diff options
author | Jim Meyering <jim@meyering.net> | 1997-05-29 13:19:34 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 1997-05-29 13:19:34 +0000 |
commit | 4377246ee3bd9c623dcfcea44f6e9af98797df57 (patch) | |
tree | 51eb5c8978cf2880000bdb4c18df0d5333bb0360 /src | |
parent | 6edc738156c31bc7dfdb1d7f92162a73df117cd3 (diff) | |
download | coreutils-4377246ee3bd9c623dcfcea44f6e9af98797df57.tar.xz |
update from automake-1.1p
Diffstat (limited to 'src')
-rw-r--r-- | src/ansi2knr.c | 175 |
1 files changed, 120 insertions, 55 deletions
diff --git a/src/ansi2knr.c b/src/ansi2knr.c index 72519f01d..64a4578a2 100644 --- a/src/ansi2knr.c +++ b/src/ansi2knr.c @@ -1,5 +1,3 @@ -/* Copyright (C) 1989, 1991, 1993, 1994, 1995 Aladdin Enterprises. All rights reserved. */ - /* ansi2knr.c */ /* Convert ANSI C function definitions to K&R ("traditional C") syntax */ @@ -34,22 +32,30 @@ program under the GPL. * * ansi2knr recognizes function definitions by seeing a non-keyword * identifier at the left margin, followed by a left parenthesis, - * with a right parenthesis as the last character on the line. - * It will recognize a multi-line header provided that the last character - * of the last line of the header is a right parenthesis, - * and no intervening line ends with a left or right brace or a semicolon. + * with a right parenthesis as the last character on the line, + * and with a left brace as the first token on the following line + * (ignoring possible intervening comments). + * It will recognize a multi-line header provided that no intervening + * line ends with a left or right brace or a semicolon. * These algorithms ignore whitespace and comments, except that * the function name must be the first thing on the line. * The following constructs will confuse it: * - Any other construct that starts at the left margin and * follows the above syntax (such as a macro or function call). - * - Macros that tinker with the syntax of the function header. + * - Some macros that tinker with the syntax of the function header. */ /* * The original and principal author of ansi2knr is L. Peter Deutsch * <ghost@aladdin.com>. Other authors are noted in the change history * that follows (in reverse chronological order): + lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with + compilers that don't understand void, as suggested by + Tom Lane + lpd 96-01-15 changed to require that the first non-comment token + on the line following a function header be a left brace, + to reduce sensitivity to macros, as suggested by Tom Lane + <tgl@sss.pgh.pa.us> lpd 95-06-22 removed #ifndefs whose sole purpose was to define undefined preprocessor symbols as 0; changed all #ifdefs for configuration symbols to #ifs @@ -70,7 +76,7 @@ program under the GPL. */ /* Most of the conditionals here are to make ansi2knr work with */ -/* the GNU configure machinery. */ +/* or without the GNU configure machinery. */ #if HAVE_CONFIG_H # include <config.h> @@ -94,12 +100,17 @@ program under the GPL. #else /* not HAVE_CONFIG_H */ -/* - Without AC_CONFIG_HEADER, merely use <string.h> as in the original - Ghostscript distribution. This loses on older BSD systems. - */ +/* Otherwise do it the hard way */ -# include <string.h> +# ifdef BSD +# include <strings.h> +# else +# ifdef VMS + extern int strlen(), strncmp(); +# else +# include <string.h> +# endif +# endif #endif /* not HAVE_CONFIG_H */ @@ -110,8 +121,18 @@ program under the GPL. malloc and free should be declared in stdlib.h, but if you've got a K&R compiler, they probably aren't. */ -char *malloc(); -void free(); +# ifdef MSDOS +# include <malloc.h> +# else +# ifdef VMS + extern char *malloc(); + extern void free(); +# else + extern char *malloc(); + extern int free(); +# endif +# endif + #endif /* @@ -119,14 +140,14 @@ void free(); * Compensate for this here. */ #ifdef isascii -# undef HAVE_ISASCII /* just in case */ -# define HAVE_ISASCII 1 +# undef HAVE_ISASCII /* just in case */ +# define HAVE_ISASCII 1 #else #endif #if STDC_HEADERS || !HAVE_ISASCII -# define is_ascii(c) 1 +# define is_ascii(c) 1 #else -# define is_ascii(c) isascii(c) +# define is_ascii(c) isascii(c) #endif #define is_space(c) (is_ascii(c) && isspace(c)) @@ -139,7 +160,7 @@ void free(); /* Forward references */ char *skipspace(); -void writeblanks(); +int writeblanks(); int test1(); int convert1(); @@ -152,6 +173,7 @@ main(argc, argv) #define bufsize 5000 /* arbitrary size */ char *buf; char *line; + char *more; /* * In previous versions, ansi2knr recognized a --varargs switch. * If this switch was supplied, ansi2knr would attempt to convert @@ -197,26 +219,53 @@ main(argc, argv) buf = malloc(bufsize); line = buf; while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) - { switch ( test1(buf) ) + { +test: line += strlen(line); + switch ( test1(buf) ) { case 2: /* a function header */ convert1(buf, out, 1, convert_varargs); break; case 1: /* a function */ - convert1(buf, out, 0, convert_varargs); + /* Check for a { at the start of the next line. */ + more = ++line; +f: if ( line >= buf + (bufsize - 1) ) /* overflow check */ + goto wl; + if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL ) + goto wl; + switch ( *skipspace(more, 1) ) + { + case '{': + /* Definitely a function header. */ + convert1(buf, out, 0, convert_varargs); + fputs(more, out); + break; + case 0: + /* The next line was blank or a comment: */ + /* keep scanning for a non-comment. */ + line += strlen(line); + goto f; + default: + /* buf isn't a function header, but */ + /* more might be. */ + fputs(buf, out); + strcpy(buf, more); + line = buf; + goto test; + } break; case -1: /* maybe the start of a function */ - line = buf + strlen(buf); if ( line != buf + (bufsize - 1) ) /* overflow check */ - continue; + continue; /* falls through */ default: /* not a function */ - fputs(buf, out); +wl: fputs(buf, out); break; } line = buf; } - if ( line != buf ) fputs(buf, out); + if ( line != buf ) + fputs(buf, out); free(buf); fclose(out); fclose(in); @@ -229,11 +278,14 @@ skipspace(p, dir) register char *p; register int dir; /* 1 for forward, -1 for backward */ { for ( ; ; ) - { while ( is_space(*p) ) p += dir; - if ( !(*p == '/' && p[dir] == '*') ) break; + { while ( is_space(*p) ) + p += dir; + if ( !(*p == '/' && p[dir] == '*') ) + break; p += dir; p += dir; while ( !(*p == '*' && p[dir] == '/') ) - { if ( *p == 0 ) return p; /* multi-line comment?? */ + { if ( *p == 0 ) + return p; /* multi-line comment?? */ p += dir; } p += dir; p += dir; @@ -245,13 +297,15 @@ skipspace(p, dir) * Write blanks over part of a string. * Don't overwrite end-of-line characters. */ -void +int writeblanks(start, end) char *start; char *end; { char *p; for ( p = start; p < end; p++ ) - if ( *p != '\r' && *p != '\n' ) *p = ' '; + if ( *p != '\r' && *p != '\n' ) + *p = ' '; + return 0; } /* @@ -274,25 +328,27 @@ test1(buf) char *bend; char *endfn; int contin; + if ( !isidfirstchar(*p) ) - return 0; /* no name at left margin */ + return 0; /* no name at left margin */ bend = skipspace(buf + strlen(buf) - 1, -1); switch ( *bend ) { - case ';': contin = 0 /*2*/; break; - case ')': contin = 1; break; - case '{': return 0; /* not a function */ - case '}': return 0; /* not a function */ - default: contin = -1; + case ';': contin = 0 /*2*/; break; + case ')': contin = 1; break; + case '{': return 0; /* not a function */ + case '}': return 0; /* not a function */ + default: contin = -1; } - while ( isidchar(*p) ) p++; + while ( isidchar(*p) ) + p++; endfn = p; p = skipspace(p, 1); if ( *p++ != '(' ) - return 0; /* not a function */ + return 0; /* not a function */ p = skipspace(p, 1); if ( *p == ')' ) - return 0; /* no parameters */ + return 0; /* no parameters */ /* Check that the apparent function name isn't a keyword. */ /* We only need to check for keywords that could be followed */ /* by a left parenthesis (which, unfortunately, is most of them). */ @@ -306,9 +362,10 @@ test1(buf) char **key = words; char *kp; int len = endfn - buf; + while ( (kp = *key) != 0 ) { if ( strlen(kp) == len && !strncmp(kp, buf, len) ) - return 0; /* name is a keyword */ + return 0; /* name is a keyword */ key++; } } @@ -324,15 +381,21 @@ convert1(buf, out, header, convert_varargs) int convert_varargs; /* Boolean */ { char *endfn; register char *p; + /* + * The breaks table contains pointers to the beginning and end + * of each argument. + */ char **breaks; unsigned num_breaks = 2; /* for testing */ char **btop; char **bp; char **ap; char *vararg = 0; + /* Pre-ANSI implementations don't agree on whether strchr */ /* is called strchr or index, so we open-code it here. */ - for ( endfn = buf; *(endfn++) != '('; ) ; + for ( endfn = buf; *(endfn++) != '('; ) + ; top: p = endfn; breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); if ( breaks == 0 ) @@ -349,6 +412,7 @@ top: p = endfn; char *lp = NULL; char *rp; char *end = NULL; + if ( bp >= btop ) { /* Filled up break table. */ /* Allocate a bigger one and start over. */ @@ -361,21 +425,21 @@ top: p = endfn; for ( ; end == NULL; p++ ) { switch(*p) { - case ',': + case ',': if ( !level ) end = p; break; - case '(': + case '(': if ( !level ) lp = p; level++; break; - case ')': + case ')': if ( --level < 0 ) end = p; else rp = p; break; - case '/': + case '/': p = skipspace(p, 1) - 1; break; - default: + default: ; } } @@ -390,26 +454,27 @@ top: p = endfn; { p = skipspace(p - 1, -1); switch ( *p ) { - case ']': /* skip array dimension(s) */ - case ')': /* skip procedure args OR name */ + case ']': /* skip array dimension(s) */ + case ')': /* skip procedure args OR name */ { int level = 1; while ( level ) switch ( *--p ) { - case ']': case ')': level++; break; - case '[': case '(': level--; break; - case '/': p = skipspace(p, -1) + 1; break; - default: ; + case ']': case ')': level++; break; + case '[': case '(': level--; break; + case '/': p = skipspace(p, -1) + 1; break; + default: ; } } if ( *p == '(' && *skipspace(p + 1, 1) == '*' ) { /* We found the name being declared */ while ( !isidfirstchar(*p) ) - p = skipspace(p, 1) + 1; + p = skipspace(p, 1) + 1; goto found; } break; - default: goto found; + default: + goto found; } } found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' ) |