1 /* scan-decls.c - Extracts declarations from cpp output.
2 Copyright (C) 1993 Free Software Foundation, Inc.
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
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.
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.
18 Written by Per Bothner <bothner@cygnus.com>, July 1993. */
31 int brace_nesting = 0;
33 /* The first extern_C_braces_length elements of extern_C_braces
34 indicate the (brace nesting levels of) left braces that were
35 prefixed by extern "C". */
36 int extern_C_braces_length = 0;
37 char extern_C_braces[20];
38 #define in_extern_C_brace (extern_C_braces_length>0)
40 /* True if the function declaration currently being scanned is
41 prefixed by extern "C". */
42 int current_extern_C = 0;
45 skip_to_closing_brace (fp)
51 int c = get_token (fp, &buf);
56 if (c == '}' && --nesting == 0)
61 /* This function scans a C source file (actually, the output of cpp),
62 reading from FP. It looks for function declarations, and certain
63 other interesting sequences (external variables and macros). */
70 int saw_extern, saw_inline;
73 c = get_token (fp, &buf);
80 /* Pop an 'extern "C"' nesting level, if appropriate. */
81 if (extern_C_braces_length
82 && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
83 extern_C_braces_length--;
96 if (c != IDENTIFIER_TOKEN)
98 rtype.ptr = rtype.base;
99 if (SSTRING_LENGTH (&buf) > 16
100 && strncmp (buf.base, "__DEFINED_MACRO_", 16) == 0)
102 /* For certain interesting macro names, fixproto puts
106 into the file to be pre-processed. So if we see __DEFINED_MACRO_FOO,
107 it means FOO was defined, which we may want to make a note of. */
108 recognized_macro (buf.base+16);
111 if (strcmp (buf.base, "inline") == 0)
114 c = get_token (fp, &buf);
116 if (strcmp (buf.base, "extern") == 0)
119 c = get_token (fp, &buf);
120 if (c == STRING_TOKEN && strcmp (buf.base, "C") == 0)
122 current_extern_C = 1;
123 c = get_token (fp, &buf);
127 extern_C_braces[extern_C_braces_length++] = brace_nesting;
130 c = get_token (fp, &buf);
135 int followingc = getc (fp); /* char following token in buf */
137 MAKE_SSTRING_SPACE (&rtype, 1);
140 if (c == IDENTIFIER_TOKEN)
142 int nextc = skip_spaces (fp, followingc);
146 int func_lineno = source_lineno;
149 arg_list.ptr = arg_list.base;
166 SSTRING_PUT (&arg_list, c);
168 SSTRING_PUT (&arg_list, '\0');
169 args = arg_list.base;
172 recognized_function (buf.base,
174 : in_extern_C_brace || current_extern_C
177 source_filename.base, func_lineno);
178 c = get_token (fp, &buf);
181 /* skip body of (normally) inline function */
182 skip_to_closing_brace (fp);
185 goto handle_statement;
187 else if (nextc == ';' && saw_extern)
189 recognized_extern (buf.base, rtype.base);
190 goto handle_statement;
195 else if (followingc != EOF)
196 ungetc (followingc, fp);
197 if (c == ';' || c == '{' || c == '}' || c == EOF)
198 goto handle_statement;
199 sstring_append (&rtype, &buf);
200 if (followingc == ' ' || followingc == '\t' || followingc == '\n')
201 SSTRING_PUT (&rtype, ' ');
202 c = get_token (fp, &buf);