fix-header.c

来自「GCC编译器源代码」· C语言 代码 · 共 1,375 行 · 第 1/3 页

C
1,375
字号
/* fix-header.c - Make C header file suitable for C++.   Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.This program is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* This program massages a system include file (such as stdio.h),   into a form that is compatible with GNU C and GNU C++.   * extern "C" { ... } braces are added (inside #ifndef __cplusplus),   if they seem to be needed.  These prevent C++ compilers from name   mangling the functions inside the braces.   * If an old-style incomplete function declaration is seen (without   an argument list), and it is a "standard" function listed in   the file sys-protos.h (and with a non-empty argument list), then   the declaration is converted to a complete prototype by replacing   the empty parameter list with the argument lust from sys-protos.h.   * The program can be given a list of (names of) required standard   functions (such as fclose for stdio.h).  If a required function   is not seen in the input, then a prototype for it will be   written to the output.   * If all of the non-comment code of the original file is protected   against multiple inclusion:	#ifndef FOO	#define FOO	<body of include file>	#endif   then extra matter added to the include file is placed inside the <body>.   * If the input file is OK (nothing needs to be done);   the output file is not written (nor removed if it exists).   There are also some special actions that are done for certain   well-known standard include files:   * If argv[1] is "sys/stat.h", the Posix.1 macros   S_ISBLK, S_ISCHR, S_ISDIR, S_ISFIFO, S_ISLNK, S_ISREG are added if   they were missing, and the corresponding "traditional" S_IFxxx   macros were defined.   * If argv[1] is "errno.h", errno is declared if it was missing.   * TODO:  The input file should be read complete into memory, because:   a) it needs to be scanned twice anyway, and   b) it would be nice to allow update in place.   Usage:	fix-header FOO.H INFILE.H OUTFILE.H [OPTIONS]   where:   * FOO.H is the relative file name of the include file,   as it would be #include'd by a C file.  (E.g. stdio.h)   * INFILE.H is a full pathname for the input file (e.g. /usr/include/stdio.h)   * OUTFILE.H is the full pathname for where to write the output file,   if anything needs to be done.  (e.g. ./include/stdio.h)   * OPTIONS are such as you would pass to cpp.   Written by Per Bothner <bothner@cygnus.com>, July 1993.  */#include <stdio.h>#include <ctype.h>#include "hconfig.h"#include "obstack.h"#include "scan.h"#include "cpplib.h"#include "gansidecl.h"#ifndef O_RDONLY#define O_RDONLY 0#endifextern void cpp_fatal ();#if !__STDC__ && !defined(const)#define const /* nothing */#endifsstring buf;int verbose = 0;int partial_count = 0;int warnings = 0;/* We no longer need to add extern "C", because cpp implicitly   forces the standard include files to be treated as C.  *//*#define ADD_MISSING_EXTERN_C 1 */#if ADD_MISSING_EXTERN_Cint missing_extern_C_count = 0;#endif#include "xsys-protos.h"#ifdef FIXPROTO_IGNORE_LIST/* This is a currently unused feature.  *//* List of files and directories to ignore.   A directory name (ending in '/') means ignore anything in that   directory.  (It might be more efficient to do directory pruning   earlier in fixproto, but this is simpler and easier to customize.) */static char *files_to_ignore[] = {  "X11/",  FIXPROTO_IGNORE_LIST  0};#endifchar *inf_buffer;char *inf_limit;char *inf_ptr;/* Certain standard files get extra treatment */enum special_file{  no_special,  errno_h,  stdio_h,  stdlib_h,  sys_stat_h};/* A NAMELIST is a sequence of names, separated by '\0', and terminated   by an empty name (i.e. by "\0\0").  */typedef const char *namelist;/* The following macros provide the bits for symbol_flags.  */typedef int symbol_flags;/* Used to mark names defined in the ANSI/ISO C standard.  */#define ANSI_SYMBOL 1/* We no longer massage include files for POSIX or XOPEN symbols,   as there are now several versions of the POSIX and XOPEN standards,   and it would be a maintenance nightmare for us to track them all.   Better to be compatible with the system include files.  *//*#define ADD_MISSING_POSIX 1 *//*#define ADD_MISSING_XOPEN 1 */#if ADD_MISSING_POSIX/* Used to mark names defined in the Posix.1 or Posix.2 standard.  */#define POSIX1_SYMBOL 2#define POSIX2_SYMBOL 4#else#define POSIX1_SYMBOL 0#define POSIX2_SYMBOL 0#endif#if ADD_MISSING_XOPEN/* Used to mark names defined in X/Open Portability Guide.  */#define XOPEN_SYMBOL 8/* Used to mark names defined in X/Open UNIX Extensions.  */#define XOPEN_EXTENDED_SYMBOL 16#else#define XOPEN_SYMBOL 0#define XOPEN_EXTENDED_SYMBOL 0#endif/* Used to indicate names that are not functions */#define MACRO_SYMBOL 512struct symbol_list {  symbol_flags flags;  namelist names;};#define SYMBOL_TABLE_SIZE 10struct symbol_list symbol_table[SYMBOL_TABLE_SIZE];int cur_symbol_table_size;voidadd_symbols (flags, names)     symbol_flags flags;     namelist names;{  symbol_table[cur_symbol_table_size].flags = flags;  symbol_table[cur_symbol_table_size].names = names;  cur_symbol_table_size++;  if (cur_symbol_table_size >= SYMBOL_TABLE_SIZE)    fatal ("too many calls to add_symbols");  symbol_table[cur_symbol_table_size].names = NULL; /* Termination.  */}struct std_include_entry {  const char *name;  symbol_flags flags;  namelist names;};const char NONE[] = "";  /* The empty namelist.  *//* Special name to indicate a continuation line in std_include_table.  */const char CONTINUED[] = "";struct std_include_entry *include_entry;struct std_include_entry std_include_table [] = {  { "ctype.h", ANSI_SYMBOL,      "isalnum\0isalpha\0iscntrl\0isdigit\0isgraph\0islower\0\isprint\0ispunct\0isspace\0isupper\0isxdigit\0tolower\0toupper\0" },  { "dirent.h", POSIX1_SYMBOL, "closedir\0opendir\0readdir\0rewinddir\0"},  { "errno.h", ANSI_SYMBOL|MACRO_SYMBOL, "errno\0" },  /* ANSI_SYMBOL is wrong, but ...  */  { "curses.h", ANSI_SYMBOL, "box\0delwin\0endwin\0getcurx\0getcury\0initscr\0\mvcur\0mvwprintw\0mvwscanw\0newwin\0overlay\0overwrite\0\scroll\0subwin\0touchwin\0waddstr\0wclear\0wclrtobot\0wclrtoeol\0\waddch\0wdelch\0wdeleteln\0werase\0wgetch\0wgetstr\0winsch\0winsertln\0\wmove\0wprintw\0wrefresh\0wscanw\0wstandend\0wstandout\0" },  { "fcntl.h", POSIX1_SYMBOL, "creat\0fcntl\0open\0" },  /* Maybe also "getgrent fgetgrent setgrent endgrent" */  { "grp.h", POSIX1_SYMBOL, "getgrgid\0getgrnam\0" },/*{ "limit.h", ... provided by gcc }, */  { "locale.h", ANSI_SYMBOL, "localeconv\0setlocale\0" },  { "math.h", ANSI_SYMBOL,      "acos\0asin\0atan\0atan2\0ceil\0cos\0cosh\0exp\0\fabs\0floor\0fmod\0frexp\0ldexp\0log10\0log\0modf\0pow\0sin\0sinh\0sqrt\0\tan\0tanh\0" },  { CONTINUED, ANSI_SYMBOL|MACRO_SYMBOL, "HUGE_VAL\0" },  { "pwd.h", POSIX1_SYMBOL, "getpwnam\0getpwuid\0" },  /* Left out siglongjmp sigsetjmp - these depend on sigjmp_buf.  */  { "setjmp.h", ANSI_SYMBOL, "longjmp\0setjmp\0" },  /* Left out signal() - its prototype is too complex for us!     Also left out "sigaction sigaddset sigdelset sigemptyset     sigfillset sigismember sigpending sigprocmask sigsuspend"     because these need sigset_t or struct sigaction.     Most systems that provide them will also declare them.  */  { "signal.h", ANSI_SYMBOL, "kill\0raise\0" },  { "stdio.h", ANSI_SYMBOL,      "clearerr\0fclose\0feof\0ferror\0fflush\0fgetc\0fgetpos\0\fgets\0fopen\0fprintf\0fputc\0fputs\0fread\0freopen\0fscanf\0fseek\0\fsetpos\0ftell\0fwrite\0getc\0getchar\0gets\0perror\0\printf\0putc\0putchar\0puts\0remove\0rename\0rewind\0scanf\0setbuf\0\setvbuf\0sprintf\0sscanf\0vprintf\0vsprintf\0vfprintf\0tmpfile\0\tmpnam\0ungetc\0" },  { CONTINUED, POSIX1_SYMBOL, "fdopen\0fileno\0" },  { CONTINUED, POSIX2_SYMBOL, "pclose\0popen\0" },  /* I think ...  *//* Should perhaps also handle NULL, EOF, ... ? */  /* "div ldiv", - ignored because these depend on div_t, ldiv_t     ignore these: "mblen mbstowcs mbstowc wcstombs wctomb"     Left out getgroups, because SunOS4 has incompatible BSD and SVR4 versions.     Should perhaps also add NULL */  { "stdlib.h", ANSI_SYMBOL,      "abort\0abs\0atexit\0atof\0atoi\0atol\0bsearch\0calloc\0\exit\0free\0getenv\0labs\0malloc\0putenv\0qsort\0rand\0realloc\0\srand\0strtod\0strtol\0strtoul\0system\0" },  { CONTINUED, ANSI_SYMBOL|MACRO_SYMBOL, "EXIT_FAILURE\0EXIT_SUCCESS\0" },  { "string.h", ANSI_SYMBOL, "memchr\0memcmp\0memcpy\0memmove\0memset\0\strcat\0strchr\0strcmp\0strcoll\0strcpy\0strcspn\0strerror\0\strlen\0strncat\0strncmp\0strncpy\0strpbrk\0strrchr\0strspn\0strstr\0\strtok\0strxfrm\0" },/* Should perhaps also add NULL and size_t */  { "strings.h", XOPEN_EXTENDED_SYMBOL,      "bcmp\0bcopy\0bzero\0ffs\0index\0rindex\0strcasecmp\0strncasecmp\0" },  { "strops.h", XOPEN_EXTENDED_SYMBOL, "ioctl\0" },  /* Actually, XPG4 does not seem to have <sys/ioctl.h>, but defines     ioctl in <strops.h>.  However, many systems have it is sys/ioctl.h,     and many systems do have <sys/ioctl.h> but not <strops.h>.  */  { "sys/ioctl.h", XOPEN_EXTENDED_SYMBOL, "ioctl\0" },  { "sys/socket.h", XOPEN_EXTENDED_SYMBOL, "socket\0" },  { "sys/stat.h", POSIX1_SYMBOL,      "chmod\0fstat\0mkdir\0mkfifo\0stat\0lstat\0umask\0" },  { CONTINUED, POSIX1_SYMBOL|MACRO_SYMBOL,      "S_ISDIR\0S_ISBLK\0S_ISCHR\0S_ISFIFO\0S_ISREG\0S_ISLNK\0S_IFDIR\0\S_IFBLK\0S_IFCHR\0S_IFIFO\0S_IFREG\0S_IFLNK\0" },  { CONTINUED, XOPEN_EXTENDED_SYMBOL, "fchmod\0" },#if 0/* How do we handle fd_set? */  { "sys/time.h", XOPEN_EXTENDED_SYMBOL, "select\0" },  { "sys/select.h", XOPEN_EXTENDED_SYMBOL /* fake */, "select\0" },#endif  { "sys/times.h", POSIX1_SYMBOL, "times\0" },  /* "sys/types.h" add types (not in old g++-include) */  { "sys/utsname.h", POSIX1_SYMBOL, "uname\0" },  { "sys/wait.h", POSIX1_SYMBOL, "wait\0waitpid\0" },  { CONTINUED, POSIX1_SYMBOL|MACRO_SYMBOL,      "WEXITSTATUS\0WIFEXITED\0WIFSIGNALED\0WIFSTOPPED\0WSTOPSIG\0\WTERMSIG\0WNOHANG\0WNOTRACED\0" },  { "tar.h", POSIX1_SYMBOL, NONE },  { "termios.h", POSIX1_SYMBOL,      "cfgetispeed\0cfgetospeed\0cfsetispeed\0cfsetospeed\0tcdrain\0tcflow\0tcflush\0tcgetattr\0tcsendbreak\0tcsetattr\0" },  { "time.h", ANSI_SYMBOL,      "asctime\0clock\0ctime\0difftime\0gmtime\0localtime\0mktime\0strftime\0time\0tzset\0" },  { "unistd.h", POSIX1_SYMBOL,      "_exit\0access\0alarm\0chdir\0chown\0close\0ctermid\0cuserid\0\dup\0dup2\0execl\0execle\0execlp\0execv\0execve\0execvp\0fork\0fpathconf\0\getcwd\0getegid\0geteuid\0getgid\0getlogin\0getpgrp\0getpid\0\getppid\0getuid\0isatty\0link\0lseek\0pathconf\0pause\0pipe\0read\0rmdir\0\setgid\0setpgid\0setsid\0setuid\0sleep\0sysconf\0tcgetpgrp\0tcsetpgrp\0\ttyname\0unlink\0write\0" },  { CONTINUED, POSIX2_SYMBOL, "getopt\0" },  { CONTINUED, XOPEN_EXTENDED_SYMBOL,      "lockf\0gethostid\0gethostname\0readlink\0" },  { "utime.h", POSIX1_SYMBOL, "utime\0" },  { NULL, 0, NONE }};enum special_file special_file_handling = no_special;/* They are set if the corresponding macro has been seen.  *//* The following are only used when handling sys/stat.h */int seen_S_IFBLK = 0, seen_S_ISBLK  = 0;int seen_S_IFCHR = 0, seen_S_ISCHR  = 0;int seen_S_IFDIR = 0, seen_S_ISDIR  = 0;int seen_S_IFIFO = 0, seen_S_ISFIFO = 0;int seen_S_IFLNK = 0, seen_S_ISLNK  = 0;int seen_S_IFREG = 0, seen_S_ISREG  = 0;/* The following are only used when handling errno.h */int seen_errno = 0;/* The following are only used when handling stdlib.h */int seen_EXIT_FAILURE = 0, seen_EXIT_SUCCESS = 0;/* Wrapper around free, to avoid prototype clashes.  */voidxfree (ptr)     char *ptr;{  free (ptr);}/* Avoid error if config defines abort as fancy_abort.   It's not worth "really" implementing this because ordinary   compiler users never run fix-header.  */voidfancy_abort (){  abort ();}#define obstack_chunk_alloc xmalloc#define obstack_chunk_free xfreestruct obstack scan_file_obstack;/* NOTE:  If you edit this, also edit gen-protos.c !! */struct fn_decl *lookup_std_proto (name, name_length)     const char *name;     int name_length;{  int i = hashf (name, name_length, HASH_SIZE);  int i0 = i;  for (;;)    {      struct fn_decl *fn;      if (hash_tab[i] == 0)	return NULL;      fn = &std_protos[hash_tab[i]];      if (strlen (fn->fname) == name_length	  && strncmp (fn->fname, name, name_length) == 0)	return fn;      i = (i+1) % HASH_SIZE;      if (i == i0)	abort ();    }}char *inc_filename;int inc_filename_length;char *progname = "fix-header";FILE *outf;sstring line;int lbrac_line, rbrac_line;int required_unseen_count = 0;int required_other = 0;void write_lbrac (){  #if ADD_MISSING_EXTERN_C  if (missing_extern_C_count + required_unseen_count > 0)    fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");#endif  if (partial_count)    {      fprintf (outf, "#ifndef _PARAMS\n");      fprintf (outf, "#if defined(__STDC__) || defined(__cplusplus)\n");      fprintf (outf, "#define _PARAMS(ARGS) ARGS\n");      fprintf (outf, "#else\n");      fprintf (outf, "#define _PARAMS(ARGS) ()\n");      fprintf (outf, "#endif\n#endif /* _PARAMS */\n");    }}struct partial_proto{  struct partial_proto *next;  char *fname;	/* name of function */  char *rtype;	/* return type */  struct fn_decl *fn;  int line_seen;};struct partial_proto *partial_proto_list = NULL;struct partial_proto required_dummy_proto, seen_dummy_proto;#define REQUIRED(FN) ((FN)->partial == &required_dummy_proto)#define SET_REQUIRED(FN) ((FN)->partial = &required_dummy_proto)#define SET_SEEN(FN) ((FN)->partial = &seen_dummy_proto)#define SEEN(FN) ((FN)->partial == &seen_dummy_proto)voidrecognized_macro (fname)     char *fname;{  /* The original include file defines fname as a macro.  */  struct fn_decl *fn = lookup_std_proto (fname, strlen (fname));  /* Since fname is a macro, don't require a prototype for it.  */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?