Home | History | Annotate | Download | only in src
      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