Blame gtkmm-osx/jpeg-6b/ansi2knr.c

darco 56a656
/* ansi2knr.c */
darco 56a656
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
darco 56a656
darco 56a656
/*
darco 56a656
ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
darco 56a656
WARRANTY.  No author or distributor accepts responsibility to anyone for the
darco 56a656
consequences of using it or for whether it serves any particular purpose or
darco 56a656
works at all, unless he says so in writing.  Refer to the GNU General Public
darco 56a656
License (the "GPL") for full details.
darco 56a656
darco 56a656
Everyone is granted permission to copy, modify and redistribute ansi2knr,
darco 56a656
but only under the conditions described in the GPL.  A copy of this license
darco 56a656
is supposed to have been given to you along with ansi2knr so you can know
darco 56a656
your rights and responsibilities.  It should be in a file named COPYLEFT.
darco 56a656
[In the IJG distribution, the GPL appears below, not in a separate file.]
darco 56a656
Among other things, the copyright notice and this notice must be preserved
darco 56a656
on all copies.
darco 56a656
darco 56a656
We explicitly state here what we believe is already implied by the GPL: if
darco 56a656
the ansi2knr program is distributed as a separate set of sources and a
darco 56a656
separate executable file which are aggregated on a storage medium together
darco 56a656
with another program, this in itself does not bring the other program under
darco 56a656
the GPL, nor does the mere fact that such a program or the procedures for
darco 56a656
constructing it invoke the ansi2knr executable bring any other part of the
darco 56a656
program under the GPL.
darco 56a656
*/
darco 56a656
darco 56a656
/*
darco 56a656
---------- Here is the GNU GPL file COPYLEFT, referred to above ----------
darco 56a656
----- These terms do NOT apply to the JPEG software itself; see README ------
darco 56a656
darco 56a656
		    GHOSTSCRIPT GENERAL PUBLIC LICENSE
darco 56a656
		    (Clarified 11 Feb 1988)
darco 56a656
darco 56a656
 Copyright (C) 1988 Richard M. Stallman
darco 56a656
 Everyone is permitted to copy and distribute verbatim copies of this
darco 56a656
 license, but changing it is not allowed.  You can also use this wording
darco 56a656
 to make the terms for other programs.
darco 56a656
darco 56a656
  The license agreements of most software companies keep you at the
darco 56a656
mercy of those companies.  By contrast, our general public license is
darco 56a656
intended to give everyone the right to share Ghostscript.  To make sure
darco 56a656
that you get the rights we want you to have, we need to make
darco 56a656
restrictions that forbid anyone to deny you these rights or to ask you
darco 56a656
to surrender the rights.  Hence this license agreement.
darco 56a656
darco 56a656
  Specifically, we want to make sure that you have the right to give
darco 56a656
away copies of Ghostscript, that you receive source code or else can get
darco 56a656
it if you want it, that you can change Ghostscript or use pieces of it
darco 56a656
in new free programs, and that you know you can do these things.
darco 56a656
darco 56a656
  To make sure that everyone has such rights, we have to forbid you to
darco 56a656
deprive anyone else of these rights.  For example, if you distribute
darco 56a656
copies of Ghostscript, you must give the recipients all the rights that
darco 56a656
you have.  You must make sure that they, too, receive or can get the
darco 56a656
source code.  And you must tell them their rights.
darco 56a656
darco 56a656
  Also, for our own protection, we must make certain that everyone finds
darco 56a656
out that there is no warranty for Ghostscript.  If Ghostscript is
darco 56a656
modified by someone else and passed on, we want its recipients to know
darco 56a656
that what they have is not what we distributed, so that any problems
darco 56a656
introduced by others will not reflect on our reputation.
darco 56a656
darco 56a656
  Therefore we (Richard M. Stallman and the Free Software Foundation,
darco 56a656
Inc.) make the following terms which say what you must do to be allowed
darco 56a656
to distribute or change Ghostscript.
darco 56a656
darco 56a656
darco 56a656
			COPYING POLICIES
darco 56a656
darco 56a656
  1. You may copy and distribute verbatim copies of Ghostscript source
darco 56a656
code as you receive it, in any medium, provided that you conspicuously
darco 56a656
and appropriately publish on each copy a valid copyright and license
darco 56a656
notice "Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
darco 56a656
Distributed by Free Software Foundation, Inc." (or with whatever year is
darco 56a656
appropriate); keep intact the notices on all files that refer to this
darco 56a656
License Agreement and to the absence of any warranty; and give any other
darco 56a656
recipients of the Ghostscript program a copy of this License Agreement
darco 56a656
along with the program.  You may charge a distribution fee for the
darco 56a656
physical act of transferring a copy.
darco 56a656
darco 56a656
  2. You may modify your copy or copies of Ghostscript or any portion of
darco 56a656
it, and copy and distribute such modifications under the terms of
darco 56a656
Paragraph 1 above, provided that you also do the following:
darco 56a656
darco 56a656
    a) cause the modified files to carry prominent notices stating
darco 56a656
    that you changed the files and the date of any change; and
darco 56a656
darco 56a656
    b) cause the whole of any work that you distribute or publish,
darco 56a656
    that in whole or in part contains or is a derivative of Ghostscript
darco 56a656
    or any part thereof, to be licensed at no charge to all third
darco 56a656
    parties on terms identical to those contained in this License
darco 56a656
    Agreement (except that you may choose to grant more extensive
darco 56a656
    warranty protection to some or all third parties, at your option).
darco 56a656
darco 56a656
    c) You may charge a distribution fee for the physical act of
darco 56a656
    transferring a copy, and you may at your option offer warranty
darco 56a656
    protection in exchange for a fee.
darco 56a656
darco 56a656
Mere aggregation of another unrelated program with this program (or its
darco 56a656
derivative) on a volume of a storage or distribution medium does not bring
darco 56a656
the other program under the scope of these terms.
darco 56a656
darco 56a656
  3. You may copy and distribute Ghostscript (or a portion or derivative
darco 56a656
of it, under Paragraph 2) in object code or executable form under the
darco 56a656
terms of Paragraphs 1 and 2 above provided that you also do one of the
darco 56a656
following:
darco 56a656
darco 56a656
    a) accompany it with the complete corresponding machine-readable
darco 56a656
    source code, which must be distributed under the terms of
darco 56a656
    Paragraphs 1 and 2 above; or,
darco 56a656
darco 56a656
    b) accompany it with a written offer, valid for at least three
darco 56a656
    years, to give any third party free (except for a nominal
darco 56a656
    shipping charge) a complete machine-readable copy of the
darco 56a656
    corresponding source code, to be distributed under the terms of
darco 56a656
    Paragraphs 1 and 2 above; or,
darco 56a656
darco 56a656
    c) accompany it with the information you received as to where the
darco 56a656
    corresponding source code may be obtained.  (This alternative is
darco 56a656
    allowed only for noncommercial distribution and only if you
darco 56a656
    received the program in object code or executable form alone.)
darco 56a656
darco 56a656
For an executable file, complete source code means all the source code for
darco 56a656
all modules it contains; but, as a special exception, it need not include
darco 56a656
source code for modules which are standard libraries that accompany the
darco 56a656
operating system on which the executable file runs.
darco 56a656
darco 56a656
  4. You may not copy, sublicense, distribute or transfer Ghostscript
darco 56a656
except as expressly provided under this License Agreement.  Any attempt
darco 56a656
otherwise to copy, sublicense, distribute or transfer Ghostscript is
darco 56a656
void and your rights to use the program under this License agreement
darco 56a656
shall be automatically terminated.  However, parties who have received
darco 56a656
computer software programs from you with this License Agreement will not
darco 56a656
have their licenses terminated so long as such parties remain in full
darco 56a656
compliance.
darco 56a656
darco 56a656
  5. If you wish to incorporate parts of Ghostscript into other free
darco 56a656
programs whose distribution conditions are different, write to the Free
darco 56a656
Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not
darco 56a656
yet worked out a simple rule that can be stated here, but we will often
darco 56a656
permit this.  We will be guided by the two goals of preserving the free
darco 56a656
status of all derivatives of our free software and of promoting the
darco 56a656
sharing and reuse of software.
darco 56a656
darco 56a656
Your comments and suggestions about our licensing policies and our
darco 56a656
software are welcome!  Please contact the Free Software Foundation,
darco 56a656
Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
darco 56a656
darco 56a656
		       NO WARRANTY
darco 56a656
darco 56a656
  BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
darco 56a656
NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
darco 56a656
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
darco 56a656
M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
darco 56a656
PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
darco 56a656
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
darco 56a656
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
darco 56a656
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
darco 56a656
YOU.  SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
darco 56a656
NECESSARY SERVICING, REPAIR OR CORRECTION.
darco 56a656
darco 56a656
  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
darco 56a656
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
darco 56a656
ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
darco 56a656
GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
darco 56a656
ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
darco 56a656
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
darco 56a656
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
darco 56a656
INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
darco 56a656
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
darco 56a656
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
darco 56a656
BY ANY OTHER PARTY.
darco 56a656
darco 56a656
-------------------- End of file COPYLEFT ------------------------------
darco 56a656
*/
darco 56a656
darco 56a656
/*
darco 56a656
 * Usage:
darco 56a656
	ansi2knr input_file [output_file]
darco 56a656
 * If no output_file is supplied, output goes to stdout.
darco 56a656
 * There are no error messages.
darco 56a656
 *
darco 56a656
 * ansi2knr recognizes function definitions by seeing a non-keyword
darco 56a656
 * identifier at the left margin, followed by a left parenthesis,
darco 56a656
 * with a right parenthesis as the last character on the line,
darco 56a656
 * and with a left brace as the first token on the following line
darco 56a656
 * (ignoring possible intervening comments).
darco 56a656
 * It will recognize a multi-line header provided that no intervening
darco 56a656
 * line ends with a left or right brace or a semicolon.
darco 56a656
 * These algorithms ignore whitespace and comments, except that
darco 56a656
 * the function name must be the first thing on the line.
darco 56a656
 * The following constructs will confuse it:
darco 56a656
 *	- Any other construct that starts at the left margin and
darco 56a656
 *	    follows the above syntax (such as a macro or function call).
darco 56a656
 *	- Some macros that tinker with the syntax of the function header.
darco 56a656
 */
