From: Zack Weinberg <zack@codesourcery.com>
To: binutils@sourceware.org
Subject: gas/hash.c: add interface for looking up non-NUL-terminated strings
Date: Wed, 30 Mar 2005 10:49:00 -0000 [thread overview]
Message-ID: <871x9ynrx6.fsf@codesourcery.com> (raw)
The appended patch adds a new interface to gas/hash.c, hash_find_n,
with exactly the same semantics as hash_find except that the length of
the key is passed in as an argument, and the key is not assumed to be
NUL-terminated. This is more convenient when parsing an assembly
instruction: one does not need to write a NUL into the line buffer so
that hash_find knows where to stop.
Thoughts? The only downside that I see is that the other hash_*
functions may now be marginally slower, since they have to call strlen
up front. I thought this was better than duplicating the entire body
of hash_lookup.
zw
* hash.c (hash_lookup): Delete unnecessary forward declaration.
Add 'len' argument. Do not assume 'key' is NUL-terminated.
All callers changed to match.
(hash_find_n): New interface.
* hash.h: Prototype hash_find_n.
===================================================================
Index: hash.c
--- hash.c (revision 7)
+++ hash.c (revision 8)
@@ -120,19 +120,13 @@
Each time we look up a string, we move it to the start of the list
for its hash code, to take advantage of referential locality. */
-static struct hash_entry *hash_lookup (struct hash_control *,
- const char *,
- struct hash_entry ***,
- unsigned long *);
-
static struct hash_entry *
-hash_lookup (struct hash_control *table, const char *key,
+hash_lookup (struct hash_control *table, const char *key, size_t len,
struct hash_entry ***plist, unsigned long *phash)
{
- register unsigned long hash;
- unsigned int len;
- register const unsigned char *s;
- register unsigned int c;
+ unsigned long hash;
+ size_t n;
+ unsigned int c;
unsigned int index;
struct hash_entry **list;
struct hash_entry *p;
@@ -143,13 +137,11 @@
#endif
hash = 0;
- len = 0;
- s = (const unsigned char *) key;
- while ((c = *s++) != '\0')
+ for (n = 0; n < len; n++)
{
+ c = key[n];
hash += c + (c << 17);
hash ^= hash >> 2;
- ++len;
}
hash += len + (len << 17);
hash ^= hash >> 2;
@@ -176,7 +168,7 @@
++table->string_compares;
#endif
- if (strcmp (p->string, key) == 0)
+ if (p->string[len] == '\0' && strncmp (p->string, key, len) == 0)
{
if (prev != NULL)
{
@@ -207,7 +199,7 @@
struct hash_entry **list;
unsigned long hash;
- p = hash_lookup (table, key, &list, &hash);
+ p = hash_lookup (table, key, strlen (key), &list, &hash);
if (p != NULL)
return "exists";
@@ -237,7 +229,7 @@
struct hash_entry **list;
unsigned long hash;
- p = hash_lookup (table, key, &list, &hash);
+ p = hash_lookup (table, key, strlen (key), &list, &hash);
if (p != NULL)
{
#ifdef HASH_STATISTICS
@@ -274,7 +266,7 @@
struct hash_entry *p;
PTR ret;
- p = hash_lookup (table, key, NULL, NULL);
+ p = hash_lookup (table, key, strlen (key), NULL, NULL);
if (p == NULL)
return NULL;
@@ -297,13 +289,28 @@
{
struct hash_entry *p;
- p = hash_lookup (table, key, NULL, NULL);
+ p = hash_lookup (table, key, strlen (key), NULL, NULL);
if (p == NULL)
return NULL;
return p->data;
}
+/* As hash_find, but KEY is of length LEN and is not guaranteed to be
+ NUL-terminated. */
+
+PTR
+hash_find_n (struct hash_control *table, const char *key, size_t len)
+{
+ struct hash_entry *p;
+
+ p = hash_lookup (table, key, len, NULL, NULL);
+ if (p == NULL)
+ return NULL;
+
+ return p->data;
+}
+
/* Delete an entry from a hash table. This returns the value stored
for that entry, or NULL if there is no such entry. */
@@ -313,7 +320,7 @@
struct hash_entry *p;
struct hash_entry **list;
- p = hash_lookup (table, key, &list, NULL);
+ p = hash_lookup (table, key, strlen (key), &list, NULL);
if (p == NULL)
return NULL;
===================================================================
Index: hash.h
--- hash.h (revision 7)
+++ hash.h (revision 8)
@@ -59,6 +59,11 @@
extern PTR hash_find (struct hash_control *, const char *key);
+/* As hash_find, but KEY is of length LEN and is not guaranteed to be
+ NUL-terminated. */
+
+extern PTR hash_find_n (struct hash_control *, const char *key, size_t len);
+
/* Delete an entry from a hash table. This returns the value stored
for that entry, or NULL if there is no such entry. */
next reply other threads:[~2005-03-29 20:00 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-30 10:49 Zack Weinberg [this message]
2005-04-04 3:21 ` Alan Modra
2005-04-04 5:33 ` Zack Weinberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=871x9ynrx6.fsf@codesourcery.com \
--to=zack@codesourcery.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).