Make much more usage of dynamic strings (StrBufs) instead of char* and
friends. Since names and other strings are now StrBufs in many places, code for output had to be changed. Added support for string literals to StrBuf. git-svn-id: svn://svn.cc65.org/cc65/trunk@3825 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2003 Ullrich von Bassewitz */
|
||||
/* R<EFBFBD>merstrasse 52 */
|
||||
/* (C) 2003-2008 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
/* A string pool is used to store identifiers and other strings. Each string
|
||||
* stored in the pool has a unique id, which may be used to access the string
|
||||
* in the pool. Identical strings are only stored once in the pool and have
|
||||
* in the pool. Identical strings are stored only once in the pool and have
|
||||
* identical ids. This means that instead of comparing strings, just the
|
||||
* string pool ids must be compared.
|
||||
*/
|
||||
@@ -64,8 +64,7 @@ struct StringPoolEntry {
|
||||
StringPoolEntry* Next; /* Pointer to next entry in hash chain */
|
||||
unsigned Hash; /* Full hash value */
|
||||
unsigned Id; /* The numeric string id */
|
||||
unsigned Len; /* Length of the string (excluding terminator) */
|
||||
char S[1]; /* The string itself */
|
||||
StrBuf Buf; /* The string itself */
|
||||
};
|
||||
|
||||
|
||||
@@ -76,21 +75,21 @@ struct StringPoolEntry {
|
||||
|
||||
|
||||
|
||||
static StringPoolEntry* NewStringPoolEntry (const char* S, unsigned Hash, unsigned Id)
|
||||
static StringPoolEntry* NewStringPoolEntry (const StrBuf* S, unsigned Hash, unsigned Id)
|
||||
/* Create a new string pool entry and return it. */
|
||||
{
|
||||
/* Get the length of the string */
|
||||
unsigned Len = strlen (S);
|
||||
|
||||
/* Allocate memory */
|
||||
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry) + Len);
|
||||
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry));
|
||||
|
||||
/* Initialize the fields */
|
||||
E->Next = 0;
|
||||
E->Hash = Hash;
|
||||
E->Id = Id;
|
||||
E->Len = Len;
|
||||
memcpy (E->S, S, Len+1);
|
||||
E->Buf = AUTO_STRBUF_INITIALIZER;
|
||||
SB_Copy (&E->Buf, S);
|
||||
|
||||
/* Always zero terminate the string */
|
||||
SB_Terminate (&E->Buf);
|
||||
|
||||
/* Return the new entry */
|
||||
return E;
|
||||
@@ -129,7 +128,15 @@ void DoneStringPool (StringPool* P)
|
||||
|
||||
/* Free all entries and clear the entry collection */
|
||||
for (I = 0; I < CollCount (&P->Entries); ++I) {
|
||||
xfree (CollAtUnchecked (&P->Entries, I));
|
||||
|
||||
/* Get a pointer to the entry */
|
||||
StringPoolEntry* E = CollAtUnchecked (&P->Entries, I);
|
||||
|
||||
/* Free string buffer memory */
|
||||
SB_Done (&E->Buf);
|
||||
|
||||
/* Free the memory for the entry itself */
|
||||
xfree (E);
|
||||
}
|
||||
CollDeleteAll (&P->Entries);
|
||||
|
||||
@@ -165,25 +172,26 @@ void FreeStringPool (StringPool* P)
|
||||
|
||||
|
||||
|
||||
const char* SP_Get (const StringPool* P, unsigned Index)
|
||||
const StrBuf* SP_Get (const StringPool* P, unsigned Index)
|
||||
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */
|
||||
{
|
||||
/* Get the collection entry */
|
||||
const StringPoolEntry* E = CollConstAt (&P->Entries, Index);
|
||||
|
||||
/* Return the string from the entry */
|
||||
return E->S;
|
||||
return &E->Buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned SP_Add (StringPool* P, const char* S)
|
||||
/* Add a string to the buffer and return the index. If the string does already
|
||||
* exist in the pool, SP_Add will just return the index of the existing string.
|
||||
unsigned SP_Add (StringPool* P, const StrBuf* S)
|
||||
/* Add a string buffer to the buffer and return the index. If the string does
|
||||
* already exist in the pool, SP_AddBuf will just return the index of the
|
||||
* existing string.
|
||||
*/
|
||||
{
|
||||
/* Calculate the string hash */
|
||||
unsigned Hash = HashStr (S);
|
||||
unsigned Hash = HashBuf (S);
|
||||
|
||||
/* Calculate the reduced string hash */
|
||||
unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0]));
|
||||
@@ -191,7 +199,7 @@ unsigned SP_Add (StringPool* P, const char* S)
|
||||
/* Search for an existing entry */
|
||||
StringPoolEntry* E = P->Tab[RHash];
|
||||
while (E) {
|
||||
if (E->Hash == Hash && strcmp (E->S, S) == 0) {
|
||||
if (E->Hash == Hash && SB_Compare (&E->Buf, S) == 0) {
|
||||
/* Found, return the id of the existing string */
|
||||
return E->Id;
|
||||
}
|
||||
@@ -208,8 +216,8 @@ unsigned SP_Add (StringPool* P, const char* S)
|
||||
E->Next = P->Tab[RHash];
|
||||
P->Tab[RHash] = E;
|
||||
|
||||
/* Add up the string size (plus terminator) */
|
||||
P->TotalSize += E->Len + 1;
|
||||
/* Add up the string size */
|
||||
P->TotalSize += SB_GetLen (&E->Buf);
|
||||
|
||||
/* Return the id of the entry */
|
||||
return E->Id;
|
||||
@@ -217,3 +225,22 @@ unsigned SP_Add (StringPool* P, const char* S)
|
||||
|
||||
|
||||
|
||||
unsigned SP_AddStr (StringPool* P, const char* S)
|
||||
/* Add a string to the buffer and return the index. If the string does already
|
||||
* exist in the pool, SP_Add will just return the index of the existing string.
|
||||
*/
|
||||
{
|
||||
unsigned Id;
|
||||
|
||||
/* First make a string buffer, then add it. This is some overhead, but the
|
||||
* routine will probably go.
|
||||
*/
|
||||
StrBuf Buf;
|
||||
Id = SP_Add (P, SB_InitFromString (&Buf, S));
|
||||
|
||||
/* Return the id of the new entry */
|
||||
return Id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user