darco 56a656
darco 56a656
/*
darco 56a656
 * The original and principal author of ansi2knr is L. Peter Deutsch
darco 56a656
 * <ghost@aladdin.com>.  Other authors are noted in the change history</ghost@aladdin.com>
darco 56a656
 * that follows (in reverse chronological order):
darco 56a656
	lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
darco 56a656
		compilers that don't understand void, as suggested by
darco 56a656
		Tom Lane
darco 56a656
	lpd 96-01-15 changed to require that the first non-comment token
darco 56a656
		on the line following a function header be a left brace,
darco 56a656
		to reduce sensitivity to macros, as suggested by Tom Lane
darco 56a656
		<tgl@sss.pgh.pa.us></tgl@sss.pgh.pa.us>
darco 56a656
	lpd 95-06-22 removed #ifndefs whose sole purpose was to define
darco 56a656
		undefined preprocessor symbols as 0; changed all #ifdefs
darco 56a656
		for configuration symbols to #ifs
darco 56a656
	lpd 95-04-05 changed copyright notice to make it clear that
darco 56a656
		including ansi2knr in a program does not bring the entire
darco 56a656
		program under the GPL
darco 56a656
	lpd 94-12-18 added conditionals for systems where ctype macros
darco 56a656
		don't handle 8-bit characters properly, suggested by
darco 56a656
		Francois Pinard <pinard@iro.umontreal.ca>;</pinard@iro.umontreal.ca>
darco 56a656
		removed --varargs switch (this is now the default)
darco 56a656
	lpd 94-10-10 removed CONFIG_BROKETS conditional
darco 56a656
	lpd 94-07-16 added some conditionals to help GNU `configure',
darco 56a656
		suggested by Francois Pinard <pinard@iro.umontreal.ca>;</pinard@iro.umontreal.ca>
darco 56a656
		properly erase prototype args in function parameters,
darco 56a656
		contributed by Jim Avera <jima@netcom.com>;</jima@netcom.com>
darco 56a656
		correct error in writeblanks (it shouldn't erase EOLs)
darco 56a656
	lpd 89-xx-xx original version
darco 56a656
 */
