[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
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
.SH SYNOPSIS
.I ansi2knr
input_file output_file
[--varargs] input_file [output_file]
.SH DESCRIPTION
If no output_file is supplied, output goes to stdout.
.br
There are no error messages.
.sp
.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
The following constructs will confuse it:
.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
- 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>
* 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 */
/*
@ -11,9 +13,10 @@ License (the "GPL") for full details.
Everyone is granted permission to copy, modify and redistribute ansi2knr,
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
your rights and responsibilities. It should be in a file named COPYLEFT.
Among other things, the copyright notice and this notice must be preserved
on all copies.
your rights and responsibilities. It should be in a file named COPYLEFT,
or, if there is no file named COPYLEFT, a file named COPYING. Among other
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
the ansi2knr program is distributed as a separate set of sources and a
@ -26,7 +29,10 @@ program under the GPL.
/*
* 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.
* There are no error messages.
*
@ -34,45 +40,71 @@ program under the GPL.
* 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.
* (ignoring possible intervening comments), except that a line
* consisting of only
* 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
* 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).
* - 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
* <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
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
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,
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
lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
undefined preprocessor symbols as 0; changed all #ifdefs
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
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
Francois Pinard <pinard@iro.umontreal.ca>;
removed --varargs switch (this is now the default)
lpd 94-10-10 removed CONFIG_BROKETS conditional
lpd 94-07-16 added some conditionals to help GNU `configure',
lpd 1994-10-10 removed CONFIG_BROKETS conditional
lpd 1994-07-16 added some conditionals to help GNU `configure',
suggested by Francois Pinard <pinard@iro.umontreal.ca>;
properly erase prototype args in function parameters,
contributed by Jim Avera <jima@netcom.com>;
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 */
@ -135,19 +167,24 @@ program under the GPL.
#endif
/* Define NULL (for *very* old compilers). */
#ifndef NULL
# define NULL (0)
#endif
/*
* The ctype macros don't always handle 8-bit characters correctly.
* 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))
@ -160,6 +197,7 @@ program under the GPL.
/* Forward references */
char *skipspace();
char *scanstring();
int writeblanks();
int test1();
int convert1();
@ -169,11 +207,17 @@ int
main(argc, argv)
int argc;
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 */
char *buf;
char *line;
char *more;
char *usage =
"Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
/*
* In previous versions, ansi2knr recognized a --varargs switch.
* If this switch was supplied, ansi2knr would attempt to convert
@ -183,44 +227,61 @@ main(argc, argv)
* check for this switch for backward compatibility.
*/
int convert_varargs = 1;
int output_error;
if ( argc > 1 && argv[1][0] == '-' )
{ if ( !strcmp(argv[1], "--varargs") )
{ convert_varargs = 1;
argc--;
argv++;
}
else
{ fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
exit(1);
}
while ( argc > 1 && argv[1][0] == '-' ) {
if ( !strcmp(argv[1], "--varargs") ) {
convert_varargs = 1;
argc--;
argv++;
continue;
}
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");
exit(1);
}
in = fopen(argv[1], "r");
if ( in == NULL )
{
fprintf(stderr, "Cannot open input file %s\n", argv[1]);
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);
}
/* 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);
}
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;
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
{
@ -271,12 +332,24 @@ wl: fputs(buf, out);
if ( line != buf )
fputs(buf, out);
free(buf);
fclose(out);
fclose(in);
if ( output_name ) {
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;
}
/* Skip over space and comments, in either direction. */
/* Skip over whitespace and comments, in either direction. */
char *
skipspace(p, dir)
register char *p;
@ -297,6 +370,17 @@ skipspace(p, dir)
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.
* Don't overwrite end-of-line characters.
@ -365,7 +449,7 @@ test1(buf)
};
char **key = words;
char *kp;
int len = endfn - buf;
unsigned len = endfn - buf;
while ( (kp = *key) != 0 )
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
@ -373,6 +457,36 @@ test1(buf)
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;
}
@ -402,7 +516,7 @@ convert1(buf, out, header, convert_varargs)
;
top: p = endfn;
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
if ( breaks == 0 )
if ( breaks == NULL )
{ /* Couldn't allocate break table, give up */
fprintf(stderr, "Unable to allocate break table!\n");
fputs(buf, out);
@ -414,7 +528,7 @@ top: p = endfn;
do
{ int level = 0;
char *lp = NULL;
char *rp;
char *rp = NULL;
char *end = NULL;
if ( bp >= btop )
@ -441,14 +555,18 @@ top: p = endfn;
else rp = p;
break;
case '/':
p = skipspace(p, 1) - 1;
if (p[1] == '*')
p = skipspace(p, 1) - 1;
break;
case '"':
p = scanstring(p, 1) - 1;
break;
default:
;
}
}
/* Erase any embedded prototype parameters. */
if ( lp )
if ( lp && rp )
writeblanks(lp + 1, rp);
p--; /* back up over terminator */
/* Find the name being declared. */
@ -464,9 +582,19 @@ top: p = endfn;
while ( level )
switch ( *--p )
{
case ']': case ')': level++; break;
case '[': case '(': level--; break;
case '/': p = skipspace(p, -1) + 1; break;
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: ;
}
}

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.
If it fails, it will return either -1 (POSIX?) or the number of
characters that *would have* been written, if there had been
enough room. In the former case, we double the available_size
and malloc() to get a larger buffer, and try again. In the
latter case, we use the returned information to build a buffer of
the correct size. */
enough room (C99). In the former case, we double the
available_size and malloc to get a larger buffer, and try again.
In the latter case, we use the returned information to build a
buffer of the correct size. */
if (numwritten == -1)
{
@ -473,46 +473,27 @@ log_set_save_context (int savep)
return old;
}
#ifdef WGET_USE_STDARG
# define VA_START_1(arg1_type, arg1, args) va_start(args, arg1)
# define VA_START_2(arg1_type, arg1, arg2_type, arg2, args) va_start(args, arg2)
#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 @#%#@$@#$. */
/* Handle difference in va_start between pre-ANSI and ANSI C. Note
that we always use `...' in function definitions and let ansi2knr
convert it for us. */
#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
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;
struct logvprintf_state lpstate;
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 ();
if (inhibit_logging)
return;
@ -521,7 +502,7 @@ logprintf (va_alist)
memset (&lpstate, '\0', sizeof (lpstate));
do
{
VA_START_2 (enum log_options, o, char *, fmt, args);
VA_START (args, fmt);
done = logvprintf (&lpstate, fmt, args);
va_end (args);
}
@ -531,21 +512,12 @@ logprintf (va_alist)
#ifdef DEBUG
/* The same as logprintf(), but does anything only if opt.debug is
non-zero. */
#ifdef WGET_USE_STDARG
void
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)
{
va_list args;
#ifndef WGET_USE_STDARG
const char *fmt;
#endif
struct logvprintf_state lpstate;
int done;
@ -556,7 +528,7 @@ debug_logprintf (va_alist)
memset (&lpstate, '\0', sizeof (lpstate));
do
{
VA_START_1 (char *, fmt, args);
VA_START (args, fmt);
done = logvprintf (&lpstate, fmt, args);
va_end (args);
}
@ -590,9 +562,9 @@ log_init (const char *file, int appendp)
logfp = stderr;
/* If the output is a TTY, enable storing, which will make Wget
remember all the printed messages, to be able to dump them to
a log file in case SIGHUP or SIGUSR1 is received (or
Ctrl+Break is pressed under Windows). */
remember the last several printed messages, to be able to
dump them to a log file in case SIGHUP or SIGUSR1 is received
(or Ctrl+Break is pressed under Windows). */
if (1
#ifdef HAVE_ISATTY
&& isatty (fileno (logfp))