| version 1.1.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. |