darco 56a656
darco 56a656
/* Most of the conditionals here are to make ansi2knr work with */
darco 56a656
/* or without the GNU configure machinery. */
darco 56a656
darco 56a656
#if HAVE_CONFIG_H
darco 56a656
# include <config.h></config.h>
darco 56a656
#endif
darco 56a656
darco 56a656
#include <stdio.h></stdio.h>
darco 56a656
#include <ctype.h></ctype.h>
darco 56a656
darco 56a656
#if HAVE_CONFIG_H
darco 56a656
darco 56a656
/*
darco 56a656
   For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
darco 56a656
   This will define HAVE_CONFIG_H and so, activate the following lines.
darco 56a656
 */
darco 56a656
darco 56a656
# if STDC_HEADERS || HAVE_STRING_H
darco 56a656
#  include <string.h></string.h>
darco 56a656
# else
darco 56a656
#  include <strings.h></strings.h>
darco 56a656
# endif
darco 56a656
darco 56a656
#else /* not HAVE_CONFIG_H */
darco 56a656
darco 56a656
/* Otherwise do it the hard way */
darco 56a656
darco 56a656
# ifdef BSD
darco 56a656
#  include <strings.h></strings.h>
darco 56a656
# else
darco 56a656
#  ifdef VMS
darco 56a656
    extern int strlen(), strncmp();
