1 /* Routines for name->symbol lookups in GDB.
3 Copyright (C) 2003-2017 Free Software Foundation, Inc.
5 Contributed by David Carlton <carlton@bactrian.org> and by Kealia,
8 This file is part of GDB.
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
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
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.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #include "gdb_obstack.h"
28 #include "dictionary.h"
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).
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.)
42 To add a new dictionary implementation <impl>, what you should do
45 * Add a new element DICT_<IMPL> to dict_type.
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.
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
61 * Define a static const struct dict_vector dict_<impl>_vector.
63 * Define a function dict_create_<impl> to create these
64 gizmos. Add its declaration to dictionary.h.
66 To add a new operation <op> on all existing implementations, what
69 * Add a new member <op> to struct dict_vector.
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.)
75 * For every implementation <impl> that should have its own specific
76 behavior for <op>, define a static function <op>_<impl>
79 * Modify all existing dict_vector_<impl>'s to include the appropriate
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. */
86 /* An enum representing the various implementations of dictionaries.
87 Used only for debugging. */
91 /* Symbols are stored in a fixed-size hash table. */
93 /* Symbols are stored in an expandable hash table. */
94 DICT_HASHED_EXPANDABLE
,
95 /* Symbols are stored in a fixed-size array. */
97 /* Symbols are stored in an expandable array. */
98 DICT_LINEAR_EXPANDABLE
101 /* The virtual function table. */
105 /* The type of the dictionary. This is only here to make debugging
106 a bit easier; it's not actually used. */
108 /* The function to free a dictionary. */
109 void (*free
) (struct dictionary
*dict
);
110 /* Add a symbol to a dictionary, if possible. */
111 void (*add_symbol
) (struct dictionary
*dict
, struct symbol
*sym
);
112 /* Iterator functions. */
113 struct symbol
*(*iterator_first
) (const struct dictionary
*dict
,
114 struct dict_iterator
*iterator
);
115 struct symbol
*(*iterator_next
) (struct dict_iterator
*iterator
);
116 /* Functions to iterate over symbols with a given name. */
117 struct symbol
*(*iter_match_first
) (const struct dictionary
*dict
,
119 symbol_compare_ftype
*equiv
,
120 struct dict_iterator
*iterator
);
121 struct symbol
*(*iter_match_next
) (const char *name
,
122 symbol_compare_ftype
*equiv
,
123 struct dict_iterator
*iterator
);
124 /* A size function, for maint print symtabs. */
125 int (*size
) (const struct dictionary
*dict
);
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
133 struct dictionary_hashed
136 struct symbol
**buckets
;
139 struct dictionary_hashed_expandable
141 /* How many buckets we currently have. */
143 struct symbol
**buckets
;
144 /* How many syms we currently have; we need this so we will know
145 when to add more buckets. */
149 struct dictionary_linear
152 struct symbol
**syms
;
155 struct dictionary_linear_expandable
157 /* How many symbols we currently have. */
159 struct symbol
**syms
;
160 /* How many symbols we can store before needing to reallocate. */
164 /* And now, the star of our show. */
168 const struct language_defn
*language
;
169 const struct dict_vector
*vector
;
172 struct dictionary_hashed hashed
;
173 struct dictionary_hashed_expandable hashed_expandable
;
174 struct dictionary_linear linear
;
175 struct dictionary_linear_expandable linear_expandable
;
180 /* Accessor macros. */
182 #define DICT_VECTOR(d) (d)->vector
183 #define DICT_LANGUAGE(d) (d)->language
185 /* These can be used for DICT_HASHED_EXPANDABLE, too. */
187 #define DICT_HASHED_NBUCKETS(d) (d)->data.hashed.nbuckets
188 #define DICT_HASHED_BUCKETS(d) (d)->data.hashed.buckets
189 #define DICT_HASHED_BUCKET(d,i) DICT_HASHED_BUCKETS (d) [i]
191 #define DICT_HASHED_EXPANDABLE_NSYMS(d) (d)->data.hashed_expandable.nsyms
193 /* These can be used for DICT_LINEAR_EXPANDABLEs, too. */
195 #define DICT_LINEAR_NSYMS(d) (d)->data.linear.nsyms
196 #define DICT_LINEAR_SYMS(d) (d)->data.linear.syms
197 #define DICT_LINEAR_SYM(d,i) DICT_LINEAR_SYMS (d) [i]
199 #define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \
200 (d)->data.linear_expandable.capacity
202 /* The initial size of a DICT_*_EXPANDABLE dictionary. */
204 #define DICT_EXPANDABLE_INITIAL_CAPACITY 10
206 /* This calculates the number of buckets we'll use in a hashtable,
207 given the number of symbols that it will contain. */
209 #define DICT_HASHTABLE_SIZE(n) ((n)/5 + 1)
211 /* Accessor macros for dict_iterators; they're here rather than
212 dictionary.h because code elsewhere should treat dict_iterators as
215 /* The dictionary that the iterator is associated to. */
216 #define DICT_ITERATOR_DICT(iter) (iter)->dict
217 /* For linear dictionaries, the index of the last symbol returned; for
218 hashed dictionaries, the bucket of the last symbol returned. */
219 #define DICT_ITERATOR_INDEX(iter) (iter)->index
220 /* For hashed dictionaries, this points to the last symbol returned;
221 otherwise, this is unused. */
222 #define DICT_ITERATOR_CURRENT(iter) (iter)->current
224 /* Declarations of functions for vectors. */
226 /* Functions that might work across a range of dictionary types. */
228 static void add_symbol_nonexpandable (struct dictionary
*dict
,
231 static void free_obstack (struct dictionary
*dict
);
233 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE
236 static struct symbol
*iterator_first_hashed (const struct dictionary
*dict
,
237 struct dict_iterator
*iterator
);
239 static struct symbol
*iterator_next_hashed (struct dict_iterator
*iterator
);
241 static struct symbol
*iter_match_first_hashed (const struct dictionary
*dict
,
243 symbol_compare_ftype
*compare
,
244 struct dict_iterator
*iterator
);
246 static struct symbol
*iter_match_next_hashed (const char *name
,
247 symbol_compare_ftype
*compare
,
248 struct dict_iterator
*iterator
);
250 /* Functions only for DICT_HASHED. */
252 static int size_hashed (const struct dictionary
*dict
);
254 /* Functions only for DICT_HASHED_EXPANDABLE. */
256 static void free_hashed_expandable (struct dictionary
*dict
);
258 static void add_symbol_hashed_expandable (struct dictionary
*dict
,
261 static int size_hashed_expandable (const struct dictionary
*dict
);
263 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE
266 static struct symbol
*iterator_first_linear (const struct dictionary
*dict
,
267 struct dict_iterator
*iterator
);
269 static struct symbol
*iterator_next_linear (struct dict_iterator
*iterator
);
271 static struct symbol
*iter_match_first_linear (const struct dictionary
*dict
,
273 symbol_compare_ftype
*compare
,
274 struct dict_iterator
*iterator
);
276 static struct symbol
*iter_match_next_linear (const char *name
,
277 symbol_compare_ftype
*compare
,
278 struct dict_iterator
*iterator
);
280 static int size_linear (const struct dictionary
*dict
);
282 /* Functions only for DICT_LINEAR_EXPANDABLE. */
284 static void free_linear_expandable (struct dictionary
*dict
);
286 static void add_symbol_linear_expandable (struct dictionary
*dict
,
289 /* Various vectors that we'll actually use. */
291 static const struct dict_vector dict_hashed_vector
=
293 DICT_HASHED
, /* type */
294 free_obstack
, /* free */
295 add_symbol_nonexpandable
, /* add_symbol */
296 iterator_first_hashed
, /* iterator_first */
297 iterator_next_hashed
, /* iterator_next */
298 iter_match_first_hashed
, /* iter_name_first */
299 iter_match_next_hashed
, /* iter_name_next */
300 size_hashed
, /* size */
303 static const struct dict_vector dict_hashed_expandable_vector
=
305 DICT_HASHED_EXPANDABLE
, /* type */
306 free_hashed_expandable
, /* free */
307 add_symbol_hashed_expandable
, /* add_symbol */
308 iterator_first_hashed
, /* iterator_first */
309 iterator_next_hashed
, /* iterator_next */
310 iter_match_first_hashed
, /* iter_name_first */
311 iter_match_next_hashed
, /* iter_name_next */
312 size_hashed_expandable
, /* size */
315 static const struct dict_vector dict_linear_vector
=
317 DICT_LINEAR
, /* type */
318 free_obstack
, /* free */
319 add_symbol_nonexpandable
, /* add_symbol */
320 iterator_first_linear
, /* iterator_first */
321 iterator_next_linear
, /* iterator_next */
322 iter_match_first_linear
, /* iter_name_first */
323 iter_match_next_linear
, /* iter_name_next */
324 size_linear
, /* size */
327 static const struct dict_vector dict_linear_expandable_vector
=
329 DICT_LINEAR_EXPANDABLE
, /* type */
330 free_linear_expandable
, /* free */
331 add_symbol_linear_expandable
, /* add_symbol */
332 iterator_first_linear
, /* iterator_first */
333 iterator_next_linear
, /* iterator_next */
334 iter_match_first_linear
, /* iter_name_first */
335 iter_match_next_linear
, /* iter_name_next */
336 size_linear
, /* size */
339 /* Declarations of helper functions (i.e. ones that don't go into
342 static struct symbol
*iterator_hashed_advance (struct dict_iterator
*iter
);
344 static void insert_symbol_hashed (struct dictionary
*dict
,
347 static void expand_hashtable (struct dictionary
*dict
);
349 /* The creation functions. */
351 /* See dictionary.h. */
354 dict_create_hashed (struct obstack
*obstack
,
355 enum language language
,
356 const struct pending
*symbol_list
)
358 struct dictionary
*retval
;
359 int nsyms
= 0, nbuckets
, i
;
360 struct symbol
**buckets
;
361 const struct pending
*list_counter
;
363 retval
= XOBNEW (obstack
, struct dictionary
);
364 DICT_VECTOR (retval
) = &dict_hashed_vector
;
365 DICT_LANGUAGE (retval
) = language_def (language
);
367 /* Calculate the number of symbols, and allocate space for them. */
368 for (list_counter
= symbol_list
;
369 list_counter
!= NULL
;
370 list_counter
= list_counter
->next
)
372 nsyms
+= list_counter
->nsyms
;
374 nbuckets
= DICT_HASHTABLE_SIZE (nsyms
);
375 DICT_HASHED_NBUCKETS (retval
) = nbuckets
;
376 buckets
= XOBNEWVEC (obstack
, struct symbol
*, nbuckets
);
377 memset (buckets
, 0, nbuckets
* sizeof (struct symbol
*));
378 DICT_HASHED_BUCKETS (retval
) = buckets
;
380 /* Now fill the buckets. */
381 for (list_counter
= symbol_list
;
382 list_counter
!= NULL
;
383 list_counter
= list_counter
->next
)
385 for (i
= list_counter
->nsyms
- 1; i
>= 0; --i
)
387 insert_symbol_hashed (retval
, list_counter
->symbol
[i
]);
394 /* See dictionary.h. */
396 extern struct dictionary
*
397 dict_create_hashed_expandable (enum language language
)
399 struct dictionary
*retval
= XNEW (struct dictionary
);
401 DICT_VECTOR (retval
) = &dict_hashed_expandable_vector
;
402 DICT_LANGUAGE (retval
) = language_def (language
);
403 DICT_HASHED_NBUCKETS (retval
) = DICT_EXPANDABLE_INITIAL_CAPACITY
;
404 DICT_HASHED_BUCKETS (retval
) = XCNEWVEC (struct symbol
*,
405 DICT_EXPANDABLE_INITIAL_CAPACITY
);
406 DICT_HASHED_EXPANDABLE_NSYMS (retval
) = 0;
411 /* See dictionary.h. */
414 dict_create_linear (struct obstack
*obstack
,
415 enum language language
,
416 const struct pending
*symbol_list
)
418 struct dictionary
*retval
;
420 struct symbol
**syms
;
421 const struct pending
*list_counter
;
423 retval
= XOBNEW (obstack
, struct dictionary
);
424 DICT_VECTOR (retval
) = &dict_linear_vector
;
425 DICT_LANGUAGE (retval
) = language_def (language
);
427 /* Calculate the number of symbols, and allocate space for them. */
428 for (list_counter
= symbol_list
;
429 list_counter
!= NULL
;
430 list_counter
= list_counter
->next
)
432 nsyms
+= list_counter
->nsyms
;
434 DICT_LINEAR_NSYMS (retval
) = nsyms
;
435 syms
= XOBNEWVEC (obstack
, struct symbol
*, nsyms
);
436 DICT_LINEAR_SYMS (retval
) = syms
;
438 /* Now fill in the symbols. Start filling in from the back, so as
439 to preserve the original order of the symbols. */
440 for (list_counter
= symbol_list
, j
= nsyms
- 1;
441 list_counter
!= NULL
;
442 list_counter
= list_counter
->next
)
444 for (i
= list_counter
->nsyms
- 1;
448 syms
[j
] = list_counter
->symbol
[i
];
455 /* See dictionary.h. */
458 dict_create_linear_expandable (enum language language
)
460 struct dictionary
*retval
= XNEW (struct dictionary
);
462 DICT_VECTOR (retval
) = &dict_linear_expandable_vector
;
463 DICT_LANGUAGE (retval
) = language_def (language
);
464 DICT_LINEAR_NSYMS (retval
) = 0;
465 DICT_LINEAR_EXPANDABLE_CAPACITY (retval
) = DICT_EXPANDABLE_INITIAL_CAPACITY
;
466 DICT_LINEAR_SYMS (retval
)
467 = XNEWVEC (struct symbol
*, DICT_LINEAR_EXPANDABLE_CAPACITY (retval
));
472 /* The functions providing the dictionary interface. */
474 /* Free the memory used by a dictionary that's not on an obstack. (If
478 dict_free (struct dictionary
*dict
)
480 (DICT_VECTOR (dict
))->free (dict
);
483 /* Add SYM to DICT. DICT had better be expandable. */
486 dict_add_symbol (struct dictionary
*dict
, struct symbol
*sym
)
488 (DICT_VECTOR (dict
))->add_symbol (dict
, sym
);
491 /* Utility to add a list of symbols to a dictionary.
492 DICT must be an expandable dictionary. */
495 dict_add_pending (struct dictionary
*dict
, const struct pending
*symbol_list
)
497 const struct pending
*list
;
500 for (list
= symbol_list
; list
!= NULL
; list
= list
->next
)
502 for (i
= 0; i
< list
->nsyms
; ++i
)
503 dict_add_symbol (dict
, list
->symbol
[i
]);
507 /* Initialize ITERATOR to point at the first symbol in DICT, and
508 return that first symbol, or NULL if DICT is empty. */
511 dict_iterator_first (const struct dictionary
*dict
,
512 struct dict_iterator
*iterator
)
514 return (DICT_VECTOR (dict
))->iterator_first (dict
, iterator
);
517 /* Advance ITERATOR, and return the next symbol, or NULL if there are
521 dict_iterator_next (struct dict_iterator
*iterator
)
523 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator
)))
524 ->iterator_next (iterator
);
528 dict_iter_match_first (const struct dictionary
*dict
,
529 const char *name
, symbol_compare_ftype
*compare
,
530 struct dict_iterator
*iterator
)
532 return (DICT_VECTOR (dict
))->iter_match_first (dict
, name
,
537 dict_iter_match_next (const char *name
, symbol_compare_ftype
*compare
,
538 struct dict_iterator
*iterator
)
540 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator
)))
541 ->iter_match_next (name
, compare
, iterator
);
545 dict_size (const struct dictionary
*dict
)
547 return (DICT_VECTOR (dict
))->size (dict
);
550 /* Now come functions (well, one function, currently) that are
551 implemented generically by means of the vtable. Typically, they're
554 /* Test to see if DICT is empty. */
557 dict_empty (struct dictionary
*dict
)
559 struct dict_iterator iter
;
561 return (dict_iterator_first (dict
, &iter
) == NULL
);
565 /* The functions implementing the dictionary interface. */
567 /* Generic functions, where appropriate. */
570 free_obstack (struct dictionary
*dict
)
576 add_symbol_nonexpandable (struct dictionary
*dict
, struct symbol
*sym
)
578 internal_error (__FILE__
, __LINE__
,
579 _("dict_add_symbol: non-expandable dictionary"));
582 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE. */
584 static struct symbol
*
585 iterator_first_hashed (const struct dictionary
*dict
,
586 struct dict_iterator
*iterator
)
588 DICT_ITERATOR_DICT (iterator
) = dict
;
589 DICT_ITERATOR_INDEX (iterator
) = -1;
590 return iterator_hashed_advance (iterator
);
593 static struct symbol
*
594 iterator_next_hashed (struct dict_iterator
*iterator
)
598 next
= DICT_ITERATOR_CURRENT (iterator
)->hash_next
;
601 return iterator_hashed_advance (iterator
);
604 DICT_ITERATOR_CURRENT (iterator
) = next
;
609 static struct symbol
*
610 iterator_hashed_advance (struct dict_iterator
*iterator
)
612 const struct dictionary
*dict
= DICT_ITERATOR_DICT (iterator
);
613 int nbuckets
= DICT_HASHED_NBUCKETS (dict
);
616 for (i
= DICT_ITERATOR_INDEX (iterator
) + 1; i
< nbuckets
; ++i
)
618 struct symbol
*sym
= DICT_HASHED_BUCKET (dict
, i
);
622 DICT_ITERATOR_INDEX (iterator
) = i
;
623 DICT_ITERATOR_CURRENT (iterator
) = sym
;
631 static struct symbol
*
632 iter_match_first_hashed (const struct dictionary
*dict
, const char *name
,
633 symbol_compare_ftype
*compare
,
634 struct dict_iterator
*iterator
)
636 unsigned int hash_index
637 = (search_name_hash (DICT_LANGUAGE (dict
)->la_language
, name
)
638 % DICT_HASHED_NBUCKETS (dict
));
641 DICT_ITERATOR_DICT (iterator
) = dict
;
643 /* Loop through the symbols in the given bucket, breaking when SYM
644 first matches. If SYM never matches, it will be set to NULL;
645 either way, we have the right return value. */
647 for (sym
= DICT_HASHED_BUCKET (dict
, hash_index
);
649 sym
= sym
->hash_next
)
651 /* Warning: the order of arguments to compare matters! */
652 if (compare (SYMBOL_SEARCH_NAME (sym
), name
) == 0)
659 DICT_ITERATOR_CURRENT (iterator
) = sym
;
663 static struct symbol
*
664 iter_match_next_hashed (const char *name
, symbol_compare_ftype
*compare
,
665 struct dict_iterator
*iterator
)
669 for (next
= DICT_ITERATOR_CURRENT (iterator
)->hash_next
;
671 next
= next
->hash_next
)
673 if (compare (SYMBOL_SEARCH_NAME (next
), name
) == 0)
677 DICT_ITERATOR_CURRENT (iterator
) = next
;
682 /* Insert SYM into DICT. */
685 insert_symbol_hashed (struct dictionary
*dict
,
688 unsigned int hash_index
;
690 struct symbol
**buckets
= DICT_HASHED_BUCKETS (dict
);
692 /* We don't want to insert a symbol into a dictionary of a different
693 language. The two may not use the same hashing algorithm. */
694 gdb_assert (SYMBOL_LANGUAGE (sym
) == DICT_LANGUAGE (dict
)->la_language
);
696 hash
= search_name_hash (SYMBOL_LANGUAGE (sym
), SYMBOL_SEARCH_NAME (sym
));
697 hash_index
= hash
% DICT_HASHED_NBUCKETS (dict
);
698 sym
->hash_next
= buckets
[hash_index
];
699 buckets
[hash_index
] = sym
;
703 size_hashed (const struct dictionary
*dict
)
705 return DICT_HASHED_NBUCKETS (dict
);
708 /* Functions only for DICT_HASHED_EXPANDABLE. */
711 free_hashed_expandable (struct dictionary
*dict
)
713 xfree (DICT_HASHED_BUCKETS (dict
));
718 add_symbol_hashed_expandable (struct dictionary
*dict
,
721 int nsyms
= ++DICT_HASHED_EXPANDABLE_NSYMS (dict
);
723 if (DICT_HASHTABLE_SIZE (nsyms
) > DICT_HASHED_NBUCKETS (dict
))
724 expand_hashtable (dict
);
726 insert_symbol_hashed (dict
, sym
);
727 DICT_HASHED_EXPANDABLE_NSYMS (dict
) = nsyms
;
731 size_hashed_expandable (const struct dictionary
*dict
)
733 return DICT_HASHED_EXPANDABLE_NSYMS (dict
);
737 expand_hashtable (struct dictionary
*dict
)
739 int old_nbuckets
= DICT_HASHED_NBUCKETS (dict
);
740 struct symbol
**old_buckets
= DICT_HASHED_BUCKETS (dict
);
741 int new_nbuckets
= 2 * old_nbuckets
+ 1;
742 struct symbol
**new_buckets
= XCNEWVEC (struct symbol
*, new_nbuckets
);
745 DICT_HASHED_NBUCKETS (dict
) = new_nbuckets
;
746 DICT_HASHED_BUCKETS (dict
) = new_buckets
;
748 for (i
= 0; i
< old_nbuckets
; ++i
)
750 struct symbol
*sym
, *next_sym
;
752 sym
= old_buckets
[i
];
755 for (next_sym
= sym
->hash_next
;
757 next_sym
= sym
->hash_next
)
759 insert_symbol_hashed (dict
, sym
);
763 insert_symbol_hashed (dict
, sym
);
770 /* See dictionary.h. */
773 default_search_name_hash (const char *string0
)
775 /* The Ada-encoded version of a name P1.P2...Pn has either the form
776 P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi
777 are lower-cased identifiers). The <suffix> (which can be empty)
778 encodes additional information about the denoted entity. This
779 routine hashes such names to msymbol_hash_iw(Pn). It actually
780 does this for a superset of both valid Pi and of <suffix>, but
781 in other cases it simply returns msymbol_hash_iw(STRING0). */
789 if (startswith (string
, "_ada_"))
792 return msymbol_hash_iw (string0
);
798 /* Ignore "TKB" suffixes.
800 These are used by Ada for subprograms implementing a task body.
801 For instance for a task T inside package Pck, the name of the
802 subprogram implementing T's body is `pck__tTKB'. We need to
803 ignore the "TKB" suffix because searches for this task body
804 subprogram are going to be performed using `pck__t' (the encoded
805 version of the natural name `pck.t'). */
806 if (strcmp (string
, "TKB") == 0)
814 if (string0
== string
)
815 return msymbol_hash_iw (string0
);
820 return msymbol_hash_iw (string0
);
822 if (string
[1] == '_' && string
!= string0
)
826 if ((c
< 'a' || c
> 'z') && c
!= 'O')
834 hash
= SYMBOL_HASH_NEXT (hash
, *string
);
842 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */
844 static struct symbol
*
845 iterator_first_linear (const struct dictionary
*dict
,
846 struct dict_iterator
*iterator
)
848 DICT_ITERATOR_DICT (iterator
) = dict
;
849 DICT_ITERATOR_INDEX (iterator
) = 0;
850 return DICT_LINEAR_NSYMS (dict
) ? DICT_LINEAR_SYM (dict
, 0) : NULL
;
853 static struct symbol
*
854 iterator_next_linear (struct dict_iterator
*iterator
)
856 const struct dictionary
*dict
= DICT_ITERATOR_DICT (iterator
);
858 if (++DICT_ITERATOR_INDEX (iterator
) >= DICT_LINEAR_NSYMS (dict
))
861 return DICT_LINEAR_SYM (dict
, DICT_ITERATOR_INDEX (iterator
));
864 static struct symbol
*
865 iter_match_first_linear (const struct dictionary
*dict
,
866 const char *name
, symbol_compare_ftype
*compare
,
867 struct dict_iterator
*iterator
)
869 DICT_ITERATOR_DICT (iterator
) = dict
;
870 DICT_ITERATOR_INDEX (iterator
) = -1;
872 return iter_match_next_linear (name
, compare
, iterator
);
875 static struct symbol
*
876 iter_match_next_linear (const char *name
, symbol_compare_ftype
*compare
,
877 struct dict_iterator
*iterator
)
879 const struct dictionary
*dict
= DICT_ITERATOR_DICT (iterator
);
880 int i
, nsyms
= DICT_LINEAR_NSYMS (dict
);
881 struct symbol
*sym
, *retval
= NULL
;
883 for (i
= DICT_ITERATOR_INDEX (iterator
) + 1; i
< nsyms
; ++i
)
885 sym
= DICT_LINEAR_SYM (dict
, i
);
886 if (compare (SYMBOL_SEARCH_NAME (sym
), name
) == 0)
893 DICT_ITERATOR_INDEX (iterator
) = i
;
899 size_linear (const struct dictionary
*dict
)
901 return DICT_LINEAR_NSYMS (dict
);
904 /* Functions only for DICT_LINEAR_EXPANDABLE. */
907 free_linear_expandable (struct dictionary
*dict
)
909 xfree (DICT_LINEAR_SYMS (dict
));
915 add_symbol_linear_expandable (struct dictionary
*dict
,
918 int nsyms
= ++DICT_LINEAR_NSYMS (dict
);
920 /* Do we have enough room? If not, grow it. */
921 if (nsyms
> DICT_LINEAR_EXPANDABLE_CAPACITY (dict
))
923 DICT_LINEAR_EXPANDABLE_CAPACITY (dict
) *= 2;
924 DICT_LINEAR_SYMS (dict
)
925 = XRESIZEVEC (struct symbol
*, DICT_LINEAR_SYMS (dict
),
926 DICT_LINEAR_EXPANDABLE_CAPACITY (dict
));
929 DICT_LINEAR_SYM (dict
, nsyms
- 1) = sym
;