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) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin (Intel) 2018-12-11 13:06:14 -08:00
parent ebb05a0e5f
commit 64471097ca
10 changed files with 72 additions and 196 deletions

View File

@ -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) \

View File

@ -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) \

View File

@ -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) &

View File

@ -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);

View File

@ -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) {

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */