Home | History | Annotate | Line # | Download | only in gdb
dictionary.c revision 1.5
      1  1.1  christos /* Routines for name->symbol lookups in GDB.
      2  1.1  christos 
      3  1.3  christos    Copyright (C) 2003-2015 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    Contributed by David Carlton <carlton (at) bactrian.org> and by Kealia,
      6  1.1  christos    Inc.
      7  1.1  christos 
      8  1.1  christos    This file is part of GDB.
      9  1.1  christos 
     10  1.1  christos    This program is free software; you can redistribute it and/or modify
     11  1.1  christos    it under the terms of the GNU General Public License as published by
     12  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     13  1.1  christos    (at your option) any later version.
     14  1.1  christos 
     15  1.1  christos    This program is distributed in the hope that it will be useful,
     16  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  1.1  christos    GNU General Public License for more details.
     19  1.1  christos 
     20  1.1  christos    You should have received a copy of the GNU General Public License
     21  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     22  1.1  christos 
     23  1.1  christos #include "defs.h"
     24  1.1  christos #include <ctype.h>
     25  1.1  christos #include "gdb_obstack.h"
     26  1.1  christos #include "symtab.h"
     27  1.1  christos #include "buildsym.h"
     28  1.1  christos #include "dictionary.h"
     29  1.1  christos 
     30  1.1  christos /* This file implements dictionaries, which are tables that associate
     31  1.1  christos    symbols to names.  They are represented by an opaque type 'struct
     32  1.1  christos    dictionary'.  That type has various internal implementations, which
     33  1.1  christos    you can choose between depending on what properties you need
     34  1.1  christos    (e.g. fast lookup, order-preserving, expandable).
     35  1.1  christos 
     36  1.1  christos    Each dictionary starts with a 'virtual function table' that
     37  1.1  christos    contains the functions that actually implement the various
     38  1.1  christos    operations that dictionaries provide.  (Note, however, that, for
     39  1.1  christos    the sake of client code, we also provide some functions that can be
     40  1.1  christos    implemented generically in terms of the functions in the vtable.)
     41  1.1  christos 
     42  1.1  christos    To add a new dictionary implementation <impl>, what you should do
     43  1.1  christos    is:
     44  1.1  christos 
     45  1.1  christos    * Add a new element DICT_<IMPL> to dict_type.
     46  1.1  christos 
     47  1.1  christos    * Create a new structure dictionary_<impl>.  If your new
     48  1.1  christos    implementation is a variant of an existing one, make sure that
     49  1.1  christos    their structs have the same initial data members.  Define accessor
     50  1.1  christos    macros for your new data members.
     51  1.1  christos 
     52  1.1  christos    * Implement all the functions in dict_vector as static functions,
     53  1.1  christos    whose name is the same as the corresponding member of dict_vector
     54  1.1  christos    plus _<impl>.  You don't have to do this for those members where
     55  1.1  christos    you can reuse existing generic functions
     56  1.1  christos    (e.g. add_symbol_nonexpandable, free_obstack) or in the case where
     57  1.1  christos    your new implementation is a variant of an existing implementation
     58  1.1  christos    and where the variant doesn't affect the member function in
     59  1.1  christos    question.
     60  1.1  christos 
     61  1.1  christos    * Define a static const struct dict_vector dict_<impl>_vector.
     62  1.1  christos 
     63  1.1  christos    * Define a function dict_create_<impl> to create these
     64  1.1  christos    gizmos.  Add its declaration to dictionary.h.
     65  1.1  christos 
     66  1.1  christos    To add a new operation <op> on all existing implementations, what
     67  1.1  christos    you should do is:
     68  1.1  christos 
     69  1.1  christos    * Add a new member <op> to struct dict_vector.
     70  1.1  christos 
     71  1.1  christos    * If there is useful generic behavior <op>, define a static
     72  1.1  christos    function <op>_something_informative that implements that behavior.
     73  1.1  christos    (E.g. add_symbol_nonexpandable, free_obstack.)
     74  1.1  christos 
     75  1.1  christos    * For every implementation <impl> that should have its own specific
     76  1.1  christos    behavior for <op>, define a static function <op>_<impl>
     77  1.1  christos    implementing it.
     78  1.1  christos 
     79  1.1  christos    * Modify all existing dict_vector_<impl>'s to include the appropriate
     80  1.1  christos    member.
     81  1.1  christos 
     82  1.1  christos    * Define a function dict_<op> that looks up <op> in the dict_vector
     83  1.1  christos    and calls the appropriate function.  Add a declaration for
     84  1.1  christos    dict_<op> to dictionary.h.  */
     85  1.1  christos 
     86  1.1  christos /* An enum representing the various implementations of dictionaries.
     87  1.1  christos    Used only for debugging.  */
     88  1.1  christos 
     89  1.1  christos enum dict_type
     90  1.1  christos   {
     91  1.1  christos     /* Symbols are stored in a fixed-size hash table.  */
     92  1.1  christos     DICT_HASHED,
     93  1.1  christos     /* Symbols are stored in an expandable hash table.  */
     94  1.1  christos     DICT_HASHED_EXPANDABLE,
     95  1.1  christos     /* Symbols are stored in a fixed-size array.  */
     96  1.1  christos     DICT_LINEAR,
     97  1.1  christos     /* Symbols are stored in an expandable array.  */
     98  1.1  christos     DICT_LINEAR_EXPANDABLE
     99  1.1  christos   };
    100  1.1  christos 
    101  1.1  christos /* The virtual function table.  */
    102  1.1  christos 
    103  1.1  christos struct dict_vector
    104  1.1  christos {
    105  1.1  christos   /* The type of the dictionary.  This is only here to make debugging
    106  1.1  christos      a bit easier; it's not actually used.  */
    107  1.1  christos   enum dict_type type;
    108  1.1  christos   /* The function to free a dictionary.  */
    109  1.1  christos   void (*free) (struct dictionary *dict);
    110  1.1  christos   /* Add a symbol to a dictionary, if possible.  */
    111  1.1  christos   void (*add_symbol) (struct dictionary *dict, struct symbol *sym);
    112  1.1  christos   /* Iterator functions.  */
    113  1.1  christos   struct symbol *(*iterator_first) (const struct dictionary *dict,
    114  1.1  christos 				    struct dict_iterator *iterator);
    115  1.1  christos   struct symbol *(*iterator_next) (struct dict_iterator *iterator);
    116  1.1  christos   /* Functions to iterate over symbols with a given name.  */
    117  1.1  christos   struct symbol *(*iter_match_first) (const struct dictionary *dict,
    118  1.1  christos 				      const char *name,
    119  1.1  christos 				      symbol_compare_ftype *equiv,
    120  1.1  christos 				      struct dict_iterator *iterator);
    121  1.1  christos   struct symbol *(*iter_match_next) (const char *name,
    122  1.1  christos 				     symbol_compare_ftype *equiv,
    123  1.1  christos 				     struct dict_iterator *iterator);
    124  1.1  christos   /* A size function, for maint print symtabs.  */
    125  1.1  christos   int (*size) (const struct dictionary *dict);
    126  1.1  christos };
    127  1.1  christos 
    128  1.1  christos /* Now comes the structs used to store the data for different
    129  1.1  christos    implementations.  If two implementations have data in common, put
    130  1.1  christos    the common data at the top of their structs, ordered in the same
    131  1.1  christos    way.  */
    132  1.1  christos 
    133  1.1  christos struct dictionary_hashed
    134  1.1  christos {
    135  1.1  christos   int nbuckets;
    136  1.1  christos   struct symbol **buckets;
    137  1.1  christos };
    138  1.1  christos 
    139  1.1  christos struct dictionary_hashed_expandable
    140  1.1  christos {
    141  1.1  christos   /* How many buckets we currently have.  */
    142  1.1  christos   int nbuckets;
    143  1.1  christos   struct symbol **buckets;
    144  1.1  christos   /* How many syms we currently have; we need this so we will know
    145  1.1  christos      when to add more buckets.  */
    146  1.1  christos   int nsyms;
    147  1.1  christos };
    148  1.1  christos 
    149  1.1  christos struct dictionary_linear
    150  1.1  christos {
    151  1.1  christos   int nsyms;
    152  1.1  christos   struct symbol **syms;
    153  1.1  christos };
    154  1.1  christos 
    155  1.1  christos struct dictionary_linear_expandable
    156  1.1  christos {
    157  1.1  christos   /* How many symbols we currently have.  */
    158  1.1  christos   int nsyms;
    159  1.1  christos   struct symbol **syms;
    160  1.1  christos   /* How many symbols we can store before needing to reallocate.  */
    161  1.1  christos   int capacity;
    162  1.1  christos };
    163  1.1  christos 
    164  1.1  christos /* And now, the star of our show.  */
    165  1.1  christos 
    166  1.1  christos struct dictionary
    167  1.1  christos {
    168  1.1  christos   const struct dict_vector *vector;
    169  1.1  christos   union
    170  1.1  christos   {
    171  1.1  christos     struct dictionary_hashed hashed;
    172  1.1  christos     struct dictionary_hashed_expandable hashed_expandable;
    173  1.1  christos     struct dictionary_linear linear;
    174  1.1  christos     struct dictionary_linear_expandable linear_expandable;
    175  1.1  christos   }
    176  1.1  christos   data;
    177  1.1  christos };
    178  1.1  christos 
    179  1.1  christos /* Accessor macros.  */
    180  1.1  christos 
    181  1.1  christos #define DICT_VECTOR(d)			(d)->vector
    182  1.1  christos 
    183  1.1  christos /* These can be used for DICT_HASHED_EXPANDABLE, too.  */
    184  1.1  christos 
    185  1.1  christos #define DICT_HASHED_NBUCKETS(d)		(d)->data.hashed.nbuckets
    186  1.1  christos #define DICT_HASHED_BUCKETS(d)		(d)->data.hashed.buckets
    187  1.1  christos #define DICT_HASHED_BUCKET(d,i)		DICT_HASHED_BUCKETS (d) [i]
    188  1.1  christos 
    189  1.1  christos #define DICT_HASHED_EXPANDABLE_NSYMS(d)	(d)->data.hashed_expandable.nsyms
    190  1.1  christos 
    191  1.1  christos /* These can be used for DICT_LINEAR_EXPANDABLEs, too.  */
    192  1.1  christos 
    193  1.1  christos #define DICT_LINEAR_NSYMS(d)		(d)->data.linear.nsyms
    194  1.1  christos #define DICT_LINEAR_SYMS(d)		(d)->data.linear.syms
    195  1.1  christos #define DICT_LINEAR_SYM(d,i)		DICT_LINEAR_SYMS (d) [i]
    196  1.1  christos 
    197  1.1  christos #define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \
    198  1.1  christos 		(d)->data.linear_expandable.capacity
    199  1.1  christos 
    200  1.1  christos /* The initial size of a DICT_*_EXPANDABLE dictionary.  */
    201  1.1  christos 
    202  1.1  christos #define DICT_EXPANDABLE_INITIAL_CAPACITY 10
    203  1.1  christos 
    204  1.1  christos /* This calculates the number of buckets we'll use in a hashtable,
    205  1.1  christos    given the number of symbols that it will contain.  */
    206  1.1  christos 
    207  1.1  christos #define DICT_HASHTABLE_SIZE(n)	((n)/5 + 1)
    208  1.1  christos 
    209  1.1  christos /* Accessor macros for dict_iterators; they're here rather than
    210  1.1  christos    dictionary.h because code elsewhere should treat dict_iterators as
    211  1.1  christos    opaque.  */
    212  1.1  christos 
    213  1.1  christos /* The dictionary that the iterator is associated to.  */
    214  1.1  christos #define DICT_ITERATOR_DICT(iter)		(iter)->dict
    215  1.1  christos /* For linear dictionaries, the index of the last symbol returned; for
    216  1.1  christos    hashed dictionaries, the bucket of the last symbol returned.  */
    217  1.1  christos #define DICT_ITERATOR_INDEX(iter)		(iter)->index
    218  1.1  christos /* For hashed dictionaries, this points to the last symbol returned;
    219  1.1  christos    otherwise, this is unused.  */
    220  1.1  christos #define DICT_ITERATOR_CURRENT(iter)		(iter)->current
    221  1.1  christos 
    222  1.1  christos /* Declarations of functions for vectors.  */
    223  1.1  christos 
    224  1.1  christos /* Functions that might work across a range of dictionary types.  */
    225  1.1  christos 
    226  1.1  christos static void add_symbol_nonexpandable (struct dictionary *dict,
    227  1.1  christos 				      struct symbol *sym);
    228  1.1  christos 
    229  1.1  christos static void free_obstack (struct dictionary *dict);
    230  1.1  christos 
    231  1.1  christos /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE
    232  1.1  christos    dictionaries.  */
    233  1.1  christos 
    234  1.1  christos static struct symbol *iterator_first_hashed (const struct dictionary *dict,
    235  1.1  christos 					     struct dict_iterator *iterator);
    236  1.1  christos 
    237  1.1  christos static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
    238  1.1  christos 
    239  1.1  christos static struct symbol *iter_match_first_hashed (const struct dictionary *dict,
    240  1.1  christos 					       const char *name,
    241  1.1  christos 					       symbol_compare_ftype *compare,
    242  1.1  christos 					      struct dict_iterator *iterator);
    243  1.1  christos 
    244  1.1  christos static struct symbol *iter_match_next_hashed (const char *name,
    245  1.1  christos 					      symbol_compare_ftype *compare,
    246  1.1  christos 					      struct dict_iterator *iterator);
    247  1.1  christos 
    248  1.1  christos static unsigned int dict_hash (const char *string);
    249  1.1  christos 
    250  1.1  christos /* Functions only for DICT_HASHED.  */
    251  1.1  christos 
    252  1.1  christos static int size_hashed (const struct dictionary *dict);
    253  1.1  christos 
    254  1.1  christos /* Functions only for DICT_HASHED_EXPANDABLE.  */
    255  1.1  christos 
    256  1.1  christos static void free_hashed_expandable (struct dictionary *dict);
    257  1.1  christos 
    258  1.1  christos static void add_symbol_hashed_expandable (struct dictionary *dict,
    259  1.1  christos 					  struct symbol *sym);
    260  1.1  christos 
    261  1.1  christos static int size_hashed_expandable (const struct dictionary *dict);
    262  1.1  christos 
    263  1.1  christos /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE
    264  1.1  christos    dictionaries.  */
    265  1.1  christos 
    266  1.1  christos static struct symbol *iterator_first_linear (const struct dictionary *dict,
    267  1.1  christos 					     struct dict_iterator *iterator);
    268  1.1  christos 
    269  1.1  christos static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
    270  1.1  christos 
    271  1.1  christos static struct symbol *iter_match_first_linear (const struct dictionary *dict,
    272  1.1  christos 					       const char *name,
    273  1.1  christos 					       symbol_compare_ftype *compare,
    274  1.1  christos 					       struct dict_iterator *iterator);
    275  1.1  christos 
    276  1.1  christos static struct symbol *iter_match_next_linear (const char *name,
    277  1.1  christos 					      symbol_compare_ftype *compare,
    278  1.1  christos 					      struct dict_iterator *iterator);
    279  1.1  christos 
    280  1.1  christos static int size_linear (const struct dictionary *dict);
    281  1.1  christos 
    282  1.1  christos /* Functions only for DICT_LINEAR_EXPANDABLE.  */
    283  1.1  christos 
    284  1.1  christos static void free_linear_expandable (struct dictionary *dict);
    285  1.1  christos 
    286  1.1  christos static void add_symbol_linear_expandable (struct dictionary *dict,
    287  1.1  christos 					  struct symbol *sym);
    288  1.1  christos 
    289  1.1  christos /* Various vectors that we'll actually use.  */
    290  1.1  christos 
    291  1.1  christos static const struct dict_vector dict_hashed_vector =
    292  1.1  christos   {
    293  1.1  christos     DICT_HASHED,			/* type */
    294  1.1  christos     free_obstack,			/* free */
    295  1.1  christos     add_symbol_nonexpandable,		/* add_symbol */
    296  1.1  christos     iterator_first_hashed,		/* iterator_first */
    297  1.1  christos     iterator_next_hashed,		/* iterator_next */
    298  1.1  christos     iter_match_first_hashed,		/* iter_name_first */
    299  1.1  christos     iter_match_next_hashed,		/* iter_name_next */
    300  1.1  christos     size_hashed,			/* size */
    301  1.1  christos   };
    302  1.1  christos 
    303  1.1  christos static const struct dict_vector dict_hashed_expandable_vector =
    304  1.1  christos   {
    305  1.1  christos     DICT_HASHED_EXPANDABLE,		/* type */
    306  1.1  christos     free_hashed_expandable,		/* free */
    307  1.1  christos     add_symbol_hashed_expandable,	/* add_symbol */
    308  1.1  christos     iterator_first_hashed,		/* iterator_first */
    309  1.1  christos     iterator_next_hashed,		/* iterator_next */
    310  1.1  christos     iter_match_first_hashed,		/* iter_name_first */
    311  1.1  christos     iter_match_next_hashed,		/* iter_name_next */
    312  1.1  christos     size_hashed_expandable,		/* size */
    313  1.1  christos   };
    314  1.1  christos 
    315  1.1  christos static const struct dict_vector dict_linear_vector =
    316  1.1  christos   {
    317  1.1  christos     DICT_LINEAR,			/* type */
    318  1.1  christos     free_obstack,			/* free */
    319  1.1  christos     add_symbol_nonexpandable,		/* add_symbol */
    320  1.1  christos     iterator_first_linear,		/* iterator_first */
    321  1.1  christos     iterator_next_linear,		/* iterator_next */
    322  1.1  christos     iter_match_first_linear,		/* iter_name_first */
    323  1.1  christos     iter_match_next_linear,		/* iter_name_next */
    324  1.1  christos     size_linear,			/* size */
    325  1.1  christos   };
    326  1.1  christos 
    327  1.1  christos static const struct dict_vector dict_linear_expandable_vector =
    328  1.1  christos   {
    329  1.1  christos     DICT_LINEAR_EXPANDABLE,		/* type */
    330  1.1  christos     free_linear_expandable,		/* free */
    331  1.1  christos     add_symbol_linear_expandable,	/* add_symbol */
    332  1.1  christos     iterator_first_linear,		/* iterator_first */
    333  1.1  christos     iterator_next_linear,		/* iterator_next */
    334  1.1  christos     iter_match_first_linear,		/* iter_name_first */
    335  1.1  christos     iter_match_next_linear,		/* iter_name_next */
    336  1.1  christos     size_linear,			/* size */
    337  1.1  christos   };
    338  1.1  christos 
    339  1.1  christos /* Declarations of helper functions (i.e. ones that don't go into
    340  1.1  christos    vectors).  */
    341  1.1  christos 
    342  1.1  christos static struct symbol *iterator_hashed_advance (struct dict_iterator *iter);
    343  1.1  christos 
    344  1.1  christos static void insert_symbol_hashed (struct dictionary *dict,
    345  1.1  christos 				  struct symbol *sym);
    346  1.1  christos 
    347  1.1  christos static void expand_hashtable (struct dictionary *dict);
    348  1.1  christos 
    349  1.1  christos /* The creation functions.  */
    350  1.1  christos 
    351  1.1  christos /* Create a dictionary implemented via a fixed-size hashtable.  All
    352  1.1  christos    memory it uses is allocated on OBSTACK; the environment is
    353  1.1  christos    initialized from SYMBOL_LIST.  */
    354  1.1  christos 
    355  1.1  christos struct dictionary *
    356  1.1  christos dict_create_hashed (struct obstack *obstack,
    357  1.1  christos 		    const struct pending *symbol_list)
    358  1.1  christos {
    359  1.1  christos   struct dictionary *retval;
    360  1.1  christos   int nsyms = 0, nbuckets, i;
    361  1.1  christos   struct symbol **buckets;
    362  1.1  christos   const struct pending *list_counter;
    363  1.1  christos 
    364  1.1  christos   retval = obstack_alloc (obstack, sizeof (struct dictionary));
    365  1.1  christos   DICT_VECTOR (retval) = &dict_hashed_vector;
    366  1.1  christos 
    367  1.1  christos   /* Calculate the number of symbols, and allocate space for them.  */
    368  1.1  christos   for (list_counter = symbol_list;
    369  1.1  christos        list_counter != NULL;
    370  1.1  christos        list_counter = list_counter->next)
    371  1.1  christos     {
    372  1.1  christos       nsyms += list_counter->nsyms;
    373  1.1  christos     }
    374  1.1  christos   nbuckets = DICT_HASHTABLE_SIZE (nsyms);
    375  1.1  christos   DICT_HASHED_NBUCKETS (retval) = nbuckets;
    376  1.1  christos   buckets = obstack_alloc (obstack, nbuckets * sizeof (struct symbol *));
    377  1.1  christos   memset (buckets, 0, nbuckets * sizeof (struct symbol *));
    378  1.1  christos   DICT_HASHED_BUCKETS (retval) = buckets;
    379  1.1  christos 
    380  1.1  christos   /* Now fill the buckets.  */
    381  1.1  christos   for (list_counter = symbol_list;
    382  1.1  christos        list_counter != NULL;
    383  1.1  christos        list_counter = list_counter->next)
    384  1.1  christos     {
    385  1.1  christos       for (i = list_counter->nsyms - 1; i >= 0; --i)
    386  1.1  christos 	{
    387  1.1  christos 	  insert_symbol_hashed (retval, list_counter->symbol[i]);
    388  1.1  christos 	}
    389  1.1  christos     }
    390  1.1  christos 
    391  1.1  christos   return retval;
    392  1.1  christos }
    393  1.1  christos 
    394  1.1  christos /* Create a dictionary implemented via a hashtable that grows as
    395  1.1  christos    necessary.  The dictionary is initially empty; to add symbols to
    396  1.1  christos    it, call dict_add_symbol().  Call dict_free() when you're done with
    397  1.1  christos    it.  */
    398  1.1  christos 
    399  1.1  christos extern struct dictionary *
    400  1.1  christos dict_create_hashed_expandable (void)
    401  1.1  christos {
    402  1.1  christos   struct dictionary *retval;
    403  1.1  christos 
    404  1.1  christos   retval = xmalloc (sizeof (struct dictionary));
    405  1.1  christos   DICT_VECTOR (retval) = &dict_hashed_expandable_vector;
    406  1.1  christos   DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY;
    407  1.1  christos   DICT_HASHED_BUCKETS (retval) = xcalloc (DICT_EXPANDABLE_INITIAL_CAPACITY,
    408  1.1  christos 					  sizeof (struct symbol *));
    409  1.1  christos   DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0;
    410  1.1  christos 
    411  1.1  christos   return retval;
    412  1.1  christos }
    413  1.1  christos 
    414  1.1  christos /* Create a dictionary implemented via a fixed-size array.  All memory
    415  1.1  christos    it uses is allocated on OBSTACK; the environment is initialized
    416  1.1  christos    from the SYMBOL_LIST.  The symbols are ordered in the same order
    417  1.1  christos    that they're found in SYMBOL_LIST.  */
    418  1.1  christos 
    419  1.1  christos struct dictionary *
    420  1.1  christos dict_create_linear (struct obstack *obstack,
    421  1.1  christos 		    const struct pending *symbol_list)
    422  1.1  christos {
    423  1.1  christos   struct dictionary *retval;
    424  1.1  christos   int nsyms = 0, i, j;
    425  1.1  christos   struct symbol **syms;
    426  1.1  christos   const struct pending *list_counter;
    427  1.1  christos 
    428  1.1  christos   retval = obstack_alloc (obstack, sizeof (struct dictionary));
    429  1.1  christos   DICT_VECTOR (retval) = &dict_linear_vector;
    430  1.1  christos 
    431  1.1  christos   /* Calculate the number of symbols, and allocate space for them.  */
    432  1.1  christos   for (list_counter = symbol_list;
    433  1.1  christos        list_counter != NULL;
    434  1.1  christos        list_counter = list_counter->next)
    435  1.1  christos     {
    436  1.1  christos       nsyms += list_counter->nsyms;
    437  1.1  christos     }
    438  1.1  christos   DICT_LINEAR_NSYMS (retval) = nsyms;
    439  1.1  christos   syms = obstack_alloc (obstack, nsyms * sizeof (struct symbol *));
    440  1.1  christos   DICT_LINEAR_SYMS (retval) = syms;
    441  1.1  christos 
    442  1.1  christos   /* Now fill in the symbols.  Start filling in from the back, so as
    443  1.1  christos      to preserve the original order of the symbols.  */
    444  1.1  christos   for (list_counter = symbol_list, j = nsyms - 1;
    445  1.1  christos        list_counter != NULL;
    446  1.1  christos        list_counter = list_counter->next)
    447  1.1  christos     {
    448  1.1  christos       for (i = list_counter->nsyms - 1;
    449  1.1  christos 	   i >= 0;
    450  1.1  christos 	   --i, --j)
    451  1.1  christos 	{
    452  1.1  christos 	  syms[j] = list_counter->symbol[i];
    453  1.1  christos 	}
    454  1.1  christos     }
    455  1.1  christos 
    456  1.1  christos   return retval;
    457  1.1  christos }
    458  1.1  christos 
    459  1.1  christos /* Create a dictionary implemented via an array that grows as
    460  1.1  christos    necessary.  The dictionary is initially empty; to add symbols to
    461  1.1  christos    it, call dict_add_symbol().  Call dict_free() when you're done with
    462  1.1  christos    it.  */
    463  1.1  christos 
    464  1.1  christos struct dictionary *
    465  1.1  christos dict_create_linear_expandable (void)
    466  1.1  christos {
    467  1.1  christos   struct dictionary *retval;
    468  1.1  christos 
    469  1.1  christos   retval = xmalloc (sizeof (struct dictionary));
    470  1.1  christos   DICT_VECTOR (retval) = &dict_linear_expandable_vector;
    471  1.1  christos   DICT_LINEAR_NSYMS (retval) = 0;
    472  1.1  christos   DICT_LINEAR_EXPANDABLE_CAPACITY (retval)
    473  1.1  christos     = DICT_EXPANDABLE_INITIAL_CAPACITY;
    474  1.1  christos   DICT_LINEAR_SYMS (retval)
    475  1.1  christos     = xmalloc (DICT_LINEAR_EXPANDABLE_CAPACITY (retval)
    476  1.1  christos 	       * sizeof (struct symbol *));
    477  1.1  christos 
    478  1.1  christos   return retval;
    479  1.1  christos }
    480  1.1  christos 
    481  1.1  christos /* The functions providing the dictionary interface.  */
    482  1.1  christos 
    483  1.1  christos /* Free the memory used by a dictionary that's not on an obstack.  (If
    484  1.1  christos    any.)  */
    485  1.1  christos 
    486  1.1  christos void
    487  1.1  christos dict_free (struct dictionary *dict)
    488  1.1  christos {
    489  1.1  christos   (DICT_VECTOR (dict))->free (dict);
    490  1.1  christos }
    491  1.1  christos 
    492  1.1  christos /* Add SYM to DICT.  DICT had better be expandable.  */
    493  1.1  christos 
    494  1.1  christos void
    495  1.1  christos dict_add_symbol (struct dictionary *dict, struct symbol *sym)
    496  1.1  christos {
    497  1.1  christos   (DICT_VECTOR (dict))->add_symbol (dict, sym);
    498  1.1  christos }
    499  1.1  christos 
    500  1.1  christos /* Utility to add a list of symbols to a dictionary.
    501  1.1  christos    DICT must be an expandable dictionary.  */
    502  1.1  christos 
    503  1.1  christos void
    504  1.1  christos dict_add_pending (struct dictionary *dict, const struct pending *symbol_list)
    505  1.1  christos {
    506  1.1  christos   const struct pending *list;
    507  1.1  christos   int i;
    508  1.1  christos 
    509  1.1  christos   for (list = symbol_list; list != NULL; list = list->next)
    510  1.1  christos     {
    511  1.1  christos       for (i = 0; i < list->nsyms; ++i)
    512  1.1  christos 	dict_add_symbol (dict, list->symbol[i]);
    513  1.1  christos     }
    514  1.1  christos }
    515  1.1  christos 
    516  1.1  christos /* Initialize ITERATOR to point at the first symbol in DICT, and
    517  1.1  christos    return that first symbol, or NULL if DICT is empty.  */
    518  1.1  christos 
    519  1.1  christos struct symbol *
    520  1.1  christos dict_iterator_first (const struct dictionary *dict,
    521  1.1  christos 		     struct dict_iterator *iterator)
    522  1.1  christos {
    523  1.1  christos   return (DICT_VECTOR (dict))->iterator_first (dict, iterator);
    524  1.1  christos }
    525  1.1  christos 
    526  1.1  christos /* Advance ITERATOR, and return the next symbol, or NULL if there are
    527  1.1  christos    no more symbols.  */
    528  1.1  christos 
    529  1.1  christos struct symbol *
    530  1.1  christos dict_iterator_next (struct dict_iterator *iterator)
    531  1.1  christos {
    532  1.1  christos   return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
    533  1.1  christos     ->iterator_next (iterator);
    534  1.1  christos }
    535  1.1  christos 
    536  1.1  christos struct symbol *
    537  1.1  christos dict_iter_name_first (const struct dictionary *dict,
    538  1.1  christos 		      const char *name,
    539  1.1  christos 		      struct dict_iterator *iterator)
    540  1.1  christos {
    541  1.1  christos   return dict_iter_match_first (dict, name, strcmp_iw, iterator);
    542  1.1  christos }
    543  1.1  christos 
    544  1.1  christos struct symbol *
    545  1.1  christos dict_iter_name_next (const char *name, struct dict_iterator *iterator)
    546  1.1  christos {
    547  1.1  christos   return dict_iter_match_next (name, strcmp_iw, iterator);
    548  1.1  christos }
    549  1.1  christos 
    550  1.1  christos struct symbol *
    551  1.1  christos dict_iter_match_first (const struct dictionary *dict,
    552  1.1  christos 		       const char *name, symbol_compare_ftype *compare,
    553  1.1  christos 		       struct dict_iterator *iterator)
    554  1.1  christos {
    555  1.1  christos   return (DICT_VECTOR (dict))->iter_match_first (dict, name,
    556  1.1  christos 						 compare, iterator);
    557  1.1  christos }
    558  1.1  christos 
    559  1.1  christos struct symbol *
    560  1.1  christos dict_iter_match_next (const char *name, symbol_compare_ftype *compare,
    561  1.1  christos 		      struct dict_iterator *iterator)
    562  1.1  christos {
    563  1.1  christos   return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
    564  1.1  christos     ->iter_match_next (name, compare, iterator);
    565  1.1  christos }
    566  1.1  christos 
    567  1.1  christos int
    568  1.1  christos dict_size (const struct dictionary *dict)
    569  1.1  christos {
    570  1.1  christos   return (DICT_VECTOR (dict))->size (dict);
    571  1.1  christos }
    572  1.1  christos 
    573  1.1  christos /* Now come functions (well, one function, currently) that are
    574  1.1  christos    implemented generically by means of the vtable.  Typically, they're
    575  1.1  christos    rarely used.  */
    576  1.1  christos 
    577  1.1  christos /* Test to see if DICT is empty.  */
    578  1.1  christos 
    579  1.1  christos int
    580  1.1  christos dict_empty (struct dictionary *dict)
    581  1.1  christos {
    582  1.1  christos   struct dict_iterator iter;
    583  1.1  christos 
    584  1.1  christos   return (dict_iterator_first (dict, &iter) == NULL);
    585  1.1  christos }
    586  1.1  christos 
    587  1.1  christos 
    588  1.1  christos /* The functions implementing the dictionary interface.  */
    589  1.1  christos 
    590  1.1  christos /* Generic functions, where appropriate.  */
    591  1.1  christos 
    592  1.1  christos static void
    593  1.1  christos free_obstack (struct dictionary *dict)
    594  1.1  christos {
    595  1.1  christos   /* Do nothing!  */
    596  1.1  christos }
    597  1.1  christos 
    598  1.1  christos static void
    599  1.1  christos add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym)
    600  1.1  christos {
    601  1.1  christos   internal_error (__FILE__, __LINE__,
    602  1.1  christos 		  _("dict_add_symbol: non-expandable dictionary"));
    603  1.1  christos }
    604  1.1  christos 
    605  1.1  christos /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE.  */
    606  1.1  christos 
    607  1.1  christos static struct symbol *
    608  1.1  christos iterator_first_hashed (const struct dictionary *dict,
    609  1.1  christos 		       struct dict_iterator *iterator)
    610  1.1  christos {
    611  1.1  christos   DICT_ITERATOR_DICT (iterator) = dict;
    612  1.1  christos   DICT_ITERATOR_INDEX (iterator) = -1;
    613  1.1  christos   return iterator_hashed_advance (iterator);
    614  1.1  christos }
    615  1.1  christos 
    616  1.1  christos static struct symbol *
    617  1.1  christos iterator_next_hashed (struct dict_iterator *iterator)
    618  1.1  christos {
    619  1.1  christos   struct symbol *next;
    620  1.1  christos 
    621  1.1  christos   next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
    622  1.1  christos 
    623  1.1  christos   if (next == NULL)
    624  1.1  christos     return iterator_hashed_advance (iterator);
    625  1.1  christos   else
    626  1.1  christos     {
    627  1.1  christos       DICT_ITERATOR_CURRENT (iterator) = next;
    628  1.1  christos       return next;
    629  1.1  christos     }
    630  1.1  christos }
    631  1.1  christos 
    632  1.1  christos static struct symbol *
    633  1.1  christos iterator_hashed_advance (struct dict_iterator *iterator)
    634  1.1  christos {
    635  1.1  christos   const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
    636  1.1  christos   int nbuckets = DICT_HASHED_NBUCKETS (dict);
    637  1.1  christos   int i;
    638  1.1  christos 
    639  1.1  christos   for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nbuckets; ++i)
    640  1.1  christos     {
    641  1.1  christos       struct symbol *sym = DICT_HASHED_BUCKET (dict, i);
    642  1.1  christos 
    643  1.1  christos       if (sym != NULL)
    644  1.1  christos 	{
    645  1.1  christos 	  DICT_ITERATOR_INDEX (iterator) = i;
    646  1.1  christos 	  DICT_ITERATOR_CURRENT (iterator) = sym;
    647  1.1  christos 	  return sym;
    648  1.1  christos 	}
    649  1.1  christos     }
    650  1.1  christos 
    651  1.1  christos   return NULL;
    652  1.1  christos }
    653  1.1  christos 
    654  1.1  christos static struct symbol *
    655  1.1  christos iter_match_first_hashed (const struct dictionary *dict, const char *name,
    656  1.1  christos 			 symbol_compare_ftype *compare,
    657  1.1  christos 			 struct dict_iterator *iterator)
    658  1.1  christos {
    659  1.1  christos   unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict);
    660  1.1  christos   struct symbol *sym;
    661  1.1  christos 
    662  1.1  christos   DICT_ITERATOR_DICT (iterator) = dict;
    663  1.1  christos 
    664  1.1  christos   /* Loop through the symbols in the given bucket, breaking when SYM
    665  1.1  christos      first matches.  If SYM never matches, it will be set to NULL;
    666  1.1  christos      either way, we have the right return value.  */
    667  1.1  christos 
    668  1.1  christos   for (sym = DICT_HASHED_BUCKET (dict, hash_index);
    669  1.1  christos        sym != NULL;
    670  1.1  christos        sym = sym->hash_next)
    671  1.1  christos     {
    672  1.1  christos       /* Warning: the order of arguments to compare matters!  */
    673  1.1  christos       if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0)
    674  1.1  christos 	{
    675  1.1  christos 	  break;
    676  1.1  christos 	}
    677  1.1  christos 
    678  1.1  christos     }
    679  1.1  christos 
    680  1.1  christos   DICT_ITERATOR_CURRENT (iterator) = sym;
    681  1.1  christos   return sym;
    682  1.1  christos }
    683  1.1  christos 
    684  1.1  christos static struct symbol *
    685  1.1  christos iter_match_next_hashed (const char *name, symbol_compare_ftype *compare,
    686  1.1  christos 			struct dict_iterator *iterator)
    687  1.1  christos {
    688  1.1  christos   struct symbol *next;
    689  1.1  christos 
    690  1.1  christos   for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
    691  1.1  christos        next != NULL;
    692  1.1  christos        next = next->hash_next)
    693  1.1  christos     {
    694  1.1  christos       if (compare (SYMBOL_SEARCH_NAME (next), name) == 0)
    695  1.1  christos 	break;
    696  1.1  christos     }
    697  1.1  christos 
    698  1.1  christos   DICT_ITERATOR_CURRENT (iterator) = next;
    699  1.1  christos 
    700  1.1  christos   return next;
    701  1.1  christos }
    702  1.1  christos 
    703  1.1  christos /* Insert SYM into DICT.  */
    704  1.1  christos 
    705  1.1  christos static void
    706  1.1  christos insert_symbol_hashed (struct dictionary *dict,
    707  1.1  christos 		      struct symbol *sym)
    708  1.1  christos {
    709  1.1  christos   unsigned int hash_index;
    710  1.1  christos   struct symbol **buckets = DICT_HASHED_BUCKETS (dict);
    711  1.1  christos 
    712  1.1  christos   hash_index =
    713  1.1  christos     dict_hash (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict);
    714  1.1  christos   sym->hash_next = buckets[hash_index];
    715  1.1  christos   buckets[hash_index] = sym;
    716  1.1  christos }
    717  1.1  christos 
    718  1.1  christos static int
    719  1.1  christos size_hashed (const struct dictionary *dict)
    720  1.1  christos {
    721  1.1  christos   return DICT_HASHED_NBUCKETS (dict);
    722  1.1  christos }
    723  1.1  christos 
    724  1.1  christos /* Functions only for DICT_HASHED_EXPANDABLE.  */
    725  1.1  christos 
    726  1.1  christos static void
    727  1.1  christos free_hashed_expandable (struct dictionary *dict)
    728  1.1  christos {
    729  1.1  christos   xfree (DICT_HASHED_BUCKETS (dict));
    730  1.1  christos   xfree (dict);
    731  1.1  christos }
    732  1.1  christos 
    733  1.1  christos static void
    734  1.1  christos add_symbol_hashed_expandable (struct dictionary *dict,
    735  1.1  christos 			      struct symbol *sym)
    736  1.1  christos {
    737  1.1  christos   int nsyms = ++DICT_HASHED_EXPANDABLE_NSYMS (dict);
    738  1.1  christos 
    739  1.1  christos   if (DICT_HASHTABLE_SIZE (nsyms) > DICT_HASHED_NBUCKETS (dict))
    740  1.1  christos     expand_hashtable (dict);
    741  1.1  christos 
    742  1.1  christos   insert_symbol_hashed (dict, sym);
    743  1.1  christos   DICT_HASHED_EXPANDABLE_NSYMS (dict) = nsyms;
    744  1.1  christos }
    745  1.1  christos 
    746  1.1  christos static int
    747  1.1  christos size_hashed_expandable (const struct dictionary *dict)
    748  1.1  christos {
    749  1.1  christos   return DICT_HASHED_EXPANDABLE_NSYMS (dict);
    750  1.1  christos }
    751  1.1  christos 
    752  1.1  christos static void
    753  1.1  christos expand_hashtable (struct dictionary *dict)
    754  1.1  christos {
    755  1.1  christos   int old_nbuckets = DICT_HASHED_NBUCKETS (dict);
    756  1.1  christos   struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict);
    757  1.1  christos   int new_nbuckets = 2*old_nbuckets + 1;
    758  1.1  christos   struct symbol **new_buckets = xcalloc (new_nbuckets,
    759  1.1  christos 					 sizeof (struct symbol *));
    760  1.1  christos   int i;
    761  1.1  christos 
    762  1.1  christos   DICT_HASHED_NBUCKETS (dict) = new_nbuckets;
    763  1.1  christos   DICT_HASHED_BUCKETS (dict) = new_buckets;
    764  1.1  christos 
    765  1.1  christos   for (i = 0; i < old_nbuckets; ++i)
    766  1.1  christos     {
    767  1.1  christos       struct symbol *sym, *next_sym;
    768  1.1  christos 
    769  1.1  christos       sym = old_buckets[i];
    770  1.1  christos       if (sym != NULL)
    771  1.1  christos 	{
    772  1.1  christos 	  for (next_sym = sym->hash_next;
    773  1.1  christos 	       next_sym != NULL;
    774  1.1  christos 	       next_sym = sym->hash_next)
    775  1.1  christos 	    {
    776  1.1  christos 	      insert_symbol_hashed (dict, sym);
    777  1.1  christos 	      sym = next_sym;
    778  1.1  christos 	    }
    779  1.1  christos 
    780  1.1  christos 	  insert_symbol_hashed (dict, sym);
    781  1.1  christos 	}
    782  1.1  christos     }
    783  1.1  christos 
    784  1.1  christos   xfree (old_buckets);
    785  1.1  christos }
    786  1.1  christos 
    787  1.1  christos /* Produce an unsigned hash value from STRING0 that is consistent
    788  1.1  christos    with strcmp_iw, strcmp, and, at least on Ada symbols, wild_match.
    789  1.1  christos    That is, two identifiers equivalent according to any of those three
    790  1.1  christos    comparison operators hash to the same value.  */
    791  1.1  christos 
    792  1.1  christos static unsigned int
    793  1.1  christos dict_hash (const char *string0)
    794  1.1  christos {
    795  1.1  christos   /* The Ada-encoded version of a name P1.P2...Pn has either the form
    796  1.1  christos      P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi
    797  1.1  christos      are lower-cased identifiers).  The <suffix> (which can be empty)
    798  1.1  christos      encodes additional information about the denoted entity.  This
    799  1.1  christos      routine hashes such names to msymbol_hash_iw(Pn).  It actually
    800  1.1  christos      does this for a superset of both valid Pi and of <suffix>, but
    801  1.1  christos      in other cases it simply returns msymbol_hash_iw(STRING0).  */
    802  1.1  christos 
    803  1.1  christos   const char *string;
    804  1.1  christos   unsigned int hash;
    805  1.1  christos 
    806  1.1  christos   string = string0;
    807  1.1  christos   if (*string == '_')
    808  1.1  christos     {
    809  1.5  christos       if (startswith (string, "_ada_"))
    810  1.1  christos 	string += 5;
    811  1.1  christos       else
    812  1.1  christos 	return msymbol_hash_iw (string0);
    813  1.1  christos     }
    814  1.1  christos 
    815  1.1  christos   hash = 0;
    816  1.1  christos   while (*string)
    817  1.1  christos     {
    818  1.1  christos       /* Ignore "TKB" suffixes.
    819  1.1  christos 
    820  1.1  christos 	 These are used by Ada for subprograms implementing a task body.
    821  1.1  christos 	 For instance for a task T inside package Pck, the name of the
    822  1.1  christos 	 subprogram implementing T's body is `pck__tTKB'.  We need to
    823  1.1  christos 	 ignore the "TKB" suffix because searches for this task body
    824  1.1  christos 	 subprogram are going to be performed using `pck__t' (the encoded
    825  1.1  christos 	 version of the natural name `pck.t').  */
    826  1.1  christos       if (strcmp (string, "TKB") == 0)
    827  1.1  christos 	return hash;
    828  1.1  christos 
    829  1.1  christos       switch (*string)
    830  1.1  christos 	{
    831  1.1  christos 	case '$':
    832  1.1  christos 	case '.':
    833  1.1  christos 	case 'X':
    834  1.1  christos 	  if (string0 == string)
    835  1.1  christos 	    return msymbol_hash_iw (string0);
    836  1.1  christos 	  else
    837  1.1  christos 	    return hash;
    838  1.1  christos 	case ' ':
    839  1.1  christos 	case '(':
    840  1.1  christos 	  return msymbol_hash_iw (string0);
    841  1.1  christos 	case '_':
    842  1.1  christos 	  if (string[1] == '_' && string != string0)
    843  1.1  christos 	    {
    844  1.1  christos 	      int c = string[2];
    845  1.1  christos 
    846  1.1  christos 	      if ((c < 'a' || c > 'z') && c != 'O')
    847  1.1  christos 		return hash;
    848  1.1  christos 	      hash = 0;
    849  1.1  christos 	      string += 2;
    850  1.1  christos 	      break;
    851  1.1  christos 	    }
    852  1.1  christos 	  /* FALL THROUGH */
    853  1.1  christos 	default:
    854  1.1  christos 	  hash = SYMBOL_HASH_NEXT (hash, *string);
    855  1.1  christos 	  string += 1;
    856  1.1  christos 	  break;
    857  1.1  christos 	}
    858  1.1  christos     }
    859  1.1  christos   return hash;
    860  1.1  christos }
    861  1.1  christos 
    862  1.1  christos /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE.  */
    863  1.1  christos 
    864  1.1  christos static struct symbol *
    865  1.1  christos iterator_first_linear (const struct dictionary *dict,
    866  1.1  christos 		       struct dict_iterator *iterator)
    867  1.1  christos {
    868  1.1  christos   DICT_ITERATOR_DICT (iterator) = dict;
    869  1.1  christos   DICT_ITERATOR_INDEX (iterator) = 0;
    870  1.1  christos   return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL;
    871  1.1  christos }
    872  1.1  christos 
    873  1.1  christos static struct symbol *
    874  1.1  christos iterator_next_linear (struct dict_iterator *iterator)
    875  1.1  christos {
    876  1.1  christos   const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
    877  1.1  christos 
    878  1.1  christos   if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict))
    879  1.1  christos     return NULL;
    880  1.1  christos   else
    881  1.1  christos     return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator));
    882  1.1  christos }
    883  1.1  christos 
    884  1.1  christos static struct symbol *
    885  1.1  christos iter_match_first_linear (const struct dictionary *dict,
    886  1.1  christos 			 const char *name, symbol_compare_ftype *compare,
    887  1.1  christos 			 struct dict_iterator *iterator)
    888  1.1  christos {
    889  1.1  christos   DICT_ITERATOR_DICT (iterator) = dict;
    890  1.1  christos   DICT_ITERATOR_INDEX (iterator) = -1;
    891  1.1  christos 
    892  1.1  christos   return iter_match_next_linear (name, compare, iterator);
    893  1.1  christos }
    894  1.1  christos 
    895  1.1  christos static struct symbol *
    896  1.1  christos iter_match_next_linear (const char *name, symbol_compare_ftype *compare,
    897  1.1  christos 			struct dict_iterator *iterator)
    898  1.1  christos {
    899  1.1  christos   const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
    900  1.1  christos   int i, nsyms = DICT_LINEAR_NSYMS (dict);
    901  1.1  christos   struct symbol *sym, *retval = NULL;
    902  1.1  christos 
    903  1.1  christos   for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i)
    904  1.1  christos     {
    905  1.1  christos       sym = DICT_LINEAR_SYM (dict, i);
    906  1.1  christos       if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0)
    907  1.1  christos 	{
    908  1.1  christos 	  retval = sym;
    909  1.1  christos 	  break;
    910  1.1  christos 	}
    911  1.1  christos     }
    912  1.1  christos 
    913  1.1  christos   DICT_ITERATOR_INDEX (iterator) = i;
    914  1.1  christos 
    915  1.1  christos   return retval;
    916  1.1  christos }
    917  1.1  christos 
    918  1.1  christos static int
    919  1.1  christos size_linear (const struct dictionary *dict)
    920  1.1  christos {
    921  1.1  christos   return DICT_LINEAR_NSYMS (dict);
    922  1.1  christos }
    923  1.1  christos 
    924  1.1  christos /* Functions only for DICT_LINEAR_EXPANDABLE.  */
    925  1.1  christos 
    926  1.1  christos static void
    927  1.1  christos free_linear_expandable (struct dictionary *dict)
    928  1.1  christos {
    929  1.1  christos   xfree (DICT_LINEAR_SYMS (dict));
    930  1.1  christos   xfree (dict);
    931  1.1  christos }
    932  1.1  christos 
    933  1.1  christos 
    934  1.1  christos static void
    935  1.1  christos add_symbol_linear_expandable (struct dictionary *dict,
    936  1.1  christos 			      struct symbol *sym)
    937  1.1  christos {
    938  1.1  christos   int nsyms = ++DICT_LINEAR_NSYMS (dict);
    939  1.1  christos 
    940  1.1  christos   /* Do we have enough room?  If not, grow it.  */
    941  1.1  christos   if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict))
    942  1.1  christos     {
    943  1.1  christos       DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2;
    944  1.1  christos       DICT_LINEAR_SYMS (dict)
    945  1.1  christos 	= xrealloc (DICT_LINEAR_SYMS (dict),
    946  1.1  christos 		    DICT_LINEAR_EXPANDABLE_CAPACITY (dict)
    947  1.1  christos 		    * sizeof (struct symbol *));
    948  1.1  christos     }
    949  1.1  christos 
    950  1.1  christos   DICT_LINEAR_SYM (dict, nsyms - 1) = sym;
    951  1.1  christos }
    952