LCOV - code coverage report
Current view: directory - gfx/angle/src/compiler/preprocessor - atom.c (source / functions) Found Hit Coverage
Test: app.info Lines: 250 0 0.0 %
Date: 2012-06-02 Functions: 25 0 0.0 %

       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                 : 

Generated by: LCOV version 1.7