diff options
-rw-r--r-- | asm/nasm.c | 4 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/nasmlib.h | 9 | ||||
-rw-r--r-- | include/strlist.h | 9 | ||||
-rw-r--r-- | nasmlib/asprintf.c | 8 | ||||
-rw-r--r-- | nasmlib/strlist.c | 94 |
6 files changed, 99 insertions, 27 deletions
@@ -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; } |