OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [dictionary.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Routines for name->symbol lookups in GDB.
2
 
3
   Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
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.
19
 
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/>.  */
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
 
91
enum 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.  */
100
    DICT_LINEAR_EXPANDABLE
101
  };
102
 
103
/* The virtual function table.  */
104
 
105
struct 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
 
133
struct dictionary_hashed
134
{
135
  int nbuckets;
136
  struct symbol **buckets;
137
};
138
 
139
struct 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
 
149
struct dictionary_linear
150
{
151
  int nsyms;
152
  struct symbol **syms;
153
};
154
 
155
struct 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
 
166
struct 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
 
226
static void add_symbol_nonexpandable (struct dictionary *dict,
227
                                      struct symbol *sym);
228
 
229
static void free_obstack (struct dictionary *dict);
230
 
231
/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE
232
   dictionaries.  */
233
 
234
static struct symbol *iterator_first_hashed (const struct dictionary *dict,
235
                                             struct dict_iterator *iterator);
236
 
237
static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
238
 
239
static struct symbol *iter_name_first_hashed (const struct dictionary *dict,
240
                                              const char *name,
241
                                              struct dict_iterator *iterator);
242
 
243
static struct symbol *iter_name_next_hashed (const char *name,
244
                                             struct dict_iterator *iterator);
245
 
246
/* Functions only for DICT_HASHED.  */
247
 
248
static int size_hashed (const struct dictionary *dict);
249
 
250
/* Functions only for DICT_HASHED_EXPANDABLE.  */
251
 
252
static void free_hashed_expandable (struct dictionary *dict);
253
 
254
static void add_symbol_hashed_expandable (struct dictionary *dict,
255
                                          struct symbol *sym);
256
 
257
static int size_hashed_expandable (const struct dictionary *dict);
258
 
259
/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE
260
   dictionaries.  */
261
 
262
static struct symbol *iterator_first_linear (const struct dictionary *dict,
263
                                             struct dict_iterator *iterator);
264
 
265
static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
266
 
267
static struct symbol *iter_name_first_linear (const struct dictionary *dict,
268
                                              const char *name,
269
                                              struct dict_iterator *iterator);
270
 
271
static struct symbol *iter_name_next_linear (const char *name,
272
                                             struct dict_iterator *iterator);
273
 
274
static int size_linear (const struct dictionary *dict);
275
 
276
/* Functions only for DICT_LINEAR_EXPANDABLE.  */
277
 
278
static void free_linear_expandable (struct dictionary *dict);
279
 
280
static void add_symbol_linear_expandable (struct dictionary *dict,
281
                                          struct symbol *sym);
282
 
283
/* Various vectors that we'll actually use.  */
284
 
285
static const struct dict_vector dict_hashed_vector =
286
  {
287
    DICT_HASHED,                        /* type */
288
    free_obstack,                       /* free */
289
    add_symbol_nonexpandable,           /* add_symbol */
290
    iterator_first_hashed,              /* iterator_first */
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
 
297
static 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 */
302
    iterator_first_hashed,              /* iterator_first */
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
 
309
static const struct dict_vector dict_linear_vector =
310
  {
311
    DICT_LINEAR,                        /* type */
312
    free_obstack,                       /* free */
313
    add_symbol_nonexpandable,           /* add_symbol */
314
    iterator_first_linear,              /* iterator_first */
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
 
321
static 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 */
326
    iterator_first_linear,              /* iterator_first */
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
 
336
static struct symbol *iterator_hashed_advance (struct dict_iterator *iter);
337
 
338
static void insert_symbol_hashed (struct dictionary *dict,
339
                                  struct symbol *sym);
340
 
341
static 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
 
349
struct dictionary *
350
dict_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
 
393
extern struct dictionary *
394
dict_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
 
413
struct dictionary *
414
dict_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
 
458
struct dictionary *
459
dict_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
 
480
void
481
dict_free (struct dictionary *dict)
482
{
483
  (DICT_VECTOR (dict))->free (dict);
484
}
485
 
486
/* Add SYM to DICT.  DICT had better be expandable.  */
487
 
488
void
489
dict_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
 
497
struct symbol *
498
dict_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
 
507
struct symbol *
508
dict_iterator_next (struct dict_iterator *iterator)
509
{
510
  return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
511
    ->iterator_next (iterator);
512
}
513
 
514
struct symbol *
515
dict_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
 
522
struct symbol *
523
dict_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
 
529
int
530
dict_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
 
541
int
542
dict_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
 
554
static void
555
free_obstack (struct dictionary *dict)
556
{
557
  /* Do nothing!  */
558
}
559
 
560
static void
561
add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym)
562
{
563
  internal_error (__FILE__, __LINE__,
564
                  _("dict_add_symbol: non-expandable dictionary"));
565
}
566
 
567
/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE.  */
568
 
569
static struct symbol *
570
iterator_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
 
578
static struct symbol *
579
iterator_next_hashed (struct dict_iterator *iterator)
580
{
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
 
594
static struct symbol *
595
iterator_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
 
616
static struct symbol *
617
iter_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!  */
636
      if (strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
637
        {
638
          break;
639
        }
640
 
641
    }
642
 
643
  DICT_ITERATOR_CURRENT (iterator) = sym;
644
  return sym;
645
}
646
 
647
static struct symbol *
648
iter_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
    {
656
      if (strcmp_iw (SYMBOL_SEARCH_NAME (next), name) == 0)
657
        break;
658
    }
659
 
660
  DICT_ITERATOR_CURRENT (iterator) = next;
661
 
662
  return next;
663
}
664
 
