Commit b3ca463c by Per Bothner

Re-write fixproto/fix-header/etc to use cpplib.

From-SVN: r9316
parent 355142da
...@@ -1736,9 +1736,9 @@ deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs ...@@ -1736,9 +1736,9 @@ deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs
$(SHELL) $(srcdir)/scan-types.sh "$(srcdir)" >tmp-deduced.h $(SHELL) $(srcdir)/scan-types.sh "$(srcdir)" >tmp-deduced.h
mv tmp-deduced.h 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 \ ${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 gen-protos.o: gen-protos.c scan.h hconfig.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c $(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 ...@@ -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 mv xsys-protos.hT xsys-protos.h
rm -rf fixtmp.c 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 \ $(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 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 $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c
...@@ -1785,9 +1785,8 @@ stmp-fixproto: fixhdr.ready fixproto stmp-headers ...@@ -1785,9 +1785,8 @@ stmp-fixproto: fixhdr.ready fixproto stmp-headers
-if [ -f include/fixed ] ; then true; \ -if [ -f include/fixed ] ; then true; \
else \ else \
: This line works around a 'make' bug in BSDI 1.1.; \ : 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; \
FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \ $(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
$(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
touch include/fixed; \ touch include/fixed; \
fi fi
touch stmp-fixproto touch stmp-fixproto
......
/* fix-header.c - Make C header file suitable for C++. /* 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 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 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. */ ...@@ -59,15 +59,14 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
b) it would be nice to allow update in place. b) it would be nice to allow update in place.
Usage: Usage:
fix-header FOO.H INFILE.H OUTFILE.H REQUIRED_FUNCS <SCAN-FILE fix-header FOO.H INFILE.H OUTFILE.H [OPTIONS]
where: where:
* FOO.H is the relative file name of the include file, * 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) 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) * 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, * OUTFILE.H is the full pathname for where to write the output file,
if anything needs to be done. (e.g. ./include/stdio.h) if anything needs to be done. (e.g. ./include/stdio.h)
* SCAN-FILE is the output of the scan-decls program. * OPTIONS are such as you would pass to cpp.
* REQUIRED_FUNCS is a list of required function (e.g. fclose for stdio.h).
Written by Per Bothner <bothner@cygnus.com>, July 1993. */ Written by Per Bothner <bothner@cygnus.com>, July 1993. */
...@@ -81,22 +80,44 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -81,22 +80,44 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "hconfig.h" #include "hconfig.h"
#include "obstack.h" #include "obstack.h"
#include "scan.h" #include "scan.h"
#include "cpplib.h"
extern sstring buf; #if !__STDC__
#define const /* nothing */
#endif
sstring buf;
int verbose = 0; int verbose = 0;
int partial_count = 0; int partial_count = 0;
#if 0 int warnings = 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. /* We no longer need to add extern "C", because cpp implicitly
Adding an explicit extern "C" is undesireable as it breaks the SunOS 4.x forces the standard include files to be treated as C. */
sun4c/romvec.h file. */ /*#define ADD_MISSING_EXTERN_C 1 */
#if ADD_MISSING_EXTERN_C
int missing_extern_C_count = 0; int missing_extern_C_count = 0;
#endif #endif
int missing_errno = 0; int missing_errno = 0;
#include "xsys-protos.h" #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_buffer;
char *inf_limit; char *inf_limit;
char *inf_ptr; char *inf_ptr;
...@@ -106,8 +127,134 @@ char *inf_ptr; ...@@ -106,8 +127,134 @@ char *inf_ptr;
enum special_file enum special_file
{ {
no_special, no_special,
errno_special, errno_h,
sys_stat_special 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; enum special_file special_file_handling = no_special;
...@@ -146,10 +293,11 @@ struct obstack scan_file_obstack; ...@@ -146,10 +293,11 @@ struct obstack scan_file_obstack;
/* NOTE: If you edit this, also edit gen-protos.c !! */ /* NOTE: If you edit this, also edit gen-protos.c !! */
struct fn_decl * struct fn_decl *
lookup_std_proto (name) lookup_std_proto (name, name_length)
char *name; const char *name;
int name_length;
{ {
int i = hash (name) % HASH_SIZE; int i = hashf (name, name_length, HASH_SIZE);
int i0 = i; int i0 = i;
for (;;) for (;;)
{ {
...@@ -157,7 +305,8 @@ lookup_std_proto (name) ...@@ -157,7 +305,8 @@ lookup_std_proto (name)
if (hash_tab[i] == 0) if (hash_tab[i] == 0)
return NULL; return NULL;
fn = &std_protos[hash_tab[i]]; 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; return fn;
i = (i+1) % HASH_SIZE; i = (i+1) % HASH_SIZE;
if (i == i0) if (i == i0)
...@@ -173,14 +322,14 @@ sstring line; ...@@ -173,14 +322,14 @@ sstring line;
int lbrac_line, rbrac_line; int lbrac_line, rbrac_line;
char **required_functions; namelist required_functions_list;
int required_unseen_count; int required_unseen_count = 0;
void void
write_lbrac () write_lbrac ()
{ {
#if 0 #if ADD_MISSING_EXTERN_C
if (missing_extern_C_count + required_unseen_count > 0) if (missing_extern_C_count + required_unseen_count > 0)
fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
#endif #endif
...@@ -207,31 +356,33 @@ struct partial_proto ...@@ -207,31 +356,33 @@ struct partial_proto
struct partial_proto *partial_proto_list = NULL; 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 REQUIRED(FN) ((FN)->partial == &required_dummy_proto)
#define SET_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 void
recognized_macro (fname) recognized_macro (fname)
char *fname; char *fname;
{ {
/* The original include file defines fname as a macro. */ /* 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. */ /* Since fname is a macro, don't require a prototype for it. */
if (fn && REQUIRED (fn)) if (fn)
{ {
CLEAR_REQUIRED (fn); if (REQUIRED (fn))
required_unseen_count--; required_unseen_count--;
SET_SEEN (fn);
} }
switch (special_file_handling) switch (special_file_handling)
{ {
case errno_special: case errno_h:
if (strcmp (fname, "errno") == 0) missing_errno = 0; if (strcmp (fname, "errno") == 0) missing_errno = 0;
break; break;
case sys_stat_special: case sys_stat_h:
if (fname[0] == 'S' && fname[1] == '_') if (fname[0] == 'S' && fname[1] == '_')
{ {
if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++; if (strcmp (fname, "S_IFBLK") == 0) seen_S_IFBLK++;
...@@ -251,14 +402,15 @@ recognized_macro (fname) ...@@ -251,14 +402,15 @@ recognized_macro (fname)
} }
void void
recognized_extern (name, type) recognized_extern (name, name_length, type, type_length)
char *name; char *name;
char *type; char *type;
int name_length, type_length;
{ {
switch (special_file_handling) switch (special_file_handling)
{ {
case errno_special: case errno_h:
if (strcmp (name, "errno") == 0) missing_errno = 0; if (strncmp (name, "errno", name_length) == 0) missing_errno = 0;
break; break;
} }
} }
...@@ -272,33 +424,38 @@ recognized_extern (name, type) ...@@ -272,33 +424,38 @@ recognized_extern (name, type)
'f' for other function declarations. */ 'f' for other function declarations. */
void 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; char *fname;
int fname_length;
int kind; /* One of 'f' 'F' or 'I' */ int kind; /* One of 'f' 'F' or 'I' */
char *rtype; char *rtype;
char *args; int rtype_length;
int have_arg_list;
char *file_seen; char *file_seen;
int line_seen; int line_seen;
{ {
struct partial_proto *partial; struct partial_proto *partial;
int i; int i;
struct fn_decl *fn; struct fn_decl *fn;
#if 0 #if ADD_MISSING_EXTERN_C
if (kind == 'f') if (kind == 'f')
missing_extern_C_count++; missing_extern_C_count++;
#endif #endif
fn = lookup_std_proto (fname); fn = lookup_std_proto (fname, fname_length);
/* Remove the function from the list of required function. */ /* Remove the function from the list of required function. */
if (fn && REQUIRED (fn)) if (fn)
{ {
CLEAR_REQUIRED (fn); if (REQUIRED (fn))
required_unseen_count--; required_unseen_count--;
SET_SEEN (fn);
} }
/* If we have a full prototype, we're done. */ /* If we have a full prototype, we're done. */
if (args[0] != '\0') if (have_arg_list)
return; return;
if (kind == 'I') /* don't edit inline function */ if (kind == 'I') /* don't edit inline function */
...@@ -321,10 +478,11 @@ recognized_function (fname, kind, rtype, args, file_seen, line_seen) ...@@ -321,10 +478,11 @@ recognized_function (fname, kind, rtype, args, file_seen, line_seen)
partial_count++; partial_count++;
partial = (struct partial_proto*) partial = (struct partial_proto*)
obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto)); obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
partial->fname = obstack_alloc (&scan_file_obstack, strlen (fname) + 1); partial->fname = obstack_alloc (&scan_file_obstack, fname_length + 1);
strcpy (partial->fname, fname); bcopy (fname, partial->fname, fname_length);
partial->rtype = obstack_alloc (&scan_file_obstack, strlen (rtype) + 1); partial->fname[fname_length] = 0;
strcpy (partial->rtype, rtype); partial->rtype = obstack_alloc (&scan_file_obstack, rtype_length + 1);
sprintf (partial->rtype, "%.*s", rtype_length, rtype);
partial->line_seen = line_seen; partial->line_seen = line_seen;
partial->fn = fn; partial->fn = fn;
fn->partial = partial; fn->partial = partial;
...@@ -333,20 +491,122 @@ recognized_function (fname, kind, rtype, args, file_seen, line_seen) ...@@ -333,20 +491,122 @@ recognized_function (fname, kind, rtype, args, file_seen, line_seen)
if (verbose) if (verbose)
{ {
fprintf (stderr, "(%s: %s non-prototype function declaration.)\n", 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 void
read_scan_file (scan_file) read_scan_file (in_fname, argc, argv)
FILE *scan_file; 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); 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 (required_unseen_count + partial_count + missing_errno
#if 0 #if ADD_MISSING_EXTERN_C
+ missing_extern_C_count + missing_extern_C_count
#endif #endif
== 0) == 0)
...@@ -365,7 +625,7 @@ read_scan_file (scan_file) ...@@ -365,7 +625,7 @@ read_scan_file (scan_file)
if (partial_count) if (partial_count)
fprintf (stderr, "%s: %d non-prototype function declarations.\n", fprintf (stderr, "%s: %d non-prototype function declarations.\n",
inc_filename, partial_count); inc_filename, partial_count);
#if 0 #if ADD_MISSING_EXTERN_C
if (missing_extern_C_count) if (missing_extern_C_count)
fprintf (stderr, fprintf (stderr,
"%s: %d declarations not protected by extern \"C\".\n", "%s: %d declarations not protected by extern \"C\".\n",
...@@ -378,7 +638,7 @@ void ...@@ -378,7 +638,7 @@ void
write_rbrac () write_rbrac ()
{ {
struct fn_decl *fn; struct fn_decl *fn;
char **rptr; const char *cptr;
if (required_unseen_count) if (required_unseen_count)
{ {
...@@ -390,11 +650,13 @@ write_rbrac () ...@@ -390,11 +650,13 @@ write_rbrac ()
} }
/* Now we print out prototypes for those functions that we haven't seen. */ /* 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 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)) if (fn == NULL || !REQUIRED (fn))
continue; continue;
...@@ -425,11 +687,11 @@ write_rbrac () ...@@ -425,11 +687,11 @@ write_rbrac ()
switch (special_file_handling) switch (special_file_handling)
{ {
case errno_special: case errno_h:
if (missing_errno) if (missing_errno)
fprintf (outf, "extern int errno;\n"); fprintf (outf, "extern int errno;\n");
break; break;
case sys_stat_special: case sys_stat_h:
if (!seen_S_ISBLK && seen_S_IFBLK) if (!seen_S_ISBLK && seen_S_IFBLK)
fprintf (outf, fprintf (outf,
"#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n"); "#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n");
...@@ -452,7 +714,7 @@ write_rbrac () ...@@ -452,7 +714,7 @@ write_rbrac ()
} }
#if 0 #if ADD_MISSING_EXTERN_C
if (missing_extern_C_count + required_unseen_count > 0) if (missing_extern_C_count + required_unseen_count > 0)
fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n"); fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");
#endif #endif
...@@ -674,7 +936,7 @@ main (argc, argv) ...@@ -674,7 +936,7 @@ main (argc, argv)
struct stat sbuf; struct stat sbuf;
int c; int c;
int i, done; int i, done;
char *cptr, *cptr0, **pptr; const char *cptr0, *cptr, **pptr;
int ifndef_line; int ifndef_line;
int endif_line; int endif_line;
long to_read; long to_read;
...@@ -693,34 +955,58 @@ main (argc, argv) ...@@ -693,34 +955,58 @@ main (argc, argv)
if (argc < 4) 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); progname);
exit (-1); exit (-1);
} }
inc_filename = argv[1]; inc_filename = argv[1];
inc_filename_length = strlen (inc_filename); 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) 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) else if (strcmp (inc_filename, "errno.h") == 0)
special_file_handling = errno_special, missing_errno = 1; special_file_handling = errno_h, missing_errno = 1;
else if (strcmp (inc_filename, "stdio.h") == 0)
/* Calculate an upper bound of the number of function names in argv[4] */ special_file_handling = stdio_h;
for (i = 1, cptr = argv[4]; *cptr; cptr++) include_entry = std_include_table;
if (*cptr == ' ') i++; while (include_entry->name != NULL
/* Find the list of prototypes required for this include file. */ && strcmp (inc_filename, include_entry->name) != 0)
required_functions = (char**)xmalloc ((i+1) * sizeof (char*)); include_entry++;
for (cptr = argv[4], cptr0 = cptr, pptr = required_functions, done = 0;
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++)
{ {
done = *cptr == '\0'; if (*cptr == '\0')
if (*cptr == ' ' || done)
{ {
*cptr = '\0'; if (cptr[1] == 0)
if (cptr > cptr0) break;
else
{ {
struct fn_decl *fn = lookup_std_proto (cptr0); struct fn_decl *fn = lookup_std_proto (cptr0, strlen (cptr0));
*pptr++ = cptr0; required_unseen_count++;
if (fn == NULL) if (fn == NULL)
fprintf (stderr, "Internal error: No prototype for %s\n", fprintf (stderr, "Internal error: No prototype for %s\n",
cptr0); cptr0);
...@@ -730,10 +1016,8 @@ main (argc, argv) ...@@ -730,10 +1016,8 @@ main (argc, argv)
cptr0 = cptr + 1; 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); inf_fd = open (argv[2], O_RDONLY, 0666);
if (inf_fd < 0) if (inf_fd < 0)
...@@ -794,10 +1078,6 @@ main (argc, argv) ...@@ -794,10 +1078,6 @@ main (argc, argv)
if (check_protection (&ifndef_line, &endif_line)) 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; lbrac_line = ifndef_line+1;
rbrac_line = endif_line; rbrac_line = endif_line;
} }
...@@ -828,7 +1108,7 @@ main (argc, argv) ...@@ -828,7 +1108,7 @@ main (argc, argv)
c = inf_scan_ident (&buf, c); c = inf_scan_ident (&buf, c);
INF_UNGET (c); INF_UNGET (c);
fputs (buf.base, outf); 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 /* We only want to edit the declaration matching the one
seen by scan-decls, as there can be multiple seen by scan-decls, as there can be multiple
declarations, selected by #ifdef __STDC__ or whatever. */ declarations, selected by #ifdef __STDC__ or whatever. */
...@@ -872,3 +1152,62 @@ main (argc, argv) ...@@ -872,3 +1152,62 @@ main (argc, argv)
return 0; 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);
}
...@@ -56,7 +56,6 @@ ...@@ -56,7 +56,6 @@
progname=$0 progname=$0
progname=`basename $progname` progname=`basename $progname`
original_dir=`pwd` original_dir=`pwd`
CPP=${CPP-./cpp}
FIX_HEADER=${FIX_HEADER-$original_dir/fix-header} FIX_HEADER=${FIX_HEADER-$original_dir/fix-header}
DEFINES="-D__STDC__=0 -D__cplusplus ${FIXPROTO_DEFINES}" DEFINES="-D__STDC__=0 -D__cplusplus ${FIXPROTO_DEFINES}"
...@@ -243,92 +242,10 @@ for code in ALL STD ; do ...@@ -243,92 +242,10 @@ for code in ALL STD ; do
&& grep "$rel_source_file" fixproto.list >/dev/null && grep "$rel_source_file" fixproto.list >/dev/null
then true then true
else else
# echo doing $rel_source_file from $abs_source_dir $FIX_HEADER $rel_source_file $abs_source_file $abs_target_file ${DEFINES} $include_path
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
echo "${rel_source_file}" >>fixproto.list echo "${rel_source_file}" >>fixproto.list
fi fi
done done
rm -f fixtmp.c fixtmp.i
done done
done_dirs="$done_dir $rel_source_dir" done_dirs="$done_dir $rel_source_dir"
done done
...@@ -348,7 +265,7 @@ do ...@@ -348,7 +265,7 @@ do
#define ${rel_source_ident} #define ${rel_source_ident}
#endif #endif
EOF 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 rm tmp.h
fi fi
done done
......
...@@ -19,9 +19,25 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -19,9 +19,25 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ctype.h> #include <ctype.h>
#include "hconfig.h" #include "hconfig.h"
#include "scan.h" #include "scan.h"
#include "cpplib.h"
#include "cpphash.h"
#define HASH_SIZE 2503 /* a prime */ #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 hash_tab[HASH_SIZE];
int verbose = 0; int verbose = 0;
...@@ -119,7 +135,7 @@ main (argc, argv) ...@@ -119,7 +135,7 @@ main (argc, argv)
/* NOTE: If you edit this, /* NOTE: If you edit this,
also edit lookup_std_proto in fix-header.c !! */ 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; i0 = i;
if (hash_tab[i] != 0) if (hash_tab[i] != 0)
{ {
...@@ -153,3 +169,14 @@ main (argc, argv) ...@@ -153,3 +169,14 @@ main (argc, argv)
return 0; 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);
}
...@@ -20,11 +20,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ...@@ -20,11 +20,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include "hconfig.h" #include "hconfig.h"
#include "scan.h" #include "cpplib.h"
sstring buf;
sstring rtype;
sstring arg_list;
int brace_nesting = 0; int brace_nesting = 0;
...@@ -40,18 +36,18 @@ char extern_C_braces[20]; ...@@ -40,18 +36,18 @@ char extern_C_braces[20];
int current_extern_C = 0; int current_extern_C = 0;
static void static void
skip_to_closing_brace (fp) skip_to_closing_brace (pfile)
FILE *fp; cpp_reader *pfile;
{ {
int nesting = 1; int nesting = 1;
for (;;) for (;;)
{ {
int c = get_token (fp, &buf); enum cpp_token token = cpp_get_token (pfile);
if (c == EOF) if (token == CPP_EOF)
break; break;
if (c == '{') if (token == CPP_LBRACE)
nesting++; nesting++;
if (c == '}' && --nesting == 0) if (token == CPP_RBRACE && --nesting == 0)
break; break;
} }
} }
...@@ -61,19 +57,26 @@ skip_to_closing_brace (fp) ...@@ -61,19 +57,26 @@ skip_to_closing_brace (fp)
other interesting sequences (external variables and macros). */ other interesting sequences (external variables and macros). */
int int
scan_decls (fp) scan_decls (pfile, argc, argv)
FILE *fp; cpp_reader *pfile;
int argc;
char**argv;
{ {
int c;
int saw_extern, saw_inline; int saw_extern, saw_inline;
int old_written;
int prev_id_start, prev_id_end;
enum cpp_token token;
new_statement: new_statement:
c = get_token (fp, &buf); CPP_SET_WRITTEN (pfile, 0);
token = cpp_get_token (pfile);
handle_statement: handle_statement:
current_extern_C = 0; current_extern_C = 0;
saw_extern = 0; saw_extern = 0;
saw_inline = 0; saw_inline = 0;
if (c == '}') if (token == CPP_RBRACE)
{ {
/* Pop an 'extern "C"' nesting level, if appropriate. */ /* Pop an 'extern "C"' nesting level, if appropriate. */
if (extern_C_braces_length if (extern_C_braces_length
...@@ -82,121 +85,117 @@ scan_decls (fp) ...@@ -82,121 +85,117 @@ scan_decls (fp)
brace_nesting--; brace_nesting--;
goto new_statement; goto new_statement;
} }
if (c == '{') if (token == CPP_LBRACE)
{ {
brace_nesting++; brace_nesting++;
goto new_statement; goto new_statement;
} }
if (c == EOF) if (token == CPP_EOF)
return 0; return 0;
if (c == ';') if (token == CPP_SEMICOLON)
goto new_statement; goto new_statement;
if (c != IDENTIFIER_TOKEN) if (token != CPP_NAME)
goto new_statement; goto new_statement;
rtype.ptr = rtype.base; if (strcmp (pfile->token_buffer, "inline") == 0)
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)
{
saw_inline = 1; 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; saw_extern = 1;
c = get_token (fp, &buf); CPP_SET_WRITTEN (pfile, 0);
if (c == STRING_TOKEN && strcmp (buf.base, "C") == 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; current_extern_C = 1;
c = get_token (fp, &buf); token = cpp_get_non_space_token (pfile);
if (c == '{') if (token == CPP_LPAREN)
{ {
brace_nesting++; brace_nesting++;
extern_C_braces[extern_C_braces_length++] = brace_nesting; extern_C_braces[extern_C_braces_length++] = brace_nesting;
goto new_statement; goto new_statement;
} }
c = get_token (fp, &buf); token = cpp_get_non_space_token (pfile);
} }
} }
prev_id_start = NULL;
for (;;) for (;;)
{ {
int followingc = getc (fp); /* char following token in buf */ int start_written = CPP_WRITTEN (pfile);
token = cpp_get_token (pfile);
MAKE_SSTRING_SPACE (&rtype, 1); switch (token)
*rtype.ptr = 0;
if (c == IDENTIFIER_TOKEN)
{ {
int nextc = skip_spaces (fp, followingc); case CPP_LPAREN:
if (nextc == '(') if (prev_id_start)
{ {
int nesting = 1; int nesting = 1;
int func_lineno = source_lineno; int have_arg_list = 0;
char *args; cpp_buffer *fbuf = cpp_file_buffer (pfile);
long func_lineno;
arg_list.ptr = arg_list.base; cpp_buf_line_and_col (fbuf, &func_lineno, NULL);
for (;;) for (;;)
{ {
c = getc (fp); token = cpp_get_token (pfile);
if (c == '(') if (token == CPP_LPAREN)
nesting++; nesting++;
else if (c == ')') else if (token == CPP_RPAREN)
if (--nesting == 0)
break;
if (c == EOF)
break;
if (c == '\n')
{ {
c = ' '; nesting--;
source_lineno++; if (nesting == 0)
lineno++; 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'); recognized_function (pfile->token_buffer + prev_id_start,
args = arg_list.base; prev_id_end - prev_id_start,
while (*args == ' ')
args++;
recognized_function (buf.base,
(saw_inline ? 'I' (saw_inline ? 'I'
: in_extern_C_brace || current_extern_C : in_extern_C_brace || current_extern_C
? 'F' : 'f'), ? 'F' : 'f'),
rtype.base, args, pfile->token_buffer, prev_id_start,
source_filename.base, func_lineno); have_arg_list,
c = get_token (fp, &buf); fbuf->nominal_fname, func_lineno);
if (c == '{') token = cpp_get_non_space_token (pfile);
if (token == CPP_LBRACE)
{ {
/* skip body of (normally) inline function */ /* skip body of (normally) inline function */
skip_to_closing_brace (fp); skip_to_closing_brace (pfile);
goto new_statement; goto new_statement;
} }
goto handle_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); recognized_extern (pfile->token_buffer + prev_id_start,
goto new_statement; prev_id_end - prev_id_start,
pfile->token_buffer,
prev_id_start);
} }
else goto new_statement;
ungetc (nextc, fp); 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);
} }
} }
...@@ -58,35 +58,6 @@ sstring_append (dst, src) ...@@ -58,35 +58,6 @@ sstring_append (dst, src)
*d = 0; *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 int
scan_ident (fp, s, c) scan_ident (fp, s, c)
register FILE *fp; register FILE *fp;
...@@ -267,13 +238,3 @@ get_token (fp, s) ...@@ -267,13 +238,3 @@ get_token (fp, s)
*s->ptr = 0; *s->ptr = 0;
return c; 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;
}
...@@ -59,7 +59,7 @@ extern int scan_string _PARAMS((FILE*, sstring *, int)); ...@@ -59,7 +59,7 @@ extern int scan_string _PARAMS((FILE*, sstring *, int));
extern int read_upto _PARAMS((FILE*, sstring*, int)); extern int read_upto _PARAMS((FILE*, sstring*, int));
extern char *xmalloc _PARAMS((unsigned)); extern char *xmalloc _PARAMS((unsigned));
extern char *xrealloc _PARAMS((char *, 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. */ /* get_token is a simple C lexer. */
#define IDENTIFIER_TOKEN 300 #define IDENTIFIER_TOKEN 300
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment