/* C string table handling.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000-2019 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
This program is free software; you can redistribute it and/or modify
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/cdefs.h>
#include <sys/param.h>
static size_t ps;
-extern void *xmalloc (size_t n) __attribute__ ((__malloc__));
+#include <programs/xmalloc.h>
+
+/* Prototypes for our functions that are used from iconvconfig.c. If
+ you change these, change also iconvconfig.c. */
+/* Create new C string table object in memory. */
+extern struct Strtab *strtabinit (void);
+
+/* Free resources allocated for C string table ST. */
+extern void strtabfree (struct Strtab *st);
+
+/* Add string STR (length LEN is != 0) to C string table ST. */
+extern struct Strent *strtabadd (struct Strtab *st, const char *str,
+ size_t len);
+
+/* Finalize string table ST and store size in *SIZE and return a pointer. */
+extern void *strtabfinalize (struct Strtab *st, size_t *size);
+
+/* Get offset in string table for string associated with SE. */
+extern size_t strtaboffset (struct Strent *se);
struct Strtab *
strtabinit (void)
{
+ struct Strtab *ret;
+
if (ps == 0)
{
ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *);
assert (sizeof (struct memoryblock) < ps);
}
- return (struct Strtab *) calloc (1, sizeof (struct Strtab));
+ ret = (struct Strtab *) calloc (1, sizeof (struct Strtab));
+ if (ret != NULL)
+ {
+ ret->null.len = 1;
+ ret->null.string = "";
+ }
+ return ret;
}
size_t align;
int i;
- /* Compute the string length if the caller doesn't know it. */
- if (len == 0)
- len = strlen (str) + 1;
-
/* Compute the amount of padding needed to make the structure aligned. */
align = ((__alignof__ (struct Strent)
- (((uintptr_t) st->backp)
/* XXX This function should definitely be rewritten to use a balancing
- tree algorith (AVL, red-black trees). For now a simple, correct
+ tree algorithm (AVL, red-black trees). For now a simple, correct
implementation is enough. */
static struct Strent **
searchstring (struct Strent **sep, struct Strent *newstr)
/* Compare the strings. */
cmpres = memcmp ((*sep)->reverse, newstr->reverse,
- MIN ((*sep)->len, newstr->len));
+ MIN ((*sep)->len, newstr->len) - 1);
if (cmpres == 0)
/* We found a matching string. */
return sep;
struct Strent *newstr;
struct Strent **sep;
+ /* Compute the string length if the caller doesn't know it. */
+ if (len == 0)
+ len = strlen (str) + 1;
+
+ /* Make sure all "" strings get offset 0. */
+ if (len == 1)
+ return &st->null;
+
/* Allocate memory for the new string and its associated information. */
newstr = newstring (st, str, len);
/* This is not the same entry. This means we have a prefix match. */
if ((*sep)->len > newstr->len)
{
+ struct Strent *subs;
+
+ for (subs = (*sep)->next; subs; subs = subs->next)
+ if (subs->len == newstr->len)
+ {
+ /* We have an exact match with a substring. Free the memory
+ we allocated. */
+ st->left += st->backp - (char *) newstr;
+ st->backp = (char *) newstr;
+
+ return subs;
+ }
+
/* We have a new substring. This means we don't need the reverse
string of this entry anymore. */
st->backp -= newstr->len;
/* When we get here it means that the string we are about to
add has a common prefix with a string we already have but
it is longer. In this case we have to put it first. */
+ st->total += newstr->len - (*sep)->len;
newstr->next = *sep;
+ newstr->left = (*sep)->left;
+ newstr->right = (*sep)->right;
*sep = newstr;
-
- st->total += newstr->len - (*sep)->len;
}
else
{
copylen = 1;
copystrings (st->root, &endp, ©len);
assert (copylen == st->total + 1);
- assert (endp = retval + st->total + 1);
+ assert (endp == retval + st->total + 1);
*size = copylen;
return retval;