/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2000 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
** MA 02111-1307, USA.
**
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For information on splint: info@splint.org
+** To report a bug: splint-bug@splint.org
+** For more information: http://www.splint.org
*/
/*
** cpphash.c
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! */
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
# include "llbasic.h"
# include <string.h>
-# include "cpp.h"
# include "cpplib.h"
# include "cpphash.h"
-typedef /*@only@*/ HASHNODE *o_HASHNODE;
+typedef /*@null@*/ /*@only@*/ hashNode o_hashNode;
+typedef /*@null@*/ /*@only@*/ hashNode n_hashNode;
-static o_HASHNODE hashtab[CPP_HASHSIZE];
-static o_HASHNODE ohashtab[CPP_HASHSIZE];
+static o_hashNode hashtab[CPP_HASHSIZE];
+static o_hashNode ohashtab[CPP_HASHSIZE];
-static void HashNode_delete (/*@null@*/ /*@only@*/ HASHNODE *);
+static void hashNode_delete (/*@null@*/ /*@only@*/ hashNode);
-/* p_prev need not be defined, but isn't defined by HashNode_copy */
+/* p_prev need not be defined, but isn't defined by hashNode_copy */
/*@function static unsigned int hashStep (unsigned, char) modifies nothing ; @*/
# define hashStep(old, c) (((old) << 2) + (unsigned int) (c))
/*@function static unsigned int makePositive (unsigned int) modifies nothing ; @*/
# define makePositive(v) ((v) & 0x7fffffff) /* make number positive */
-static /*@null@*/ HASHNODE *
- HashNode_copy (/*@null@*/ HASHNODE *,
- /*@dependent@*/ HASHNODE **p_hdr,
- /*@dependent@*/ /*@null@*/ /*@special@*/ HASHNODE *p_prev)
+static /*@null@*/ hashNode hashNode_copy (/*@null@*/ hashNode,
+ /*@null@*/ /*@dependent@*/ n_hashNode *p_hdr,
+ /*@dependent@*/ /*@null@*/ /*@special@*/ hashNode p_prev)
/*@*/ ;
void cppReader_saveHashtab ()
for (i = 0; i < CPP_HASHSIZE; i++)
{
- ohashtab[i] = HashNode_copy (hashtab[i], &ohashtab[i], NULL);
+ ohashtab[i] = hashNode_copy (hashtab[i], &ohashtab[i], NULL);
}
}
int i;
for (i = 0; i < CPP_HASHSIZE; i++) {
- /* HashNode_delete (hashtab[i]); */
- hashtab[i] = HashNode_copy (ohashtab[i], &hashtab[i], NULL);
+ /* hashNode_delete (hashtab[i]); */
+ hashtab[i] = hashNode_copy (ohashtab[i], &hashtab[i], NULL);
}
}
-static void HashNode_delete (/*@only@*/ /*@null@*/ HASHNODE *node)
+static void hashNode_delete (/*@only@*/ /*@null@*/ hashNode node)
{
if (node == NULL)
{
}
else
{
- HashNode_delete (node->next);
+ hashNode_delete (node->next);
if (node->type == T_MACRO)
{
}
}
-/*@null@*/ HASHNODE *HashNode_copy (HASHNODE *node, HASHNODE **hdr,
- /*@dependent@*/ HASHNODE *prev)
+/*@null@*/ hashNode hashNode_copy (hashNode node, hashNode *hdr,
+ /*@dependent@*/ hashNode prev)
{
if (node == NULL)
{
}
else
{
- HASHNODE *res = dmalloc (sizeof (*res));
+ hashNode res = dmalloc (sizeof (*res));
- res->next = HashNode_copy (node->next, hdr, res);
+ res->next = hashNode_copy (node->next, hdr, res);
res->prev = prev;
res->bucket_hdr = hdr;
for (ap = d->pattern; ap != NULL; ap = nextap)
{
- struct reflist *npattern = dmalloc (sizeof (*(nd->pattern)));
+ struct reflist *npattern = dmalloc (sizeof (* (nd->pattern)));
nextap = ap->next;
/*@-branchstate@*/
} /*@=branchstate@*/ /* npattern is propagated through loop */
- last = &(npattern->next);
+ last = & (npattern->next);
npattern->next = NULL; /* will get filled in */
npattern->stringify = d->pattern->stringify;
npattern->raw_before = d->pattern->raw_before;
** From: "N.Komazaki" <koma@focs.sei.co.jp>
*/
- /*! why doesn't lclint report an error for this? */
+ /*! why doesn't splint report an error for this? */
nd->args.argnames = mstring_createEmpty ();
}
}
else if (node->type == T_PCSTRING)
{
res->value.cpval = mstring_copy (node->value.cpval);
- llassert (res->value.cpval != NULL);
+ llassert (res->value.cpval != NULL);
}
else
{
computed a step at a time, elsewhere */
int
-hashf (const char *name, int len, int hashsize)
+cpphash_hashCode (const char *name, size_t len, int hashsize)
{
unsigned int r = 0;
/*
** Find the most recent hash node for name name (ending with first
-** non-identifier char) cppReader_installed by install
+** non-identifier char) cpphash_installed by install
**
-** 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.
**
-** If HASH is >= 0, it is the precomputed hash code.
+** If hash is >= 0, it is the precomputed hash code.
** Otherwise, compute the hash code.
*/
-/*@null@*/ HASHNODE *cppReader_lookup (char *name, int len, int hash)
+/*@null@*/ hashNode cpphash_lookup (char *name, int len, int hash)
{
const char *bp;
- HASHNODE *bucket;
+ hashNode bucket;
if (len < 0)
{
if (hash < 0)
{
- hash = hashf (name, len, CPP_HASHSIZE);
+ hash = cpphash_hashCode (name, size_fromInt (len), CPP_HASHSIZE);
}
bucket = hashtab[hash];
while (bucket != NULL)
{
- if (bucket->length == len &&
- cstring_equalLen (bucket->name, cstring_fromChars (name), len))
+ if (bucket->length == size_fromInt (len) &&
+ cstring_equalLen (bucket->name, cstring_fromChars (name), size_fromInt (len)))
{
return bucket;
}
return NULL;
}
-/*@null@*/ HASHNODE *cppReader_lookupExpand (char *name, int len, int hash)
+/*@null@*/ hashNode cpphash_lookupExpand (char *name, int len, int hash, bool forceExpand)
{
- HASHNODE *node = cppReader_lookup (name, len, hash);
+ hashNode node = cpphash_lookup (name, len, hash);
DPRINTF (("Lookup expand: %s", name));
DPRINTF (("Check macro..."));
- if (defn->noExpand) {
+ if (defn->noExpand && !forceExpand) {
DPRINTF (("No expand!"));
return NULL;
}
If #undef freed the DEFINITION, that would crash. */
void
-cppReader_deleteMacro (HASHNODE *hp)
+cppReader_deleteMacro (hashNode hp)
{
if (hp->prev != NULL)
{
/* make sure that the bucket chain header that
the deleted guy was on points to the right thing afterwards. */
+
+ llassert (hp != NULL);
+ llassert (hp->bucket_hdr != NULL);
+
if (hp == *hp->bucket_hdr) {
*hp->bucket_hdr = hp->next;
}
If HASH is >= 0, it is the precomputed hash code.
Otherwise, compute the hash code. */
-HASHNODE *cppReader_install (char *name, int len, enum node_type type,
+hashNode cpphash_install (char *name, int len, enum node_type type,
int ivalue, char *value, int hash)
{
- HASHNODE *hp;
- int i, bucket;
- char *p, *q;
+ hashNode hp;
+ int bucket;
+ char *p;
+
+ DPRINTF (("Install: %s / %d", name, len));
if (len < 0) {
p = name;
if (hash < 0)
{
- hash = hashf (name, len, CPP_HASHSIZE);
+ hash = cpphash_hashCode (name, size_fromInt (len), CPP_HASHSIZE);
}
- i = sizeof (*hp) + len + 1;
-
-
- hp = (HASHNODE *) dmalloc (size_fromInt (i));
+ hp = (hashNode) dmalloc (sizeof (*hp));
bucket = hash;
hp->bucket_hdr = &hashtab[bucket];
hashtab[bucket] = hp;
hp->type = type;
- hp->length = len;
+ hp->length = size_fromInt (len);
if (hp->type == T_CONST)
{
hp->value.cpval = value;
}
- {
- char *tmp = ((char *) hp) + sizeof (*hp);
- p = tmp;
- q = name;
-
- for (i = 0; i < len; i++)
- {
- *p++ = *q++;
- }
-
- tmp[len] = '\0';
- hp->name = cstring_fromChars (tmp);
- }
+ hp->name = cstring_clip (cstring_fromCharsNew (name), size_fromInt (len));
- /*@-mustfree@*/ /*@-uniondef@*/ /*@-compdef@*/
+ DPRINTF (("Name: *%s*", hp->name));
+ /*@-mustfree@*/ /*@-uniondef@*/ /*@-compdef@*/ /*@-compmempass@*/
return hp;
- /*@=mustfree@*/ /*@=uniondef@*/ /*@=compdef@*/
+ /*@=mustfree@*/ /*@=uniondef@*/ /*@=compdef@*/ /*@=compmempass@*/
}
-HASHNODE *cppReader_installMacro (char *name, int len,
- struct definition *defn, int hash)
+hashNode cpphash_installMacro (char *name, size_t len,
+ struct definition *defn, int hash)
{
- return cppReader_install (name, len, T_MACRO, 0, (char *) defn, hash);
+ DPRINTF (("install macro: %s", name));
+ return cpphash_install (name, size_toInt (len), T_MACRO, 0, (char *) defn, hash);
}
void