darco 56a656
#  else
darco 56a656
#   include <string.h></string.h>
darco 56a656
#  endif
darco 56a656
# endif
darco 56a656
darco 56a656
#endif /* not HAVE_CONFIG_H */
darco 56a656
darco 56a656
#if STDC_HEADERS
darco 56a656
# include <stdlib.h></stdlib.h>
darco 56a656
#else
darco 56a656
/*
darco 56a656
   malloc and free should be declared in stdlib.h,
darco 56a656
   but if you've got a K&R compiler, they probably aren't.
darco 56a656
 */
darco 56a656
# ifdef MSDOS
darco 56a656
#  include <malloc.h></malloc.h>
darco 56a656
# else
darco 56a656
#  ifdef VMS
darco 56a656
     extern char *malloc();
darco 56a656
     extern void free();
darco 56a656
#  else
darco 56a656
     extern char *malloc();
darco 56a656
     extern int free();
darco 56a656
#  endif
darco 56a656
# endif
darco 56a656
darco 56a656
#endif
darco 56a656
darco 56a656
/*
darco 56a656
 * The ctype macros don't always handle 8-bit characters correctly.
darco 56a656
 * Compensate for this here.
darco 56a656
 */
darco 56a656
#ifdef isascii
darco 56a656
#  undef HAVE_ISASCII		/* just in case */
darco 56a656
#  define HAVE_ISASCII 1
darco 56a656
#else
darco 56a656
#endif
darco 56a656
#if STDC_HEADERS || !HAVE_ISASCII
darco 56a656
#  define is_ascii(c) 1
darco 56a656
#else
darco 56a656
#  define is_ascii(c) isascii(c)
darco 56a656
#endif
darco 56a656
darco 56a656
#define is_space(c) (is_ascii(c) && isspace(c))
darco 56a656
#define is_alpha(c) (is_ascii(c) && isalpha(c))
darco 56a656
#define is_alnum(c) (is_ascii(c) && isalnum(c))
darco 56a656
darco 56a656
/* Scanning macros */
darco 56a656
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
darco 56a656
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
darco 56a656
darco 56a656
/* Forward references */
darco 56a656
char *skipspace();
darco 56a656
int writeblanks();
darco 56a656
int test1();
darco 56a656
int convert1();
darco 56a656
darco 56a656
/* The main program */
darco 56a656
int
darco 56a656
main(argc, argv)
darco 56a656
    int argc;
darco 56a656
    char *argv[];
