summaryrefslogtreecommitdiffstats
path: root/lib/symtab.h
blob: 008b7853d72449c631140a11f94f2f4ffee1e0e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
/* Symbol Table data structure -- header
 * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef _ZEBRA_SYMTAB_H
#define _ZEBRA_SYMTAB_H

#include "misc.h"
#include "vector.h"

/* Maximum number of symbol table bases -- something has gone tragically wrong
 * if we hit this.  Assume can multiply this by 2 and get valid size_t result.
 */
#define SYMBOL_TABLE_BASES_MAX	(1024 * 1024 * 1024)

/* Minimum number of symbol table bases.                        */
#define SYMBOL_TABLE_BASES_MIN	         10
/* Point at which stops doubling the symbol table size (bases)  */
#define SYMBOL_TABLE_BASES_DOUBLE_MAX  2000

/* Structures defined below.    */
struct symbol_table ;
struct symbol ;
struct symbol_ref ;
struct symbol_hash ;

typedef struct symbol_table* symbol_table ;
typedef struct symbol*       symbol ;
typedef struct symbol_ref*   symbol_ref ;
typedef struct symbol_hash*  symbol_hash ;

/* Function types used.		*/
typedef void symbol_hash_function(symbol_hash hash, const void* name) ;
typedef void symbol_call_back_function(symbol sym, void* value) ;
typedef void symbol_destroy_function(symbol sym) ;

/* Symbol Table.
 *
 * Don't fiddle with this directly... see access functions below.
 */

struct symbol_table
{
  void* parent ;			/* to identify the table.          */

  symbol*       bases ;                 /* ref:array of chain bases        */
  unsigned int	base_count ;            /* number of chain bases           */

  unsigned int	entry_count ;		/* number of entries in the table  */
  unsigned int	extend_thresh ;		/* when to extend the hash table   */

  symbol_hash_function* hash_function ;	/* function to hash given "name"   */
					/* NULL => use default	           */
  symbol_call_back_function* value_call_back ;
                                        /* called when symbol value is set */
} ;

/* Symbol Table Entry.
 *
 * Don't fiddle with this directly... see access macros/functions below.
 */

struct symbol
{
  symbol_table table ;    /* so can go from symbol to enclosing table   */
                          /* NULL => orphan symbol, with NULL value.    */

  symbol     next ;       /* assume chains are short and seldom remove  */
                          /* symbols -- so single pointer will do.      */

  void*      value ;      /* see: symbol_get_value(sym) etc.            */

  symbol_ref ref_list ;   /* list of symbol_ref references              */
  unsigned   ref_count ;  /* count of simple references                 */

  uint32_t   hash ;       /* used in lookup and when extending bases.   */

  uint16_t   name_len ;	  /* see: symbol_get_name_len(sym)              */
  char       name[] ;     /* see: symbol_get_name(sym)                  */
} ;

/* Symbol Reference (or "bookmark").
 *
 * Don't fiddle with this directly...  see access macros/functions below
 */

typedef union
{
  void*          p ;
  unsigned long  u ;
    signed long  i ;
} symbol_ref_tag_t ;

struct symbol_ref
{
  symbol sym ;              /* Address of symbol referred to (if any).   */
                            /* (In "bookmark" this points to self.)      */

  symbol_ref next ;         /* fellow references to the symbol ...       */
  symbol_ref prev ;         /* ... ignore if sym is NULL.                */

  void*	 parent ;	    /* see: sym_ref_parent(sym_ref) etc.         */
  symbol_ref_tag_t  tag ;   /* see: sym_ref_tag(sym_ref) etc.            */
} ;

/* Result of a hash function for a symbol name.                       */
struct symbol_hash
{
  uint32_t      hash ;          /* the hash value !			      */
  const void*   name ;          /* symbol name as byte vector		      */
  uint16_t      name_len ;      /* length in chars for comparison purposes    */
  uint16_t      name_copy_len ; /* number of chars to copy to store name.     */
} ;

/* Symbol Walk Iterator		*/
struct symbol_walker
{
  symbol    next ;        /* next symbol to return (if any)         */
  symbol*   base ;        /* next chain base to process (if any)    */
  unsigned  base_count ;  /* number of chain bases left to process  */
} ;

/* Symbol Table Operations.	*/

extern symbol_table symbol_table_init_new(
                                symbol_table table,
                                void* parent,
                                uint bases,
                                uint density,
                                symbol_hash_function* hash_function,
                                symbol_call_back_function* value_call_back) ;
extern void  symbol_table_set_parent(symbol_table table, void* parent) ;
extern void* symbol_table_get_parent(symbol_table table) ;
extern void* symbol_table_ream(symbol_table table, free_keep_b free_structure) ;
extern symbol_table symbol_table_reset(symbol_table table,
                                                   free_keep_b free_structure) ;

