/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-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 "fileio.h"
+#include "spool.h"
-char* ReadStr (FILE* F)
-/* Read a string from the file (the memory will be malloc'ed) */
+unsigned ReadStr (FILE* F)
+/* Read a string from the file, place it into the global string pool, and
+ * return its string id.
+ */
{
+ unsigned Id;
+ char* B;
+ char Buf[256];
+
/* Read the length */
unsigned Len = ReadVar (F);
- /* Allocate memory and read the string itself */
- char* S = xmalloc (Len + 1);
- ReadData (F, S, Len);
+ /* If the string is short enough, use our buffer on the stack, otherwise
+ * allocate space on the heap.
+ */
+ if (Len < sizeof (Buf)) {
+ B = Buf;
+ } else {
+ B = xmalloc (Len + 1);
+ }
+
+ /* Read the string */
+ ReadData (F, B, Len);
+
+ /* Terminate the string */
+ B[Len] = '\0';
- /* Terminate the string and return it */
- S [Len] = '\0';
- return S;
+ /* Insert it into the string pool and remember the id */
+ Id = GetStringId (B);
+
+ /* If we had allocated memory before, free it now */
+ if (B != Buf) {
+ xfree (B);
+ }
+
+ /* Return the string id */
+ return Id;
}
void* ReadData (FILE* F, void* Data, unsigned Size)
/* Read data from the file */
-{
+{
/* Explicitly allow reading zero bytes */
if (Size > 0) {
if (fread (Data, 1, Size, F) != Size) {
/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-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 */
unsigned long ReadVar (FILE* F);
/* Read a variable size value from the file */
-char* ReadStr (FILE* F);
-/* Read a string from the file into a malloced area */
+unsigned ReadStr (FILE* F);
+/* Read a string from the file, place it into the global string pool, and
+ * return its string id.
+ */
FilePos* ReadFilePos (FILE* F, FilePos* Pos);
/* Read a file position from the file */
/* ld65 */
#include "error.h"
-#include "expr.h"
#include "fragment.h"
-#include "fileio.h"
#include "segments.h"
-#include "spool.h"
-static FragCheck* NewFragCheck (unsigned Action)
-/* Allocate a new FragCheck struct and return it */
-{
- /* Allocate memory */
- FragCheck* FC = xmalloc (sizeof (FragCheck));
-
- /* Initialize the fields */
- FC->Next = 0;
- FC->Expr = 0;
- FC->Action = Action;
- FC->Message = INVALID_STRING_ID;
-
- /* Return the new struct */
- return FC;
-}
-
-
-
-FragCheck* ReadFragCheck (FILE* F, Fragment* Frag)
-/* Read a fragment check expression from the given file */
-{
- /* Get the object file pointer from the fragment */
- ObjData* O = Frag->Obj;
-
- /* Read the action and create a new struct */
- FragCheck* FC = NewFragCheck (ReadVar (F));
-
- /* Determine the remaining data from the action */
- switch (FC->Action) {
-
- case FRAG_ACT_WARN:
- case FRAG_ACT_ERROR:
- FC->Expr = ReadExpr (F, O);
- FC->Message = MakeGlobalStringId (O, ReadVar (F));
- break;
-
- default:
- Internal ("In module `%s', file `%s', line %lu: Invalid fragment "
- "check action: %u",
- GetObjFileName (O),
- GetSourceFileName (O, Frag->Pos.Name),
- Frag->Pos.Line, FC->Action);
- }
-
- /* Return the new fragment check */
- return FC;
-}
-
-
-
Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
/* Create a new fragment and insert it into the section S */
{
F->Expr = 0;
InitFilePos (&F->Pos);
F->LI = 0;
- F->Check = 0;
F->Type = Type;
/* Insert the code fragment into the section */
-/* Fragment check expression */
-typedef struct FragCheck FragCheck;
-struct FragCheck {
- struct FragCheck* Next; /* Next check expression */
- struct ExprNode* Expr; /* The expression itself */
- unsigned Action; /* Action to take if the check fails */
- unsigned Message; /* Message number */
-};
-
/* Fragment structure */
typedef struct Fragment Fragment;
struct Fragment {
struct ExprNode* Expr; /* Expression if FRAG_EXPR */
FilePos Pos; /* File position in source */
struct LineInfo* LI; /* Additional line info */
- FragCheck* Check; /* Single linked list of checks */
unsigned char Type; /* Type of fragment */
unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */
};
-FragCheck* ReadFragCheck (FILE* F, Fragment* Frag);
-/* Read a fragment check expression from the given file */
-
Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
/* Create a new fragment and insert it into the section S */
ObjData* O = NewObjData ();
/* Module name */
- char* Name = ReadStr (Lib);
- O->Name = GetStringId (Name);
- xfree (Name);
+ O->Name = ReadStr (Lib);
/* Module flags/MTime/Start/Size */
O->Flags = Read16 (Lib);
- O->MTime = Read32 (Lib);
+ O->MTime = Read32 (Lib);
O->Start = Read32 (Lib);
Read32 (Lib); /* Skip Size */
/* */
/* */
/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
-void RelocLineInfo (struct Segment* S)
+void RelocLineInfo (Segment* S)
/* Relocate the line info for a segment. */
{
unsigned long Offs = 0;
/* */
/* */
/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
FreeImport (O->Imports[--O->ImportCount]);
}
xfree (O->Imports);
- FreeObjStrings (O);
+ xfree (O->Strings);
xfree (O);
}
* when all strings are converted to global strings.
*/
{
- while (O->StringCount) {
- xfree (O->Strings[--O->StringCount]);
- }
xfree (O->Strings);
O->Strings = 0;
}
-const char* GetObjString (const ObjData* O, unsigned Index)
-/* Get a string from the object file string table. Abort if the string index
- * is invalid.
- */
-{
- if (Index >= O->StringCount) {
- Error ("Invalid string index (%u) in module `%s'",
- Index, GetObjFileName (O));
- }
- return O->Strings[Index];
-}
-
-
-
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
/* Convert a local string id into a global one and return it. */
{
Error ("Invalid string index (%u) in module `%s'",
Index, GetObjFileName (O));
}
- return GetStringId (O->Strings[Index]);
+ return O->Strings[Index];
}
unsigned LineInfoCount; /* Count of additional line infos */
struct LineInfo** LineInfos; /* List of additional line infos */
unsigned StringCount; /* Count of strings */
- char** Strings; /* List of strings used */
+ unsigned* Strings; /* List of global string indices */
};
void InsertObjData (ObjData* O);
/* Insert the ObjData object into the collection of used ObjData objects. */
-const char* GetObjString (const ObjData* O, unsigned Index);
-/* Get a string from the object file string table. Abort if the string index
- * is invalid.
- */
-
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index);
/* Convert a local string id into a global one and return it. */
unsigned I;
O->FileCount = ReadVar (F);
- O->Files = xmalloc (O->FileCount * sizeof (FileInfo*));
+ O->Files = xmalloc (O->FileCount * sizeof (O->Files[0]));
for (I = 0; I < O->FileCount; ++I) {
O->Files[I] = ReadFileInfo (F, O);
}
unsigned I;
O->ImportCount = ReadVar (F);
- O->Imports = xmalloc (O->ImportCount * sizeof (Import*));
+ O->Imports = xmalloc (O->ImportCount * sizeof (O->Imports[0]));
for (I = 0; I < O->ImportCount; ++I) {
O->Imports [I] = ReadImport (F, O);
InsertImport (O->Imports [I]);
unsigned I;
O->ExportCount = ReadVar (F);
- O->Exports = xmalloc (O->ExportCount * sizeof (Export*));
+ O->Exports = xmalloc (O->ExportCount * sizeof (O->Exports[0]));
for (I = 0; I < O->ExportCount; ++I) {
O->Exports [I] = ReadExport (F, O);
InsertExport (O->Exports [I]);
unsigned I;
O->DbgSymCount = ReadVar (F);
- O->DbgSyms = xmalloc (O->DbgSymCount * sizeof (DbgSym*));
+ O->DbgSyms = xmalloc (O->DbgSymCount * sizeof (O->DbgSyms[0]));
for (I = 0; I < O->DbgSymCount; ++I) {
O->DbgSyms [I] = ReadDbgSym (F, O);
}
unsigned I;
O->LineInfoCount = ReadVar (F);
- O->LineInfos = xmalloc (O->LineInfoCount * sizeof (LineInfo*));
+ O->LineInfos = xmalloc (O->LineInfoCount * sizeof (O->LineInfos[0]));
for (I = 0; I < O->LineInfoCount; ++I) {
O->LineInfos[I] = ReadLineInfo (F, O);
}
/* Read the string pool from a file at the current position */
{
unsigned I;
+
O->StringCount = ReadVar (F);
- O->Strings = xmalloc (O->StringCount * sizeof (char*));
+ O->Strings = xmalloc (O->StringCount * sizeof (O->Strings[0]));
for (I = 0; I < O->StringCount; ++I) {
O->Strings[I] = ReadStr (F);
}
unsigned I;
O->SectionCount = ReadVar (F);
- O->Sections = xmalloc (O->SectionCount * sizeof (Section*));
+ O->Sections = xmalloc (O->SectionCount * sizeof (O->Sections[0]));
for (I = 0; I < O->SectionCount; ++I) {
O->Sections [I] = ReadSection (F, O);
}
unsigned char Type = Read8 (F);
/* Extract the check mask from the type */
- unsigned char Check = Type & FRAG_CHECKMASK;
unsigned char Bytes = Type & FRAG_BYTEMASK;
Type &= FRAG_TYPEMASK;
return 0;
}
- /* A list of check expressions may follow */
- if (Check) {
-
- /* Read the number of expressions that follow */
- unsigned Count = ReadVar (F);
-
- /* Read the expressions */
- while (Count--) {
- /* ### */
- }
- }
-
/* Read the file position of the fragment */
ReadFilePos (F, &Frag->Pos);