1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Update ansi2knr.c and ansi2knr.1.

Update log.c to use `...' in function definition argument lists
unconditionally.
This commit is contained in:
hniksic 2003-10-04 03:34:10 -07:00
parent 57de5c1967
commit 98b7ac79f3
4 changed files with 243 additions and 120 deletions

View File

@ -1,19 +1,36 @@
.TH ANSI2KNR 1 "31 December 1990" .TH ANSI2KNR 1 "19 Jan 1996"
.SH NAME .SH NAME
ansi2knr \- convert ANSI C to Kernighan & Ritchie C ansi2knr \- convert ANSI C to Kernighan & Ritchie C
.SH SYNOPSIS .SH SYNOPSIS
.I ansi2knr .I ansi2knr
input_file output_file [--varargs] input_file [output_file]
.SH DESCRIPTION .SH DESCRIPTION
If no output_file is supplied, output goes to stdout. If no output_file is supplied, output goes to stdout.
.br .br
There are no error messages. There are no error messages.
.sp .sp
.I ansi2knr .I ansi2knr
recognizes functions 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 if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line. 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, 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.
.sp .sp
The following constructs will confuse it: The following constructs will confuse it:
.br .br
- Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call). - Any other construct that starts at the left margin and follows the
above syntax (such as a macro or function call).
.br .br
- Macros that tinker with the syntax of the function header. - Some macros that tinker with the syntax of the function header.
.sp
The --varargs switch is obsolete, and is recognized only for
backwards compatibility. The present version of
.I ansi2knr
will always attempt to convert a ... argument to va_alist and va_dcl.
.SH AUTHOR
L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
continues to maintain the current version; most of the code in the current
version is his work. ansi2knr also includes contributions by Francois
Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.

View File

@ -1,3 +1,9 @@
2003-10-04 Hrvoje Niksic <hniksic@xemacs.org>
* log.c: Use `...' in function definitions; ansi2knr will convert
them to va_dcl. This allowed removal of the ugly VA_START_1 and
VA_START_2 macros.
2003-10-03 Gisle Vanem <giva@bgnett.no> 2003-10-03 Gisle Vanem <giva@bgnett.no>
* connect.c: And don't include them here. * connect.c: And don't include them here.

View File