darco 56a656
{	FILE *in, *out;
darco 56a656
#define bufsize 5000			/* arbitrary size */
darco 56a656
	char *buf;
darco 56a656
	char *line;
darco 56a656
	char *more;
darco 56a656
	/*
darco 56a656
	 * In previous versions, ansi2knr recognized a --varargs switch.
darco 56a656
	 * If this switch was supplied, ansi2knr would attempt to convert
darco 56a656
	 * a ... argument to va_alist and va_dcl; if this switch was not
darco 56a656
	 * supplied, ansi2knr would simply drop any such arguments.
darco 56a656
	 * Now, ansi2knr always does this conversion, and we only
darco 56a656
	 * check for this switch for backward compatibility.
darco 56a656
	 */
darco 56a656
	int convert_varargs = 1;
darco 56a656
darco 56a656
	if ( argc > 1 && argv[1][0] == '-' )
darco 56a656
	  {	if ( !strcmp(argv[1], "--varargs") )
darco 56a656
		  {	convert_varargs = 1;
darco 56a656
			argc--;
darco 56a656
			argv++;
darco 56a656
		  }
darco 56a656
		else
darco 56a656
		  {	fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
darco 56a656
			exit(1);
darco 56a656
		  }
darco 56a656
	  }
darco 56a656
	switch ( argc )
darco 56a656
	   {
darco 56a656
	default:
darco 56a656
		printf("Usage: ansi2knr input_file [output_file]\n");
darco 56a656
		exit(0);
darco 56a656
	case 2:
darco 56a656
		out = stdout;
darco 56a656
		break;
darco 56a656
	case 3:
darco 56a656
		out = fopen(argv[2], "w");
darco 56a656
		if ( out == NULL )
darco 56a656
		   {	fprintf(stderr, "Cannot open output file %s\n", argv[2]);
darco 56a656
			exit(1);
darco 56a656
		   }
darco 56a656
	   }
darco 56a656
	in = fopen(argv[1], "r");
darco 56a656
	if ( in == NULL )
darco 56a656
	   {	fprintf(stderr, "Cannot open input file %s\n", argv[1]);
darco 56a656
		exit(1);
darco 56a656
	   }
darco 56a656
	fprintf(out, "#line 1 \"%s\"\n", argv[1]);
darco 56a656
	buf = malloc(bufsize);
darco 56a656
	line = buf;
darco 56a656
	while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
darco 56a656
	   {
darco 56a656
test:		line += strlen(line);
darco 56a656
		switch ( test1(buf) )
darco 56a656
		   {
darco 56a656
		case 2:			/* a function header */
darco 56a656
			convert1(buf, out, 1, convert_varargs);
darco 56a656
			break;
darco 56a656
		case 1:			/* a function */
darco 56a656
			/* Check for a { at the start of the next line. */
darco 56a656
			more = ++line;
darco 56a656
f:			if ( line >= buf + (bufsize - 1) ) /* overflow check */
darco 56a656
			  goto wl;
darco 56a656
			if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
darco 56a656
			  goto wl;
darco 56a656
			switch ( *skipspace(more, 1) )
darco 56a656
			  {
darco 56a656
			  case '{':
darco 56a656
			    /* Definitely a function header. */
darco 56a656
			    convert1(buf, out, 0, convert_varargs);
darco 56a656
			    fputs(more, out);
darco 56a656
			    break;
darco 56a656
			  case 0:
darco 56a656
			    /* The next line was blank or a comment: */
darco 56a656
			    /* keep scanning for a non-comment. */
darco 56a656
			    line += strlen(line);
darco 56a656
			    goto f;
darco 56a656
			  default:
darco 56a656
			    /* buf isn't a function header, but */
darco 56a656
			    /* more might be. */
darco 56a656
			    fputs(buf, out);
darco 56a656
			    strcpy(buf, more);
darco 56a656
			    line = buf;
darco 56a656
			    goto test;
darco 56a656
			  }
darco 56a656
			break;
darco 56a656
		case -1:		/* maybe the start of a function */
darco 56a656
			if ( line != buf + (bufsize - 1) ) /* overflow check */
darco 56a656
			  continue;
darco 56a656
			/* falls through */
darco 56a656
		default:		/* not a function */
darco 56a656
wl:			fputs(buf, out);
darco 56a656
			break;
darco 56a656
		   }
darco 56a656
		line = buf;
darco 56a656
	   }
darco 56a656
	if ( line != buf )
darco 56a656
	  fputs(buf, out);
darco 56a656
	free(buf);
darco 56a656
	fclose(out);
darco 56a656
	fclose(in);
darco 56a656
	return 0;
darco 56a656
}
darco 56a656
darco 56a656
/* Skip over space and comments, in either direction. */
darco 56a656
char *
darco 56a656
skipspace(p, dir)
darco 56a656
    register char *p;
