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 37static struct hash_table *uniqstrs_table = NULL; 38 39/*-------------------------------------. 40| Create the uniqstr for S if needed. | 41`-------------------------------------*/ 42 43uniqstr 44uniqstr_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 57uniqstr 58uniqstr_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 77void 78uniqstr_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 93static inline bool 94uniqstr_print (uniqstr ustr) 95{ 96 fprintf (stderr, "%s\n", ustr); 97 return true; 98} 99 100static bool 101uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED) 102{ 103 return uniqstr_print (ustr); 104} 105 106 107/*-----------------------. 108| A uniqstr hash table. | 109`-----------------------*/ 110 111static bool 112hash_compare_uniqstr (void const *m1, void const *m2) 113{ 114 return strcmp (m1, m2) == 0; 115} 116 117static size_t 118hash_uniqstr (void const *m, size_t tablesize) 119{ 120 return hash_string (m, tablesize); 121} 122 123/*----------------------------. 124| Create the uniqstrs table. | 125`----------------------------*/ 126 127void 128uniqstrs_new (void) 129{ 130 uniqstrs_table = hash_initialize (HT_INITIAL_CAPACITY, 131 NULL, 132 hash_uniqstr, 133 hash_compare_uniqstr, 134 free); 135} 136 137 138/*-------------------------------------. 139| Perform a task on all the uniqstrs. | 140`-------------------------------------*/ 141 142static void 143uniqstrs_do (Hash_processor processor, void *processor_data) 144{ 145 hash_do_for_each (uniqstrs_table, processor, processor_data); 146} 147 148 149/*-----------------. 150| Print them all. | 151`-----------------*/ 152 153void 154uniqstrs_print (void) 155{ 156 uniqstrs_do (uniqstr_print_processor, NULL); 157} 158 159 160/*--------------------. 161| Free the uniqstrs. | 162`--------------------*/ 163 164void 165uniqstrs_free (void) 166{ 167 hash_free (uniqstrs_table); 168} 169