@ -1,4 +1,6 @@
/* ansi2knr.c */ /* Copyright (C) 1989, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. */
/*$Id: ansi2knr.c 1002 2003-10-04 10:34:10Z hniksic $*/
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */ /* Convert ANSI C function definitions to K&R ("traditional C") syntax */
/* /*
@ -11,9 +13,10 @@ License (the "GPL") for full details.
Everyone is granted permission to copy, modify and redistribute ansi2knr, Everyone is granted permission to copy, modify and redistribute ansi2knr,
but only under the conditions described in the GPL. A copy of this license but only under the conditions described in the GPL. A copy of this license
is supposed to have been given to you along with ansi2knr so you can know is supposed to have been given to you along with ansi2knr so you can know
your rights and responsibilities. It should be in a file named COPYLEFT. your rights and responsibilities. It should be in a file named COPYLEFT,
Among other things, the copyright notice and this notice must be preserved or, if there is no file named COPYLEFT, a file named COPYING. Among other
on all copies. things, the copyright notice and this notice must be preserved on all
copies.
We explicitly state here what we believe is already implied by the GPL: if We explicitly state here what we believe is already implied by the GPL: if
the ansi2knr program is distributed as a separate set of sources and a the ansi2knr program is distributed as a separate set of sources and a
@ -26,7 +29,10 @@ program under the GPL.
/* /*
* Usage: * Usage:
ansi2knr input_file [output_file] ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
* --filename provides the file name for the #line directive in the output,
* overriding input_file (if present).
* If no input_file is supplied, input is read from stdin.
* If no output_file is supplied, output goes to stdout. * If no output_file is supplied, output goes to stdout.
* There are no error messages. * There are no error messages.
* *
@ -34,45 +40,71 @@ program under the GPL.
* identifier at the left margin, followed by a left parenthesis, * identifier at the left margin, followed by a left parenthesis,
* with a right parenthesis as the last character on the line, * with a right parenthesis as the last character on the line,
* and with a left brace as the first token on the following line * and with a left brace as the first token on the following line
* (ignoring possible intervening comments). * (ignoring possible intervening comments), except that a line
* It will recognize a multi-line header provided that no intervening * consisting of only
* line ends with a left or right brace or a semicolon. * identifier1(identifier2)
* will not be considered a function definition unless identifier2 is
* the word "void", and a line consisting of
* identifier1(identifier2, <<arbitrary>>)
* will not be considered a function definition.
* ansi2knr 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 * These algorithms ignore whitespace and comments, 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 constructs will confuse it: * The following 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 the function header. * - Some macros that tinker with the syntax of function headers.
*/ */
/* /*
* 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 96-01-21 added code to cope with not HAVE_CONFIG_H and with lpd 1999-04-12 added minor fixes from Pavel Roskin
<pavel_roskin@geocities.com> for clean compilation with
gcc -W -Wall
lpd 1999-03-22 added hack to recognize lines consisting of
identifier1(identifier2, xxx) as *not* being procedures
lpd 1999-02-03 made indentation of preprocessor commands consistent
lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
endless loop; quoted strings within an argument list
confused the parser
lpd 1999-01-24 added a check for write errors on the output,
suggested by Jim Meyering <meyering@ascend.com>
lpd 1998-11-09 added further hack to recognize identifier(void)
as being a procedure
lpd 1998-10-23 added hack to recognize lines consisting of
identifier1(identifier2) as *not* being procedures
lpd 1997-12-08 made input_file optional; only closes input and/or
output file if not stdin or stdout respectively; prints
usage message on stderr rather than stdout; adds
--filename switch (changes suggested by
<ceder@lysator.liu.se>)
lpd 1996-01-21 added code to cope with not HAVE_CONFIG_H and with
compilers that don't understand void, as suggested by compilers that don't understand void, as suggested by
Tom Lane Tom Lane
lpd 96-01-15 changed to require that the first non-comment token lpd 1996-01-15 changed to require that the first non-comment token
on the line following a function header be a left brace, on the line following a function header be a left brace,
to reduce sensitivity to macros, as suggested by Tom Lane to reduce sensitivity to macros, as suggested by Tom Lane
<tgl@sss.pgh.pa.us> <tgl@sss.pgh.pa.us>
lpd 95-06-22 removed #ifndefs whose sole purpose was to define lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
undefined preprocessor symbols as 0; changed all #ifdefs undefined preprocessor symbols as 0; changed all #ifdefs
for configuration symbols to #ifs for configuration symbols to #ifs
lpd 95-04-05 changed copyright notice to make it clear that lpd 1995-04-05 changed copyright notice to make it clear that
including ansi2knr in a program does not bring the entire including ansi2knr in a program does not bring the entire
program under the GPL program under the GPL
lpd 94-12-18 added conditionals for systems where ctype macros lpd 1994-12-18 added conditionals for systems where ctype macros
don't handle 8-bit characters properly, suggested by don't handle 8-bit characters properly, suggested by
Francois Pinard <pinard@iro.umontreal.ca>; Francois Pinard <pinard@iro.umontreal.ca>;
removed --varargs switch (this is now the default) removed --varargs switch (this is now the default)
lpd 94-10-10 removed CONFIG_BROKETS conditional lpd 1994-10-10 removed CONFIG_BROKETS conditional
lpd 94-07-16 added some conditionals to help GNU `configure', lpd 1994-07-16 added some conditionals to help GNU `configure',
suggested by Francois Pinard <pinard@iro.umontreal.ca>; suggested by Francois Pinard <pinard@iro.umontreal.ca>;
properly erase prototype args in function parameters, properly erase prototype args in function parameters,
contributed by Jim Avera <jima@netcom.com>; contributed by Jim Avera <jima@netcom.com>;
correct error in writeblanks (it shouldn't erase EOLs) correct error in writeblanks (it shouldn't erase EOLs)
lpd 89-xx-xx original version lpd 1989-xx-xx original version
*/ */
/* Most of the conditionals here are to make ansi2knr work with */ /* Most of the conditionals here are to make ansi2knr work with */
@ -135,19 +167,24 @@ program under the GPL.
#endif #endif
/* Define NULL (for *very* old compilers). */
#ifndef NULL
# define NULL (0)
#endif
/* /*
* The ctype macros don't always handle 8-bit characters correctly. * The ctype macros don't always handle 8-bit characters correctly.
* Compensate for this here. * Compensate for this here.
*/ */
#ifdef isascii #ifdef isascii
# undef HAVE_ISASCII /* just in case */ # undef HAVE_ISASCII /* just in case */
# define HAVE_ISASCII 1 # define HAVE_ISASCII 1
#else #else
#endif #endif
#if STDC_HEADERS || !HAVE_ISASCII #if STDC_HEADERS || !HAVE_ISASCII
# define is_ascii(c) 1 # define is_ascii(c) 1
#else #else
# define is_ascii(c) isascii(c) # define is_ascii(c) isascii(c)
#endif #endif
#define is_space(c) (is_ascii(c) && isspace(c)) #define is_space(c) (is_ascii(c) && isspace(c))
@ -160,6 +197,7 @@ program under the GPL.
/* Forward references */ /* Forward references */
char *skipspace(); char *skipspace();
char *scanstring();
int writeblanks(); int writeblanks();
int test1(); int test1();
int convert1(); int convert1();
@ -169,11 +207,17 @@ int
main(argc, argv) main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{ FILE *in, *out; { FILE *in = stdin;
FILE *out = stdout;
char *filename = 0;
char *program_name = argv[0];
char *output_name = 0;
#define bufsize 5000 /* arbitrary size */ #define bufsize 5000 /* arbitrary size */
char *buf; char *buf;
char *line; char *line;
char *more; char *more;
char *usage =
"Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
/* /*
* In previous versions, ansi2knr recognized a --varargs switch. * In previous versions, ansi2knr recognized a --varargs switch.
* If this switch was supplied, ansi2knr would attempt to convert * If this switch was supplied, ansi2knr would attempt to convert
@ -183,44 +227,61 @@ main(argc, argv)
* check for this switch for backward compatibility. * check for this switch for backward compatibility.
*/ */
int convert_varargs = 1; int convert_varargs = 1;
int output_error;
if ( argc > 1 && argv[1][0] == '-' ) while ( argc > 1 && argv[1][0] == '-' ) {
{ if ( !strcmp(argv[1], "--varargs") ) if ( !strcmp(argv[1], "--varargs") ) {
{ convert_varargs = 1; convert_varargs = 1;
argc--; argc--;
argv++; argv++;
} continue;
else
{ fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
exit(1);
}
} }
if (argc < 2 || argc > 3) 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 )
{ {
printf("Usage: ansi2knr input_file [output_file]\n"); default:
exit(1); fprintf(stderr, usage);
} exit(0);
in = fopen(argv[1], "r"); case 3:
if ( in == NULL ) output_name = argv[2];
{ out = fopen(output_name, "w");
fprintf(stderr, "Cannot open input file %s\n", argv[1]); if ( out == NULL ) {
fprintf(stderr, "%s: Cannot open output file %s\n",
program_name, output_name);
exit(1);
}
/* falls through */
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];
/* falls through */
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); exit(1);
} }
if (argc == 3)
{
out = fopen(argv[2], "w");
if ( out == NULL )
{
fprintf(stderr, "Cannot open output file %s\n", argv[2]);
exit(1);
}
}
else
{
out = stdout;
}
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
buf = malloc(bufsize);
line = buf; line = buf;
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
{ {
@ -271,12 +332,24 @@ wl: fputs(buf, out);
if ( line != buf ) if ( line != buf )
fputs(buf, out); fputs(buf, out);
free(buf); free(buf);
fclose(out); if ( output_name ) {
fclose(in); output_error = ferror(out);
output_error |= fclose(out);
} else { /* out == stdout */
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; return 0;
} }
/* Skip over space and comments, in either direction. */ /* Skip over whitespace and comments, in either direction. */
char * char *
skipspace(p, dir) skipspace(p, dir)
register char *p; register char *p;
@ -297,6 +370,17 @@ skipspace(p, dir)
return p; return p;
} }
/* Scan over a quoted string, in either direction. */
char *
scanstring(p, dir)
register char *p;
register int dir;
{
for (p += dir; ; p += dir)
if (*p == '"' && p[-dir] != '\\')
return p + dir;
}
/* /*
* Write blanks over part of a string. * Write blanks over part of a string.
* Don't overwrite end-of-line characters. * Don't overwrite end-of-line characters.
@ -365,7 +449,7 @@ test1(buf)
}; };
char **key = words; char **key = words;
char *kp; char *kp;
int len = endfn - buf; unsigned len = endfn - buf;
while ( (kp = *key) != 0 ) while ( (kp = *key) != 0 )
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) ) { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
@ -373,6 +457,36 @@ test1(buf)
key++; key++;
} }
} }
{
char *id = p;
int len;
/*
* Check for identifier1(identifier2) and not
* identifier1(void), or identifier1(identifier2, xxxx).
*/
while ( isidchar(*p) )
p++;
len = p - id;
p = skipspace(p, 1);
if (*p == ',' ||
(*p == ')' && (len != 4 || strncmp(id, "void", 4)))
)
return 0; /* not a function */
}
/*
* If the last significant character was a ), we need to count
* parentheses, because it might be part of a formal parameter
* that is a procedure.
*/
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; return contin;
} }
@ -402,7 +516,7 @@ convert1(buf, out, header, convert_varargs)
; ;
top: p = endfn; top: p = endfn;
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
if ( breaks == 0 ) if ( breaks == NULL )
{ /* Couldn't allocate break table, give up */ { /* Couldn't allocate break table, give up */
fprintf(stderr, "Unable to allocate break table!\n"); fprintf(stderr, "Unable to allocate break table!\n");
fputs(buf, out); fputs(buf, out);
@ -414,7 +528,7 @@ top: p = endfn;
do do
{ int level = 0; { int level = 0;
char *lp = NULL; char *lp = NULL;
char *rp; char *rp = NULL;
char *end = NULL; char *end = NULL;
if ( bp >= btop ) if ( bp >= btop )
@ -441,14 +555,18 @@ top: p = endfn;
else rp = p; else rp = p;
break; break;
case '/': case '/':
p = skipspace(p, 1) - 1; if (p[1] == '*')
p = skipspace(p, 1) - 1;
break; break;
case '"':
p = scanstring(p, 1) - 1;
break;
default: default:
; ;
} }
} }
/* Erase any embedded prototype parameters. */ /* Erase any embedded prototype parameters. */
if ( lp ) if ( lp && rp )
writeblanks(lp + 1, rp); writeblanks(lp + 1, rp);
p--; /* back up over terminator */ p--; /* back up over terminator */
/* Find the name being declared. */ /* Find the name being declared. */
@ -464,9 +582,19 @@ top: p = endfn;
while ( level ) while ( level )
switch ( *--p ) switch ( *--p )
{ {
case ']': case ')': level++; break; case ']': case ')':
case '[': case '(': level--; break; level++;
case '/': p = skipspace(p, -1) + 1; break; 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: ; default: ;
} }
} }