darco 56a656
    register int dir;			/* 1 for forward, -1 for backward */
darco 56a656
{	for ( ; ; )
darco 56a656
	   {	while ( is_space(*p) )
darco 56a656
		  p += dir;
darco 56a656
		if ( !(*p == '/' && p[dir] == '*') )
darco 56a656
		  break;
darco 56a656
		p += dir;  p += dir;
darco 56a656
		while ( !(*p == '*' && p[dir] == '/') )
darco 56a656
		   {	if ( *p == 0 )
darco 56a656
			  return p;	/* multi-line comment?? */
darco 56a656
			p += dir;
darco 56a656
		   }
darco 56a656
		p += dir;  p += dir;
darco 56a656
	   }
darco 56a656
	return p;
darco 56a656
}
darco 56a656
darco 56a656
/*
darco 56a656
 * Write blanks over part of a string.
darco 56a656
 * Don't overwrite end-of-line characters.
darco 56a656
 */
darco 56a656
int
darco 56a656
writeblanks(start, end)
darco 56a656
    char *start;
darco 56a656
    char *end;
darco 56a656
{	char *p;
darco 56a656
	for ( p = start; p < end; p++ )
darco 56a656
	  if ( *p != '\r' && *p != '\n' )
darco 56a656
	    *p = ' ';
darco 56a656
	return 0;
darco 56a656
}
darco 56a656
darco 56a656
/*
darco 56a656
 * Test whether the string in buf is a function definition.
darco 56a656
 * The string may contain and/or end with a newline.
darco 56a656
 * Return as follows:
darco 56a656
 *	0 - definitely not a function definition;
darco 56a656
 *	1 - definitely a function definition;
darco 56a656
 *	2 - definitely a function prototype (NOT USED);
darco 56a656
 *	-1 - may be the beginning of a function definition,
darco 56a656
 *		append another line and look again.
darco 56a656
 * The reason we don't attempt to convert function prototypes is that
darco 56a656
 * Ghostscript's declaration-generating macros look too much like
darco 56a656
 * prototypes, and confuse the algorithms.
darco 56a656
 */
darco 56a656
int
darco 56a656
test1(buf)
darco 56a656
    char *buf;
darco 56a656
{	register char *p = buf;
darco 56a656
	char *bend;
darco 56a656
	char *endfn;
darco 56a656
	int contin;
darco 56a656
darco 56a656
	if ( !isidfirstchar(*p) )
darco 56a656
	  return 0;		/* no name at left margin */
darco 56a656
	bend = skipspace(buf + strlen(buf) - 1, -1);
darco 56a656
	switch ( *bend )
darco 56a656
	   {
darco 56a656
	   case ';': contin = 0 /*2*/; break;
darco 56a656
	   case ')': contin = 1; break;
darco 56a656
	   case '{': return 0;		/* not a function */
darco 56a656
	   case '}': return 0;		/* not a function */
darco 56a656
	   default: contin = -1;
darco 56a656
	   }
darco 56a656
	while ( isidchar(*p) )
darco 56a656
	  p++;
darco 56a656
	endfn = p;
darco 56a656
	p = skipspace(p, 1);
darco 56a656
	if ( *p++ != '(' )
darco 56a656
	  return 0;		/* not a function */
darco 56a656
	p = skipspace(p, 1);
darco 56a656
	if ( *p == ')' )
darco 56a656
	  return 0;		/* no parameters */
darco 56a656
	/* Check that the apparent function name isn't a keyword. */
darco 56a656
	/* We only need to check for keywords that could be followed */
darco 56a656
	/* by a left parenthesis (which, unfortunately, is most of them). */
darco 56a656
	   {	static char *words[] =
darco 56a656
		   {	"asm", "auto", "case", "char", "const", "double",
darco 56a656
			"extern", "float", "for", "if", "int", "long",
darco 56a656
			"register", "return", "short", "signed", "sizeof",
darco 56a656
			"static", "switch", "typedef", "unsigned",
darco 56a656
			"void", "volatile", "while", 0
darco 56a656
		   };
darco 56a656
		char **key = words;
darco 56a656
		char *kp;
darco 56a656
		int len = endfn - buf;
darco 56a656
darco 56a656
		while ( (kp = *key) != 0 )
darco 56a656
		   {	if ( strlen(kp) == len && !strncmp(kp, buf, len) )
darco 56a656
			  return 0;	/* name is a keyword */
darco 56a656
			key++;
darco 56a656
		   }
darco 56a656
	   }
darco 56a656
	return contin;
darco 56a656
}
darco 56a656
darco 56a656
/* Convert a recognized function definition or header to K&R syntax. */
darco 56a656
int
darco 56a656
convert1(buf, out, header, convert_varargs)
darco 56a656
    char *buf;
