summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/nasm.c4
-rw-r--r--configure.ac2
-rw-r--r--include/nasmlib.h9
-rw-r--r--include/strlist.h9
-rw-r--r--nasmlib/asprintf.c8
-rw-r--r--nasmlib/strlist.c94
6 files changed, 99 insertions, 27 deletions
diff --git a/asm/nasm.c b/asm/nasm.c
index 6bc55528..3c8b877c 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -456,7 +456,7 @@ int main(int argc, char **argv)
iflag_set_default_cpu(&cpu);
iflag_set_default_cpu(&cmd_cpu);
- include_path = strlist_alloc();
+ include_path = strlist_alloc(true);
pass0 = 0;
want_usage = terminate_after_phase = false;
@@ -533,7 +533,7 @@ int main(int argc, char **argv)
}
}
- depend_list = (operating_mode & OP_DEPEND) ? strlist_alloc() : NULL;
+ depend_list = (operating_mode & OP_DEPEND) ? strlist_alloc(true) : NULL;
if (!depend_target)
depend_target = quote_for_make(outname);
diff --git a/configure.ac b/configure.ac
index a7be0c50..dfa74126 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,8 +118,6 @@ AC_CHECK_FUNCS(strrchrnul)
AC_CHECK_FUNCS(iscntrl)
AC_CHECK_FUNCS(isascii)
-AC_CHECK_FUNCS(vasprintf)
-
AC_CHECK_FUNCS(getuid)
AC_CHECK_FUNCS(getgid)
diff --git a/include/nasmlib.h b/include/nasmlib.h
index 239f60e1..66fbebcf 100644
--- a/include/nasmlib.h
+++ b/include/nasmlib.h
@@ -67,7 +67,8 @@ char * safe_alloc end_with_null nasm_strcatn(const char *one, ...);
/*
* 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
@@ -78,6 +79,12 @@ char * safe_alloc nasm_vasprintf(const char *fmt, va_list ap);
void * safe_alloc printf_func(2, 3) nasm_axprintf(size_t extra, const char *fmt, ...);
void * safe_alloc nasm_vaxprintf(size_t extra, const char *fmt, va_list ap);
+extern size_t _nasm_aprintf_size;
+static inline size_t nasm_aprintf_size(void)
+{
+ return _nasm_aprintf_size;
+}
+
/* Assert the argument is a pointer without evaluating it */
#define nasm_assert_pointer(p) ((void)sizeof(*(p)))
diff --git a/include/strlist.h b/include/strlist.h
index fc9f38ef..b0e2919b 100644
--- a/include/strlist.h
+++ b/include/strlist.h
@@ -53,6 +53,7 @@ struct strlist {
struct hash_table hash;
struct strlist_entry *head, **tailp;
size_t nstr, size;
+ bool uniq;
};
static inline const struct strlist_entry *
@@ -69,9 +70,13 @@ static inline size_t strlist_size(const struct strlist *list)
return list ? list->size : 0;
}
-struct strlist safe_alloc *strlist_alloc(void);
+struct strlist safe_alloc *strlist_alloc(bool uniq);
void strlist_free(struct strlist *list);
-const struct strlist_entry *strlist_add(struct strlist *list, const char *str);
+const struct strlist_entry * never_null strlist_add(struct strlist *list, const char *str);
+const struct strlist_entry * printf_func(2, 3) never_null
+ strlist_printf(struct strlist *list, const char *fmt, ...);
+const struct strlist_entry * never_null
+ strlist_vprintf(struct strlist *list, const char *fmt, va_list ap);
const struct strlist_entry *
strlist_find(const struct strlist *list, const char *str);
void * safe_alloc strlist_linearize(const struct strlist *list, char sep);
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;
}