Annotation of GNUtools/cc/scan-decls.c, revision 1.1.1.1

1.1       root        1: /* scan-decls.c - Extracts declarations from cpp output.
                      2:    Copyright (C) 1993 Free Software Foundation, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or modify it
                      5: under the terms of the GNU General Public License as published by the
                      6: Free Software Foundation; either version 2, or (at your option) any
                      7: later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12: GNU General Public License for more details.
                     13: 
                     14: You should have received a copy of the GNU General Public License
                     15: along with this program; if not, write to the Free Software
                     16: Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     17: 
                     18:    Written by Per Bothner <[email protected]>, July 1993.  */
                     19: 
                     20: #include <stdio.h>
                     21: #include <ctype.h>
                     22: #include "hconfig.h"
                     23: #include "scan.h"
                     24: 
                     25: sstring buf;
                     26: sstring rtype;
                     27: sstring arg_list;
                     28: 
                     29: int brace_nesting = 0;
                     30: 
                     31: /* The first extern_C_braces_length elements of extern_C_braces
                     32:    indicate the (brace nesting levels of) left braces that were
                     33:    prefixed by extern "C".  */
                     34: int extern_C_braces_length = 0;
                     35: char extern_C_braces[20];
                     36: #define in_extern_C_brace (extern_C_braces_length>0)
                     37: 
                     38: /* True if the function declaration currently being scanned is
                     39:    prefixed by extern "C".  */
                     40: int current_extern_C = 0;
                     41: 
                     42: static void
                     43: skip_to_closing_brace (fp)
                     44:      FILE *fp;
                     45: {
                     46:   int nesting = 1;
                     47:   for (;;)
                     48:     {
                     49:       int c = get_token (fp, &buf);
                     50:       if (c == EOF)
                     51:        break;
                     52:       if (c == '{')
                     53:        nesting++;
                     54:       if (c == '}' && --nesting == 0)
                     55:        break;
                     56:     }
                     57: }
                     58: 
                     59: /* This function scans a C source file (actually, the output of cpp),
                     60:    reading from FP.  It looks for function declarations, and certain
                     61:    other interesting sequences (external variables and macros).  */
                     62: 
                     63: int
                     64: scan_decls (fp)
                     65:      FILE *fp;
                     66: {
                     67:   int c;
                     68:   int saw_extern, saw_inline;
                     69: 
                     70:  new_statement:
                     71:   c = get_token (fp, &buf);
                     72:  handle_statement:
                     73:   current_extern_C = 0;
                     74:   saw_extern = 0;
                     75:   saw_inline = 0;
                     76:   if (c == '}')
                     77:     {
                     78:       /* Pop an 'extern "C"' nesting level, if appropriate.  */
                     79:       if (extern_C_braces_length
                     80:          && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
                     81:        extern_C_braces_length--;
                     82:       brace_nesting--;
                     83:       goto new_statement;
                     84:     }
                     85:   if (c == '{')
                     86:     {
                     87:       brace_nesting++;
                     88:       goto new_statement;
                     89:     }
                     90:   if (c == EOF)
                     91:     return 0;
                     92:   if (c == ';')
                     93:     goto new_statement;
                     94:   if (c != IDENTIFIER_TOKEN)
                     95:     goto new_statement;
                     96:   rtype.ptr = rtype.base;
                     97:   if (SSTRING_LENGTH (&buf) > 16
                     98:       && strncmp (buf.base, "__DEFINED_MACRO_", 16) == 0)
                     99:     {
                    100:       /* For certain interesting macro names, fixproto puts
                    101:         #ifdef FOO
                    102:         __DEFINED_MACRO_FOO
                    103:         #endif
                    104:         into the file to be pre-processed.  So if we see __DEFINED_MACRO_FOO,
                    105:         it means FOO was defined, which we may want to make a note of.  */
                    106:       recognized_macro (buf.base+16);
                    107:       goto new_statement;
                    108:     }
                    109:   if (strcmp (buf.base, "inline") == 0)
                    110:     {
                    111:       saw_inline = 1;
                    112:       c = get_token (fp, &buf);
                    113:     }
                    114:   if (strcmp (buf.base, "extern") == 0)
                    115:     {
                    116:       saw_extern = 1;
                    117:       c = get_token (fp, &buf);
                    118:       if (c == STRING_TOKEN && strcmp (buf.base, "C") == 0)
                    119:        {
                    120:          current_extern_C = 1;
                    121:          c = get_token (fp, &buf);
                    122:          if (c == '{')
                    123:            {
                    124:              brace_nesting++;
                    125:              extern_C_braces[extern_C_braces_length++] = brace_nesting;
                    126:              goto new_statement;
                    127:            }
                    128:          c = get_token (fp, &buf);
                    129:        }
                    130:     }
                    131:   for (;;)
                    132:     {
                    133:       int followingc = getc (fp); /* char following token in buf */
                    134: 
                    135:       MAKE_SSTRING_SPACE (&rtype, 1);
                    136:       *rtype.ptr = 0;
                    137: 
                    138:       if (c == IDENTIFIER_TOKEN)
                    139:        {
                    140:          int nextc = skip_spaces (fp, followingc);
                    141:          if (nextc == '(')
                    142:            {
                    143:              int nesting = 1;
                    144:              int func_lineno = source_lineno;
                    145:              char *args;
                    146: 
                    147:              arg_list.ptr = arg_list.base;
                    148:              for (;;)
                    149:                {
                    150:                  c = getc (fp);
                    151:                  if (c == '(')
                    152:                    nesting++;
                    153:                  else if (c == ')')
                    154:                    if (--nesting == 0)
                    155:                      break;
                    156:                  if (c == EOF)
                    157:                    break;
                    158:                  if (c == '\n')
                    159:                    {
                    160:                      c = ' ';
                    161:                      source_lineno++;
                    162:                      lineno++;
                    163:                    }
                    164:                  SSTRING_PUT (&arg_list, c);
                    165:                }
                    166:              SSTRING_PUT (&arg_list, '\0');
                    167:              args = arg_list.base;
                    168:              while (*args == ' ')
                    169:                args++;
                    170:              recognized_function (buf.base,
                    171:                                   (saw_inline ? 'I'
                    172:                                    : in_extern_C_brace || current_extern_C
                    173:                                    ? 'F' : 'f'),
                    174:                                   rtype.base, args,
                    175:                                   source_filename.base, func_lineno);
                    176:              c = get_token (fp, &buf);
                    177:              if (c == '{')
                    178:                {
                    179:                  /* skip body of (normally) inline function */
                    180:                  skip_to_closing_brace (fp);
                    181:                  goto new_statement;
                    182:                }
                    183:              goto handle_statement;
                    184:            }
                    185:          else if (nextc == ';' && saw_extern)
                    186:            {
                    187:              recognized_extern (buf.base, rtype.base);
                    188:              goto new_statement;
                    189:            }
                    190:          else
                    191:            ungetc (nextc, fp);
                    192:        }
                    193:       else if (followingc != EOF)
                    194:        ungetc (followingc, fp);
                    195:       if (c == ';' || c == '{' || c == '}' || c == EOF)
                    196:        goto handle_statement;
                    197:       sstring_append (&rtype, &buf);
                    198:       if (followingc == ' ' || followingc == '\t' || followingc == '\n')
                    199:        SSTRING_PUT (&rtype, ' ');
                    200:       c = get_token (fp, &buf);
                    201:     }
                    202: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.