summaryrefslogtreecommitdiff
path: root/nasmlib
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-13 22:48:14 -0800
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-13 22:48:14 -0800
commit7bb13eac112443cbeb27c3f613759e292274c385 (patch)
treee1c762bc63f3d3594cbf6746bdb836a00d9560bf /nasmlib
parentbe99ebd656a6805fbe4d5de8136b5e5a19cf0b3c (diff)
downloadnasm-7bb13eac112443cbeb27c3f613759e292274c385.tar.gz
strlist: can be unique or not, add printf functions
Make it a selectable option at allocation time if a strlist should contain only unique strings or not. If not, we omit the hash table and strlist_find() will not do anything. Add printf()-style functions to a strlist. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Diffstat (limited to 'nasmlib')
-rw-r--r--nasmlib/asprintf.c8
-rw-r--r--nasmlib/strlist.c94
2 files changed, 82 insertions, 20 deletions
diff --git a/nasmlib/asprintf.c b/nasmlib/asprintf.c
index 3e7b8ef9..be88d491 100644
--- a/nasmlib/asprintf.c
+++ b/nasmlib/asprintf.c
@@ -38,12 +38,16 @@
/*
* nasm_[v]asprintf() are variants of the semi-standard [v]asprintf()
* functions, except that we return the pointer instead of a count.
- * Use %n if you need the count, too.
+ * The size of the string (including the final NUL!) is available
+ * by calling nasm_aprintf_size() afterwards.
*
* nasm_[v]axprintf() are similar, but allocates a user-defined amount
* of storage before the string, and returns a pointer to the
* allocated buffer.
*/
+
+size_t _nasm_aprintf_size;
+
void *nasm_vaxprintf(size_t extra, const char *fmt, va_list ap)
{
char *strp;
@@ -51,7 +55,7 @@ void *nasm_vaxprintf(size_t extra, const char *fmt, va_list ap)
size_t bytes;
va_copy(xap, ap);
- bytes = vsnprintf(NULL, 0, fmt, xap) + 1;
+ _nasm_aprintf_size = bytes = vsnprintf(NULL, 0, fmt, xap) + 1;
va_end(xap);
strp = nasm_malloc(extra+bytes);
vsnprintf(strp+extra, bytes, fmt, ap);
diff --git a/nasmlib/strlist.c b/nasmlib/strlist.c
index 1b6fb726..7518982a 100644
--- a/nasmlib/strlist.c
+++ b/nasmlib/strlist.c
@@ -32,26 +32,47 @@
* ----------------------------------------------------------------------- */
/*
- * strlist.c - list of unique, ordered strings
+ * strlist.c - list of ordered strings, optionally made unique
*/
#include "strlist.h"
/*
- * Create a string list
+ * Create a string list. The list can be uniqizing or not.
*/
-struct strlist *strlist_alloc(void)
+struct strlist *strlist_alloc(bool uniq)
{
struct strlist *list = nasm_zalloc(sizeof(*list));
list->tailp = &list->head;
+ list->uniq = uniq;
return list;
}
/*
- * Append a string to a string list if and only if it isn't
- * already there. If it was added, return the entry pointer.
+ * Append a string to a string list. Return the entry pointer, which
+ * may be a pre-existing entry for a uniqizing list.
*/
-const struct strlist_entry *strlist_add(struct strlist *list, const char *str)
+
+static const struct strlist_entry *
+strlist_add_common(struct strlist *list, struct strlist_entry *e,
+ struct hash_insert *hi)
+{
+ e->offset = list->size;
+ e->next = NULL;
+
+ *list->tailp = e;
+ list->tailp = &e->next;
+ list->nstr++;
+ list->size += e->size;
+
+ if (list->uniq)
+ hash_add(hi, e->str, (void *)e);
+
+ return e;
+}
+
+const struct strlist_entry *
+strlist_add(struct strlist *list, const char *str)
{
struct strlist_entry *e;
struct hash_insert hi;
@@ -61,22 +82,56 @@ const struct strlist_entry *strlist_add(struct strlist *list, const char *str)
return NULL;
size = strlen(str) + 1;
- if (hash_findb(&list->hash, str, size, &hi))
- return NULL;
+ if (list->uniq) {
+ void **dp = hash_findb(&list->hash, str, size, &hi);
+ if (dp)
+ return *dp;
+ }
/* Structure already has char[1] as EOS */
e = nasm_malloc(sizeof(*e) - 1 + size);
e->size = size;
- e->offset = list->size;
- e->next = NULL;
memcpy(e->str, str, size);
- *list->tailp = e;
- list->tailp = &e->next;
- list->nstr++;
- list->size += size;
+ return strlist_add_common(list, e, &hi);
+}
+
+/*
+ * printf() to a string list
+ */
+const struct strlist_entry *
+strlist_vprintf(struct strlist *list, const char *fmt, va_list ap)
+{
+ struct strlist_entry *e;
+ struct hash_insert hi;
+
+ if (!list)
+ return NULL;
+
+ e = nasm_vaxprintf(offsetof(struct strlist_entry, str), fmt, ap);
+ e->size = nasm_aprintf_size();
+
+ if (list->uniq) {
+ void **dp = hash_findb(&list->hash, e->str, e->size, &hi);
+ if (dp) {
+ nasm_free(e);
+ return *dp;
+ }
+ }
+
+ return strlist_add_common(list, e, &hi);
+}
+
+const struct strlist_entry *
+strlist_printf(struct strlist *list, const char *fmt, ...)
+{
+ va_list ap;
+ const struct strlist_entry *e;
+
+ va_start(ap, fmt);
+ e = strlist_vprintf(list, fmt, ap);
+ va_end(ap);
- hash_add(&hi, e->str, (void *)e);
return e;
}
@@ -93,12 +148,15 @@ void strlist_free(struct strlist *list)
/*
* Search the string list for an entry. If found, return the entry pointer.
- * (This is basically the opposite of strlist_add_string()!)
+ * Only possible on a uniqizing list.
*/
const struct strlist_entry *
strlist_find(const struct strlist *list, const char *str)
{
void **hf;
+
+ nasm_assert(list->uniq);
+
hf = hash_find((struct hash_table *)&list->hash, str, NULL);
return hf ? *hf : NULL;
}
@@ -114,11 +172,11 @@ void *strlist_linearize(const struct strlist *list, char sep)
const struct strlist_entry *sl;
char *buf = nasm_malloc(list->size);
char *p = buf;
-
+
strlist_for_each(sl, list) {
p = mempcpy(p, sl->str, sl->size);
p[-1] = sep;
}
-
+
return buf;
}