]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
update from automake-1.1p
authorJim Meyering <jim@meyering.net>
Thu, 29 May 1997 13:19:34 +0000 (13:19 +0000)
committerJim Meyering <jim@meyering.net>
Thu, 29 May 1997 13:19:34 +0000 (13:19 +0000)
src/ansi2knr.c

index 72519f01d5b2574ce6cfb7c37e5ce361d7dcff92..64a4578a2fa63d92463a77c2107f397d3ebdd03c 100644 (file)
@@ -1,5 +1,3 @@
-/* Copyright (C) 1989, 1991, 1993, 1994, 1995 Aladdin Enterprises. All rights reserved. */
-
 /* ansi2knr.c */
 /* Convert ANSI C function definitions to K&R ("traditional C") syntax */
 
@@ -34,22 +32,30 @@ program under the GPL.
  *
  * ansi2knr 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.
- * It will recognize a multi-line header provided that the last character
- * of the last line of the header is a right parenthesis,
- * and no intervening line ends with a left or right brace or a semicolon.
+ * 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.
  * 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).
- *     - Macros that tinker with the syntax of the function header.
+ *     - Some macros that tinker with the syntax of the function header.
  */
 
 /*
  * 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
+               compilers that don't understand void, as suggested by
+               Tom Lane
+       lpd 96-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
                undefined preprocessor symbols as 0; changed all #ifdefs
                for configuration symbols to #ifs
@@ -70,7 +76,7 @@ program under the GPL.
  */
 
 /* Most of the conditionals here are to make ansi2knr work with */
-/* the GNU configure machinery. */
+/* or without the GNU configure machinery. */
 
 #if HAVE_CONFIG_H
 # include <config.h>
@@ -94,12 +100,17 @@ program under the GPL.
 
 #else /* not HAVE_CONFIG_H */
 
-/*
-   Without AC_CONFIG_HEADER, merely use <string.h> as in the original
-   Ghostscript distribution.  This loses on older BSD systems.
- */
+/* Otherwise do it the hard way */
 
-# include <string.h>
+# ifdef BSD
+#  include <strings.h>
+# else
+#  ifdef VMS
+    extern int strlen(), strncmp();
+#  else
+#   include <string.h>
+#  endif
+# endif
 
 #endif /* not HAVE_CONFIG_H */
 
@@ -110,8 +121,18 @@ program under the GPL.
    malloc and free should be declared in stdlib.h,
    but if you've got a K&R compiler, they probably aren't.
  */
-char *malloc();
-void free();
+# ifdef MSDOS
+#  include <malloc.h>
+# else
+#  ifdef VMS
+     extern char *malloc();
+     extern void free();
+#  else
+     extern char *malloc();
+     extern int free();
+#  endif
+# endif
+
 #endif
 
 /*
@@ -119,14 +140,14 @@ void free();
  * 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))
@@ -139,7 +160,7 @@ void free();
 
 /* Forward references */
 char *skipspace();
-void writeblanks();
+int writeblanks();
 int test1();
 int convert1();
 
@@ -152,6 +173,7 @@ main(argc, argv)
 #define bufsize 5000                   /* arbitrary size */
        char *buf;
        char *line;
+       char *more;
        /*
         * In previous versions, ansi2knr recognized a --varargs switch.
         * If this switch was supplied, ansi2knr would attempt to convert
@@ -197,26 +219,53 @@ main(argc, argv)
        buf = malloc(bufsize);
        line = buf;
        while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
-          {    switch ( test1(buf) )
+          {
+test:          line += strlen(line);
+               switch ( test1(buf) )
                   {
                case 2:                 /* a function header */
                        convert1(buf, out, 1, convert_varargs);
                        break;
                case 1:                 /* a function */
-                       convert1(buf, out, 0, convert_varargs);
+                       /* Check for a { at the start of the next line. */
+                       more = ++line;
+f:                     if ( line >= buf + (bufsize - 1) ) /* overflow check */
+                         goto wl;
+                       if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
+                         goto wl;
+                       switch ( *skipspace(more, 1) )
+                         {
+                         case '{':
+                           /* Definitely a function header. */
+                           convert1(buf, out, 0, convert_varargs);
+                           fputs(more, out);
+                           break;
+                         case 0:
+                           /* The next line was blank or a comment: */
+                           /* keep scanning for a non-comment. */
+                           line += strlen(line);
+                           goto f;
+                         default:
+                           /* buf isn't a function header, but */
+                           /* more might be. */
+                           fputs(buf, out);
+                           strcpy(buf, more);
+                           line = buf;
+                           goto test;
+                         }
                        break;
                case -1:                /* maybe the start of a function */
-                       line = buf + strlen(buf);
                        if ( line != buf + (bufsize - 1) ) /* overflow check */
-                               continue;
+                         continue;
                        /* falls through */
                default:                /* not a function */
-                       fputs(buf, out);
+wl:                    fputs(buf, out);
                        break;
                   }
                line = buf;
           }
-       if ( line != buf ) fputs(buf, out);
+       if ( line != buf )
+         fputs(buf, out);
        free(buf);
        fclose(out);
        fclose(in);
