summaryrefslogtreecommitdiff
path: root/gcc/cpphash.c
diff options
context:
space:
mode:
authorYamaArashi <shadow962@live.com>2016-01-06 01:47:28 -0800
committerYamaArashi <shadow962@live.com>2016-01-06 01:47:28 -0800
commitbe8b04496302184c6e8f04d6179f9c3afc50aeb6 (patch)
tree726e2468c0c07add773c0dbd86ab6386844259ae /gcc/cpphash.c
initial commit
Diffstat (limited to 'gcc/cpphash.c')
-rwxr-xr-xgcc/cpphash.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
new file mode 100755
index 0000000..2ce8a3c
--- /dev/null
+++ b/gcc/cpphash.c
@@ -0,0 +1,200 @@
+/* Part of CPP library. (Macro hash table support.)
+ Copyright (C) 1986, 87, 89, 92-95, 1996, 1998 Free Software Foundation, Inc.
+ Written by Per Bothner, 1994.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+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
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+
+static HASHNODE *hashtab[HASHSIZE];
+
+/* Return hash function on name. must be compatible with the one
+ computed a step at a time, elsewhere */
+
+int
+hashf (name, len, hashsize)
+ register const U_CHAR *name;
+ register int len;
+ int hashsize;
+{
+ register int r = 0;
+
+ while (len--)
+ r = HASHSTEP (r, *name++);
+
+ return MAKE_POS (r) % hashsize;
+}
+
+/* Find the most recent hash node for name "name" (ending with first
+ non-identifier char) installed by install
+
+ 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_lookup (pfile, name, len, hash)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ const U_CHAR *name;
+ int len;
+ int hash;
+{
+ register const U_CHAR *bp;
+ register HASHNODE *bucket;
+
+ if (len < 0)
+ {
+ for (bp = name; is_idchar[*bp]; bp++) ;
+ len = bp - name;
+ }
+
+ if (hash < 0)
+ hash = hashf (name, len, HASHSIZE);
+
+ bucket = hashtab[hash];
+ while (bucket) {
+ if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
+ return bucket;
+ bucket = bucket->next;
+ }
+ return (HASHNODE *) 0;
+}
+
+/*
+ * 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.
+ */
+
+/* Note that the DEFINITION of a macro is removed from the hash table
+ but its storage is not freed. This would be a storage leak
+ except that it is not reasonable to keep undefining and redefining
+ large numbers of macros many times.
+ In any case, this is necessary, because a macro can be #undef'd
+ in the middle of reading the arguments to a call to it.
+ If #undef freed the DEFINITION, that would crash. */
+
+void
+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)
+ {
+ DEFINITION *d = hp->value.defn;
+ struct reflist *ap, *nextap;
+
+ for (ap = d->pattern; ap != NULL; ap = nextap)
+ {
+ nextap = ap->next;
+ free (ap);
+ }
+ if (d->nargs >= 0)
+ free (d->args.argnames);
+ free (d);
+ }
+
+ 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 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 *
+install (name, len, type, ivalue, value, hash)
+ U_CHAR *name;
+ int len;
+ enum node_type type;
+ int ivalue;
+ char *value;
+ int hash;
+{
+ register HASHNODE *hp;
+ register int i, bucket;
+ register U_CHAR *p;
+
+ if (len < 0) {
+ p = name;
+ while (is_idchar[*p])
+ p++;
+ len = p - name;
+ }
+
+ if (hash < 0)
+ hash = hashf (name, len, HASHSIZE);
+
+ i = sizeof (HASHNODE) + len + 1;
+ hp = (HASHNODE *) xmalloc (i);
+ bucket = hash;
+ hp->bucket_hdr = &hashtab[bucket];
+ hp->next = hashtab[bucket];
+ hashtab[bucket] = hp;
+ hp->prev = NULL;
+ if (hp->next != NULL)
+ hp->next->prev = hp;
+ hp->type = type;
+ hp->length = len;
+ if (hp->type == T_CONST)
+ hp->value.ival = ivalue;
+ else
+ hp->value.cpval = value;
+ hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
+ bcopy (name, hp->name, len);
+ hp->name[len] = 0;
+ return hp;
+}
+
+void
+cpp_hash_cleanup (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ register int i;
+ for (i = HASHSIZE; --i >= 0; )
+ {
+ while (hashtab[i])
+ delete_macro (hashtab[i]);
+ }
+}