Commit d35364d1 by Zack Weinberg Committed by Zack Weinberg

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.

From-SVN: r32497
parent 6973bf54
2000-03-12 Zack Weinberg <zack@wolery.cumb.org>
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.
2000-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2000-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* cppinit.c (cl_directive_handler): More K&R fixing. * cppinit.c (cl_directive_handler): More K&R fixing.
......
...@@ -2029,6 +2029,7 @@ LIBCPP_OBJS = cpplib.o cpphash.o cpperror.o cppexp.o cppfiles.o \ ...@@ -2029,6 +2029,7 @@ LIBCPP_OBJS = cpplib.o cpphash.o cpperror.o cppexp.o cppfiles.o \
prefix.o version.o mbchar.o @extra_cpp_objs@ prefix.o version.o mbchar.o @extra_cpp_objs@
LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
HASHTAB_H = $(srcdir)/../include/hashtab.h
# All the other archives built/used by this makefile are for targets. This # All the other archives built/used by this makefile are for targets. This
# one is strictly for the host. # one is strictly for the host.
...@@ -2042,17 +2043,17 @@ cppmain$(exeext): cppmain.o intl.o libcpp.a $(LIBDEPS) ...@@ -2042,17 +2043,17 @@ cppmain$(exeext): cppmain.o intl.o libcpp.a $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cppmain$(exeext) cppmain.o \ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cppmain$(exeext) cppmain.o \
intl.o libcpp.a $(LIBS) intl.o libcpp.a $(LIBS)
cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h system.h cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h system.h
cppulp.o: cppulp.c $(CONFIG_H) system.h output.h cppulp.o: cppulp.c $(CONFIG_H) system.h output.h
cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) mkdeps.h
cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) version.h
cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS) cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS) cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS)
cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H)
cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H) version.h
cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H) mkdeps.h
cppinit.o: cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \ cppinit.o: cppinit.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H) mkdeps.h \
cpphash.h prefix.h output.h Makefile version.h mkdeps.h prefix.h output.h Makefile version.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(PREPROCESSOR_DEFINES) \ $(PREPROCESSOR_DEFINES) \
-c `echo $(srcdir)/cppinit.c | sed 's,^\./,,'` -c `echo $(srcdir)/cppinit.c | sed 's,^\./,,'`
......
...@@ -27,10 +27,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -27,10 +27,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "system.h" #include "system.h"
#include "cpplib.h" #include "cpplib.h"
#include "cpphash.h" #include "cpphash.h"
#include "hashtab.h"
#include "version.h" #include "version.h"
#undef abort #undef abort
static unsigned int hashf PARAMS ((const U_CHAR *, int)); static unsigned int hash_HASHNODE PARAMS ((const void *));
static int eq_HASHNODE PARAMS ((const void *, const void *));
static void del_HASHNODE PARAMS ((void *));
static int dump_hash_helper PARAMS ((void *, void *));
static int comp_def_part PARAMS ((int, U_CHAR *, int, U_CHAR *, static int comp_def_part PARAMS ((int, U_CHAR *, int, U_CHAR *,
int, int)); int, int));
static void push_macro_expansion PARAMS ((cpp_reader *, static void push_macro_expansion PARAMS ((cpp_reader *,
...@@ -45,6 +50,9 @@ static void special_symbol PARAMS ((HASHNODE *, cpp_reader *)); ...@@ -45,6 +50,9 @@ static void special_symbol PARAMS ((HASHNODE *, cpp_reader *));
#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) #define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
/* Initial hash table size. (It can grow if necessary - see hashtab.c.) */
#define HASHSIZE 500
/* The arglist structure is built by create_definition to tell /* The arglist structure is built by create_definition to tell
collect_expansion where the argument names begin. That collect_expansion where the argument names begin. That
is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
...@@ -92,28 +100,81 @@ struct argdata ...@@ -92,28 +100,81 @@ struct argdata
int stringified_length; int stringified_length;
}; };
/* Calculate hash of a HASHNODE structure. */
/* Calculate hash function on a string. */
static unsigned int static unsigned int
hashf (s, len) hash_HASHNODE (x)
register const U_CHAR *s; const void *x;
register int len;
{ {
unsigned int n = len; HASHNODE *h = (HASHNODE *)x;
unsigned int r = 0; const U_CHAR *s = h->name;
unsigned int len = h->length;
unsigned int n = len, r = 0;
if (h->hash != (unsigned long)-1)
return h->hash;
do do
r = r * 67 + (*s++ - 113); r = r * 67 + (*s++ - 113);
while (--n); while (--n);
h->hash = r + len;
return r + len; return r + len;
} }
/* Find the most recent hash node for name "name" (ending with first /* Compare two HASHNODE structures. */
non-identifier char) installed by cpp_install static int
eq_HASHNODE (x, y)
const void *x;
const void *y;
{
const HASHNODE *a = (const HASHNODE *)x;
const HASHNODE *b = (const HASHNODE *)y;
return (a->length == b->length
&& !strncmp (a->name, b->name, a->length));
}
/* Destroy a HASHNODE. */
static void
del_HASHNODE (x)
void *x;
{
HASHNODE *h = (HASHNODE *)x;
if (h->type == T_MACRO)
_cpp_free_definition (h->value.defn);
free ((void *) h->name);
free (h);
}
/* Allocate and initialize a HASHNODE structure.
Caller must fill in the value field. */
HASHNODE *
_cpp_make_hashnode (name, len, type, hash)
const U_CHAR *name;
size_t len;
enum node_type type;
unsigned long hash;
{
HASHNODE *hp = (HASHNODE *) xmalloc (sizeof (HASHNODE));
U_CHAR *p = xmalloc (len + 1);
hp->type = type;
hp->length = len;
hp->name = p;
hp->hash = hash;
memcpy (p, name, len);
p[len] = 0;
return hp;
}
/* Find the hash node for name "name", which ends at the first
non-identifier char.
If LEN is >= 0, it is the length of the name. If LEN is >= 0, it is the length of the name.
Otherwise, compute the length by scanning the entire name. */ Otherwise, compute the length now. */
HASHNODE * HASHNODE *
_cpp_lookup (pfile, name, len) _cpp_lookup (pfile, name, len)
...@@ -121,9 +182,8 @@ _cpp_lookup (pfile, name, len) ...@@ -121,9 +182,8 @@ _cpp_lookup (pfile, name, len)
const U_CHAR *name; const U_CHAR *name;
int len; int len;
{ {
register const U_CHAR *bp; const U_CHAR *bp;
register HASHNODE *bucket; HASHNODE dummy;
register unsigned int hash;
if (len < 0) if (len < 0)
{ {
...@@ -131,16 +191,49 @@ _cpp_lookup (pfile, name, len) ...@@ -131,16 +191,49 @@ _cpp_lookup (pfile, name, len)
len = bp - name; len = bp - name;
} }
hash = hashf (name, len) % HASHSIZE; dummy.name = name;
dummy.length = len;
dummy.hash = -1;
return (HASHNODE *) htab_find (pfile->hashtab, (void *)&dummy);
}
/* Find the hashtable slot for name "name". Used to insert or delete. */
HASHNODE **
_cpp_lookup_slot (pfile, name, len, insert, hash)
cpp_reader *pfile;
const U_CHAR *name;
int len;
int insert;
unsigned long *hash;
{
const U_CHAR *bp;
HASHNODE dummy;
HASHNODE **slot;
bucket = pfile->hashtab[hash]; if (len < 0)
while (bucket)
{ {
if (bucket->length == len && strncmp (bucket->name, name, len) == 0) for (bp = name; is_idchar (*bp); bp++);
return bucket; len = bp - name;
bucket = bucket->next;
} }
return (HASHNODE *) 0;
dummy.name = name;
dummy.length = len;
dummy.hash = -1;
slot = (HASHNODE **) htab_find_slot (pfile->hashtab, (void *)&dummy, insert);
if (insert)
*hash = dummy.hash;
return slot;
}
/* Init the hash table. In here so it can see the hash and eq functions. */
void
_cpp_init_macro_hash (pfile)
cpp_reader *pfile;
{
pfile->hashtab = htab_create (HASHSIZE, hash_HASHNODE,
eq_HASHNODE, del_HASHNODE);
} }
/* Free a DEFINITION structure. Used by delete_macro, and by /* Free a DEFINITION structure. Used by delete_macro, and by
...@@ -162,86 +255,6 @@ _cpp_free_definition (d) ...@@ -162,86 +255,6 @@ _cpp_free_definition (d)
free (d); free (d);
} }
/*
* Delete a hash node. Some weirdness to free junk from macros.
* More such weirdness will have to be added if you define more hash
* types that need it.
*/
void
_cpp_delete_macro (hp)
HASHNODE *hp;
{
if (hp->prev != NULL)
hp->prev->next = hp->next;
if (hp->next != NULL)
hp->next->prev = hp->prev;
/* make sure that the bucket chain header that
the deleted guy was on points to the right thing afterwards. */
if (hp == *hp->bucket_hdr)
*hp->bucket_hdr = hp->next;
if (hp->type == T_MACRO)
_cpp_free_definition (hp->value.defn);
free (hp);
}
/* Install a name in the main hash table, even if it is already there.
Name stops with first non alphanumeric, except leading '#'.
Caller must check against redefinition if that is desired.
delete_macro () removes things installed by cpp_install () in fifo order.
this is important because of the `defined' special symbol used
in #if, and also if pushdef/popdef directives are ever implemented.
If LEN is >= 0, it is the length of the name.
Otherwise, compute the length by scanning the entire name.
If HASH is >= 0, it is the precomputed hash code.
Otherwise, compute the hash code. */
HASHNODE *
_cpp_install (pfile, name, len, type, value)
cpp_reader *pfile;
const U_CHAR *name;
int len;
enum node_type type;
const char *value;
{
register HASHNODE *hp;
register int i, bucket;
register const U_CHAR *p;
unsigned int hash;
if (len < 0)
{
p = name;
while (is_idchar(*p))
p++;
len = p - name;
}
hash = hashf (name, len) % HASHSIZE;
i = sizeof (HASHNODE) + len + 1;
hp = (HASHNODE *) xmalloc (i);
bucket = hash;
hp->bucket_hdr = &pfile->hashtab[bucket];
hp->next = pfile->hashtab[bucket];
pfile->hashtab[bucket] = hp;
hp->prev = NULL;
if (hp->next != NULL)
hp->next->prev = hp;
hp->type = type;
hp->length = len;
hp->value.cpval = value;
hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
memcpy (hp->name, name, len);
hp->name[len] = 0;
return hp;
}
static int static int
macro_cleanup (pbuf, pfile) macro_cleanup (pbuf, pfile)
cpp_buffer *pbuf; cpp_buffer *pbuf;
...@@ -255,7 +268,6 @@ macro_cleanup (pbuf, pfile) ...@@ -255,7 +268,6 @@ macro_cleanup (pbuf, pfile)
return 0; return 0;
} }
/* Read a replacement list for a macro, and build the DEFINITION /* Read a replacement list for a macro, and build the DEFINITION
structure. ARGLIST specifies the formal parameters to look for in structure. ARGLIST specifies the formal parameters to look for in
the text of the definition. If ARGLIST is null, this is an the text of the definition. If ARGLIST is null, this is an
...@@ -503,7 +515,6 @@ collect_expansion (pfile, arglist) ...@@ -503,7 +515,6 @@ collect_expansion (pfile, arglist)
while (here > last && is_hspace (pfile->token_buffer [here-1])) while (here > last && is_hspace (pfile->token_buffer [here-1]))
here--; here--;
CPP_SET_WRITTEN (pfile, here); CPP_SET_WRITTEN (pfile, here);
CPP_NUL_TERMINATE (pfile); CPP_NUL_TERMINATE (pfile);
len = CPP_WRITTEN (pfile) - start + 1; len = CPP_WRITTEN (pfile) - start + 1;
/* space for no-concat markers at either end */ /* space for no-concat markers at either end */
...@@ -1666,8 +1677,27 @@ _cpp_dump_definition (pfile, sym, len, defn) ...@@ -1666,8 +1677,27 @@ _cpp_dump_definition (pfile, sym, len, defn)
if (*x == '\r') x += 2, i -= 2; if (*x == '\r') x += 2, i -= 2;
if (i > 0) CPP_PUTS (pfile, x, i); if (i > 0) CPP_PUTS (pfile, x, i);
} }
if (pfile->lineno == 0) if (pfile->lineno == 0)
CPP_PUTC (pfile, '\n'); CPP_PUTC (pfile, '\n');
CPP_NUL_TERMINATE (pfile); CPP_NUL_TERMINATE (pfile);
} }
/* Dump out the hash table. */
static int
dump_hash_helper (h, p)
void *h;
void *p;
{
HASHNODE *hp = (HASHNODE *)h;
cpp_reader *pfile = (cpp_reader *)p;
_cpp_dump_definition (pfile, hp->name, hp->length, hp->value.defn);
return 1;
}
void
_cpp_dump_macro_hash (pfile)
cpp_reader *pfile;
{
htab_traverse (pfile->hashtab, dump_hash_helper, pfile);
}
...@@ -132,15 +132,11 @@ union hashval ...@@ -132,15 +132,11 @@ union hashval
typedef struct hashnode HASHNODE; typedef struct hashnode HASHNODE;
struct hashnode struct hashnode
{ {
struct hashnode *next; /* double links for easy deletion */ const U_CHAR *name; /* the actual name */
struct hashnode *prev; size_t length; /* length of token, for quick comparison */
struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash unsigned long hash; /* cached hash value */
chain is kept, in case the node is the head
of the chain and gets deleted. */
enum node_type type; /* type of special token */
int length; /* length of token, for quick comparison */
U_CHAR *name; /* the actual name */
union hashval value; /* pointer to expansion, or whatever */ union hashval value; /* pointer to expansion, or whatever */
enum node_type type; /* type of special token */
}; };
/* List of directories to look for include files in. */ /* List of directories to look for include files in. */
...@@ -169,7 +165,6 @@ struct file_name_list ...@@ -169,7 +165,6 @@ struct file_name_list
#include statement) which is stored in *nshort. */ #include statement) which is stored in *nshort. */
struct ihash struct ihash
{ {
struct ihash *next;
/* Next file with the same short name but a /* Next file with the same short name but a
different (partial) pathname). */ different (partial) pathname). */
struct ihash *next_this_file; struct ihash *next_this_file;
...@@ -177,12 +172,13 @@ struct ihash ...@@ -177,12 +172,13 @@ struct ihash
/* Location of the file in the include search path. /* Location of the file in the include search path.
Used for include_next */ Used for include_next */
struct file_name_list *foundhere; struct file_name_list *foundhere;
const char *name; /* (partial) pathname of file */
const char *nshort; /* name of file as referenced in #include */ unsigned long hash; /* save hash value for future reference */
const char *nshort; /* name of file as referenced in #include;
points into name[] */
const U_CHAR *control_macro; /* macro, if any, preventing reinclusion - const U_CHAR *control_macro; /* macro, if any, preventing reinclusion -
see redundant_include_p */ see redundant_include_p */
char *buf, *limit; /* for file content cache, const char name[1]; /* (partial) pathname of file */
not yet implemented */
}; };
typedef struct ihash IHASH; typedef struct ihash IHASH;
...@@ -247,19 +243,23 @@ extern unsigned char _cpp_IStable[256]; ...@@ -247,19 +243,23 @@ extern unsigned char _cpp_IStable[256];
(CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p) (CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p)
/* In cpphash.c */ /* In cpphash.c */
extern HASHNODE *_cpp_install PARAMS ((cpp_reader *, const U_CHAR *, int, extern HASHNODE *_cpp_make_hashnode PARAMS ((const U_CHAR *, size_t,
enum node_type, const char *)); enum node_type,
extern HASHNODE *_cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int)); unsigned long));
extern void _cpp_free_definition PARAMS ((DEFINITION *)); extern HASHNODE *_cpp_lookup PARAMS ((cpp_reader *,
extern void _cpp_delete_macro PARAMS ((HASHNODE *)); const U_CHAR *, int));
extern HASHNODE **_cpp_lookup_slot PARAMS ((cpp_reader *,
extern DEFINITION *_cpp_create_definition const U_CHAR *, int, int,
PARAMS ((cpp_reader *, int)); unsigned long *));
extern int _cpp_compare_defs PARAMS ((cpp_reader *, DEFINITION *, extern void _cpp_free_definition PARAMS ((DEFINITION *));
DEFINITION *)); extern DEFINITION *_cpp_create_definition PARAMS ((cpp_reader *, int));
extern void _cpp_macroexpand PARAMS ((cpp_reader *, HASHNODE *)); extern void _cpp_dump_definition PARAMS ((cpp_reader *, const U_CHAR *,
extern void _cpp_dump_definition PARAMS ((cpp_reader *, const U_CHAR *, long, long, DEFINITION *));
DEFINITION *)); extern int _cpp_compare_defs PARAMS ((cpp_reader *, DEFINITION *,
DEFINITION *));
extern void _cpp_macroexpand PARAMS ((cpp_reader *, HASHNODE *));
extern void _cpp_init_macro_hash PARAMS ((cpp_reader *));
extern void _cpp_dump_macro_hash PARAMS ((cpp_reader *));
/* In cppfiles.c */ /* In cppfiles.c */
extern void _cpp_simplify_pathname PARAMS ((char *)); extern void _cpp_simplify_pathname PARAMS ((char *));
...@@ -267,6 +267,7 @@ extern int _cpp_find_include_file PARAMS ((cpp_reader *, const char *, ...@@ -267,6 +267,7 @@ extern int _cpp_find_include_file PARAMS ((cpp_reader *, const char *,
struct file_name_list *, struct file_name_list *,
IHASH **, int *)); IHASH **, int *));
extern int _cpp_read_include_file PARAMS ((cpp_reader *, int, IHASH *)); extern int _cpp_read_include_file PARAMS ((cpp_reader *, int, IHASH *));
extern void _cpp_init_include_hash PARAMS ((cpp_reader *));
/* In cppexp.c */ /* In cppexp.c */
extern int _cpp_parse_expr PARAMS ((cpp_reader *)); extern int _cpp_parse_expr PARAMS ((cpp_reader *));
......
...@@ -28,6 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -28,6 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "prefix.h" #include "prefix.h"
#include "intl.h" #include "intl.h"
#include "version.h" #include "version.h"
#include "hashtab.h"
#include "mkdeps.h" #include "mkdeps.h"
/* Predefined symbols, built-in macros, and the default include path. */ /* Predefined symbols, built-in macros, and the default include path. */
...@@ -554,7 +555,8 @@ cpp_reader_init (pfile) ...@@ -554,7 +555,8 @@ cpp_reader_init (pfile)
pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size); pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size);
CPP_SET_WRITTEN (pfile, 0); CPP_SET_WRITTEN (pfile, 0);
pfile->hashtab = (HASHNODE **) xcalloc (HASHSIZE, sizeof (HASHNODE *)); _cpp_init_macro_hash (pfile);
_cpp_init_include_hash (pfile);
} }
/* Free resources used by PFILE. /* Free resources used by PFILE.
...@@ -563,7 +565,6 @@ void ...@@ -563,7 +565,6 @@ void
cpp_cleanup (pfile) cpp_cleanup (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int i;
while (CPP_BUFFER (pfile) != NULL) while (CPP_BUFFER (pfile) != NULL)
cpp_pop_buffer (pfile); cpp_pop_buffer (pfile);
...@@ -584,25 +585,8 @@ cpp_cleanup (pfile) ...@@ -584,25 +585,8 @@ cpp_cleanup (pfile)
if (pfile->deps) if (pfile->deps)
deps_free (pfile->deps); deps_free (pfile->deps);
for (i = ALL_INCLUDE_HASHSIZE; --i >= 0; ) htab_delete (pfile->hashtab);
{ htab_delete (pfile->all_include_files);
IHASH *imp, *next;
for (imp = pfile->all_include_files[i]; imp; imp = next)
{
next = imp->next;
free ((PTR) imp->name);
free ((PTR) imp->nshort);
free (imp);
}
pfile->all_include_files[i] = 0;
}
for (i = HASHSIZE; --i >= 0;)
{
while (pfile->hashtab[i])
_cpp_delete_macro (pfile->hashtab[i]);
}
free (pfile->hashtab);
} }
...@@ -654,7 +638,6 @@ static const struct builtin builtin_array[] = ...@@ -654,7 +638,6 @@ static const struct builtin builtin_array[] =
/* Subroutine of cpp_start_read; reads the builtins table above and /* Subroutine of cpp_start_read; reads the builtins table above and
enters the macros into the hash table. */ enters the macros into the hash table. */
static void static void
initialize_builtins (pfile) initialize_builtins (pfile)
cpp_reader *pfile; cpp_reader *pfile;
...@@ -662,6 +645,7 @@ initialize_builtins (pfile) ...@@ -662,6 +645,7 @@ initialize_builtins (pfile)
int len; int len;
const struct builtin *b; const struct builtin *b;
const char *val; const char *val;
HASHNODE *hp;
for(b = builtin_array; b->name; b++) for(b = builtin_array; b->name; b++)
{ {
if ((b->flags & STDC) && CPP_TRADITIONAL (pfile)) if ((b->flags & STDC) && CPP_TRADITIONAL (pfile))
...@@ -670,7 +654,10 @@ initialize_builtins (pfile) ...@@ -670,7 +654,10 @@ initialize_builtins (pfile)
val = (b->flags & ULP) ? user_label_prefix : b->value; val = (b->flags & ULP) ? user_label_prefix : b->value;
len = strlen (b->name); len = strlen (b->name);
_cpp_install (pfile, b->name, len, b->type, val); hp = _cpp_make_hashnode (b->name, len, b->type, -1);
hp->value.cpval = val;
*(htab_find_slot (pfile->hashtab, (void *)hp, 1)) = hp;
if ((b->flags & DUMP) && CPP_OPTIONS (pfile)->debug_output) if ((b->flags & DUMP) && CPP_OPTIONS (pfile)->debug_output)
dump_special_to_buffer (pfile, b->name); dump_special_to_buffer (pfile, b->name);
} }
...@@ -1015,20 +1002,7 @@ cpp_finish (pfile) ...@@ -1015,20 +1002,7 @@ cpp_finish (pfile)
} }
if (opts->dump_macros == dump_only) if (opts->dump_macros == dump_only)
{ _cpp_dump_macro_hash (pfile);
int i;
HASHNODE *h;
for (i = HASHSIZE; --i >= 0;)
{
for (h = pfile->hashtab[i]; h; h = h->next)
if (h->type == T_MACRO)
{
_cpp_dump_definition (pfile, h->name, h->length,
h->value.defn);
CPP_PUTC (pfile, '\n');
}
}
}
} }
static void static void
......
...@@ -24,6 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -24,6 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpplib.h" #include "cpplib.h"
#include "cpphash.h" #include "cpphash.h"
#include "hashtab.h"
#include "intl.h" #include "intl.h"
#include "mkdeps.h" #include "mkdeps.h"
...@@ -659,9 +660,10 @@ do_define (pfile, keyword) ...@@ -659,9 +660,10 @@ do_define (pfile, keyword)
cpp_reader *pfile; cpp_reader *pfile;
const struct directive *keyword ATTRIBUTE_UNUSED; const struct directive *keyword ATTRIBUTE_UNUSED;
{ {
HASHNODE *hp; HASHNODE **slot;
DEFINITION *def; DEFINITION *def;
long here; long here;
unsigned long hash;
int len, c; int len, c;
int funlike = 0; int funlike = 0;
U_CHAR *sym; U_CHAR *sym;
...@@ -692,9 +694,11 @@ do_define (pfile, keyword) ...@@ -692,9 +694,11 @@ do_define (pfile, keyword)
if (def == 0) if (def == 0)
return 0; return 0;
if ((hp = _cpp_lookup (pfile, sym, len)) != NULL) slot = _cpp_lookup_slot (pfile, sym, len, 1, &hash);
if (*slot)
{ {
int ok; int ok;
HASHNODE *hp = *slot;
/* Redefining a macro is ok if the definitions are the same. */ /* Redefining a macro is ok if the definitions are the same. */
if (hp->type == T_MACRO) if (hp->type == T_MACRO)
...@@ -729,7 +733,11 @@ do_define (pfile, keyword) ...@@ -729,7 +733,11 @@ do_define (pfile, keyword)
} }
} }
else else
_cpp_install (pfile, sym, len, T_MACRO, (char *) def); {
HASHNODE *hp = _cpp_make_hashnode (sym, len, T_MACRO, hash);
hp->value.defn = def;
*slot = hp;
}
if (CPP_OPTIONS (pfile)->debug_output if (CPP_OPTIONS (pfile)->debug_output
|| CPP_OPTIONS (pfile)->dump_macros == dump_definitions) || CPP_OPTIONS (pfile)->dump_macros == dump_definitions)
...@@ -1260,21 +1268,12 @@ do_include (pfile, keyword) ...@@ -1260,21 +1268,12 @@ do_include (pfile, keyword)
if (importing) if (importing)
ihash->control_macro = (const U_CHAR *) ""; ihash->control_macro = (const U_CHAR *) "";
if (cpp_push_buffer (pfile, NULL, 0) == NULL)
{
close (fd);
return 0;
}
if (angle_brackets)
pfile->system_include_depth++; /* Decremented in file_cleanup. */
if (_cpp_read_include_file (pfile, fd, ihash)) if (_cpp_read_include_file (pfile, fd, ihash))
{ {
output_line_command (pfile, enter_file); output_line_command (pfile, enter_file);
pfile->only_seen_white = 2; if (angle_brackets)
pfile->system_include_depth++; /* Decremented in file_cleanup. */
} }
return 0; return 0;
} }
...@@ -1435,7 +1434,7 @@ do_undef (pfile, keyword) ...@@ -1435,7 +1434,7 @@ do_undef (pfile, keyword)
const struct directive *keyword; const struct directive *keyword;
{ {
int len; int len;
HASHNODE *hp; HASHNODE **slot;
U_CHAR *buf, *name, *limit; U_CHAR *buf, *name, *limit;
int c; int c;
long here = CPP_WRITTEN (pfile); long here = CPP_WRITTEN (pfile);
...@@ -1468,8 +1467,10 @@ do_undef (pfile, keyword) ...@@ -1468,8 +1467,10 @@ do_undef (pfile, keyword)
} }
CPP_SET_WRITTEN (pfile, here); CPP_SET_WRITTEN (pfile, here);
while ((hp = _cpp_lookup (pfile, name, len)) != NULL) slot = _cpp_lookup_slot (pfile, name, len, 0, 0);
if (slot)
{ {
HASHNODE *hp = *slot;
/* If we are generating additional info for debugging (with -g) we /* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef commands. */ need to pass through all effective #undef commands. */
if (CPP_OPTIONS (pfile)->debug_output && keyword) if (CPP_OPTIONS (pfile)->debug_output && keyword)
...@@ -1480,7 +1481,8 @@ do_undef (pfile, keyword) ...@@ -1480,7 +1481,8 @@ do_undef (pfile, keyword)
{ {
if (hp->type != T_MACRO) if (hp->type != T_MACRO)
cpp_warning (pfile, "undefining `%s'", hp->name); cpp_warning (pfile, "undefining `%s'", hp->name);
_cpp_delete_macro (hp);
htab_clear_slot (pfile->hashtab, (void **)slot);
} }
} }
...@@ -1692,6 +1694,7 @@ do_pragma_implementation (pfile) ...@@ -1692,6 +1694,7 @@ do_pragma_implementation (pfile)
long written = CPP_WRITTEN (pfile); long written = CPP_WRITTEN (pfile);
U_CHAR *name; U_CHAR *name;
U_CHAR *copy; U_CHAR *copy;
size_t len;
token = get_directive_token (pfile); token = get_directive_token (pfile);
if (token == CPP_VSPACE) if (token == CPP_VSPACE)
...@@ -1703,14 +1706,15 @@ do_pragma_implementation (pfile) ...@@ -1703,14 +1706,15 @@ do_pragma_implementation (pfile)
} }
name = pfile->token_buffer + written + 1; name = pfile->token_buffer + written + 1;
copy = (U_CHAR *) xstrdup (name); len = strlen (name);
copy[strlen(copy)] = '\0'; /* trim trailing quote */ copy = (U_CHAR *) alloca (len);
memcpy (copy, name, len - 1);
copy[len] = '\0'; /* trim trailing quote */
if (cpp_included (pfile, copy)) if (cpp_included (pfile, copy))
cpp_warning (pfile, cpp_warning (pfile,
"`#pragma implementation' for `%s' appears after file is included", "`#pragma implementation' for `%s' appears after file is included",
copy); copy);
free (copy);
return 0; return 0;
} }
...@@ -1721,11 +1725,13 @@ do_pragma_poison (pfile) ...@@ -1721,11 +1725,13 @@ do_pragma_poison (pfile)
/* Poison these symbols so that all subsequent usage produces an /* Poison these symbols so that all subsequent usage produces an
error message. */ error message. */
U_CHAR *p; U_CHAR *p;
HASHNODE *hp; HASHNODE **slot;
long written; long written;
size_t len; size_t len;
enum cpp_token token; enum cpp_token token;
int writeit; int writeit;
unsigned long hash;
/* As a rule, don't include #pragma poison commands in output, /* As a rule, don't include #pragma poison commands in output,
unless the user asks for them. */ unless the user asks for them. */
writeit = (CPP_OPTIONS (pfile)->debug_output writeit = (CPP_OPTIONS (pfile)->debug_output
...@@ -1747,8 +1753,10 @@ do_pragma_poison (pfile) ...@@ -1747,8 +1753,10 @@ do_pragma_poison (pfile)
p = pfile->token_buffer + written; p = pfile->token_buffer + written;
len = strlen (p); len = strlen (p);
if ((hp = _cpp_lookup (pfile, p, len))) slot = _cpp_lookup_slot (pfile, p, len, 1, &hash);
if (*slot)
{ {
HASHNODE *hp = *slot;
if (hp->type != T_POISON) if (hp->type != T_POISON)
{ {
cpp_warning (pfile, "poisoning existing macro `%s'", p); cpp_warning (pfile, "poisoning existing macro `%s'", p);
...@@ -1759,7 +1767,11 @@ do_pragma_poison (pfile) ...@@ -1759,7 +1767,11 @@ do_pragma_poison (pfile)
} }
} }
else else
_cpp_install (pfile, p, len, T_POISON, 0); {
HASHNODE *hp = _cpp_make_hashnode (p, len, T_POISON, hash);
hp->value.cpval = 0;
*slot = hp;
}
if (writeit) if (writeit)
CPP_PUTC (pfile, ' '); CPP_PUTC (pfile, ' ');
} }
...@@ -3025,7 +3037,9 @@ do_assert (pfile, keyword) ...@@ -3025,7 +3037,9 @@ do_assert (pfile, keyword)
U_CHAR *sym; U_CHAR *sym;
int ret, c; int ret, c;
HASHNODE *base, *this; HASHNODE *base, *this;
int baselen, thislen; HASHNODE **bslot, **tslot;
size_t blen, tlen;
unsigned long bhash, thash;
if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing) if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing)
cpp_pedwarn (pfile, "ANSI C does not allow `#assert'"); cpp_pedwarn (pfile, "ANSI C does not allow `#assert'");
...@@ -3049,27 +3063,30 @@ do_assert (pfile, keyword) ...@@ -3049,27 +3063,30 @@ do_assert (pfile, keyword)
goto error; goto error;
} }
thislen = strlen (sym); tlen = strlen (sym);
baselen = (U_CHAR *) strchr (sym, '(') - sym; blen = (U_CHAR *) strchr (sym, '(') - sym;
this = _cpp_lookup (pfile, sym, thislen); tslot = _cpp_lookup_slot (pfile, sym, tlen, 1, &thash);
if (this) if (*tslot)
{ {
cpp_warning (pfile, "`%s' re-asserted", sym); cpp_warning (pfile, "`%s' re-asserted", sym);
goto error; goto error;
} }
base = _cpp_lookup (pfile, sym, baselen); bslot = _cpp_lookup_slot (pfile, sym, blen, 1, &bhash);
if (! base) if (! *bslot)
base = _cpp_install (pfile, sym, baselen, T_ASSERT, 0); *bslot = base = _cpp_make_hashnode (sym, blen, T_ASSERT, bhash);
else if (base->type != T_ASSERT) else
{ {
/* Token clash - but with what?! */ base = *bslot;
cpp_ice (pfile, "base->type != T_ASSERT in do_assert"); if (base->type != T_ASSERT)
goto error; {
} /* Token clash - but with what?! */
cpp_ice (pfile, "base->type != T_ASSERT in do_assert");
this = _cpp_install (pfile, sym, thislen, T_ASSERT, goto error;
(char *)base->value.aschain); }
}
*tslot = this = _cpp_make_hashnode (sym, tlen, T_ASSERT, thash);
this->value.aschain = base->value.aschain;
base->value.aschain = this; base->value.aschain = this;
pfile->limit = sym; /* Pop */ pfile->limit = sym; /* Pop */
...@@ -3118,9 +3135,9 @@ do_unassert (pfile, keyword) ...@@ -3118,9 +3135,9 @@ do_unassert (pfile, keyword)
for (this = base->value.aschain; this; this = next) for (this = base->value.aschain; this; this = next)
{ {
next = this->value.aschain; next = this->value.aschain;
_cpp_delete_macro (this); htab_remove_elt (pfile->hashtab, this);
} }
_cpp_delete_macro (base); htab_remove_elt (pfile->hashtab, base);
} }
else else
{ {
...@@ -3135,10 +3152,11 @@ do_unassert (pfile, keyword) ...@@ -3135,10 +3152,11 @@ do_unassert (pfile, keyword)
next = next->value.aschain; next = next->value.aschain;
next->value.aschain = this->value.aschain; next->value.aschain = this->value.aschain;
_cpp_delete_macro (this); htab_remove_elt (pfile->hashtab, this);
if (base->value.aschain == NULL) if (base->value.aschain == NULL)
_cpp_delete_macro (base); /* Last answer for this predicate deleted. */ /* Last answer for this predicate deleted. */
htab_remove_elt (pfile->hashtab, base);
} }
pfile->limit = sym; /* Pop */ pfile->limit = sym; /* Pop */
......
...@@ -121,6 +121,7 @@ struct cpp_buffer ...@@ -121,6 +121,7 @@ struct cpp_buffer
}; };
struct file_name_map_list; struct file_name_map_list;
struct htab;
/* Maximum nesting of cpp_buffers. We use a static limit, partly for /* Maximum nesting of cpp_buffers. We use a static limit, partly for
efficiency, and partly to limit runaway recursion. */ efficiency, and partly to limit runaway recursion. */
...@@ -155,12 +156,10 @@ struct cpp_reader ...@@ -155,12 +156,10 @@ struct cpp_reader
int buffer_stack_depth; int buffer_stack_depth;
/* Hash table of macros and assertions. See cpphash.c */ /* Hash table of macros and assertions. See cpphash.c */
#define HASHSIZE 1403 struct htab *hashtab;
struct hashnode **hashtab;
/* Hash table of other included files. See cppfiles.c */ /* Hash table of other included files. See cppfiles.c */
#define ALL_INCLUDE_HASHSIZE 71 struct htab *all_include_files;
struct ihash *all_include_files[ALL_INCLUDE_HASHSIZE];
/* Chain of `actual directory' file_name_list entries, /* Chain of `actual directory' file_name_list entries,
for "" inclusion. */ for "" inclusion. */
...@@ -503,7 +502,6 @@ extern void output_line_command PARAMS ((cpp_reader *, ...@@ -503,7 +502,6 @@ extern void output_line_command PARAMS ((cpp_reader *,
extern int cpp_included PARAMS ((cpp_reader *, const char *)); extern int cpp_included PARAMS ((cpp_reader *, const char *));
extern int cpp_read_file PARAMS ((cpp_reader *, const char *)); extern int cpp_read_file PARAMS ((cpp_reader *, const char *));
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
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