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