Removed (pretty inconsistently used) tab chars from source code base.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* add.c */
|
||||
/* add.c */
|
||||
/* */
|
||||
/* Object file adding for the ar65 archiver */
|
||||
/* Object file adding for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,10 +55,10 @@ void AddObjFiles (int argc, char* argv [])
|
||||
|
||||
/* Check the argument count */
|
||||
if (argc <= 0) {
|
||||
Error ("No library name given");
|
||||
Error ("No library name given");
|
||||
}
|
||||
if (argc <= 1) {
|
||||
Error ("No object files to add");
|
||||
Error ("No object files to add");
|
||||
}
|
||||
|
||||
/* Open the library, read the index */
|
||||
@@ -67,8 +67,8 @@ void AddObjFiles (int argc, char* argv [])
|
||||
/* Add the object files */
|
||||
I = 1;
|
||||
while (I < argc) {
|
||||
ObjAdd (argv [I]);
|
||||
++I;
|
||||
ObjAdd (argv [I]);
|
||||
++I;
|
||||
}
|
||||
|
||||
/* Create a new library file and close the old one */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* add.h */
|
||||
/* add.h */
|
||||
/* */
|
||||
/* Object file adding for the ar65 archiver */
|
||||
/* Object file adding for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* del.h */
|
||||
/* del.h */
|
||||
/* */
|
||||
/* Object file deleting for the ar65 archiver */
|
||||
/* Object file deleting for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,10 +55,10 @@ void DelObjFiles (int argc, char* argv [])
|
||||
|
||||
/* Check the argument count */
|
||||
if (argc <= 0) {
|
||||
Error ("No library name given");
|
||||
Error ("No library name given");
|
||||
}
|
||||
if (argc <= 1) {
|
||||
Error ("No modules to delete");
|
||||
Error ("No modules to delete");
|
||||
}
|
||||
|
||||
/* Open the library, read the index */
|
||||
@@ -67,9 +67,9 @@ void DelObjFiles (int argc, char* argv [])
|
||||
/* Delete the modules */
|
||||
I = 1;
|
||||
while (I < argc) {
|
||||
/* Delete the module from the list */
|
||||
DelObjData (argv [I]);
|
||||
++I;
|
||||
/* Delete the module from the list */
|
||||
DelObjData (argv [I]);
|
||||
++I;
|
||||
}
|
||||
|
||||
/* Create a new library file and close the old one */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* del.h */
|
||||
/* del.h */
|
||||
/* */
|
||||
/* Object file deleting for the ar65 archiver */
|
||||
/* Object file deleting for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ void DelObjFiles (int argc, char* argv []);
|
||||
|
||||
|
||||
|
||||
/* End of del.h */
|
||||
/* End of del.h */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.c */
|
||||
/* global.c */
|
||||
/* */
|
||||
/* Error handling for the ar65 archiver */
|
||||
/* Error handling for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.h */
|
||||
/* global.h */
|
||||
/* */
|
||||
/* Error handling for the ar65 archiver */
|
||||
/* Error handling for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* exports.c */
|
||||
/* exports.c */
|
||||
/* */
|
||||
/* Duplicate export checking for the ar65 archiver */
|
||||
/* Duplicate export checking for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -56,19 +56,19 @@
|
||||
/* A hash table entry */
|
||||
typedef struct HashEntry HashEntry;
|
||||
struct HashEntry {
|
||||
HashEntry* Next; /* Next in list */
|
||||
const ObjData* Module; /* Pointer to object module */
|
||||
char Name [1]; /* Name of identifier */
|
||||
HashEntry* Next; /* Next in list */
|
||||
const ObjData* Module; /* Pointer to object module */
|
||||
char Name [1]; /* Name of identifier */
|
||||
};
|
||||
|
||||
/* Hash table */
|
||||
#define HASHTAB_SIZE 4783
|
||||
static HashEntry* HashTab [HASHTAB_SIZE];
|
||||
#define HASHTAB_SIZE 4783
|
||||
static HashEntry* HashTab [HASHTAB_SIZE];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ static HashEntry* NewHashEntry (const char* Name, const ObjData* Module)
|
||||
HashEntry* H = xmalloc (sizeof (HashEntry) + Len);
|
||||
|
||||
/* Initialize the fields and return it */
|
||||
H->Next = 0;
|
||||
H->Module = Module;
|
||||
H->Next = 0;
|
||||
H->Module = Module;
|
||||
memcpy (H->Name, Name, Len);
|
||||
H->Name [Len] = '\0';
|
||||
return H;
|
||||
@@ -105,23 +105,23 @@ void ExpInsert (const char* Name, const ObjData* Module)
|
||||
|
||||
/* Search through the list in that slot and print matching duplicates */
|
||||
if (HashTab [HashVal] == 0) {
|
||||
/* The slot is empty */
|
||||
HashTab [HashVal] = H;
|
||||
return;
|
||||
/* The slot is empty */
|
||||
HashTab [HashVal] = H;
|
||||
return;
|
||||
}
|
||||
L = HashTab [HashVal];
|
||||
while (1) {
|
||||
if (strcmp (L->Name, Name) == 0) {
|
||||
/* Duplicate entry */
|
||||
Warning ("External symbol `%s' in module `%s', library `%s' "
|
||||
if (strcmp (L->Name, Name) == 0) {
|
||||
/* Duplicate entry */
|
||||
Warning ("External symbol `%s' in module `%s', library `%s' "
|
||||
"is duplicated in module `%s'",
|
||||
Name, L->Name, LibName, Module->Name);
|
||||
}
|
||||
if (L->Next == 0) {
|
||||
break;
|
||||
} else {
|
||||
L = L->Next;
|
||||
}
|
||||
Name, L->Name, LibName, Module->Name);
|
||||
}
|
||||
if (L->Next == 0) {
|
||||
break;
|
||||
} else {
|
||||
L = L->Next;
|
||||
}
|
||||
}
|
||||
L->Next = H;
|
||||
}
|
||||
@@ -137,11 +137,11 @@ const ObjData* ExpFind (const char* Name)
|
||||
HashEntry* L = HashTab [HashStr (Name) % HASHTAB_SIZE];
|
||||
while (L) {
|
||||
/* Search through the list in that slot */
|
||||
if (strcmp (L->Name, Name) == 0) {
|
||||
/* Entry found */
|
||||
return L->Module;
|
||||
}
|
||||
L = L->Next;
|
||||
if (strcmp (L->Name, Name) == 0) {
|
||||
/* Entry found */
|
||||
return L->Module;
|
||||
}
|
||||
L = L->Next;
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* exports.h */
|
||||
/* exports.h */
|
||||
/* */
|
||||
/* Duplicate export checking for the ar65 archiver */
|
||||
/* Duplicate export checking for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@ struct ObjData;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* extract.c */
|
||||
/* extract.c */
|
||||
/* */
|
||||
/* Object file extraction for the ar65 archiver */
|
||||
/* Object file extraction for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,10 +55,10 @@ void ExtractObjFiles (int argc, char* argv [])
|
||||
|
||||
/* Check the argument count */
|
||||
if (argc <= 0) {
|
||||
Error ("No library name given");
|
||||
Error ("No library name given");
|
||||
}
|
||||
if (argc <= 1) {
|
||||
Error ("No object files to extract");
|
||||
Error ("No object files to extract");
|
||||
}
|
||||
|
||||
/* Open the library, read the index */
|
||||
@@ -67,8 +67,8 @@ void ExtractObjFiles (int argc, char* argv [])
|
||||
/* Extract the object files */
|
||||
I = 1;
|
||||
while (I < argc) {
|
||||
ObjExtract (argv [I]);
|
||||
++I;
|
||||
ObjExtract (argv [I]);
|
||||
++I;
|
||||
}
|
||||
|
||||
/* Create a new library file and close the old one */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* extract.h */
|
||||
/* extract.h */
|
||||
/* */
|
||||
/* Object file extraction for the ar65 archiver */
|
||||
/* Object file extraction for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fileio.c */
|
||||
/* fileio.c */
|
||||
/* */
|
||||
/* File I/O for the ar65 archiver */
|
||||
/* File I/O for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ void Write8 (FILE* F, unsigned char Val)
|
||||
/* Write an 8 bit value to the file */
|
||||
{
|
||||
if (putc (Val, F) == EOF) {
|
||||
Error ("Write error (disk full?)");
|
||||
Error ("Write error (disk full?)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,12 +89,12 @@ void WriteVar (FILE* F, unsigned long V)
|
||||
* needing 5 bytes if a 32 bit value is written to file.
|
||||
*/
|
||||
do {
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
if (V) {
|
||||
C |= 0x80;
|
||||
}
|
||||
Write8 (F, C);
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
if (V) {
|
||||
C |= 0x80;
|
||||
}
|
||||
Write8 (F, C);
|
||||
} while (V != 0);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ void WriteData (FILE* F, const void* Data, unsigned Size)
|
||||
/* Write data to the file */
|
||||
{
|
||||
if (fwrite (Data, 1, Size, F) != Size) {
|
||||
Error ("Write error (disk full?)");
|
||||
Error ("Write error (disk full?)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ unsigned Read8 (FILE* F)
|
||||
{
|
||||
int C = getc (F);
|
||||
if (C == EOF) {
|
||||
Error ("Read error (file corrupt?)");
|
||||
Error ("Read error (file corrupt?)");
|
||||
}
|
||||
return C;
|
||||
}
|
||||
@@ -162,12 +162,12 @@ unsigned long ReadVar (FILE* F)
|
||||
unsigned long V = 0;
|
||||
unsigned Shift = 0;
|
||||
do {
|
||||
/* Read one byte */
|
||||
C = Read8 (F);
|
||||
/* Encode it into the target value */
|
||||
V |= ((unsigned long)(C & 0x7F)) << Shift;
|
||||
/* Next value */
|
||||
Shift += 7;
|
||||
/* Read one byte */
|
||||
C = Read8 (F);
|
||||
/* Encode it into the target value */
|
||||
V |= ((unsigned long)(C & 0x7F)) << Shift;
|
||||
/* Next value */
|
||||
Shift += 7;
|
||||
} while (C & 0x80);
|
||||
|
||||
/* Return the value read */
|
||||
@@ -197,7 +197,7 @@ void* ReadData (FILE* F, void* Data, unsigned Size)
|
||||
/* Read data from the file */
|
||||
{
|
||||
if (fread (Data, 1, Size, F) != Size) {
|
||||
Error ("Read error (file corrupt?)");
|
||||
Error ("Read error (file corrupt?)");
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fileio.h */
|
||||
/* fileio.h */
|
||||
/* */
|
||||
/* File I/O for the ar65 archiver */
|
||||
/* File I/O for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.c */
|
||||
/* global.c */
|
||||
/* */
|
||||
/* Global variables for the ar65 archiver */
|
||||
/* Global variables for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.h */
|
||||
/* global.h */
|
||||
/* */
|
||||
/* Global variables for the ar65 archiver */
|
||||
/* Global variables for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* library.c */
|
||||
/* library.c */
|
||||
/* */
|
||||
/* Library data structures and helpers for the ar65 archiver */
|
||||
/* Library data structures and helpers for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -56,20 +56,20 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Name of the library file */
|
||||
const char* LibName = 0;
|
||||
const char* LibName = 0;
|
||||
|
||||
/* File descriptor for the library file */
|
||||
FILE* NewLib = 0;
|
||||
static FILE* Lib = 0;
|
||||
FILE* NewLib = 0;
|
||||
static FILE* Lib = 0;
|
||||
|
||||
/* The library header */
|
||||
static LibHeader Header = {
|
||||
static LibHeader Header = {
|
||||
LIB_MAGIC,
|
||||
LIB_VERSION,
|
||||
0,
|
||||
@@ -79,7 +79,7 @@ static LibHeader Header = {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Writing file data structures */
|
||||
/* Writing file data structures */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -93,11 +93,11 @@ static void ReadHeader (void)
|
||||
/* Read the header fields, checking magic and version */
|
||||
Header.Magic = Read32 (Lib);
|
||||
if (Header.Magic != LIB_MAGIC) {
|
||||
Error ("`%s' is not a valid library file", LibName);
|
||||
Error ("`%s' is not a valid library file", LibName);
|
||||
}
|
||||
Header.Version = Read16 (Lib);
|
||||
if (Header.Version != LIB_VERSION) {
|
||||
Error ("Wrong data version in `%s'", LibName);
|
||||
Error ("Wrong data version in `%s'", LibName);
|
||||
}
|
||||
Header.Flags = Read16 (Lib);
|
||||
Header.IndexOffs = Read32 (Lib);
|
||||
@@ -109,7 +109,7 @@ static void ReadIndexEntry (void)
|
||||
/* Read one entry in the index */
|
||||
{
|
||||
/* Create a new entry and insert it into the list */
|
||||
ObjData* O = NewObjData ();
|
||||
ObjData* O = NewObjData ();
|
||||
|
||||
/* Module name/flags/MTime/Start/Size */
|
||||
O->Name = ReadStr (Lib);
|
||||
@@ -134,7 +134,7 @@ static void ReadIndex (void)
|
||||
|
||||
/* Read all entries in the index */
|
||||
while (Count--) {
|
||||
ReadIndexEntry ();
|
||||
ReadIndexEntry ();
|
||||
}
|
||||
|
||||
/* Read basic object file data from the actual entries */
|
||||
@@ -151,7 +151,7 @@ static void ReadIndex (void)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Writing file data structures */
|
||||
/* Writing file data structures */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -200,14 +200,14 @@ static void WriteIndex (void)
|
||||
|
||||
/* Write the object files */
|
||||
for (I = 0; I < CollCount (&ObjPool); ++I) {
|
||||
WriteIndexEntry (CollConstAt (&ObjPool, I));
|
||||
WriteIndexEntry (CollConstAt (&ObjPool, I));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* High level stuff */
|
||||
/* High level stuff */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -225,32 +225,32 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp)
|
||||
Lib = fopen (Name, "rb");
|
||||
if (Lib == 0) {
|
||||
|
||||
/* File does not exist */
|
||||
if (MustExist) {
|
||||
Error ("Library `%s' does not exist", Name);
|
||||
} else {
|
||||
Warning ("Library `%s' not found - will be created", Name);
|
||||
}
|
||||
/* File does not exist */
|
||||
if (MustExist) {
|
||||
Error ("Library `%s' does not exist", Name);
|
||||
} else {
|
||||
Warning ("Library `%s' not found - will be created", Name);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* We have an existing file: Read the header */
|
||||
ReadHeader ();
|
||||
ReadHeader ();
|
||||
|
||||
/* Now read the existing index */
|
||||
ReadIndex ();
|
||||
/* Now read the existing index */
|
||||
ReadIndex ();
|
||||
|
||||
}
|
||||
|
||||
if (NeedTemp) {
|
||||
/* Create the temporary library */
|
||||
NewLib = tmpfile ();
|
||||
if (NewLib == 0) {
|
||||
Error ("Cannot create temporary file: %s", strerror (errno));
|
||||
}
|
||||
/* Create the temporary library */
|
||||
NewLib = tmpfile ();
|
||||
if (NewLib == 0) {
|
||||
Error ("Cannot create temporary file: %s", strerror (errno));
|
||||
}
|
||||
|
||||
/* Write a dummy header to the temp file */
|
||||
WriteHeader ();
|
||||
/* Write a dummy header to the temp file */
|
||||
WriteHeader ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,10 +268,10 @@ unsigned long LibCopyTo (FILE* F, unsigned long Bytes)
|
||||
|
||||
/* Copy loop */
|
||||
while (Bytes) {
|
||||
unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
|
||||
ReadData (F, Buf, Count);
|
||||
WriteData (NewLib, Buf, Count);
|
||||
Bytes -= Count;
|
||||
unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
|
||||
ReadData (F, Buf, Count);
|
||||
WriteData (NewLib, Buf, Count);
|
||||
Bytes -= Count;
|
||||
}
|
||||
|
||||
/* Return the start position */
|
||||
@@ -290,10 +290,10 @@ void LibCopyFrom (unsigned long Pos, unsigned long Bytes, FILE* F)
|
||||
|
||||
/* Copy loop */
|
||||
while (Bytes) {
|
||||
unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
|
||||
ReadData (Lib, Buf, Count);
|
||||
WriteData (F, Buf, Count);
|
||||
Bytes -= Count;
|
||||
unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
|
||||
ReadData (Lib, Buf, Count);
|
||||
WriteData (F, Buf, Count);
|
||||
Bytes -= Count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,11 +313,11 @@ static void LibCheckExports (ObjData* O)
|
||||
for (I = 0; I < CollCount (&O->Exports); ++I) {
|
||||
|
||||
/* Get the name of the export */
|
||||
const char* Name = CollConstAt (&O->Exports, I);
|
||||
const char* Name = CollConstAt (&O->Exports, I);
|
||||
|
||||
/* Insert the name into the hash table */
|
||||
Print (stdout, 1, " %s\n", Name);
|
||||
ExpInsert (Name, O);
|
||||
/* Insert the name into the hash table */
|
||||
Print (stdout, 1, " %s\n", Name);
|
||||
ExpInsert (Name, O);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,65 +331,65 @@ void LibClose (void)
|
||||
/* Do we have a temporary library? */
|
||||
if (NewLib) {
|
||||
|
||||
unsigned I;
|
||||
unsigned char Buf [4096];
|
||||
size_t Count;
|
||||
unsigned I;
|
||||
unsigned char Buf [4096];
|
||||
size_t Count;
|
||||
|
||||
/* Walk through the object file list, inserting exports into the
|
||||
* export list checking for duplicates. Copy any data that is still
|
||||
* in the old library into the new one.
|
||||
*/
|
||||
for (I = 0; I < CollCount (&ObjPool); ++I) {
|
||||
* export list checking for duplicates. Copy any data that is still
|
||||
* in the old library into the new one.
|
||||
*/
|
||||
for (I = 0; I < CollCount (&ObjPool); ++I) {
|
||||
|
||||
/* Get a pointer to the object */
|
||||
ObjData* O = CollAtUnchecked (&ObjPool, I);
|
||||
/* Get a pointer to the object */
|
||||
ObjData* O = CollAtUnchecked (&ObjPool, I);
|
||||
|
||||
/* Check exports, make global export table */
|
||||
LibCheckExports (O);
|
||||
/* Check exports, make global export table */
|
||||
LibCheckExports (O);
|
||||
|
||||
/* Copy data if needed */
|
||||
if ((O->Flags & OBJ_HAVEDATA) == 0) {
|
||||
/* Data is still in the old library */
|
||||
fseek (Lib, O->Start, SEEK_SET);
|
||||
O->Start = ftell (NewLib);
|
||||
LibCopyTo (Lib, O->Size);
|
||||
O->Flags |= OBJ_HAVEDATA;
|
||||
}
|
||||
}
|
||||
/* Copy data if needed */
|
||||
if ((O->Flags & OBJ_HAVEDATA) == 0) {
|
||||
/* Data is still in the old library */
|
||||
fseek (Lib, O->Start, SEEK_SET);
|
||||
O->Start = ftell (NewLib);
|
||||
LibCopyTo (Lib, O->Size);
|
||||
O->Flags |= OBJ_HAVEDATA;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the index */
|
||||
WriteIndex ();
|
||||
/* Write the index */
|
||||
WriteIndex ();
|
||||
|
||||
/* Write the updated header */
|
||||
WriteHeader ();
|
||||
/* Write the updated header */
|
||||
WriteHeader ();
|
||||
|
||||
/* Close the file */
|
||||
if (Lib && fclose (Lib) != 0) {
|
||||
Error ("Error closing library: %s", strerror (errno));
|
||||
}
|
||||
/* Close the file */
|
||||
if (Lib && fclose (Lib) != 0) {
|
||||
Error ("Error closing library: %s", strerror (errno));
|
||||
}
|
||||
|
||||
/* Reopen the library and truncate it */
|
||||
Lib = fopen (LibName, "wb");
|
||||
if (Lib == 0) {
|
||||
Error ("Cannot open library `%s' for writing: %s",
|
||||
LibName, strerror (errno));
|
||||
}
|
||||
/* Reopen the library and truncate it */
|
||||
Lib = fopen (LibName, "wb");
|
||||
if (Lib == 0) {
|
||||
Error ("Cannot open library `%s' for writing: %s",
|
||||
LibName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Copy the new library to the new one */
|
||||
fseek (NewLib, 0, SEEK_SET);
|
||||
while ((Count = fread (Buf, 1, sizeof (Buf), NewLib)) != 0) {
|
||||
if (fwrite (Buf, 1, Count, Lib) != Count) {
|
||||
Error ("Cannot write to `%s': %s", LibName, strerror (errno));
|
||||
}
|
||||
}
|
||||
/* Copy the new library to the new one */
|
||||
fseek (NewLib, 0, SEEK_SET);
|
||||
while ((Count = fread (Buf, 1, sizeof (Buf), NewLib)) != 0) {
|
||||
if (fwrite (Buf, 1, Count, Lib) != Count) {
|
||||
Error ("Cannot write to `%s': %s", LibName, strerror (errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close both files */
|
||||
if (Lib && fclose (Lib) != 0) {
|
||||
Error ("Problem closing `%s': %s", LibName, strerror (errno));
|
||||
Error ("Problem closing `%s': %s", LibName, strerror (errno));
|
||||
}
|
||||
if (NewLib && fclose (NewLib) != 0) {
|
||||
Error ("Problem closing temporary library file: %s", strerror (errno));
|
||||
Error ("Problem closing temporary library file: %s", strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* library.h */
|
||||
/* library.h */
|
||||
/* */
|
||||
/* Library data structures and helpers for the ar65 archiver */
|
||||
/* Library data structures and helpers for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -52,12 +52,12 @@
|
||||
extern const char* LibName;
|
||||
|
||||
/* File descriptor for the new library file */
|
||||
extern FILE* NewLib;
|
||||
extern FILE* NewLib;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* list.c */
|
||||
/* list.c */
|
||||
/* */
|
||||
/* Module listing for the ar65 archiver */
|
||||
/* Module listing for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@ void ListObjFiles (int argc, char* argv [])
|
||||
|
||||
/* Check the argument count */
|
||||
if (argc <= 0) {
|
||||
Error ("No library name given");
|
||||
Error ("No library name given");
|
||||
}
|
||||
if (argc > 2) {
|
||||
Error ("Too many arguments");
|
||||
Error ("Too many arguments");
|
||||
}
|
||||
|
||||
/* Open the library, read the index */
|
||||
@@ -74,7 +74,7 @@ void ListObjFiles (int argc, char* argv [])
|
||||
O = CollConstAt (&ObjPool, I);
|
||||
|
||||
/* Print the name */
|
||||
printf ("%s\n", O->Name);
|
||||
printf ("%s\n", O->Name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* list.h */
|
||||
/* list.h */
|
||||
/* */
|
||||
/* Module listing for the ar65 archiver */
|
||||
/* Module listing for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
104
src/ar65/main.c
104
src/ar65/main.c
@@ -1,34 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* main.c */
|
||||
/* */
|
||||
/* Main program for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* main.c */
|
||||
/* */
|
||||
/* Main program for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -83,54 +83,54 @@ int main (int argc, char* argv [])
|
||||
|
||||
/* We must have a file name */
|
||||
if (ArgCount < 2) {
|
||||
Usage ();
|
||||
Usage ();
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
I = 1;
|
||||
while (I < ArgCount) {
|
||||
|
||||
/* Get the argument */
|
||||
const char* Arg = ArgVec [I];
|
||||
/* Get the argument */
|
||||
const char* Arg = ArgVec [I];
|
||||
|
||||
/* Check for an option */
|
||||
if (strlen (Arg) != 1) {
|
||||
Usage ();
|
||||
}
|
||||
switch (Arg [0]) {
|
||||
/* Check for an option */
|
||||
if (strlen (Arg) != 1) {
|
||||
Usage ();
|
||||
}
|
||||
switch (Arg [0]) {
|
||||
|
||||
case 'a':
|
||||
AddObjFiles (ArgCount - I - 1, &ArgVec[I+1]);
|
||||
break;
|
||||
case 'a':
|
||||
AddObjFiles (ArgCount - I - 1, &ArgVec[I+1]);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
DelObjFiles (ArgCount - I - 1, &ArgVec [I+1]);
|
||||
break;
|
||||
case 'd':
|
||||
DelObjFiles (ArgCount - I - 1, &ArgVec [I+1]);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
ListObjFiles (ArgCount - I - 1, &ArgVec [I+1]);
|
||||
break;
|
||||
case 'l':
|
||||
ListObjFiles (ArgCount - I - 1, &ArgVec [I+1]);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
++Verbosity;
|
||||
break;
|
||||
case 'v':
|
||||
++Verbosity;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
ExtractObjFiles (ArgCount - I - 1, &ArgVec [I+1]);
|
||||
break;
|
||||
case 'x':
|
||||
ExtractObjFiles (ArgCount - I - 1, &ArgVec [I+1]);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
fprintf (stderr, "ar65 V%s\n", GetVersionAsString ());
|
||||
break;
|
||||
case 'V':
|
||||
fprintf (stderr, "ar65 V%s\n", GetVersionAsString ());
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "Unknown option: %s\n", Arg);
|
||||
Usage ();
|
||||
default:
|
||||
fprintf (stderr, "Unknown option: %s\n", Arg);
|
||||
Usage ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Next argument */
|
||||
++I;
|
||||
/* Next argument */
|
||||
++I;
|
||||
}
|
||||
|
||||
/* Return an apropriate exit code */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objdata.c */
|
||||
/* objdata.c */
|
||||
/* */
|
||||
/* Handling object file data for the ar65 archiver */
|
||||
/* Handling object file data for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Collection ObjPool = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -70,12 +70,12 @@ ObjData* NewObjData (void)
|
||||
ObjData* O = xmalloc (sizeof (ObjData));
|
||||
|
||||
/* Initialize the data */
|
||||
O->Name = 0;
|
||||
O->Name = 0;
|
||||
|
||||
O->Flags = 0;
|
||||
O->MTime = 0;
|
||||
O->Start = 0;
|
||||
O->Size = 0;
|
||||
O->Flags = 0;
|
||||
O->MTime = 0;
|
||||
O->Start = 0;
|
||||
O->Size = 0;
|
||||
|
||||
O->Strings = EmptyCollection;
|
||||
O->Exports = EmptyCollection;
|
||||
@@ -134,9 +134,9 @@ ObjData* FindObjData (const char* Module)
|
||||
ObjData* O = CollAtUnchecked (&ObjPool, I);
|
||||
|
||||
/* Did we find it? */
|
||||
if (strcmp (O->Name, Module) == 0) {
|
||||
return O;
|
||||
}
|
||||
if (strcmp (O->Name, Module) == 0) {
|
||||
return O;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -153,15 +153,15 @@ void DelObjData (const char* Module)
|
||||
ObjData* O = CollAtUnchecked (&ObjPool, I);
|
||||
|
||||
/* Did we find it? */
|
||||
if (strcmp (O->Name, Module) == 0) {
|
||||
if (strcmp (O->Name, Module) == 0) {
|
||||
|
||||
/* Free the entry */
|
||||
/* Free the entry */
|
||||
CollDelete (&ObjPool, I);
|
||||
FreeObjData (O);
|
||||
FreeObjData (O);
|
||||
|
||||
/* Done */
|
||||
return;
|
||||
}
|
||||
/* Done */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found! */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objdata.h */
|
||||
/* objdata.h */
|
||||
/* */
|
||||
/* Handling object file data for the ar65 archiver */
|
||||
/* Handling object file data for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,32 +45,32 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Values for the Flags field */
|
||||
#define OBJ_HAVEDATA 0x0001 /* The object data is in the tmp file */
|
||||
#define OBJ_HAVEDATA 0x0001 /* The object data is in the tmp file */
|
||||
|
||||
|
||||
/* Internal structure holding object file data */
|
||||
typedef struct ObjData ObjData;
|
||||
struct ObjData {
|
||||
char* Name; /* Module name */
|
||||
char* Name; /* Module name */
|
||||
|
||||
/* Index entry */
|
||||
unsigned Flags;
|
||||
unsigned long MTime; /* Modifiation time of object file */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned long Size; /* Size of data in library */
|
||||
unsigned Flags;
|
||||
unsigned long MTime; /* Modifiation time of object file */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned long Size; /* Size of data in library */
|
||||
|
||||
/* Object file header */
|
||||
ObjHeader Header;
|
||||
|
||||
/* Basic data needed for simple checks */
|
||||
Collection Strings; /* Strings from the object file */
|
||||
Collection Exports; /* Exports list from object file */
|
||||
Collection Exports; /* Exports list from object file */
|
||||
};
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ extern Collection ObjPool;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objfile.c */
|
||||
/* */
|
||||
/* Object file handling for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* objfile.c */
|
||||
/* */
|
||||
/* Object file handling for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ static const char* GetModule (const char* Name)
|
||||
|
||||
/* Must not end with a path separator */
|
||||
if (*Module == 0) {
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
}
|
||||
|
||||
/* Done */
|
||||
@@ -80,21 +80,21 @@ static const char* GetModule (const char* Name)
|
||||
static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
/* Read the header of the object file checking the signature */
|
||||
{
|
||||
H->Magic = Read32 (Obj);
|
||||
H->Magic = Read32 (Obj);
|
||||
if (H->Magic != OBJ_MAGIC) {
|
||||
Error ("`%s' is not an object file", Name);
|
||||
Error ("`%s' is not an object file", Name);
|
||||
}
|
||||
H->Version = Read16 (Obj);
|
||||
H->Version = Read16 (Obj);
|
||||
if (H->Version != OBJ_VERSION) {
|
||||
Error ("Object file `%s' has wrong version", Name);
|
||||
Error ("Object file `%s' has wrong version", Name);
|
||||
}
|
||||
H->Flags = Read16 (Obj);
|
||||
H->Flags = Read16 (Obj);
|
||||
H->OptionOffs = Read32 (Obj);
|
||||
H->OptionSize = Read32 (Obj);
|
||||
H->FileOffs = Read32 (Obj);
|
||||
H->FileSize = Read32 (Obj);
|
||||
H->SegOffs = Read32 (Obj);
|
||||
H->SegSize = Read32 (Obj);
|
||||
H->SegOffs = Read32 (Obj);
|
||||
H->SegSize = Read32 (Obj);
|
||||
H->ImportOffs = Read32 (Obj);
|
||||
H->ImportSize = Read32 (Obj);
|
||||
H->ExportOffs = Read32 (Obj);
|
||||
@@ -124,23 +124,23 @@ static void SkipExpr (FILE* F)
|
||||
/* Handle then different expression nodes */
|
||||
switch (Op) {
|
||||
|
||||
case EXPR_NULL:
|
||||
break;
|
||||
case EXPR_NULL:
|
||||
break;
|
||||
|
||||
case EXPR_LITERAL:
|
||||
/* 32 bit literal value */
|
||||
(void) Read32 (F);
|
||||
break;
|
||||
/* 32 bit literal value */
|
||||
(void) Read32 (F);
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Variable seized symbol index */
|
||||
(void) ReadVar (F);
|
||||
break;
|
||||
/* Variable seized symbol index */
|
||||
(void) ReadVar (F);
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* 8 bit segment number */
|
||||
(void) Read8 (F);
|
||||
break;
|
||||
/* 8 bit segment number */
|
||||
(void) Read8 (F);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* What's left are unary and binary nodes */
|
||||
@@ -236,7 +236,7 @@ void ObjAdd (const char* Name)
|
||||
/* Open the object file */
|
||||
FILE* Obj = fopen (Name, "rb");
|
||||
if (Obj == 0) {
|
||||
Error ("Could not open `%s': %s", Name, strerror (errno));
|
||||
Error ("Could not open `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Get the modification time of the object file. There a race condition
|
||||
@@ -248,7 +248,7 @@ void ObjAdd (const char* Name)
|
||||
* here.
|
||||
*/
|
||||
if (FileStat (Name, &StatBuf) != 0) {
|
||||
Error ("Cannot stat object file `%s': %s", Name, strerror (errno));
|
||||
Error ("Cannot stat object file `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Read and check the header */
|
||||
@@ -260,16 +260,16 @@ void ObjAdd (const char* Name)
|
||||
/* Check if we already have a module with this name */
|
||||
O = FindObjData (Module);
|
||||
if (O == 0) {
|
||||
/* Not found, create a new entry */
|
||||
O = NewObjData ();
|
||||
/* Not found, create a new entry */
|
||||
O = NewObjData ();
|
||||
} else {
|
||||
/* Found - check the file modification times of the internal copy
|
||||
* and the external one.
|
||||
*/
|
||||
if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) {
|
||||
Warning ("Replacing module `%s' by older version in library `%s'",
|
||||
/* Found - check the file modification times of the internal copy
|
||||
* and the external one.
|
||||
*/
|
||||
if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) {
|
||||
Warning ("Replacing module `%s' by older version in library `%s'",
|
||||
O->Name, LibName);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free data */
|
||||
ClearObjData (O);
|
||||
@@ -277,8 +277,8 @@ void ObjAdd (const char* Name)
|
||||
|
||||
/* Initialize the object module data structure */
|
||||
O->Name = xstrdup (Module);
|
||||
O->Flags = OBJ_HAVEDATA;
|
||||
O->MTime = (unsigned long) StatBuf.st_mtime;
|
||||
O->Flags = OBJ_HAVEDATA;
|
||||
O->MTime = (unsigned long) StatBuf.st_mtime;
|
||||
O->Start = 0;
|
||||
|
||||
/* Determine the file size. Note: Race condition here */
|
||||
@@ -313,13 +313,13 @@ void ObjExtract (const char* Name)
|
||||
|
||||
/* Bail out if the module does not exist */
|
||||
if (O == 0) {
|
||||
Error ("Module `%s' not found in library `%s'", Module, LibName);
|
||||
Error ("Module `%s' not found in library `%s'", Module, LibName);
|
||||
}
|
||||
|
||||
/* Open the output file */
|
||||
Obj = fopen (Name, "w+b");
|
||||
if (Obj == 0) {
|
||||
Error ("Cannot open target file `%s': %s", Name, strerror (errno));
|
||||
Error ("Cannot open target file `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Copy the complete object file data from the library to the new object
|
||||
@@ -329,12 +329,12 @@ void ObjExtract (const char* Name)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (Obj) != 0) {
|
||||
Error ("Problem closing object file `%s': %s", Name, strerror (errno));
|
||||
Error ("Problem closing object file `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Set access and modification time */
|
||||
if (SetFileTimes (Name, O->MTime) != 0) {
|
||||
Error ("Cannot set mod time on `%s': %s", Name, strerror (errno));
|
||||
Error ("Cannot set mod time on `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objfile.h */
|
||||
/* objfile.h */
|
||||
/* */
|
||||
/* Object file handling for the ar65 archiver */
|
||||
/* Object file handling for the ar65 archiver */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -53,7 +53,7 @@ struct ObjData;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* anonname.c */
|
||||
/* anonname.c */
|
||||
/* */
|
||||
/* Create names for anonymous scopes/variables/types */
|
||||
/* */
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ static const char AnonTag[] = "$anon";
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* anonname.h */
|
||||
/* anonname.h */
|
||||
/* */
|
||||
/* Create names for anonymous scopes/variables/types */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ static Collection Assertions = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ struct ExprNode;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* condasm.c */
|
||||
/* condasm.c */
|
||||
/* */
|
||||
/* Conditional assembly support for ca65 */
|
||||
/* Conditional assembly support for ca65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,21 +46,21 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Maximum count of nested .ifs */
|
||||
#define MAX_IFS 256
|
||||
#define MAX_IFS 256
|
||||
|
||||
/* Set of bitmapped flags for the if descriptor */
|
||||
enum {
|
||||
ifNone = 0x0000, /* No flag */
|
||||
ifCond = 0x0001, /* IF condition was true */
|
||||
ifNone = 0x0000, /* No flag */
|
||||
ifCond = 0x0001, /* IF condition was true */
|
||||
ifParentCond= 0x0002, /* IF condition of parent */
|
||||
ifElse = 0x0004, /* We had a .ELSE branch */
|
||||
ifNeedTerm = 0x0008, /* Need .ENDIF termination */
|
||||
ifElse = 0x0004, /* We had a .ELSE branch */
|
||||
ifNeedTerm = 0x0008, /* Need .ENDIF termination */
|
||||
};
|
||||
|
||||
/* The overall .IF condition */
|
||||
@@ -69,7 +69,7 @@ int IfCond = 1;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* struct IfDesc */
|
||||
/* struct IfDesc */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -77,9 +77,9 @@ int IfCond = 1;
|
||||
/* One .IF descriptor */
|
||||
typedef struct IfDesc IfDesc;
|
||||
struct IfDesc {
|
||||
unsigned Flags; /* Bitmapped flags, see above */
|
||||
unsigned Flags; /* Bitmapped flags, see above */
|
||||
Collection LineInfos; /* File position of the .IF */
|
||||
const char* Name; /* Name of the directive */
|
||||
const char* Name; /* Name of the directive */
|
||||
};
|
||||
|
||||
/* The .IF stack */
|
||||
@@ -92,7 +92,7 @@ static IfDesc* GetCurrentIf (void)
|
||||
/* Return the current .IF descriptor */
|
||||
{
|
||||
if (IfCount == 0) {
|
||||
return 0;
|
||||
return 0;
|
||||
} else {
|
||||
return &IfStack[IfCount-1];
|
||||
}
|
||||
@@ -125,9 +125,9 @@ static void SetIfCond (IfDesc* ID, int C)
|
||||
/* Set the .IF condition */
|
||||
{
|
||||
if (C) {
|
||||
ID->Flags |= ifCond;
|
||||
ID->Flags |= ifCond;
|
||||
} else {
|
||||
ID->Flags &= ~ifCond;
|
||||
ID->Flags &= ~ifCond;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ static IfDesc* AllocIf (const char* Directive, int NeedTerm)
|
||||
|
||||
/* Check for stack overflow */
|
||||
if (IfCount >= MAX_IFS) {
|
||||
Fatal ("Too many nested .IFs");
|
||||
Fatal ("Too many nested .IFs");
|
||||
}
|
||||
|
||||
/* Get the next element */
|
||||
@@ -192,23 +192,23 @@ static void FreeIf (void)
|
||||
{
|
||||
int Done;
|
||||
do {
|
||||
IfDesc* ID = GetCurrentIf();
|
||||
if (ID == 0) {
|
||||
Error (" Unexpected .ENDIF");
|
||||
Done = 1;
|
||||
} else {
|
||||
Done = (ID->Flags & ifNeedTerm) != 0;
|
||||
IfDesc* ID = GetCurrentIf();
|
||||
if (ID == 0) {
|
||||
Error (" Unexpected .ENDIF");
|
||||
Done = 1;
|
||||
} else {
|
||||
Done = (ID->Flags & ifNeedTerm) != 0;
|
||||
ReleaseFullLineInfo (&ID->LineInfos);
|
||||
DoneCollection (&ID->LineInfos);
|
||||
--IfCount;
|
||||
}
|
||||
}
|
||||
} while (!Done);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -220,10 +220,10 @@ void DoConditionals (void)
|
||||
|
||||
do {
|
||||
|
||||
switch (CurTok.Tok) {
|
||||
switch (CurTok.Tok) {
|
||||
|
||||
case TOK_ELSE:
|
||||
D = GetCurrentIf ();
|
||||
case TOK_ELSE:
|
||||
D = GetCurrentIf ();
|
||||
|
||||
/* Allow an .ELSE */
|
||||
ElseClause (D, ".ELSE");
|
||||
@@ -239,12 +239,12 @@ void DoConditionals (void)
|
||||
CalcOverallIfCond ();
|
||||
|
||||
/* Skip .ELSE */
|
||||
NextTok ();
|
||||
ExpectSep ();
|
||||
break;
|
||||
NextTok ();
|
||||
ExpectSep ();
|
||||
break;
|
||||
|
||||
case TOK_ELSEIF:
|
||||
D = GetCurrentIf ();
|
||||
case TOK_ELSEIF:
|
||||
D = GetCurrentIf ();
|
||||
/* Handle as if there was an .ELSE first */
|
||||
ElseClause (D, ".ELSEIF");
|
||||
|
||||
@@ -266,172 +266,172 @@ void DoConditionals (void)
|
||||
|
||||
/* Get the new overall condition */
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_ENDIF:
|
||||
/* We're done with this .IF.. - remove the descriptor(s) */
|
||||
FreeIf ();
|
||||
case TOK_ENDIF:
|
||||
/* We're done with this .IF.. - remove the descriptor(s) */
|
||||
FreeIf ();
|
||||
|
||||
/* Be sure not to read the next token until the .IF stack
|
||||
* has been cleanup up, since we may be at end of file.
|
||||
*/
|
||||
NextTok ();
|
||||
ExpectSep ();
|
||||
/* Be sure not to read the next token until the .IF stack
|
||||
* has been cleanup up, since we may be at end of file.
|
||||
*/
|
||||
NextTok ();
|
||||
ExpectSep ();
|
||||
|
||||
/* Get the new overall condition */
|
||||
/* Get the new overall condition */
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IF:
|
||||
D = AllocIf (".IF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
case TOK_IF:
|
||||
D = AllocIf (".IF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, ConstExpression ());
|
||||
ExpectSep ();
|
||||
}
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFBLANK:
|
||||
D = AllocIf (".IFBLANK", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
case TOK_IFBLANK:
|
||||
D = AllocIf (".IFBLANK", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
SetIfCond (D, 1);
|
||||
} else {
|
||||
SetIfCond (D, 0);
|
||||
SetIfCond (D, 0);
|
||||
SkipUntilSep ();
|
||||
}
|
||||
}
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFCONST:
|
||||
D = AllocIf (".IFCONST", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
ExprNode* Expr = Expression();
|
||||
SetIfCond (D, IsConstExpr (Expr, 0));
|
||||
FreeExpr (Expr);
|
||||
ExpectSep ();
|
||||
}
|
||||
case TOK_IFCONST:
|
||||
D = AllocIf (".IFCONST", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
ExprNode* Expr = Expression();
|
||||
SetIfCond (D, IsConstExpr (Expr, 0));
|
||||
FreeExpr (Expr);
|
||||
ExpectSep ();
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFDEF:
|
||||
D = AllocIf (".IFDEF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym != 0 && SymIsDef (Sym));
|
||||
}
|
||||
case TOK_IFDEF:
|
||||
D = AllocIf (".IFDEF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym != 0 && SymIsDef (Sym));
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFNBLANK:
|
||||
D = AllocIf (".IFNBLANK", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
case TOK_IFNBLANK:
|
||||
D = AllocIf (".IFNBLANK", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
SetIfCond (D, 0);
|
||||
} else {
|
||||
SetIfCond (D, 1);
|
||||
SetIfCond (D, 1);
|
||||
SkipUntilSep ();
|
||||
}
|
||||
}
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFNCONST:
|
||||
D = AllocIf (".IFNCONST", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
ExprNode* Expr = Expression();
|
||||
SetIfCond (D, !IsConstExpr (Expr, 0));
|
||||
FreeExpr (Expr);
|
||||
ExpectSep ();
|
||||
}
|
||||
case TOK_IFNCONST:
|
||||
D = AllocIf (".IFNCONST", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
ExprNode* Expr = Expression();
|
||||
SetIfCond (D, !IsConstExpr (Expr, 0));
|
||||
FreeExpr (Expr);
|
||||
ExpectSep ();
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFNDEF:
|
||||
D = AllocIf (".IFNDEF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
|
||||
ExpectSep ();
|
||||
}
|
||||
case TOK_IFNDEF:
|
||||
D = AllocIf (".IFNDEF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
|
||||
ExpectSep ();
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFNREF:
|
||||
D = AllocIf (".IFNREF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
|
||||
ExpectSep ();
|
||||
}
|
||||
case TOK_IFNREF:
|
||||
D = AllocIf (".IFNREF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
|
||||
ExpectSep ();
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFP02:
|
||||
D = AllocIf (".IFP02", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_6502);
|
||||
}
|
||||
ExpectSep ();
|
||||
case TOK_IFP02:
|
||||
D = AllocIf (".IFP02", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_6502);
|
||||
}
|
||||
ExpectSep ();
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFP816:
|
||||
D = AllocIf (".IFP816", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_65816);
|
||||
}
|
||||
ExpectSep ();
|
||||
case TOK_IFP816:
|
||||
D = AllocIf (".IFP816", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_65816);
|
||||
}
|
||||
ExpectSep ();
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFPC02:
|
||||
D = AllocIf (".IFPC02", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_65C02);
|
||||
}
|
||||
ExpectSep ();
|
||||
case TOK_IFPC02:
|
||||
D = AllocIf (".IFPC02", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_65C02);
|
||||
}
|
||||
ExpectSep ();
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFPSC02:
|
||||
D = AllocIf (".IFPSC02", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_65SC02);
|
||||
}
|
||||
ExpectSep ();
|
||||
case TOK_IFPSC02:
|
||||
D = AllocIf (".IFPSC02", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_65SC02);
|
||||
}
|
||||
ExpectSep ();
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_IFREF:
|
||||
D = AllocIf (".IFREF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym != 0 && SymIsRef (Sym));
|
||||
ExpectSep ();
|
||||
}
|
||||
case TOK_IFREF:
|
||||
D = AllocIf (".IFREF", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||
SetIfCond (D, Sym != 0 && SymIsRef (Sym));
|
||||
ExpectSep ();
|
||||
}
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Skip tokens */
|
||||
NextTok ();
|
||||
default:
|
||||
/* Skip tokens */
|
||||
NextTok ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} while (IfCond == 0 && CurTok.Tok != TOK_EOF);
|
||||
}
|
||||
@@ -479,24 +479,24 @@ void CheckOpenIfs (void)
|
||||
const LineInfo* LI;
|
||||
|
||||
while (1) {
|
||||
/* Get the current file number and check if the topmost entry on the
|
||||
* .IF stack was inserted with this file number
|
||||
*/
|
||||
IfDesc* D = GetCurrentIf ();
|
||||
if (D == 0) {
|
||||
/* There are no open .IFs */
|
||||
break;
|
||||
}
|
||||
/* Get the current file number and check if the topmost entry on the
|
||||
* .IF stack was inserted with this file number
|
||||
*/
|
||||
IfDesc* D = GetCurrentIf ();
|
||||
if (D == 0) {
|
||||
/* There are no open .IFs */
|
||||
break;
|
||||
}
|
||||
|
||||
LI = CollConstAt (&D->LineInfos, 0);
|
||||
if (GetSourcePos (LI)->Name != CurTok.Pos.Name) {
|
||||
/* The .if is from another file, bail out */
|
||||
break;
|
||||
}
|
||||
if (GetSourcePos (LI)->Name != CurTok.Pos.Name) {
|
||||
/* The .if is from another file, bail out */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start of .if is in the file we're about to leave */
|
||||
LIError (&D->LineInfos, "Conditional assembly branch was never closed");
|
||||
FreeIf ();
|
||||
/* Start of .if is in the file we're about to leave */
|
||||
LIError (&D->LineInfos, "Conditional assembly branch was never closed");
|
||||
FreeIf ();
|
||||
}
|
||||
|
||||
/* Calculate the new overall .IF condition */
|
||||
@@ -517,7 +517,7 @@ void CleanupIfStack (unsigned SP)
|
||||
/* Cleanup the .IF stack, remove anything above the given stack pointer */
|
||||
{
|
||||
while (IfCount > SP) {
|
||||
FreeIf ();
|
||||
FreeIf ();
|
||||
}
|
||||
|
||||
/* Calculate the new overall .IF condition */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* condasm.h */
|
||||
/* condasm.h */
|
||||
/* */
|
||||
/* Conditional assembly support for ca65 */
|
||||
/* Conditional assembly support for ca65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -50,7 +50,7 @@ extern int IfCond;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dbginfo.c */
|
||||
/* dbginfo.c */
|
||||
/* */
|
||||
/* Handle the .dbg commands */
|
||||
/* Handle the .dbg commands */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -181,8 +181,8 @@ void DbgInfoFile (void)
|
||||
|
||||
/* Name */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
}
|
||||
SB_Copy (&Name, &CurTok.SVal);
|
||||
NextTok ();
|
||||
@@ -212,8 +212,8 @@ void DbgInfoFunc (void)
|
||||
/* Parse and handle func subcommand of the .dbg pseudo instruction */
|
||||
{
|
||||
static const char* StorageKeys[] = {
|
||||
"EXTERN",
|
||||
"STATIC",
|
||||
"EXTERN",
|
||||
"STATIC",
|
||||
};
|
||||
|
||||
unsigned Name;
|
||||
@@ -228,8 +228,8 @@ void DbgInfoFunc (void)
|
||||
|
||||
/* Name */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
}
|
||||
Name = GetStrBufId (&CurTok.SVal);
|
||||
NextTok ();
|
||||
@@ -239,8 +239,8 @@ void DbgInfoFunc (void)
|
||||
|
||||
/* Type */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
}
|
||||
Type = ValidateType (&CurTok.SVal);
|
||||
if (Type < 0) {
|
||||
@@ -253,8 +253,8 @@ void DbgInfoFunc (void)
|
||||
|
||||
/* The storage class follows */
|
||||
if (CurTok.Tok != TOK_IDENT) {
|
||||
ErrorSkip ("Storage class specifier expected");
|
||||
return;
|
||||
ErrorSkip ("Storage class specifier expected");
|
||||
return;
|
||||
}
|
||||
switch (GetSubKey (StorageKeys, sizeof (StorageKeys)/sizeof (StorageKeys[0]))) {
|
||||
case 0: Flags = HLL_TYPE_FUNC | HLL_SC_EXTERN; break;
|
||||
@@ -314,7 +314,7 @@ void DbgInfoLine (void)
|
||||
* follow, the last line info is terminated.
|
||||
*/
|
||||
if (CurTok.Tok == TOK_SEP) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parameters are separated by a comma */
|
||||
@@ -322,8 +322,8 @@ void DbgInfoLine (void)
|
||||
|
||||
/* The name of the file follows */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the index in the file table for the name */
|
||||
@@ -338,8 +338,8 @@ void DbgInfoLine (void)
|
||||
/* Line number */
|
||||
Line = ConstExpression ();
|
||||
if (Line < 0) {
|
||||
ErrorSkip ("Line number is out of valid range");
|
||||
return;
|
||||
ErrorSkip ("Line number is out of valid range");
|
||||
return;
|
||||
}
|
||||
Pos.Line = Line;
|
||||
|
||||
@@ -354,9 +354,9 @@ void DbgInfoSym (void)
|
||||
{
|
||||
static const char* StorageKeys[] = {
|
||||
"AUTO",
|
||||
"EXTERN",
|
||||
"EXTERN",
|
||||
"REGISTER",
|
||||
"STATIC",
|
||||
"STATIC",
|
||||
};
|
||||
|
||||
unsigned Name;
|
||||
@@ -372,8 +372,8 @@ void DbgInfoSym (void)
|
||||
|
||||
/* Name */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
}
|
||||
Name = GetStrBufId (&CurTok.SVal);
|
||||
NextTok ();
|
||||
@@ -383,8 +383,8 @@ void DbgInfoSym (void)
|
||||
|
||||
/* Type */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
ErrorSkip ("String constant expected");
|
||||
return;
|
||||
}
|
||||
Type = ValidateType (&CurTok.SVal);
|
||||
if (Type < 0) {
|
||||
@@ -397,8 +397,8 @@ void DbgInfoSym (void)
|
||||
|
||||
/* The storage class follows */
|
||||
if (CurTok.Tok != TOK_IDENT) {
|
||||
ErrorSkip ("Storage class specifier expected");
|
||||
return;
|
||||
ErrorSkip ("Storage class specifier expected");
|
||||
return;
|
||||
}
|
||||
switch (GetSubKey (StorageKeys, sizeof (StorageKeys)/sizeof (StorageKeys[0]))) {
|
||||
case 0: Flags = HLL_SC_AUTO; break;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dbginfo.h */
|
||||
/* dbginfo.h */
|
||||
/* */
|
||||
/* Handle the .dbg commands */
|
||||
/* Handle the .dbg commands */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -34,12 +34,12 @@
|
||||
|
||||
|
||||
#ifndef DBGINFO_H
|
||||
#define DBGINFO_H
|
||||
#define DBGINFO_H
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* ea65.h */
|
||||
/* ea65.h */
|
||||
/* */
|
||||
/* Effective address structure definition */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
128
src/ca65/ea65.c
128
src/ca65/ea65.c
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* ea65.c */
|
||||
/* ea65.c */
|
||||
/* */
|
||||
/* 65XX effective address parsing for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -83,87 +83,87 @@ void GetEA (EffAddr* A)
|
||||
/* Parse the effective address */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
|
||||
A->AddrModeSet = AM65_IMPLICIT;
|
||||
A->AddrModeSet = AM65_IMPLICIT;
|
||||
|
||||
} else if (CurTok.Tok == TOK_HASH) {
|
||||
|
||||
/* #val */
|
||||
NextTok ();
|
||||
A->Expr = Expression ();
|
||||
A->AddrModeSet = AM65_ALL_IMM;
|
||||
/* #val */
|
||||
NextTok ();
|
||||
A->Expr = Expression ();
|
||||
A->AddrModeSet = AM65_ALL_IMM;
|
||||
|
||||
} else if (CurTok.Tok == TOK_A) {
|
||||
|
||||
NextTok ();
|
||||
A->AddrModeSet = AM65_ACCU;
|
||||
NextTok ();
|
||||
A->AddrModeSet = AM65_ACCU;
|
||||
|
||||
} else if (CurTok.Tok == TOK_LBRACK) {
|
||||
|
||||
/* [dir] or [dir],y */
|
||||
NextTok ();
|
||||
A->Expr = Expression ();
|
||||
Consume (TOK_RBRACK, "']' expected");
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
/* [dir],y */
|
||||
NextTok ();
|
||||
Consume (TOK_Y, "`Y' expected");
|
||||
A->AddrModeSet = AM65_DIR_IND_LONG_Y;
|
||||
} else {
|
||||
/* [dir] */
|
||||
A->AddrModeSet = AM65_DIR_IND_LONG;
|
||||
}
|
||||
/* [dir] or [dir],y */
|
||||
NextTok ();
|
||||
A->Expr = Expression ();
|
||||
Consume (TOK_RBRACK, "']' expected");
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
/* [dir],y */
|
||||
NextTok ();
|
||||
Consume (TOK_Y, "`Y' expected");
|
||||
A->AddrModeSet = AM65_DIR_IND_LONG_Y;
|
||||
} else {
|
||||
/* [dir] */
|
||||
A->AddrModeSet = AM65_DIR_IND_LONG;
|
||||
}
|
||||
|
||||
} else if (CurTok.Tok == TOK_LPAREN) {
|
||||
|
||||
/* One of the indirect modes */
|
||||
NextTok ();
|
||||
A->Expr = Expression ();
|
||||
/* One of the indirect modes */
|
||||
NextTok ();
|
||||
A->Expr = Expression ();
|
||||
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
|
||||
/* (expr,X) or (rel,S),y */
|
||||
NextTok ();
|
||||
if (CurTok.Tok == TOK_X) {
|
||||
/* (adr,x) */
|
||||
NextTok ();
|
||||
A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
|
||||
ConsumeRParen ();
|
||||
} else if (CurTok.Tok == TOK_S) {
|
||||
/* (rel,s),y */
|
||||
NextTok ();
|
||||
A->AddrModeSet = AM65_STACK_REL_IND_Y;
|
||||
ConsumeRParen ();
|
||||
ConsumeComma ();
|
||||
Consume (TOK_Y, "`Y' expected");
|
||||
} else {
|
||||
Error ("Syntax error");
|
||||
}
|
||||
/* (expr,X) or (rel,S),y */
|
||||
NextTok ();
|
||||
if (CurTok.Tok == TOK_X) {
|
||||
/* (adr,x) */
|
||||
NextTok ();
|
||||
A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
|
||||
ConsumeRParen ();
|
||||
} else if (CurTok.Tok == TOK_S) {
|
||||
/* (rel,s),y */
|
||||
NextTok ();
|
||||
A->AddrModeSet = AM65_STACK_REL_IND_Y;
|
||||
ConsumeRParen ();
|
||||
ConsumeComma ();
|
||||
Consume (TOK_Y, "`Y' expected");
|
||||
} else {
|
||||
Error ("Syntax error");
|
||||
}
|
||||
|
||||
} else {
|
||||
} else {
|
||||
|
||||
/* (adr) or (adr),y */
|
||||
ConsumeRParen ();
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
/* (adr),y */
|
||||
NextTok ();
|
||||
Consume (TOK_Y, "`Y' expected");
|
||||
A->AddrModeSet = AM65_DIR_IND_Y;
|
||||
} else {
|
||||
/* (adr) */
|
||||
A->AddrModeSet = AM65_ABS_IND | AM65_DIR_IND;
|
||||
}
|
||||
}
|
||||
/* (adr) or (adr),y */
|
||||
ConsumeRParen ();
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
/* (adr),y */
|
||||
NextTok ();
|
||||
Consume (TOK_Y, "`Y' expected");
|
||||
A->AddrModeSet = AM65_DIR_IND_Y;
|
||||
} else {
|
||||
/* (adr) */
|
||||
A->AddrModeSet = AM65_ABS_IND | AM65_DIR_IND;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Remaining stuff:
|
||||
*
|
||||
* adr
|
||||
* adr,x
|
||||
* adr,y
|
||||
* adr,s
|
||||
*/
|
||||
A->Expr = Expression ();
|
||||
/* Remaining stuff:
|
||||
*
|
||||
* adr
|
||||
* adr,x
|
||||
* adr,y
|
||||
* adr,s
|
||||
*/
|
||||
A->Expr = Expression ();
|
||||
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* ea65.h */
|
||||
/* ea65.h */
|
||||
/* */
|
||||
/* 65XX effective address parsing for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@ struct EffAddr;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* easw16.c */
|
||||
/* easw16.c */
|
||||
/* */
|
||||
/* SWEET16 effective address parsing for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -82,13 +82,13 @@ void GetSweet16EA (EffAddr* A)
|
||||
/* Parse the effective address */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
|
||||
A->AddrModeSet = AMSW16_IMP;
|
||||
A->AddrModeSet = AMSW16_IMP;
|
||||
|
||||
} else if (CurTok.Tok == TOK_AT) {
|
||||
|
||||
/* @reg or @regnumber */
|
||||
A->AddrModeSet = AMSW16_IND;
|
||||
NextTok ();
|
||||
/* @reg or @regnumber */
|
||||
A->AddrModeSet = AMSW16_IND;
|
||||
NextTok ();
|
||||
if (CurTok.Tok == TOK_REG) {
|
||||
A->Reg = (unsigned) CurTok.IVal;
|
||||
NextTok ();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* easw16.h */
|
||||
/* easw16.h */
|
||||
/* */
|
||||
/* SWEET16 effective address parsing for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@ struct EffAddr;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* error.c */
|
||||
/* error.c */
|
||||
/* */
|
||||
/* Error handling for the ca65 macroassembler */
|
||||
/* Error handling for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,17 +49,17 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Warning level */
|
||||
unsigned WarnLevel = 1;
|
||||
unsigned WarnLevel = 1;
|
||||
|
||||
/* Statistics */
|
||||
unsigned ErrorCount = 0;
|
||||
unsigned WarningCount = 0;
|
||||
unsigned ErrorCount = 0;
|
||||
unsigned WarningCount = 0;
|
||||
|
||||
/* Maximum number of additional notifications */
|
||||
#define MAX_NOTES 8
|
||||
@@ -184,7 +184,7 @@ static void AddNotifications (const Collection* LineInfos)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Warnings */
|
||||
/* Warnings */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Errors */
|
||||
/* Errors */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ void ErrorSkip (const char* Format, ...)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* error.h */
|
||||
/* error.h */
|
||||
/* */
|
||||
/* Error handling for the ca65 macroassembler */
|
||||
/* Error handling for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ extern unsigned WarningCount;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
448
src/ca65/expr.c
448
src/ca65/expr.c
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* expr.c */
|
||||
/* expr.c */
|
||||
/* */
|
||||
/* Expression evaluation for the ca65 macroassembler */
|
||||
/* Expression evaluation for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -77,14 +77,14 @@
|
||||
* number of freed nodes for later and remember them in a single linked list
|
||||
* using the Left link.
|
||||
*/
|
||||
#define MAX_FREE_NODES 64
|
||||
static ExprNode* FreeExprNodes = 0;
|
||||
static unsigned FreeNodeCount = 0;
|
||||
#define MAX_FREE_NODES 64
|
||||
static ExprNode* FreeExprNodes = 0;
|
||||
static unsigned FreeNodeCount = 0;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Helpers */
|
||||
/* Helpers */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -96,12 +96,12 @@ static ExprNode* NewExprNode (unsigned Op)
|
||||
|
||||
/* Do we have some nodes in the list already? */
|
||||
if (FreeNodeCount) {
|
||||
/* Use first node from list */
|
||||
N = FreeExprNodes;
|
||||
FreeExprNodes = N->Left;
|
||||
/* Use first node from list */
|
||||
N = FreeExprNodes;
|
||||
FreeExprNodes = N->Left;
|
||||
--FreeNodeCount;
|
||||
} else {
|
||||
/* Allocate fresh memory */
|
||||
/* Allocate fresh memory */
|
||||
N = xmalloc (sizeof (ExprNode));
|
||||
}
|
||||
N->Op = Op;
|
||||
@@ -122,22 +122,22 @@ static void FreeExprNode (ExprNode* E)
|
||||
SymDelExprRef (E->V.Sym, E);
|
||||
}
|
||||
/* Place the symbol into the free nodes list if possible */
|
||||
if (FreeNodeCount < MAX_FREE_NODES) {
|
||||
/* Remember this node for later */
|
||||
E->Left = FreeExprNodes;
|
||||
FreeExprNodes = E;
|
||||
if (FreeNodeCount < MAX_FREE_NODES) {
|
||||
/* Remember this node for later */
|
||||
E->Left = FreeExprNodes;
|
||||
FreeExprNodes = E;
|
||||
++FreeNodeCount;
|
||||
} else {
|
||||
/* Free the memory */
|
||||
xfree (E);
|
||||
}
|
||||
} else {
|
||||
/* Free the memory */
|
||||
xfree (E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -361,19 +361,19 @@ static ExprNode* FuncBlank (void)
|
||||
unsigned Count = 0;
|
||||
while (CurTok.Tok != Term) {
|
||||
|
||||
/* Check for end of line or end of input. Since the calling function
|
||||
* will check for the closing paren, we don't need to print an error
|
||||
* here, just bail out.
|
||||
*/
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
break;
|
||||
}
|
||||
/* Check for end of line or end of input. Since the calling function
|
||||
* will check for the closing paren, we don't need to print an error
|
||||
* here, just bail out.
|
||||
*/
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* One more token */
|
||||
++Count;
|
||||
/* One more token */
|
||||
++Count;
|
||||
|
||||
/* Skip the token */
|
||||
NextTok ();
|
||||
/* Skip the token */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* If the list was enclosed in curly braces, skip the closing brace */
|
||||
@@ -464,25 +464,25 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
|
||||
token_t Term = GetTokListTerm (TOK_COMMA);
|
||||
while (CurTok.Tok != Term) {
|
||||
|
||||
/* We may not end-of-line of end-of-file here */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
Error ("Unexpected end of line");
|
||||
return GenLiteral0 ();
|
||||
}
|
||||
/* We may not end-of-line of end-of-file here */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
Error ("Unexpected end of line");
|
||||
return GenLiteral0 ();
|
||||
}
|
||||
|
||||
/* Get a node with this token */
|
||||
Node = NewTokNode ();
|
||||
/* Get a node with this token */
|
||||
Node = NewTokNode ();
|
||||
|
||||
/* Insert the node into the list */
|
||||
if (Last == 0) {
|
||||
Root = Node;
|
||||
} else {
|
||||
Last->Next = Node;
|
||||
}
|
||||
Last = Node;
|
||||
/* Insert the node into the list */
|
||||
if (Last == 0) {
|
||||
Root = Node;
|
||||
} else {
|
||||
Last->Next = Node;
|
||||
}
|
||||
Last = Node;
|
||||
|
||||
/* Skip the token */
|
||||
NextTok ();
|
||||
/* Skip the token */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Skip the terminator token*/
|
||||
@@ -502,30 +502,30 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
|
||||
Node = Root;
|
||||
while (CurTok.Tok != Term) {
|
||||
|
||||
/* We may not end-of-line of end-of-file here */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
Error ("Unexpected end of line");
|
||||
return GenLiteral0 ();
|
||||
}
|
||||
/* We may not end-of-line of end-of-file here */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
Error ("Unexpected end of line");
|
||||
return GenLiteral0 ();
|
||||
}
|
||||
|
||||
/* Compare the tokens if the result is not already known */
|
||||
if (Result != 0) {
|
||||
if (Node == 0) {
|
||||
/* The second list is larger than the first one */
|
||||
Result = 0;
|
||||
} else if (TokCmp (Node) < EqualityLevel) {
|
||||
/* Tokens do not match */
|
||||
Result = 0;
|
||||
}
|
||||
}
|
||||
/* Compare the tokens if the result is not already known */
|
||||
if (Result != 0) {
|
||||
if (Node == 0) {
|
||||
/* The second list is larger than the first one */
|
||||
Result = 0;
|
||||
} else if (TokCmp (Node) < EqualityLevel) {
|
||||
/* Tokens do not match */
|
||||
Result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Next token in first list */
|
||||
if (Node) {
|
||||
Node = Node->Next;
|
||||
}
|
||||
/* Next token in first list */
|
||||
if (Node) {
|
||||
Node = Node->Next;
|
||||
}
|
||||
|
||||
/* Next token in current list */
|
||||
NextTok ();
|
||||
/* Next token in current list */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* If the token list was enclosed in curly braces, eat the closing brace */
|
||||
@@ -535,14 +535,14 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
|
||||
|
||||
/* Check if there are remaining tokens in the first list */
|
||||
if (Node != 0) {
|
||||
Result = 0;
|
||||
Result = 0;
|
||||
}
|
||||
|
||||
/* Free the token list */
|
||||
while (Root) {
|
||||
Node = Root;
|
||||
Root = Root->Next;
|
||||
FreeTokNode (Node);
|
||||
Node = Root;
|
||||
Root = Root->Next;
|
||||
FreeTokNode (Node);
|
||||
}
|
||||
|
||||
/* Done, return the result */
|
||||
@@ -733,9 +733,9 @@ static ExprNode* FuncStrAt (void)
|
||||
|
||||
/* String constant expected */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
Error ("String constant expected");
|
||||
NextTok ();
|
||||
goto ExitPoint;
|
||||
Error ("String constant expected");
|
||||
NextTok ();
|
||||
goto ExitPoint;
|
||||
}
|
||||
|
||||
/* Remember the string and skip it */
|
||||
@@ -750,7 +750,7 @@ static ExprNode* FuncStrAt (void)
|
||||
|
||||
/* Must be a valid index */
|
||||
if (Index >= (long) SB_GetLen (&Str)) {
|
||||
Error ("Range error");
|
||||
Error ("Range error");
|
||||
goto ExitPoint;
|
||||
}
|
||||
|
||||
@@ -777,20 +777,20 @@ static ExprNode* FuncStrLen (void)
|
||||
/* String constant expected */
|
||||
if (CurTok.Tok != TOK_STRCON) {
|
||||
|
||||
Error ("String constant expected");
|
||||
/* Smart error recovery */
|
||||
if (CurTok.Tok != TOK_RPAREN) {
|
||||
NextTok ();
|
||||
}
|
||||
Len = 0;
|
||||
Error ("String constant expected");
|
||||
/* Smart error recovery */
|
||||
if (CurTok.Tok != TOK_RPAREN) {
|
||||
NextTok ();
|
||||
}
|
||||
Len = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Get the length of the string */
|
||||
Len = SB_GetLen (&CurTok.SVal);
|
||||
Len = SB_GetLen (&CurTok.SVal);
|
||||
|
||||
/* Skip the string */
|
||||
NextTok ();
|
||||
/* Skip the string */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Return the length */
|
||||
@@ -809,19 +809,19 @@ static ExprNode* FuncTCount (void)
|
||||
int Count = 0;
|
||||
while (CurTok.Tok != Term) {
|
||||
|
||||
/* Check for end of line or end of input. Since the calling function
|
||||
* will check for the closing paren, we don't need to print an error
|
||||
* here, just bail out.
|
||||
*/
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
break;
|
||||
}
|
||||
/* Check for end of line or end of input. Since the calling function
|
||||
* will check for the closing paren, we don't need to print an error
|
||||
* here, just bail out.
|
||||
*/
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* One more token */
|
||||
++Count;
|
||||
/* One more token */
|
||||
++Count;
|
||||
|
||||
/* Skip the token */
|
||||
NextTok ();
|
||||
/* Skip the token */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* If the list was enclosed in curly braces, skip the closing brace */
|
||||
@@ -853,9 +853,9 @@ static ExprNode* Function (ExprNode* (*F) (void))
|
||||
|
||||
/* Expression must be enclosed in braces */
|
||||
if (CurTok.Tok != TOK_LPAREN) {
|
||||
Error ("'(' expected");
|
||||
SkipUntilSep ();
|
||||
return GenLiteral0 ();
|
||||
Error ("'(' expected");
|
||||
SkipUntilSep ();
|
||||
return GenLiteral0 ();
|
||||
}
|
||||
NextTok ();
|
||||
|
||||
@@ -879,46 +879,46 @@ static ExprNode* Factor (void)
|
||||
|
||||
switch (CurTok.Tok) {
|
||||
|
||||
case TOK_INTCON:
|
||||
N = GenLiteralExpr (CurTok.IVal);
|
||||
NextTok ();
|
||||
break;
|
||||
case TOK_INTCON:
|
||||
N = GenLiteralExpr (CurTok.IVal);
|
||||
NextTok ();
|
||||
break;
|
||||
|
||||
case TOK_CHARCON:
|
||||
N = GenLiteralExpr (TgtTranslateChar (CurTok.IVal));
|
||||
NextTok ();
|
||||
break;
|
||||
case TOK_CHARCON:
|
||||
N = GenLiteralExpr (TgtTranslateChar (CurTok.IVal));
|
||||
NextTok ();
|
||||
break;
|
||||
|
||||
case TOK_NAMESPACE:
|
||||
case TOK_IDENT:
|
||||
case TOK_NAMESPACE:
|
||||
case TOK_IDENT:
|
||||
case TOK_LOCAL_IDENT:
|
||||
N = Symbol (ParseAnySymName (SYM_ALLOC_NEW));
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_ULABEL:
|
||||
N = ULabRef (CurTok.IVal);
|
||||
NextTok ();
|
||||
break;
|
||||
case TOK_ULABEL:
|
||||
N = ULabRef (CurTok.IVal);
|
||||
NextTok ();
|
||||
break;
|
||||
|
||||
case TOK_PLUS:
|
||||
NextTok ();
|
||||
N = Factor ();
|
||||
break;
|
||||
|
||||
case TOK_MINUS:
|
||||
NextTok ();
|
||||
case TOK_MINUS:
|
||||
NextTok ();
|
||||
L = Factor ();
|
||||
if (IsEasyConst (L, &Val)) {
|
||||
FreeExpr (L);
|
||||
N = GenLiteralExpr (-Val);
|
||||
} else {
|
||||
N = NewExprNode (EXPR_UNARY_MINUS);
|
||||
N->Left = L;
|
||||
N->Left = L;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_NOT:
|
||||
NextTok ();
|
||||
case TOK_NOT:
|
||||
NextTok ();
|
||||
L = Factor ();
|
||||
if (IsEasyConst (L, &Val)) {
|
||||
FreeExpr (L);
|
||||
@@ -927,23 +927,23 @@ static ExprNode* Factor (void)
|
||||
N = NewExprNode (EXPR_NOT);
|
||||
N->Left = L;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_STAR:
|
||||
case TOK_PC:
|
||||
NextTok ();
|
||||
N = GenCurrentPC ();
|
||||
break;
|
||||
case TOK_STAR:
|
||||
case TOK_PC:
|
||||
NextTok ();
|
||||
N = GenCurrentPC ();
|
||||
break;
|
||||
|
||||
case TOK_LT:
|
||||
NextTok ();
|
||||
case TOK_LT:
|
||||
NextTok ();
|
||||
N = LoByte (Factor ());
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_GT:
|
||||
NextTok ();
|
||||
case TOK_GT:
|
||||
NextTok ();
|
||||
N = HiByte (Factor ());
|
||||
break;
|
||||
break;
|
||||
|
||||
case TOK_XOR:
|
||||
/* ^ means the bank byte of an expression */
|
||||
@@ -951,11 +951,11 @@ static ExprNode* Factor (void)
|
||||
N = BankByte (Factor ());
|
||||
break;
|
||||
|
||||
case TOK_LPAREN:
|
||||
NextTok ();
|
||||
N = Expr0 ();
|
||||
ConsumeRParen ();
|
||||
break;
|
||||
case TOK_LPAREN:
|
||||
NextTok ();
|
||||
N = Expr0 ();
|
||||
ConsumeRParen ();
|
||||
break;
|
||||
|
||||
case TOK_BANK:
|
||||
N = Function (FuncBank);
|
||||
@@ -966,21 +966,21 @@ static ExprNode* Factor (void)
|
||||
break;
|
||||
|
||||
case TOK_BLANK:
|
||||
N = Function (FuncBlank);
|
||||
break;
|
||||
N = Function (FuncBlank);
|
||||
break;
|
||||
|
||||
case TOK_CONST:
|
||||
N = Function (FuncConst);
|
||||
break;
|
||||
case TOK_CONST:
|
||||
N = Function (FuncConst);
|
||||
break;
|
||||
|
||||
case TOK_CPU:
|
||||
N = GenLiteralExpr (CPUIsets[CPU]);
|
||||
NextTok ();
|
||||
break;
|
||||
case TOK_CPU:
|
||||
N = GenLiteralExpr (CPUIsets[CPU]);
|
||||
NextTok ();
|
||||
break;
|
||||
|
||||
case TOK_DEFINED:
|
||||
N = Function (FuncDefined);
|
||||
break;
|
||||
N = Function (FuncDefined);
|
||||
break;
|
||||
|
||||
case TOK_HIBYTE:
|
||||
N = Function (FuncHiByte);
|
||||
@@ -998,9 +998,9 @@ static ExprNode* Factor (void)
|
||||
N = Function (FuncLoWord);
|
||||
break;
|
||||
|
||||
case TOK_MATCH:
|
||||
N = Function (FuncMatch);
|
||||
break;
|
||||
case TOK_MATCH:
|
||||
N = Function (FuncMatch);
|
||||
break;
|
||||
|
||||
case TOK_MAX:
|
||||
N = Function (FuncMax);
|
||||
@@ -1011,50 +1011,50 @@ static ExprNode* Factor (void)
|
||||
break;
|
||||
|
||||
case TOK_REFERENCED:
|
||||
N = Function (FuncReferenced);
|
||||
break;
|
||||
N = Function (FuncReferenced);
|
||||
break;
|
||||
|
||||
case TOK_SIZEOF:
|
||||
N = Function (FuncSizeOf);
|
||||
break;
|
||||
|
||||
case TOK_STRAT:
|
||||
N = Function (FuncStrAt);
|
||||
break;
|
||||
case TOK_STRAT:
|
||||
N = Function (FuncStrAt);
|
||||
break;
|
||||
|
||||
case TOK_STRLEN:
|
||||
N = Function (FuncStrLen);
|
||||
break;
|
||||
case TOK_STRLEN:
|
||||
N = Function (FuncStrLen);
|
||||
break;
|
||||
|
||||
case TOK_TCOUNT:
|
||||
N = Function (FuncTCount);
|
||||
break;
|
||||
case TOK_TCOUNT:
|
||||
N = Function (FuncTCount);
|
||||
break;
|
||||
|
||||
case TOK_TIME:
|
||||
N = GenLiteralExpr ((long) time (0));
|
||||
NextTok ();
|
||||
break;
|
||||
case TOK_TIME:
|
||||
N = GenLiteralExpr ((long) time (0));
|
||||
NextTok ();
|
||||
break;
|
||||
|
||||
case TOK_VERSION:
|
||||
N = GenLiteralExpr (GetVersionAsNumber ());
|
||||
NextTok ();
|
||||
break;
|
||||
|
||||
case TOK_XMATCH:
|
||||
N = Function (FuncXMatch);
|
||||
break;
|
||||
case TOK_XMATCH:
|
||||
N = Function (FuncXMatch);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (LooseCharTerm && CurTok.Tok == TOK_STRCON &&
|
||||
default:
|
||||
if (LooseCharTerm && CurTok.Tok == TOK_STRCON &&
|
||||
SB_GetLen (&CurTok.SVal) == 1) {
|
||||
/* A character constant */
|
||||
N = GenLiteralExpr (TgtTranslateChar (SB_At (&CurTok.SVal, 0)));
|
||||
} else {
|
||||
N = GenLiteral0 (); /* Dummy */
|
||||
Error ("Syntax error");
|
||||
}
|
||||
NextTok ();
|
||||
break;
|
||||
/* A character constant */
|
||||
N = GenLiteralExpr (TgtTranslateChar (SB_At (&CurTok.SVal, 0)));
|
||||
} else {
|
||||
N = GenLiteral0 (); /* Dummy */
|
||||
Error ("Syntax error");
|
||||
}
|
||||
NextTok ();
|
||||
break;
|
||||
}
|
||||
return N;
|
||||
}
|
||||
@@ -1070,7 +1070,7 @@ static ExprNode* Term (void)
|
||||
while (CurTok.Tok == TOK_MUL || CurTok.Tok == TOK_DIV ||
|
||||
CurTok.Tok == TOK_MOD || CurTok.Tok == TOK_AND ||
|
||||
CurTok.Tok == TOK_XOR || CurTok.Tok == TOK_SHL ||
|
||||
CurTok.Tok == TOK_SHR) {
|
||||
CurTok.Tok == TOK_SHR) {
|
||||
|
||||
long LVal, RVal, Val;
|
||||
ExprNode* Left;
|
||||
@@ -1142,14 +1142,14 @@ static ExprNode* Term (void)
|
||||
/* Generate an expression tree */
|
||||
unsigned char Op;
|
||||
switch (T) {
|
||||
case TOK_MUL: Op = EXPR_MUL; break;
|
||||
case TOK_MUL: Op = EXPR_MUL; break;
|
||||
case TOK_DIV: Op = EXPR_DIV; break;
|
||||
case TOK_MOD: Op = EXPR_MOD; break;
|
||||
case TOK_AND: Op = EXPR_AND; break;
|
||||
case TOK_XOR: Op = EXPR_XOR; break;
|
||||
case TOK_SHL: Op = EXPR_SHL; break;
|
||||
case TOK_SHR: Op = EXPR_SHR; break;
|
||||
default: Internal ("Invalid token");
|
||||
default: Internal ("Invalid token");
|
||||
}
|
||||
Root = NewExprNode (Op);
|
||||
Root->Left = Left;
|
||||
@@ -1212,7 +1212,7 @@ static ExprNode* SimpleExpr (void)
|
||||
case TOK_PLUS: Op = EXPR_PLUS; break;
|
||||
case TOK_MINUS: Op = EXPR_MINUS; break;
|
||||
case TOK_OR: Op = EXPR_OR; break;
|
||||
default: Internal ("Invalid token");
|
||||
default: Internal ("Invalid token");
|
||||
}
|
||||
Root = NewExprNode (Op);
|
||||
Root->Left = Left;
|
||||
@@ -1281,7 +1281,7 @@ static ExprNode* BoolExpr (void)
|
||||
case TOK_GT: Op = EXPR_GT; break;
|
||||
case TOK_LE: Op = EXPR_LE; break;
|
||||
case TOK_GE: Op = EXPR_GE; break;
|
||||
default: Internal ("Invalid token");
|
||||
default: Internal ("Invalid token");
|
||||
}
|
||||
Root = NewExprNode (Op);
|
||||
Root->Left = Left;
|
||||
@@ -1340,7 +1340,7 @@ static ExprNode* Expr2 (void)
|
||||
switch (T) {
|
||||
case TOK_BOOLAND: Op = EXPR_BOOLAND; break;
|
||||
case TOK_BOOLXOR: Op = EXPR_BOOLXOR; break;
|
||||
default: Internal ("Invalid token");
|
||||
default: Internal ("Invalid token");
|
||||
}
|
||||
Root = NewExprNode (Op);
|
||||
Root->Left = Left;
|
||||
@@ -1397,7 +1397,7 @@ static ExprNode* Expr1 (void)
|
||||
unsigned char Op;
|
||||
switch (T) {
|
||||
case TOK_BOOLOR: Op = EXPR_BOOLOR; break;
|
||||
default: Internal ("Invalid token");
|
||||
default: Internal ("Invalid token");
|
||||
}
|
||||
Root = NewExprNode (Op);
|
||||
Root->Left = Left;
|
||||
@@ -1424,7 +1424,7 @@ static ExprNode* Expr0 (void)
|
||||
ExprNode* Left;
|
||||
|
||||
/* Skip the operator token */
|
||||
NextTok ();
|
||||
NextTok ();
|
||||
|
||||
/* Read the argument */
|
||||
Left = Expr0 ();
|
||||
@@ -1440,8 +1440,8 @@ static ExprNode* Expr0 (void)
|
||||
|
||||
} else {
|
||||
|
||||
/* Read left hand side */
|
||||
Root = Expr1 ();
|
||||
/* Read left hand side */
|
||||
Root = Expr1 ();
|
||||
|
||||
}
|
||||
|
||||
@@ -1481,8 +1481,8 @@ long ConstExpression (void)
|
||||
if (ED_IsConst (&D)) {
|
||||
Val = D.Val;
|
||||
} else {
|
||||
Error ("Constant expression expected");
|
||||
Val = 0;
|
||||
Error ("Constant expression expected");
|
||||
Val = 0;
|
||||
}
|
||||
|
||||
/* Free the expression tree and allocated memory for D */
|
||||
@@ -1499,9 +1499,9 @@ void FreeExpr (ExprNode* Root)
|
||||
/* Free the expression, Root is pointing to. */
|
||||
{
|
||||
if (Root) {
|
||||
FreeExpr (Root->Left);
|
||||
FreeExpr (Root->Right);
|
||||
FreeExprNode (Root);
|
||||
FreeExpr (Root->Left);
|
||||
FreeExpr (Root->Right);
|
||||
FreeExprNode (Root);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1595,12 +1595,12 @@ ExprNode* GenCurrentPC (void)
|
||||
ExprNode* Root;
|
||||
|
||||
if (GetRelocMode ()) {
|
||||
/* Create SegmentBase + Offset */
|
||||
Root = GenAddExpr (GenSectionExpr (GetCurrentSegNum ()),
|
||||
/* Create SegmentBase + Offset */
|
||||
Root = GenAddExpr (GenSectionExpr (GetCurrentSegNum ()),
|
||||
GenLiteralExpr (GetPC ()));
|
||||
} else {
|
||||
/* Absolute mode, just return PC value */
|
||||
Root = GenLiteralExpr (GetPC ());
|
||||
/* Absolute mode, just return PC value */
|
||||
Root = GenLiteralExpr (GetPC ());
|
||||
}
|
||||
|
||||
return Root;
|
||||
@@ -1679,7 +1679,7 @@ ExprNode* GenULabelExpr (unsigned Num)
|
||||
/* Return an expression for an unnamed label with the given index */
|
||||
{
|
||||
ExprNode* Node = NewExprNode (EXPR_ULABEL);
|
||||
Node->V.IVal = Num;
|
||||
Node->V.IVal = Num;
|
||||
|
||||
/* Return the new node */
|
||||
return Node;
|
||||
@@ -1749,7 +1749,7 @@ ExprNode* GenNE (ExprNode* Expr, long Val)
|
||||
/* Generate a compare node */
|
||||
ExprNode* Root = NewExprNode (EXPR_NE);
|
||||
Root->Left = Expr;
|
||||
Root->Right = GenLiteralExpr (Val);
|
||||
Root->Right = GenLiteralExpr (Val);
|
||||
|
||||
/* Return the result */
|
||||
return Root;
|
||||
@@ -1798,21 +1798,21 @@ ExprNode* CloneExpr (ExprNode* Expr)
|
||||
/* Clone the node */
|
||||
switch (Expr->Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
case EXPR_LITERAL:
|
||||
Clone = GenLiteralExpr (Expr->V.IVal);
|
||||
break;
|
||||
|
||||
case EXPR_ULABEL:
|
||||
Clone = GenULabelExpr (Expr->V.IVal);
|
||||
break;
|
||||
case EXPR_ULABEL:
|
||||
Clone = GenULabelExpr (Expr->V.IVal);
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
Clone = GenSymExpr (Expr->V.Sym);
|
||||
break;
|
||||
case EXPR_SYMBOL:
|
||||
Clone = GenSymExpr (Expr->V.Sym);
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
Clone = GenSectionExpr (Expr->V.SecNum);
|
||||
break;
|
||||
case EXPR_SECTION:
|
||||
Clone = GenSectionExpr (Expr->V.SecNum);
|
||||
break;
|
||||
|
||||
case EXPR_BANK:
|
||||
Clone = GenBankExpr (Expr->V.SecNum);
|
||||
@@ -1838,8 +1838,8 @@ void WriteExpr (ExprNode* Expr)
|
||||
{
|
||||
/* Null expressions are encoded by a type byte of zero */
|
||||
if (Expr == 0) {
|
||||
ObjWrite8 (EXPR_NULL);
|
||||
return;
|
||||
ObjWrite8 (EXPR_NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the is a leafnode, write the expression attribute, otherwise
|
||||
@@ -1849,33 +1849,33 @@ void WriteExpr (ExprNode* Expr)
|
||||
|
||||
case EXPR_LITERAL:
|
||||
ObjWrite8 (EXPR_LITERAL);
|
||||
ObjWrite32 (Expr->V.IVal);
|
||||
break;
|
||||
ObjWrite32 (Expr->V.IVal);
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
if (SymIsImport (Expr->V.Sym)) {
|
||||
if (SymIsImport (Expr->V.Sym)) {
|
||||
ObjWrite8 (EXPR_SYMBOL);
|
||||
ObjWriteVar (GetSymImportId (Expr->V.Sym));
|
||||
} else {
|
||||
WriteExpr (GetSymExpr (Expr->V.Sym));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
ObjWrite8 (EXPR_SECTION);
|
||||
ObjWriteVar (Expr->V.SecNum);
|
||||
break;
|
||||
ObjWriteVar (Expr->V.SecNum);
|
||||
break;
|
||||
|
||||
case EXPR_ULABEL:
|
||||
case EXPR_ULABEL:
|
||||
WriteExpr (ULabResolve (Expr->V.IVal));
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Not a leaf node */
|
||||
/* Not a leaf node */
|
||||
ObjWrite8 (Expr->Op);
|
||||
WriteExpr (Expr->Left);
|
||||
WriteExpr (Expr->Right);
|
||||
break;
|
||||
WriteExpr (Expr->Left);
|
||||
WriteExpr (Expr->Right);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* expr.h */
|
||||
/* expr.h */
|
||||
/* */
|
||||
/* Expression evaluation for the ca65 macroassembler */
|
||||
/* Expression evaluation for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -55,7 +55,7 @@ struct ExprDesc;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* feature.c */
|
||||
/* feature.c */
|
||||
/* */
|
||||
/* Subroutines for the emulation features */
|
||||
/* Subroutines for the emulation features */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -82,10 +82,10 @@ feature_t FindFeature (const StrBuf* Key)
|
||||
|
||||
/* This is not time critical, so do a linear search */
|
||||
for (F = (feature_t) 0; F < FEAT_COUNT; ++F) {
|
||||
if (SB_CompareStr (Key, FeatureKeys[F]) == 0) {
|
||||
/* Found, index is enum value */
|
||||
return F;
|
||||
}
|
||||
if (SB_CompareStr (Key, FeatureKeys[F]) == 0) {
|
||||
/* Found, index is enum value */
|
||||
return F;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
@@ -105,21 +105,21 @@ feature_t SetFeature (const StrBuf* Key)
|
||||
|
||||
/* Set the flags */
|
||||
switch (Feature) {
|
||||
case FEAT_DOLLAR_IS_PC: DollarIsPC = 1; break;
|
||||
case FEAT_LABELS_WITHOUT_COLONS: NoColonLabels = 1; break;
|
||||
case FEAT_LOOSE_STRING_TERM: LooseStringTerm = 1; break;
|
||||
case FEAT_LOOSE_CHAR_TERM: LooseCharTerm = 1; break;
|
||||
case FEAT_AT_IN_IDENTIFIERS: AtInIdents = 1; break;
|
||||
case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = 1; break;
|
||||
case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1; break;
|
||||
case FEAT_DOLLAR_IS_PC: DollarIsPC = 1; break;
|
||||
case FEAT_LABELS_WITHOUT_COLONS: NoColonLabels = 1; break;
|
||||
case FEAT_LOOSE_STRING_TERM: LooseStringTerm = 1; break;
|
||||
case FEAT_LOOSE_CHAR_TERM: LooseCharTerm = 1; break;
|
||||
case FEAT_AT_IN_IDENTIFIERS: AtInIdents = 1; break;
|
||||
case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = 1; break;
|
||||
case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1; break;
|
||||
case FEAT_ORG_PER_SEG: OrgPerSeg = 1; break;
|
||||
case FEAT_PC_ASSIGNMENT: PCAssignment = 1; break;
|
||||
case FEAT_PC_ASSIGNMENT: PCAssignment = 1; break;
|
||||
case FEAT_MISSING_CHAR_TERM: MissingCharTerm = 1; break;
|
||||
case FEAT_UBIQUITOUS_IDENTS: UbiquitousIdents = 1; break;
|
||||
case FEAT_C_COMMENTS: CComments = 1; break;
|
||||
case FEAT_FORCE_RANGE: ForceRange = 1; break;
|
||||
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break;
|
||||
default: /* Keep gcc silent */ break;
|
||||
default: /* Keep gcc silent */ break;
|
||||
}
|
||||
|
||||
/* Return the value found */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* feature.h */
|
||||
/* feature.h */
|
||||
/* */
|
||||
/* Subroutines for the emulation features */
|
||||
/* Subroutines for the emulation features */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
#ifndef FEATURE_H
|
||||
#define FEATURE_H
|
||||
#define FEATURE_H
|
||||
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
FEAT_UNKNOWN = -1,
|
||||
FEAT_UNKNOWN = -1,
|
||||
FEAT_DOLLAR_IS_PC,
|
||||
FEAT_LABELS_WITHOUT_COLONS,
|
||||
FEAT_LOOSE_STRING_TERM,
|
||||
@@ -73,7 +73,7 @@ typedef enum {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* filetab.h */
|
||||
/* filetab.h */
|
||||
/* */
|
||||
/* Input file table for ca65 */
|
||||
/* Input file table for ca65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -73,7 +73,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -87,10 +87,10 @@ typedef struct FileEntry FileEntry;
|
||||
struct FileEntry {
|
||||
HashNode Node;
|
||||
unsigned Name; /* File name */
|
||||
unsigned Index; /* Index of entry */
|
||||
unsigned Index; /* Index of entry */
|
||||
FileType Type; /* Type of file */
|
||||
unsigned long Size; /* Size of file */
|
||||
unsigned long MTime; /* Time of last modification */
|
||||
unsigned long Size; /* Size of file */
|
||||
unsigned long MTime; /* Time of last modification */
|
||||
};
|
||||
|
||||
/* Array of all entries, listed by index */
|
||||
@@ -142,7 +142,7 @@ static int HT_Compare (const void* Key1, const void* Key2)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -157,10 +157,10 @@ static FileEntry* NewFileEntry (unsigned Name, FileType Type,
|
||||
/* Initialize the fields */
|
||||
InitHashNode (&F->Node);
|
||||
F->Name = Name;
|
||||
F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
|
||||
F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
|
||||
F->Type = Type;
|
||||
F->Size = Size;
|
||||
F->MTime = MTime;
|
||||
F->Size = Size;
|
||||
F->MTime = MTime;
|
||||
|
||||
/* Insert the file into the file table */
|
||||
CollAppend (&FileTab, F);
|
||||
@@ -182,16 +182,16 @@ const StrBuf* GetFileName (unsigned Name)
|
||||
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 (CollCount (&FileTab) == 0) {
|
||||
/* No files defined until now */
|
||||
/* 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 (CollCount (&FileTab) == 0) {
|
||||
/* No files defined until now */
|
||||
return &ErrorMsg;
|
||||
} else {
|
||||
} else {
|
||||
F = CollConstAt (&FileTab, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
F = CollConstAt (&FileTab, Name-1);
|
||||
}
|
||||
@@ -248,12 +248,12 @@ void WriteFiles (void)
|
||||
|
||||
/* Write the file data */
|
||||
for (I = 0; I < CollCount (&FileTab); ++I) {
|
||||
/* Get a pointer to the entry */
|
||||
const FileEntry* F = CollConstAt (&FileTab, I);
|
||||
/* Write the fields */
|
||||
ObjWriteVar (F->Name);
|
||||
ObjWrite32 (F->MTime);
|
||||
ObjWriteVar (F->Size);
|
||||
/* Get a pointer to the entry */
|
||||
const FileEntry* F = CollConstAt (&FileTab, I);
|
||||
/* Write the fields */
|
||||
ObjWriteVar (F->Name);
|
||||
ObjWrite32 (F->MTime);
|
||||
ObjWriteVar (F->Size);
|
||||
}
|
||||
|
||||
/* Done writing files */
|
||||
@@ -272,20 +272,20 @@ static void WriteDep (FILE* F, FileType Types)
|
||||
|
||||
const StrBuf* Filename;
|
||||
|
||||
/* Get the next input file */
|
||||
const FileEntry* E = (const FileEntry*) CollAt (&FileTab, I);
|
||||
/* Get the next input file */
|
||||
const FileEntry* E = (const FileEntry*) CollAt (&FileTab, I);
|
||||
|
||||
/* Ignore it if it is not of the correct type */
|
||||
if ((E->Type & Types) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If this is not the first file, add a space */
|
||||
if (I > 0) {
|
||||
/* If this is not the first file, add a space */
|
||||
if (I > 0) {
|
||||
fputc (' ', F);
|
||||
}
|
||||
|
||||
/* Print the dependency */
|
||||
/* Print the dependency */
|
||||
Filename = GetStrBuf (E->Name);
|
||||
fprintf (F, "%*s", SB_GetLen (Filename), SB_GetConstBuf (Filename));
|
||||
}
|
||||
@@ -301,7 +301,7 @@ static void CreateDepFile (const char* Name, FileType Types)
|
||||
/* Open the file */
|
||||
FILE* F = fopen (Name, "w");
|
||||
if (F == 0) {
|
||||
Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno));
|
||||
Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Print the output file followed by a tab char */
|
||||
@@ -317,8 +317,8 @@ static void CreateDepFile (const char* Name, FileType Types)
|
||||
|
||||
/* Close the file, check for errors */
|
||||
if (fclose (F) != 0) {
|
||||
remove (Name);
|
||||
Fatal ("Cannot write to dependeny file (disk full?)");
|
||||
remove (Name);
|
||||
Fatal ("Cannot write to dependeny file (disk full?)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* filetab.h */
|
||||
/* filetab.h */
|
||||
/* */
|
||||
/* Input file table for ca65 */
|
||||
/* Input file table for ca65 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
#ifndef FILETAB_H
|
||||
#define FILETAB_H
|
||||
#define FILETAB_H
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ typedef enum {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fragment.c */
|
||||
/* fragment.c */
|
||||
/* */
|
||||
/* Data fragments for the ca65 crossassembler */
|
||||
/* Data fragments for the ca65 crossassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -56,12 +56,12 @@ Fragment* NewFragment (unsigned char Type, unsigned short Len)
|
||||
Fragment* F = xmalloc (sizeof (*F));
|
||||
|
||||
/* Initialize it */
|
||||
F->Next = 0;
|
||||
F->Next = 0;
|
||||
F->LineList = 0;
|
||||
F->LI = EmptyCollection;
|
||||
GetFullLineInfo (&F->LI);
|
||||
F->Len = Len;
|
||||
F->Type = Type;
|
||||
F->Len = Len;
|
||||
F->Type = Type;
|
||||
|
||||
/* And return it */
|
||||
return F;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fragment.h */
|
||||
/* fragment.h */
|
||||
/* */
|
||||
/* Data fragments for the ca65 crossassembler */
|
||||
/* Data fragments for the ca65 crossassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -48,21 +48,21 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* struct Fragment */
|
||||
/* struct Fragment */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
typedef struct Fragment Fragment;
|
||||
struct Fragment {
|
||||
Fragment* Next; /* Pointer to next fragment in segment */
|
||||
Fragment* LineList; /* List of fragments for one src line */
|
||||
Fragment* Next; /* Pointer to next fragment in segment */
|
||||
Fragment* LineList; /* List of fragments for one src line */
|
||||
Collection LI; /* Line info for this fragment */
|
||||
unsigned short Len; /* Length for this fragment */
|
||||
unsigned char Type; /* Fragment type */
|
||||
unsigned short Len; /* Length for this fragment */
|
||||
unsigned char Type; /* Fragment type */
|
||||
union {
|
||||
unsigned char Data[sizeof (ExprNode*)]; /* Literal values */
|
||||
ExprNode* Expr; /* Expression */
|
||||
unsigned char Data[sizeof (ExprNode*)]; /* Literal values */
|
||||
ExprNode* Expr; /* Expression */
|
||||
} V;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.c */
|
||||
/* global.c */
|
||||
/* */
|
||||
/* Global variables for the ca65 macroassembler */
|
||||
/* Global variables for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -42,40 +42,40 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* File names */
|
||||
const char* InFile = 0; /* Name of input file */
|
||||
const char* OutFile = 0; /* Name of output file */
|
||||
const char* InFile = 0; /* Name of input file */
|
||||
const char* OutFile = 0; /* Name of output file */
|
||||
StrBuf ListingName = STATIC_STRBUF_INITIALIZER; /* Name of listing file */
|
||||
StrBuf DepName = STATIC_STRBUF_INITIALIZER; /* Dependency file */
|
||||
StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Full dependency file */
|
||||
|
||||
/* Default extensions */
|
||||
const char ObjExt[] = ".o";/* Default object extension */
|
||||
const char ObjExt[] = ".o";/* Default object extension */
|
||||
|
||||
char LocalStart = '@'; /* This char starts local symbols */
|
||||
char LocalStart = '@'; /* This char starts local symbols */
|
||||
|
||||
unsigned char IgnoreCase = 0; /* Ignore case on identifiers? */
|
||||
unsigned char AutoImport = 0; /* Mark unresolveds as import */
|
||||
unsigned char SmartMode = 0; /* Smart mode */
|
||||
unsigned char DbgSyms = 0; /* Add debug symbols */
|
||||
unsigned char LineCont = 0; /* Allow line continuation */
|
||||
unsigned char SmartMode = 0; /* Smart mode */
|
||||
unsigned char DbgSyms = 0; /* Add debug symbols */
|
||||
unsigned char LineCont = 0; /* Allow line continuation */
|
||||
unsigned char LargeAlignment = 0; /* Don't warn about large alignments */
|
||||
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
||||
|
||||
/* Emulation features */
|
||||
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
|
||||
unsigned char NoColonLabels = 0; /* Allow labels without a colon */
|
||||
unsigned char LooseStringTerm = 0; /* Allow ' as string terminator */
|
||||
unsigned char LooseCharTerm = 0; /* Allow " for char constants */
|
||||
unsigned char AtInIdents = 0; /* Allow '@' in identifiers */
|
||||
unsigned char LooseStringTerm = 0; /* Allow ' as string terminator */
|
||||
unsigned char LooseCharTerm = 0; /* Allow " for char constants */
|
||||
unsigned char AtInIdents = 0; /* Allow '@' in identifiers */
|
||||
unsigned char DollarInIdents = 0; /* Allow '$' in identifiers */
|
||||
unsigned char LeadingDotInIdents = 0; /* Allow '.' to start an identifier */
|
||||
unsigned char PCAssignment = 0; /* Allow "* = $XXX" or "$ = $XXX" */
|
||||
unsigned char PCAssignment = 0; /* Allow "* = $XXX" or "$ = $XXX" */
|
||||
unsigned char MissingCharTerm = 0; /* Allow lda #'a (no closing term) */
|
||||
unsigned char UbiquitousIdents = 0; /* Allow ubiquitous identifiers */
|
||||
unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.h */
|
||||
/* global.h */
|
||||
/* */
|
||||
/* Global variables for the ca65 macroassembler */
|
||||
/* Global variables for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,40 +44,40 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* File names */
|
||||
extern const char* InFile; /* Name of input file */
|
||||
extern const char* OutFile; /* Name of output file */
|
||||
extern const char* InFile; /* Name of input file */
|
||||
extern const char* OutFile; /* Name of output file */
|
||||
extern StrBuf ListingName; /* Name of listing file */
|
||||
extern StrBuf DepName; /* Name of dependencies file */
|
||||
extern StrBuf FullDepName; /* Name of full dependencies file */
|
||||
|
||||
/* Default extensions */
|
||||
extern const char ObjExt[]; /* Default object extension */
|
||||
extern const char ObjExt[]; /* Default object extension */
|
||||
|
||||
extern char LocalStart; /* This char starts local symbols */
|
||||
extern char LocalStart; /* This char starts local symbols */
|
||||
|
||||
extern unsigned char IgnoreCase; /* Ignore case on identifiers? */
|
||||
extern unsigned char AutoImport; /* Mark unresolveds as import */
|
||||
extern unsigned char SmartMode; /* Smart mode */
|
||||
extern unsigned char DbgSyms; /* Add debug symbols */
|
||||
extern unsigned char LineCont; /* Allow line continuation */
|
||||
extern unsigned char IgnoreCase; /* Ignore case on identifiers? */
|
||||
extern unsigned char AutoImport; /* Mark unresolveds as import */
|
||||
extern unsigned char SmartMode; /* Smart mode */
|
||||
extern unsigned char DbgSyms; /* Add debug symbols */
|
||||
extern unsigned char LineCont; /* Allow line continuation */
|
||||
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
||||
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
||||
|
||||
/* Emulation features */
|
||||
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
||||
extern unsigned char NoColonLabels; /* Allow labels without a colon */
|
||||
extern unsigned char LooseStringTerm; /* Allow ' as string terminator */
|
||||
extern unsigned char LooseCharTerm; /* Allow " for char constants */
|
||||
extern unsigned char AtInIdents; /* Allow '@' in identifiers */
|
||||
extern unsigned char DollarInIdents; /* Allow '$' in identifiers */
|
||||
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
||||
extern unsigned char NoColonLabels; /* Allow labels without a colon */
|
||||
extern unsigned char LooseStringTerm; /* Allow ' as string terminator */
|
||||
extern unsigned char LooseCharTerm; /* Allow " for char constants */
|
||||
extern unsigned char AtInIdents; /* Allow '@' in identifiers */
|
||||
extern unsigned char DollarInIdents; /* Allow '$' in identifiers */
|
||||
extern unsigned char LeadingDotInIdents; /* Allow '.' to start an identifier */
|
||||
extern unsigned char PCAssignment; /* Allow "* = $XXX" or "$ = $XXX" */
|
||||
extern unsigned char PCAssignment; /* Allow "* = $XXX" or "$ = $XXX" */
|
||||
extern unsigned char MissingCharTerm; /* Allow lda #'a (no closing term) */
|
||||
extern unsigned char UbiquitousIdents; /* Allow ubiquitous identifiers */
|
||||
extern unsigned char OrgPerSeg; /* Make .org local to current seg */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* incpath.c */
|
||||
/* incpath.c */
|
||||
/* */
|
||||
/* Include path handling for the ca65 macro assembler */
|
||||
/* Include path handling for the ca65 macro assembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ SearchPath* BinSearchPath; /* Binary include path */
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* incpath.h */
|
||||
/* incpath.h */
|
||||
/* */
|
||||
/* Include path handling for the ca65 macro assembler */
|
||||
/* Include path handling for the ca65 macro assembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ extern SearchPath* BinSearchPath; /* Binary include path */
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
1246
src/ca65/instr.c
1246
src/ca65/instr.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* instr.h */
|
||||
/* instr.h */
|
||||
/* */
|
||||
/* Instruction encoding for the ca65 macroassembler */
|
||||
/* Instruction encoding for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -58,18 +58,18 @@
|
||||
* When assembling for the 6502 or 65C02, all addressing modes that are not
|
||||
* available on these CPUs are removed before doing any checks.
|
||||
*/
|
||||
#define AM65_IMPLICIT 0x00000003UL
|
||||
#define AM65_ACCU 0x00000002UL
|
||||
#define AM65_DIR 0x00000004UL
|
||||
#define AM65_ABS 0x00000008UL
|
||||
#define AM65_ABS_LONG 0x00000010UL
|
||||
#define AM65_DIR_X 0x00000020UL
|
||||
#define AM65_ABS_X 0x00000040UL
|
||||
#define AM65_ABS_LONG_X 0x00000080UL
|
||||
#define AM65_IMPLICIT 0x00000003UL
|
||||
#define AM65_ACCU 0x00000002UL
|
||||
#define AM65_DIR 0x00000004UL
|
||||
#define AM65_ABS 0x00000008UL
|
||||
#define AM65_ABS_LONG 0x00000010UL
|
||||
#define AM65_DIR_X 0x00000020UL
|
||||
#define AM65_ABS_X 0x00000040UL
|
||||
#define AM65_ABS_LONG_X 0x00000080UL
|
||||
#define AM65_DIR_Y 0x00000100UL
|
||||
#define AM65_ABS_Y 0x00000200UL
|
||||
#define AM65_DIR_IND 0x00000400UL
|
||||
#define AM65_ABS_IND 0x00000800UL
|
||||
#define AM65_ABS_IND 0x00000800UL
|
||||
#define AM65_DIR_IND_LONG 0x00001000UL
|
||||
#define AM65_DIR_IND_Y 0x00002000UL
|
||||
#define AM65_DIR_IND_LONG_Y 0x00004000UL
|
||||
@@ -79,14 +79,14 @@
|
||||
#define AM65_REL_LONG 0x00040000UL
|
||||
#define AM65_STACK_REL 0x00080000UL
|
||||
#define AM65_STACK_REL_IND_Y 0x00100000UL
|
||||
#define AM65_IMM_ACCU 0x00200000UL
|
||||
#define AM65_IMM_INDEX 0x00400000UL
|
||||
#define AM65_IMM_IMPLICIT 0x00800000UL
|
||||
#define AM65_IMM_ACCU 0x00200000UL
|
||||
#define AM65_IMM_INDEX 0x00400000UL
|
||||
#define AM65_IMM_IMPLICIT 0x00800000UL
|
||||
#define AM65_BLOCKMOVE 0x01000000UL
|
||||
#define AM65_BLOCKXFER 0x02000000UL
|
||||
|
||||
/* Bitmask for all ZP operations that have correspondent ABS ops */
|
||||
#define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND)
|
||||
#define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND)
|
||||
|
||||
/* Bitmask for all ABS operations that have correspondent FAR ops */
|
||||
#define AM65_SET_ABS (AM65_ABS | AM65_ABS_X)
|
||||
@@ -104,28 +104,28 @@
|
||||
#define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT)
|
||||
|
||||
/* Bit numbers and count */
|
||||
#define AM65I_IMM_ACCU 21
|
||||
#define AM65I_IMM_INDEX 22
|
||||
#define AM65I_IMM_ACCU 21
|
||||
#define AM65I_IMM_INDEX 22
|
||||
#define AM65I_IMM_IMPLICIT 23
|
||||
#define AM65I_COUNT 26
|
||||
#define AM65I_COUNT 26
|
||||
|
||||
|
||||
|
||||
/* Description for one instruction */
|
||||
typedef struct InsDesc InsDesc;
|
||||
struct InsDesc {
|
||||
char Mnemonic[5];
|
||||
unsigned long AddrMode; /* Valid adressing modes */
|
||||
unsigned char BaseCode; /* Base opcode */
|
||||
unsigned char ExtCode; /* Number of ext code table */
|
||||
void (*Emit) (const InsDesc*);/* Handler function */
|
||||
char Mnemonic[5];
|
||||
unsigned long AddrMode; /* Valid adressing modes */
|
||||
unsigned char BaseCode; /* Base opcode */
|
||||
unsigned char ExtCode; /* Number of ext code table */
|
||||
void (*Emit) (const InsDesc*);/* Handler function */
|
||||
};
|
||||
|
||||
/* An instruction table */
|
||||
typedef struct InsTable InsTable;
|
||||
struct InsTable {
|
||||
unsigned Count; /* Number of intstructions */
|
||||
InsDesc Ins[1]; /* Varying length */
|
||||
unsigned Count; /* Number of intstructions */
|
||||
InsDesc Ins[1]; /* Varying length */
|
||||
};
|
||||
|
||||
/* The instruction table for the currently active CPU */
|
||||
@@ -154,7 +154,7 @@ extern unsigned char ExtBytes[AM65I_COUNT];
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* istack.c */
|
||||
/* istack.c */
|
||||
/* */
|
||||
/* Input stack for the scanner */
|
||||
/* Input stack for the scanner */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,31 +44,31 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Size of the stack (== maximum nested macro or repeat count) */
|
||||
#define ISTACK_MAX 256
|
||||
#define ISTACK_MAX 256
|
||||
|
||||
/* Structure holding a stack element */
|
||||
typedef struct IElement IElement;
|
||||
struct IElement {
|
||||
IElement* Next; /* Next stack element */
|
||||
int (*Func)(void*); /* Function called for input */
|
||||
void* Data; /* User data given as argument */
|
||||
const char* Desc; /* Description */
|
||||
IElement* Next; /* Next stack element */
|
||||
int (*Func)(void*); /* Function called for input */
|
||||
void* Data; /* User data given as argument */
|
||||
const char* Desc; /* Description */
|
||||
};
|
||||
|
||||
/* The stack */
|
||||
static IElement* IStack = 0; /* Input stack pointer */
|
||||
static unsigned ICount = 0; /* Number of items on the stack */
|
||||
static IElement* IStack = 0; /* Input stack pointer */
|
||||
static unsigned ICount = 0; /* Number of items on the stack */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ void PushInput (int (*Func) (void*), void* Data, const char* Desc)
|
||||
|
||||
/* Check for a stack overflow */
|
||||
if (ICount > ISTACK_MAX) {
|
||||
Fatal ("Maximum input stack nesting exceeded");
|
||||
Fatal ("Maximum input stack nesting exceeded");
|
||||
}
|
||||
|
||||
/* Create a new stack element */
|
||||
@@ -127,10 +127,10 @@ int InputFromStack (void)
|
||||
* routines.
|
||||
*/
|
||||
while (IStack) {
|
||||
if (IStack->Func (IStack->Data) != 0) {
|
||||
/* We have a token */
|
||||
return 1;
|
||||
}
|
||||
if (IStack->Func (IStack->Data) != 0) {
|
||||
/* We have a token */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing is on the stack */
|
||||
@@ -153,7 +153,7 @@ void CheckInputStack (void)
|
||||
*/
|
||||
{
|
||||
if (IStack) {
|
||||
Error ("Open %s", IStack->Desc);
|
||||
Error ("Open %s", IStack->Desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* istack.h */
|
||||
/* istack.h */
|
||||
/* */
|
||||
/* Input stack for the scanner */
|
||||
/* Input stack for the scanner */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* lineinfo.c */
|
||||
/* lineinfo.c */
|
||||
/* */
|
||||
/* Source file line info structure */
|
||||
/* Source file line info structure */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -72,7 +72,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ static int CheckLineInfo (void* Entry, void* Data attribute ((unused)))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* lineinfo.h */
|
||||
/* lineinfo.h */
|
||||
/* */
|
||||
/* Source file line info management */
|
||||
/* */
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef struct LineInfo LineInfo;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* listing.c */
|
||||
/* listing.c */
|
||||
/* */
|
||||
/* Listing support for the ca65 crossassembler */
|
||||
/* Listing support for the ca65 crossassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -55,29 +55,29 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Single linked list of lines */
|
||||
ListLine* LineList = 0; /* List of listing lines */
|
||||
ListLine* LineCur = 0; /* Current listing line */
|
||||
ListLine* LineLast = 0; /* Last (current) listing line */
|
||||
ListLine* LineList = 0; /* List of listing lines */
|
||||
ListLine* LineCur = 0; /* Current listing line */
|
||||
ListLine* LineLast = 0; /* Last (current) listing line */
|
||||
|
||||
/* Page and other formatting */
|
||||
int PageLength = -1; /* Length of a listing page */
|
||||
static unsigned PageNumber = 1; /* Current listing page number */
|
||||
static int PageLines = 0; /* Current line on page */
|
||||
static unsigned ListBytes = 12; /* Number of bytes to list for one line */
|
||||
int PageLength = -1; /* Length of a listing page */
|
||||
static unsigned PageNumber = 1; /* Current listing page number */
|
||||
static int PageLines = 0; /* Current line on page */
|
||||
static unsigned ListBytes = 12; /* Number of bytes to list for one line */
|
||||
|
||||
/* Switch the listing on/off */
|
||||
static int ListingEnabled = 1; /* Enabled if > 0 */
|
||||
static int ListingEnabled = 1; /* Enabled if > 0 */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -88,39 +88,39 @@ void NewListingLine (const StrBuf* Line, unsigned char File, unsigned char Depth
|
||||
/* Store only if listing is enabled */
|
||||
if (SB_GetLen (&ListingName) > 0) {
|
||||
|
||||
ListLine* L;
|
||||
ListLine* L;
|
||||
|
||||
/* Get the length of the line */
|
||||
unsigned Len = SB_GetLen (Line);
|
||||
/* Get the length of the line */
|
||||
unsigned Len = SB_GetLen (Line);
|
||||
|
||||
/* Ignore trailing newlines */
|
||||
while (Len > 0 && SB_AtUnchecked (Line, Len-1) == '\n') {
|
||||
--Len;
|
||||
}
|
||||
/* Ignore trailing newlines */
|
||||
while (Len > 0 && SB_AtUnchecked (Line, Len-1) == '\n') {
|
||||
--Len;
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
L = xmalloc (sizeof (ListLine) + Len);
|
||||
/* Allocate memory */
|
||||
L = xmalloc (sizeof (ListLine) + Len);
|
||||
|
||||
/* Initialize the fields. */
|
||||
L->Next = 0;
|
||||
L->FragList = 0;
|
||||
L->FragLast = 0;
|
||||
L->PC = GetPC ();
|
||||
L->Reloc = GetRelocMode ();
|
||||
L->File = File;
|
||||
L->Depth = Depth;
|
||||
L->Output = (ListingEnabled > 0);
|
||||
L->ListBytes = (unsigned char) ListBytes;
|
||||
memcpy (L->Line, SB_GetConstBuf (Line), Len);
|
||||
L->Line[Len] = '\0';
|
||||
/* Initialize the fields. */
|
||||
L->Next = 0;
|
||||
L->FragList = 0;
|
||||
L->FragLast = 0;
|
||||
L->PC = GetPC ();
|
||||
L->Reloc = GetRelocMode ();
|
||||
L->File = File;
|
||||
L->Depth = Depth;
|
||||
L->Output = (ListingEnabled > 0);
|
||||
L->ListBytes = (unsigned char) ListBytes;
|
||||
memcpy (L->Line, SB_GetConstBuf (Line), Len);
|
||||
L->Line[Len] = '\0';
|
||||
|
||||
/* Insert the line into the list of lines */
|
||||
if (LineList == 0) {
|
||||
LineList = L;
|
||||
} else {
|
||||
LineLast->Next = L;
|
||||
}
|
||||
LineLast = L;
|
||||
/* Insert the line into the list of lines */
|
||||
if (LineList == 0) {
|
||||
LineList = L;
|
||||
} else {
|
||||
LineLast->Next = L;
|
||||
}
|
||||
LineLast = L;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,12 +130,12 @@ void EnableListing (void)
|
||||
/* Enable output of lines to the listing */
|
||||
{
|
||||
if (SB_GetLen (&ListingName) > 0) {
|
||||
/* If we're about to enable the listing, do this for the current line
|
||||
* also, so we will see the source line that did this.
|
||||
*/
|
||||
if (ListingEnabled++ == 0) {
|
||||
LineCur->Output = 1;
|
||||
}
|
||||
/* If we're about to enable the listing, do this for the current line
|
||||
* also, so we will see the source line that did this.
|
||||
*/
|
||||
if (ListingEnabled++ == 0) {
|
||||
LineCur->Output = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,12 +145,12 @@ void DisableListing (void)
|
||||
/* Disable output of lines to the listing */
|
||||
{
|
||||
if (SB_GetLen (&ListingName) > 0) {
|
||||
if (ListingEnabled == 0) {
|
||||
/* Cannot switch the listing off once more */
|
||||
Error ("Counter underflow");
|
||||
} else {
|
||||
--ListingEnabled;
|
||||
}
|
||||
if (ListingEnabled == 0) {
|
||||
/* Cannot switch the listing off once more */
|
||||
Error ("Counter underflow");
|
||||
} else {
|
||||
--ListingEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ void SetListBytes (int Bytes)
|
||||
/* Set the maximum number of bytes listed for one line */
|
||||
{
|
||||
if (Bytes < 0) {
|
||||
Bytes = 0; /* Encode "unlimited" as zero */
|
||||
Bytes = 0; /* Encode "unlimited" as zero */
|
||||
}
|
||||
ListBytes = Bytes;
|
||||
}
|
||||
@@ -171,30 +171,30 @@ void InitListingLine (void)
|
||||
/* Initialize the current listing line */
|
||||
{
|
||||
if (SB_GetLen (&ListingName) > 0) {
|
||||
/* Make the last loaded line the current line */
|
||||
/* ###### This code is a hack! We really need to do it right
|
||||
* as soon as we know, how:-(
|
||||
*/
|
||||
if (LineCur && LineCur->Next && LineCur->Next != LineLast) {
|
||||
ListLine* L = LineCur;
|
||||
do {
|
||||
L = L->Next;
|
||||
/* Set the values for this line */
|
||||
CHECK (L != 0);
|
||||
L->PC = GetPC ();
|
||||
L->Reloc = GetRelocMode ();
|
||||
L->Output = (ListingEnabled > 0);
|
||||
L->ListBytes = (unsigned char) ListBytes;
|
||||
} while (L->Next != LineLast);
|
||||
}
|
||||
LineCur = LineLast;
|
||||
/* Make the last loaded line the current line */
|
||||
/* ###### This code is a hack! We really need to do it right
|
||||
* as soon as we know, how:-(
|
||||
*/
|
||||
if (LineCur && LineCur->Next && LineCur->Next != LineLast) {
|
||||
ListLine* L = LineCur;
|
||||
do {
|
||||
L = L->Next;
|
||||
/* Set the values for this line */
|
||||
CHECK (L != 0);
|
||||
L->PC = GetPC ();
|
||||
L->Reloc = GetRelocMode ();
|
||||
L->Output = (ListingEnabled > 0);
|
||||
L->ListBytes = (unsigned char) ListBytes;
|
||||
} while (L->Next != LineLast);
|
||||
}
|
||||
LineCur = LineLast;
|
||||
|
||||
/* Set the values for this line */
|
||||
CHECK (LineCur != 0);
|
||||
LineCur->PC = GetPC ();
|
||||
LineCur->Reloc = GetRelocMode ();
|
||||
LineCur->Output = (ListingEnabled > 0);
|
||||
LineCur->ListBytes = (unsigned char) ListBytes;
|
||||
/* Set the values for this line */
|
||||
CHECK (LineCur != 0);
|
||||
LineCur->PC = GetPC ();
|
||||
LineCur->Reloc = GetRelocMode ();
|
||||
LineCur->Output = (ListingEnabled > 0);
|
||||
LineCur->ListBytes = (unsigned char) ListBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ static char* AddHex (char* S, unsigned Val)
|
||||
/* Add a hex byte in ASCII to the given string and return the new pointer */
|
||||
{
|
||||
static const char HexTab [16] = {
|
||||
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||
};
|
||||
|
||||
*S++ = HexTab [(Val >> 4) & 0x0F];
|
||||
@@ -225,13 +225,13 @@ static void PrintPageHeader (FILE* F, const ListLine* L)
|
||||
|
||||
/* Print the header on the new page */
|
||||
fprintf (F,
|
||||
"ca65 V%s\n"
|
||||
"Main file : %s\n"
|
||||
"Current file: %.*s\n"
|
||||
"\n",
|
||||
GetVersionAsString (),
|
||||
InFile,
|
||||
(int) SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
|
||||
"ca65 V%s\n"
|
||||
"Main file : %s\n"
|
||||
"Current file: %.*s\n"
|
||||
"\n",
|
||||
GetVersionAsString (),
|
||||
InFile,
|
||||
(int) SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
|
||||
|
||||
/* Count pages, reset lines */
|
||||
++PageNumber;
|
||||
@@ -253,10 +253,10 @@ static void PrintLine (FILE* F, const char* Header, const char* Line, const List
|
||||
* the last one, to avoid pages that consist of just the header.
|
||||
*/
|
||||
if (PageLength > 0 && PageLines >= PageLength && L->Next != 0) {
|
||||
/* Do a formfeed */
|
||||
putc ('\f', F);
|
||||
/* Print the header on the new page */
|
||||
PrintPageHeader (F, L);
|
||||
/* Do a formfeed */
|
||||
putc ('\f', F);
|
||||
/* Print the header on the new page */
|
||||
PrintPageHeader (F, L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ void CreateListing (void)
|
||||
/* Open the real listing file */
|
||||
F = fopen (SB_GetConstBuf (&ListingName), "w");
|
||||
if (F == 0) {
|
||||
Fatal ("Cannot open listing file `%s': %s",
|
||||
Fatal ("Cannot open listing file `%s': %s",
|
||||
SB_GetConstBuf (&ListingName),
|
||||
strerror (errno));
|
||||
}
|
||||
@@ -320,132 +320,132 @@ void CreateListing (void)
|
||||
L = LineList;
|
||||
while (L) {
|
||||
|
||||
char* Buf;
|
||||
char* B;
|
||||
unsigned Count;
|
||||
unsigned I;
|
||||
char* Line;
|
||||
char* Buf;
|
||||
char* B;
|
||||
unsigned Count;
|
||||
unsigned I;
|
||||
char* Line;
|
||||
|
||||
/* If we should not output this line, go to the next */
|
||||
if (L->Output == 0) {
|
||||
L = L->Next;
|
||||
continue;
|
||||
}
|
||||
/* If we should not output this line, go to the next */
|
||||
if (L->Output == 0) {
|
||||
L = L->Next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we don't have a fragment list for this line, things are easy */
|
||||
if (L->FragList == 0) {
|
||||
PrintLine (F, MakeLineHeader (HeaderBuf, L), L->Line, L);
|
||||
L = L->Next;
|
||||
continue;
|
||||
}
|
||||
/* If we don't have a fragment list for this line, things are easy */
|
||||
if (L->FragList == 0) {
|
||||
PrintLine (F, MakeLineHeader (HeaderBuf, L), L->Line, L);
|
||||
L = L->Next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Count the number of bytes in the complete fragment list */
|
||||
Count = 0;
|
||||
Frag = L->FragList;
|
||||
while (Frag) {
|
||||
Count += Frag->Len;
|
||||
Frag = Frag->LineList;
|
||||
}
|
||||
/* Count the number of bytes in the complete fragment list */
|
||||
Count = 0;
|
||||
Frag = L->FragList;
|
||||
while (Frag) {
|
||||
Count += Frag->Len;
|
||||
Frag = Frag->LineList;
|
||||
}
|
||||
|
||||
/* Allocate memory for the given number of bytes */
|
||||
Buf = xmalloc (Count*2+1);
|
||||
/* Allocate memory for the given number of bytes */
|
||||
Buf = xmalloc (Count*2+1);
|
||||
|
||||
/* Copy an ASCII representation of the bytes into the buffer */
|
||||
B = Buf;
|
||||
Frag = L->FragList;
|
||||
while (Frag) {
|
||||
/* Copy an ASCII representation of the bytes into the buffer */
|
||||
B = Buf;
|
||||
Frag = L->FragList;
|
||||
while (Frag) {
|
||||
|
||||
/* Write data depending on the type */
|
||||
switch (Frag->Type) {
|
||||
/* Write data depending on the type */
|
||||
switch (Frag->Type) {
|
||||
|
||||
case FRAG_LITERAL:
|
||||
for (I = 0; I < Frag->Len; ++I) {
|
||||
B = AddHex (B, Frag->V.Data[I]);
|
||||
}
|
||||
break;
|
||||
case FRAG_LITERAL:
|
||||
for (I = 0; I < Frag->Len; ++I) {
|
||||
B = AddHex (B, Frag->V.Data[I]);
|
||||
}
|
||||
break;
|
||||
|
||||
case FRAG_EXPR:
|
||||
case FRAG_SEXPR:
|
||||
B = AddMult (B, 'r', Frag->Len*2);
|
||||
break;
|
||||
case FRAG_EXPR:
|
||||
case FRAG_SEXPR:
|
||||
B = AddMult (B, 'r', Frag->Len*2);
|
||||
break;
|
||||
|
||||
case FRAG_FILL:
|
||||
B = AddMult (B, 'x', Frag->Len*2);
|
||||
break;
|
||||
case FRAG_FILL:
|
||||
B = AddMult (B, 'x', Frag->Len*2);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid fragment type: %u", Frag->Type);
|
||||
default:
|
||||
Internal ("Invalid fragment type: %u", Frag->Type);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Next fragment */
|
||||
Frag = Frag->LineList;
|
||||
/* Next fragment */
|
||||
Frag = Frag->LineList;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Limit the number of bytes actually printed */
|
||||
if (L->ListBytes != 0) {
|
||||
/* Not unlimited */
|
||||
if (Count > L->ListBytes) {
|
||||
Count = L->ListBytes;
|
||||
}
|
||||
}
|
||||
/* Limit the number of bytes actually printed */
|
||||
if (L->ListBytes != 0) {
|
||||
/* Not unlimited */
|
||||
if (Count > L->ListBytes) {
|
||||
Count = L->ListBytes;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the data. The format of a listing line is:
|
||||
*
|
||||
* PPPPPPm I 11 22 33 44
|
||||
*
|
||||
* where
|
||||
*
|
||||
* PPPPPP is the PC
|
||||
* m is the mode ('r' or empty)
|
||||
* I is the include level
|
||||
* 11 .. are code or data bytes
|
||||
*/
|
||||
Line = L->Line;
|
||||
B = Buf;
|
||||
while (Count) {
|
||||
/* Output the data. The format of a listing line is:
|
||||
*
|
||||
* PPPPPPm I 11 22 33 44
|
||||
*
|
||||
* where
|
||||
*
|
||||
* PPPPPP is the PC
|
||||
* m is the mode ('r' or empty)
|
||||
* I is the include level
|
||||
* 11 .. are code or data bytes
|
||||
*/
|
||||
Line = L->Line;
|
||||
B = Buf;
|
||||
while (Count) {
|
||||
|
||||
unsigned Chunk;
|
||||
char* P;
|
||||
unsigned Chunk;
|
||||
char* P;
|
||||
|
||||
/* Prepare the line header */
|
||||
MakeLineHeader (HeaderBuf, L);
|
||||
/* Prepare the line header */
|
||||
MakeLineHeader (HeaderBuf, L);
|
||||
|
||||
/* Get the number of bytes for the next line */
|
||||
Chunk = Count;
|
||||
if (Chunk > 4) {
|
||||
Chunk = 4;
|
||||
}
|
||||
Count -= Chunk;
|
||||
/* Get the number of bytes for the next line */
|
||||
Chunk = Count;
|
||||
if (Chunk > 4) {
|
||||
Chunk = 4;
|
||||
}
|
||||
Count -= Chunk;
|
||||
|
||||
/* Increment the program counter. Since we don't need the PC stored
|
||||
* in the LineList object for anything else, just increment this
|
||||
* variable.
|
||||
*/
|
||||
L->PC += Chunk;
|
||||
/* Increment the program counter. Since we don't need the PC stored
|
||||
* in the LineList object for anything else, just increment this
|
||||
* variable.
|
||||
*/
|
||||
L->PC += Chunk;
|
||||
|
||||
/* Copy the bytes into the line */
|
||||
P = HeaderBuf + 11;
|
||||
for (I = 0; I < Chunk; ++I) {
|
||||
*P++ = *B++;
|
||||
*P++ = *B++;
|
||||
*P++ = ' ';
|
||||
}
|
||||
/* Copy the bytes into the line */
|
||||
P = HeaderBuf + 11;
|
||||
for (I = 0; I < Chunk; ++I) {
|
||||
*P++ = *B++;
|
||||
*P++ = *B++;
|
||||
*P++ = ' ';
|
||||
}
|
||||
|
||||
/* Output this line */
|
||||
PrintLine (F, HeaderBuf, Line, L);
|
||||
/* Output this line */
|
||||
PrintLine (F, HeaderBuf, Line, L);
|
||||
|
||||
/* Don't output a line twice */
|
||||
Line = "";
|
||||
/* Don't output a line twice */
|
||||
Line = "";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete the temporary buffer */
|
||||
xfree (Buf);
|
||||
/* Delete the temporary buffer */
|
||||
xfree (Buf);
|
||||
|
||||
/* Next line */
|
||||
L = L->Next;
|
||||
/* Next line */
|
||||
L = L->Next;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* listing.h */
|
||||
/* listing.h */
|
||||
/* */
|
||||
/* Listing support for the ca65 crossassembler */
|
||||
/* Listing support for the ca65 crossassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -54,47 +54,47 @@ struct StrBuf;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Length of the header of a listing line */
|
||||
#define LINE_HEADER_LEN 24
|
||||
#define LINE_HEADER_LEN 24
|
||||
|
||||
/* One listing line as it is stored in memory */
|
||||
typedef struct ListLine ListLine;
|
||||
struct ListLine {
|
||||
ListLine* Next; /* Pointer to next line */
|
||||
Fragment* FragList; /* List of fragments for this line */
|
||||
Fragment* FragLast; /* Last entry in fragment list */
|
||||
unsigned long PC; /* Program counter for this line */
|
||||
unsigned char Reloc; /* Relocatable mode? */
|
||||
unsigned char File; /* From which file is the line? */
|
||||
unsigned char Depth; /* Include depth */
|
||||
unsigned char Output; /* Should we output this line? */
|
||||
unsigned char ListBytes; /* How many bytes at max? */
|
||||
char Line[1]; /* Line with dynamic length */
|
||||
ListLine* Next; /* Pointer to next line */
|
||||
Fragment* FragList; /* List of fragments for this line */
|
||||
Fragment* FragLast; /* Last entry in fragment list */
|
||||
unsigned long PC; /* Program counter for this line */
|
||||
unsigned char Reloc; /* Relocatable mode? */
|
||||
unsigned char File; /* From which file is the line? */
|
||||
unsigned char Depth; /* Include depth */
|
||||
unsigned char Output; /* Should we output this line? */
|
||||
unsigned char ListBytes; /* How many bytes at max? */
|
||||
char Line[1]; /* Line with dynamic length */
|
||||
};
|
||||
|
||||
/* Single linked list of lines */
|
||||
extern ListLine* LineList; /* List of listing lines */
|
||||
extern ListLine* LineCur; /* Current listing line */
|
||||
extern ListLine* LineLast; /* Last listing line */
|
||||
extern ListLine* LineList; /* List of listing lines */
|
||||
extern ListLine* LineCur; /* Current listing line */
|
||||
extern ListLine* LineLast; /* Last listing line */
|
||||
|
||||
/* Page formatting */
|
||||
#define MIN_PAGE_LEN 32
|
||||
#define MAX_PAGE_LEN 127
|
||||
extern int PageLength; /* Length of a listing page */
|
||||
#define MIN_PAGE_LEN 32
|
||||
#define MAX_PAGE_LEN 127
|
||||
extern int PageLength; /* Length of a listing page */
|
||||
|
||||
/* Byte for one listing line */
|
||||
#define MIN_LIST_BYTES 4
|
||||
#define MAX_LIST_BYTES 255
|
||||
#define MIN_LIST_BYTES 4
|
||||
#define MAX_LIST_BYTES 255
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
572
src/ca65/macro.c
572
src/ca65/macro.c
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* macro.c */
|
||||
/* macro.c */
|
||||
/* */
|
||||
/* Macros for the ca65 macroassembler */
|
||||
/* Macros for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -77,7 +77,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
|
||||
/* Struct that describes an identifer (macro param, local list) */
|
||||
typedef struct IdDesc IdDesc;
|
||||
struct IdDesc {
|
||||
IdDesc* Next; /* Linked list */
|
||||
IdDesc* Next; /* Linked list */
|
||||
StrBuf Id; /* Identifier, dynamically allocated */
|
||||
};
|
||||
|
||||
@@ -94,17 +94,17 @@ struct IdDesc {
|
||||
/* Struct that describes a macro definition */
|
||||
struct Macro {
|
||||
HashNode Node; /* Hash list node */
|
||||
Macro* List; /* List of all macros */
|
||||
unsigned LocalCount; /* Count of local symbols */
|
||||
IdDesc* Locals; /* List of local symbols */
|
||||
unsigned ParamCount; /* Parameter count of macro */
|
||||
IdDesc* Params; /* Identifiers of macro parameters */
|
||||
unsigned TokCount; /* Number of tokens for this macro */
|
||||
TokNode* TokRoot; /* Root of token list */
|
||||
TokNode* TokLast; /* Pointer to last token in list */
|
||||
StrBuf Name; /* Macro name, dynamically allocated */
|
||||
Macro* List; /* List of all macros */
|
||||
unsigned LocalCount; /* Count of local symbols */
|
||||
IdDesc* Locals; /* List of local symbols */
|
||||
unsigned ParamCount; /* Parameter count of macro */
|
||||
IdDesc* Params; /* Identifiers of macro parameters */
|
||||
unsigned TokCount; /* Number of tokens for this macro */
|
||||
TokNode* TokRoot; /* Root of token list */
|
||||
TokNode* TokLast; /* Pointer to last token in list */
|
||||
StrBuf Name; /* Macro name, dynamically allocated */
|
||||
unsigned Expansions; /* Number of active macro expansions */
|
||||
unsigned char Style; /* Macro style */
|
||||
unsigned char Style; /* Macro style */
|
||||
unsigned char Incomplete; /* Macro is currently built */
|
||||
};
|
||||
|
||||
@@ -121,16 +121,16 @@ static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc);
|
||||
/* Structs that holds data for a macro expansion */
|
||||
typedef struct MacExp MacExp;
|
||||
struct MacExp {
|
||||
MacExp* Next; /* Pointer to next expansion */
|
||||
Macro* M; /* Which macro do we expand? */
|
||||
unsigned IfSP; /* .IF stack pointer at start of expansion */
|
||||
TokNode* Exp; /* Pointer to current token */
|
||||
TokNode* Final; /* Pointer to final token */
|
||||
MacExp* Next; /* Pointer to next expansion */
|
||||
Macro* M; /* Which macro do we expand? */
|
||||
unsigned IfSP; /* .IF stack pointer at start of expansion */
|
||||
TokNode* Exp; /* Pointer to current token */
|
||||
TokNode* Final; /* Pointer to final token */
|
||||
unsigned MacExpansions; /* Number of active macro expansions */
|
||||
unsigned LocalStart; /* Start of counter for local symbol names */
|
||||
unsigned ParamCount; /* Number of actual parameters */
|
||||
TokNode** Params; /* List of actual parameters */
|
||||
TokNode* ParamExp; /* Node for expanding parameters */
|
||||
unsigned LocalStart; /* Start of counter for local symbol names */
|
||||
unsigned ParamCount; /* Number of actual parameters */
|
||||
TokNode** Params; /* List of actual parameters */
|
||||
TokNode* ParamExp; /* Node for expanding parameters */
|
||||
LineInfo* LI; /* Line info for the expansion */
|
||||
LineInfo* ParamLI; /* Line info for parameter expansion */
|
||||
};
|
||||
@@ -186,7 +186,7 @@ static int HT_Compare (const void* Key1, const void* Key2)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -244,13 +244,13 @@ static Macro* NewMacro (const StrBuf* Name, unsigned char Style)
|
||||
M->Locals = 0;
|
||||
M->ParamCount = 0;
|
||||
M->Params = 0;
|
||||
M->TokCount = 0;
|
||||
M->TokCount = 0;
|
||||
M->TokRoot = 0;
|
||||
M->TokLast = 0;
|
||||
SB_Init (&M->Name);
|
||||
SB_Copy (&M->Name, Name);
|
||||
M->Expansions = 0;
|
||||
M->Style = Style;
|
||||
M->Style = Style;
|
||||
M->Incomplete = 1;
|
||||
|
||||
/* Insert the macro into the hash table */
|
||||
@@ -297,19 +297,19 @@ static MacExp* NewMacExp (Macro* M)
|
||||
MacExp* E = xmalloc (sizeof (MacExp));
|
||||
|
||||
/* Initialize the data */
|
||||
E->M = M;
|
||||
E->IfSP = GetIfStack ();
|
||||
E->Exp = M->TokRoot;
|
||||
E->Final = 0;
|
||||
E->M = M;
|
||||
E->IfSP = GetIfStack ();
|
||||
E->Exp = M->TokRoot;
|
||||
E->Final = 0;
|
||||
E->MacExpansions = ++MacExpansions; /* One macro expansion more */
|
||||
E->LocalStart = LocalName;
|
||||
LocalName += M->LocalCount;
|
||||
E->ParamCount = 0;
|
||||
E->Params = xmalloc (M->ParamCount * sizeof (TokNode*));
|
||||
for (I = 0; I < M->ParamCount; ++I) {
|
||||
E->Params[I] = 0;
|
||||
E->Params[I] = 0;
|
||||
}
|
||||
E->ParamExp = 0;
|
||||
E->ParamExp = 0;
|
||||
E->LI = 0;
|
||||
E->ParamLI = 0;
|
||||
|
||||
@@ -355,7 +355,7 @@ static void FreeMacExp (MacExp* E)
|
||||
|
||||
/* Free the final token if we have one */
|
||||
if (E->Final) {
|
||||
FreeTokNode (E->Final);
|
||||
FreeTokNode (E->Final);
|
||||
}
|
||||
|
||||
/* Free the structure itself */
|
||||
@@ -368,18 +368,18 @@ static void MacSkipDef (unsigned Style)
|
||||
/* Skip a macro definition */
|
||||
{
|
||||
if (Style == MAC_STYLE_CLASSIC) {
|
||||
/* Skip tokens until we reach the final .endmacro */
|
||||
while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
|
||||
NextTok ();
|
||||
}
|
||||
if (CurTok.Tok != TOK_EOF) {
|
||||
SkipUntilSep ();
|
||||
} else {
|
||||
Error ("`.ENDMACRO' expected");
|
||||
}
|
||||
/* Skip tokens until we reach the final .endmacro */
|
||||
while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
|
||||
NextTok ();
|
||||
}
|
||||
if (CurTok.Tok != TOK_EOF) {
|
||||
SkipUntilSep ();
|
||||
} else {
|
||||
Error ("`.ENDMACRO' expected");
|
||||
}
|
||||
} else {
|
||||
/* Skip until end of line */
|
||||
SkipUntilSep ();
|
||||
/* Skip until end of line */
|
||||
SkipUntilSep ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,9 +394,9 @@ void MacDef (unsigned Style)
|
||||
|
||||
/* We expect a macro name here */
|
||||
if (CurTok.Tok != TOK_IDENT) {
|
||||
Error ("Identifier expected");
|
||||
MacSkipDef (Style);
|
||||
return;
|
||||
Error ("Identifier expected");
|
||||
MacSkipDef (Style);
|
||||
return;
|
||||
} else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
|
||||
/* The identifier is a name of a 6502 instruction, which is not
|
||||
* allowed if not explicitly enabled.
|
||||
@@ -408,11 +408,11 @@ void MacDef (unsigned Style)
|
||||
|
||||
/* Did we already define that macro? */
|
||||
if (HT_Find (&MacroTab, &CurTok.SVal) != 0) {
|
||||
/* Macro is already defined */
|
||||
Error ("A macro named `%m%p' is already defined", &CurTok.SVal);
|
||||
/* Skip tokens until we reach the final .endmacro */
|
||||
MacSkipDef (Style);
|
||||
return;
|
||||
/* Macro is already defined */
|
||||
Error ("A macro named `%m%p' is already defined", &CurTok.SVal);
|
||||
/* Skip tokens until we reach the final .endmacro */
|
||||
MacSkipDef (Style);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Define the macro */
|
||||
@@ -426,62 +426,62 @@ void MacDef (unsigned Style)
|
||||
* otherwise we may have parameters without braces.
|
||||
*/
|
||||
if (Style == MAC_STYLE_CLASSIC) {
|
||||
HaveParams = 1;
|
||||
HaveParams = 1;
|
||||
} else {
|
||||
if (CurTok.Tok == TOK_LPAREN) {
|
||||
HaveParams = 1;
|
||||
NextTok ();
|
||||
} else {
|
||||
HaveParams = 0;
|
||||
}
|
||||
if (CurTok.Tok == TOK_LPAREN) {
|
||||
HaveParams = 1;
|
||||
NextTok ();
|
||||
} else {
|
||||
HaveParams = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the parameter list */
|
||||
if (HaveParams) {
|
||||
|
||||
while (CurTok.Tok == TOK_IDENT) {
|
||||
while (CurTok.Tok == TOK_IDENT) {
|
||||
|
||||
/* Create a struct holding the identifier */
|
||||
IdDesc* I = NewIdDesc (&CurTok.SVal);
|
||||
/* Create a struct holding the identifier */
|
||||
IdDesc* I = NewIdDesc (&CurTok.SVal);
|
||||
|
||||
/* Insert the struct into the list, checking for duplicate idents */
|
||||
if (M->ParamCount == 0) {
|
||||
M->Params = I;
|
||||
} else {
|
||||
IdDesc* List = M->Params;
|
||||
while (1) {
|
||||
if (SB_Compare (&List->Id, &CurTok.SVal) == 0) {
|
||||
Error ("Duplicate symbol `%m%p'", &CurTok.SVal);
|
||||
}
|
||||
if (List->Next == 0) {
|
||||
break;
|
||||
} else {
|
||||
List = List->Next;
|
||||
}
|
||||
}
|
||||
List->Next = I;
|
||||
}
|
||||
++M->ParamCount;
|
||||
/* Insert the struct into the list, checking for duplicate idents */
|
||||
if (M->ParamCount == 0) {
|
||||
M->Params = I;
|
||||
} else {
|
||||
IdDesc* List = M->Params;
|
||||
while (1) {
|
||||
if (SB_Compare (&List->Id, &CurTok.SVal) == 0) {
|
||||
Error ("Duplicate symbol `%m%p'", &CurTok.SVal);
|
||||
}
|
||||
if (List->Next == 0) {
|
||||
break;
|
||||
} else {
|
||||
List = List->Next;
|
||||
}
|
||||
}
|
||||
List->Next = I;
|
||||
}
|
||||
++M->ParamCount;
|
||||
|
||||
/* Skip the name */
|
||||
NextTok ();
|
||||
/* Skip the name */
|
||||
NextTok ();
|
||||
|
||||
/* Maybe there are more params... */
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Maybe there are more params... */
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For class macros, we expect a separator token, for define style macros,
|
||||
* we expect the closing paren.
|
||||
*/
|
||||
if (Style == MAC_STYLE_CLASSIC) {
|
||||
ConsumeSep ();
|
||||
ConsumeSep ();
|
||||
} else if (HaveParams) {
|
||||
ConsumeRParen ();
|
||||
ConsumeRParen ();
|
||||
}
|
||||
|
||||
/* Preparse the macro body. We will read the tokens until we reach end of
|
||||
@@ -491,98 +491,98 @@ void MacDef (unsigned Style)
|
||||
*/
|
||||
while (1) {
|
||||
|
||||
/* Check for end of macro */
|
||||
if (Style == MAC_STYLE_CLASSIC) {
|
||||
/* In classic macros, only .endmacro is allowed */
|
||||
if (CurTok.Tok == TOK_ENDMACRO) {
|
||||
/* Done */
|
||||
break;
|
||||
}
|
||||
/* May not have end of file in a macro definition */
|
||||
if (CurTok.Tok == TOK_EOF) {
|
||||
Error ("`.ENDMACRO' expected");
|
||||
goto Done;
|
||||
}
|
||||
} else {
|
||||
/* Accept a newline or end of file for new style macros */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Check for end of macro */
|
||||
if (Style == MAC_STYLE_CLASSIC) {
|
||||
/* In classic macros, only .endmacro is allowed */
|
||||
if (CurTok.Tok == TOK_ENDMACRO) {
|
||||
/* Done */
|
||||
break;
|
||||
}
|
||||
/* May not have end of file in a macro definition */
|
||||
if (CurTok.Tok == TOK_EOF) {
|
||||
Error ("`.ENDMACRO' expected");
|
||||
goto Done;
|
||||
}
|
||||
} else {
|
||||
/* Accept a newline or end of file for new style macros */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for a .LOCAL declaration */
|
||||
if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) {
|
||||
/* Check for a .LOCAL declaration */
|
||||
if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) {
|
||||
|
||||
while (1) {
|
||||
while (1) {
|
||||
|
||||
IdDesc* I;
|
||||
IdDesc* I;
|
||||
|
||||
/* Skip .local or comma */
|
||||
NextTok ();
|
||||
/* Skip .local or comma */
|
||||
NextTok ();
|
||||
|
||||
/* Need an identifer */
|
||||
if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) {
|
||||
Error ("Identifier expected");
|
||||
SkipUntilSep ();
|
||||
break;
|
||||
}
|
||||
/* Need an identifer */
|
||||
if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) {
|
||||
Error ("Identifier expected");
|
||||
SkipUntilSep ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Put the identifier into the locals list and skip it */
|
||||
I = NewIdDesc (&CurTok.SVal);
|
||||
I->Next = M->Locals;
|
||||
M->Locals = I;
|
||||
++M->LocalCount;
|
||||
NextTok ();
|
||||
/* Put the identifier into the locals list and skip it */
|
||||
I = NewIdDesc (&CurTok.SVal);
|
||||
I->Next = M->Locals;
|
||||
M->Locals = I;
|
||||
++M->LocalCount;
|
||||
NextTok ();
|
||||
|
||||
/* Check for end of list */
|
||||
if (CurTok.Tok != TOK_COMMA) {
|
||||
break;
|
||||
}
|
||||
/* Check for end of list */
|
||||
if (CurTok.Tok != TOK_COMMA) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* We need end of line after the locals */
|
||||
ConsumeSep ();
|
||||
continue;
|
||||
}
|
||||
/* We need end of line after the locals */
|
||||
ConsumeSep ();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a token node for the current token */
|
||||
N = NewTokNode ();
|
||||
/* Create a token node for the current token */
|
||||
N = NewTokNode ();
|
||||
|
||||
/* If the token is an identifier, check if it is a local parameter */
|
||||
if (CurTok.Tok == TOK_IDENT) {
|
||||
unsigned Count = 0;
|
||||
IdDesc* I = M->Params;
|
||||
while (I) {
|
||||
if (SB_Compare (&I->Id, &CurTok.SVal) == 0) {
|
||||
/* Local param name, replace it */
|
||||
N->T.Tok = TOK_MACPARAM;
|
||||
N->T.IVal = Count;
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
I = I->Next;
|
||||
}
|
||||
}
|
||||
if (CurTok.Tok == TOK_IDENT) {
|
||||
unsigned Count = 0;
|
||||
IdDesc* I = M->Params;
|
||||
while (I) {
|
||||
if (SB_Compare (&I->Id, &CurTok.SVal) == 0) {
|
||||
/* Local param name, replace it */
|
||||
N->T.Tok = TOK_MACPARAM;
|
||||
N->T.IVal = Count;
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
I = I->Next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert the new token in the list */
|
||||
if (M->TokCount == 0) {
|
||||
/* First token */
|
||||
M->TokRoot = M->TokLast = N;
|
||||
} else {
|
||||
/* We have already tokens */
|
||||
M->TokLast->Next = N;
|
||||
M->TokLast = N;
|
||||
}
|
||||
++M->TokCount;
|
||||
/* Insert the new token in the list */
|
||||
if (M->TokCount == 0) {
|
||||
/* First token */
|
||||
M->TokRoot = M->TokLast = N;
|
||||
} else {
|
||||
/* We have already tokens */
|
||||
M->TokLast->Next = N;
|
||||
M->TokLast = N;
|
||||
}
|
||||
++M->TokCount;
|
||||
|
||||
/* Read the next token */
|
||||
NextTok ();
|
||||
/* Read the next token */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Skip the .endmacro for a classic macro */
|
||||
if (Style == MAC_STYLE_CLASSIC) {
|
||||
NextTok ();
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Reset the Incomplete flag now that parsing is done */
|
||||
@@ -634,14 +634,14 @@ static int MacExpand (void* Data)
|
||||
/* Check if we should abort this macro */
|
||||
if (DoMacAbort) {
|
||||
|
||||
/* Reset the flag */
|
||||
DoMacAbort = 0;
|
||||
/* Reset the flag */
|
||||
DoMacAbort = 0;
|
||||
|
||||
/* Abort any open .IF statements in this macro expansion */
|
||||
CleanupIfStack (Mac->IfSP);
|
||||
/* Abort any open .IF statements in this macro expansion */
|
||||
CleanupIfStack (Mac->IfSP);
|
||||
|
||||
/* Terminate macro expansion */
|
||||
goto MacEnd;
|
||||
/* Terminate macro expansion */
|
||||
goto MacEnd;
|
||||
}
|
||||
|
||||
/* We're expanding a macro. Check if we are expanding one of the
|
||||
@@ -650,8 +650,8 @@ static int MacExpand (void* Data)
|
||||
ExpandParam:
|
||||
if (Mac->ParamExp) {
|
||||
|
||||
/* Ok, use token from parameter list */
|
||||
TokSet (Mac->ParamExp);
|
||||
/* Ok, use token from parameter list */
|
||||
TokSet (Mac->ParamExp);
|
||||
|
||||
/* Create new line info for this parameter token */
|
||||
if (Mac->ParamLI) {
|
||||
@@ -659,11 +659,11 @@ ExpandParam:
|
||||
}
|
||||
Mac->ParamLI = StartLine (&CurTok.Pos, LI_TYPE_MACPARAM, Mac->MacExpansions);
|
||||
|
||||
/* Set pointer to next token */
|
||||
Mac->ParamExp = Mac->ParamExp->Next;
|
||||
/* Set pointer to next token */
|
||||
Mac->ParamExp = Mac->ParamExp->Next;
|
||||
|
||||
/* Done */
|
||||
return 1;
|
||||
/* Done */
|
||||
return 1;
|
||||
|
||||
} else if (Mac->ParamLI) {
|
||||
|
||||
@@ -678,8 +678,8 @@ ExpandParam:
|
||||
*/
|
||||
if (Mac->Exp) {
|
||||
|
||||
/* Use next macro token */
|
||||
TokSet (Mac->Exp);
|
||||
/* Use next macro token */
|
||||
TokSet (Mac->Exp);
|
||||
|
||||
/* Create new line info for this token */
|
||||
if (Mac->LI) {
|
||||
@@ -687,35 +687,35 @@ ExpandParam:
|
||||
}
|
||||
Mac->LI = StartLine (&CurTok.Pos, LI_TYPE_MACRO, Mac->MacExpansions);
|
||||
|
||||
/* Set pointer to next token */
|
||||
Mac->Exp = Mac->Exp->Next;
|
||||
/* Set pointer to next token */
|
||||
Mac->Exp = Mac->Exp->Next;
|
||||
|
||||
/* Is it a request for actual parameter count? */
|
||||
if (CurTok.Tok == TOK_PARAMCOUNT) {
|
||||
CurTok.Tok = TOK_INTCON;
|
||||
CurTok.IVal = Mac->ParamCount;
|
||||
return 1;
|
||||
}
|
||||
/* Is it a request for actual parameter count? */
|
||||
if (CurTok.Tok == TOK_PARAMCOUNT) {
|
||||
CurTok.Tok = TOK_INTCON;
|
||||
CurTok.IVal = Mac->ParamCount;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Is it the name of a macro parameter? */
|
||||
if (CurTok.Tok == TOK_MACPARAM) {
|
||||
/* Is it the name of a macro parameter? */
|
||||
if (CurTok.Tok == TOK_MACPARAM) {
|
||||
|
||||
/* Start to expand the parameter token list */
|
||||
Mac->ParamExp = Mac->Params[CurTok.IVal];
|
||||
/* Start to expand the parameter token list */
|
||||
Mac->ParamExp = Mac->Params[CurTok.IVal];
|
||||
|
||||
/* Go back and expand the parameter */
|
||||
goto ExpandParam;
|
||||
}
|
||||
/* Go back and expand the parameter */
|
||||
goto ExpandParam;
|
||||
}
|
||||
|
||||
/* If it's an identifier, it may in fact be a local symbol */
|
||||
if ((CurTok.Tok == TOK_IDENT || CurTok.Tok == TOK_LOCAL_IDENT) &&
|
||||
/* If it's an identifier, it may in fact be a local symbol */
|
||||
if ((CurTok.Tok == TOK_IDENT || CurTok.Tok == TOK_LOCAL_IDENT) &&
|
||||
Mac->M->LocalCount) {
|
||||
/* Search for the local symbol in the list */
|
||||
unsigned Index = 0;
|
||||
IdDesc* I = Mac->M->Locals;
|
||||
while (I) {
|
||||
if (SB_Compare (&CurTok.SVal, &I->Id) == 0) {
|
||||
/* This is in fact a local symbol, change the name. Be sure
|
||||
/* Search for the local symbol in the list */
|
||||
unsigned Index = 0;
|
||||
IdDesc* I = Mac->M->Locals;
|
||||
while (I) {
|
||||
if (SB_Compare (&CurTok.SVal, &I->Id) == 0) {
|
||||
/* This is in fact a local symbol, change the name. Be sure
|
||||
* to generate a local label name if the original name was
|
||||
* a local label, and also generate a name that cannot be
|
||||
* generated by a user.
|
||||
@@ -729,28 +729,28 @@ ExpandParam:
|
||||
SB_Printf (&CurTok.SVal, "LOCAL-MACRO_SYMBOL-%04X",
|
||||
Mac->LocalStart + Index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Next symbol */
|
||||
++Index;
|
||||
I = I->Next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Next symbol */
|
||||
++Index;
|
||||
I = I->Next;
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return 1;
|
||||
}
|
||||
/* Done */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The token was successfully set */
|
||||
return 1;
|
||||
/* The token was successfully set */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* No more macro tokens. Do we have a final token? */
|
||||
if (Mac->Final) {
|
||||
|
||||
/* Set the final token and remove it */
|
||||
TokSet (Mac->Final);
|
||||
FreeTokNode (Mac->Final);
|
||||
Mac->Final = 0;
|
||||
/* Set the final token and remove it */
|
||||
TokSet (Mac->Final);
|
||||
FreeTokNode (Mac->Final);
|
||||
Mac->Final = 0;
|
||||
|
||||
/* Problem: When a .define style macro is expanded within the call
|
||||
* of a classic one, the latter may be terminated and removed while
|
||||
@@ -765,8 +765,8 @@ ExpandParam:
|
||||
FreeMacExp (Mac);
|
||||
PopInput ();
|
||||
|
||||
/* The token was successfully set */
|
||||
return 1;
|
||||
/* The token was successfully set */
|
||||
return 1;
|
||||
}
|
||||
|
||||
MacEnd:
|
||||
@@ -793,47 +793,47 @@ static void StartExpClassic (MacExp* E)
|
||||
/* Read the actual parameters */
|
||||
while (!TokIsSep (CurTok.Tok)) {
|
||||
|
||||
TokNode* Last;
|
||||
TokNode* Last;
|
||||
|
||||
/* Check for maximum parameter count */
|
||||
if (E->ParamCount >= E->M->ParamCount) {
|
||||
ErrorSkip ("Too many macro parameters");
|
||||
break;
|
||||
}
|
||||
/* Check for maximum parameter count */
|
||||
if (E->ParamCount >= E->M->ParamCount) {
|
||||
ErrorSkip ("Too many macro parameters");
|
||||
break;
|
||||
}
|
||||
|
||||
/* The macro may optionally be enclosed in curly braces */
|
||||
Term = GetTokListTerm (TOK_COMMA);
|
||||
|
||||
/* Read tokens for one parameter, accept empty params */
|
||||
Last = 0;
|
||||
while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) {
|
||||
/* Read tokens for one parameter, accept empty params */
|
||||
Last = 0;
|
||||
while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) {
|
||||
|
||||
TokNode* T;
|
||||
TokNode* T;
|
||||
|
||||
/* Check for end of file */
|
||||
if (CurTok.Tok == TOK_EOF) {
|
||||
Error ("Unexpected end of file");
|
||||
/* Check for end of file */
|
||||
if (CurTok.Tok == TOK_EOF) {
|
||||
Error ("Unexpected end of file");
|
||||
FreeMacExp (E);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the next token in a node */
|
||||
T = NewTokNode ();
|
||||
/* Get the next token in a node */
|
||||
T = NewTokNode ();
|
||||
|
||||
/* Insert it into the list */
|
||||
if (Last == 0) {
|
||||
E->Params [E->ParamCount] = T;
|
||||
} else {
|
||||
Last->Next = T;
|
||||
}
|
||||
Last = T;
|
||||
/* Insert it into the list */
|
||||
if (Last == 0) {
|
||||
E->Params [E->ParamCount] = T;
|
||||
} else {
|
||||
Last->Next = T;
|
||||
}
|
||||
Last = T;
|
||||
|
||||
/* And skip it... */
|
||||
NextTok ();
|
||||
}
|
||||
/* And skip it... */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* One parameter more */
|
||||
++E->ParamCount;
|
||||
/* One parameter more */
|
||||
++E->ParamCount;
|
||||
|
||||
/* If the macro argument was enclosed in curly braces, end-of-line
|
||||
* is an error. Skip the closing curly brace.
|
||||
@@ -846,12 +846,12 @@ static void StartExpClassic (MacExp* E)
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Check for a comma */
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
/* Check for a comma */
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We must be at end of line now, otherwise something is wrong */
|
||||
@@ -877,42 +877,42 @@ static void StartExpDefine (MacExp* E)
|
||||
/* Read the actual parameters */
|
||||
while (Count--) {
|
||||
|
||||
TokNode* Last;
|
||||
TokNode* Last;
|
||||
|
||||
/* The macro may optionally be enclosed in curly braces */
|
||||
token_t Term = GetTokListTerm (TOK_COMMA);
|
||||
|
||||
/* Check if there is really a parameter */
|
||||
if (TokIsSep (CurTok.Tok) || CurTok.Tok == Term) {
|
||||
/* Check if there is really a parameter */
|
||||
if (TokIsSep (CurTok.Tok) || CurTok.Tok == Term) {
|
||||
ErrorSkip ("Macro parameter #%u is empty", E->ParamCount+1);
|
||||
FreeMacExp (E);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read tokens for one parameter */
|
||||
Last = 0;
|
||||
do {
|
||||
/* Read tokens for one parameter */
|
||||
Last = 0;
|
||||
do {
|
||||
|
||||
TokNode* T;
|
||||
TokNode* T;
|
||||
|
||||
/* Get the next token in a node */
|
||||
T = NewTokNode ();
|
||||
/* Get the next token in a node */
|
||||
T = NewTokNode ();
|
||||
|
||||
/* Insert it into the list */
|
||||
if (Last == 0) {
|
||||
E->Params [E->ParamCount] = T;
|
||||
} else {
|
||||
Last->Next = T;
|
||||
}
|
||||
Last = T;
|
||||
/* Insert it into the list */
|
||||
if (Last == 0) {
|
||||
E->Params [E->ParamCount] = T;
|
||||
} else {
|
||||
Last->Next = T;
|
||||
}
|
||||
Last = T;
|
||||
|
||||
/* And skip it... */
|
||||
NextTok ();
|
||||
/* And skip it... */
|
||||
NextTok ();
|
||||
|
||||
} while (CurTok.Tok != Term && !TokIsSep (CurTok.Tok));
|
||||
} while (CurTok.Tok != Term && !TokIsSep (CurTok.Tok));
|
||||
|
||||
/* One parameter more */
|
||||
++E->ParamCount;
|
||||
/* One parameter more */
|
||||
++E->ParamCount;
|
||||
|
||||
/* If the macro argument was enclosed in curly braces, end-of-line
|
||||
* is an error. Skip the closing curly brace.
|
||||
@@ -925,14 +925,14 @@ static void StartExpDefine (MacExp* E)
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Check for a comma */
|
||||
if (Count > 0) {
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
Error ("`,' expected");
|
||||
}
|
||||
}
|
||||
/* Check for a comma */
|
||||
if (Count > 0) {
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
Error ("`,' expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Macro expansion will overwrite the current token. This is a problem
|
||||
@@ -975,9 +975,9 @@ void MacExpandStart (Macro* M)
|
||||
|
||||
/* Call the apropriate subroutine */
|
||||
switch (M->Style) {
|
||||
case MAC_STYLE_CLASSIC: StartExpClassic (E); break;
|
||||
case MAC_STYLE_DEFINE: StartExpDefine (E); break;
|
||||
default: Internal ("Invalid macro style: %d", M->Style);
|
||||
case MAC_STYLE_CLASSIC: StartExpClassic (E); break;
|
||||
case MAC_STYLE_DEFINE: StartExpDefine (E); break;
|
||||
default: Internal ("Invalid macro style: %d", M->Style);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* macro.h */
|
||||
/* macro.h */
|
||||
/* */
|
||||
/* Macros for the ca65 macroassembler */
|
||||
/* Macros for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,14 +49,14 @@ struct StrBuf;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Macro styles */
|
||||
#define MAC_STYLE_CLASSIC 0
|
||||
#define MAC_STYLE_DEFINE 1
|
||||
#define MAC_STYLE_CLASSIC 0
|
||||
#define MAC_STYLE_DEFINE 1
|
||||
|
||||
/* Macro as an opaque data type */
|
||||
struct Macro;
|
||||
@@ -65,7 +65,7 @@ typedef struct Macro Macro;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
356
src/ca65/main.c
356
src/ca65/main.c
@@ -1,7 +1,7 @@
|
||||
/* */
|
||||
/* main.c */
|
||||
/* main.c */
|
||||
/* */
|
||||
/* Main program for the ca65 macroassembler */
|
||||
/* Main program for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ static void NewSymbol (const char* SymName, long Val)
|
||||
|
||||
/* Check if have already a symbol with this name */
|
||||
if (SymIsDef (Sym)) {
|
||||
AbEnd ("`%s' is already defined", SymName);
|
||||
AbEnd ("`%s' is already defined", SymName);
|
||||
}
|
||||
|
||||
/* Generate an expression for the symbol */
|
||||
@@ -197,75 +197,75 @@ static void SetSys (const char* Sys)
|
||||
{
|
||||
switch (Target = FindTarget (Sys)) {
|
||||
|
||||
case TGT_NONE:
|
||||
break;
|
||||
case TGT_NONE:
|
||||
break;
|
||||
|
||||
case TGT_MODULE:
|
||||
AbEnd ("Cannot use `module' as a target for the assembler");
|
||||
break;
|
||||
|
||||
case TGT_ATARI:
|
||||
NewSymbol ("__ATARI__", 1);
|
||||
break;
|
||||
case TGT_ATARI:
|
||||
NewSymbol ("__ATARI__", 1);
|
||||
break;
|
||||
|
||||
case TGT_C16:
|
||||
CBMSystem ("__C16__");
|
||||
break;
|
||||
case TGT_C16:
|
||||
CBMSystem ("__C16__");
|
||||
break;
|
||||
|
||||
case TGT_C64:
|
||||
CBMSystem ("__C64__");
|
||||
break;
|
||||
case TGT_C64:
|
||||
CBMSystem ("__C64__");
|
||||
break;
|
||||
|
||||
case TGT_VIC20:
|
||||
CBMSystem ("__VIC20__");
|
||||
break;
|
||||
case TGT_VIC20:
|
||||
CBMSystem ("__VIC20__");
|
||||
break;
|
||||
|
||||
case TGT_C128:
|
||||
CBMSystem ("__C128__");
|
||||
break;
|
||||
case TGT_C128:
|
||||
CBMSystem ("__C128__");
|
||||
break;
|
||||
|
||||
case TGT_PLUS4:
|
||||
CBMSystem ("__PLUS4__");
|
||||
break;
|
||||
case TGT_PLUS4:
|
||||
CBMSystem ("__PLUS4__");
|
||||
break;
|
||||
|
||||
case TGT_CBM510:
|
||||
CBMSystem ("__CBM510__");
|
||||
break;
|
||||
case TGT_CBM510:
|
||||
CBMSystem ("__CBM510__");
|
||||
break;
|
||||
|
||||
case TGT_CBM610:
|
||||
CBMSystem ("__CBM610__");
|
||||
break;
|
||||
case TGT_CBM610:
|
||||
CBMSystem ("__CBM610__");
|
||||
break;
|
||||
|
||||
case TGT_PET:
|
||||
CBMSystem ("__PET__");
|
||||
break;
|
||||
case TGT_PET:
|
||||
CBMSystem ("__PET__");
|
||||
break;
|
||||
|
||||
case TGT_BBC:
|
||||
NewSymbol ("__BBC__", 1);
|
||||
break;
|
||||
case TGT_BBC:
|
||||
NewSymbol ("__BBC__", 1);
|
||||
break;
|
||||
|
||||
case TGT_APPLE2:
|
||||
NewSymbol ("__APPLE2__", 1);
|
||||
break;
|
||||
case TGT_APPLE2:
|
||||
NewSymbol ("__APPLE2__", 1);
|
||||
break;
|
||||
|
||||
case TGT_APPLE2ENH:
|
||||
case TGT_APPLE2ENH:
|
||||
NewSymbol ("__APPLE2ENH__", 1);
|
||||
break;
|
||||
break;
|
||||
|
||||
case TGT_GEOS_CBM:
|
||||
/* Do not handle as a CBM system */
|
||||
NewSymbol ("__GEOS__", 1);
|
||||
NewSymbol ("__GEOS_CBM__", 1);
|
||||
break;
|
||||
case TGT_GEOS_CBM:
|
||||
/* Do not handle as a CBM system */
|
||||
NewSymbol ("__GEOS__", 1);
|
||||
NewSymbol ("__GEOS_CBM__", 1);
|
||||
break;
|
||||
|
||||
case TGT_GEOS_APPLE:
|
||||
NewSymbol ("__GEOS__", 1);
|
||||
NewSymbol ("__GEOS_APPLE__", 1);
|
||||
break;
|
||||
case TGT_GEOS_APPLE:
|
||||
NewSymbol ("__GEOS__", 1);
|
||||
NewSymbol ("__GEOS_APPLE__", 1);
|
||||
break;
|
||||
|
||||
case TGT_LUNIX:
|
||||
NewSymbol ("__LUNIX__", 1);
|
||||
break;
|
||||
case TGT_LUNIX:
|
||||
NewSymbol ("__LUNIX__", 1);
|
||||
break;
|
||||
|
||||
case TGT_ATMOS:
|
||||
NewSymbol ("__ATMOS__", 1);
|
||||
@@ -283,7 +283,7 @@ static void SetSys (const char* Sys)
|
||||
NewSymbol ("__LYNX__", 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
AbEnd ("Invalid target name: `%s'", Sys);
|
||||
|
||||
}
|
||||
@@ -318,7 +318,7 @@ static void DefineSymbol (const char* Def)
|
||||
|
||||
/* The symbol must start with a character or underline */
|
||||
if (!IsIdStart (Def [0])) {
|
||||
InvDef (Def);
|
||||
InvDef (Def);
|
||||
}
|
||||
P = Def;
|
||||
|
||||
@@ -330,23 +330,23 @@ static void DefineSymbol (const char* Def)
|
||||
|
||||
/* Do we have a value given? */
|
||||
if (*P != '=') {
|
||||
if (*P != '\0') {
|
||||
InvDef (Def);
|
||||
}
|
||||
Val = 0;
|
||||
if (*P != '\0') {
|
||||
InvDef (Def);
|
||||
}
|
||||
Val = 0;
|
||||
} else {
|
||||
/* We have a value */
|
||||
++P;
|
||||
if (*P == '$') {
|
||||
++P;
|
||||
if (sscanf (P, "%lx", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
} else {
|
||||
if (sscanf (P, "%li", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
}
|
||||
/* We have a value */
|
||||
++P;
|
||||
if (*P == '$') {
|
||||
++P;
|
||||
if (sscanf (P, "%lx", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
} else {
|
||||
if (sscanf (P, "%li", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Define the new symbol */
|
||||
@@ -359,7 +359,7 @@ static void DefineSymbol (const char* Def)
|
||||
|
||||
|
||||
static void OptAutoImport (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Mark unresolved symbols as imported */
|
||||
{
|
||||
AutoImport = 1;
|
||||
@@ -380,9 +380,9 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
|
||||
{
|
||||
cpu_t CPU = FindCPU (Arg);
|
||||
if (CPU == CPU_UNKNOWN) {
|
||||
AbEnd ("Invalid CPU: `%s'", Arg);
|
||||
AbEnd ("Invalid CPU: `%s'", Arg);
|
||||
} else {
|
||||
SetCPU (CPU);
|
||||
SetCPU (CPU);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ static void OptCreateDep (const char* Opt, const char* Arg)
|
||||
|
||||
|
||||
static void OptCreateFullDep (const char* Opt attribute ((unused)),
|
||||
const char* Arg)
|
||||
const char* Arg)
|
||||
/* Handle the --create-full-dep option */
|
||||
{
|
||||
FileNameOption (Opt, Arg, &FullDepName);
|
||||
@@ -406,7 +406,7 @@ static void OptCreateFullDep (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
static void OptDebug (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Compiler debug mode */
|
||||
{
|
||||
++Debug;
|
||||
@@ -415,7 +415,7 @@ static void OptDebug (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
static void OptDebugInfo (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Add debug info to the object file */
|
||||
{
|
||||
DbgSyms = 1;
|
||||
@@ -431,14 +431,14 @@ static void OptFeature (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
/* Set the feature, check for errors */
|
||||
if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) {
|
||||
AbEnd ("Illegal emulation feature: `%s'", Arg);
|
||||
AbEnd ("Illegal emulation feature: `%s'", Arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptHelp (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Print usage information and exit */
|
||||
{
|
||||
Usage ();
|
||||
@@ -448,7 +448,7 @@ static void OptHelp (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
static void OptIgnoreCase (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Ignore case on symbols */
|
||||
{
|
||||
IgnoreCase = 1;
|
||||
@@ -465,7 +465,7 @@ static void OptIncludeDir (const char* Opt attribute ((unused)), const char* Arg
|
||||
|
||||
|
||||
static void OptLargeAlignment (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Don't warn about large alignments */
|
||||
{
|
||||
LargeAlignment = 1;
|
||||
@@ -541,7 +541,7 @@ static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg
|
||||
{
|
||||
int Len = atoi (Arg);
|
||||
if (Len != -1 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) {
|
||||
AbEnd ("Invalid page length: %d", Len);
|
||||
AbEnd ("Invalid page length: %d", Len);
|
||||
}
|
||||
PageLength = Len;
|
||||
}
|
||||
@@ -549,7 +549,7 @@ static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg
|
||||
|
||||
|
||||
static void OptRelaxChecks (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the --relax-checks options */
|
||||
{
|
||||
RelaxChecks = 1;
|
||||
@@ -558,7 +558,7 @@ static void OptRelaxChecks (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
static void OptSmart (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the -s/--smart options */
|
||||
{
|
||||
SmartMode = 1;
|
||||
@@ -575,7 +575,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
static void OptVerbose (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Increase verbosity */
|
||||
{
|
||||
++Verbosity;
|
||||
@@ -584,7 +584,7 @@ static void OptVerbose (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
static void OptVersion (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Print the assembler version */
|
||||
{
|
||||
fprintf (stderr, "ca65 V%s\n", GetVersionAsString ());
|
||||
@@ -597,9 +597,9 @@ static void DoPCAssign (void)
|
||||
{
|
||||
long PC = ConstExpression ();
|
||||
if (PC < 0 || PC > 0xFFFFFF) {
|
||||
Error ("Range error");
|
||||
Error ("Range error");
|
||||
} else {
|
||||
EnterAbsoluteMode (PC);
|
||||
EnterAbsoluteMode (PC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,13 +618,13 @@ static void OneLine (void)
|
||||
* and not from internally pushed input.
|
||||
*/
|
||||
if (!HavePushedInput ()) {
|
||||
InitListingLine ();
|
||||
InitListingLine ();
|
||||
}
|
||||
|
||||
/* Single colon means unnamed label */
|
||||
if (CurTok.Tok == TOK_COLON) {
|
||||
ULabDef ();
|
||||
NextTok ();
|
||||
ULabDef ();
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* If the first token on the line is an identifier, check for a macro or
|
||||
@@ -794,7 +794,7 @@ static void Assemble (void)
|
||||
|
||||
/* Assemble lines until end of file */
|
||||
while (CurTok.Tok != TOK_EOF) {
|
||||
OneLine ();
|
||||
OneLine ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,27 +850,27 @@ int main (int argc, char* argv [])
|
||||
{
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--auto-import", 0, OptAutoImport },
|
||||
{ "--auto-import", 0, OptAutoImport },
|
||||
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--create-dep", 1, OptCreateDep },
|
||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||
{ "--debug", 0, OptDebug },
|
||||
{ "--debug-info", 0, OptDebugInfo },
|
||||
{ "--feature", 1, OptFeature },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--ignore-case", 0, OptIgnoreCase },
|
||||
{ "--include-dir", 1, OptIncludeDir },
|
||||
{ "--debug", 0, OptDebug },
|
||||
{ "--debug-info", 0, OptDebugInfo },
|
||||
{ "--feature", 1, OptFeature },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--ignore-case", 0, OptIgnoreCase },
|
||||
{ "--include-dir", 1, OptIncludeDir },
|
||||
{ "--large-alignment", 0, OptLargeAlignment },
|
||||
{ "--list-bytes", 1, OptListBytes },
|
||||
{ "--listing", 1, OptListing },
|
||||
{ "--listing", 1, OptListing },
|
||||
{ "--memory-model", 1, OptMemoryModel },
|
||||
{ "--pagelength", 1, OptPageLength },
|
||||
{ "--pagelength", 1, OptPageLength },
|
||||
{ "--relax-checks", 0, OptRelaxChecks },
|
||||
{ "--smart", 0, OptSmart },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--smart", 0, OptSmart },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
};
|
||||
|
||||
/* Name of the global name space */
|
||||
@@ -904,36 +904,36 @@ int main (int argc, char* argv [])
|
||||
I = 1;
|
||||
while (I < ArgCount) {
|
||||
|
||||
/* Get the argument */
|
||||
const char* Arg = ArgVec [I];
|
||||
/* Get the argument */
|
||||
const char* Arg = ArgVec [I];
|
||||
|
||||
/* Check for an option */
|
||||
if (Arg[0] == '-') {
|
||||
switch (Arg[1]) {
|
||||
/* Check for an option */
|
||||
if (Arg[0] == '-') {
|
||||
switch (Arg[1]) {
|
||||
|
||||
case '-':
|
||||
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
|
||||
break;
|
||||
case '-':
|
||||
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
OptDebug (Arg, 0);
|
||||
break;
|
||||
case 'd':
|
||||
OptDebug (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
OptDebugInfo (Arg, 0);
|
||||
break;
|
||||
case 'g':
|
||||
OptDebugInfo (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
OptHelp (Arg, 0);
|
||||
break;
|
||||
case 'h':
|
||||
OptHelp (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
OptIgnoreCase (Arg, 0);
|
||||
break;
|
||||
case 'i':
|
||||
OptIgnoreCase (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
OptListing (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 'l':
|
||||
OptListing (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (Arg[2] == 'm') {
|
||||
@@ -943,66 +943,66 @@ int main (int argc, char* argv [])
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
OutFile = GetArg (&I, 2);
|
||||
break;
|
||||
case 'o':
|
||||
OutFile = GetArg (&I, 2);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
OptSmart (Arg, 0);
|
||||
break;
|
||||
case 's':
|
||||
OptSmart (Arg, 0);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
OptTarget (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 't':
|
||||
OptTarget (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
OptVerbose (Arg, 0);
|
||||
break;
|
||||
case 'v':
|
||||
OptVerbose (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
DefineSymbol (GetArg (&I, 2));
|
||||
break;
|
||||
case 'D':
|
||||
DefineSymbol (GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
OptIncludeDir (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 'I':
|
||||
OptIncludeDir (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
OptAutoImport (Arg, 0);
|
||||
break;
|
||||
case 'U':
|
||||
OptAutoImport (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
OptVersion (Arg, 0);
|
||||
break;
|
||||
case 'V':
|
||||
OptVersion (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
WarnLevel = atoi (GetArg (&I, 2));
|
||||
break;
|
||||
case 'W':
|
||||
WarnLevel = atoi (GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
default:
|
||||
UnknownOption (Arg);
|
||||
break;
|
||||
default:
|
||||
UnknownOption (Arg);
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
/* Filename. Check if we already had one */
|
||||
if (InFile) {
|
||||
fprintf (stderr, "%s: Don't know what to do with `%s'\n",
|
||||
ProgName, Arg);
|
||||
exit (EXIT_FAILURE);
|
||||
} else {
|
||||
InFile = Arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Filename. Check if we already had one */
|
||||
if (InFile) {
|
||||
fprintf (stderr, "%s: Don't know what to do with `%s'\n",
|
||||
ProgName, Arg);
|
||||
exit (EXIT_FAILURE);
|
||||
} else {
|
||||
InFile = Arg;
|
||||
}
|
||||
}
|
||||
|
||||
/* Next argument */
|
||||
++I;
|
||||
/* Next argument */
|
||||
++I;
|
||||
}
|
||||
|
||||
/* Do we have an input file? */
|
||||
if (InFile == 0) {
|
||||
fprintf (stderr, "%s: No input files\n", ProgName);
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf (stderr, "%s: No input files\n", ProgName);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Add the default include search paths. */
|
||||
@@ -1082,10 +1082,10 @@ int main (int argc, char* argv [])
|
||||
* dependency files
|
||||
*/
|
||||
if (ErrorCount == 0) {
|
||||
CreateObjFile ();
|
||||
if (SB_GetLen (&ListingName) > 0) {
|
||||
CreateListing ();
|
||||
}
|
||||
CreateObjFile ();
|
||||
if (SB_GetLen (&ListingName) > 0) {
|
||||
CreateListing ();
|
||||
}
|
||||
CreateDependencies ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* nexttok.c */
|
||||
/* nexttok.c */
|
||||
/* */
|
||||
/* Get next token and handle token level functions */
|
||||
/* Get next token and handle token level functions */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -53,12 +53,12 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static unsigned RawMode = 0; /* Raw token mode flag/counter */
|
||||
static unsigned RawMode = 0; /* Raw token mode flag/counter */
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ static int LookAtStrCon (void)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -109,21 +109,21 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
|
||||
unsigned Current = 0;
|
||||
while (CurTok.Tok != Term) {
|
||||
|
||||
/* Check for end of line or end of input */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
Error ("Unexpected end of line");
|
||||
return List;
|
||||
}
|
||||
/* Check for end of line or end of input */
|
||||
if (TokIsSep (CurTok.Tok)) {
|
||||
Error ("Unexpected end of line");
|
||||
return List;
|
||||
}
|
||||
|
||||
/* Collect tokens in the given range */
|
||||
if (Current >= Start && Current < Start+Count) {
|
||||
/* Add the current token to the list */
|
||||
AddCurTok (List);
|
||||
}
|
||||
/* Collect tokens in the given range */
|
||||
if (Current >= Start && Current < Start+Count) {
|
||||
/* Add the current token to the list */
|
||||
AddCurTok (List);
|
||||
}
|
||||
|
||||
/* Get the next token */
|
||||
++Current;
|
||||
NextTok ();
|
||||
/* Get the next token */
|
||||
++Current;
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Eat the terminator token */
|
||||
@@ -154,35 +154,35 @@ static void FuncConcat (void)
|
||||
/* Concatenate any number of strings */
|
||||
while (1) {
|
||||
|
||||
/* Next token must be a string */
|
||||
/* Next token must be a string */
|
||||
if (!LookAtStrCon ()) {
|
||||
SB_Done (&Buf);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append the string */
|
||||
SB_Append (&Buf, &CurTok.SVal);
|
||||
|
||||
/* Skip the string token */
|
||||
NextTok ();
|
||||
/* Skip the string token */
|
||||
NextTok ();
|
||||
|
||||
/* Comma means another argument */
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
/* Done */
|
||||
break;
|
||||
}
|
||||
/* Comma means another argument */
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
NextTok ();
|
||||
} else {
|
||||
/* Done */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We expect a closing parenthesis, but will not skip it but replace it
|
||||
* by the string token just created.
|
||||
*/
|
||||
if (CurTok.Tok != TOK_RPAREN) {
|
||||
Error ("`)' expected");
|
||||
Error ("`)' expected");
|
||||
} else {
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
SB_Copy (&CurTok.SVal, &Buf);
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
SB_Copy (&CurTok.SVal, &Buf);
|
||||
SB_Terminate (&CurTok.SVal);
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ static void FuncIdent (void)
|
||||
SB_Copy (&Buf, &CurTok.SVal);
|
||||
NextTok ();
|
||||
if (CurTok.Tok != TOK_RPAREN) {
|
||||
Error ("`)' expected");
|
||||
Error ("`)' expected");
|
||||
} else {
|
||||
CurTok.Tok = Id;
|
||||
SB_Copy (&CurTok.SVal, &Buf);
|
||||
@@ -269,8 +269,8 @@ static void FuncIdent (void)
|
||||
static void FuncLeft (void)
|
||||
/* Handle the .LEFT function */
|
||||
{
|
||||
long Count;
|
||||
TokList* List;
|
||||
long Count;
|
||||
TokList* List;
|
||||
|
||||
/* Skip it */
|
||||
NextTok ();
|
||||
@@ -281,7 +281,7 @@ static void FuncLeft (void)
|
||||
/* Count argument. Correct negative counts to zero. */
|
||||
Count = ConstExpression ();
|
||||
if (Count < 0) {
|
||||
Count = 0;
|
||||
Count = 0;
|
||||
}
|
||||
ConsumeComma ();
|
||||
|
||||
@@ -309,9 +309,9 @@ static void FuncLeft (void)
|
||||
static void FuncMid (void)
|
||||
/* Handle the .MID function */
|
||||
{
|
||||
long Start;
|
||||
long Count;
|
||||
TokList* List;
|
||||
long Start;
|
||||
long Count;
|
||||
TokList* List;
|
||||
|
||||
/* Skip it */
|
||||
NextTok ();
|
||||
@@ -324,7 +324,7 @@ static void FuncMid (void)
|
||||
*/
|
||||
Start = ConstExpression ();
|
||||
if (Start < 0 || Start > 100) {
|
||||
Start = 0;
|
||||
Start = 0;
|
||||
}
|
||||
ConsumeComma ();
|
||||
|
||||
@@ -333,7 +333,7 @@ static void FuncMid (void)
|
||||
*/
|
||||
Count = ConstExpression ();
|
||||
if (Count < 0) {
|
||||
Count = 0;
|
||||
Count = 0;
|
||||
}
|
||||
ConsumeComma ();
|
||||
|
||||
@@ -361,8 +361,8 @@ static void FuncMid (void)
|
||||
static void FuncRight (void)
|
||||
/* Handle the .RIGHT function */
|
||||
{
|
||||
long Count;
|
||||
TokList* List;
|
||||
long Count;
|
||||
TokList* List;
|
||||
|
||||
/* Skip it */
|
||||
NextTok ();
|
||||
@@ -373,7 +373,7 @@ static void FuncRight (void)
|
||||
/* Count argument. Correct negative counts to zero. */
|
||||
Count = ConstExpression ();
|
||||
if (Count < 0) {
|
||||
Count = 0;
|
||||
Count = 0;
|
||||
}
|
||||
ConsumeComma ();
|
||||
|
||||
@@ -382,17 +382,17 @@ static void FuncRight (void)
|
||||
|
||||
/* Delete tokens from the list until Count tokens are remaining */
|
||||
while (List->Count > (unsigned) Count) {
|
||||
/* Get the first node */
|
||||
TokNode* T = List->Root;
|
||||
/* Get the first node */
|
||||
TokNode* T = List->Root;
|
||||
|
||||
/* Remove it from the list */
|
||||
List->Root = List->Root->Next;
|
||||
/* Remove it from the list */
|
||||
List->Root = List->Root->Next;
|
||||
|
||||
/* Free the node */
|
||||
FreeTokNode (T);
|
||||
/* Free the node */
|
||||
FreeTokNode (T);
|
||||
|
||||
/* Corrent the token counter */
|
||||
List->Count--;
|
||||
/* Corrent the token counter */
|
||||
List->Count--;
|
||||
}
|
||||
|
||||
/* Since we want to insert the list before the now current token, we have
|
||||
@@ -600,9 +600,9 @@ static void FuncSPrintF (void)
|
||||
* by the string token just created.
|
||||
*/
|
||||
if (CurTok.Tok != TOK_RPAREN) {
|
||||
Error ("`)' expected");
|
||||
Error ("`)' expected");
|
||||
} else {
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
SB_Copy (&CurTok.SVal, &R);
|
||||
SB_Terminate (&CurTok.SVal);
|
||||
}
|
||||
@@ -630,9 +630,9 @@ static void FuncString (void)
|
||||
|
||||
/* Accept identifiers or numeric expressions */
|
||||
if (CurTok.Tok == TOK_LOCAL_IDENT) {
|
||||
/* Save the identifier, then skip it */
|
||||
SB_Copy (&Buf, &CurTok.SVal);
|
||||
NextTok ();
|
||||
/* Save the identifier, then skip it */
|
||||
SB_Copy (&Buf, &CurTok.SVal);
|
||||
NextTok ();
|
||||
} else if (CurTok.Tok == TOK_NAMESPACE || CurTok.Tok == TOK_IDENT) {
|
||||
|
||||
/* Parse a fully qualified symbol name. We cannot use
|
||||
@@ -651,19 +651,19 @@ static void FuncString (void)
|
||||
(NameSpace == 0 && CurTok.Tok == TOK_NAMESPACE));
|
||||
|
||||
} else {
|
||||
/* Numeric expression */
|
||||
long Val = ConstExpression ();
|
||||
SB_Printf (&Buf, "%ld", Val);
|
||||
/* Numeric expression */
|
||||
long Val = ConstExpression ();
|
||||
SB_Printf (&Buf, "%ld", Val);
|
||||
}
|
||||
|
||||
/* We expect a closing parenthesis, but will not skip it but replace it
|
||||
* by the string token just created.
|
||||
*/
|
||||
if (CurTok.Tok != TOK_RPAREN) {
|
||||
Error ("`)' expected");
|
||||
Error ("`)' expected");
|
||||
} else {
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
SB_Copy (&CurTok.SVal, &Buf);
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
SB_Copy (&CurTok.SVal, &Buf);
|
||||
SB_Terminate (&CurTok.SVal);
|
||||
}
|
||||
|
||||
@@ -684,42 +684,42 @@ void NextTok (void)
|
||||
*/
|
||||
if (RawMode == 0 && IfCond) {
|
||||
|
||||
/* Execute token handling functions */
|
||||
switch (CurTok.Tok) {
|
||||
/* Execute token handling functions */
|
||||
switch (CurTok.Tok) {
|
||||
|
||||
case TOK_CONCAT:
|
||||
FuncConcat ();
|
||||
break;
|
||||
case TOK_CONCAT:
|
||||
FuncConcat ();
|
||||
break;
|
||||
|
||||
case TOK_LEFT:
|
||||
FuncLeft ();
|
||||
break;
|
||||
case TOK_LEFT:
|
||||
FuncLeft ();
|
||||
break;
|
||||
|
||||
case TOK_MAKEIDENT:
|
||||
FuncIdent ();
|
||||
break;
|
||||
|
||||
case TOK_MID:
|
||||
FuncMid ();
|
||||
break;
|
||||
case TOK_MID:
|
||||
FuncMid ();
|
||||
break;
|
||||
|
||||
case TOK_RIGHT:
|
||||
FuncRight ();
|
||||
break;
|
||||
case TOK_RIGHT:
|
||||
FuncRight ();
|
||||
break;
|
||||
|
||||
case TOK_SPRINTF:
|
||||
FuncSPrintF ();
|
||||
break;
|
||||
|
||||
case TOK_STRING:
|
||||
FuncString ();
|
||||
break;
|
||||
case TOK_STRING:
|
||||
FuncString ();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Quiet down gcc */
|
||||
break;
|
||||
default:
|
||||
/* Quiet down gcc */
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,9 +729,9 @@ void Consume (token_t Expected, const char* ErrMsg)
|
||||
/* Consume Expected, print an error if we don't find it */
|
||||
{
|
||||
if (CurTok.Tok == Expected) {
|
||||
NextTok ();
|
||||
NextTok ();
|
||||
} else {
|
||||
Error ("%s", ErrMsg);
|
||||
Error ("%s", ErrMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ void ConsumeSep (void)
|
||||
|
||||
/* If we are at end of line, skip it */
|
||||
if (CurTok.Tok == TOK_SEP) {
|
||||
NextTok ();
|
||||
NextTok ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -779,7 +779,7 @@ void SkipUntilSep (void)
|
||||
/* Skip tokens until we reach a line separator or end of file */
|
||||
{
|
||||
while (!TokIsSep (CurTok.Tok)) {
|
||||
NextTok ();
|
||||
NextTok ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,7 +791,7 @@ void ExpectSep (void)
|
||||
*/
|
||||
{
|
||||
if (!TokIsSep (CurTok.Tok)) {
|
||||
ErrorSkip ("Unexpected trailing garbage characters");
|
||||
ErrorSkip ("Unexpected trailing garbage characters");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* nexttok.h */
|
||||
/* nexttok.h */
|
||||
/* */
|
||||
/* Get next token and handle token level functions */
|
||||
/* Get next token and handle token level functions */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objcode.c */
|
||||
/* objcode.c */
|
||||
/* */
|
||||
/* Objectcode management for the ca65 macroassembler */
|
||||
/* Objectcode management for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -159,23 +159,23 @@ void EmitData (const void* D, unsigned Size)
|
||||
|
||||
/* Create lots of fragments for the data */
|
||||
while (Size) {
|
||||
Fragment* F;
|
||||
Fragment* F;
|
||||
|
||||
/* Determine the length of the next fragment */
|
||||
unsigned Len = Size;
|
||||
if (Len > sizeof (F->V.Data)) {
|
||||
Len = sizeof (F->V.Data);
|
||||
}
|
||||
/* Determine the length of the next fragment */
|
||||
unsigned Len = Size;
|
||||
if (Len > sizeof (F->V.Data)) {
|
||||
Len = sizeof (F->V.Data);
|
||||
}
|
||||
|
||||
/* Create a new fragment */
|
||||
F = GenFragment (FRAG_LITERAL, Len);
|
||||
/* Create a new fragment */
|
||||
F = GenFragment (FRAG_LITERAL, Len);
|
||||
|
||||
/* Copy the data */
|
||||
memcpy (F->V.Data, Data, Len);
|
||||
/* Copy the data */
|
||||
memcpy (F->V.Data, Data, Len);
|
||||
|
||||
/* Next chunk */
|
||||
Data += Len;
|
||||
Size -= Len;
|
||||
/* Next chunk */
|
||||
Data += Len;
|
||||
Size -= Len;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -270,12 +270,12 @@ void EmitFill (unsigned long Count)
|
||||
/* Emit Count fill bytes */
|
||||
{
|
||||
while (Count) {
|
||||
/* Calculate the size of the next chunk */
|
||||
unsigned Chunk = (Count > 0xFFFF)? 0xFFFF : (unsigned) Count;
|
||||
Count -= Chunk;
|
||||
/* Calculate the size of the next chunk */
|
||||
unsigned Chunk = (Count > 0xFFFF)? 0xFFFF : (unsigned) Count;
|
||||
Count -= Chunk;
|
||||
|
||||
/* Emit one chunk */
|
||||
GenFragment (FRAG_FILL, Chunk);
|
||||
/* Emit one chunk */
|
||||
GenFragment (FRAG_FILL, Chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objcode.h */
|
||||
/* objcode.h */
|
||||
/* */
|
||||
/* Objectcode management for the ca65 macroassembler */
|
||||
/* Objectcode management for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objfile.c */
|
||||
/* objfile.c */
|
||||
/* */
|
||||
/* Object file writing routines for the ca65 macroassembler */
|
||||
/* Object file writing routines for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
static FILE* F = 0;
|
||||
|
||||
/* Default extension */
|
||||
#define OBJ_EXT ".o"
|
||||
#define OBJ_EXT ".o"
|
||||
|
||||
/* Header structure */
|
||||
static ObjHeader Header = {
|
||||
@@ -93,7 +93,7 @@ static ObjHeader Header = {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Internally used functions */
|
||||
/* Internally used functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ static void ObjWriteHeader (void)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -161,16 +161,16 @@ void ObjOpen (void)
|
||||
{
|
||||
/* Do we have a name for the output file? */
|
||||
if (OutFile == 0) {
|
||||
/* We don't have an output name explicitly given, construct one from
|
||||
* the name of the input file.
|
||||
*/
|
||||
OutFile = MakeFilename (InFile, OBJ_EXT);
|
||||
/* We don't have an output name explicitly given, construct one from
|
||||
* the name of the input file.
|
||||
*/
|
||||
OutFile = MakeFilename (InFile, OBJ_EXT);
|
||||
}
|
||||
|
||||
/* Create the output file */
|
||||
F = fopen (OutFile, "w+b");
|
||||
if (F == 0) {
|
||||
Fatal ("Cannot open output file `%s': %s", OutFile, strerror (errno));
|
||||
Fatal ("Cannot open output file `%s': %s", OutFile, strerror (errno));
|
||||
}
|
||||
|
||||
/* Write a dummy header */
|
||||
@@ -184,7 +184,7 @@ void ObjClose (void)
|
||||
{
|
||||
/* Go back to the beginning */
|
||||
if (fseek (F, 0, SEEK_SET) != 0) {
|
||||
ObjWriteError ();
|
||||
ObjWriteError ();
|
||||
}
|
||||
|
||||
/* If we have debug infos, set the flag in the header */
|
||||
@@ -197,7 +197,7 @@ void ObjClose (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
ObjWriteError ();
|
||||
ObjWriteError ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ void ObjWrite8 (unsigned V)
|
||||
/* Write an 8 bit value to the file */
|
||||
{
|
||||
if (putc (V, F) == EOF) {
|
||||
ObjWriteError ();
|
||||
ObjWriteError ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,12 +274,12 @@ void ObjWriteVar (unsigned long V)
|
||||
* needing 5 bytes if a 32 bit value is written to file.
|
||||
*/
|
||||
do {
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
if (V) {
|
||||
C |= 0x80;
|
||||
}
|
||||
ObjWrite8 (C);
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
if (V) {
|
||||
C |= 0x80;
|
||||
}
|
||||
ObjWrite8 (C);
|
||||
} while (V != 0);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ void ObjWriteData (const void* Data, unsigned Size)
|
||||
/* Write literal data to the file */
|
||||
{
|
||||
if (fwrite (Data, 1, Size, F) != Size) {
|
||||
ObjWriteError ();
|
||||
ObjWriteError ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,8 +330,8 @@ void ObjWritePos (const FilePos* Pos)
|
||||
ObjWriteVar (Pos->Line);
|
||||
ObjWriteVar (Pos->Col);
|
||||
if (Pos->Name == 0) {
|
||||
/* Position is outside file scope, use the main file instead */
|
||||
ObjWriteVar (0);
|
||||
/* Position is outside file scope, use the main file instead */
|
||||
ObjWriteVar (0);
|
||||
} else {
|
||||
ObjWriteVar (Pos->Name - 1);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objfile.h */
|
||||
/* objfile.h */
|
||||
/* */
|
||||
/* Object file writing routines for the ca65 macroassembler */
|
||||
/* Object file writing routines for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* options.c */
|
||||
/* options.c */
|
||||
/* */
|
||||
/* Object file options for the ca65 macroassembler */
|
||||
/* Object file options for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -48,20 +48,20 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Option list */
|
||||
static Option* OptRoot = 0;
|
||||
static Option* OptLast = 0;
|
||||
static unsigned OptCount = 0;
|
||||
static Option* OptRoot = 0;
|
||||
static Option* OptLast = 0;
|
||||
static unsigned OptCount = 0;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -81,9 +81,9 @@ static Option* NewOption (unsigned char Type, unsigned long Val)
|
||||
|
||||
/* Insert it into the list */
|
||||
if (OptRoot == 0) {
|
||||
OptRoot = Opt;
|
||||
OptRoot = Opt;
|
||||
} else {
|
||||
OptLast->Next = Opt;
|
||||
OptLast->Next = Opt;
|
||||
}
|
||||
OptLast = Opt;
|
||||
|
||||
@@ -167,12 +167,12 @@ void WriteOptions (void)
|
||||
O = OptRoot;
|
||||
while (O) {
|
||||
|
||||
/* Write the type of the option, then the value */
|
||||
ObjWrite8 (O->Type);
|
||||
/* Write the type of the option, then the value */
|
||||
ObjWrite8 (O->Type);
|
||||
ObjWriteVar (O->Val);
|
||||
|
||||
/* Next option */
|
||||
O = O->Next;
|
||||
/* Next option */
|
||||
O = O->Next;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* options.h */
|
||||
/* options.h */
|
||||
/* */
|
||||
/* Object file options for the ca65 macroassembler */
|
||||
/* Object file options for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* pseudo.h */
|
||||
/* pseudo.h */
|
||||
/* */
|
||||
/* Pseudo instructions for the ca65 macroassembler */
|
||||
/* Pseudo instructions for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* repeat.c */
|
||||
/* repeat.c */
|
||||
/* */
|
||||
/* Handle the .REPEAT pseudo instruction */
|
||||
/* Handle the .REPEAT pseudo instruction */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -65,25 +65,25 @@ static TokList* CollectRepeatTokens (void)
|
||||
unsigned Repeats = 0;
|
||||
while (Repeats != 0 || CurTok.Tok != TOK_ENDREP) {
|
||||
|
||||
/* Check for end of input */
|
||||
if (CurTok.Tok == TOK_EOF) {
|
||||
Error ("Unexpected end of file");
|
||||
FreeTokList (List);
|
||||
return 0;
|
||||
}
|
||||
/* Check for end of input */
|
||||
if (CurTok.Tok == TOK_EOF) {
|
||||
Error ("Unexpected end of file");
|
||||
FreeTokList (List);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Collect all tokens in the list */
|
||||
AddCurTok (List);
|
||||
/* Collect all tokens in the list */
|
||||
AddCurTok (List);
|
||||
|
||||
/* Check for and count nested .REPEATs */
|
||||
if (CurTok.Tok == TOK_REPEAT) {
|
||||
++Repeats;
|
||||
} else if (CurTok.Tok == TOK_ENDREP) {
|
||||
--Repeats;
|
||||
}
|
||||
/* Check for and count nested .REPEATs */
|
||||
if (CurTok.Tok == TOK_REPEAT) {
|
||||
++Repeats;
|
||||
} else if (CurTok.Tok == TOK_ENDREP) {
|
||||
--Repeats;
|
||||
}
|
||||
|
||||
/* Get the next token */
|
||||
NextTok ();
|
||||
/* Get the next token */
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Eat the closing .ENDREP */
|
||||
@@ -103,9 +103,9 @@ static void RepeatTokenCheck (TokList* L)
|
||||
if (CurTok.Tok == TOK_IDENT &&
|
||||
L->Data != 0 &&
|
||||
SB_CompareStr (&CurTok.SVal, L->Data) == 0) {
|
||||
/* Must replace by the repeat counter */
|
||||
CurTok.Tok = TOK_INTCON;
|
||||
CurTok.IVal = L->RepCount;
|
||||
/* Must replace by the repeat counter */
|
||||
CurTok.Tok = TOK_INTCON;
|
||||
CurTok.IVal = L->RepCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,26 +120,26 @@ void ParseRepeat (void)
|
||||
/* Repeat count follows */
|
||||
long RepCount = ConstExpression ();
|
||||
if (RepCount < 0) {
|
||||
Error ("Range error");
|
||||
RepCount = 0;
|
||||
Error ("Range error");
|
||||
RepCount = 0;
|
||||
}
|
||||
|
||||
/* Optional there is a comma and a counter variable */
|
||||
Name = 0;
|
||||
if (CurTok.Tok == TOK_COMMA) {
|
||||
|
||||
/* Skip the comma */
|
||||
NextTok ();
|
||||
/* Skip the comma */
|
||||
NextTok ();
|
||||
|
||||
/* Check for an identifier */
|
||||
if (CurTok.Tok != TOK_IDENT) {
|
||||
ErrorSkip ("Identifier expected");
|
||||
} else {
|
||||
/* Remember the name and skip it */
|
||||
/* Check for an identifier */
|
||||
if (CurTok.Tok != TOK_IDENT) {
|
||||
ErrorSkip ("Identifier expected");
|
||||
} else {
|
||||
/* Remember the name and skip it */
|
||||
SB_Terminate (&CurTok.SVal);
|
||||
Name = xstrdup (SB_GetConstBuf (&CurTok.SVal));
|
||||
NextTok ();
|
||||
}
|
||||
Name = xstrdup (SB_GetConstBuf (&CurTok.SVal));
|
||||
NextTok ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Switch to raw token mode, then skip the separator */
|
||||
@@ -151,8 +151,8 @@ void ParseRepeat (void)
|
||||
|
||||
/* If we had an error, bail out */
|
||||
if (List == 0) {
|
||||
xfree (Name);
|
||||
goto Done;
|
||||
xfree (Name);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Update the token list for replay */
|
||||
@@ -164,8 +164,8 @@ void ParseRepeat (void)
|
||||
* to repeat.
|
||||
*/
|
||||
if (List->Count == 0 || RepCount == 0) {
|
||||
FreeTokList (List);
|
||||
goto Done;
|
||||
FreeTokList (List);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Read input from the repeat descriptor */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* repeat.h */
|
||||
/* repeat.h */
|
||||
/* */
|
||||
/* Handle the .REPEAT pseudo instruction */
|
||||
/* Handle the .REPEAT pseudo instruction */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* scanner.h */
|
||||
/* scanner.h */
|
||||
/* */
|
||||
/* The scanner for the ca65 macroassembler */
|
||||
/* The scanner for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,19 +44,19 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Scanner variables */
|
||||
extern Token CurTok; /* Current input token incl. attributes */
|
||||
extern int ForcedEnd; /* Force end of assembly */
|
||||
extern int ForcedEnd; /* Force end of assembly */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* segdef.c */
|
||||
/* segdef.c */
|
||||
/* */
|
||||
/* Segment definitions for the ca65 assembler */
|
||||
/* Segment definitions for the ca65 assembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* segdef.h */
|
||||
/* segdef.h */
|
||||
/* */
|
||||
/* Segment definitions for the ca65 assembler */
|
||||
/* Segment definitions for the ca65 assembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ struct SegDef {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* segment.c */
|
||||
/* segment.c */
|
||||
/* */
|
||||
/* Segments for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
* used when in absolute mode. OrgPerSeg may be set by .feature org_per_seg
|
||||
*/
|
||||
static int RelocMode = 1;
|
||||
static unsigned long AbsPC = 0; /* PC if in absolute mode */
|
||||
static unsigned long AbsPC = 0; /* PC if in absolute mode */
|
||||
|
||||
/* Definitions for predefined segments */
|
||||
SegDef NullSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL, ADDR_SIZE_ABS);
|
||||
@@ -90,7 +90,7 @@ Segment* ActiveSeg;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -129,12 +129,12 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
|
||||
{
|
||||
/* Check for too many segments */
|
||||
if (CollCount (&SegmentList) >= 256) {
|
||||
Fatal ("Too many segments");
|
||||
Fatal ("Too many segments");
|
||||
}
|
||||
|
||||
/* Check the segment name for invalid names */
|
||||
if (!ValidSegName (Name)) {
|
||||
Error ("Illegal segment name: `%s'", Name);
|
||||
Error ("Illegal segment name: `%s'", Name);
|
||||
}
|
||||
|
||||
/* Create a new segment and return it */
|
||||
@@ -151,21 +151,21 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len)
|
||||
|
||||
/* Insert the fragment into the current segment */
|
||||
if (ActiveSeg->Root) {
|
||||
ActiveSeg->Last->Next = F;
|
||||
ActiveSeg->Last = F;
|
||||
ActiveSeg->Last->Next = F;
|
||||
ActiveSeg->Last = F;
|
||||
} else {
|
||||
ActiveSeg->Root = ActiveSeg->Last = F;
|
||||
ActiveSeg->Root = ActiveSeg->Last = F;
|
||||
}
|
||||
++ActiveSeg->FragCount;
|
||||
|
||||
/* Add this fragment to the current listing line */
|
||||
if (LineCur) {
|
||||
if (LineCur->FragList == 0) {
|
||||
LineCur->FragList = F;
|
||||
} else {
|
||||
LineCur->FragLast->LineList = F;
|
||||
}
|
||||
LineCur->FragLast = F;
|
||||
if (LineCur->FragList == 0) {
|
||||
LineCur->FragList = F;
|
||||
} else {
|
||||
LineCur->FragLast->LineList = F;
|
||||
}
|
||||
LineCur->FragLast = F;
|
||||
}
|
||||
|
||||
/* Increment the program counter */
|
||||
@@ -194,17 +194,17 @@ void UseSeg (const SegDef* D)
|
||||
unsigned I;
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
Segment* Seg = CollAtUnchecked (&SegmentList, I);
|
||||
if (strcmp (Seg->Def->Name, D->Name) == 0) {
|
||||
/* We found this segment. Check if the type is identical */
|
||||
if (D->AddrSize != ADDR_SIZE_DEFAULT &&
|
||||
if (strcmp (Seg->Def->Name, D->Name) == 0) {
|
||||
/* We found this segment. Check if the type is identical */
|
||||
if (D->AddrSize != ADDR_SIZE_DEFAULT &&
|
||||
Seg->Def->AddrSize != D->AddrSize) {
|
||||
Error ("Segment attribute mismatch");
|
||||
/* Use the new attribute to avoid errors */
|
||||
Seg->Def->AddrSize = D->AddrSize;
|
||||
}
|
||||
ActiveSeg = Seg;
|
||||
return;
|
||||
}
|
||||
Error ("Segment attribute mismatch");
|
||||
/* Use the new attribute to avoid errors */
|
||||
Seg->Def->AddrSize = D->AddrSize;
|
||||
}
|
||||
ActiveSeg = Seg;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Segment is not in list, create a new one */
|
||||
@@ -319,20 +319,20 @@ void SegAlign (unsigned long Alignment, int FillVal)
|
||||
|
||||
/* Emit the data or a fill fragment */
|
||||
if (FillVal != -1) {
|
||||
/* User defined fill value */
|
||||
memset (Data, FillVal, sizeof (Data));
|
||||
while (Count) {
|
||||
if (Count > sizeof (Data)) {
|
||||
EmitData (Data, sizeof (Data));
|
||||
Count -= sizeof (Data);
|
||||
} else {
|
||||
EmitData (Data, Count);
|
||||
Count = 0;
|
||||
}
|
||||
}
|
||||
/* User defined fill value */
|
||||
memset (Data, FillVal, sizeof (Data));
|
||||
while (Count) {
|
||||
if (Count > sizeof (Data)) {
|
||||
EmitData (Data, sizeof (Data));
|
||||
Count -= sizeof (Data);
|
||||
} else {
|
||||
EmitData (Data, Count);
|
||||
Count = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Linker defined fill value */
|
||||
EmitFill (Count);
|
||||
/* Linker defined fill value */
|
||||
EmitFill (Count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ unsigned char GetSegAddrSize (unsigned SegNum)
|
||||
{
|
||||
/* Is there such a segment? */
|
||||
if (SegNum >= CollCount (&SegmentList)) {
|
||||
FAIL ("Invalid segment number");
|
||||
FAIL ("Invalid segment number");
|
||||
}
|
||||
|
||||
/* Return the address size */
|
||||
@@ -356,18 +356,18 @@ void SegDone (void)
|
||||
/* Check the segments for range and other errors. Do cleanup. */
|
||||
{
|
||||
static const unsigned long U_Hi[4] = {
|
||||
0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
|
||||
0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
|
||||
};
|
||||
static const long S_Hi[4] = {
|
||||
0x0000007FL, 0x00007FFFL, 0x007FFFFFL, 0x7FFFFFFFL
|
||||
0x0000007FL, 0x00007FFFL, 0x007FFFFFL, 0x7FFFFFFFL
|
||||
};
|
||||
|
||||
unsigned I;
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
Segment* S = CollAtUnchecked (&SegmentList, I);
|
||||
Fragment* F = S->Root;
|
||||
while (F) {
|
||||
if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
Fragment* F = S->Root;
|
||||
while (F) {
|
||||
if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
|
||||
/* We have an expression, study it */
|
||||
ExprDesc ED;
|
||||
@@ -377,9 +377,9 @@ void SegDone (void)
|
||||
/* Check if the expression is constant */
|
||||
if (ED_IsConst (&ED)) {
|
||||
|
||||
unsigned J;
|
||||
unsigned J;
|
||||
|
||||
/* The expression is constant. Check for range errors. */
|
||||
/* The expression is constant. Check for range errors. */
|
||||
CHECK (F->Len <= 4);
|
||||
if (F->Type == FRAG_SEXPR) {
|
||||
long Hi = S_Hi[F->Len-1];
|
||||
@@ -400,32 +400,32 @@ void SegDone (void)
|
||||
/* We don't need the expression tree any longer */
|
||||
FreeExpr (F->V.Expr);
|
||||
|
||||
/* Convert the fragment into a literal fragment */
|
||||
for (J = 0; J < F->Len; ++J) {
|
||||
F->V.Data[J] = ED.Val & 0xFF;
|
||||
ED.Val >>= 8;
|
||||
}
|
||||
F->Type = FRAG_LITERAL;
|
||||
/* Convert the fragment into a literal fragment */
|
||||
for (J = 0; J < F->Len; ++J) {
|
||||
F->V.Data[J] = ED.Val & 0xFF;
|
||||
ED.Val >>= 8;
|
||||
}
|
||||
F->Type = FRAG_LITERAL;
|
||||
|
||||
} else if (RelaxChecks == 0) {
|
||||
} else if (RelaxChecks == 0) {
|
||||
|
||||
/* We cannot evaluate the expression now, leave the job for
|
||||
* the linker. However, we can check if the address size
|
||||
/* We cannot evaluate the expression now, leave the job for
|
||||
* the linker. However, we can check if the address size
|
||||
* matches the fragment size. Mismatches are errors in
|
||||
* most situations.
|
||||
*/
|
||||
*/
|
||||
if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP) ||
|
||||
(F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) ||
|
||||
(F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) {
|
||||
LIError (&F->LI, "Range error");
|
||||
}
|
||||
}
|
||||
LIError (&F->LI, "Range error");
|
||||
}
|
||||
}
|
||||
|
||||
/* Release memory allocated for the expression decriptor */
|
||||
ED_Done (&ED);
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,38 +440,38 @@ void SegDump (void)
|
||||
printf ("\n");
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
Segment* S = CollAtUnchecked (&SegmentList, I);
|
||||
unsigned I;
|
||||
Fragment* F;
|
||||
int State = -1;
|
||||
printf ("New segment: %s", S->Def->Name);
|
||||
F = S->Root;
|
||||
while (F) {
|
||||
if (F->Type == FRAG_LITERAL) {
|
||||
if (State != 0) {
|
||||
printf ("\n Literal:");
|
||||
X = 15;
|
||||
State = 0;
|
||||
}
|
||||
for (I = 0; I < F->Len; ++I) {
|
||||
printf (" %02X", F->V.Data [I]);
|
||||
X += 3;
|
||||
}
|
||||
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
State = 1;
|
||||
printf ("\n Expression (%u): ", F->Len);
|
||||
DumpExpr (F->V.Expr, SymResolve);
|
||||
} else if (F->Type == FRAG_FILL) {
|
||||
State = 1;
|
||||
printf ("\n Fill bytes (%u)", F->Len);
|
||||
} else {
|
||||
Internal ("Unknown fragment type: %u", F->Type);
|
||||
}
|
||||
if (X > 65) {
|
||||
State = -1;
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
printf ("\n End PC = $%04X\n", (unsigned)(S->PC & 0xFFFF));
|
||||
unsigned I;
|
||||
Fragment* F;
|
||||
int State = -1;
|
||||
printf ("New segment: %s", S->Def->Name);
|
||||
F = S->Root;
|
||||
while (F) {
|
||||
if (F->Type == FRAG_LITERAL) {
|
||||
if (State != 0) {
|
||||
printf ("\n Literal:");
|
||||
X = 15;
|
||||
State = 0;
|
||||
}
|
||||
for (I = 0; I < F->Len; ++I) {
|
||||
printf (" %02X", F->V.Data [I]);
|
||||
X += 3;
|
||||
}
|
||||
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
State = 1;
|
||||
printf ("\n Expression (%u): ", F->Len);
|
||||
DumpExpr (F->V.Expr, SymResolve);
|
||||
} else if (F->Type == FRAG_FILL) {
|
||||
State = 1;
|
||||
printf ("\n Fill bytes (%u)", F->Len);
|
||||
} else {
|
||||
Internal ("Unknown fragment type: %u", F->Type);
|
||||
}
|
||||
if (X > 65) {
|
||||
State = -1;
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
printf ("\n End PC = $%04X\n", (unsigned)(S->PC & 0xFFFF));
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
@@ -549,52 +549,52 @@ static void WriteOneSeg (Segment* Seg)
|
||||
Frag = Seg->Root;
|
||||
while (Frag) {
|
||||
|
||||
/* Write data depending on the type */
|
||||
switch (Frag->Type) {
|
||||
/* Write data depending on the type */
|
||||
switch (Frag->Type) {
|
||||
|
||||
case FRAG_LITERAL:
|
||||
ObjWrite8 (FRAG_LITERAL);
|
||||
ObjWriteVar (Frag->Len);
|
||||
ObjWriteData (Frag->V.Data, Frag->Len);
|
||||
break;
|
||||
case FRAG_LITERAL:
|
||||
ObjWrite8 (FRAG_LITERAL);
|
||||
ObjWriteVar (Frag->Len);
|
||||
ObjWriteData (Frag->V.Data, Frag->Len);
|
||||
break;
|
||||
|
||||
case FRAG_EXPR:
|
||||
switch (Frag->Len) {
|
||||
case 1: ObjWrite8 (FRAG_EXPR8); break;
|
||||
case 2: ObjWrite8 (FRAG_EXPR16); break;
|
||||
case 3: ObjWrite8 (FRAG_EXPR24); break;
|
||||
case 4: ObjWrite8 (FRAG_EXPR32); break;
|
||||
default: Internal ("Invalid fragment size: %u", Frag->Len);
|
||||
}
|
||||
WriteExpr (Frag->V.Expr);
|
||||
break;
|
||||
case FRAG_EXPR:
|
||||
switch (Frag->Len) {
|
||||
case 1: ObjWrite8 (FRAG_EXPR8); break;
|
||||
case 2: ObjWrite8 (FRAG_EXPR16); break;
|
||||
case 3: ObjWrite8 (FRAG_EXPR24); break;
|
||||
case 4: ObjWrite8 (FRAG_EXPR32); break;
|
||||
default: Internal ("Invalid fragment size: %u", Frag->Len);
|
||||
}
|
||||
WriteExpr (Frag->V.Expr);
|
||||
break;
|
||||
|
||||
case FRAG_SEXPR:
|
||||
switch (Frag->Len) {
|
||||
case 1: ObjWrite8 (FRAG_SEXPR8); break;
|
||||
case 2: ObjWrite8 (FRAG_SEXPR16); break;
|
||||
case 3: ObjWrite8 (FRAG_SEXPR24); break;
|
||||
case 4: ObjWrite8 (FRAG_SEXPR32); break;
|
||||
default: Internal ("Invalid fragment size: %u", Frag->Len);
|
||||
}
|
||||
WriteExpr (Frag->V.Expr);
|
||||
break;
|
||||
case FRAG_SEXPR:
|
||||
switch (Frag->Len) {
|
||||
case 1: ObjWrite8 (FRAG_SEXPR8); break;
|
||||
case 2: ObjWrite8 (FRAG_SEXPR16); break;
|
||||
case 3: ObjWrite8 (FRAG_SEXPR24); break;
|
||||
case 4: ObjWrite8 (FRAG_SEXPR32); break;
|
||||
default: Internal ("Invalid fragment size: %u", Frag->Len);
|
||||
}
|
||||
WriteExpr (Frag->V.Expr);
|
||||
break;
|
||||
|
||||
case FRAG_FILL:
|
||||
ObjWrite8 (FRAG_FILL);
|
||||
ObjWriteVar (Frag->Len);
|
||||
break;
|
||||
case FRAG_FILL:
|
||||
ObjWrite8 (FRAG_FILL);
|
||||
ObjWriteVar (Frag->Len);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid fragment type: %u", Frag->Type);
|
||||
default:
|
||||
Internal ("Invalid fragment type: %u", Frag->Type);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the line infos for this fragment */
|
||||
WriteLineInfo (&Frag->LI);
|
||||
/* Write the line infos for this fragment */
|
||||
WriteLineInfo (&Frag->LI);
|
||||
|
||||
/* Next fragment */
|
||||
Frag = Frag->Next;
|
||||
/* Next fragment */
|
||||
Frag = Frag->Next;
|
||||
}
|
||||
|
||||
/* Calculate the size of the data, seek back and write it */
|
||||
@@ -620,8 +620,8 @@ void WriteSegments (void)
|
||||
|
||||
/* Now walk through all segments and write them to the object file */
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
/* Write one segment */
|
||||
WriteOneSeg (CollAtUnchecked (&SegmentList, I));
|
||||
/* Write one segment */
|
||||
WriteOneSeg (CollAtUnchecked (&SegmentList, I));
|
||||
}
|
||||
|
||||
/* Done writing segments */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* segment.h */
|
||||
/* segment.h */
|
||||
/* */
|
||||
/* Segments for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,12 +58,12 @@
|
||||
/* Segment definition */
|
||||
typedef struct Segment Segment;
|
||||
struct Segment {
|
||||
Fragment* Root; /* Root of fragment list */
|
||||
Fragment* Last; /* Pointer to last fragment */
|
||||
Fragment* Root; /* Root of fragment list */
|
||||
Fragment* Last; /* Pointer to last fragment */
|
||||
unsigned long FragCount; /* Number of fragments */
|
||||
unsigned Num; /* Segment number */
|
||||
unsigned Num; /* Segment number */
|
||||
unsigned Flags; /* Segment flags */
|
||||
unsigned long Align; /* Segment alignment */
|
||||
unsigned long Align; /* Segment alignment */
|
||||
int RelocMode; /* Relocatable mode if OrgPerSeg */
|
||||
unsigned long PC; /* PC if in relocatable mode */
|
||||
unsigned long AbsPC; /* PC if in local absolute mode */
|
||||
@@ -88,7 +88,7 @@ extern Segment* ActiveSeg;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ static const StrBuf SizeEntryName = LIT_STRBUF_INITIALIZER (".size");
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ struct SymTable;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ typedef struct Span Span;
|
||||
struct Span{
|
||||
HashNode Node; /* Node for hash table */
|
||||
unsigned Id; /* Id of span */
|
||||
struct Segment* Seg; /* Pointer to segment */
|
||||
struct Segment* Seg; /* Pointer to segment */
|
||||
unsigned Start; /* Start of range */
|
||||
unsigned End; /* End of range */
|
||||
unsigned Type; /* Type of data in span */
|
||||
@@ -70,7 +70,7 @@ struct Span{
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ StringPool* StrPool = 0;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ extern StringPool* StrPool;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ enum {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ static long DoStructInternal (long Offs, unsigned Type)
|
||||
break;
|
||||
|
||||
case TOK_RES:
|
||||
NextTok ();
|
||||
NextTok ();
|
||||
if (CurTok.Tok == TOK_SEP) {
|
||||
ErrorSkip ("Size is missing");
|
||||
} else {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ struct SymTable;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ ExprDesc* ED_Init (ExprDesc* ED)
|
||||
{
|
||||
ED->Flags = ED_OK;
|
||||
ED->AddrSize = ADDR_SIZE_DEFAULT;
|
||||
ED->Val = 0;
|
||||
ED->Val = 0;
|
||||
ED->SymCount = 0;
|
||||
ED->SymLimit = 0;
|
||||
ED->SymRef = 0;
|
||||
@@ -432,7 +432,7 @@ static void ED_Move (ExprDesc* From, ExprDesc* To)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -1283,29 +1283,29 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
|
||||
/* Study this expression node */
|
||||
switch (Expr->Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
case EXPR_LITERAL:
|
||||
StudyLiteral (Expr, D);
|
||||
break;
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
case EXPR_SYMBOL:
|
||||
StudySymbol (Expr, D);
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
case EXPR_SECTION:
|
||||
StudySection (Expr, D);
|
||||
break;
|
||||
break;
|
||||
|
||||
case EXPR_ULABEL:
|
||||
case EXPR_ULABEL:
|
||||
StudyULabel (Expr, D);
|
||||
break;
|
||||
|
||||
case EXPR_PLUS:
|
||||
case EXPR_PLUS:
|
||||
StudyPlus (Expr, D);
|
||||
break;
|
||||
break;
|
||||
|
||||
case EXPR_MINUS:
|
||||
StudyMinus (Expr, D);
|
||||
break;
|
||||
case EXPR_MINUS:
|
||||
StudyMinus (Expr, D);
|
||||
break;
|
||||
|
||||
case EXPR_MUL:
|
||||
StudyMul (Expr, D);
|
||||
@@ -1436,8 +1436,8 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Unknown Op type: %u", Expr->Op);
|
||||
break;
|
||||
Internal ("Unknown Op type: %u", Expr->Op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef struct ExprDesc ExprDesc;
|
||||
struct ExprDesc {
|
||||
unsigned short Flags; /* See ED_xxx */
|
||||
unsigned char AddrSize; /* Address size of the expression */
|
||||
long Val; /* The offset value */
|
||||
long Val; /* The offset value */
|
||||
long Right; /* Right value for StudyBinaryExpr */
|
||||
|
||||
/* Symbol reference management */
|
||||
@@ -107,7 +107,7 @@ int ED_IsConst (const ExprDesc* ED);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ struct StrBuf;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* symentry.c */
|
||||
/* symentry.c */
|
||||
/* */
|
||||
/* Symbol table entry for the ca65 macroassembler */
|
||||
/* */
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ SymEntry* SymLast = 0;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -82,9 +82,9 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
|
||||
SymEntry* S = xmalloc (sizeof (SymEntry));
|
||||
|
||||
/* Initialize the entry */
|
||||
S->Left = 0;
|
||||
S->Right = 0;
|
||||
S->Locals = 0;
|
||||
S->Left = 0;
|
||||
S->Right = 0;
|
||||
S->Locals = 0;
|
||||
S->Sym.Tab = 0;
|
||||
S->DefLines = EmptyCollection;
|
||||
S->RefLines = EmptyCollection;
|
||||
@@ -92,7 +92,7 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
|
||||
S->GuessedUse[I] = 0;
|
||||
}
|
||||
S->HLLSym = 0;
|
||||
S->Flags = Flags;
|
||||
S->Flags = Flags;
|
||||
S->DebugSymId = ~0U;
|
||||
S->ImportId = ~0U;
|
||||
S->ExportId = ~0U;
|
||||
@@ -124,8 +124,8 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
|
||||
{
|
||||
/* Is there a tree? */
|
||||
if (T == 0) {
|
||||
*E = 0;
|
||||
return 1;
|
||||
*E = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have a table, search it */
|
||||
@@ -134,17 +134,17 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
|
||||
/* Get the symbol name */
|
||||
const StrBuf* SymName = GetStrBuf (T->Name);
|
||||
|
||||
/* Choose next entry */
|
||||
/* Choose next entry */
|
||||
int Cmp = SB_Compare (Name, SymName);
|
||||
if (Cmp < 0 && T->Left) {
|
||||
T = T->Left;
|
||||
} else if (Cmp > 0 && T->Right) {
|
||||
T = T->Right;
|
||||
} else {
|
||||
/* Found or end of search, return the result */
|
||||
if (Cmp < 0 && T->Left) {
|
||||
T = T->Left;
|
||||
} else if (Cmp > 0 && T->Right) {
|
||||
T = T->Right;
|
||||
} else {
|
||||
/* Found or end of search, return the result */
|
||||
*E = T;
|
||||
return Cmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,9 +212,9 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
||||
/* Define a new symbol */
|
||||
{
|
||||
if (S->Flags & SF_IMPORT) {
|
||||
/* Defined symbol is marked as imported external symbol */
|
||||
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||
return;
|
||||
/* Defined symbol is marked as imported external symbol */
|
||||
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||
return;
|
||||
}
|
||||
if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
|
||||
/* Variable symbols cannot be exports or globals */
|
||||
@@ -222,7 +222,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
||||
return;
|
||||
}
|
||||
if (S->Flags & SF_DEFINED) {
|
||||
/* Multiple definition. In case of a variable, this is legal. */
|
||||
/* Multiple definition. In case of a variable, this is legal. */
|
||||
if ((S->Flags & SF_VAR) == 0) {
|
||||
Error ("Symbol `%m%p' is already defined", GetSymName (S));
|
||||
S->Flags |= SF_MULTDEF;
|
||||
@@ -293,7 +293,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
||||
|
||||
/* If this is not a local symbol, remember it as the last global one */
|
||||
if ((S->Flags & SF_LOCAL) == 0) {
|
||||
SymLast = S;
|
||||
SymLast = S;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,14 +315,14 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
||||
/* Mark the given symbol as an imported symbol */
|
||||
{
|
||||
if (S->Flags & SF_DEFINED) {
|
||||
Error ("Symbol `%m%p' is already defined", GetSymName (S));
|
||||
S->Flags |= SF_MULTDEF;
|
||||
return;
|
||||
Error ("Symbol `%m%p' is already defined", GetSymName (S));
|
||||
S->Flags |= SF_MULTDEF;
|
||||
return;
|
||||
}
|
||||
if (S->Flags & SF_EXPORT) {
|
||||
/* The symbol is already marked as exported symbol */
|
||||
Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
|
||||
return;
|
||||
/* The symbol is already marked as exported symbol */
|
||||
Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no address size is given, use the address size of the enclosing
|
||||
@@ -336,9 +336,9 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
||||
* then do silently remove the global flag.
|
||||
*/
|
||||
if (S->Flags & SF_IMPORT) {
|
||||
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
|
||||
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
|
||||
}
|
||||
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
|
||||
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
|
||||
}
|
||||
if (AddrSize != S->AddrSize) {
|
||||
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||
}
|
||||
@@ -347,7 +347,7 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
||||
S->Flags &= ~SF_GLOBAL;
|
||||
if (AddrSize != S->AddrSize) {
|
||||
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the symbol data */
|
||||
@@ -368,9 +368,9 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
||||
{
|
||||
/* Check if it's ok to export the symbol */
|
||||
if (S->Flags & SF_IMPORT) {
|
||||
/* The symbol is already marked as imported external symbol */
|
||||
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||
return;
|
||||
/* The symbol is already marked as imported external symbol */
|
||||
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||
return;
|
||||
}
|
||||
if (S->Flags & SF_VAR) {
|
||||
/* Variable symbols cannot be exported */
|
||||
@@ -536,9 +536,9 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
||||
|
||||
/* Check for errors */
|
||||
if (S->Flags & SF_IMPORT) {
|
||||
/* The symbol is already marked as imported external symbol */
|
||||
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||
return;
|
||||
/* The symbol is already marked as imported external symbol */
|
||||
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||
return;
|
||||
}
|
||||
if (S->Flags & SF_VAR) {
|
||||
/* Variable symbols cannot be exported or imported */
|
||||
@@ -574,9 +574,9 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
||||
* priority value is the same as the old one.
|
||||
*/
|
||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||
if (S->ConDesPrio[Type] != Prio) {
|
||||
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
|
||||
}
|
||||
if (S->ConDesPrio[Type] != Prio) {
|
||||
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
|
||||
}
|
||||
}
|
||||
S->ConDesPrio[Type] = Prio;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* symentry.h */
|
||||
/* symentry.h */
|
||||
/* */
|
||||
/* Symbol table entry forward for the ca65 macroassembler */
|
||||
/* Symbol table entry forward for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,19 +61,19 @@ struct HLLDbgSym;
|
||||
|
||||
/* Bits for the Flags value in SymEntry */
|
||||
#define SF_NONE 0x0000 /* Empty flag set */
|
||||
#define SF_USER 0x0001 /* User bit */
|
||||
#define SF_UNUSED 0x0002 /* Unused entry */
|
||||
#define SF_EXPORT 0x0004 /* Export this symbol */
|
||||
#define SF_IMPORT 0x0008 /* Import this symbol */
|
||||
#define SF_GLOBAL 0x0010 /* Global symbol */
|
||||
#define SF_USER 0x0001 /* User bit */
|
||||
#define SF_UNUSED 0x0002 /* Unused entry */
|
||||
#define SF_EXPORT 0x0004 /* Export this symbol */
|
||||
#define SF_IMPORT 0x0008 /* Import this symbol */
|
||||
#define SF_GLOBAL 0x0010 /* Global symbol */
|
||||
#define SF_LOCAL 0x0020 /* Cheap local symbol */
|
||||
#define SF_LABEL 0x0040 /* Used as a label */
|
||||
#define SF_VAR 0x0080 /* Variable symbol */
|
||||
#define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */
|
||||
#define SF_FIXED 0x0200 /* May not be trampoline */
|
||||
#define SF_MULTDEF 0x1000 /* Multiply defined symbol */
|
||||
#define SF_DEFINED 0x2000 /* Defined */
|
||||
#define SF_REFERENCED 0x4000 /* Referenced */
|
||||
#define SF_MULTDEF 0x1000 /* Multiply defined symbol */
|
||||
#define SF_DEFINED 0x2000 /* Defined */
|
||||
#define SF_REFERENCED 0x4000 /* Referenced */
|
||||
|
||||
/* Combined values */
|
||||
#define SF_REFIMP (SF_REFERENCED|SF_IMPORT) /* A ref'd import */
|
||||
@@ -81,12 +81,12 @@ struct HLLDbgSym;
|
||||
/* Structure of a symbol table entry */
|
||||
typedef struct SymEntry SymEntry;
|
||||
struct SymEntry {
|
||||
SymEntry* Left; /* Lexically smaller entry */
|
||||
SymEntry* Right; /* Lexically larger entry */
|
||||
SymEntry* List; /* List of all entries */
|
||||
SymEntry* Locals; /* Root of subtree for local symbols */
|
||||
SymEntry* Left; /* Lexically smaller entry */
|
||||
SymEntry* Right; /* Lexically larger entry */
|
||||
SymEntry* List; /* List of all entries */
|
||||
SymEntry* Locals; /* Root of subtree for local symbols */
|
||||
union {
|
||||
struct SymTable* Tab; /* Table this symbol is in */
|
||||
struct SymTable* Tab; /* Table this symbol is in */
|
||||
struct SymEntry* Entry; /* Parent for cheap locals */
|
||||
} Sym;
|
||||
Collection DefLines; /* Line infos for definition */
|
||||
@@ -98,17 +98,17 @@ struct SymEntry {
|
||||
* addressing
|
||||
*/
|
||||
struct HLLDbgSym* HLLSym; /* Symbol from high level language */
|
||||
unsigned Flags; /* Symbol flags */
|
||||
unsigned Flags; /* Symbol flags */
|
||||
unsigned DebugSymId; /* Debug symbol id */
|
||||
unsigned ImportId; /* Id of import if this is one */
|
||||
unsigned ExportId; /* Id of export if this is one */
|
||||
struct ExprNode* Expr; /* Symbol expression */
|
||||
struct ExprNode* Expr; /* Symbol expression */
|
||||
Collection ExprRefs; /* Expressions using this symbol */
|
||||
unsigned char ExportSize; /* Export address size */
|
||||
unsigned char AddrSize; /* Address size of label */
|
||||
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
|
||||
/* ...actually value+1 (used as flag) */
|
||||
unsigned Name; /* Name index in global string pool */
|
||||
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
|
||||
/* ...actually value+1 (used as flag) */
|
||||
unsigned Name; /* Name index in global string pool */
|
||||
};
|
||||
|
||||
/* List of all symbol table entries */
|
||||
@@ -120,7 +120,7 @@ extern SymEntry* SymLast;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* symtab.c */
|
||||
/* symtab.c */
|
||||
/* */
|
||||
/* Symbol table for the ca65 macroassembler */
|
||||
/* Symbol table for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -61,18 +61,18 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Combined symbol entry flags used within this module */
|
||||
#define SF_UNDEFMASK (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
|
||||
#define SF_UNDEFVAL (SF_REFERENCED)
|
||||
#define SF_UNDEFMASK (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
|
||||
#define SF_UNDEFVAL (SF_REFERENCED)
|
||||
|
||||
/* Symbol tables */
|
||||
SymTable* CurrentScope = 0; /* Pointer to current symbol table */
|
||||
SymTable* RootScope = 0; /* Root symbol table */
|
||||
SymTable* CurrentScope = 0; /* Pointer to current symbol table */
|
||||
SymTable* RootScope = 0; /* Root symbol table */
|
||||
static SymTable* LastScope = 0; /* Pointer to last scope in list */
|
||||
static unsigned ScopeCount = 0; /* Number of scopes */
|
||||
|
||||
@@ -83,7 +83,7 @@ static unsigned ExportCount = 0; /* Counter for export symbols */
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Internally used functions */
|
||||
/* Internally used functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
|
||||
S->Parent = Parent;
|
||||
S->Name = GetStrBufId (Name);
|
||||
while (Slots--) {
|
||||
S->Table[Slots] = 0;
|
||||
S->Table[Slots] = 0;
|
||||
}
|
||||
|
||||
/* Insert the symbol table into the list of all symbol tables */
|
||||
@@ -191,7 +191,7 @@ static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -310,12 +310,12 @@ SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name)
|
||||
{
|
||||
SymTable* Scope;
|
||||
do {
|
||||
/* Search in the current table */
|
||||
Scope = SymFindScope (Parent, Name, SYM_FIND_EXISTING);
|
||||
if (Scope == 0) {
|
||||
/* Not found, search in the parent scope, if we have one */
|
||||
Parent = Parent->Parent;
|
||||
}
|
||||
/* Search in the current table */
|
||||
Scope = SymFindScope (Parent, Name, SYM_FIND_EXISTING);
|
||||
if (Scope == 0) {
|
||||
/* Not found, search in the parent scope, if we have one */
|
||||
Parent = Parent->Parent;
|
||||
}
|
||||
} while (Scope == 0 && Parent != 0);
|
||||
|
||||
return Scope;
|
||||
@@ -470,7 +470,7 @@ static void SymCheckUndefined (SymEntry* S)
|
||||
*
|
||||
* - An undefined symbol in a nested lexical level. If the symbol is not
|
||||
* fixed to this level, search for the symbol in the higher levels and
|
||||
* make the entry a trampoline entry if we find one.
|
||||
* make the entry a trampoline entry if we find one.
|
||||
*
|
||||
* - If the symbol is not found, it is a real undefined symbol. If the
|
||||
* AutoImport flag is set, make it an import. If the AutoImport flag is
|
||||
@@ -499,12 +499,12 @@ static void SymCheckUndefined (SymEntry* S)
|
||||
* and check for problems.
|
||||
*/
|
||||
if (S->Flags & SF_EXPORT) {
|
||||
if (Sym->Flags & SF_IMPORT) {
|
||||
/* The symbol is already marked as import */
|
||||
LIError (&S->RefLines,
|
||||
if (Sym->Flags & SF_IMPORT) {
|
||||
/* The symbol is already marked as import */
|
||||
LIError (&S->RefLines,
|
||||
"Symbol `%s' is already an import",
|
||||
GetString (Sym->Name));
|
||||
}
|
||||
}
|
||||
if (Sym->Flags & SF_EXPORT) {
|
||||
/* The symbol is already marked as an export. */
|
||||
if (Sym->AddrSize > S->ExportSize) {
|
||||
@@ -547,27 +547,27 @@ static void SymCheckUndefined (SymEntry* S)
|
||||
S->Flags = SF_UNUSED;
|
||||
|
||||
} else {
|
||||
/* The symbol is definitely undefined */
|
||||
if (S->Flags & SF_EXPORT) {
|
||||
/* We will not auto-import an export */
|
||||
LIError (&S->RefLines,
|
||||
/* The symbol is definitely undefined */
|
||||
if (S->Flags & SF_EXPORT) {
|
||||
/* We will not auto-import an export */
|
||||
LIError (&S->RefLines,
|
||||
"Exported symbol `%m%p' was never defined",
|
||||
GetSymName (S));
|
||||
} else {
|
||||
if (AutoImport) {
|
||||
/* Mark as import, will be indexed later */
|
||||
S->Flags |= SF_IMPORT;
|
||||
} else {
|
||||
if (AutoImport) {
|
||||
/* Mark as import, will be indexed later */
|
||||
S->Flags |= SF_IMPORT;
|
||||
/* Use the address size for code */
|
||||
S->AddrSize = CodeAddrSize;
|
||||
/* Mark point of import */
|
||||
GetFullLineInfo (&S->DefLines);
|
||||
} else {
|
||||
/* Error */
|
||||
LIError (&S->RefLines,
|
||||
} else {
|
||||
/* Error */
|
||||
LIError (&S->RefLines,
|
||||
"Symbol `%m%p' is undefined",
|
||||
GetSymName (S));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +580,7 @@ void SymCheck (void)
|
||||
|
||||
/* Check for open scopes */
|
||||
if (CurrentScope->Parent != 0) {
|
||||
Error ("Local scope was not closed");
|
||||
Error ("Local scope was not closed");
|
||||
}
|
||||
|
||||
/* First pass: Walk through all symbols, checking for undefined's and
|
||||
@@ -588,25 +588,25 @@ void SymCheck (void)
|
||||
*/
|
||||
S = SymList;
|
||||
while (S) {
|
||||
/* If the symbol is marked as global, mark it as export, if it is
|
||||
* already defined, otherwise mark it as import.
|
||||
*/
|
||||
if (S->Flags & SF_GLOBAL) {
|
||||
if (S->Flags & SF_DEFINED) {
|
||||
SymExportFromGlobal (S);
|
||||
} else {
|
||||
SymImportFromGlobal (S);
|
||||
}
|
||||
}
|
||||
/* If the symbol is marked as global, mark it as export, if it is
|
||||
* already defined, otherwise mark it as import.
|
||||
*/
|
||||
if (S->Flags & SF_GLOBAL) {
|
||||
if (S->Flags & SF_DEFINED) {
|
||||
SymExportFromGlobal (S);
|
||||
} else {
|
||||
SymImportFromGlobal (S);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle undefined symbols */
|
||||
if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
|
||||
/* This is an undefined symbol. Handle it. */
|
||||
SymCheckUndefined (S);
|
||||
}
|
||||
/* Handle undefined symbols */
|
||||
if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
|
||||
/* This is an undefined symbol. Handle it. */
|
||||
SymCheckUndefined (S);
|
||||
}
|
||||
|
||||
/* Next symbol */
|
||||
S = S->List;
|
||||
/* Next symbol */
|
||||
S = S->List;
|
||||
}
|
||||
|
||||
/* Second pass: Walk again through the symbols. Count exports and imports
|
||||
@@ -616,8 +616,8 @@ void SymCheck (void)
|
||||
*/
|
||||
S = SymList;
|
||||
while (S) {
|
||||
if ((S->Flags & SF_UNUSED) == 0 &&
|
||||
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
|
||||
if ((S->Flags & SF_UNUSED) == 0 &&
|
||||
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
|
||||
|
||||
/* Check for defined symbols that were never referenced */
|
||||
if (IsSizeOfSymbol (S)) {
|
||||
@@ -631,22 +631,22 @@ void SymCheck (void)
|
||||
}
|
||||
|
||||
/* Assign an index to all imports */
|
||||
if (S->Flags & SF_IMPORT) {
|
||||
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
|
||||
/* Imported symbol is not referenced */
|
||||
LIWarning (&S->DefLines, 2,
|
||||
if (S->Flags & SF_IMPORT) {
|
||||
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
|
||||
/* Imported symbol is not referenced */
|
||||
LIWarning (&S->DefLines, 2,
|
||||
"Symbol `%m%p' is imported but never used",
|
||||
GetSymName (S));
|
||||
} else {
|
||||
/* Give the import an id, count imports */
|
||||
S->ImportId = ImportCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Give the import an id, count imports */
|
||||
S->ImportId = ImportCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Count exports, assign the export ID */
|
||||
if (S->Flags & SF_EXPORT) {
|
||||
if (S->Flags & SF_EXPORT) {
|
||||
S->ExportId = ExportCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the symbol is defined but has an unknown address size,
|
||||
* recalculate it.
|
||||
@@ -690,10 +690,10 @@ void SymCheck (void)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Next symbol */
|
||||
S = S->List;
|
||||
/* Next symbol */
|
||||
S = S->List;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,19 +705,19 @@ void SymDump (FILE* F)
|
||||
SymEntry* S = SymList;
|
||||
|
||||
while (S) {
|
||||
/* Ignore unused symbols */
|
||||
if ((S->Flags & SF_UNUSED) != 0) {
|
||||
fprintf (F,
|
||||
"%m%-24p %s %s %s %s %s\n",
|
||||
GetSymName (S),
|
||||
(S->Flags & SF_DEFINED)? "DEF" : "---",
|
||||
(S->Flags & SF_REFERENCED)? "REF" : "---",
|
||||
(S->Flags & SF_IMPORT)? "IMP" : "---",
|
||||
(S->Flags & SF_EXPORT)? "EXP" : "---",
|
||||
/* Ignore unused symbols */
|
||||
if ((S->Flags & SF_UNUSED) != 0) {
|
||||
fprintf (F,
|
||||
"%m%-24p %s %s %s %s %s\n",
|
||||
GetSymName (S),
|
||||
(S->Flags & SF_DEFINED)? "DEF" : "---",
|
||||
(S->Flags & SF_REFERENCED)? "REF" : "---",
|
||||
(S->Flags & SF_IMPORT)? "IMP" : "---",
|
||||
(S->Flags & SF_EXPORT)? "EXP" : "---",
|
||||
AddrSizeToStr (S->AddrSize));
|
||||
}
|
||||
/* Next symbol */
|
||||
S = S->List;
|
||||
}
|
||||
/* Next symbol */
|
||||
S = S->List;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,11 +745,11 @@ void WriteImports (void)
|
||||
(S->Flags & (SF_REFERENCED | SF_FORCED)) != 0) {
|
||||
|
||||
ObjWrite8 (S->AddrSize);
|
||||
ObjWriteVar (S->Name);
|
||||
WriteLineInfo (&S->DefLines);
|
||||
ObjWriteVar (S->Name);
|
||||
WriteLineInfo (&S->DefLines);
|
||||
WriteLineInfo (&S->RefLines);
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
|
||||
/* Done writing imports */
|
||||
@@ -773,9 +773,9 @@ void WriteExports (void)
|
||||
/* Walk throught list and write all exports to the file */
|
||||
S = SymList;
|
||||
while (S) {
|
||||
if ((S->Flags & (SF_UNUSED | SF_EXPORT)) == SF_EXPORT) {
|
||||
if ((S->Flags & (SF_UNUSED | SF_EXPORT)) == SF_EXPORT) {
|
||||
|
||||
/* Get the expression bits and the value */
|
||||
/* Get the expression bits and the value */
|
||||
long ConstVal;
|
||||
unsigned SymFlags = GetSymInfoFlags (S, &ConstVal);
|
||||
|
||||
@@ -788,37 +788,37 @@ void WriteExports (void)
|
||||
SymFlags |= SYM_SIZE;
|
||||
}
|
||||
|
||||
/* Count the number of ConDes types */
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||
SYM_INC_CONDES_COUNT (SymFlags);
|
||||
}
|
||||
}
|
||||
/* Count the number of ConDes types */
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||
SYM_INC_CONDES_COUNT (SymFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the type and the export size */
|
||||
ObjWriteVar (SymFlags);
|
||||
/* Write the type and the export size */
|
||||
ObjWriteVar (SymFlags);
|
||||
ObjWrite8 (S->ExportSize);
|
||||
|
||||
/* Write any ConDes declarations */
|
||||
if (SYM_GET_CONDES_COUNT (SymFlags) > 0) {
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
unsigned char Prio = S->ConDesPrio[Type];
|
||||
if (Prio != CD_PRIO_NONE) {
|
||||
ObjWrite8 (CD_BUILD (Type, Prio));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Write any ConDes declarations */
|
||||
if (SYM_GET_CONDES_COUNT (SymFlags) > 0) {
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
unsigned char Prio = S->ConDesPrio[Type];
|
||||
if (Prio != CD_PRIO_NONE) {
|
||||
ObjWrite8 (CD_BUILD (Type, Prio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the name */
|
||||
ObjWriteVar (S->Name);
|
||||
/* Write the name */
|
||||
ObjWriteVar (S->Name);
|
||||
|
||||
/* Write the value */
|
||||
if (SYM_IS_CONST (SymFlags)) {
|
||||
/* Constant value */
|
||||
ObjWrite32 (ConstVal);
|
||||
} else {
|
||||
/* Expression involved */
|
||||
WriteExpr (S->Expr);
|
||||
/* Write the value */
|
||||
if (SYM_IS_CONST (SymFlags)) {
|
||||
/* Constant value */
|
||||
ObjWrite32 (ConstVal);
|
||||
} else {
|
||||
/* Expression involved */
|
||||
WriteExpr (S->Expr);
|
||||
}
|
||||
|
||||
/* If the symbol has a size, write it to the file */
|
||||
@@ -826,11 +826,11 @@ void WriteExports (void)
|
||||
ObjWriteVar (Size);
|
||||
}
|
||||
|
||||
/* Write the line infos */
|
||||
/* Write the line infos */
|
||||
WriteLineInfo (&S->DefLines);
|
||||
WriteLineInfo (&S->RefLines);
|
||||
}
|
||||
S = S->List;
|
||||
WriteLineInfo (&S->RefLines);
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
|
||||
/* Done writing exports */
|
||||
@@ -851,25 +851,25 @@ void WriteDbgSyms (void)
|
||||
/* Check if debug info is requested */
|
||||
if (DbgSyms) {
|
||||
|
||||
/* Walk through the list, give each symbol an id and count them */
|
||||
Count = 0;
|
||||
S = SymList;
|
||||
while (S) {
|
||||
if (IsDbgSym (S)) {
|
||||
/* Walk through the list, give each symbol an id and count them */
|
||||
Count = 0;
|
||||
S = SymList;
|
||||
while (S) {
|
||||
if (IsDbgSym (S)) {
|
||||
S->DebugSymId = Count++;
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
|
||||
/* Write the symbol count to the list */
|
||||
ObjWriteVar (Count);
|
||||
/* Write the symbol count to the list */
|
||||
ObjWriteVar (Count);
|
||||
|
||||
/* Walk through list and write all symbols to the file. Ignore size
|
||||
/* Walk through list and write all symbols to the file. Ignore size
|
||||
* symbols.
|
||||
*/
|
||||
S = SymList;
|
||||
while (S) {
|
||||
if (IsDbgSym (S)) {
|
||||
S = SymList;
|
||||
while (S) {
|
||||
if (IsDbgSym (S)) {
|
||||
|
||||
/* Get the expression bits and the value */
|
||||
long ConstVal;
|
||||
@@ -884,8 +884,8 @@ void WriteDbgSyms (void)
|
||||
SymFlags |= SYM_SIZE;
|
||||
}
|
||||
|
||||
/* Write the type */
|
||||
ObjWriteVar (SymFlags);
|
||||
/* Write the type */
|
||||
ObjWriteVar (SymFlags);
|
||||
|
||||
/* Write the address size */
|
||||
ObjWrite8 (S->AddrSize);
|
||||
@@ -899,17 +899,17 @@ void WriteDbgSyms (void)
|
||||
ObjWriteVar (S->Sym.Entry->DebugSymId);
|
||||
}
|
||||
|
||||
/* Write the name */
|
||||
ObjWriteVar (S->Name);
|
||||
/* Write the name */
|
||||
ObjWriteVar (S->Name);
|
||||
|
||||
/* Write the value */
|
||||
if (SYM_IS_CONST (SymFlags)) {
|
||||
/* Constant value */
|
||||
ObjWrite32 (ConstVal);
|
||||
} else {
|
||||
/* Expression involved */
|
||||
WriteExpr (S->Expr);
|
||||
}
|
||||
/* Write the value */
|
||||
if (SYM_IS_CONST (SymFlags)) {
|
||||
/* Constant value */
|
||||
ObjWrite32 (ConstVal);
|
||||
} else {
|
||||
/* Expression involved */
|
||||
WriteExpr (S->Expr);
|
||||
}
|
||||
|
||||
/* If the symbol has a size, write it to the file */
|
||||
if (SYM_HAS_SIZE (SymFlags)) {
|
||||
@@ -924,17 +924,17 @@ void WriteDbgSyms (void)
|
||||
ObjWriteVar (GetSymExportId (S));
|
||||
}
|
||||
|
||||
/* Write the line infos */
|
||||
/* Write the line infos */
|
||||
WriteLineInfo (&S->DefLines);
|
||||
WriteLineInfo (&S->RefLines);
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
WriteLineInfo (&S->RefLines);
|
||||
}
|
||||
S = S->List;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* No debug symbols */
|
||||
ObjWriteVar (0);
|
||||
/* No debug symbols */
|
||||
ObjWriteVar (0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* symtab.h */
|
||||
/* symtab.h */
|
||||
/* */
|
||||
/* Symbol table for the ca65 macroassembler */
|
||||
/* Symbol table for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -50,15 +50,15 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Arguments for SymFind... */
|
||||
typedef enum {
|
||||
SYM_FIND_EXISTING = 0x00,
|
||||
SYM_ALLOC_NEW = 0x01,
|
||||
SYM_FIND_EXISTING = 0x00,
|
||||
SYM_ALLOC_NEW = 0x01,
|
||||
SYM_CHECK_ONLY = 0x02,
|
||||
} SymFindAction;
|
||||
|
||||
@@ -73,29 +73,29 @@ struct SymTable {
|
||||
SymTable* Next; /* Pointer to next table in list */
|
||||
SymTable* Left; /* Pointer to smaller entry */
|
||||
SymTable* Right; /* Pointer to greater entry */
|
||||
SymTable* Parent; /* Link to enclosing scope if any */
|
||||
SymTable* Parent; /* Link to enclosing scope if any */
|
||||
SymTable* Childs; /* Pointer to child scopes */
|
||||
SymEntry* Label; /* Scope label */
|
||||
Collection Spans; /* Spans for this scope */
|
||||
unsigned Id; /* Scope id */
|
||||
unsigned short Flags; /* Symbol table flags */
|
||||
unsigned char AddrSize; /* Address size */
|
||||
unsigned char AddrSize; /* Address size */
|
||||
unsigned char Type; /* Type of the scope */
|
||||
unsigned Level; /* Lexical level */
|
||||
unsigned TableSlots; /* Number of hash table slots */
|
||||
unsigned TableEntries; /* Number of entries in the table */
|
||||
unsigned TableSlots; /* Number of hash table slots */
|
||||
unsigned TableEntries; /* Number of entries in the table */
|
||||
unsigned Name; /* Name of the scope */
|
||||
SymEntry* Table[1]; /* Dynamic allocation */
|
||||
SymEntry* Table[1]; /* Dynamic allocation */
|
||||
};
|
||||
|
||||
/* Symbol tables */
|
||||
extern SymTable* CurrentScope; /* Pointer to current symbol table */
|
||||
extern SymTable* RootScope; /* Root symbol table */
|
||||
extern SymTable* RootScope; /* Root symbol table */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
102
src/ca65/token.h
102
src/ca65/token.h
@@ -46,67 +46,67 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Tokens */
|
||||
typedef enum token_t {
|
||||
TOK_NONE, /* Start value, invalid */
|
||||
TOK_EOF, /* End of input file */
|
||||
TOK_SEP, /* Separator (usually newline) */
|
||||
TOK_IDENT, /* An identifier */
|
||||
TOK_NONE, /* Start value, invalid */
|
||||
TOK_EOF, /* End of input file */
|
||||
TOK_SEP, /* Separator (usually newline) */
|
||||
TOK_IDENT, /* An identifier */
|
||||
TOK_LOCAL_IDENT, /* A cheap local identifier */
|
||||
|
||||
TOK_INTCON, /* Integer constant */
|
||||
TOK_CHARCON, /* Character constant */
|
||||
TOK_STRCON, /* String constant */
|
||||
TOK_INTCON, /* Integer constant */
|
||||
TOK_CHARCON, /* Character constant */
|
||||
TOK_STRCON, /* String constant */
|
||||
|
||||
TOK_A, /* A)ccumulator */
|
||||
TOK_X, /* X register */
|
||||
TOK_Y, /* Y register */
|
||||
TOK_S, /* S register */
|
||||
TOK_A, /* A)ccumulator */
|
||||
TOK_X, /* X register */
|
||||
TOK_Y, /* Y register */
|
||||
TOK_S, /* S register */
|
||||
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
|
||||
|
||||
TOK_ASSIGN, /* := */
|
||||
TOK_ULABEL, /* :++ or :-- */
|
||||
TOK_ULABEL, /* :++ or :-- */
|
||||
|
||||
TOK_EQ, /* = */
|
||||
TOK_NE, /* <> */
|
||||
TOK_LT, /* < */
|
||||
TOK_GT, /* > */
|
||||
TOK_LE, /* <= */
|
||||
TOK_GE, /* >= */
|
||||
TOK_EQ, /* = */
|
||||
TOK_NE, /* <> */
|
||||
TOK_LT, /* < */
|
||||
TOK_GT, /* > */
|
||||
TOK_LE, /* <= */
|
||||
TOK_GE, /* >= */
|
||||
|
||||
TOK_BOOLAND, /* .and */
|
||||
TOK_BOOLOR, /* .or */
|
||||
TOK_BOOLXOR, /* .xor */
|
||||
TOK_BOOLNOT, /* .not */
|
||||
TOK_BOOLAND, /* .and */
|
||||
TOK_BOOLOR, /* .or */
|
||||
TOK_BOOLXOR, /* .xor */
|
||||
TOK_BOOLNOT, /* .not */
|
||||
|
||||
TOK_PLUS, /* + */
|
||||
TOK_MINUS, /* - */
|
||||
TOK_MUL, /* * */
|
||||
TOK_STAR = TOK_MUL, /* Alias */
|
||||
TOK_DIV, /* / */
|
||||
TOK_MOD, /* ! */
|
||||
TOK_OR, /* | */
|
||||
TOK_XOR, /* ^ */
|
||||
TOK_AND, /* & */
|
||||
TOK_SHL, /* << */
|
||||
TOK_SHR, /* >> */
|
||||
TOK_NOT, /* ~ */
|
||||
TOK_PLUS, /* + */
|
||||
TOK_MINUS, /* - */
|
||||
TOK_MUL, /* * */
|
||||
TOK_STAR = TOK_MUL, /* Alias */
|
||||
TOK_DIV, /* / */
|
||||
TOK_MOD, /* ! */
|
||||
TOK_OR, /* | */
|
||||
TOK_XOR, /* ^ */
|
||||
TOK_AND, /* & */
|
||||
TOK_SHL, /* << */
|
||||
TOK_SHR, /* >> */
|
||||
TOK_NOT, /* ~ */
|
||||
|
||||
TOK_PC, /* $ if enabled */
|
||||
TOK_NAMESPACE, /* :: */
|
||||
TOK_DOT, /* . */
|
||||
TOK_COMMA, /* , */
|
||||
TOK_HASH, /* # */
|
||||
TOK_COLON, /* : */
|
||||
TOK_LPAREN, /* ( */
|
||||
TOK_RPAREN, /* ) */
|
||||
TOK_LBRACK, /* [ */
|
||||
TOK_RBRACK, /* ] */
|
||||
TOK_PC, /* $ if enabled */
|
||||
TOK_NAMESPACE, /* :: */
|
||||
TOK_DOT, /* . */
|
||||
TOK_COMMA, /* , */
|
||||
TOK_HASH, /* # */
|
||||
TOK_COLON, /* : */
|
||||
TOK_LPAREN, /* ( */
|
||||
TOK_RPAREN, /* ) */
|
||||
TOK_LBRACK, /* [ */
|
||||
TOK_RBRACK, /* ] */
|
||||
TOK_LCURLY, /* { */
|
||||
TOK_RCURLY, /* } */
|
||||
TOK_AT, /* @ - in Sweet16 mode */
|
||||
@@ -115,12 +115,12 @@ typedef enum token_t {
|
||||
TOK_OVERRIDE_ABS, /* a: */
|
||||
TOK_OVERRIDE_FAR, /* f: */
|
||||
|
||||
TOK_MACPARAM, /* Macro parameter, not generated by scanner */
|
||||
TOK_REPCOUNTER, /* Repeat counter, not generated by scanner */
|
||||
TOK_MACPARAM, /* Macro parameter, not generated by scanner */
|
||||
TOK_REPCOUNTER, /* Repeat counter, not generated by scanner */
|
||||
|
||||
/* The next ones are tokens for the pseudo instructions. Keep together! */
|
||||
TOK_FIRSTPSEUDO,
|
||||
TOK_A16 = TOK_FIRSTPSEUDO,
|
||||
TOK_A16 = TOK_FIRSTPSEUDO,
|
||||
TOK_A8,
|
||||
TOK_ADDR,
|
||||
TOK_ALIGN,
|
||||
@@ -255,9 +255,9 @@ typedef enum token_t {
|
||||
TOK_WORD,
|
||||
TOK_XMATCH,
|
||||
TOK_ZEROPAGE,
|
||||
TOK_LASTPSEUDO = TOK_ZEROPAGE,
|
||||
TOK_LASTPSEUDO = TOK_ZEROPAGE,
|
||||
|
||||
TOK_COUNT /* Count of tokens */
|
||||
TOK_COUNT /* Count of tokens */
|
||||
} token_t;
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ struct Token {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* toklist.c */
|
||||
/* toklist.c */
|
||||
/* */
|
||||
/* Token list for the ca65 macroassembler */
|
||||
/* Token list for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -61,7 +61,7 @@ static unsigned PushCounter = 0;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -107,19 +107,19 @@ enum TC TokCmp (const TokNode* N)
|
||||
/* Compare the token given as parameter against the current token */
|
||||
{
|
||||
if (N->T.Tok != CurTok.Tok) {
|
||||
/* Different token */
|
||||
return tcDifferent;
|
||||
/* Different token */
|
||||
return tcDifferent;
|
||||
}
|
||||
|
||||
/* If the token has string attribute, check it */
|
||||
if (TokHasSVal (N->T.Tok)) {
|
||||
if (SB_Compare (&CurTok.SVal, &N->T.SVal) != 0) {
|
||||
return tcSameToken;
|
||||
}
|
||||
if (SB_Compare (&CurTok.SVal, &N->T.SVal) != 0) {
|
||||
return tcSameToken;
|
||||
}
|
||||
} else if (TokHasIVal (N->T.Tok)) {
|
||||
if (N->T.IVal != CurTok.IVal) {
|
||||
return tcSameToken;
|
||||
}
|
||||
if (N->T.IVal != CurTok.IVal) {
|
||||
return tcSameToken;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tokens are identical */
|
||||
@@ -135,14 +135,14 @@ TokList* NewTokList (void)
|
||||
TokList* T = xmalloc (sizeof (TokList));
|
||||
|
||||
/* Initialize the fields */
|
||||
T->Next = 0;
|
||||
T->Root = 0;
|
||||
T->Last = 0;
|
||||
T->RepCount = 0;
|
||||
T->RepMax = 1;
|
||||
T->Count = 0;
|
||||
T->Check = 0;
|
||||
T->Data = 0;
|
||||
T->Next = 0;
|
||||
T->Root = 0;
|
||||
T->Last = 0;
|
||||
T->RepCount = 0;
|
||||
T->RepMax = 1;
|
||||
T->Count = 0;
|
||||
T->Check = 0;
|
||||
T->Data = 0;
|
||||
T->LI = 0;
|
||||
|
||||
/* Return the new list */
|
||||
@@ -157,9 +157,9 @@ void FreeTokList (TokList* List)
|
||||
/* Free the token list */
|
||||
TokNode* T = List->Root;
|
||||
while (T) {
|
||||
TokNode* Tmp = T;
|
||||
T = T->Next;
|
||||
FreeTokNode (Tmp);
|
||||
TokNode* Tmp = T;
|
||||
T = T->Next;
|
||||
FreeTokNode (Tmp);
|
||||
}
|
||||
|
||||
/* Free associated line info */
|
||||
@@ -169,7 +169,7 @@ void FreeTokList (TokList* List)
|
||||
|
||||
/* If we have associated data, free it */
|
||||
if (List->Data) {
|
||||
xfree (List->Data);
|
||||
xfree (List->Data);
|
||||
}
|
||||
|
||||
/* Free the list structure itself */
|
||||
@@ -202,9 +202,9 @@ void AddCurTok (TokList* List)
|
||||
|
||||
/* Insert the node into the list */
|
||||
if (List->Root == 0) {
|
||||
List->Root = T;
|
||||
List->Root = T;
|
||||
} else {
|
||||
List->Last->Next = T;
|
||||
List->Last->Next = T;
|
||||
}
|
||||
List->Last = T;
|
||||
|
||||
@@ -227,16 +227,16 @@ static int ReplayTokList (void* List)
|
||||
* zero, delete the list and remove the function from the stack.
|
||||
*/
|
||||
if (L->Last == 0) {
|
||||
if (++L->RepCount >= L->RepMax) {
|
||||
/* Done with this list */
|
||||
FreeTokList (L);
|
||||
if (++L->RepCount >= L->RepMax) {
|
||||
/* Done with this list */
|
||||
FreeTokList (L);
|
||||
--PushCounter;
|
||||
PopInput ();
|
||||
PopInput ();
|
||||
return 0;
|
||||
} else {
|
||||
/* Replay one more time */
|
||||
L->Last = L->Root;
|
||||
}
|
||||
} else {
|
||||
/* Replay one more time */
|
||||
L->Last = L->Root;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the next token from the list */
|
||||
@@ -252,7 +252,7 @@ static int ReplayTokList (void* List)
|
||||
* just set and changed it as apropriate.
|
||||
*/
|
||||
if (L->Check) {
|
||||
L->Check (L);
|
||||
L->Check (L);
|
||||
}
|
||||
|
||||
/* Set the pointer to the next token */
|
||||
@@ -272,8 +272,8 @@ void PushTokList (TokList* List, const char* Desc)
|
||||
{
|
||||
/* If the list is empty, just delete it and bail out */
|
||||
if (List->Count == 0) {
|
||||
FreeTokList (List);
|
||||
return;
|
||||
FreeTokList (List);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset the last pointer to the first element */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* toklist.h */
|
||||
/* toklist.h */
|
||||
/* */
|
||||
/* Token list for the ca65 macroassembler */
|
||||
/* Token list for the ca65 macroassembler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -56,21 +56,21 @@
|
||||
/* Struct holding a token */
|
||||
typedef struct TokNode TokNode;
|
||||
struct TokNode {
|
||||
TokNode* Next; /* For single linked list */
|
||||
TokNode* Next; /* For single linked list */
|
||||
Token T; /* Token value */
|
||||
};
|
||||
|
||||
/* Struct holding a token list */
|
||||
typedef struct TokList TokList;
|
||||
struct TokList {
|
||||
TokList* Next; /* Single linked list (for replay) */
|
||||
TokNode* Root; /* First node in list */
|
||||
TokNode* Last; /* Last node in list or replay */
|
||||
unsigned RepCount; /* Repeat counter (used for replay) */
|
||||
unsigned RepMax; /* Maximum repeat count for replay */
|
||||
unsigned Count; /* Token count */
|
||||
void (*Check)(TokList*); /* Token check function */
|
||||
void* Data; /* Additional data for check */
|
||||
TokList* Next; /* Single linked list (for replay) */
|
||||
TokNode* Root; /* First node in list */
|
||||
TokNode* Last; /* Last node in list or replay */
|
||||
unsigned RepCount; /* Repeat counter (used for replay) */
|
||||
unsigned RepMax; /* Maximum repeat count for replay */
|
||||
unsigned Count; /* Token count */
|
||||
void (*Check)(TokList*); /* Token check function */
|
||||
void* Data; /* Additional data for check */
|
||||
LineInfo* LI; /* Line info for replay */
|
||||
};
|
||||
|
||||
@@ -78,15 +78,15 @@ struct TokList {
|
||||
|
||||
/* Return codes for TokCmp - higher numeric code means better match */
|
||||
enum TC {
|
||||
tcDifferent, /* Different tokents */
|
||||
tcSameToken, /* Same token, different attribute */
|
||||
tcIdentical /* Identical (token + attribute) */
|
||||
tcDifferent, /* Different tokents */
|
||||
tcSameToken, /* Same token, different attribute */
|
||||
tcIdentical /* Identical (token + attribute) */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user