darco 56a656
    FILE *out;
darco 56a656
    int header;			/* Boolean */
darco 56a656
    int convert_varargs;	/* Boolean */
darco 56a656
{	char *endfn;
darco 56a656
	register char *p;
darco 56a656
	char **breaks;
darco 56a656
	unsigned num_breaks = 2;	/* for testing */
darco 56a656
	char **btop;
darco 56a656
	char **bp;
darco 56a656
	char **ap;
darco 56a656
	char *vararg = 0;
darco 56a656
darco 56a656
	/* Pre-ANSI implementations don't agree on whether strchr */
darco 56a656
	/* is called strchr or index, so we open-code it here. */
darco 56a656
	for ( endfn = buf; *(endfn++) != '('; )
darco 56a656
	  ;
darco 56a656
top:	p = endfn;
darco 56a656
	breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
darco 56a656
	if ( breaks == 0 )
darco 56a656
	   {	/* Couldn't allocate break table, give up */
darco 56a656
		fprintf(stderr, "Unable to allocate break table!\n");
darco 56a656
		fputs(buf, out);
darco 56a656
		return -1;
darco 56a656
	   }
darco 56a656
	btop = breaks + num_breaks * 2 - 2;
darco 56a656
	bp = breaks;
darco 56a656
	/* Parse the argument list */
darco 56a656
	do
darco 56a656
	   {	int level = 0;
darco 56a656
		char *lp = NULL;
darco 56a656
		char *rp;
darco 56a656
		char *end = NULL;
darco 56a656
darco 56a656
		if ( bp >= btop )
darco 56a656
		   {	/* Filled up break table. */
darco 56a656
			/* Allocate a bigger one and start over. */
darco 56a656
			free((char *)breaks);
darco 56a656
			num_breaks <<= 1;
darco 56a656
			goto top;
darco 56a656
		   }
darco 56a656
		*bp++ = p;
darco 56a656
		/* Find the end of the argument */
darco 56a656
		for ( ; end == NULL; p++ )
darco 56a656
		   {	switch(*p)
darco 56a656
			   {
darco 56a656
			   case ',':
darco 56a656
				if ( !level ) end = p;
darco 56a656
				break;
darco 56a656
			   case '(':
darco 56a656
				if ( !level ) lp = p;
darco 56a656
				level++;
darco 56a656
				break;
darco 56a656
			   case ')':
darco 56a656
				if ( --level < 0 ) end = p;
darco 56a656
				else rp = p;
darco 56a656
				break;
darco 56a656
			   case '/':
darco 56a656
				p = skipspace(p, 1) - 1;
darco 56a656
				break;
darco 56a656
			   default:
darco 56a656
				;
darco 56a656
			   }
darco 56a656
		   }
darco 56a656
		/* Erase any embedded prototype parameters. */
darco 56a656
		if ( lp )
darco 56a656
		  writeblanks(lp + 1, rp);
darco 56a656
		p--;			/* back up over terminator */
darco 56a656
		/* Find the name being declared. */
darco 56a656
		/* This is complicated because of procedure and */
darco 56a656
		/* array modifiers. */
darco 56a656
		for ( ; ; )
darco 56a656
		   {	p = skipspace(p - 1, -1);
darco 56a656
			switch ( *p )
darco 56a656
			   {
darco 56a656
			   case ']':	/* skip array dimension(s) */
darco 56a656
			   case ')':	/* skip procedure args OR name */
darco 56a656
			   {	int level = 1;
darco 56a656
				while ( level )
darco 56a656
				 switch ( *--p )
darco 56a656
				   {
darco 56a656
				   case ']': case ')': level++; break;
darco 56a656
				   case '[': case '(': level--; break;
darco 56a656
				   case '/': p = skipspace(p, -1) + 1; break;
darco 56a656
				   default: ;
darco 56a656
				   }
darco 56a656
			   }
darco 56a656
				if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
darco 56a656
				   {	/* We found the name being declared */
darco 56a656
					while ( !isidfirstchar(*p) )
darco 56a656
					  p = skipspace(p, 1) + 1;
darco 56a656
					goto found;
darco 56a656
				   }
darco 56a656
				break;
darco 56a656
			   default:
darco 56a656
				goto found;
darco 56a656
			   }
darco 56a656
		   }
darco 56a656
found:		if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
darco 56a656
		  {	if ( convert_varargs )
darco 56a656
			  {	*bp++ = "va_alist";
darco 56a656
				vararg = p-2;
darco 56a656
			  }
darco 56a656
			else
darco 56a656
			  {	p++;
darco 56a656
				if ( bp == breaks + 1 )	/* sole argument */
darco 56a656
				  writeblanks(breaks[0], p);
darco 56a656
				else
darco 56a656
				  writeblanks(bp[-1] - 1, p);
darco 56a656
				bp--;
darco 56a656
			  }
darco 56a656
		   }
darco 56a656
		else
darco 56a656
		   {	while ( isidchar(*p) ) p--;
darco 56a656
			*bp++ = p+1;
darco 56a656
		   }
darco 56a656
		p = end;
darco 56a656
	   }
darco 56a656
	while ( *p++ == ',' );
darco 56a656
	*bp = p;
darco 56a656
	/* Make a special check for 'void' arglist */
darco 56a656
	if ( bp == breaks+2 )
darco 56a656
	   {	p = skipspace(breaks[0], 1);
darco 56a656
		if ( !strncmp(p, "void", 4) )
darco 56a656
		   {	p = skipspace(p+4, 1);
darco 56a656
			if ( p == breaks[2] - 1 )
darco 56a656
			   {	bp = breaks;	/* yup, pretend arglist is empty */
darco 56a656
				writeblanks(breaks[0], p + 1);
darco 56a656
			   }
darco 56a656
		   }
darco 56a656
	   }
darco 56a656
	/* Put out the function name and left parenthesis. */
darco 56a656
	p = buf;
darco 56a656
	while ( p != endfn ) putc(*p, out), p++;
darco 56a656
	/* Put out the declaration. */
darco 56a656
	if ( header )
darco 56a656
	  {	fputs(");", out);
darco 56a656
		for ( p = breaks[0]; *p; p++ )
darco 56a656
		  if ( *p == '\r' || *p == '\n' )
darco 56a656
		    putc(*p, out);
darco 56a656
	  }
darco 56a656
	else
darco 56a656
	  {	for ( ap = breaks+1; ap < bp; ap += 2 )
darco 56a656
		  {	p = *ap;
darco 56a656
			while ( isidchar(*p) )
darco 56a656
			  putc(*p, out), p++;
darco 56a656
			if ( ap < bp - 1 )
darco 56a656
			  fputs(", ", out);
darco 56a656
		  }
darco 56a656
		fputs(")  ", out);
darco 56a656
		/* Put out the argument declarations */
darco 56a656
		for ( ap = breaks+2; ap <= bp; ap += 2 )
darco 56a656
		  (*ap)[-1] = ';';
darco 56a656
		if ( vararg != 0 )
darco 56a656
		  {	*vararg = 0;
darco 56a656
			fputs(breaks[0], out);		/* any prior args */
darco 56a656
			fputs("va_dcl", out);		/* the final arg */
darco 56a656
			fputs(bp[0], out);
darco 56a656
		  }
darco 56a656
		else
darco 56a656
		  fputs(breaks[0], out);
darco 56a656
	  }
darco 56a656
	free((char *)breaks);
darco 56a656
	return 0;
darco 56a656
}