extern void symbol_hash_string(struct symbol_hash* p_hash, const char* string) ;
extern void symbol_hash_bytes(struct symbol_hash* p_hash, const void* bytes,
                                                                   size_t len) ;
extern void symbol_table_set_value_call_back(symbol_table table,
				   symbol_call_back_function* value_call_back) ;

extern void symbol_table_free(symbol_table) ;

extern symbol symbol_lookup(symbol_table table, const void* name, add_b add) ;

extern void* symbol_delete(symbol sym) ;

extern void* symbol_set_value(symbol sym, void* new_value) ;
Inline void*
symbol_unset_value(symbol sym)
{
  return symbol_set_value(sym, NULL) ;
} ;

extern void symbol_ref_walk_start(symbol sym, symbol_ref walk) ;
extern symbol_ref symbol_ref_walk_step(symbol_ref walk) ;
extern void symbol_ref_walk_end(symbol_ref walk) ;

extern void symbol_walk_start(symbol_table table, struct symbol_walker* walker);
extern symbol symbol_walk_next(struct symbol_walker* walker) ;

typedef int symbol_select_cmp(const symbol, const void*) ;
typedef int symbol_sort_cmp(const symbol*, const symbol*) ;
extern vector symbol_table_extract(symbol_table table,
	                           symbol_select_cmp* select,
	                           const void* p_value,
			           bool most,
			           symbol_sort_cmp* sort) ;

extern symbol_sort_cmp symbol_mixed_name_cmp ;

/* Access functions -- argument is address of symbol (may be NULL).           */
Inline void*
symbol_get_value(const symbol sym)
{
  return (sym != NULL) ? sym->value : NULL ;
} ;

Inline const void*
symbol_get_name(const symbol sym)
{
  return (sym != NULL) ? sym->name : NULL ;
} ;

Inline unsigned
symbol_get_name_len(const symbol sym)
{
  return (sym != NULL) ? sym->name_len : 0 ;
} ;

Inline struct symbol_table*
symbol_get_table(const symbol sym)
{
  return (sym != NULL) ? sym->table : NULL ;
} ;

Inline symbol
symbol_inc_ref(symbol sym)
{
  ++sym->ref_count ;
  return sym ;
} ;

Private symbol symbol_zero_ref(symbol sym, bool force) ;

Inline symbol
symbol_dec_ref(symbol sym)
{
  if (sym->ref_count <= 1)
    return symbol_zero_ref(sym, false) ;

  --sym->ref_count ;
  return sym ;
} ;

extern symbol_ref symbol_init_ref(symbol_ref ref) ;
extern symbol_ref symbol_set_ref(symbol_ref ref, symbol sym) ;
extern symbol_ref symbol_unset_ref(symbol_ref ref,
                                               free_keep_b free_ref_structure) ;

/* Access functions -- argument is address of symbol_ref.                     */
/* These cope if address of symbol_ref is null, or reference is undefined.    */
Inline void*
sym_ref_symbol(symbol_ref ref)
{
  return (ref != NULL) ? ref->sym : NULL ;
}
Inline void*
sym_ref_value(symbol_ref ref)
{
  return symbol_get_value(sym_ref_symbol(ref)) ;
}
Inline const void*
sym_ref_name(symbol_ref ref)
{
  return symbol_get_name(sym_ref_symbol(ref)) ;
}
Inline uint16_t
sym_ref_name_len(symbol_ref ref)
{
  return symbol_get_name_len(sym_ref_symbol(ref)) ;
}

Inline void*
sym_ref_parent(symbol_ref ref)
{
  return (ref != NULL) ? ref->parent : NULL ;
}
Inline void*
sym_ref_p_tag(symbol_ref ref)
{
  return (ref != NULL) ? ref->tag.p  : NULL ;
}
Inline unsigned long int
sym_ref_u_tag(symbol_ref ref)
{
  return (ref != NULL) ? ref->tag.u : 0 ;
}
Inline signed long int
sym_ref_i_tag(symbol_ref ref)
{
  return (ref != NULL) ? ref->tag.i : 0 ;
}

/* Set properties of reference -- argument is address of symbol_ref, which is */
/* assumed to NOT be NULL.                                                    */
Inline void
sym_ref_set_parent(symbol_ref ref, void* pa)
{
  ref->parent = pa ;
}
Inline void
sym_ref_set_p_tag(symbol_ref ref, void* p_tag)
{
  ref->tag.p  = p_tag ;
}
Inline void
sym_ref_set_u_tag(symbol_ref ref, unsigned long int u_tag)
{
  ref->tag.u  = u_tag ;
}
Inline void
sym_ref_set_i_tag(symbol_ref ref, signed long int i_tag)
{
  ref->tag.i  = i_tag ;
}

#endif /* _ZEBRA_SYMTAB_H */