From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- libraries/edje/src/bin/epp/cpphash.c | 198 +++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 libraries/edje/src/bin/epp/cpphash.c (limited to 'libraries/edje/src/bin/epp/cpphash.c') diff --git a/libraries/edje/src/bin/epp/cpphash.c b/libraries/edje/src/bin/epp/cpphash.c new file mode 100644 index 0000000..e3b68e0 --- /dev/null +++ b/libraries/edje/src/bin/epp/cpphash.c @@ -0,0 +1,198 @@ +/* Part of CPP library. (Macro hash table support.) + * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + * Written by Per Bothner, 1994. + * Based on CCCP program by by Paul Rubin, June 1986 + * Adapted to ANSI C, Richard Stallman, Jan 1987 + * Copyright (C) 2003-2011 Kim Woelders + * + * 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, 675 Mass Ave, Cambridge, MA 02139, 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! */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "cpplib.h" +#include "cpphash.h" + +static HASHNODE *hashtab[HASHSIZE]; + +#define IS_IDCHAR(ch) is_idchar[(unsigned char)(ch)] + +/* + * return hash function on name. must be compatible with the one + * computed a step at a time, elsewhere + */ +int +hashf(const char *name, int len, int hashsize) +{ + 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(const char *name, int len, int hash) +{ + const char *bp; + 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((const char *)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(HASHNODE * hp) +{ + + if (hp->prev) + hp->prev->next = hp->next; + if (hp->next) + 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; 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(const char *name, int len, enum node_type type, int ivalue, char *value, + int hash) +{ + HASHNODE *hp; + int i, bucket; + const 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) + 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 = ((char *)hp) + sizeof(HASHNODE); + memcpy(hp->name, name, len); + hp->name[len] = 0; + return hp; +} + +void +cpp_hash_cleanup(cpp_reader * pfile __UNUSED__) +{ + int i; + + for (i = HASHSIZE; --i >= 0;) + { + while (hashtab[i]) + delete_macro(hashtab[i]); + } +} -- cgit v1.1