@@ -229,11 +278,14 @@ skipspace(p, dir)
     register char *p;
     register int dir;                  /* 1 for forward, -1 for backward */
 {      for ( ; ; )
-          {    while ( is_space(*p) ) p += dir;
-               if ( !(*p == '/' && p[dir] == '*') ) break;
+          {    while ( is_space(*p) )
+                 p += dir;
+               if ( !(*p == '/' && p[dir] == '*') )
+                 break;
                p += dir;  p += dir;
                while ( !(*p == '*' && p[dir] == '/') )
-                  {    if ( *p == 0 ) return p;        /* multi-line comment?? */
+                  {    if ( *p == 0 )
+                         return p;     /* multi-line comment?? */
                        p += dir;
                   }
                p += dir;  p += dir;
@@ -245,13 +297,15 @@ skipspace(p, dir)
  * Write blanks over part of a string.
  * Don't overwrite end-of-line characters.
  */
-void
+int
 writeblanks(start, end)
     char *start;
     char *end;
 {      char *p;
        for ( p = start; p < end; p++ )
-         if ( *p != '\r' && *p != '\n' ) *p = ' ';
+         if ( *p != '\r' && *p != '\n' )
+           *p = ' ';
+       return 0;
 }
 
 /*
@@ -274,25 +328,27 @@ test1(buf)
        char *bend;
        char *endfn;
        int contin;
+
        if ( !isidfirstchar(*p) )
-               return 0;               /* no name at left margin */
+         return 0;             /* no name at left margin */
        bend = skipspace(buf + strlen(buf) - 1, -1);
        switch ( *bend )
           {
-       case ';': contin = 0 /*2*/; break;
-       case ')': contin = 1; break;
-       case '{': return 0;             /* not a function */
-       case '}': return 0;             /* not a function */
-       default: contin = -1;
+          case ';': contin = 0 /*2*/; break;
+          case ')': contin = 1; break;
+          case '{': return 0;          /* not a function */
+          case '}': return 0;          /* not a function */
+          default: contin = -1;
           }
-       while ( isidchar(*p) ) p++;
+       while ( isidchar(*p) )
+         p++;
        endfn = p;
        p = skipspace(p, 1);
        if ( *p++ != '(' )
-               return 0;               /* not a function */
+         return 0;             /* not a function */
        p = skipspace(p, 1);
        if ( *p == ')' )
-               return 0;               /* no parameters */
+         return 0;             /* no parameters */
        /* Check that the apparent function name isn't a keyword. */
        /* We only need to check for keywords that could be followed */
        /* by a left parenthesis (which, unfortunately, is most of them). */
@@ -306,9 +362,10 @@ test1(buf)
                char **key = words;
                char *kp;
                int len = endfn - buf;
+
                while ( (kp = *key) != 0 )
                   {    if ( strlen(kp) == len && !strncmp(kp, buf, len) )
-                               return 0;       /* name is a keyword */
+                         return 0;     /* name is a keyword */
                        key++;
                   }
           }
@@ -324,15 +381,21 @@ convert1(buf, out, header, convert_varargs)
     int convert_varargs;       /* Boolean */
 {      char *endfn;
        register char *p;
+       /*
+        * The breaks table contains pointers to the beginning and end
+        * of each argument.
+        */
        char **breaks;
        unsigned num_breaks = 2;        /* for testing */
        char **btop;
        char **bp;
        char **ap;
        char *vararg = 0;
+
        /* Pre-ANSI implementations don't agree on whether strchr */
        /* is called strchr or index, so we open-code it here. */
-       for ( endfn = buf; *(endfn++) != '('; ) ;
+       for ( endfn = buf; *(endfn++) != '('; )
+         ;
 top:   p = endfn;
        breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
        if ( breaks == 0 )
@@ -349,6 +412,7 @@ top:        p = endfn;
                char *lp = NULL;
                char *rp;
                char *end = NULL;
+
                if ( bp >= btop )
                   {    /* Filled up break table. */
                        /* Allocate a bigger one and start over. */
@@ -361,21 +425,21 @@ top:      p = endfn;
                for ( ; end == NULL; p++ )
                   {    switch(*p)
                           {
-                       case ',':
+                          case ',':
                                if ( !level ) end = p;
                                break;
-                       case '(':
+                          case '(':
                                if ( !level ) lp = p;
                                level++;
                                break;
-                       case ')':
+                          case ')':
                                if ( --level < 0 ) end = p;
                                else rp = p;
                                break;
-                       case '/':
+                          case '/':
                                p = skipspace(p, 1) - 1;
                                break;
-                       default:
+                          default:
                                ;
                           }
                   }
@@ -390,26 +454,27 @@ top:      p = endfn;
                   {    p = skipspace(p - 1, -1);
                        switch ( *p )
                           {
-                       case ']':       /* skip array dimension(s) */
-                       case ')':       /* skip procedure args OR name */
+                          case ']':    /* skip array dimension(s) */
+                          case ')':    /* skip procedure args OR name */
                           {    int level = 1;
                                while ( level )
                                 switch ( *--p )
                                   {
-                               case ']': case ')': level++; break;
-                               case '[': case '(': level--; break;
-                               case '/': p = skipspace(p, -1) + 1; break;
-                               default: ;
+                                  case ']': case ')': level++; break;
+                                  case '[': case '(': level--; break;
+                                  case '/': p = skipspace(p, -1) + 1; break;
+                                  default: ;
                                   }
                           }
                                if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
                                   {    /* We found the name being declared */
                                        while ( !isidfirstchar(*p) )
-                                               p = skipspace(p, 1) + 1;
+                                         p = skipspace(p, 1) + 1;
                                        goto found;
                                   }
                                break;
-                       default: goto found;
+                          default:
+                               goto found;
                           }
                   }
 found:         if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )