fix-header.c
来自「GCC编译器源代码」· C语言 代码 · 共 1,375 行 · 第 1/3 页
C
1,375 行
if (fn) { if (REQUIRED (fn)) required_unseen_count--; SET_SEEN (fn); } switch (special_file_handling) { case errno_h: if (strcmp (fname, "errno") == 0 && !seen_errno) seen_errno = 1, required_other--; break; case stdlib_h: if (strcmp (fname, "EXIT_FAILURE") == 0 && !seen_EXIT_FAILURE) seen_EXIT_FAILURE = 1, required_other--; if (strcmp (fname, "EXIT_SUCCESS") == 0 && !seen_EXIT_SUCCESS) seen_EXIT_SUCCESS = 1, required_other--; break; case sys_stat_h: if (fname[0] == 'S' && fname[1] == '_') { if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++; else if (strcmp (fname, "S_ISBLK") == 0) seen_S_ISBLK++; else if (strcmp (fname, "S_IFCHR") == 0) seen_S_IFCHR++; else if (strcmp (fname, "S_ISCHR") == 0) seen_S_ISCHR++; else if (strcmp (fname, "S_IFDIR") == 0) seen_S_IFDIR++; else if (strcmp (fname, "S_ISDIR") == 0) seen_S_ISDIR++; else if (strcmp (fname, "S_IFIFO") == 0) seen_S_IFIFO++; else if (strcmp (fname, "S_ISFIFO") == 0) seen_S_ISFIFO++; else if (strcmp (fname, "S_IFLNK") == 0) seen_S_IFLNK++; else if (strcmp (fname, "S_ISLNK") == 0) seen_S_ISLNK++; else if (strcmp (fname, "S_IFREG") == 0) seen_S_IFREG++; else if (strcmp (fname, "S_ISREG") == 0) seen_S_ISREG++; } }}voidrecognized_extern (name, name_length, type, type_length) char *name; char *type; int name_length, type_length;{ switch (special_file_handling) { case errno_h: if (name_length == 5 && strncmp (name, "errno", 5) == 0 && !seen_errno) seen_errno = 1, required_other--; break; }}/* Called by scan_decls if it saw a function definition for a function named FNAME, with return type RTYPE, and argument list ARGS, in source file FILE_SEEN on line LINE_SEEN. KIND is 'I' for an inline function; 'F' if a normal function declaration preceded by 'extern "C"' (or nested inside 'extern "C"' braces); or 'f' for other function declarations. */voidrecognized_function (fname, fname_length, kind, rtype, rtype_length, have_arg_list, file_seen, line_seen) char *fname; int fname_length; int kind; /* One of 'f' 'F' or 'I' */ char *rtype; int rtype_length; int have_arg_list; char *file_seen; int line_seen;{ struct partial_proto *partial; int i; struct fn_decl *fn;#if ADD_MISSING_EXTERN_C if (kind == 'f') missing_extern_C_count++;#endif fn = lookup_std_proto (fname, fname_length); /* Remove the function from the list of required function. */ if (fn) { if (REQUIRED (fn)) required_unseen_count--; SET_SEEN (fn); } /* If we have a full prototype, we're done. */ if (have_arg_list) return; if (kind == 'I') /* don't edit inline function */ return; /* If the partial prototype was included from some other file, we don't need to patch it up (in this run). */ i = strlen (file_seen); if (i < inc_filename_length || strcmp (inc_filename, file_seen + (i - inc_filename_length)) != 0) return; if (fn == NULL) return; if (fn->params[0] == '\0' || strcmp (fn->params, "void") == 0) return; /* We only have a partial function declaration, so remember that we have to add a complete prototype. */ partial_count++; partial = (struct partial_proto *) obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto)); partial->fname = obstack_alloc (&scan_file_obstack, fname_length + 1); bcopy (fname, partial->fname, fname_length); partial->fname[fname_length] = 0; partial->rtype = obstack_alloc (&scan_file_obstack, rtype_length + 1); sprintf (partial->rtype, "%.*s", rtype_length, rtype); partial->line_seen = line_seen; partial->fn = fn; fn->partial = partial; partial->next = partial_proto_list; partial_proto_list = partial; if (verbose) { fprintf (stderr, "(%s: %s non-prototype function declaration.)\n", inc_filename, partial->fname); }}/* For any name in NAMES that is defined as a macro, call recognized_macro on it. */voidcheck_macro_names (pfile, names) cpp_reader *pfile; namelist names;{ while (*names) { if (cpp_lookup (pfile, names, -1, -1)) recognized_macro (names); names += strlen (names) + 1; }}voidread_scan_file (in_fname, argc, argv) char *in_fname; int argc; char **argv;{ cpp_reader scan_in; cpp_options scan_options; struct fn_decl *fn; int i; register struct symbol_list *cur_symbols; obstack_init (&scan_file_obstack); cpp_reader_init (&scan_in); scan_in.data = &scan_options; cpp_options_init (&scan_options); i = cpp_handle_options (&scan_in, argc, argv); if (i < argc && ! CPP_FATAL_ERRORS (&scan_in)) cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]); if (CPP_FATAL_ERRORS (&scan_in)) exit (FATAL_EXIT_CODE); if (! cpp_start_read (&scan_in, in_fname)) exit (FATAL_EXIT_CODE); CPP_OPTIONS (&scan_in)->no_line_commands = 1; scan_decls (&scan_in, argc, argv); for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++) check_macro_names (&scan_in, cur_symbols->names); if (verbose && (scan_in.errors + warnings) > 0) fprintf (stderr, "(%s: %d errors and %d warnings from cpp)\n", inc_filename, scan_in.errors, warnings); if (scan_in.errors) exit (SUCCESS_EXIT_CODE); /* Traditionally, getc and putc are defined in terms of _filbuf and _flsbuf. If so, those functions are also required. */ if (special_file_handling == stdio_h && (fn = lookup_std_proto ("_filbuf", 7)) != NULL) { static char getchar_call[] = "getchar();"; cpp_buffer *buf = cpp_push_buffer (&scan_in, getchar_call, sizeof(getchar_call) - 1); int old_written = CPP_WRITTEN (&scan_in); int seen_filbuf = 0; /* Scan the macro expansion of "getchar();". */ for (;;) { enum cpp_token token = cpp_get_token (&scan_in); int length = CPP_WRITTEN (&scan_in) - old_written; CPP_SET_WRITTEN (&scan_in, old_written); if (token == CPP_EOF) /* Should not happen ... */ break; if (token == CPP_POP && CPP_BUFFER (&scan_in) == buf) { cpp_pop_buffer (&scan_in); break; } if (token == CPP_NAME && length == 7 && strcmp ("_filbuf", scan_in.token_buffer + old_written) == 0) seen_filbuf++; } if (seen_filbuf) { int need_filbuf = !SEEN (fn) && !REQUIRED (fn); struct fn_decl *flsbuf_fn = lookup_std_proto ("_flsbuf", 7); int need_flsbuf = flsbuf_fn && !SEEN (flsbuf_fn) && !REQUIRED (flsbuf_fn); /* Append "_filbuf" and/or "_flsbuf" to the required functions. */ if (need_filbuf + need_flsbuf) { char *new_list; if (need_filbuf) SET_REQUIRED (fn); if (need_flsbuf) SET_REQUIRED (flsbuf_fn); if (need_flsbuf + need_filbuf == 2) new_list = "_filbuf\0_flsbuf\0"; else if (need_flsbuf) new_list = "_flsbuf\0"; else /* if (need_flsbuf) */ new_list = "_filbuf\0"; add_symbols (ANSI_SYMBOL, new_list); required_unseen_count += need_filbuf + need_flsbuf; } } } if (required_unseen_count + partial_count + required_other#if ADD_MISSING_EXTERN_C + missing_extern_C_count#endif == 0) { if (verbose) fprintf (stderr, "%s: OK, nothing needs to be done.\n", inc_filename); exit (SUCCESS_EXIT_CODE); } if (!verbose) fprintf (stderr, "%s: fixing %s\n", progname, inc_filename); else { if (required_unseen_count) fprintf (stderr, "%s: %d missing function declarations.\n", inc_filename, required_unseen_count); if (partial_count) fprintf (stderr, "%s: %d non-prototype function declarations.\n", inc_filename, partial_count);#if ADD_MISSING_EXTERN_C if (missing_extern_C_count) fprintf (stderr, "%s: %d declarations not protected by extern \"C\".\n", inc_filename, missing_extern_C_count);#endif }}voidwrite_rbrac (){ struct fn_decl *fn; const char *cptr; register struct symbol_list *cur_symbols; if (required_unseen_count) {#ifdef NO_IMPLICIT_EXTERN_C fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");#endif } /* Now we print out prototypes for those functions that we haven't seen. */ for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++) { int if_was_emitted = 0; int name_len; cptr = cur_symbols->names; for ( ; (name_len = strlen (cptr)) != 0; cptr+= name_len + 1) { int macro_protect = 0; if (cur_symbols->flags & MACRO_SYMBOL) continue; fn = lookup_std_proto (cptr, name_len); if (fn == NULL || !REQUIRED (fn)) continue; if (!if_was_emitted) {/* what about curses. ??? or _flsbuf/_filbuf ??? */ if (cur_symbols->flags & ANSI_SYMBOL) fprintf (outf, "#if defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined (__STRICT_ANSI__)\n"); else if (cur_symbols->flags & (POSIX1_SYMBOL|POSIX2_SYMBOL)) fprintf (outf, "#if defined(__USE_FIXED_PROTOTYPES__) || (defined(__cplusplus) \\\n\ ? (!defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)) \\\n\ : (defined(__STRICT_ANSI__) && defined(_POSIX_SOURCE)))\n"); else if (cur_symbols->flags & XOPEN_SYMBOL) { fprintf (outf, "#if defined(__USE_FIXED_PROTOTYPES__) \\\n\ || (defined(__STRICT_ANSI__) && defined(_XOPEN_SOURCE))\n"); } else if (cur_symbols->flags & XOPEN_EXTENDED_SYMBOL) { fprintf (outf, "#if defined(__USE_FIXED_PROTOTYPES__) \\\n\ || (defined(__STRICT_ANSI__) && defined(_XOPEN_EXTENDED_SOURCE))\n"); } else { fatal ("internal error for function %s", fn->fname); } if_was_emitted = 1; } /* In the case of memmove, protect in case the application defines it as a macro before including the header. */ if (!strcmp (fn->fname, "memmove") || !strcmp (fn->fname, "vprintf") || !strcmp (fn->fname, "vfprintf") || !strcmp (fn->fname, "vsprintf") || !strcmp (fn->fname, "rewinddir")) macro_protect = 1; if (macro_protect) fprintf (outf, "#ifndef %s\n", fn->fname); fprintf (outf, "extern %s %s (%s);\n", fn->rtype, fn->fname, fn->params); if (macro_protect) fprintf (outf, "#endif\n"); } if (if_was_emitted) fprintf (outf, "#endif /* defined(__USE_FIXED_PROTOTYPES__) || ... */\n"); } if (required_unseen_count) {#ifdef NO_IMPLICIT_EXTERN_C fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");#endif } switch (special_file_handling) { case errno_h: if (!seen_errno) fprintf (outf, "extern int errno;\n"); break; case stdlib_h: if (!seen_EXIT_FAILURE) fprintf (outf, "#define EXIT_FAILURE 1\n"); if (!seen_EXIT_SUCCESS) fprintf (outf, "#define EXIT_SUCCESS 0\n"); break; case sys_stat_h: if (!seen_S_ISBLK && seen_S_IFBLK) fprintf (outf, "#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n"); if (!seen_S_ISCHR && seen_S_IFCHR) fprintf (outf, "#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)\n"); if (!seen_S_ISDIR && seen_S_IFDIR) fprintf (outf, "#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)\n"); if (!seen_S_ISFIFO && seen_S_IFIFO) fprintf (outf, "#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)\n"); if (!seen_S_ISLNK && seen_S_IFLNK) fprintf (outf, "#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)\n"); if (!seen_S_ISREG && seen_S_IFREG) fprintf (outf, "#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)\n"); break; }#if ADD_MISSING_EXTERN_C if (missing_extern_C_count + required_unseen_count > 0) fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");#endif}char *xstrdup (str) char *str;{ char *copy = (char *) xmalloc (strlen (str) + 1); strcpy (copy, str); return copy;}/* Returns 1 iff the file is properly protected from multiple inclusion: #ifndef PROTECT_NAME #define PROTECT_NAME #endif */#define INF_GET() (inf_ptr < inf_limit ? *(unsigned char *) inf_ptr++ : EOF)#define INF_UNGET(c) ((c)!=EOF && inf_ptr--)intinf_skip_spaces (c) int c;{ for (;;) { if (c == ' ' || c == '\t') c = INF_GET (); else if (c == '/') { c = INF_GET (); if (c != '*') { INF_UNGET (c); return '/'; } c = INF_GET (); for (;;) { if (c == EOF) return EOF; else if (c != '*') { if (c == '\n') source_lineno++, lineno++; c = INF_GET (); } else if ((c = INF_GET ()) == '/') return INF_GET (); } } else break; } return c;}/* Read into STR from inf_buffer upto DELIM. */intinf_read_upto (str, delim)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?