diff options
author | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-03-12 23:46:05 +0000 |
---|---|---|
committer | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-03-12 23:46:05 +0000 |
commit | 5ecec5dabe4dbe0744ff950108e23d2675e77eac (patch) | |
tree | a98d122ee7a482f328ecd041626122a0cd1beaa8 /gcc/cppfiles.c | |
parent | a25d35f6be24a9f7ee6b012ee5fef7b81a7ec9df (diff) | |
download | gcc-5ecec5dabe4dbe0744ff950108e23d2675e77eac.tar.gz |
Convert cpplib to use libiberty/hashtab.c.
* cpplib.h (struct cpp_reader): Make hashtab and
all_include_files of type 'struct htab *'. Delete HASHSIZE
and ALL_INCLUDE_HASHSIZE macros.
* cpphash.h: Update prototypes.
(struct hashnode): Remove next, prev, and bucket_hdr members.
Make length a size_t. Add hash member.
(struct ihash): Remove next member. Add hash member. Make
name a flexible array member.
* cppfiles.c: Include hashtab.h.
(include_hash): Delete.
(IHASHSIZE): New macro.
(hash_IHASH, eq_IHASH, _cpp_init_include_hash): New functions.
(cpp_included): Do the hash lookup here.
(_cpp_find_include_file): Rewrite.
(cpp_read_file): Put the "fake" hash entry into the hash
table. Honor the control_macro, if it turns out we've seen
the file before. Don't push the buffer here.
(_cpp_read_include_file): Push the buffer here.
(OMODES): New macro. Use it whenever we call open(2).
* cpphash.c: Include hashtab.h.
(hash_HASHNODE, eq_HASHNODE, del_HASHNODE, dump_hash_helper,
_cpp_init_macro_hash, _cpp_dump_macro_hash, _cpp_make_hashnode,
_cpp_lookup_slot): New functions.
(HASHSIZE): new macro.
(hashf, _cpp_install, _cpp_delete_macro): Delete.
(_cpp_lookup): Use hashtab.h routines.
* cppinit.c: Include hashtab.h.
(cpp_reader_init): Call _cpp_init_macro_hash and
_cpp_init_include_hash. Don't allocate hashtab directly.
(cpp_cleanup): Just call htab_delete on pfile->hashtab and
pfile->all_include_files.
(initialize_builtins): Use _cpp_make_hashnode and
htab_find_slot to add hash entries.
(cpp_finish): Just call _cpp_dump_macro_hash.
* cpplib.c: Include hashtab.h.
(do_define): Use _cpp_lookup_slot and _cpp_make_hashnode to
create hash entries.
(do_pragma_poison, do_assert): Likewise.
(do_include): Don't push the buffer here. Don't increment
system_include_depth unless _cpp_read_include_file succeeds.
(do_undef, do_unassert): Use _cpp_lookup_slot and htab_clear_slot
or htab_remove_elt.
(do_pragma_implementation): Use alloca to create copy.
* Makefile.in: Update dependencies.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32497 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cppfiles.c')
-rw-r--r-- | gcc/cppfiles.c | 320 |
1 files changed, 153 insertions, 167 deletions
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 7b2b2407971..3354663309d 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -28,9 +28,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "system.h" #include "cpplib.h" #include "cpphash.h" +#include "hashtab.h" #include "intl.h" -static IHASH *include_hash PARAMS ((cpp_reader *, const char *, int)); static IHASH *redundant_include_p PARAMS ((cpp_reader *, IHASH *, struct file_name_list *)); static struct file_name_map *read_name_map @@ -42,6 +42,10 @@ static long read_and_prescan PARAMS ((cpp_reader *, cpp_buffer *, int, size_t)); static struct file_name_list *actual_directory PARAMS ((cpp_reader *, const char *)); + +static unsigned int hash_IHASH PARAMS ((const void *)); +static int eq_IHASH PARAMS ((const void *, const void *)); + static void init_input_buffer PARAMS ((cpp_reader *, int, struct stat *)); static int file_cleanup PARAMS ((cpp_buffer *, cpp_reader *)); static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *)); @@ -50,50 +54,57 @@ static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *)); static void hack_vms_include_specification PARAMS ((char *)); #endif +/* Initial size of include hash table. */ +#define IHASHSIZE 50 + #ifndef INCLUDE_LEN_FUDGE #define INCLUDE_LEN_FUDGE 0 #endif -/* Look up or add an entry to the table of all includes. This table - is indexed by the name as it appears in the #include line. The - ->next_this_file chain stores all different files with the same - #include name (there are at least three ways this can happen). The - hash function could probably be improved a bit. */ - -static IHASH * -include_hash (pfile, fname, add) - cpp_reader *pfile; - const char *fname; - int add; +/* Open files in nonblocking mode, so we don't get stuck if someone + clever has asked cpp to process /dev/rmt0. _cpp_read_include_file + will check that we have a real file to work with. Also take care + not to acquire a controlling terminal by mistake (this can't happen + on sane systems, but paranoia is a virtue). */ +#define OMODES O_RDONLY|O_NONBLOCK|O_NOCTTY + +/* Calculate hash of an IHASH entry. */ +static unsigned int +hash_IHASH (x) + const void *x; { - unsigned int hash = 0; - IHASH *l, *m; - const char *f = fname; - - while (*f) - hash += *f++; + IHASH *i = (IHASH *)x; + unsigned int r = 0, len = 0; + const U_CHAR *s = i->nshort; + + if (i->hash != (unsigned long)-1) + return i->hash; + + do + len++, r = r * 67 + (*s++ - 113); + while (*s && *s != '.'); + i->hash = r + len; + return r + len; +} - l = pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE]; - m = 0; - for (; l; m = l, l = l->next) - if (!strcmp (l->nshort, fname)) - return l; +/* Compare an existing IHASH structure with a potential one. */ +static int +eq_IHASH (x, y) + const void *x; + const void *y; +{ + const U_CHAR *a = ((const IHASH *)x)->nshort; + const U_CHAR *b = ((const IHASH *)y)->nshort; + return !strcmp (a, b); +} - if (!add) - return 0; - - l = (IHASH *) xmalloc (sizeof (IHASH)); - l->next = NULL; - l->next_this_file = NULL; - l->foundhere = NULL; - l->buf = NULL; - l->limit = NULL; - if (m) - m->next = l; - else - pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE] = l; - - return l; +/* Init the hash table. In here so it can see the hash and eq functions. */ +void +_cpp_init_include_hash (pfile) + cpp_reader *pfile; +{ + pfile->all_include_files + = htab_create (IHASHSIZE, hash_IHASH, eq_IHASH, free); } /* Return 0 if the file pointed to by IHASH has never been included before, @@ -152,9 +163,10 @@ cpp_included (pfile, fname) cpp_reader *pfile; const char *fname; { - IHASH *ptr; - - ptr = include_hash (pfile, fname, 0); + IHASH dummy, *ptr; + dummy.nshort = fname; + dummy.hash = -1; + ptr = htab_find (pfile->all_include_files, (const void *)&dummy); return (ptr != NULL); } @@ -164,10 +176,7 @@ file_cleanup (pbuf, pfile) cpp_reader *pfile; { if (pbuf->buf) - { - free ((PTR) pbuf->buf); - pbuf->buf = 0; - } + free ((PTR) pbuf->buf); if (pfile->system_include_depth) pfile->system_include_depth--; return 0; @@ -178,7 +187,7 @@ file_cleanup (pbuf, pfile) (because it was included already and it's marked idempotent), -1 if an error occurred, or a file descriptor open on the file. *IHASH is set to point to the include hash entry for this file, and - *BEFORE is 1 if the file was included before (but needs to be read + *BEFORE is set to 1 if the file was included before (but needs to be read again). */ int _cpp_find_include_file (pfile, fname, search_start, ihash, before) @@ -188,97 +197,82 @@ _cpp_find_include_file (pfile, fname, search_start, ihash, before) IHASH **ihash; int *before; { - struct file_name_list *l; - IHASH *ih, *jh; - int f, len; + struct file_name_list *path; + IHASH *ih, **slot; + IHASH dummy; + int f; char *name; - - ih = include_hash (pfile, fname, 1); - jh = redundant_include_p (pfile, ih, - fname[0] == '/' ? ABSOLUTE_PATH : search_start); - - if (jh != 0) - { - *before = 1; - *ihash = jh; - if (jh == (IHASH *)-1) - return -2; - else - return open (jh->name, O_RDONLY, 0666); - } + dummy.hash = -1; + dummy.nshort = fname; + path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start; + slot = (IHASH **) htab_find_slot (pfile->all_include_files, + (const void *)&dummy, 1); - if (ih->foundhere) - /* A file is already known by this name, but it's not the same file. - Allocate another include_hash block and add it to the next_this_file - chain. */ + if (*slot && (ih = redundant_include_p (pfile, *slot, path))) { - jh = (IHASH *) xmalloc (sizeof (IHASH)); - while (ih->next_this_file) ih = ih->next_this_file; - - ih->next_this_file = jh; - jh = ih; - ih = ih->next_this_file; + if (ih == (IHASH *)-1) + return -2; - ih->next = NULL; - ih->next_this_file = NULL; - ih->buf = NULL; - ih->limit = NULL; + *before = 1; + *ihash = ih; + return open (ih->name, OMODES); } - *before = 0; - *ihash = ih; - ih->name = NULL; - ih->nshort = xstrdup (fname); - ih->control_macro = NULL; - - /* If the pathname is absolute, just open it. */ - if (fname[0] == '/') + + if (path == ABSOLUTE_PATH) { - ih->foundhere = ABSOLUTE_PATH; - ih->name = ih->nshort; - return open (ih->name, O_RDONLY, 0666); + name = (char *) fname; + f = open (name, OMODES); } - - /* Search directory path, trying to open the file. */ - - len = strlen (fname); - name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE); - - for (l = search_start; l; l = l->next) + else { - memcpy (name, l->name, l->nlen); - name[l->nlen] = '/'; - strcpy (&name[l->nlen+1], fname); - _cpp_simplify_pathname (name); - if (CPP_OPTIONS (pfile)->remap) - name = remap_filename (pfile, name, l); - - f = open (name, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666); -#ifdef EACCES - if (f == -1 && errno == EACCES) + /* Search directory path, trying to open the file. */ + name = alloca (strlen (fname) + pfile->max_include_len + + 2 + INCLUDE_LEN_FUDGE); + do { - cpp_error(pfile, "included file `%s' exists but is not readable", - name); - return -1; - } + memcpy (name, path->name, path->nlen); + name[path->nlen] = '/'; + strcpy (&name[path->nlen+1], fname); + _cpp_simplify_pathname (name); + if (CPP_OPTIONS (pfile)->remap) + name = remap_filename (pfile, name, path); + + f = open (name, OMODES); +#ifdef EACCES + if (f == -1 && errno == EACCES) + { + cpp_error (pfile, + "included file `%s' exists but is not readable", + name); + return -1; + } #endif - - if (f >= 0) - { - ih->foundhere = l; - ih->name = xrealloc (name, strlen (name) + 1); - return f; - } + if (f >= 0) + break; + path = path->next; + } + while (path); } - - if (jh) - { - jh->next_this_file = NULL; - free (ih); - } - free (name); - *ihash = (IHASH *)-1; + if (f == -1) return -1; + + ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)); + strcpy ((char *)ih->name, name); + ih->foundhere = path; + if (path == ABSOLUTE_PATH) + ih->nshort = ih->name; + else + ih->nshort = strstr (ih->name, fname); + ih->control_macro = NULL; + ih->hash = dummy.hash; + + ih->next_this_file = *slot; + *slot = ih; + + *before = 0; + *ihash = ih; + return f; } /* The file_name_map structure holds a mapping of file names for a @@ -482,54 +476,41 @@ cpp_read_file (pfile, fname) cpp_reader *pfile; const char *fname; { - IHASH *ih_fake; + IHASH *ih, **slot; + IHASH dummy; int f; - if (fname == NULL || *fname == 0) + if (fname == NULL) + fname = ""; + + dummy.hash = -1; + dummy.nshort = fname; + slot = (IHASH **) htab_find_slot (pfile->all_include_files, + (const void *) &dummy, 1); + if (*slot && (ih = redundant_include_p (pfile, *slot, ABSOLUTE_PATH))) { - fname = ""; - f = 0; + if (ih == (IHASH *)-1) + return 1; /* Already included. */ } - - /* Open the file in nonblocking mode, so we don't get stuck if - someone clever has asked cpp to process /dev/rmt0. - _cpp_read_include_file will check that we have a real file to - work with. Also take care not to acquire a controlling terminal - by mistake (this can't happen on sane systems, but paranoia is a - virtue). */ - else if ((f = open (fname, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666)) < 0) + else { - cpp_notice_from_errno (pfile, fname); - return 0; + ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (fname)); + ih->control_macro = 0; + ih->foundhere = ABSOLUTE_PATH; /* well sort of ... */ + ih->hash = dummy.hash; + strcpy ((char *)ih->name, fname); + ih->nshort = ih->name; + + ih->next_this_file = *slot; + *slot = ih; } - /* Push the buffer. */ - if (!cpp_push_buffer (pfile, NULL, 0)) - goto failed_push; - - /* Gin up an include_hash structure for this file and feed it - to finclude. */ - - ih_fake = (IHASH *) xmalloc (sizeof (IHASH)); - ih_fake->next = 0; - ih_fake->next_this_file = 0; - ih_fake->foundhere = ABSOLUTE_PATH; /* well sort of ... */ - ih_fake->name = fname; - ih_fake->control_macro = 0; - ih_fake->buf = (char *)-1; - ih_fake->limit = 0; - if (!_cpp_read_include_file (pfile, f, ih_fake)) - goto failed_finclude; - - return 1; + if (*fname == '\0') + f = 0; + else + f = open (fname, OMODES); - failed_finclude: - /* If finclude fails, it pops the buffer. */ - free (ih_fake); - failed_push: - if (f) - close (f); - return 0; + return _cpp_read_include_file (pfile, f, ih); } /* Read the contents of FD into the buffer on the top of PFILE's stack. @@ -549,13 +530,16 @@ _cpp_read_include_file (pfile, fd, ihash) long length; cpp_buffer *fp; + fp = cpp_push_buffer (pfile, NULL, 0); + + if (fp == 0) + goto push_fail; + if (fstat (fd, &st) < 0) goto perror_fail; if (fcntl (fd, F_SETFL, 0) == -1) /* turn off nonblocking mode */ goto perror_fail; - fp = CPP_BUFFER (pfile); - /* If fd points to a plain file, we know how big it is, so we can allocate the buffer all at once. If fd is a pipe or terminal, we can't. Most C source files are 4k or less, so we guess that. If @@ -632,12 +616,14 @@ _cpp_read_include_file (pfile, fd, ihash) fp->actual_dir = actual_directory (pfile, ihash->name); pfile->input_stack_listing_current = 0; + pfile->only_seen_white = 2; return 1; perror_fail: cpp_error_from_errno (pfile, ihash->name); fail: cpp_pop_buffer (pfile); + push_fail: close (fd); return 0; } @@ -1485,7 +1471,7 @@ hack_vms_include_specification (fullname) if (check_filename_before_returning) { - f = open (fullname, O_RDONLY, 0666); + f = open (fullname, OMODES); if (f >= 0) { /* The file name is OK as it is, so return it as is. */ |