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