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 + -
显示快捷键?