gnulib: update
[bison.git] / src / uniqstr.c
blobe7dbd5d371d0646c59aeb33bcac601a5674b75d8
1 /* Keep a unique copy of strings.
3 Copyright (C) 2002-2005, 2009-2015, 2018-2021 Free Software
4 Foundation, Inc.
6 This file is part of Bison, the GNU Compiler Compiler.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include "system.h"
24 #include <attribute.h>
25 #include <error.h>
26 #include <hash.h>
27 #include <quotearg.h>
28 #include <stdarg.h>
30 #include "uniqstr.h"
32 /*-----------------------.
33 | A uniqstr hash table. |
34 `-----------------------*/
36 /* Initial capacity of uniqstr hash table. */
37 #define HT_INITIAL_CAPACITY 257
39 static struct hash_table *uniqstrs_table = NULL;
41 /*-------------------------------------.
42 | Create the uniqstr for S if needed. |
43 `-------------------------------------*/
45 uniqstr
46 uniqstr_new (char const *str)
48 uniqstr res = hash_lookup (uniqstrs_table, str);
49 if (!res)
51 /* First insertion in the hash. */
52 res = xstrdup (str);
53 hash_xinsert (uniqstrs_table, res);
55 return res;
58 uniqstr
59 uniqstr_concat (int nargs, ...)
61 va_list args;
63 va_start (args, nargs);
64 size_t reslen = 0;
65 for (int i = 0; i < nargs; i++)
66 reslen += strlen (va_arg (args, char const *));
67 va_end (args);
69 char *str = xmalloc (reslen + 1);
70 char *p = str;
72 va_start (args, nargs);
73 for (int i = 0; i < nargs; i++)
75 char const *arg = va_arg (args, char const *);
76 size_t arglen = strlen (arg);
77 memcpy (p, arg, arglen);
78 p += arglen;
80 va_end (args);
82 *p = '\0';
83 uniqstr res = hash_xinsert (uniqstrs_table, str);
84 if (res != str)
85 free (str);
86 return res;
89 /*------------------------------.
90 | Abort if S is not a uniqstr. |
91 `------------------------------*/
93 void
94 uniqstr_assert (char const *str)
96 uniqstr s = hash_lookup (uniqstrs_table, str);
97 if (!s || s != str)
99 error (0, 0,
100 "not a uniqstr: %s", quotearg (str));
101 abort ();
106 /*--------------------.
107 | Print the uniqstr. |
108 `--------------------*/
110 static inline bool
111 uniqstr_print (uniqstr ustr)
113 fprintf (stderr, "%s\n", ustr);
114 return true;
117 static bool
118 uniqstr_print_processor (void *ustr, void *null MAYBE_UNUSED)
120 return uniqstr_print (ustr);
124 uniqstr_cmp (uniqstr l, uniqstr r)
126 return (l == r ? 0
127 : !l ? -1
128 : !r ? +1
129 : strcmp (l, r));
133 /*-----------------------.
134 | A uniqstr hash table. |
135 `-----------------------*/
137 static bool
138 hash_compare_uniqstr (void const *m1, void const *m2)
140 return STREQ (m1, m2);
143 static size_t
144 hash_uniqstr (void const *m, size_t tablesize)
146 return hash_string (m, tablesize);
150 /*----------------------------.
151 | Create the uniqstrs table. |
152 `----------------------------*/
154 void
155 uniqstrs_new (void)
157 uniqstrs_table = hash_xinitialize (HT_INITIAL_CAPACITY,
158 NULL,
159 hash_uniqstr,
160 hash_compare_uniqstr,
161 free);
165 /*-------------------------------------.
166 | Perform a task on all the uniqstrs. |
167 `-------------------------------------*/
169 static void
170 uniqstrs_do (Hash_processor processor, void *processor_data)
172 hash_do_for_each (uniqstrs_table, processor, processor_data);
176 /*-----------------.
177 | Print them all. |
178 `-----------------*/
180 void
181 uniqstrs_print (void)
183 uniqstrs_do (uniqstr_print_processor, NULL);
187 /*--------------------.
188 | Free the uniqstrs. |
189 `--------------------*/
191 void
192 uniqstrs_free (void)
194 hash_free (uniqstrs_table);