|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.