]> git.saurik.com Git - bison.git/blob - src/uniqstr.c
Fix portability problem on OpenBSD 4.7.
[bison.git] / src / uniqstr.c
1 /* Keep a unique copy of strings.
2
3 Copyright (C) 2002, 2003, 2004, 2005, 2009, 2010 Free Software
4 Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
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.
12
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.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include <config.h>
22 #include "system.h"
23
24 #include <error.h>
25 #include <hash.h>
26 #include <quotearg.h>
27 #include <stdarg.h>
28
29 #include "uniqstr.h"
30
31 /*-----------------------.
32 | A uniqstr hash table. |
33 `-----------------------*/
34
35 /* Initial capacity of uniqstr hash table. */
36 #define HT_INITIAL_CAPACITY 257
37
38 static struct hash_table *uniqstrs_table = NULL;
39
40 /*-------------------------------------.
41 | Create the uniqstr for S if needed. |
42 `-------------------------------------*/
43
44 uniqstr
45 uniqstr_new (char const *str)
46 {
47 uniqstr res = hash_lookup (uniqstrs_table, str);
48 if (!res)
49 {
50 /* First insertion in the hash. */
51 res = xstrdup (str);
52 if (!hash_insert (uniqstrs_table, res))
53 xalloc_die ();
54 }
55 return res;
56 }
57
58 uniqstr
59 uniqstr_vsprintf (char const *format, ...)
60 {
61 va_list args;
62 size_t length;
63 va_start (args, format);
64 length = vsnprintf (NULL, 0, format, args);
65 va_end (args);
66
67 char res[length + 1];
68 va_start (args, format);
69 vsprintf (res, format, args);
70 va_end (args);
71 return uniqstr_new (res);
72 }
73
74 /*------------------------------.
75 | Abort if S is not a uniqstr. |
76 `------------------------------*/
77
78 void
79 uniqstr_assert (char const *str)
80 {
81 if (!hash_lookup (uniqstrs_table, str))
82 {
83 error (0, 0,
84 "not a uniqstr: %s", quotearg (str));
85 abort ();
86 }
87 }
88
89
90 /*--------------------.
91 | Print the uniqstr. |
92 `--------------------*/
93
94 static inline bool
95 uniqstr_print (uniqstr ustr)
96 {
97 fprintf (stderr, "%s\n", ustr);
98 return true;
99 }
100
101 static bool
102 uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED)
103 {
104 return uniqstr_print (ustr);
105 }
106
107 \f
108 /*-----------------------.
109 | A uniqstr hash table. |
110 `-----------------------*/
111
112 static bool
113 hash_compare_uniqstr (void const *m1, void const *m2)
114 {
115 return strcmp (m1, m2) == 0;
116 }
117
118 static size_t
119 hash_uniqstr (void const *m, size_t tablesize)
120 {
121 return hash_string (m, tablesize);
122 }
123
124 /*----------------------------.
125 | Create the uniqstrs table. |
126 `----------------------------*/
127
128 void
129 uniqstrs_new (void)
130 {
131 uniqstrs_table = hash_initialize (HT_INITIAL_CAPACITY,
132 NULL,
133 hash_uniqstr,
134 hash_compare_uniqstr,
135 free);
136 }
137
138
139 /*-------------------------------------.
140 | Perform a task on all the uniqstrs. |
141 `-------------------------------------*/
142
143 static void
144 uniqstrs_do (Hash_processor processor, void *processor_data)
145 {
146 hash_do_for_each (uniqstrs_table, processor, processor_data);
147 }
148
149
150 /*-----------------.
151 | Print them all. |
152 `-----------------*/
153
154 void
155 uniqstrs_print (void)
156 {
157 uniqstrs_do (uniqstr_print_processor, NULL);
158 }
159
160
161 /*--------------------.
162 | Free the uniqstrs. |
163 `--------------------*/
164
165 void
166 uniqstrs_free (void)
167 {
168 hash_free (uniqstrs_table);
169 }