version 1.1, 2000/09/09 14:12:13 |
version 1.1.1.2, 2003/08/25 16:05:56 |
|
|
/* Copyright (C) 1989, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. */ |
/* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. */ |
|
|
/*$Id$*/ |
/*$Id$*/ |
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */ |
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */ |
Line 37 program under the GPL. |
|
Line 37 program under the GPL. |
|
* There are no error messages. |
* There are no error messages. |
* |
* |
* ansi2knr recognizes function definitions by seeing a non-keyword |
* ansi2knr recognizes function definitions by seeing a non-keyword |
* identifier at the left margin, followed by a left parenthesis, |
* identifier at the left margin, followed by a left parenthesis, with a |
* with a right parenthesis as the last character on the line, |
* right parenthesis as the last character on the line, and with a left |
* and with a left brace as the first token on the following line |
* brace as the first token on the following line (ignoring possible |
* (ignoring possible intervening comments), except that a line |
* intervening comments and/or preprocessor directives), except that a line |
* consisting of only |
* consisting of only |
* identifier1(identifier2) |
* identifier1(identifier2) |
* will not be considered a function definition unless identifier2 is |
* will not be considered a function definition unless identifier2 is |
* the word "void", and a line consisting of |
* the word "void", and a line consisting of |
* identifier1(identifier2, <<arbitrary>>) |
* identifier1(identifier2, <<arbitrary>>) |
* will not be considered a function definition. |
* will not be considered a function definition. |
* ansi2knr will recognize a multi-line header provided |
* ansi2knr will recognize a multi-line header provided that no intervening |
* that no intervening line ends with a left or right brace or a semicolon. |
* line ends with a left or right brace or a semicolon. These algorithms |
* These algorithms ignore whitespace and comments, except that |
* ignore whitespace, comments, and preprocessor directives, except that |
* the function name must be the first thing on the line. |
* the function name must be the first thing on the line. The following |
* The following constructs will confuse it: |
* constructs will confuse it: |
* - Any other construct that starts at the left margin and |
* - Any other construct that starts at the left margin and |
* follows the above syntax (such as a macro or function call). |
* follows the above syntax (such as a macro or function call). |
* - Some macros that tinker with the syntax of function headers. |
* - Some macros that tinker with the syntax of function headers. |
Line 61 program under the GPL. |
|
Line 61 program under the GPL. |
|
* The original and principal author of ansi2knr is L. Peter Deutsch |
* The original and principal author of ansi2knr is L. Peter Deutsch |
* <ghost@aladdin.com>. Other authors are noted in the change history |
* <ghost@aladdin.com>. Other authors are noted in the change history |
* that follows (in reverse chronological order): |
* that follows (in reverse chronological order): |
|
|
|
lpd 2000-04-12 backs out Eggert's changes because of bugs: |
|
- concatlits didn't declare the type of its bufend argument; |
|
- concatlits didn't't recognize when it was inside a comment; |
|
- scanstring could scan backward past the beginning of the string; when |
|
- the check for \ + newline in scanstring was unnecessary. |
|
|
|
2000-03-05 Paul Eggert <eggert@twinsun.com> |
|
|
|
Add support for concatenated string literals. |
|
* ansi2knr.c (concatlits): New decl. |
|
(main): Invoke concatlits to concatenate string literals. |
|
(scanstring): Handle backslash-newline correctly. Work with |
|
character constants. Fix bug when scanning backwards through |
|
backslash-quote. Check for unterminated strings. |
|
(convert1): Parse character constants, too. |
|
(appendline, concatlits): New functions. |
|
* ansi2knr.1: Document this. |
|
|
|
lpd 1999-08-17 added code to allow preprocessor directives |
|
wherever comments are allowed |
lpd 1999-04-12 added minor fixes from Pavel Roskin |
lpd 1999-04-12 added minor fixes from Pavel Roskin |
<pavel_roskin@geocities.com> for clean compilation with |
<pavel_roskin@geocities.com> for clean compilation with |
gcc -W -Wall |
gcc -W -Wall |
Line 196 program under the GPL. |
|
Line 217 program under the GPL. |
|
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_') |
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_') |
|
|
/* Forward references */ |
/* Forward references */ |
|
char *ppdirforward(); |
|
char *ppdirbackward(); |
char *skipspace(); |
char *skipspace(); |
char *scanstring(); |
char *scanstring(); |
int writeblanks(); |
int writeblanks(); |
Line 298 f: if ( line >= buf + (bufsize - 1) ) /* overflow ch |
|
Line 321 f: if ( line >= buf + (bufsize - 1) ) /* overflow ch |
|
goto wl; |
goto wl; |
if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL ) |
if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL ) |
goto wl; |
goto wl; |
switch ( *skipspace(more, 1) ) |
switch ( *skipspace(ppdirforward(more), 1) ) |
{ |
{ |
case '{': |
case '{': |
/* Definitely a function header. */ |
/* Definitely a function header. */ |
Line 349 wl: fputs(buf, out); |
|
Line 372 wl: fputs(buf, out); |
|
return 0; |
return 0; |
} |
} |
|
|
/* Skip over whitespace and comments, in either direction. */ |
/* |
|
* Skip forward or backward over one or more preprocessor directives. |
|
*/ |
char * |
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; |
|
} |
|
} |
|
|
|
/* |
|
* Skip over whitespace, comments, and preprocessor directives, |
|
* in either direction. |
|
*/ |
|
char * |
skipspace(p, dir) |
skipspace(p, dir) |
register char *p; |
char *p; |
register int dir; /* 1 for forward, -1 for backward */ |
int dir; /* 1 for forward, -1 for backward */ |
{ for ( ; ; ) |
{ |
{ while ( is_space(*p) ) |
for ( ; ; ) { |
p += dir; |
while ( is_space(*p) ) |
if ( !(*p == '/' && p[dir] == '*') ) |
p += dir; |
break; |
if ( !(*p == '/' && p[dir] == '*') ) |
p += dir; p += dir; |
break; |
while ( !(*p == '*' && p[dir] == '/') ) |
p += dir; p += dir; |
{ if ( *p == 0 ) |
while ( !(*p == '*' && p[dir] == '/') ) { |
return p; /* multi-line comment?? */ |
if ( *p == 0 ) |
p += dir; |
return p; /* multi-line comment?? */ |
} |
p += dir; |
p += dir; p += dir; |
} |
} |
p += dir; p += dir; |
return p; |
} |
|
return p; |
} |
} |
|
|
/* Scan over a quoted string, in either direction. */ |
/* Scan over a quoted string, in either direction. */ |
char * |
char * |
scanstring(p, dir) |
scanstring(p, dir) |
register char *p; |
char *p; |
register int dir; |
int dir; |
{ |
{ |
for (p += dir; ; p += dir) |
for (p += dir; ; p += dir) |
if (*p == '"' && p[-dir] != '\\') |
if (*p == '"' && p[-dir] != '\\') |
Line 412 writeblanks(start, end) |
|
Line 473 writeblanks(start, end) |
|
int |
int |
test1(buf) |
test1(buf) |
char *buf; |
char *buf; |
{ register char *p = buf; |
{ char *p = buf; |
char *bend; |
char *bend; |
char *endfn; |
char *endfn; |
int contin; |
int contin; |
|
|
if ( !isidfirstchar(*p) ) |
if ( !isidfirstchar(*p) ) |
return 0; /* no name at left margin */ |
return 0; /* no name at left margin */ |
bend = skipspace(buf + strlen(buf) - 1, -1); |
bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1); |
switch ( *bend ) |
switch ( *bend ) |
{ |
{ |
case ';': contin = 0 /*2*/; break; |
case ';': contin = 0 /*2*/; break; |
Line 498 convert1(buf, out, header, convert_varargs) |
|
Line 559 convert1(buf, out, header, convert_varargs) |
|
int header; /* Boolean */ |
int header; /* Boolean */ |
int convert_varargs; /* Boolean */ |
int convert_varargs; /* Boolean */ |
{ char *endfn; |
{ char *endfn; |
register char *p; |
char *p; |
/* |
/* |
* The breaks table contains pointers to the beginning and end |
* The breaks table contains pointers to the beginning and end |
* of each argument. |
* of each argument. |