1 /* Keep a unique copy of strings. 2 3 Copyright (C) 2002-2005, 2009-2012 Free Software Foundation, Inc. 4 5 This file is part of Bison, the GNU Compiler Compiler. 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include <config.h> 21 #include "system.h" 22 23 #include <error.h> 24 #include <hash.h> 25 #include <quotearg.h> 26 #include <stdarg.h> 27 28 #include "uniqstr.h" 29 30 /*-----------------------. 31 | A uniqstr hash table. | 32 `-----------------------*/ 33 34 /* Initial capacity of uniqstr hash table. */ 35 #define HT_INITIAL_CAPACITY 257 36 37 static struct hash_table *uniqstrs_table = NULL; 38 39 /*-------------------------------------. 40 | Create the uniqstr for S if needed. | 41 `-------------------------------------*/ 42 43 uniqstr 44 uniqstr_new (char const *str) 45 { 46 uniqstr res = hash_lookup (uniqstrs_table, str); 47 if (!res) 48 { 49 /* First insertion in the hash. */ 50 res = xstrdup (str); 51 if (!hash_insert (uniqstrs_table, res)) 52 xalloc_die (); 53 } 54 return res; 55 } 56 57 uniqstr 58 uniqstr_vsprintf (char const *format, ...) 59 { 60 va_list args; 61 size_t length; 62 va_start (args, format); 63 length = vsnprintf (NULL, 0, format, args); 64 va_end (args); 65 66 char res[length + 1]; 67 va_start (args, format); 68 vsprintf (res, format, args); 69 va_end (args); 70 return uniqstr_new (res); 71 } 72 73 /*------------------------------. 74 | Abort if S is not a uniqstr. | 75 `------------------------------*/ 76 77 void 78 uniqstr_assert (char const *str) 79 { 80 if (!hash_lookup (uniqstrs_table, str)) 81 { 82 error (0, 0, 83 "not a uniqstr: %s", quotearg (str)); 84 abort (); 85 } 86 } 87 88 89 /*--------------------. 90 | Print the uniqstr. | 91 `--------------------*/ 92 93 static inline bool 94 uniqstr_print (uniqstr ustr) 95 { 96 fprintf (stderr, "%s\n", ustr); 97 return true; 98 } 99 100 static bool 101 uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED) 102 { 103 return uniqstr_print (ustr); 104 } 105 106 107 /*-----------------------. 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 } 170