/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2000-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
#include "check.h"
+#include "coll.h"
#include "hashstr.h"
#include "xmalloc.h"
/* ca65 */
#include "error.h"
-#include "objfile.h"
#include "filetab.h"
+#include "objfile.h"
+#include "spool.h"
/* An entry in the file table */
typedef struct FileEntry FileEntry;
struct FileEntry {
+ unsigned Name; /* File name */
FileEntry* Next; /* Next in hash list */
unsigned Index; /* Index of entry */
unsigned long Size; /* Size of file */
unsigned long MTime; /* Time of last modification */
- char Name[1]; /* Name, dynamically allocated */
};
/* Array of all entries, listed by index */
-static FileEntry** FileTab = 0;
-static unsigned FileCount = 0;
-static unsigned FileMax = 0;
+static Collection FileTab = STATIC_COLLECTION_INITIALIZER;
/* Hash table, hashed by name */
-#define HASHTAB_SIZE 31
+#define HASHTAB_MASK 0x1FU
+#define HASHTAB_SIZE (HASHTAB_MASK + 1)
static FileEntry* HashTab[HASHTAB_SIZE];
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-static FileEntry* NewFileEntry (const char* Name, unsigned long Size, unsigned long MTime)
+static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long MTime)
/* Create a new FileEntry, insert it into the tables and return it */
{
- /* Get the length of the name */
- unsigned Len = strlen (Name);
-
/* Get the hash over the name */
- unsigned Hash = HashStr (Name) % HASHTAB_SIZE;
+ unsigned Hash = (Name & HASHTAB_MASK);
/* Allocate memory for the entry */
- FileEntry* F = xmalloc (sizeof (FileEntry) + Len);
+ FileEntry* F = xmalloc (sizeof (FileEntry));
/* Initialize the fields */
- F->Index = FileCount+1;
+ F->Name = Name;
+ F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
F->Size = Size;
F->MTime = MTime;
- memcpy (F->Name, Name, Len+1);
-
- /* Count the entries and grow the file table if needed */
- if (FileCount >= FileMax) {
- /* We need to grow the table. Create a new one. */
- unsigned NewFileMax = (FileMax == 0)? 32 : FileMax * 2;
- FileEntry** NewFileTab = xmalloc (sizeof (FileEntry*) * NewFileMax);
-
- /* Copy the old entries */
- memcpy (NewFileTab, FileTab, sizeof (FileEntry*) * FileCount);
-
- /* Use the new table */
- xfree (FileTab);
- FileTab = NewFileTab;
- FileMax = NewFileMax;
- }
/* Insert the file into the file table */
- FileTab [FileCount++] = F;
+ CollAppend (&FileTab, F);
/* Insert the entry into the hash table */
F->Next = HashTab[Hash];
const char* GetFileName (unsigned Name)
/* Get the name of a file where the name index is known */
{
- PRECONDITION (Name <= FileCount);
+ const FileEntry* F;
+
if (Name == 0) {
/* Name was defined outside any file scope, use the name of the first
* file instead. Errors are then reported with a file position of
* line zero in the first file.
*/
- if (FileCount == 0) {
+ if (CollCount (&FileTab) == 0) {
/* No files defined until now */
return "(outside file scope)";
} else {
- return FileTab [0]->Name;
+ F = CollConstAt (&FileTab, 0);
}
} else {
- return FileTab [Name-1]->Name;
+ F = CollConstAt (&FileTab, Name-1);
}
+ return GetString (F->Name);
}
unsigned GetFileIndex (const char* Name)
/* Return the file index for the given file name. */
{
+ /* Get the string pool index from the name */
+ unsigned NameIdx = GetStringId (Name);
+
/* Get the hash over the name */
- unsigned Hash = HashStr (Name) % HASHTAB_SIZE;
+ unsigned Hash = (NameIdx & HASHTAB_MASK);
/* Search the linear hash list */
FileEntry* F = HashTab[Hash];
while (F) {
/* Is it this one? */
- if (strcmp (Name, F->Name) == 0) {
+ if (NameIdx == F->Name) {
/* Found, return the index */
return F->Index;
}
*/
{
/* Create a new file entry and insert it into the tables */
- FileEntry* F = NewFileEntry (Name, Size, MTime);
+ FileEntry* F = NewFileEntry (GetStringId (Name), Size, MTime);
/* Return the index */
return F->Index;
ObjStartFiles ();
/* Write the file count */
- ObjWriteVar (FileCount);
+ ObjWriteVar (CollCount (&FileTab));
/* Write the file data */
- for (I = 0; I < FileCount; ++I) {
+ for (I = 0; I < CollCount (&FileTab); ++I) {
/* Get a pointer to the entry */
- FileEntry* F = FileTab[I];
+ const FileEntry* F = CollConstAt (&FileTab, I);
/* Write the fields */
+ ObjWriteVar (F->Name);
ObjWrite32 (F->MTime);
ObjWrite32 (F->Size);
- ObjWriteStr (F->Name);
}
/* Done writing files */
/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2000-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
# define GetStringId(S) SP_Add (&StrPool, (S))
#endif
+#if defined(HAVE_INLINE)
+INLINE const char* GetString (unsigned Index)
+/* Convert a string index into a string */
+{
+ return SP_Get (&StrPool, Index);
+}
+#else
+# define GetString(Index) SP_Get (&StrPool, (Index))
+#endif
+
void WriteStrPool (void);
/* Write the string pool to the object file */
/* */
/* */
/* */
-/* (C) 2000-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2000-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <stdlib.h>
#include <string.h>
-
+
+/* common */
#include "abend.h"
#include "debugflag.h"
#include "xmalloc.h"
void* xmalloc (size_t Size)
/* Allocate memory, check for out of memory condition. Do some debugging */
{
- /* Allocate memory */
- void* P = malloc (Size);
+ void* P = 0;
- /* Check for errors */
- if (P == 0 && Size != 0) {
- AbEnd ("Out of memory - requested block size = %lu", (unsigned long) Size);
+ /* Allow zero sized requests and return NULL in this case */
+ if (Size) {
+
+ /* Allocate memory */
+ P = malloc (Size);
+
+ /* Check for errors */
+ if (P == 0) {
+ AbEnd ("Out of memory - requested block size = %lu",
+ (unsigned long) Size);
+ }
}
/* Return a pointer to the block */
unsigned AttrFlags = atNone;
/* Remember the attributes read */
+ unsigned CfgSValId;
unsigned OS = 0; /* Initialize to keep gcc happy */
unsigned Version = 0;
AttrFlags |= atExport;
/* We expect an identifier */
CfgAssureIdent ();
+ /* Convert the string into a string index */
+ CfgSValId = GetStringId (CfgSVal);
/* Check if the export symbol is also defined as an import. */
- if (O65GetImport (O65FmtDesc, CfgSVal) != 0) {
+ if (O65GetImport (O65FmtDesc, CfgSValId) != 0) {
CfgError ("Exported symbol `%s' cannot be an import", CfgSVal);
}
/* Check if we have this symbol defined already. The entry
* routine will check this also, but we get a more verbose
* error message when checking it here.
*/
- if (O65GetExport (O65FmtDesc, CfgSVal) != 0) {
+ if (O65GetExport (O65FmtDesc, CfgSValId) != 0) {
CfgError ("Duplicate exported symbol: `%s'", CfgSVal);
}
/* Insert the symbol into the table */
- O65SetExport (O65FmtDesc, CfgSVal);
+ O65SetExport (O65FmtDesc, CfgSValId);
break;
case CFGTOK_IMPORT:
AttrFlags |= atImport;
/* We expect an identifier */
CfgAssureIdent ();
+ /* Convert the string into a string index */
+ CfgSValId = GetStringId (CfgSVal);
/* Check if the imported symbol is also defined as an export. */
- if (O65GetExport (O65FmtDesc, CfgSVal) != 0) {
+ if (O65GetExport (O65FmtDesc, CfgSValId) != 0) {
CfgError ("Imported symbol `%s' cannot be an export", CfgSVal);
}
/* Check if we have this symbol defined already. The entry
* routine will check this also, but we get a more verbose
* error message when checking it here.
*/
- if (O65GetImport (O65FmtDesc, CfgSVal) != 0) {
+ if (O65GetImport (O65FmtDesc, CfgSValId) != 0) {
CfgError ("Duplicate imported symbol: `%s'", CfgSVal);
}
/* Insert the symbol into the table */
- O65SetImport (O65FmtDesc, CfgSVal);
+ O65SetImport (O65FmtDesc, CfgSValId);
break;
case CFGTOK_TYPE:
/* Map the identifier to a token */
cfgtok_t FormatTok;
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
- FormatTok = CfgTok;
+ FormatTok = CfgTok;
/* Skip the name and the following colon */
CfgNextTok ();
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2001-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* ld65 */
+#include "dbginfo.h"
#include "fileinfo.h"
#include "lineinfo.h"
-#include "dbginfo.h"
+#include "spool.h"
/* Output the files section */
for (I = 0; I < O->FileCount; ++I) {
const FileInfo* FI = O->Files[I];
- fprintf (F, "file\t\"%s\", %lu, %lu\n", FI->Name, FI->Size, FI->MTime);
+ fprintf (F, "file\t\"%s\", %lu, %lu\n",
+ GetString (FI->Name), FI->Size, FI->MTime);
}
/* Output the lines */
}
/* Name and line number */
- fprintf (F, "line\t\"%s\", %lu", LI->File->Name, LI->Pos.Line);
+ fprintf (F, "line\t\"%s\", %lu", GetString (LI->File->Name), LI->Pos.Line);
/* Code ranges */
for (J = 0; J < CollCount (CodeRanges); ++J) {
/* */
/* */
/* */
-/* (C) 1999-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1999-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* ld65 */
#include "error.h"
#include "extsyms.h"
+#include "spool.h"
/* Structure holding an external symbol */
struct ExtSym {
+ unsigned Name; /* Name index */
ExtSym* List; /* Next entry in list of all symbols */
ExtSym* Next; /* Next entry in hash list */
unsigned Flags; /* Generic flags */
unsigned Num; /* Number of external symbol */
- char Name [1]; /* Name - dynamically allocated */
};
/* External symbol table structure */
-#define HASHTAB_SIZE 53
+#define HASHTAB_MASK 0x3FU
+#define HASHTAB_SIZE (HASHTAB_MASK + 1)
struct ExtSymTab {
ExtSym* Root; /* List of symbols */
- ExtSym* Last; /* Pointer to last symbol */
- unsigned Count; /* Number of symbols */
- ExtSym* HashTab [HASHTAB_SIZE];
+ ExtSym* Last; /* Pointer to last symbol */
+ unsigned Count; /* Number of symbols */
+ ExtSym* HashTab[HASHTAB_SIZE];
};
-ExtSym* NewExtSym (ExtSymTab* Tab, const char* Name)
+ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
/* Create a new external symbol and insert it into the table */
{
/* Get the hash value of the string */
- unsigned Hash = HashStr (Name) % HASHTAB_SIZE;
-
- /* Get the length of the name */
- unsigned Len = strlen (Name);
+ unsigned Hash = (Name & HASHTAB_MASK);
/* Check for duplicates */
- ExtSym* E = GetExtSym (Tab, Name); /* Don't care about duplicate hash here... */
+ ExtSym* E = GetExtSym (Tab, Name);
if (E != 0) {
/* We do already have a symbol with this name */
- Error ("Duplicate external symbol `%s'", Name);
+ Error ("Duplicate external symbol `%s'", GetString (Name));
}
/* Allocate memory for the structure */
- E = xmalloc (sizeof (ExtSym) + Len);
+ E = xmalloc (sizeof (ExtSym));
/* Initialize the structure */
+ E->Name = Name;
E->List = 0;
E->Flags = 0;
E->Num = Tab->Count;
- memcpy (E->Name, Name, Len+1);
/* Insert the entry into the list of all symbols */
if (Tab->Last == 0) {
++Tab->Count;
/* Insert the symbol into the hash table */
- E->Next = Tab->HashTab [Hash];
- Tab->HashTab [Hash] = E;
+ E->Next = Tab->HashTab[Hash];
+ Tab->HashTab[Hash] = E;
/* Done, return the created entry */
return E;
-ExtSym* GetExtSym (const ExtSymTab* Tab, const char* Name)
+ExtSym* GetExtSym (const ExtSymTab* Tab, unsigned Name)
/* Return the entry for the external symbol with the given name. Return NULL
* if there is no such symbol.
*/
{
/* Hash the name */
- unsigned Hash = HashStr (Name) % HASHTAB_SIZE;
+ unsigned Hash = (Name & HASHTAB_MASK);
/* Check the linked list */
- ExtSym* E = Tab->HashTab [Hash];
+ ExtSym* E = Tab->HashTab[Hash];
while (E) {
- if (strcmp (E->Name, Name) == 0) {
+ if (E->Name == Name) {
/* Found it */
break;
}
-const char* ExtSymName (const ExtSym* E)
-/* Return the symbol name */
+unsigned ExtSymName (const ExtSym* E)
+/* Return the symbol name index */
{
return E->Name;
}
+
-ExtSym* NewExtSym (ExtSymTab* Tab, const char* Name);
+ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name);
/* Create a new external symbol and insert it into the list */
ExtSymTab* NewExtSymTab (void);
void FreeExtSymTab (ExtSymTab* Tab);
/* Free an external symbol structure */
-ExtSym* GetExtSym (const ExtSymTab* Tab, const char* Name);
+ExtSym* GetExtSym (const ExtSymTab* Tab, unsigned Name);
/* Return the entry for the external symbol with the given name. Return NULL
* if there is no such symbol.
*/
unsigned ExtSymNum (const ExtSym* E);
/* Return the number of an external symbol */
-const char* ExtSymName (const ExtSym* E);
-/* Return the symbol name */
+unsigned ExtSymName (const ExtSym* E);
+/* Return the symbol name index */
const ExtSym* ExtSymNext (const ExtSym* E);
/* Return the next symbol in the list */
-FileInfo* ReadFileInfo (FILE* F, ObjData* O attribute ((unused)))
+FileInfo* ReadFileInfo (FILE* F, ObjData* O attribute ((unused)))
/* Read a file info from a file and return it */
{
/* Allocate a new FileInfo structure */
FileInfo* FI = NewFileInfo ();
/* Read the fields from the file */
+ FI->Name = ReadVar (F);
FI->MTime = Read32 (F);
FI->Size = Read32 (F);
- FI->Name = ReadStr (F);
/* Return the new struct */
return FI;
typedef struct FileInfo FileInfo;
struct FileInfo {
+ unsigned Name; /* File name index */
unsigned long MTime; /* Time of last modification */
unsigned long Size; /* Size of the file */
- char* Name; /* File name */
};
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
+/* (C) 1999-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
CircularRefError (E);
} else if (E->Expr == 0) {
/* Dummy export, must be an o65 imported symbol */
- ExtSym* S = O65GetImport (D->D, GetString (E->Name));
+ ExtSym* S = O65GetImport (D->D, E->Name);
CHECK (S != 0);
if (D->ExtRef) {
/* We cannot have more than one external reference in o65 */
S = ExtSymList (D->Imports);
while (S) {
/* Get the name */
- const char* Name = ExtSymName (S);
+ const char* Name = GetString (ExtSymName (S));
/* And write it to the output file */
WriteData (D->F, Name, strlen (Name) + 1);
/* Next symbol */
ExprDesc ED;
/* Get the name */
- const char* Name = ExtSymName (S);
+ unsigned NameIdx = ExtSymName (S);
+ const char* Name = GetString (NameIdx);
/* Get the export for this symbol. We've checked before that this
* export does really exist, so if it is unresolved, or if we don't
* find it, there is an error in the linker code.
*/
- Export* E = FindExport (GetStringId (Name));
+ Export* E = FindExport (NameIdx);
if (E == 0 || IsUnresolvedExport (E)) {
Internal ("Unresolved export `%s' found in O65WriteExports", Name);
}
-ExtSym* O65GetImport (O65Desc* D, const char* Ident)
+ExtSym* O65GetImport (O65Desc* D, unsigned Ident)
/* Return the imported symbol or NULL if not found */
{
/* Retrieve the symbol from the table */
-void O65SetImport (O65Desc* D, const char* Ident)
+void O65SetImport (O65Desc* D, unsigned Ident)
/* Set an imported identifier */
{
/* Insert the entry into the table */
-ExtSym* O65GetExport (O65Desc* D, const char* Ident)
+ExtSym* O65GetExport (O65Desc* D, unsigned Ident)
/* Return the exported symbol or NULL if not found */
{
/* Retrieve the symbol from the table */
-void O65SetExport (O65Desc* D, const char* Ident)
+void O65SetExport (O65Desc* D, unsigned Ident)
/* Set an exported identifier */
{
/* Get the export for this symbol and check if it does exist and is
* a resolved symbol.
*/
- Export* E = FindExport (GetStringId (Ident));
+ Export* E = FindExport (Ident);
if (E == 0 || IsUnresolvedExport (E)) {
- Error ("Unresolved export: `%s'", Ident);
+ Error ("Unresolved export: `%s'", GetString (Ident));
}
/* Insert the entry into the table */
/* Called if an unresolved symbol is encountered */
{
/* Check if the symbol is an imported o65 symbol */
- if (O65GetImport (D, GetString (Name)) != 0) {
+ if (O65GetImport (D, Name) != 0) {
/* This is an external symbol, relax... */
return 1;
} else {
/* */
/* */
/* */
-/* (C) 1999-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 1999-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
void O65SetOS (O65Desc* D, unsigned OS, unsigned Version, unsigned Id);
/* Set an option describing the target operating system */
-ExtSym* O65GetImport (O65Desc* D, const char* Ident);
+ExtSym* O65GetImport (O65Desc* D, unsigned Ident);
/* Return the imported symbol or NULL if not found */
-void O65SetImport (O65Desc* D, const char* Ident);
+void O65SetImport (O65Desc* D, unsigned Ident);
/* Set an imported identifier */
-ExtSym* O65GetExport (O65Desc* D, const char* Ident);
+ExtSym* O65GetExport (O65Desc* D, unsigned Ident);
/* Return the exported symbol or NULL if not found */
-void O65SetExport (O65Desc* D, const char* Ident);
+void O65SetExport (O65Desc* D, unsigned Ident);
/* Set an exported identifier */
void O65WriteTarget (O65Desc* D, File* F);
PRECONDITION (Index < O->FileCount);
/* Return the name */
- return O->Files[Index]->Name;
+ return GetString (O->Files[Index]->Name);
}
}