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 /* This filter scans a C source file (actually, the output of cpp).
19 It looks for function declaration. For each declaration, it prints:
21 NAME;C;RTYPE;ARGS;FILENAME;LINENO;
23 NAME is the function's name.
24 C is "I" if the function is declared as inline; "F" if the
25 declaration is nested inside 'extern "C"' braces; otherwise "f".
26 RTYPE is the function's return type.
27 ARGS is the function's argument list.
28 FILENAME and LINENO is where the declarations was seen
29 (taking #-directives into account).
34 indicates that the macro NAME was seen (when invoked from fixproto).
36 indicates that 'extern TYPE NAME;' was seen.
38 Written by Per Bothner <bothner@cygnus.com>, July 1993.
48 int brace_nesting = 0;
50 /* The first extern_C_braces_length elements of extern_C_braces
51 indicate the (brace nesting levels of) left braces that were
52 prefixed by extern "C". */
53 int extern_C_braces_length = 0;
54 char extern_C_braces[20];
55 #define in_extern_C_brace (extern_C_braces_length>0)
57 /* True if the function declaration currently being scanned is
58 prefixed by extern "C". */
59 int current_extern_C = 0;
62 skip_to_closing_brace (fp)
68 int c = get_token (fp, &buf);
73 if (c == '}' && --nesting == 0)
83 int saw_extern, saw_inline;
86 c = get_token (fp, &buf);
93 /* pop an 'extern "C"' nesting level, if appropriate */
94 if (extern_C_braces_length
95 && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
96 extern_C_braces_length--;
109 if (c != IDENTIFIER_TOKEN)
111 rtype.ptr = rtype.base;
112 if (SSTRING_LENGTH (&buf) > 16
113 && strncmp (buf.base, "__DEFINED_MACRO_", 16) == 0)
115 fprintf (stdout, "%s;M;\n", buf.base+16);
118 if (strcmp (buf.base, "inline") == 0)
121 c = get_token (fp, &buf);
123 if (strcmp (buf.base, "extern") == 0)
126 c = get_token (fp, &buf);
127 if (c == STRING_TOKEN && strcmp (buf.base, "C") == 0)
129 current_extern_C = 1;
130 c = get_token (fp, &buf);
134 extern_C_braces[extern_C_braces_length++] = brace_nesting;
137 c = get_token (fp, &buf);
142 int followingc = getc (fp); /* char following token in buf */
144 MAKE_SSTRING_SPACE(&rtype, 1);
147 if (c == IDENTIFIER_TOKEN)
149 int nextc = skip_spaces (fp, followingc);
154 fprintf (stdout, "%s;%s;%s;",
157 : in_extern_C_brace || current_extern_C ? "F" : "f",
159 c = skip_spaces (fp, ' ');
174 fprintf (stdout, ";%s;%d;\n",
175 source_filename.base, source_lineno);
176 c = get_token (fp, &buf);
179 /* skip body of (normally) inline function */
180 skip_to_closing_brace (fp);
183 goto handle_statement;
185 else if (nextc == ';' && saw_extern)
187 fprintf (stdout, "%s;X;%s;\n", buf.base, rtype.base);
188 goto handle_statement;
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);