From 64471097ca7598e8238f9e5ed25b3afaa9b10f2c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin (Intel)" Date: Tue, 11 Dec 2018 13:06:14 -0800 Subject: [PATCH] strlist: merge the strtbl and strlist interfaces The currently-unused strtbl was basically a slightly different version of strlist, with the find and linearize capabilities. Merge these two together by augmenting strlist to have the same capabilities. Signed-off-by: H. Peter Anvin (Intel) --- Makefile.in | 1 - Mkfiles/msvc.mak | 1 - Mkfiles/openwcom.mak | 1 - asm/nasm.c | 6 +-- asm/preproc.c | 5 +- include/strlist.h | 30 +++++++++-- nasmlib/strlist.c | 48 +++++++++++++++--- output/outobj.c | 2 +- output/strtbl.c | 117 ------------------------------------------- output/strtbl.h | 57 --------------------- 10 files changed, 72 insertions(+), 196 deletions(-) delete mode 100644 output/strtbl.c delete mode 100644 output/strtbl.h diff --git a/Makefile.in b/Makefile.in index 1ed759d4..82939be3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -129,7 +129,6 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \ macros/macros.$(O) \ \ output/outform.$(O) output/outlib.$(O) output/legacy.$(O) \ - output/strtbl.$(O) \ output/nulldbg.$(O) output/nullout.$(O) \ output/outbin.$(O) output/outaout.$(O) output/outcoff.$(O) \ output/outelf.$(O) \ diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak index 57b8cefc..7ea3b55a 100644 --- a/Mkfiles/msvc.mak +++ b/Mkfiles/msvc.mak @@ -101,7 +101,6 @@ LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) \ macros\macros.$(O) \ \ output\outform.$(O) output\outlib.$(O) output\legacy.$(O) \ - output\strtbl.$(O) \ output\nulldbg.$(O) output\nullout.$(O) \ output\outbin.$(O) output\outaout.$(O) output\outcoff.$(O) \ output\outelf.$(O) \ diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak index 5b704fda..2b0031af 100644 --- a/Mkfiles/openwcom.mak +++ b/Mkfiles/openwcom.mak @@ -90,7 +90,6 @@ LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) & macros\macros.$(O) & & output\outform.$(O) output\outlib.$(O) output\legacy.$(O) & - output\strtbl.$(O) & output\nulldbg.$(O) output\nullout.$(O) & output\outbin.$(O) output\outaout.$(O) output\outcoff.$(O) & output\outelf.$(O) & diff --git a/asm/nasm.c b/asm/nasm.c index fbcf053a..0517697d 100644 --- a/asm/nasm.c +++ b/asm/nasm.c @@ -349,7 +349,7 @@ static void emit_dependencies(struct strlist *list) int linepos, len; bool wmake = (quote_for_make == quote_for_wmake); const char *wrapstr, *nulltarget; - struct strlist_entry *l; + const struct strlist_entry *l; if (!list) return; @@ -368,7 +368,7 @@ static void emit_dependencies(struct strlist *list) } linepos = fprintf(deps, "%s :", depend_target); - list_for_each(l, list->head) { + strlist_for_each(l, list) { char *file = quote_for_make(l->str); len = strlen(file); if (linepos + len > 62 && linepos > 1) { @@ -381,7 +381,7 @@ static void emit_dependencies(struct strlist *list) } fprintf(deps, "\n\n"); - list_for_each(l, list->head) { + strlist_for_each(l, list) { if (depend_emit_phony) { char *file = quote_for_make(l->str); fprintf(deps, "%s :\n%s\n", file, nulltarget); diff --git a/asm/preproc.c b/asm/preproc.c index 15d8bbaf..9d16d539 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -1496,15 +1496,12 @@ enum incopen_mode { static FILE *inc_fopen_search(const char *file, char **slpath, enum incopen_mode omode, enum file_flags fmode) { - const struct strlist_entry *ip = NULL; + const struct strlist_entry *ip = strlist_head(ipath_list); FILE *fp; const char *prefix = ""; char *sp; bool found; - if (ipath_list) - ip = ipath_list->head; - while (1) { sp = nasm_catfile(prefix, file); if (omode == INC_PROBE) { diff --git a/include/strlist.h b/include/strlist.h index 00ac01c6..fc9f38ef 100644 --- a/include/strlist.h +++ b/include/strlist.h @@ -32,7 +32,7 @@ * ----------------------------------------------------------------------- */ /* - * strlist.h - simple linked list of strings + * strlist.h - list of unique, ordered strings */ #ifndef NASM_STRLIST_H @@ -44,18 +44,38 @@ struct strlist_entry { struct strlist_entry *next; + size_t offset; size_t size; char str[1]; }; struct strlist { struct hash_table hash; - struct strlist_entry *head; - struct strlist_entry **tailp; + struct strlist_entry *head, **tailp; + size_t nstr, size; }; +static inline const struct strlist_entry * +strlist_head(const struct strlist *list) +{ + return list ? list->head : NULL; +} +static inline size_t strlist_count(const struct strlist *list) +{ + return list ? list->nstr : 0; +} +static inline size_t strlist_size(const struct strlist *list) +{ + return list ? list->size : 0; +} + struct strlist safe_alloc *strlist_alloc(void); void strlist_free(struct strlist *list); -bool strlist_add(struct strlist *list, const char *str); - +const struct strlist_entry *strlist_add(struct strlist *list, const char *str); +const struct strlist_entry * +strlist_find(const struct strlist *list, const char *str); +void * safe_alloc strlist_linearize(const struct strlist *list, char sep); +void strlist_free(struct strlist *list); +#define strlist_for_each(p,h) list_for_each((p), strlist_head(h)) + #endif /* NASM_STRLIST_H */ diff --git a/nasmlib/strlist.c b/nasmlib/strlist.c index 6dfaa46e..1b6fb726 100644 --- a/nasmlib/strlist.c +++ b/nasmlib/strlist.c @@ -49,31 +49,35 @@ struct strlist *strlist_alloc(void) /* * Append a string to a string list if and only if it isn't - * already there. Return true if it was added. + * already there. If it was added, return the entry pointer. */ -bool strlist_add(struct strlist *list, const char *str) +const struct strlist_entry *strlist_add(struct strlist *list, const char *str) { struct strlist_entry *e; struct hash_insert hi; size_t size; if (!list) - return false; + return NULL; size = strlen(str) + 1; if (hash_findb(&list->hash, str, size, &hi)) - return false; + return NULL; /* Structure already has char[1] as EOS */ - e = nasm_zalloc(sizeof(*e) - 1 + size); + 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; hash_add(&hi, e->str, (void *)e); - return true; + return e; } /* @@ -86,3 +90,35 @@ void strlist_free(struct strlist *list) nasm_free(list); } } + +/* + * Search the string list for an entry. If found, return the entry pointer. + * (This is basically the opposite of strlist_add_string()!) + */ +const struct strlist_entry * +strlist_find(const struct strlist *list, const char *str) +{ + void **hf; + hf = hash_find((struct hash_table *)&list->hash, str, NULL); + return hf ? *hf : NULL; +} + +/* + * Produce a linearized buffer containing the whole list, in order; + * The character "sep" is the separator between strings; this is + * typically either 0 or '\n'. strlist_size() will give the size of + * the returned buffer. + */ +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; +} diff --git a/output/outobj.c b/output/outobj.c index 252ce881..252ba3c8 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -1974,7 +1974,7 @@ static void obj_write_file(void) * Output file dependency information */ if (!obj_nodepend && depend_list) { - list_for_each(depfile, depend_list->head) { + strlist_for_each(depfile, depend_list) { uint32_t ts; ts = obj_file_timestamp(depfile->str); diff --git a/output/strtbl.c b/output/strtbl.c deleted file mode 100644 index 23278f5f..00000000 --- a/output/strtbl.c +++ /dev/null @@ -1,117 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2017 The NASM Authors - All Rights Reserved - * See the file AUTHORS included with the NASM distribution for - * the specific copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following - * conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ----------------------------------------------------------------------- */ - -/* - * Common string table handling - * - * A number of output formats use a "string table"; a container for - * a number of strings which may be reused at will. This implements - * a string table which eliminates duplicates and returns the index - * into the string table when queried. - */ - -#include "compiler.h" - -#include "nasm.h" -#include "nasmlib.h" -#include "error.h" -#include "strtbl.h" - -struct strtbl_entry { - size_t index; - size_t bytes; - char str[1]; -}; - -void strtbl_init(struct nasm_strtbl *tbl) -{ - tbl->size = 0; - strtbl_add(tbl, ""); /* Index 0 is always an empty string */ -} - -void strtbl_free(struct nasm_strtbl *tbl) -{ - hash_free_all(&tbl->hash, false); -} - -size_t strtbl_add(struct nasm_strtbl *tbl, const char *str) -{ - void **sep; - struct strtbl_entry *se; - struct hash_insert hi; - size_t bytes = strlen(str) + 1; - - sep = hash_findb(&tbl->hash, str, bytes, &hi); - if (sep) { - se = *sep; - } else { - nasm_new(se); - se->index = tbl->size; - tbl->size += bytes; - se->bytes = bytes; - memcpy(se->str, str, bytes); - - hash_add(&hi, se->str, se); - } - - return se->index; -} - -size_t strtbl_find(struct nasm_strtbl *tbl, const char *str) -{ - void **sep; - struct strtbl_entry *se; - - sep = hash_find(&tbl->hash, str, NULL); - if (sep) { - se = *sep; - return se->index; - } else { - return STRTBL_NONE; - } -} - -/* This create a linearized buffer containing the actual string table */ -void *strtbl_generate(const struct nasm_strtbl *tbl) -{ - char *buf = nasm_malloc(strtbl_size(tbl)); - struct hash_iterator it; - const struct hash_node *np; - - hash_for_each(&tbl->hash, it, np) { - struct strtbl_entry *se = np->data; - memcpy(buf + se->index, se->str, se->bytes); - } - - return buf; -} diff --git a/output/strtbl.h b/output/strtbl.h deleted file mode 100644 index 12771e4e..00000000 --- a/output/strtbl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2017 The NASM Authors - All Rights Reserved - * See the file AUTHORS included with the NASM distribution for - * the specific copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following - * conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ----------------------------------------------------------------------- */ - -#ifndef NASM_STRTBL_H -#define NASM_STRTBL_H - -#include "compiler.h" -#include "hashtbl.h" - -struct nasm_strtbl { - size_t size; - struct hash_table hash; -}; - -#define STRTBL_NONE ((size_t)-1) - -void strtbl_init(struct nasm_strtbl *tbl); -void strtbl_free(struct nasm_strtbl *tbl); -size_t strtbl_find(struct nasm_strtbl *tbl, const char *str); -size_t strtbl_add(struct nasm_strtbl *tbl, const char *str); -static inline size_t strtbl_size(const struct nasm_strtbl *tbl) -{ - return tbl->size; -} -void * safe_alloc strtbl_generate(const struct nasm_strtbl *tbl); - -#endif /* NASM_STRTBL_H */