ansi2knr.c
Go to the documentation of this file.
00001 /* ansi2knr.c */
00002 /* Convert ANSI C function definitions to K&R ("traditional C") syntax */
00003 
00004 /*
00005 ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
00006 WARRANTY.  No author or distributor accepts responsibility to anyone for the
00007 consequences of using it or for whether it serves any particular purpose or
00008 works at all, unless he says so in writing.  Refer to the GNU General Public
00009 License (the "GPL") for full details.
00010 
00011 Everyone is granted permission to copy, modify and redistribute ansi2knr,
00012 but only under the conditions described in the GPL.  A copy of this license
00013 is supposed to have been given to you along with ansi2knr so you can know
00014 your rights and responsibilities.  It should be in a file named COPYLEFT.
00015 [In the IJG distribution, the GPL appears below, not in a separate file.]
00016 Among other things, the copyright notice and this notice must be preserved
00017 on all copies.
00018 
00019 We explicitly state here what we believe is already implied by the GPL: if
00020 the ansi2knr program is distributed as a separate set of sources and a
00021 separate executable file which are aggregated on a storage medium together
00022 with another program, this in itself does not bring the other program under
00023 the GPL, nor does the mere fact that such a program or the procedures for
00024 constructing it invoke the ansi2knr executable bring any other part of the
00025 program under the GPL.
00026 */
00027 
00028 /*
00029 ---------- Here is the GNU GPL file COPYLEFT, referred to above ----------
00030 ----- These terms do NOT apply to the JPEG software itself; see README ------
00031 
00032                     GHOSTSCRIPT GENERAL PUBLIC LICENSE
00033                     (Clarified 11 Feb 1988)
00034 
00035  Copyright (C) 1988 Richard M. Stallman
00036  Everyone is permitted to copy and distribute verbatim copies of this
00037  license, but changing it is not allowed.  You can also use this wording
00038  to make the terms for other programs.
00039 
00040   The license agreements of most software companies keep you at the
00041 mercy of those companies.  By contrast, our general public license is
00042 intended to give everyone the right to share Ghostscript.  To make sure
00043 that you get the rights we want you to have, we need to make
00044 restrictions that forbid anyone to deny you these rights or to ask you
00045 to surrender the rights.  Hence this license agreement.
00046 
00047   Specifically, we want to make sure that you have the right to give
00048 away copies of Ghostscript, that you receive source code or else can get
00049 it if you want it, that you can change Ghostscript or use pieces of it
00050 in new free programs, and that you know you can do these things.
00051 
00052   To make sure that everyone has such rights, we have to forbid you to
00053 deprive anyone else of these rights.  For example, if you distribute
00054 copies of Ghostscript, you must give the recipients all the rights that
00055 you have.  You must make sure that they, too, receive or can get the
00056 source code.  And you must tell them their rights.
00057 
00058   Also, for our own protection, we must make certain that everyone finds
00059 out that there is no warranty for Ghostscript.  If Ghostscript is
00060 modified by someone else and passed on, we want its recipients to know
00061 that what they have is not what we distributed, so that any problems
00062 introduced by others will not reflect on our reputation.
00063 
00064   Therefore we (Richard M. Stallman and the Free Software Foundation,
00065 Inc.) make the following terms which say what you must do to be allowed
00066 to distribute or change Ghostscript.
00067 
00068 
00069                         COPYING POLICIES
00070 
00071   1. You may copy and distribute verbatim copies of Ghostscript source
00072 code as you receive it, in any medium, provided that you conspicuously
00073 and appropriately publish on each copy a valid copyright and license
00074 notice "Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
00075 Distributed by Free Software Foundation, Inc." (or with whatever year is
00076 appropriate); keep intact the notices on all files that refer to this
00077 License Agreement and to the absence of any warranty; and give any other
00078 recipients of the Ghostscript program a copy of this License Agreement
00079 along with the program.  You may charge a distribution fee for the
00080 physical act of transferring a copy.
00081 
00082   2. You may modify your copy or copies of Ghostscript or any portion of
00083 it, and copy and distribute such modifications under the terms of
00084 Paragraph 1 above, provided that you also do the following:
00085 
00086     a) cause the modified files to carry prominent notices stating
00087     that you changed the files and the date of any change; and
00088 
00089     b) cause the whole of any work that you distribute or publish,
00090     that in whole or in part contains or is a derivative of Ghostscript
00091     or any part thereof, to be licensed at no charge to all third
00092     parties on terms identical to those contained in this License
00093     Agreement (except that you may choose to grant more extensive
00094     warranty protection to some or all third parties, at your option).
00095 
00096     c) You may charge a distribution fee for the physical act of
00097     transferring a copy, and you may at your option offer warranty
00098     protection in exchange for a fee.
00099 
00100 Mere aggregation of another unrelated program with this program (or its
00101 derivative) on a volume of a storage or distribution medium does not bring
00102 the other program under the scope of these terms.
00103 
00104   3. You may copy and distribute Ghostscript (or a portion or derivative
00105 of it, under Paragraph 2) in object code or executable form under the
00106 terms of Paragraphs 1 and 2 above provided that you also do one of the
00107 following:
00108 
00109     a) accompany it with the complete corresponding machine-readable
00110     source code, which must be distributed under the terms of
00111     Paragraphs 1 and 2 above; or,
00112 
00113     b) accompany it with a written offer, valid for at least three
00114     years, to give any third party free (except for a nominal
00115     shipping charge) a complete machine-readable copy of the
00116     corresponding source code, to be distributed under the terms of
00117     Paragraphs 1 and 2 above; or,
00118 
00119     c) accompany it with the information you received as to where the
00120     corresponding source code may be obtained.  (This alternative is
00121     allowed only for noncommercial distribution and only if you
00122     received the program in object code or executable form alone.)
00123 
00124 For an executable file, complete source code means all the source code for
00125 all modules it contains; but, as a special exception, it need not include
00126 source code for modules which are standard libraries that accompany the
00127 operating system on which the executable file runs.
00128 
00129   4. You may not copy, sublicense, distribute or transfer Ghostscript
00130 except as expressly provided under this License Agreement.  Any attempt
00131 otherwise to copy, sublicense, distribute or transfer Ghostscript is
00132 void and your rights to use the program under this License agreement
00133 shall be automatically terminated.  However, parties who have received
00134 computer software programs from you with this License Agreement will not
00135 have their licenses terminated so long as such parties remain in full
00136 compliance.
00137 
00138   5. If you wish to incorporate parts of Ghostscript into other free
00139 programs whose distribution conditions are different, write to the Free
00140 Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not
00141 yet worked out a simple rule that can be stated here, but we will often
00142 permit this.  We will be guided by the two goals of preserving the free
00143 status of all derivatives of our free software and of promoting the
00144 sharing and reuse of software.
00145 
00146 Your comments and suggestions about our licensing policies and our
00147 software are welcome!  Please contact the Free Software Foundation,
00148 Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
00149 
00150                        NO WARRANTY
00151 
00152   BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
00153 NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
00154 WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
00155 M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
00156 PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
00157 EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00158 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
00159 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
00160 YOU.  SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
00161 NECESSARY SERVICING, REPAIR OR CORRECTION.
00162 
00163   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
00164 STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
00165 ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
00166 GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
00167 ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
00168 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
00169 (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
00170 INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
00171 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
00172 HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
00173 BY ANY OTHER PARTY.
00174 
00175 -------------------- End of file COPYLEFT ------------------------------
00176 */
00177 
00178 /*
00179  * Usage:
00180         ansi2knr input_file [output_file]
00181  * If no output_file is supplied, output goes to stdout.
00182  * There are no error messages.
00183  *
00184  * ansi2knr recognizes function definitions by seeing a non-keyword
00185  * identifier at the left margin, followed by a left parenthesis,
00186  * with a right parenthesis as the last character on the line,
00187  * and with a left brace as the first token on the following line
00188  * (ignoring possible intervening comments).
00189  * It will recognize a multi-line header provided that no intervening
00190  * line ends with a left or right brace or a semicolon.
00191  * These algorithms ignore whitespace and comments, except that
00192  * the function name must be the first thing on the line.
00193  * The following constructs will confuse it:
00194  *      - Any other construct that starts at the left margin and
00195  *          follows the above syntax (such as a macro or function call).
00196  *      - Some macros that tinker with the syntax of the function header.
00197  */
00198 
00199 /*
00200  * The original and principal author of ansi2knr is L. Peter Deutsch
00201  * <ghost@aladdin.com>.  Other authors are noted in the change history
00202  * that follows (in reverse chronological order):
00203         lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
00204                 compilers that don't understand void, as suggested by
00205                 Tom Lane
00206         lpd 96-01-15 changed to require that the first non-comment token
00207                 on the line following a function header be a left brace,
00208                 to reduce sensitivity to macros, as suggested by Tom Lane
00209                 <tgl@sss.pgh.pa.us>
00210         lpd 95-06-22 removed #ifndefs whose sole purpose was to define
00211                 undefined preprocessor symbols as 0; changed all #ifdefs
00212                 for configuration symbols to #ifs
00213         lpd 95-04-05 changed copyright notice to make it clear that
00214                 including ansi2knr in a program does not bring the entire
00215                 program under the GPL
00216         lpd 94-12-18 added conditionals for systems where ctype macros
00217                 don't handle 8-bit characters properly, suggested by
00218                 Francois Pinard <pinard@iro.umontreal.ca>;
00219                 removed --varargs switch (this is now the default)
00220         lpd 94-10-10 removed CONFIG_BROKETS conditional
00221         lpd 94-07-16 added some conditionals to help GNU `configure',
00222                 suggested by Francois Pinard <pinard@iro.umontreal.ca>;
00223                 properly erase prototype args in function parameters,
00224                 contributed by Jim Avera <jima@netcom.com>;
00225                 correct error in writeblanks (it shouldn't erase EOLs)
00226         lpd 89-xx-xx original version
00227  */
00228 
00229 /* Most of the conditionals here are to make ansi2knr work with */
00230 /* or without the GNU configure machinery. */
00231 
00232 #if HAVE_CONFIG_H
00233 # include <config.h>
00234 #endif
00235 
00236 #include <stdio.h>
00237 #include <ctype.h>
00238 
00239 #if HAVE_CONFIG_H
00240 
00241 /*
00242    For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
00243    This will define HAVE_CONFIG_H and so, activate the following lines.
00244  */
00245 
00246 # if STDC_HEADERS || HAVE_STRING_H
00247 #  include <string.h>
00248 # else
00249 #  include <strings.h>
00250 # endif
00251 
00252 #else /* not HAVE_CONFIG_H */
00253 
00254 /* Otherwise do it the hard way */
00255 
00256 # ifdef BSD
00257 #  include <strings.h>
00258 # else
00259 #  ifdef VMS
00260     extern int strlen(), strncmp();
00261 #  else
00262 #   include <string.h>
00263 #  endif
00264 # endif
00265 
00266 #endif /* not HAVE_CONFIG_H */
00267 
00268 #if STDC_HEADERS
00269 # include <stdlib.h>
00270 #else
00271 /*
00272    malloc and free should be declared in stdlib.h,
00273    but if you've got a K&R compiler, they probably aren't.
00274  */
00275 # ifdef MSDOS
00276 #  include <malloc.h>
00277 # else
00278 #  ifdef VMS
00279      extern char *malloc();
00280      extern void free();
00281 #  else
00282      extern char *malloc();
00283      extern int free();
00284 #  endif
00285 # endif
00286 
00287 #endif
00288 
00289 /*
00290  * The ctype macros don't always handle 8-bit characters correctly.
00291  * Compensate for this here.
00292  */
00293 #ifdef isascii
00294 #  undef HAVE_ISASCII           /* just in case */
00295 #  define HAVE_ISASCII 1
00296 #else
00297 #endif
00298 #if STDC_HEADERS || !HAVE_ISASCII
00299 #  define is_ascii(c) 1
00300 #else
00301 #  define is_ascii(c) isascii(c)
00302 #endif
00303 
00304 #define is_space(c) (is_ascii(c) && isspace(c))
00305 #define is_alpha(c) (is_ascii(c) && isalpha(c))
00306 #define is_alnum(c) (is_ascii(c) && isalnum(c))
00307 
00308 /* Scanning macros */
00309 #define isidchar(ch) (is_alnum(ch) || (ch) == '_')
00310 #define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
00311 
00312 /* Forward references */
00313 char *skipspace();
00314 int writeblanks();
00315 int test1();
00316 int convert1();
00317 
00318 /* The main program */
00319 int
00320 main(argc, argv)
00321     int argc;
00322     char *argv[];
00323 {       FILE *in, *out;
00324 #define bufsize 5000                    /* arbitrary size */
00325         char *buf;
00326         char *line;
00327         char *more;
00328         /*
00329          * In previous versions, ansi2knr recognized a --varargs switch.
00330          * If this switch was supplied, ansi2knr would attempt to convert
00331          * a ... argument to va_alist and va_dcl; if this switch was not
00332          * supplied, ansi2knr would simply drop any such arguments.
00333          * Now, ansi2knr always does this conversion, and we only
00334          * check for this switch for backward compatibility.
00335          */
00336         int convert_varargs = 1;
00337 
00338         if ( argc > 1 && argv[1][0] == '-' )
00339           {     if ( !strcmp(argv[1], "--varargs") )
00340                   {     convert_varargs = 1;
00341                         argc--;
00342                         argv++;
00343                   }
00344                 else
00345                   {     fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
00346                         exit(1);
00347                   }
00348           }
00349         switch ( argc )
00350            {
00351         default:
00352                 printf("Usage: ansi2knr input_file [output_file]\n");
00353                 exit(0);
00354         case 2:
00355                 out = stdout;
00356                 break;
00357         case 3:
00358                 out = fopen(argv[2], "w");
00359                 if ( out == NULL )
00360                    {    fprintf(stderr, "Cannot open output file %s\n", argv[2]);
00361                         exit(1);
00362                    }
00363            }
00364         in = fopen(argv[1], "r");
00365         if ( in == NULL )
00366            {    fprintf(stderr, "Cannot open input file %s\n", argv[1]);
00367                 exit(1);
00368            }
00369         fprintf(out, "#line 1 \"%s\"\n", argv[1]);
00370         buf = malloc(bufsize);
00371         line = buf;
00372         while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
00373            {
00374 test:           line += strlen(line);
00375                 switch ( test1(buf) )
00376                    {
00377                 case 2:                 /* a function header */
00378                         convert1(buf, out, 1, convert_varargs);
00379                         break;
00380                 case 1:                 /* a function */
00381                         /* Check for a { at the start of the next line. */
00382                         more = ++line;
00383 f:                      if ( line >= buf + (bufsize - 1) ) /* overflow check */
00384                           goto wl;
00385                         if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
00386                           goto wl;
00387                         switch ( *skipspace(more, 1) )
00388                           {
00389                           case '{':
00390                             /* Definitely a function header. */
00391                             convert1(buf, out, 0, convert_varargs);
00392                             fputs(more, out);
00393                             break;
00394                           case 0:
00395                             /* The next line was blank or a comment: */
00396                             /* keep scanning for a non-comment. */
00397                             line += strlen(line);
00398                             goto f;
00399                           default:
00400                             /* buf isn't a function header, but */
00401                             /* more might be. */
00402                             fputs(buf, out);
00403                             strcpy(buf, more);
00404                             line = buf;
00405                             goto test;
00406                           }
00407                         break;
00408                 case -1:                /* maybe the start of a function */
00409                         if ( line != buf + (bufsize - 1) ) /* overflow check */
00410                           continue;
00411                         /* falls through */
00412                 default:                /* not a function */
00413 wl:                     fputs(buf, out);
00414                         break;
00415                    }
00416                 line = buf;
00417            }
00418         if ( line != buf )
00419           fputs(buf, out);
00420         free(buf);
00421         fclose(out);
00422         fclose(in);
00423         return 0;
00424 }
00425 
00426 /* Skip over space and comments, in either direction. */
00427 char *
00428 skipspace(p, dir)
00429     register char *p;
00430     register int dir;                   /* 1 for forward, -1 for backward */
00431 {       for ( ; ; )
00432            {    while ( is_space(*p) )
00433                   p += dir;
00434                 if ( !(*p == '/' && p[dir] == '*') )
00435                   break;
00436                 p += dir;  p += dir;
00437                 while ( !(*p == '*' && p[dir] == '/') )
00438                    {    if ( *p == 0 )
00439                           return p;     /* multi-line comment?? */
00440                         p += dir;
00441                    }
00442                 p += dir;  p += dir;
00443            }
00444         return p;
00445 }
00446 
00447 /*
00448  * Write blanks over part of a string.
00449  * Don't overwrite end-of-line characters.
00450  */
00451 int
00452 writeblanks(start, end)
00453     char *start;
00454     char *end;
00455 {       char *p;
00456         for ( p = start; p < end; p++ )
00457           if ( *p != '\r' && *p != '\n' )
00458             *p = ' ';
00459         return 0;
00460 }
00461 
00462 /*
00463  * Test whether the string in buf is a function definition.
00464  * The string may contain and/or end with a newline.
00465  * Return as follows:
00466  *      0 - definitely not a function definition;
00467  *      1 - definitely a function definition;
00468  *      2 - definitely a function prototype (NOT USED);
00469  *      -1 - may be the beginning of a function definition,
00470  *              append another line and look again.
00471  * The reason we don't attempt to convert function prototypes is that
00472  * Ghostscript's declaration-generating macros look too much like
00473  * prototypes, and confuse the algorithms.
00474  */
00475 int
00476 test1(buf)
00477     char *buf;
00478 {       register char *p = buf;
00479         char *bend;
00480         char *endfn;
00481         int contin;
00482 
00483         if ( !isidfirstchar(*p) )
00484           return 0;             /* no name at left margin */
00485         bend = skipspace(buf + strlen(buf) - 1, -1);
00486         switch ( *bend )
00487            {
00488            case ';': contin = 0 /*2*/; break;
00489            case ')': contin = 1; break;
00490            case '{': return 0;          /* not a function */
00491            case '}': return 0;          /* not a function */
00492            default: contin = -1;
00493            }
00494         while ( isidchar(*p) )
00495           p++;
00496         endfn = p;
00497         p = skipspace(p, 1);
00498         if ( *p++ != '(' )
00499           return 0;             /* not a function */
00500         p = skipspace(p, 1);
00501         if ( *p == ')' )
00502           return 0;             /* no parameters */
00503         /* Check that the apparent function name isn't a keyword. */
00504         /* We only need to check for keywords that could be followed */
00505         /* by a left parenthesis (which, unfortunately, is most of them). */
00506            {    static char *words[] =
00507                    {    "asm", "auto", "case", "char", "const", "double",
00508                         "extern", "float", "for", "if", "int", "long",
00509                         "register", "return", "short", "signed", "sizeof",
00510                         "static", "switch", "typedef", "unsigned",
00511                         "void", "volatile", "while", 0
00512                    };
00513                 char **key = words;
00514                 char *kp;
00515                 int len = endfn - buf;
00516 
00517                 while ( (kp = *key) != 0 )
00518                    {    if ( strlen(kp) == len && !strncmp(kp, buf, len) )
00519                           return 0;     /* name is a keyword */
00520                         key++;
00521                    }
00522            }
00523         return contin;
00524 }
00525 
00526 /* Convert a recognized function definition or header to K&R syntax. */
00527 int
00528 convert1(buf, out, header, convert_varargs)
00529     char *buf;
00530     FILE *out;
00531     int header;                 /* Boolean */
00532     int convert_varargs;        /* Boolean */
00533 {       char *endfn;
00534         register char *p;
00535         char **breaks;
00536         unsigned num_breaks = 2;        /* for testing */
00537         char **btop;
00538         char **bp;
00539         char **ap;
00540         char *vararg = 0;
00541 
00542         /* Pre-ANSI implementations don't agree on whether strchr */
00543         /* is called strchr or index, so we open-code it here. */
00544         for ( endfn = buf; *(endfn++) != '('; )
00545           ;
00546 top:    p = endfn;
00547         breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
00548         if ( breaks == 0 )
00549            {    /* Couldn't allocate break table, give up */
00550                 fprintf(stderr, "Unable to allocate break table!\n");
00551                 fputs(buf, out);
00552                 return -1;
00553            }
00554         btop = breaks + num_breaks * 2 - 2;
00555         bp = breaks;
00556         /* Parse the argument list */
00557         do
00558            {    int level = 0;
00559                 char *lp = NULL;
00560                 char *rp;
00561                 char *end = NULL;
00562 
00563                 if ( bp >= btop )
00564                    {    /* Filled up break table. */
00565                         /* Allocate a bigger one and start over. */
00566                         free((char *)breaks);
00567                         num_breaks <<= 1;
00568                         goto top;
00569                    }
00570                 *bp++ = p;
00571                 /* Find the end of the argument */
00572                 for ( ; end == NULL; p++ )
00573                    {    switch(*p)
00574                            {
00575                            case ',':
00576                                 if ( !level ) end = p;
00577                                 break;
00578                            case '(':
00579                                 if ( !level ) lp = p;
00580                                 level++;
00581                                 break;
00582                            case ')':
00583                                 if ( --level < 0 ) end = p;
00584                                 else rp = p;
00585                                 break;
00586                            case '/':
00587                                 p = skipspace(p, 1) - 1;
00588                                 break;
00589                            default:
00590                                 ;
00591                            }
00592                    }
00593                 /* Erase any embedded prototype parameters. */
00594                 if ( lp )
00595                   writeblanks(lp + 1, rp);
00596                 p--;                    /* back up over terminator */
00597                 /* Find the name being declared. */
00598                 /* This is complicated because of procedure and */
00599                 /* array modifiers. */
00600                 for ( ; ; )
00601                    {    p = skipspace(p - 1, -1);
00602                         switch ( *p )
00603                            {
00604                            case ']':    /* skip array dimension(s) */
00605                            case ')':    /* skip procedure args OR name */
00606                            {    int level = 1;
00607                                 while ( level )
00608                                  switch ( *--p )
00609                                    {
00610                                    case ']': case ')': level++; break;
00611                                    case '[': case '(': level--; break;
00612                                    case '/': p = skipspace(p, -1) + 1; break;
00613                                    default: ;
00614                                    }
00615                            }
00616                                 if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
00617                                    {    /* We found the name being declared */
00618                                         while ( !isidfirstchar(*p) )
00619                                           p = skipspace(p, 1) + 1;
00620                                         goto found;
00621                                    }
00622                                 break;
00623                            default:
00624                                 goto found;
00625                            }
00626                    }
00627 found:          if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
00628                   {     if ( convert_varargs )
00629                           {     *bp++ = "va_alist";
00630                                 vararg = p-2;
00631                           }
00632                         else
00633                           {     p++;
00634                                 if ( bp == breaks + 1 ) /* sole argument */
00635                                   writeblanks(breaks[0], p);
00636                                 else
00637                                   writeblanks(bp[-1] - 1, p);
00638                                 bp--;
00639                           }
00640                    }
00641                 else
00642                    {    while ( isidchar(*p) ) p--;
00643                         *bp++ = p+1;
00644                    }
00645                 p = end;
00646            }
00647         while ( *p++ == ',' );
00648         *bp = p;
00649         /* Make a special check for 'void' arglist */
00650         if ( bp == breaks+2 )
00651            {    p = skipspace(breaks[0], 1);
00652                 if ( !strncmp(p, "void", 4) )
00653                    {    p = skipspace(p+4, 1);
00654                         if ( p == breaks[2] - 1 )
00655                            {    bp = breaks;    /* yup, pretend arglist is empty */
00656                                 writeblanks(breaks[0], p + 1);
00657                            }
00658                    }
00659            }
00660         /* Put out the function name and left parenthesis. */
00661         p = buf;
00662         while ( p != endfn ) putc(*p, out), p++;
00663         /* Put out the declaration. */
00664         if ( header )
00665           {     fputs(");", out);
00666                 for ( p = breaks[0]; *p; p++ )
00667                   if ( *p == '\r' || *p == '\n' )
00668                     putc(*p, out);
00669           }
00670         else
00671           {     for ( ap = breaks+1; ap < bp; ap += 2 )
00672                   {     p = *ap;
00673                         while ( isidchar(*p) )
00674                           putc(*p, out), p++;
00675                         if ( ap < bp - 1 )
00676                           fputs(", ", out);
00677                   }
00678                 fputs(")  ", out);
00679                 /* Put out the argument declarations */
00680                 for ( ap = breaks+2; ap <= bp; ap += 2 )
00681                   (*ap)[-1] = ';';
00682                 if ( vararg != 0 )
00683                   {     *vararg = 0;
00684                         fputs(breaks[0], out);          /* any prior args */
00685                         fputs("va_dcl", out);           /* the final arg */
00686                         fputs(bp[0], out);
00687                   }
00688                 else
00689                   fputs(breaks[0], out);
00690           }
00691         free((char *)breaks);
00692         return 0;
00693 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:15