665
/* Insert SYM into DICT.  */
666
 
667
static void
668
insert_symbol_hashed (struct dictionary *dict,
669
                      struct symbol *sym)
670
{
671
  unsigned int hash_index;
672
  struct symbol **buckets = DICT_HASHED_BUCKETS (dict);
673
 
674
  hash_index = (msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym))
675
                % DICT_HASHED_NBUCKETS (dict));
676
  sym->hash_next = buckets[hash_index];
677
  buckets[hash_index] = sym;
678
}
679
 
680
static int
681
size_hashed (const struct dictionary *dict)
682
{
683
  return DICT_HASHED_NBUCKETS (dict);
684
}
685
 
686
/* Functions only for DICT_HASHED_EXPANDABLE.  */
687
 
688
static void
689
free_hashed_expandable (struct dictionary *dict)
690
{
691
  xfree (DICT_HASHED_BUCKETS (dict));
692
  xfree (dict);
693
}
694
 
695
static void
696
add_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
 
708
static int
709
size_hashed_expandable (const struct dictionary *dict)
710
{
711
  return DICT_HASHED_EXPANDABLE_NSYMS (dict);
712
}
713
 
714
static void
715
expand_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
    {
729
      struct symbol *sym, *next_sym;
730
 
731
      sym = old_buckets[i];
732
      if (sym != NULL)
733
        {
734
          for (next_sym = sym->hash_next;
735
               next_sym != NULL;
736
               next_sym = sym->hash_next)
737
            {
738
              insert_symbol_hashed (dict, sym);
739
              sym = next_sym;
740
            }
741
 
742
          insert_symbol_hashed (dict, sym);
743
        }
744
    }
745
 
746
  xfree (old_buckets);
747
}
748
 
749
/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE.  */
750
 
751
static struct symbol *
752
iterator_first_linear (const struct dictionary *dict,
753
                       struct dict_iterator *iterator)
754
{
755
  DICT_ITERATOR_DICT (iterator) = dict;
756
  DICT_ITERATOR_INDEX (iterator) = 0;
757
  return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL;
758
}
759
 
760
static struct symbol *
761
iterator_next_linear (struct dict_iterator *iterator)
762
{
763
  const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
764
 
765
  if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict))
766
    return NULL;
767
  else
768
    return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator));
769
}
770
 
771
static struct symbol *
772
iter_name_first_linear (const struct dictionary *dict,
773
                        const char *name,
774
                        struct dict_iterator *iterator)
775
{
776
  DICT_ITERATOR_DICT (iterator) = dict;
777
  DICT_ITERATOR_INDEX (iterator) = -1;
778
 
779
  return iter_name_next_linear (name, iterator);
780
}
781
 
782
static struct symbol *
783
iter_name_next_linear (const char *name, struct dict_iterator *iterator)
784
{
785
  const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
786
  int i, nsyms = DICT_LINEAR_NSYMS (dict);
787
  struct symbol *sym, *retval = NULL;
788
 
789
  for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i)
790
    {
791
      sym = DICT_LINEAR_SYM (dict, i);
792
      if (strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
793
        {
794
          retval = sym;
795
          break;
796
        }
797
    }
798
 
799
  DICT_ITERATOR_INDEX (iterator) = i;
800
 
801
  return retval;
802
}
803
 
804
static int
805
size_linear (const struct dictionary *dict)
806
{
807
  return DICT_LINEAR_NSYMS (dict);
808
}
809
 
810
/* Functions only for DICT_LINEAR_EXPANDABLE.  */
811
 
812
static void
813
free_linear_expandable (struct dictionary *dict)
814
{
815
  xfree (DICT_LINEAR_SYMS (dict));
816
  xfree (dict);
817
}
818
 
819
 
820
static void
821
add_symbol_linear_expandable (struct dictionary *dict,
822
                              struct symbol *sym)
823
{
824
  int nsyms = ++DICT_LINEAR_NSYMS (dict);
825
 
826
  /* Do we have enough room?  If not, grow it.  */
827
  if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict))
828
    {
829
      DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2;
830
      DICT_LINEAR_SYMS (dict)
831
        = xrealloc (DICT_LINEAR_SYMS (dict),
832
                    DICT_LINEAR_EXPANDABLE_CAPACITY (dict)
833
                    * sizeof (struct symbol *));
834
    }
835
 
836
  DICT_LINEAR_SYM (dict, nsyms - 1) = sym;
837
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.