aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>1995-04-05 21:16:26 +0000
committerbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>1995-04-05 21:16:26 +0000
commitff8281e42fe545a0b86d5f185b9f44ea4f4c55a2 (patch)
tree444e0bc9b38ad6819d87db5007348f663acf5e60 /gcc
parentad0e2334a8dbbaec4d046a4929b08571197a8ec8 (diff)
Re-write fixproto/fix-header/etc to use cpplib.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@9316 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/Makefile.in13
-rw-r--r--gcc/fix-header.c497
-rwxr-xr-xgcc/fixproto87
-rw-r--r--gcc/gen-protos.c29
-rw-r--r--gcc/scan-decls.c177
-rw-r--r--gcc/scan.c39
-rw-r--r--gcc/scan.h2
7 files changed, 543 insertions, 301 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0fb85cae6c2..49eb98795ec 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1736,9 +1736,9 @@ deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs
$(SHELL) $(srcdir)/scan-types.sh "$(srcdir)" >tmp-deduced.h
mv tmp-deduced.h deduced.h
-gen-protos: gen-protos.o scan.o $(HOST_LIBDEPS)
+gen-protos: gen-protos.o scan.o cppalloc.o $(HOST_LIBDEPS)
${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o gen-protos \
- gen-protos.o scan.o $(HOST_LIBS)
+ gen-protos.o scan.o cppalloc.o $(HOST_LIBS)
gen-protos.o: gen-protos.c scan.h hconfig.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c
@@ -1755,9 +1755,9 @@ xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos Makefil
mv xsys-protos.hT xsys-protos.h
rm -rf fixtmp.c
-fix-header: fix-header.o scan-decls.o scan.o xsys-protos.h $(HOST_LIBDEPS)
+fix-header: fix-header.o scan-decls.o scan.o xsys-protos.h $(HOST_LIBDEPS) cpplib.o cpphash.o cppalloc.o cppexp.o cpperror.o version.o
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o fix-header \
- fix-header.o scan-decls.o scan.o $(HOST_LIBS)
+ fix-header.o scan-decls.o scan.o cpplib.o cpphash.o cppalloc.o version.o cppexp.o $(HOST_LIBS)
fix-header.o: fix-header.c obstack.h scan.h xsys-protos.h hconfig.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c
@@ -1785,9 +1785,8 @@ stmp-fixproto: fixhdr.ready fixproto stmp-headers
-if [ -f include/fixed ] ; then true; \
else \
: This line works around a 'make' bug in BSDI 1.1.; \
- CPP="$(GCC_FOR_TARGET) -E"; export CPP; \
- FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \
- $(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
+ FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \
+ $(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
touch include/fixed; \
fi
touch stmp-fixproto
diff --git a/gcc/fix-header.c b/gcc/fix-header.c
index c21acf05476..4056605b8b7 100644
--- a/gcc/fix-header.c
+++ b/gcc/fix-header.c
@@ -1,5 +1,5 @@
/* fix-header.c - Make C header file suitable for C++.
- Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -59,15 +59,14 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
b) it would be nice to allow update in place.
Usage:
- fix-header FOO.H INFILE.H OUTFILE.H REQUIRED_FUNCS <SCAN-FILE
+ 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)
- * SCAN-FILE is the output of the scan-decls program.
- * REQUIRED_FUNCS is a list of required function (e.g. fclose for stdio.h).
+ * OPTIONS are such as you would pass to cpp.
Written by Per Bothner <bothner@cygnus.com>, July 1993. */
@@ -81,22 +80,44 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "hconfig.h"
#include "obstack.h"
#include "scan.h"
+#include "cpplib.h"
-extern sstring buf;
+#if !__STDC__
+#define const /* nothing */
+#endif
+
+sstring buf;
int verbose = 0;
int partial_count = 0;
-#if 0
-/* All uses of this are ifdefed out. This is no longer needed, because
- cccp.c implicitly forces the standard include files to be treated as C.
- Adding an explicit extern "C" is undesireable as it breaks the SunOS 4.x
- sun4c/romvec.h file. */
+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_C
int missing_extern_C_count = 0;
#endif
int missing_errno = 0;
#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
+};
+#endif
+
char *inf_buffer;
char *inf_limit;
char *inf_ptr;
@@ -106,8 +127,134 @@ char *inf_ptr;
enum special_file
{
no_special,
- errno_special,
- sys_stat_special
+ errno_h,
+ stdio_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;
+
+struct std_include_entry {
+ const char *name;
+ namelist required;
+ namelist extra;
+ int special;
+};
+
+/* End of namelist NAMES. */
+
+namelist
+namelist_end (names)
+ namelist names;
+{
+ register namelist ptr;
+ for (ptr = names; ; ptr++)
+ {
+ if (*ptr == '\0')
+ {
+ ptr++;
+ if (*ptr == '\0')
+ return ptr;
+ }
+ }
+}
+
+const char NONE[] = "";
+
+struct std_include_entry *include_entry;
+
+struct std_include_entry std_include_table [] = {
+ { "ctype.h",
+ "isalnum\0isalpha\0iscntrl\0isdigit\0isgraph\0islower\0\
+isprint\0ispunct\0isspace\0isupper\0isxdigit\0tolower\0toupper\0", NONE },
+
+ { "dirent.h", "closedir\0opendir\0readdir\0rewinddir\0", NONE},
+
+ { "errno.h", NONE, "errno\0" },
+
+ { "curses.h", "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", NONE },
+
+ { "fcntl.h", "creat\0fcntl\0open\0", NONE },
+
+ /* Maybe also "getgrent fgetgrent setgrent endgrent" */
+ { "grp.h", "getgrgid\0getgrnam\0", NONE },
+
+/*{ "limit.h", ... provided by gcc }, */
+
+ { "locale.h", "localeconv\0setlocale\0", NONE },
+
+ { "math.h", "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", "HUGE_VAL\0" },
+
+ { "pwd.h", "getpwnam\0getpwuid\0", NONE },
+
+ /* Left out siglongjmp sigsetjmp - these depend on sigjmp_buf. */
+ { "setjmp.h", "longjmp\0setjmp\0", NONE },
+
+ /* 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", "kill\0raise\0", NONE },
+
+ { "stdio.h", "clearerr\0fclose\0feof\0ferror\0fflush\0fgetc\0fgetpos\0\
+fgets\0fopen\0fprintf\0fputc\0fputs\0fread\0freopen\0fscanf\0fseek\0\
+fsetpos\0ftell\0fwrite\0getc\0getchar\0gets\0pclose\0perror\0popen\0\
+printf\0putc\0putchar\0puts\0remove\0rename\0rewind\0scanf\0setbuf\0\
+setvbuf\0sprintf\0sscanf\0vprintf\0vsprintf\0vfprintf\0tmpfile\0\
+tmpnam\0ungetc\0", NONE },
+/* 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", "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", NONE },
+
+ { "string.h", "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", NONE },
+/* Should perhaps also add NULL and size_t */
+
+ { "sys/stat.h", "chmod\0fstat\0mkdir\0mkfifo\0stat\0lstat\0umask\0",
+ "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" },
+
+ { "sys/times.h", "times\0", NONE },
+ /* "sys/types.h" add types (not in old g++-include) */
+
+ { "sys/utsname.h", "uname\0", NONE },
+
+ { "sys/wait.h", "wait\0waitpid\0",
+ "WEXITSTATUS\0WIFEXITED\0WIFSIGNALED\0WIFSTOPPED\0WSTOPSIG\0\
+WTERMSIG\0WNOHANG\0WNOTRACED\0" },
+
+ { "tar.h", NONE, NONE },
+
+ { "termios.h", "cfgetispeed\0cfgetospeed\0cfsetispeed\0cfsetospeed\0tcdrain\0tcflow\0tcflush\0tcgetattr\0tcsendbreak\0tcsetattr\0", NONE },
+
+ { "time.h", "asctime\0clock\0ctime\0difftime\0gmtime\0localtime\0mktime\0strftime\0time\0tzset\0", NONE },
+
+ { "unistd.h", "_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\0getopt\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", NONE },
+
+ { 0, NONE, NONE }
};
enum special_file special_file_handling = no_special;
@@ -146,10 +293,11 @@ struct obstack scan_file_obstack;
/* NOTE: If you edit this, also edit gen-protos.c !! */
struct fn_decl *
-lookup_std_proto (name)
- char *name;
+lookup_std_proto (name, name_length)
+ const char *name;
+ int name_length;
{
- int i = hash (name) % HASH_SIZE;
+ int i = hashf (name, name_length, HASH_SIZE);
int i0 = i;
for (;;)
{
@@ -157,7 +305,8 @@ lookup_std_proto (name)
if (hash_tab[i] == 0)
return NULL;
fn = &std_protos[hash_tab[i]];
- if (strcmp (fn->fname, name) == 0)
+ if (strlen (fn->fname) == name_length
+ && strncmp (fn->fname, name, name_length) == 0)
return fn;
i = (i+1) % HASH_SIZE;
if (i == i0)
@@ -173,14 +322,14 @@ sstring line;
int lbrac_line, rbrac_line;
-char **required_functions;
-int required_unseen_count;
+namelist required_functions_list;
+int required_unseen_count = 0;
void
write_lbrac ()
{
-#if 0
+#if ADD_MISSING_EXTERN_C
if (missing_extern_C_count + required_unseen_count > 0)
fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
#endif
@@ -207,31 +356,33 @@ struct partial_proto
struct partial_proto *partial_proto_list = NULL;
-struct partial_proto required_dummy_proto;
+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 CLEAR_REQUIRED(FN) ((FN)->partial = 0)
+#define SET_SEEN(FN) ((FN)->partial = &seen_dummy_proto)
+#define SEEN(FN) ((FN)->partial == &seen_dummy_proto)
void
recognized_macro (fname)
char *fname;
{
/* The original include file defines fname as a macro. */
- struct fn_decl *fn = lookup_std_proto (fname);
+ struct fn_decl *fn = lookup_std_proto (fname, strlen (fname));
/* Since fname is a macro, don't require a prototype for it. */
- if (fn && REQUIRED (fn))
+ if (fn)
{
- CLEAR_REQUIRED (fn);
- required_unseen_count--;
+ if (REQUIRED (fn))
+ required_unseen_count--;
+ SET_SEEN (fn);
}
switch (special_file_handling)
{
- case errno_special:
+ case errno_h:
if (strcmp (fname, "errno") == 0) missing_errno = 0;
break;
- case sys_stat_special:
+ case sys_stat_h:
if (fname[0] == 'S' && fname[1] == '_')
{
if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++;
@@ -251,14 +402,15 @@ recognized_macro (fname)
}
void
-recognized_extern (name, type)
+recognized_extern (name, name_length, type, type_length)
char *name;
char *type;
+ int name_length, type_length;
{
switch (special_file_handling)
{
- case errno_special:
- if (strcmp (name, "errno") == 0) missing_errno = 0;
+ case errno_h:
+ if (strncmp (name, "errno", name_length) == 0) missing_errno = 0;
break;
}
}
@@ -272,33 +424,38 @@ recognized_extern (name, type)
'f' for other function declarations. */
void
-recognized_function (fname, kind, rtype, args, file_seen, line_seen)
+recognized_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;
- char *args;
+ int rtype_length;
+ int have_arg_list;
char *file_seen;
int line_seen;
{
struct partial_proto *partial;
int i;
struct fn_decl *fn;
-#if 0
+#if ADD_MISSING_EXTERN_C
if (kind == 'f')
missing_extern_C_count++;
#endif
- fn = lookup_std_proto (fname);
+ fn = lookup_std_proto (fname, fname_length);
/* Remove the function from the list of required function. */
- if (fn && REQUIRED (fn))
+ if (fn)
{
- CLEAR_REQUIRED (fn);
- required_unseen_count--;
+ if (REQUIRED (fn))
+ required_unseen_count--;
+ SET_SEEN (fn);
}
/* If we have a full prototype, we're done. */
- if (args[0] != '\0')
+ if (have_arg_list)
return;
if (kind == 'I') /* don't edit inline function */
@@ -321,10 +478,11 @@ recognized_function (fname, kind, rtype, args, file_seen, line_seen)
partial_count++;
partial = (struct partial_proto*)
obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
- partial->fname = obstack_alloc (&scan_file_obstack, strlen (fname) + 1);
- strcpy (partial->fname, fname);
- partial->rtype = obstack_alloc (&scan_file_obstack, strlen (rtype) + 1);
- strcpy (partial->rtype, rtype);
+ 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;
@@ -333,20 +491,122 @@ recognized_function (fname, kind, rtype, args, file_seen, line_seen)
if (verbose)
{
fprintf (stderr, "(%s: %s non-prototype function declaration.)\n",
- inc_filename, fname);
+ inc_filename, partial->fname);
+ }
+}
+
+/* For any name in NAMES that is defined as a macro,
+ call recognized_macro on it. */
+
+void
+check_macro_names (pfile, names)
+ struct parse_file *pfile;
+ namelist names;
+{
+ while (*names)
+ {
+ if (cpp_lookup (pfile, names, -1, -1))
+ recognized_macro (names);
+ names += strlen (names) + 1;
}
}
void
-read_scan_file (scan_file)
- FILE *scan_file;
+read_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;
+
obstack_init (&scan_file_obstack);
- scan_decls (scan_file);
+ init_parse_file (&scan_in);
+ scan_in.data = &scan_options;
+ init_parse_options (&scan_options);
+ i = cpp_handle_options (&scan_in, argc, argv);
+ if (i < argc)
+ fatal ("Invalid option `%s'", argv[i]);
+ push_parse_file (&scan_in, in_fname);
+ CPP_OPTIONS (&scan_in)->no_line_commands = 1;
+
+ scan_decls (&scan_in, argc, argv);
+ check_macro_names (&scan_in, include_entry->required);
+ check_macro_names (&scan_in, include_entry->extra);
+
+ 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 (0);
+
+ /* 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 end of
+ required_functions_list. */
+ if (need_filbuf + need_flsbuf)
+ {
+ int old_len = namelist_end (required_functions_list)
+ - required_functions_list;
+ char *new_list = (char*) xmalloc (old_len + 20);
+ bcopy (required_functions_list, new_list, old_len);
+ if (need_filbuf)
+ {
+ strcpy (new_list + old_len, "_filbuf");
+ old_len += 8;
+ SET_REQUIRED (fn);
+ }
+ if (need_flsbuf)
+ {
+ strcpy (new_list + old_len, "_flsbuf");
+ old_len += 8;
+ SET_REQUIRED (flsbuf_fn);
+ }
+ new_list[old_len] = '\0';
+ required_functions_list = (namelist)new_list;
+ required_unseen_count += need_filbuf + need_flsbuf;
+ }
+ }
+ }
if (required_unseen_count + partial_count + missing_errno
-#if 0
+#if ADD_MISSING_EXTERN_C
+ missing_extern_C_count
#endif
== 0)
@@ -365,7 +625,7 @@ read_scan_file (scan_file)
if (partial_count)
fprintf (stderr, "%s: %d non-prototype function declarations.\n",
inc_filename, partial_count);
-#if 0
+#if ADD_MISSING_EXTERN_C
if (missing_extern_C_count)
fprintf (stderr,
"%s: %d declarations not protected by extern \"C\".\n",
@@ -378,7 +638,7 @@ void
write_rbrac ()
{
struct fn_decl *fn;
- char **rptr;
+ const char *cptr;
if (required_unseen_count)
{
@@ -390,11 +650,13 @@ write_rbrac ()
}
/* Now we print out prototypes for those functions that we haven't seen. */
- for (rptr = required_functions; *rptr; rptr++)
+ for (cptr = required_functions_list; *cptr!= '\0'; )
{
int macro_protect = 0;
+ int name_len = strlen (cptr);
- fn = lookup_std_proto (*rptr);
+ fn = lookup_std_proto (cptr, name_len);
+ cptr+= name_len + 1;
if (fn == NULL || !REQUIRED (fn))
continue;
@@ -425,11 +687,11 @@ write_rbrac ()
switch (special_file_handling)
{
- case errno_special:
+ case errno_h:
if (missing_errno)
fprintf (outf, "extern int errno;\n");
break;
- case sys_stat_special:
+ case sys_stat_h:
if (!seen_S_ISBLK && seen_S_IFBLK)
fprintf (outf,
"#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n");
@@ -452,7 +714,7 @@ write_rbrac ()
}
-#if 0
+#if ADD_MISSING_EXTERN_C
if (missing_extern_C_count + required_unseen_count > 0)
fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");
#endif
@@ -674,7 +936,7 @@ main (argc, argv)
struct stat sbuf;
int c;
int i, done;
- char *cptr, *cptr0, **pptr;
+ const char *cptr0, *cptr, **pptr;
int ifndef_line;
int endif_line;
long to_read;
@@ -693,34 +955,58 @@ main (argc, argv)
if (argc < 4)
{
- fprintf (stderr, "%s: Usage: foo.h infile.h outfile.h req_funcs <scan-file-name\n",
+ fprintf (stderr, "%s: Usage: foo.h infile.h outfile.h options\n",
progname);
exit (-1);
}
inc_filename = argv[1];
inc_filename_length = strlen (inc_filename);
+
+#ifdef FIXPROTO_IGNORE_LIST
+ for (i = 0; files_to_ignore[i] != NULL; i++)
+ {
+ char *ignore_name = files_to_ignore[i];
+ int ignore_len = strlen (ignore_name);
+ if (strncmp (inc_filename, ignore_name, ignore_len) == 0)
+ {
+ if (ignore_name[ignore_len-1] == '/'
+ || inc_filename[ignore_len] == '\0')
+ {
+ if (verbose)
+ fprintf (stderr, "%s: ignoring %s\n", progname, inc_filename);
+ exit (0);
+ }
+ }
+
+ }
+#endif
+
if (strcmp (inc_filename, "sys/stat.h") == 0)
- special_file_handling = sys_stat_special;
+ special_file_handling = sys_stat_h;
else if (strcmp (inc_filename, "errno.h") == 0)
- special_file_handling = errno_special, missing_errno = 1;
-
- /* Calculate an upper bound of the number of function names in argv[4] */
- for (i = 1, cptr = argv[4]; *cptr; cptr++)
- if (*cptr == ' ') i++;
- /* Find the list of prototypes required for this include file. */
- required_functions = (char**)xmalloc ((i+1) * sizeof (char*));
- for (cptr = argv[4], cptr0 = cptr, pptr = required_functions, done = 0;
+ special_file_handling = errno_h, missing_errno = 1;
+ else if (strcmp (inc_filename, "stdio.h") == 0)
+ special_file_handling = stdio_h;
+ include_entry = std_include_table;
+ while (include_entry->name != NULL
+ && strcmp (inc_filename, include_entry->name) != 0)
+ include_entry++;
+
+ required_functions_list = include_entry->required;
+
+ /* Count and mark the prototypes required for this include file. */
+ for (cptr = required_functions_list, cptr0 = cptr, done = 0;
!done; cptr++)
{
- done = *cptr == '\0';
- if (*cptr == ' ' || done)
+ if (*cptr == '\0')
{
- *cptr = '\0';
- if (cptr > cptr0)
+ if (cptr[1] == 0)
+ break;
+ else
{
- struct fn_decl *fn = lookup_std_proto (cptr0);
- *pptr++ = cptr0;
+ struct fn_decl *fn = lookup_std_proto (cptr0, strlen (cptr0));
+ required_unseen_count++;
if (fn == NULL)
fprintf (stderr, "Internal error: No prototype for %s\n",
cptr0);
@@ -730,10 +1016,8 @@ main (argc, argv)
cptr0 = cptr + 1;
}
}
- required_unseen_count = pptr - required_functions;
- *pptr = 0;
- read_scan_file (stdin);
+ read_scan_file (argv[2], argc - 4, argv + 4);
inf_fd = open (argv[2], O_RDONLY, 0666);
if (inf_fd < 0)
@@ -794,10 +1078,6 @@ main (argc, argv)
if (check_protection (&ifndef_line, &endif_line))
{
-#if 0
- fprintf (stderr, "#ifndef %s on line %d; #endif on line %d\n",
- protect_name, ifndef_line, endif_line);
-#endif
lbrac_line = ifndef_line+1;
rbrac_line = endif_line;
}
@@ -828,7 +1108,7 @@ main (argc, argv)
c = inf_scan_ident (&buf, c);
INF_UNGET (c);
fputs (buf.base, outf);
- fn = lookup_std_proto (buf.base);
+ fn = lookup_std_proto (buf.base, strlen (buf.base));
/* We only want to edit the declaration matching the one
seen by scan-decls, as there can be multiple
declarations, selected by #ifdef __STDC__ or whatever. */
@@ -872,3 +1152,62 @@ main (argc, argv)
return 0;
}
+
+/* Stub error functions. These replace cpperror.c,
+ because we want to suppress error messages. */
+
+void
+cpp_file_line_for_message (pfile, filename, line, column)
+ cpp_reader *pfile;
+ char *filename;
+ int line, column;
+{
+ if (!verbose)
+ return;
+ if (column > 0)
+ fprintf (stderr, "%s:%d:%d: ", filename, line, column);
+ else
+ fprintf (stderr, "%s:%d: ", filename, line);
+}
+
+void
+cpp_print_containing_files (pfile)
+ cpp_reader *pfile;
+{
+}
+
+/* IS_ERROR is 1 for error, 0 for warning */
+void cpp_message (pfile, is_error, msg, arg1, arg2, arg3)
+ int is_error;
+ cpp_reader *pfile;
+ char *msg;
+ char *arg1, *arg2, *arg3;
+{
+ if (is_error)
+ pfile->errors++;
+ if (!verbose)
+ return;
+ if (!is_error)
+ fprintf (stderr, "warning: ");
+ fprintf (stderr, msg, arg1, arg2, arg3);
+ fprintf (stderr, "\n");
+}
+
+void
+fatal (str, arg)
+ char *str, *arg;
+{
+ fprintf (stderr, "%s: ", progname);
+ fprintf (stderr, str, arg);
+ fprintf (stderr, "\n");
+ exit (FAILURE_EXIT_CODE);
+}
+
+void
+cpp_pfatal_with_name (pfile, name)
+ cpp_reader *pfile;
+ char *name;
+{
+ cpp_perror_with_name (pfile, name);
+ exit (FAILURE_EXIT_CODE);
+}
diff --git a/gcc/fixproto b/gcc/fixproto
index de3ce1ae8c6..bfa8419d99e 100755
--- a/gcc/fixproto
+++ b/gcc/fixproto
@@ -56,7 +56,6 @@
progname=$0
progname=`basename $progname`
original_dir=`pwd`
-CPP=${CPP-./cpp}
FIX_HEADER=${FIX_HEADER-$original_dir/fix-header}
DEFINES="-D__STDC__=0 -D__cplusplus ${FIXPROTO_DEFINES}"
@@ -243,92 +242,10 @@ for code in ALL STD ; do
&& grep "$rel_source_file" fixproto.list >/dev/null
then true
else
- # echo doing $rel_source_file from $abs_source_dir
- required_list=
- extra_check_list=
- case $rel_source_file in
- ctype.h)
- required_list="isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper" ;;
- dirent.h)
- required_list="closedir opendir readdir rewinddir" ;;
- errno.h)
- extra_check_list="errno" ;;
- curses.h)
- required_list="box delwin endwin getcurx getcury initscr mvcur mvwprintw mvwscanw newwin overlay overwrite scroll subwin touchwin waddstr wclear wclrtobot wclrtoeol waddch wdelch wdeleteln werase wgetch wgetstr winsch winsertln wmove wprintw wrefresh wscanw wstandend wstandout" ;;
- fcntl.h)
- required_list="creat fcntl open" ;;
- grp.h)
- #Maybe also "getgrent fgetgrent setgrent endgrent" */
- required_list="getgrgid getgrnam" ;;
- limit.h)
- required_list= /* Lots of macros */ ;;
- locale.h)
- required_list="localeconv setlocale" ;;
- math.h)
- required_list="acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp log10 log modf pow sin sinh sqrt tan tanh"
- extra_check_list="HUGE_VAL" ;;
- pwd.h)
- required_list="getpwnam getpwuid" ;;
- setjmp.h)
- # Left out siglongjmp sigsetjmp - these depend on sigjmp_buf.
- required_list="longjmp setjmp" ;;
- signal.h)
- # 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.
- required_list="kill raise" ;;
- stdio.h)
- required_list="clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell fwrite getc getchar gets pclose perror popen printf putc putchar puts remove rename rewind scanf setbuf setvbuf sprintf sscanf vprintf vsprintf vfprintf tmpfile tmpnam ungetc"
- if grep '[^_a-zA-Z0-9]_flsbuf' <$abs_source_file >/dev/null; then
- required_list="$required_list _flsbuf _filbuf"
- fi
- # Should perhaps also handle NULL, EOF, ... ?
- ;;
- stdlib.h)
- required_list="$required_stdlib_h" ;;
- string.h)
- required_list="memchr memcmp memcpy memmove memset strcat strchr strcmp strcoll strcpy strcspn strerror strlen strncat strncmp strncpy strpbrk strrchr strspn strstr strtok strxfrm" ;;
-# Should perhaps also add NULL and size_t
- sys/stat.h)
- required_list="chmod fstat mkdir mkfifo stat lstat umask"
- extra_check_list="S_ISDIR S_ISBLK S_ISCHR S_ISFIFO S_ISREG S_ISLNK S_IFDIR S_IFBLK S_IFCHR S_IFIFO S_IFREG S_IFLNK" ;;
- sys/times.h)
- required_list="times" ;;
-# "sys/types.h" add types (not in old g++-include)
- sys/utsname.h)
- required_list="uname" ;;
- sys/wait.h)
- required_list="wait waitpid"
- extra_check_list="WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG WNOHANG WNOTRACED" ;;
- tar.h)
- required_list= ;;
- termios.h)
- required_list="cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain tcflow tcflush tcgetattr tcsendbreak tcsetattr" ;;
- time.h)
- required_list="asctime clock ctime difftime gmtime localtime mktime strftime time tzset" ;;
- unistd.h)
- required_list="$required_unistd_h" ;;
- esac
- rm -f fixtmp.c fixtmp.i
- echo "#include <${rel_source_file}>" >fixtmp.c
- for macro in ${required_list} ${extra_check_list}
- do
- echo "#ifdef ${macro}" >>fixtmp.c
- echo "__DEFINED_MACRO_${macro};" >>fixtmp.c
- echo "#endif" >>fixtmp.c
- done
- if ${CPP} ${DEFINES} $include_path fixtmp.c >fixtmp.i 2>/dev/null
- then
- $FIX_HEADER $rel_source_file $abs_source_file $abs_target_file "$required_list" <fixtmp.i
- else
- echo "${progname}: cpp could not parse ${abs_source_file} (ignored)"
- fi
+ $FIX_HEADER $rel_source_file $abs_source_file $abs_target_file ${DEFINES} $include_path
echo "${rel_source_file}" >>fixproto.list
fi
done
- rm -f fixtmp.c fixtmp.i
done
done_dirs="$done_dir $rel_source_dir"
done
@@ -348,7 +265,7 @@ do
#define ${rel_source_ident}
#endif
EOF
- ${FIX_HEADER} $rel_source_file tmp.h $abs_target_dir/$rel_source_file "$required_list" </dev/null
+ ${FIX_HEADER} $rel_source_file tmp.h $abs_target_dir/$rel_source_file ${DEFINES} $include_path
rm tmp.h
fi
done
diff --git a/gcc/gen-protos.c b/gcc/gen-protos.c
index 094ce2a4fca..3b5c6108bfb 100644
--- a/gcc/gen-protos.c
+++ b/gcc/gen-protos.c
@@ -19,9 +19,25 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ctype.h>
#include "hconfig.h"
#include "scan.h"
+#include "cpplib.h"
+#include "cpphash.h"
#define HASH_SIZE 2503 /* a prime */
+int
+hashf (name, len, hashsize)
+ register U_CHAR *name;
+ register int len;
+ int hashsize;
+{
+ register int r = 0;
+
+ while (len--)
+ r = HASHSTEP (r, *name++);
+
+ return MAKE_POS (r) % hashsize;
+}
+
int hash_tab[HASH_SIZE];
int verbose = 0;
@@ -119,7 +135,7 @@ main (argc, argv)
/* NOTE: If you edit this,
also edit lookup_std_proto in fix-header.c !! */
- i = hash (name_start) % HASH_SIZE;
+ i = hashf (name_start, name_end - name_start, HASH_SIZE);
i0 = i;
if (hash_tab[i] != 0)
{
@@ -153,3 +169,14 @@ main (argc, argv)
return 0;
}
+
+void
+fatal (s)
+ char *s;
+{
+ fprintf (stderr, "%s: %s\n", "gen-protos", s);
+#ifndef FAILURE_EXIT_CODE
+#define FAILURE_EXIT_CODE 33 /* gnu cc command understands this */
+#endif
+ exit (FAILURE_EXIT_CODE);
+}
diff --git a/gcc/scan-decls.c b/gcc/scan-decls.c
index 6fbc8ee9a8e..602082d8c3d 100644
--- a/gcc/scan-decls.c
+++ b/gcc/scan-decls.c
@@ -20,11 +20,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <stdio.h>
#include <ctype.h>
#include "hconfig.h"
-#include "scan.h"
-
-sstring buf;
-sstring rtype;
-sstring arg_list;
+#include "cpplib.h"
int brace_nesting = 0;
@@ -40,18 +36,18 @@ char extern_C_braces[20];
int current_extern_C = 0;
static void
-skip_to_closing_brace (fp)
- FILE *fp;
+skip_to_closing_brace (pfile)
+ cpp_reader *pfile;
{
int nesting = 1;
for (;;)
{
- int c = get_token (fp, &buf);
- if (c == EOF)
+ enum cpp_token token = cpp_get_token (pfile);
+ if (token == CPP_EOF)
break;
- if (c == '{')
+ if (token == CPP_LBRACE)
nesting++;
- if (c == '}' && --nesting == 0)
+ if (token == CPP_RBRACE && --nesting == 0)
break;
}
}
@@ -61,19 +57,26 @@ skip_to_closing_brace (fp)
other interesting sequences (external variables and macros). */
int
-scan_decls (fp)
- FILE *fp;
+scan_decls (pfile, argc, argv)
+ cpp_reader *pfile;
+ int argc;
+ char**argv;
{
- int c;
int saw_extern, saw_inline;
+ int old_written;
+ int prev_id_start, prev_id_end;
+ enum cpp_token token;
+
new_statement:
- c = get_token (fp, &buf);
+ CPP_SET_WRITTEN (pfile, 0);
+ token = cpp_get_token (pfile);
+
handle_statement:
current_extern_C = 0;
saw_extern = 0;
saw_inline = 0;
- if (c == '}')
+ if (token == CPP_RBRACE)
{
/* Pop an 'extern "C"' nesting level, if appropriate. */
if (extern_C_braces_length
@@ -82,121 +85,117 @@ scan_decls (fp)
brace_nesting--;
goto new_statement;
}
- if (c == '{')
+ if (token == CPP_LBRACE)
{
brace_nesting++;
goto new_statement;
}
- if (c == EOF)
+ if (token == CPP_EOF)
return 0;
- if (c == ';')
+ if (token == CPP_SEMICOLON)
goto new_statement;
- if (c != IDENTIFIER_TOKEN)
+ if (token != CPP_NAME)
goto new_statement;
- rtype.ptr = rtype.base;
- if (SSTRING_LENGTH (&buf) > 16
- && strncmp (buf.base, "__DEFINED_MACRO_", 16) == 0)
- {
- /* For certain interesting macro names, fixproto puts
- #ifdef FOO
- __DEFINED_MACRO_FOO
- #endif
- into the file to be pre-processed. So if we see __DEFINED_MACRO_FOO,
- it means FOO was defined, which we may want to make a note of. */
- recognized_macro (buf.base+16);
- goto new_statement;
- }
- if (strcmp (buf.base, "inline") == 0)
- {
+ if (strcmp (pfile->token_buffer, "inline") == 0)
+ {
saw_inline = 1;
- c = get_token (fp, &buf);
+ CPP_SET_WRITTEN (pfile, 0);
+ token = cpp_get_non_space_token (pfile);
}
- if (strcmp (buf.base, "extern") == 0)
+ if (strcmp (pfile->token_buffer, "extern") == 0)
{
saw_extern = 1;
- c = get_token (fp, &buf);
- if (c == STRING_TOKEN && strcmp (buf.base, "C") == 0)
+ CPP_SET_WRITTEN (pfile, 0);
+ token = cpp_get_non_space_token (pfile);
+ if (token == CPP_STRING
+ && strcmp (pfile->token_buffer, "\"C\"") == 0)
{
+ CPP_SET_WRITTEN (pfile, 0);
current_extern_C = 1;
- c = get_token (fp, &buf);
- if (c == '{')
+ token = cpp_get_non_space_token (pfile);
+ if (token == CPP_LPAREN)
{
brace_nesting++;
extern_C_braces[extern_C_braces_length++] = brace_nesting;
goto new_statement;
}
- c = get_token (fp, &buf);
+ token = cpp_get_non_space_token (pfile);
}
}
+ prev_id_start = NULL;
for (;;)
{
- int followingc = getc (fp); /* char following token in buf */
-
- MAKE_SSTRING_SPACE (&rtype, 1);
- *rtype.ptr = 0;
-
- if (c == IDENTIFIER_TOKEN)
+ int start_written = CPP_WRITTEN (pfile);
+ token = cpp_get_token (pfile);
+ switch (token)
{
- int nextc = skip_spaces (fp, followingc);
- if (nextc == '(')
+ case CPP_LPAREN:
+ if (prev_id_start)
{
int nesting = 1;
- int func_lineno = source_lineno;
- char *args;
-
- arg_list.ptr = arg_list.base;
+ int have_arg_list = 0;
+ cpp_buffer *fbuf = cpp_file_buffer (pfile);
+ long func_lineno;
+ cpp_buf_line_and_col (fbuf, &func_lineno, NULL);
for (;;)
{
- c = getc (fp);
- if (c == '(')
+ token = cpp_get_token (pfile);
+ if (token == CPP_LPAREN)
nesting++;
- else if (c == ')')
- if (--nesting == 0)
- break;
- if (c == EOF)
- break;
- if (c == '\n')
+ else if (token == CPP_RPAREN)
{
- c = ' ';
- source_lineno++;
- lineno++;
+ nesting--;
+ if (nesting == 0)
+ break;
}
- SSTRING_PUT (&arg_list, c);
+ else if (token == CPP_EOF)
+ break;
+ else if (token == CPP_NAME || token == CPP_3DOTS)
+ have_arg_list = 1;
}
- SSTRING_PUT (&arg_list, '\0');
- args = arg_list.base;
- while (*args == ' ')
- args++;
- recognized_function (buf.base,
+ recognized_function (pfile->token_buffer + prev_id_start,
+ prev_id_end - prev_id_start,
(saw_inline ? 'I'
: in_extern_C_brace || current_extern_C
? 'F' : 'f'),
- rtype.base, args,
- source_filename.base, func_lineno);
- c = get_token (fp, &buf);
- if (c == '{')
+ pfile->token_buffer, prev_id_start,
+ have_arg_list,
+ fbuf->nominal_fname, func_lineno);
+ token = cpp_get_non_space_token (pfile);
+ if (token == CPP_LBRACE)
{
/* skip body of (normally) inline function */
- skip_to_closing_brace (fp);
+ skip_to_closing_brace (pfile);
goto new_statement;
}
goto handle_statement;
}
- else if (nextc == ';' && saw_extern)
+ break;
+ case CPP_SEMICOLON:
+ if (prev_id_start && saw_extern)
{
- recognized_extern (buf.base, rtype.base);
- goto new_statement;
+ recognized_extern (pfile->token_buffer + prev_id_start,
+ prev_id_end - prev_id_start,
+ pfile->token_buffer,
+ prev_id_start);
}
- else
- ungetc (nextc, fp);
+ goto new_statement;
+ case CPP_NAME:
+ prev_id_start = start_written;
+ prev_id_end = CPP_WRITTEN (pfile);
+ break;
+
+ case CPP_EOF:
+ return; /* ??? FIXME */
+
+ case CPP_LBRACE: case CPP_RBRACE: case CPP_DIRECTIVE:
+ goto new_statement; /* handle_statement? */
+
+ case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT: case CPP_POP:
+ break;
+
+ default:
+ prev_id_start = NULL;
}
- else if (followingc != EOF)
- ungetc (followingc, fp);
- if (c == ';' || c == '{' || c == '}' || c == EOF)
- goto handle_statement;
- sstring_append (&rtype, &buf);
- if (followingc == ' ' || followingc == '\t' || followingc == '\n')
- SSTRING_PUT (&rtype, ' ');
- c = get_token (fp, &buf);
}
}
diff --git a/gcc/scan.c b/gcc/scan.c
index b6289908191..ff4b5696d7c 100644
--- a/gcc/scan.c
+++ b/gcc/scan.c
@@ -58,35 +58,6 @@ sstring_append (dst, src)
*d = 0;
}
-memory_full ()
-{
- abort();
-}
-
-char *
-xmalloc (size)
- unsigned size;
-{
- register char *ptr = (char *) malloc (size);
- if (ptr != 0) return (ptr);
- memory_full ();
- /*NOTREACHED*/
- return 0;
-}
-
-
-char *
-xrealloc (old, size)
- char *old;
- unsigned size;
-{
- register char *ptr = (char *) realloc (old, size);
- if (ptr != 0) return (ptr);
- memory_full ();
- /*NOTREACHED*/
- return 0;
-}
-
int
scan_ident (fp, s, c)
register FILE *fp;
@@ -267,13 +238,3 @@ get_token (fp, s)
*s->ptr = 0;
return c;
}
-
-unsigned long
-hash (str)
- char *str;
-{
- int h = 0;
- /* Replace this with something faster/better! FIXME! */
- while (*str) h = (h << 3) + *str++;
- return h & 0x7FFFFFFF;
-}
diff --git a/gcc/scan.h b/gcc/scan.h
index a61a82e7185..ff666185b9f 100644
--- a/gcc/scan.h
+++ b/gcc/scan.h
@@ -59,7 +59,7 @@ extern int scan_string _PARAMS((FILE*, sstring *, int));
extern int read_upto _PARAMS((FILE*, sstring*, int));
extern char *xmalloc _PARAMS((unsigned));
extern char *xrealloc _PARAMS((char *, unsigned));
-extern unsigned long hash _PARAMS((char*));
+extern unsigned long hash _PARAMS((const char*));
/* get_token is a simple C lexer. */
#define IDENTIFIER_TOKEN 300