-/************************************************************************
- ************************************************************************
- FAUST compiler
- Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ************************************************************************
- ************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "symbol.hh"
-#include "compatibility.hh"
-#include <iostream>
-#include <cstring>
-#include <assert.h>
-
-using namespace std;
-
-/**
- * Hash table used to store the symbols
- */
-
-Symbol* Symbol::gSymbolTable[kHashTableSize];
-
-
-/**
- * Search the hash table for the symbol of name \p str or returns a new one.
- * \param str the name of the symbol
- * \return a symbol of name str
- */
-
-Symbol* Symbol::get(const string& str)
-{
- char buf[1024];
- int i;
- int n = str.length();
-
- if (n>1023) n = 1023;
- for (i = 0; i < n; i++) { buf[i] = str[i]; }
- buf[i] = 0;
-
- return Symbol::get(buf);
-}
-
-
-
-/**
- * Search the hash table for the symbol of name \p str or returns a new one.
- * \param str the name of the symbol
- * \return a symbol of name str
- */
-
-Symbol* Symbol::get(const char* str)
-{
- unsigned int hsh = calcHashKey(str);
- int bckt = hsh % kHashTableSize;
- Symbol* item = gSymbolTable[bckt];
-
- while ( item && !item->equiv(hsh,str) ) item = item->fNext;
- Symbol* r = item ? item : gSymbolTable[bckt] = new Symbol(str, hsh, gSymbolTable[bckt]);
- return r;
-}
-
-
-/**
- * Static method that searches the symbol table for a string.
- * \param str string to search
- * \return true if the string is NOT in the table (it is a new string)
- */
-
-bool Symbol::isnew(const char* str)
-{
- unsigned int hsh = calcHashKey(str);
- int bckt = hsh % kHashTableSize;
- Symbol* item = gSymbolTable[bckt];
-
- while ( item && !item->equiv(hsh,str) ) item = item->fNext;
- return item == 0;
-}
-
-
-/**
- * Creates a new symbol with a name obtained by concatenating the \p str prefix with a number in order to make it unique
- * \param str the prefix of the name
- * \return a symbol of name \p prefix++n
- */
-
-Symbol* Symbol::prefix (const char* str)
-{
- char name[256];
-
- static map<const char*, unsigned int> gPrefixCounters;
-
- for (int n = 0; n<10000; n++) {
- snprintf(name, 256, "%s%d", str, gPrefixCounters[str]++);
- if (isnew(name)) return get(name);
- }
- assert(false);
- return get("UNIQUEOVERFLOW");
-}
-
-
-/**
- * Check if the name of the symbol is equal to string \p str
- * This method is used by isnew() and make() when searching the hashtable
- * for an existing symbol.
- *
- * \param hash the hash key of the string (used to speedup the comparison)
- * \param str the string to compare
- * \return \p true if the name of the symbol and \p str are the same
- */
-
-bool Symbol::equiv (unsigned int hash, const char *str) const
-{
- return (fHash == hash) && (strcmp(fName,str) == 0);
-}
-
-
-
-/**
- * Compute the 32-bits hash key of string \p str
- * \param str the string
- * \return a 32-bits hash key
- */
-
-unsigned int Symbol::calcHashKey (const char* str)
-{
- unsigned int h = 0;
-
- while (*str) h = (h << 1) ^ (h >> 20) ^ (*str++);
- return h;
-}
-
-
-
-/**
- * Constructs a symbol ready to be placed in the hash table.
- * It makes a private copy of its name.
- * \param str the name of the symbol
- * \param hsh the hash key of the symbol
- * \param nxt a pointer to the next symbol in the hash table entry
- */
-
-Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt)
-{
- int len = strlen(str);
-
- fName = new char [len+1];
- memcpy(fName, str, len+1);
- fHash = hsh;
- fNext = nxt;
- fData = 0;
-}
-
-Symbol::~Symbol ()
-{
- delete [] fName;
-}
-
-ostream& Symbol::print (ostream& fout) const ///< print a symbol on a stream
-{
- return fout << fName;
-}