1 : /****************************************************************************\
2 : Copyright (c) 2002, NVIDIA Corporation.
3 :
4 : NVIDIA Corporation("NVIDIA") supplies this software to you in
5 : consideration of your agreement to the following terms, and your use,
6 : installation, modification or redistribution of this NVIDIA software
7 : constitutes acceptance of these terms. If you do not agree with these
8 : terms, please do not use, install, modify or redistribute this NVIDIA
9 : software.
10 :
11 : In consideration of your agreement to abide by the following terms, and
12 : subject to these terms, NVIDIA grants you a personal, non-exclusive
13 : license, under NVIDIA's copyrights in this original NVIDIA software (the
14 : "NVIDIA Software"), to use, reproduce, modify and redistribute the
15 : NVIDIA Software, with or without modifications, in source and/or binary
16 : forms; provided that if you redistribute the NVIDIA Software, you must
17 : retain the copyright notice of NVIDIA, this notice and the following
18 : text and disclaimers in all such redistributions of the NVIDIA Software.
19 : Neither the name, trademarks, service marks nor logos of NVIDIA
20 : Corporation may be used to endorse or promote products derived from the
21 : NVIDIA Software without specific prior written permission from NVIDIA.
22 : Except as expressly stated in this notice, no other rights or licenses
23 : express or implied, are granted by NVIDIA herein, including but not
24 : limited to any patent rights that may be infringed by your derivative
25 : works or by other works in which the NVIDIA Software may be
26 : incorporated. No hardware is licensed hereunder.
27 :
28 : THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
29 : WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
30 : INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
31 : NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
32 : ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
33 : PRODUCTS.
34 :
35 : IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
36 : INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 : TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
38 : USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
39 : OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
40 : NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
41 : TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
42 : NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 : \****************************************************************************/
44 :
45 : //
46 : // atom.c
47 : //
48 :
49 : #include <stdlib.h>
50 : #include <stdio.h>
51 : #include <string.h>
52 :
53 : #include "compiler/compilerdebug.h"
54 : #include "compiler/preprocessor/slglobals.h"
55 :
56 : #include "../../../../../memory/mozalloc/mozalloc.h"
57 :
58 : #undef malloc
59 : #undef realloc
60 : #undef free
61 :
62 : ///////////////////////////////////////////////////////////////////////////////////////////////
63 : ////////////////////////////////////////// String table: //////////////////////////////////////
64 : ///////////////////////////////////////////////////////////////////////////////////////////////
65 :
66 : static const struct {
67 : int val;
68 : const char *str;
69 : } tokens[] = {
70 : { CPP_AND_OP, "&&" },
71 : { CPP_AND_ASSIGN, "&=" },
72 : { CPP_SUB_ASSIGN, "-=" },
73 : { CPP_MOD_ASSIGN, "%=" },
74 : { CPP_ADD_ASSIGN, "+=" },
75 : { CPP_DIV_ASSIGN, "/=" },
76 : { CPP_MUL_ASSIGN, "*=" },
77 : { CPP_RIGHT_BRACKET, ":>" },
78 : { CPP_EQ_OP, "==" },
79 : { CPP_XOR_OP, "^^" },
80 : { CPP_XOR_ASSIGN, "^=" },
81 : { CPP_FLOATCONSTANT, "<float-const>" },
82 : { CPP_GE_OP, ">=" },
83 : { CPP_RIGHT_OP, ">>" },
84 : { CPP_RIGHT_ASSIGN, ">>=" },
85 : { CPP_IDENTIFIER, "<ident>" },
86 : { CPP_INTCONSTANT, "<int-const>" },
87 : { CPP_LE_OP, "<=" },
88 : { CPP_LEFT_OP, "<<" },
89 : { CPP_LEFT_ASSIGN, "<<=" },
90 : { CPP_LEFT_BRACKET, "<:" },
91 : { CPP_LEFT_BRACE, "<%" },
92 : { CPP_DEC_OP, "--" },
93 : { CPP_RIGHT_BRACE, "%>" },
94 : { CPP_NE_OP, "!=" },
95 : { CPP_OR_OP, "||" },
96 : { CPP_OR_ASSIGN, "|=" },
97 : { CPP_INC_OP, "++" },
98 : { CPP_STRCONSTANT, "<string-const>" },
99 : { CPP_TYPEIDENTIFIER, "<type-ident>" },
100 : };
101 :
102 : ///////////////////////////////////////////////////////////////////////////////////////////////
103 : ////////////////////////////////////////// String table: //////////////////////////////////////
104 : ///////////////////////////////////////////////////////////////////////////////////////////////
105 :
106 : #define INIT_STRING_TABLE_SIZE 16384
107 :
108 : typedef struct StringTable_Rec {
109 : char *strings;
110 : int nextFree;
111 : int size;
112 : } StringTable;
113 :
114 : /*
115 : * InitStringTable() - Initialize the string table.
116 : *
117 : */
118 :
119 0 : static int InitStringTable(StringTable *stable)
120 : {
121 0 : stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
122 0 : if (!stable->strings)
123 0 : return 0;
124 : // Zero-th offset means "empty" so don't use it.
125 0 : stable->nextFree = 1;
126 0 : stable->size = INIT_STRING_TABLE_SIZE;
127 0 : return 1;
128 : } // InitStringTable
129 :
130 : /*
131 : * FreeStringTable() - Free the string table.
132 : *
133 : */
134 :
135 0 : static void FreeStringTable(StringTable *stable)
136 : {
137 0 : if (stable->strings)
138 0 : free(stable->strings);
139 0 : stable->strings = NULL;
140 0 : stable->nextFree = 0;
141 0 : stable->size = 0;
142 0 : } // FreeStringTable
143 :
144 : /*
145 : * HashString() - Hash a string with the base hash function.
146 : *
147 : */
148 :
149 0 : static int HashString(const char *s)
150 : {
151 0 : int hval = 0;
152 :
153 0 : while (*s) {
154 0 : hval = (hval*13507 + *s*197) ^ (hval >> 2);
155 0 : s++;
156 : }
157 0 : return hval & 0x7fffffff;
158 : } // HashString
159 :
160 : /*
161 : * HashString2() - Hash a string with the incrimenting hash function.
162 : *
163 : */
164 :
165 0 : static int HashString2(const char *s)
166 : {
167 0 : int hval = 0;
168 :
169 0 : while (*s) {
170 0 : hval = (hval*729 + *s*37) ^ (hval >> 1);
171 0 : s++;
172 : }
173 0 : return hval;
174 : } // HashString2
175 :
176 : /*
177 : * AddString() - Add a string to a string table. Return it's offset.
178 : *
179 : */
180 :
181 0 : static int AddString(StringTable *stable, const char *s)
182 : {
183 : int len, loc;
184 : char *str;
185 :
186 0 : len = (int) strlen(s);
187 0 : while (stable->nextFree + len + 1 >= stable->size) {
188 0 : assert(stable->size < 1000000);
189 0 : str = (char *) malloc(stable->size*2);
190 0 : memcpy(str, stable->strings, stable->size);
191 0 : free(stable->strings);
192 0 : stable->strings = str;
193 0 : stable->size = stable->size*2;
194 : }
195 0 : loc = stable->nextFree;
196 0 : strcpy(&stable->strings[loc], s);
197 0 : stable->nextFree += len + 1;
198 0 : return loc;
199 : } // AddString
200 :
201 : ///////////////////////////////////////////////////////////////////////////////////////////////
202 : /////////////////////////////////////////// Hash table: ///////////////////////////////////////
203 : ///////////////////////////////////////////////////////////////////////////////////////////////
204 :
205 : #define INIT_HASH_TABLE_SIZE 2047
206 : #define HASH_TABLE_MAX_COLLISIONS 3
207 :
208 : typedef struct HashEntry_Rec {
209 : int index; // String table offset of string representation
210 : int value; // Atom (symbol) value
211 : } HashEntry;
212 :
213 : typedef struct HashTable_Rec {
214 : HashEntry *entry;
215 : int size;
216 : int entries;
217 : int counts[HASH_TABLE_MAX_COLLISIONS + 1];
218 : } HashTable;
219 :
220 : /*
221 : * InitHashTable() - Initialize the hash table.
222 : *
223 : */
224 :
225 0 : static int InitHashTable(HashTable *htable, int fsize)
226 : {
227 : int ii;
228 :
229 0 : htable->entry = (HashEntry *) malloc(sizeof(HashEntry)*fsize);
230 0 : if (!htable->entry)
231 0 : return 0;
232 0 : htable->size = fsize;
233 0 : for (ii = 0; ii < fsize; ii++) {
234 0 : htable->entry[ii].index = 0;
235 0 : htable->entry[ii].value = 0;
236 : }
237 0 : htable->entries = 0;
238 0 : for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++)
239 0 : htable->counts[ii] = 0;
240 0 : return 1;
241 : } // InitHashTable
242 :
243 : /*
244 : * FreeHashTable() - Free the hash table.
245 : *
246 : */
247 :
248 0 : static void FreeHashTable(HashTable *htable)
249 : {
250 0 : if (htable->entry)
251 0 : free(htable->entry);
252 0 : htable->entry = NULL;
253 0 : htable->size = 0;
254 0 : htable->entries = 0;
255 0 : } // FreeHashTable
256 :
257 : /*
258 : * Empty() - See if a hash table entry is empty.
259 : *
260 : */
261 :
262 0 : static int Empty(HashTable *htable, int hashloc)
263 : {
264 0 : assert(hashloc >= 0 && hashloc < htable->size);
265 0 : if (htable->entry[hashloc].index == 0) {
266 0 : return 1;
267 : } else {
268 0 : return 0;
269 : }
270 : } // Empty
271 :
272 : /*
273 : * Match() - See if a hash table entry is matches a string.
274 : *
275 : */
276 :
277 0 : static int Match(HashTable *htable, StringTable *stable, const char *s, int hashloc)
278 : {
279 : int strloc;
280 :
281 0 : strloc = htable->entry[hashloc].index;
282 0 : if (!strcmp(s, &stable->strings[strloc])) {
283 0 : return 1;
284 : } else {
285 0 : return 0;
286 : }
287 : } // Match
288 :
289 : ///////////////////////////////////////////////////////////////////////////////////////////////
290 : /////////////////////////////////////////// Atom table: ///////////////////////////////////////
291 : ///////////////////////////////////////////////////////////////////////////////////////////////
292 :
293 : #define INIT_ATOM_TABLE_SIZE 1024
294 :
295 :
296 : struct AtomTable_Rec {
297 : StringTable stable; // String table.
298 : HashTable htable; // Hashes string to atom number and token value. Multiple strings can
299 : // have the same token value but each unique string is a unique atom.
300 : int *amap; // Maps atom value to offset in string table. Atoms all map to unique
301 : // strings except for some undefined values in the lower, fixed part
302 : // of the atom table that map to "<undefined>". The lowest 256 atoms
303 : // correspond to single character ASCII values except for alphanumeric
304 : // characters and '_', which can be other tokens. Next come the
305 : // language tokens with their atom values equal to the token value.
306 : // Then come predefined atoms, followed by user specified identifiers.
307 : int *arev; // Reversed atom for symbol table use.
308 : int nextFree;
309 : int size;
310 : };
311 :
312 : static AtomTable latable = { { 0 } };
313 : AtomTable *atable = &latable;
314 :
315 : static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
316 :
317 : /*
318 : * GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
319 : *
320 : */
321 :
322 0 : static int GrowAtomTable(AtomTable *atable, int size)
323 : {
324 : int *newmap, *newrev;
325 :
326 0 : if (atable->size < size) {
327 0 : if (atable->amap) {
328 0 : newmap = moz_xrealloc(atable->amap, sizeof(int)*size);
329 0 : newrev = moz_xrealloc(atable->arev, sizeof(int)*size);
330 : } else {
331 0 : newmap = moz_xmalloc(sizeof(int)*size);
332 0 : newrev = moz_xmalloc(sizeof(int)*size);
333 0 : atable->size = 0;
334 : }
335 0 : memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
336 0 : memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
337 0 : atable->amap = newmap;
338 0 : atable->arev = newrev;
339 0 : atable->size = size;
340 : }
341 0 : return 0;
342 : } // GrowAtomTable
343 :
344 : /*
345 : * lReverse() - Reverse the bottom 20 bits of a 32 bit int.
346 : *
347 : */
348 :
349 0 : static int lReverse(int fval)
350 : {
351 0 : unsigned int in = fval;
352 0 : int result = 0, cnt = 0;
353 :
354 0 : while(in) {
355 0 : result <<= 1;
356 0 : result |= in&1;
357 0 : in >>= 1;
358 0 : cnt++;
359 : }
360 :
361 : // Don't use all 31 bits. One million atoms is plenty and sometimes the
362 : // upper bits are used for other things.
363 :
364 0 : if (cnt < 20)
365 0 : result <<= 20 - cnt;
366 0 : return result;
367 : } // lReverse
368 :
369 : /*
370 : * AllocateAtom() - Allocate a new atom. Associated with the "undefined" value of -1.
371 : *
372 : */
373 :
374 0 : static int AllocateAtom(AtomTable *atable)
375 : {
376 0 : if (atable->nextFree >= atable->size)
377 0 : GrowAtomTable(atable, atable->nextFree*2);
378 0 : atable->amap[atable->nextFree] = -1;
379 0 : atable->arev[atable->nextFree] = lReverse(atable->nextFree);
380 0 : atable->nextFree++;
381 0 : return atable->nextFree - 1;
382 : } // AllocateAtom
383 :
384 : /*
385 : * SetAtomValue() - Allocate a new atom associated with "hashindex".
386 : *
387 : */
388 :
389 0 : static void SetAtomValue(AtomTable *atable, int atomnumber, int hashindex)
390 : {
391 0 : atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
392 0 : atable->htable.entry[hashindex].value = atomnumber;
393 0 : } // SetAtomValue
394 :
395 : /*
396 : * FindHashLoc() - Find the hash location for this string. Return -1 it hash table is full.
397 : *
398 : */
399 :
400 0 : static int FindHashLoc(AtomTable *atable, const char *s)
401 : {
402 : int hashloc, hashdelta, count;
403 0 : int FoundEmptySlot = 0;
404 : int collision[HASH_TABLE_MAX_COLLISIONS + 1];
405 :
406 0 : hashloc = HashString(s) % atable->htable.size;
407 0 : if (!Empty(&atable->htable, hashloc)) {
408 0 : if (Match(&atable->htable, &atable->stable, s, hashloc))
409 0 : return hashloc;
410 0 : collision[0] = hashloc;
411 0 : hashdelta = HashString2(s);
412 0 : count = 0;
413 0 : while (count < HASH_TABLE_MAX_COLLISIONS) {
414 0 : hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
415 0 : if (!Empty(&atable->htable, hashloc)) {
416 0 : if (Match(&atable->htable, &atable->stable, s, hashloc)) {
417 0 : return hashloc;
418 : }
419 : } else {
420 0 : FoundEmptySlot = 1;
421 0 : break;
422 : }
423 0 : count++;
424 0 : collision[count] = hashloc;
425 : }
426 :
427 0 : if (!FoundEmptySlot) {
428 0 : if (cpp->options.DumpAtomTable) {
429 : int ii;
430 : char str[200];
431 0 : sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
432 : HASH_TABLE_MAX_COLLISIONS);
433 0 : CPPShInfoLogMsg(str);
434 :
435 0 : sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
436 0 : CPPShInfoLogMsg(str);
437 0 : for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
438 0 : sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
439 0 : ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
440 0 : CPPShInfoLogMsg(str);
441 : }
442 : }
443 0 : return -1;
444 : } else {
445 0 : atable->htable.counts[count]++;
446 : }
447 : }
448 0 : return hashloc;
449 : } // FindHashLoc
450 :
451 : /*
452 : * IncreaseHashTableSize()
453 : *
454 : */
455 :
456 0 : static int IncreaseHashTableSize(AtomTable *atable)
457 : {
458 : int ii, strloc, oldhashloc, value, size;
459 : AtomTable oldtable;
460 : char *s;
461 :
462 : // Save the old atom table and create a new one:
463 :
464 0 : oldtable = *atable;
465 0 : size = oldtable.htable.size*2 + 1;
466 0 : if (!InitAtomTable(atable, size))
467 0 : return 0;
468 :
469 : // Add all the existing values to the new atom table preserving their atom values:
470 :
471 0 : for (ii = atable->nextFree; ii < oldtable.nextFree; ii++) {
472 0 : strloc = oldtable.amap[ii];
473 0 : s = &oldtable.stable.strings[strloc];
474 0 : oldhashloc = FindHashLoc(&oldtable, s);
475 0 : assert(oldhashloc >= 0);
476 0 : value = oldtable.htable.entry[oldhashloc].value;
477 0 : AddAtomFixed(atable, s, value);
478 : }
479 0 : FreeAtomTable(&oldtable);
480 0 : return 1;
481 : } // IncreaseHashTableSize
482 :
483 : /*
484 : * LookUpAddStringHash() - Lookup a string in the hash table. If it's not there, add it and
485 : * initialize the atom value in the hash table to 0. Return the hash table index.
486 : */
487 :
488 0 : static int LookUpAddStringHash(AtomTable *atable, const char *s)
489 : {
490 : int hashloc, strloc;
491 :
492 : while(1) {
493 0 : hashloc = FindHashLoc(atable, s);
494 0 : if (hashloc >= 0)
495 : break;
496 0 : IncreaseHashTableSize(atable);
497 0 : }
498 :
499 0 : if (Empty(&atable->htable, hashloc)) {
500 0 : atable->htable.entries++;
501 0 : strloc = AddString(&atable->stable, s);
502 0 : atable->htable.entry[hashloc].index = strloc;
503 0 : atable->htable.entry[hashloc].value = 0;
504 : }
505 0 : return hashloc;
506 : } // LookUpAddStringHash
507 :
508 : /*
509 : * LookUpAddString() - Lookup a string in the hash table. If it's not there, add it and
510 : * initialize the atom value in the hash table to the next atom number.
511 : * Return the atom value of string.
512 : */
513 :
514 0 : int LookUpAddString(AtomTable *atable, const char *s)
515 : {
516 : int hashindex, atom;
517 :
518 0 : hashindex = LookUpAddStringHash(atable, s);
519 0 : atom = atable->htable.entry[hashindex].value;
520 0 : if (atom == 0) {
521 0 : atom = AllocateAtom(atable);
522 0 : SetAtomValue(atable, atom, hashindex);
523 : }
524 0 : return atom;
525 : } // LookUpAddString
526 :
527 : /*
528 : * GetAtomString()
529 : *
530 : */
531 :
532 0 : const char *GetAtomString(AtomTable *atable, int atom)
533 : {
534 : int soffset;
535 :
536 0 : if (atom > 0 && atom < atable->nextFree) {
537 0 : soffset = atable->amap[atom];
538 0 : if (soffset > 0 && soffset < atable->stable.nextFree) {
539 0 : return &atable->stable.strings[soffset];
540 : } else {
541 0 : return "<internal error: bad soffset>";
542 : }
543 : } else {
544 0 : if (atom == 0) {
545 0 : return "<null atom>";
546 : } else {
547 0 : if (atom == EOF) {
548 0 : return "<EOF>";
549 : } else {
550 0 : return "<invalid atom>";
551 : }
552 : }
553 : }
554 : } // GetAtomString
555 :
556 : /*
557 : * GetReversedAtom()
558 : *
559 : */
560 :
561 0 : int GetReversedAtom(AtomTable *atable, int atom)
562 : {
563 0 : if (atom > 0 && atom < atable->nextFree) {
564 0 : return atable->arev[atom];
565 : } else {
566 0 : return 0;
567 : }
568 : } // GetReversedAtom
569 :
570 : /*
571 : * AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
572 : * Return it's atom index.
573 : */
574 :
575 0 : int AddAtom(AtomTable *atable, const char *s)
576 : {
577 : int atom;
578 :
579 0 : atom = LookUpAddString(atable, s);
580 0 : return atom;
581 : } // AddAtom
582 :
583 : /*
584 : * AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
585 : * Assign it the atom value of "atom".
586 : */
587 :
588 0 : static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
589 : {
590 : int hashindex, lsize;
591 :
592 0 : hashindex = LookUpAddStringHash(atable, s);
593 0 : if (atable->nextFree >= atable->size || atom >= atable->size) {
594 0 : lsize = atable->size*2;
595 0 : if (lsize <= atom)
596 0 : lsize = atom + 1;
597 0 : GrowAtomTable(atable, lsize);
598 : }
599 0 : atable->amap[atom] = atable->htable.entry[hashindex].index;
600 0 : atable->htable.entry[hashindex].value = atom;
601 : //if (atom >= atable->nextFree)
602 : // atable->nextFree = atom + 1;
603 0 : while (atom >= atable->nextFree) {
604 0 : atable->arev[atable->nextFree] = lReverse(atable->nextFree);
605 0 : atable->nextFree++;
606 : }
607 0 : return atom;
608 : } // AddAtomFixed
609 :
610 : /*
611 : * InitAtomTable() - Initialize the atom table.
612 : *
613 : */
614 :
615 0 : int InitAtomTable(AtomTable *atable, int htsize)
616 : {
617 : unsigned int ii;
618 :
619 0 : htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
620 0 : if (!InitStringTable(&atable->stable))
621 0 : return 0;
622 0 : if (!InitHashTable(&atable->htable, htsize))
623 0 : return 0;
624 :
625 0 : atable->nextFree = 0;
626 0 : atable->amap = NULL;
627 0 : atable->size = 0;
628 0 : GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
629 0 : if (!atable->amap)
630 0 : return 0;
631 :
632 : // Initialize lower part of atom table to "<undefined>" atom:
633 :
634 0 : AddAtomFixed(atable, "<undefined>", 0);
635 0 : for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
636 0 : atable->amap[ii] = atable->amap[0];
637 :
638 : // Add single character tokens to the atom table:
639 :
640 : {
641 0 : const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
642 : char t[2];
643 :
644 0 : t[1] = '\0';
645 0 : while (*s) {
646 0 : t[0] = *s;
647 0 : AddAtomFixed(atable, t, s[0]);
648 0 : s++;
649 : }
650 : }
651 :
652 : // Add multiple character scanner tokens :
653 :
654 0 : for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
655 0 : AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
656 :
657 : // Add error symbol if running in error mode:
658 :
659 0 : if (cpp->options.ErrorMode)
660 0 : AddAtomFixed(atable, "error", ERROR_SY);
661 :
662 0 : AddAtom(atable, "<*** end fixed atoms ***>");
663 :
664 0 : return 1;
665 : } // InitAtomTable
666 :
667 : ///////////////////////////////////////////////////////////////////////////////////////////////
668 : ////////////////////////////////// Debug Printing Functions: //////////////////////////////////
669 : ///////////////////////////////////////////////////////////////////////////////////////////////
670 :
671 : /*
672 : * PrintAtomTable()
673 : *
674 : */
675 :
676 0 : void PrintAtomTable(AtomTable *atable)
677 : {
678 : int ii;
679 : char str[200];
680 :
681 0 : for (ii = 0; ii < atable->nextFree; ii++) {
682 0 : sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
683 0 : CPPDebugLogMsg(str);
684 : }
685 0 : sprintf(str, "Hash table: size=%d, entries=%d, collisions=",
686 : atable->htable.size, atable->htable.entries);
687 0 : CPPDebugLogMsg(str);
688 0 : for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
689 0 : sprintf(str, " %d", atable->htable.counts[ii]);
690 0 : CPPDebugLogMsg(str);
691 : }
692 :
693 0 : } // PrintAtomTable
694 :
695 :
696 : /*
697 : * GetStringOfAtom()
698 : *
699 : */
700 :
701 0 : char* GetStringOfAtom(AtomTable *atable, int atom)
702 : {
703 : char* chr_str;
704 0 : chr_str=&atable->stable.strings[atable->amap[atom]];
705 0 : return chr_str;
706 : } // GetStringOfAtom
707 :
708 : /*
709 : * FreeAtomTable() - Free the atom table and associated memory
710 : *
711 : */
712 :
713 0 : void FreeAtomTable(AtomTable *atable)
714 : {
715 0 : FreeStringTable(&atable->stable);
716 0 : FreeHashTable(&atable->htable);
717 0 : if (atable->amap)
718 0 : free(atable->amap);
719 0 : if (atable->arev)
720 0 : free(atable->arev);
721 0 : atable->amap = NULL;
722 0 : atable->arev = NULL;
723 0 : atable->nextFree = 0;
724 0 : atable->size = 0;
725 0 : } // FreeAtomTable
726 :
727 : ///////////////////////////////////////////////////////////////////////////////////////////////
728 : ///////////////////////////////////////// End of atom.c ///////////////////////////////////////
729 : ///////////////////////////////////////////////////////////////////////////////////////////////
730 :
|