View File

@ -390,10 +390,10 @@ logvprintf (struct logvprintf_state *state, const char *fmt, va_list args)
/* vsnprintf() will not step over the limit given by available_size. /* vsnprintf() will not step over the limit given by available_size.
If it fails, it will return either -1 (POSIX?) or the number of If it fails, it will return either -1 (POSIX?) or the number of
characters that *would have* been written, if there had been characters that *would have* been written, if there had been
enough room. In the former case, we double the available_size enough room (C99). In the former case, we double the
and malloc() to get a larger buffer, and try again. In the available_size and malloc to get a larger buffer, and try again.
latter case, we use the returned information to build a buffer of In the latter case, we use the returned information to build a
the correct size. */ buffer of the correct size. */
if (numwritten == -1) if (numwritten == -1)
{ {
@ -473,46 +473,27 @@ log_set_save_context (int savep)
return old; return old;
} }
#ifdef WGET_USE_STDARG /* Handle difference in va_start between pre-ANSI and ANSI C. Note
# define VA_START_1(arg1_type, arg1, args) va_start(args, arg1) that we always use `...' in function definitions and let ansi2knr
# define VA_START_2(arg1_type, arg1, arg2_type, arg2, args) va_start(args, arg2) convert it for us. */
#else /* not WGET_USE_STDARG */
# define VA_START_1(arg1_type, arg1, args) do { \
va_start (args); \
arg1 = va_arg (args, arg1_type); \
} while (0)
# define VA_START_2(arg1_type, arg1, arg2_type, arg2, args) do { \
va_start (args); \
arg1 = va_arg (args, arg1_type); \
arg2 = va_arg (args, arg2_type); \
} while (0)
#endif /* not WGET_USE_STDARG */
/* Portability with pre-ANSI compilers makes these two functions look
like @#%#@$@#$. */
#ifdef WGET_USE_STDARG #ifdef WGET_USE_STDARG
# define VA_START(args, arg1) va_start (args, arg1)
#else
# define VA_START(args, ignored) va_start (args)
#endif
/* Print a message to the screen or to the log. The first argument
defines the verbosity of the message, and the rest are as in
printf(3). */
void void
logprintf (enum log_options o, const char *fmt, ...) logprintf (enum log_options o, const char *fmt, ...)
#else /* not WGET_USE_STDARG */
void
logprintf (va_alist)
va_dcl
#endif /* not WGET_USE_STDARG */
{ {
va_list args; va_list args;
struct logvprintf_state lpstate; struct logvprintf_state lpstate;
int done; int done;
#ifndef WGET_USE_STDARG
enum log_options o;
const char *fmt;
/* Perform a "dry run" of VA_START_2 to get the value of O. */
VA_START_2 (enum log_options, o, char *, fmt, args);
va_end (args);
#endif
check_redirect_output (); check_redirect_output ();
if (inhibit_logging) if (inhibit_logging)
return; return;
@ -521,7 +502,7 @@ logprintf (va_alist)
memset (&lpstate, '\0', sizeof (lpstate)); memset (&lpstate, '\0', sizeof (lpstate));
do do
{ {
VA_START_2 (enum log_options, o, char *, fmt, args); VA_START (args, fmt);
done = logvprintf (&lpstate, fmt, args); done = logvprintf (&lpstate, fmt, args);
va_end (args); va_end (args);
} }
@ -531,21 +512,12 @@ logprintf (va_alist)
#ifdef DEBUG #ifdef DEBUG
/* The same as logprintf(), but does anything only if opt.debug is /* The same as logprintf(), but does anything only if opt.debug is
non-zero. */ non-zero. */
#ifdef WGET_USE_STDARG
void void
debug_logprintf (const char *fmt, ...) debug_logprintf (const char *fmt, ...)
#else /* not WGET_USE_STDARG */
void
debug_logprintf (va_alist)
va_dcl
#endif /* not WGET_USE_STDARG */
{ {
if (opt.debug) if (opt.debug)
{ {
va_list args; va_list args;
#ifndef WGET_USE_STDARG
const char *fmt;
#endif
struct logvprintf_state lpstate; struct logvprintf_state lpstate;
int done; int done;
@ -556,7 +528,7 @@ debug_logprintf (va_alist)
memset (&lpstate, '\0', sizeof (lpstate)); memset (&lpstate, '\0', sizeof (lpstate));
do do
{ {
VA_START_1 (char *, fmt, args); VA_START (args, fmt);
done = logvprintf (&lpstate, fmt, args); done = logvprintf (&lpstate, fmt, args);
va_end (args); va_end (args);
} }
@ -590,9 +562,9 @@ log_init (const char *file, int appendp)
logfp = stderr; logfp = stderr;
/* If the output is a TTY, enable storing, which will make Wget /* If the output is a TTY, enable storing, which will make Wget
remember all the printed messages, to be able to dump them to remember the last several printed messages, to be able to
a log file in case SIGHUP or SIGUSR1 is received (or dump them to a log file in case SIGHUP or SIGUSR1 is received
Ctrl+Break is pressed under Windows). */ (or Ctrl+Break is pressed under Windows). */
if (1 if (1
#ifdef HAVE_ISATTY #ifdef HAVE_ISATTY
&& isatty (fileno (logfp)) && isatty (fileno (logfp))