protoize.c
来自「GCC编译器源代码」· C语言 代码 · 共 2,228 行 · 第 1/5 页
C
2,228 行
For any given chain, the item at the head of the chain is the *leftmost* parameter list seen in the actual C language function declaration. If there are other members of the chain, then these are linked in left-to-right order from the head of the chain. */struct f_list_chain_item_struct { const f_list_chain_item * chain_next; /* -> to next item on chain */ const char * formals_list; /* -> to formals list string */};/* The following struct holds all of the important information about any single function definition or declaration which we need to know about. Note that for unprotoize we don't need to know very much because we never even create records for stuff that we don't intend to convert (like for instance defs and decs which are already in old K&R format and "implicit" function declarations). */struct def_dec_info_struct { const def_dec_info * next_in_file; /* -> to rest of chain for file */ file_info * file; /* -> file_info for containing file */ int line; /* source line number of def/dec */ const char * ansi_decl; /* -> left end of ansi decl */ hash_table_entry * hash_entry; /* -> hash entry for function name */ unsigned int is_func_def; /* = 0 means this is a declaration */ const def_dec_info * next_for_func; /* -> to rest of chain for func name */ unsigned int f_list_count; /* count of formals lists we expect */ char prototyped; /* = 0 means already prototyped */#ifndef UNPROTOIZE const f_list_chain_item * f_list_chain; /* -> chain of formals lists */ const def_dec_info * definition; /* -> def/dec containing related def */ char is_static; /* = 0 means visibility is "extern" */ char is_implicit; /* != 0 for implicit func decl's */ char written; /* != 0 means written for implicit */#else /* !defined (UNPROTOIZE) */ const char * formal_names; /* -> to list of names of formals */ const char * formal_decls; /* -> to string of formal declarations */#endif /* !defined (UNPROTOIZE) */};/* Pointer to the tail component of the filename by which this program was invoked. Used everywhere in error and warning messages. */static const char *pname;/* Error counter. Will be non-zero if we should give up at the next convenient stopping point. */static int errors = 0;/* Option flags. *//* ??? These comments should say what the flag mean as well as the options that set them. *//* File name to use for running gcc. Allows GCC 2 to be named something other than gcc. */static const char *compiler_file_name = "gcc";static int version_flag = 0; /* Print our version number. */static int quiet_flag = 0; /* Don't print messages normally. */static int nochange_flag = 0; /* Don't convert, just say what files we would have converted. */static int nosave_flag = 0; /* Don't save the old version. */static int keep_flag = 0; /* Don't delete the .X files. */static const char ** compile_params = 0; /* Option string for gcc. */#ifdef UNPROTOIZEstatic const char *indent_string = " "; /* Indentation for newly inserted parm decls. */#else /* !defined (UNPROTOIZE) */static int local_flag = 0; /* Insert new local decls (when?). */static int global_flag = 0; /* set by -g option */static int cplusplus_flag = 0; /* Rename converted files to *.C. */static const char *nondefault_syscalls_dir = 0; /* Dir to look for SYSCALLS.c.X in. */#endif /* !defined (UNPROTOIZE) *//* An index into the compile_params array where we should insert the source file name when we are ready to exec the C compiler. A zero value indicates that we have not yet called munge_compile_params. */static int input_file_name_index = 0;/* An index into the compile_params array where we should insert the filename for the aux info file, when we run the C compiler. */static int aux_info_file_name_index = 0;/* Count of command line arguments which were "filename" arguments. */static int n_base_source_files = 0;/* Points to a malloc'ed list of pointers to all of the filenames of base source files which were specified on the command line. */static const char **base_source_filenames;/* Line number of the line within the current aux_info file that we are currently processing. Used for error messages in case the prototypes info file is corrupted somehow. */static int current_aux_info_lineno;/* Pointer to the name of the source file currently being converted. */static const char *convert_filename;/* Pointer to relative root string (taken from aux_info file) which indicates where directory the user was in when he did the compilation step that produced the containing aux_info file. */static const char *invocation_filename;/* Pointer to the base of the input buffer that holds the original text for the source file currently being converted. */static const char *orig_text_base;/* Pointer to the byte just beyond the end of the input buffer that holds the original text for the source file currently being converted. */static const char *orig_text_limit;/* Pointer to the base of the input buffer that holds the cleaned text for the source file currently being converted. */static const char *clean_text_base;/* Pointer to the byte just beyond the end of the input buffer that holds the cleaned text for the source file currently being converted. */static const char *clean_text_limit;/* Pointer to the last byte in the cleaned text buffer that we have already (virtually) copied to the output buffer (or decided to ignore). */static const char * clean_read_ptr;/* Pointer to the base of the output buffer that holds the replacement text for the source file currently being converted. */static char *repl_text_base;/* Pointer to the byte just beyond the end of the output buffer that holds the replacement text for the source file currently being converted. */static char *repl_text_limit;/* Pointer to the last byte which has been stored into the output buffer. The next byte to be stored should be stored just past where this points to. */static char * repl_write_ptr;/* Pointer into the cleaned text buffer for the source file we are currently converting. This points to the first character of the line that we last did a "seek_to_line" to (see below). */static const char *last_known_line_start;/* Number of the line (in the cleaned text buffer) that we last did a "seek_to_line" to. Will be one if we just read a new source file into the cleaned text buffer. */static int last_known_line_number;/* The filenames hash table. */static hash_table filename_primary;/* The function names hash table. */static hash_table function_name_primary;/* The place to keep the recovery address which is used only in cases where we get hopelessly confused by something in the cleaned original text. */static jmp_buf source_confusion_recovery;/* A pointer to the current directory filename (used by abspath). */static char *cwd_buffer;/* A place to save the read pointer until we are sure that an individual attempt at editing will succeed. */static const char * saved_clean_read_ptr;/* A place to save the write pointer until we are sure that an individual attempt at editing will succeed. */static char * saved_repl_write_ptr;/* Forward declaration. */static const char *shortpath ();char *my_strerror(e) int e;{#ifdef HAVE_STRERROR return strerror(e);#else static char buffer[30]; if (!e) return ""; if (e > 0 && e < sys_nerr) return sys_errlist[e]; sprintf (buffer, "Unknown error %d", e); return buffer;#endif}/* Allocate some space, but check that the allocation was successful. *//* alloca.c uses this, so don't make it static. */pointer_typexmalloc (byte_count) size_t byte_count;{ pointer_type rv; rv = (pointer_type) malloc (byte_count); if (rv == NULL) { fprintf (stderr, "\n%s: virtual memory exceeded\n", pname); exit (FATAL_EXIT_CODE); return 0; /* avoid warnings */ } else return rv;}/* Reallocate some space, but check that the reallocation was successful. */pointer_typexrealloc (old_space, byte_count) pointer_type old_space; size_t byte_count;{ pointer_type rv; rv = (pointer_type) realloc (old_space, byte_count); if (rv == NULL) { fprintf (stderr, "\n%s: virtual memory exceeded\n", pname); exit (FATAL_EXIT_CODE); return 0; /* avoid warnings */ } else return rv;}/* Deallocate the area pointed to by an arbitrary pointer, but first, strip the `const' qualifier from it and also make sure that the pointer value is non-null. */voidxfree (p) const_pointer_type p;{ if (p) free ((NONCONST pointer_type) p);}/* Make a copy of a string INPUT with size SIZE. */static char *savestring (input, size) const char *input; unsigned int size;{ char *output = (char *) xmalloc (size + 1); strcpy (output, input); return output;}/* Make a copy of the concatenation of INPUT1 and INPUT2. */static char *savestring2 (input1, size1, input2, size2) const char *input1; unsigned int size1; const char *input2; unsigned int size2;{ char *output = (char *) xmalloc (size1 + size2 + 1); strcpy (output, input1); strcpy (&output[size1], input2); return output;}/* More 'friendly' abort that prints the line and file. config.h can #define abort fancy_abort if you like that sort of thing. */voidfancy_abort (){ fprintf (stderr, "%s: internal abort\n", pname); exit (FATAL_EXIT_CODE);}/* Make a duplicate of the first N bytes of a given string in a newly allocated area. */static char *dupnstr (s, n) const char *s; size_t n;{ char *ret_val = (char *) xmalloc (n + 1); strncpy (ret_val, s, n); ret_val[n] = '\0'; return ret_val;}/* Return a pointer to the first occurrence of s2 within s1 or NULL if s2 does not occur within s1. Assume neither s1 nor s2 are null pointers. */static const char *substr (s1, s2) const char *s1; const char *const s2;{ for (; *s1 ; s1++) { const char *p1; const char *p2; int c; for (p1 = s1, p2 = s2; c = *p2; p1++, p2++) if (*p1 != c) goto outer; return s1;outer: ; } return 0;}/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME, retrying if necessary. Return the actual number of bytes read. */static intsafe_read (desc, ptr, len) int desc; char *ptr; int len;{ int left = len; while (left > 0) { int nchars = read (desc, ptr, left); if (nchars < 0) {#ifdef EINTR if (errno == EINTR) continue;#endif return nchars; } if (nchars == 0) break; ptr += nchars; left -= nchars; } return len - left;}/* Write LEN bytes at PTR to descriptor DESC, retrying if necessary, and treating any real error as fatal. */static voidsafe_write (desc, ptr, len, out_fname) int desc; char *ptr; int len; char *out_fname;{ while (len > 0) { int written = write (desc, ptr, len); if (written < 0) {#ifdef EINTR if (errno == EINTR) continue;#endif fprintf (stderr, "%s: error writing file `%s': %s\n", pname, shortpath (NULL, out_fname), my_strerror(errno)); return; } ptr += written; len -= written; }}/* Get setup to recover in case the edit we are about to do goes awry. */voidsave_pointers (){ saved_clean_read_ptr = clean_read_ptr; saved_repl_write_ptr = repl_write_ptr;}/* Call this routine to recover our previous state whenever something looks too confusing in the source code we are trying to edit. */voidrestore_pointers (){ clean_read_ptr = saved_clean_read_ptr; repl_write_ptr = saved_repl_write_ptr;}/* Return true if the given character is a valid identifier character. */static intis_id_char (ch) char ch;{ return (isalnum (ch) || (ch == '_') || (ch == '$'));}/* Give a message indicating the proper way to invoke this program and then exit with non-zero status. */static voidusage (){#ifdef UNPROTOIZE fprintf (stderr, "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n", pname, pname);#else /* !defined (UNPROTOIZE) */ fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n", pname, pname);#endif /* !defined (UNPROTOIZE) */ exit (FATAL_EXIT_CODE);}/* Return true if the given filename (assumed to be an absolute filename) designates a file residing anywhere beneath any one of the "system"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?