Renamed the config file to info file and changed the handling when the

disassembler is invoked.


git-svn-id: svn://svn.cc65.org/cc65/trunk@2255 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-08-09 08:28:44 +00:00
parent 11328d8ea6
commit 817b2ac261
7 changed files with 362 additions and 381 deletions

View file

@ -1,15 +1,15 @@
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* config.c */ /* infofile.h */
/* */ /* */
/* Disassembler configuration file handling */ /* Disassembler info file handling */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Römerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* 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 */
@ -50,8 +50,8 @@
#include "attrtab.h" #include "attrtab.h"
#include "error.h" #include "error.h"
#include "global.h" #include "global.h"
#include "infofile.h"
#include "scanner.h" #include "scanner.h"
#include "config.h"
@ -65,74 +65,74 @@ static void GlobalSection (void)
/* Parse a global section */ /* Parse a global section */
{ {
static const IdentTok GlobalDefs[] = { static const IdentTok GlobalDefs[] = {
{ "INPUTNAME", CFGTOK_INPUTNAME }, { "INPUTNAME", INFOTOK_INPUTNAME },
{ "OUTPUTNAME", CFGTOK_OUTPUTNAME }, { "OUTPUTNAME", INFOTOK_OUTPUTNAME },
{ "PAGELENGTH", CFGTOK_PAGELENGTH }, { "PAGELENGTH", INFOTOK_PAGELENGTH },
{ "STARTADDR", CFGTOK_STARTADDR }, { "STARTADDR", INFOTOK_STARTADDR },
}; };
/* Skip the token */ /* Skip the token */
CfgNextTok (); InfoNextTok ();
/* Expect the opening curly brace */ /* Expect the opening curly brace */
CfgConsumeLCurly (); InfoConsumeLCurly ();
/* Look for section tokens */ /* Look for section tokens */
while (CfgTok != CFGTOK_RCURLY) { while (InfoTok != INFOTOK_RCURLY) {
/* Convert to special token */ /* Convert to special token */
CfgSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive"); InfoSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive");
/* Look at the token */ /* Look at the token */
switch (CfgTok) { switch (InfoTok) {
case CFGTOK_INPUTNAME: case INFOTOK_INPUTNAME:
CfgNextTok (); InfoNextTok ();
CfgAssureStr (); InfoAssureStr ();
if (InFile) { if (InFile) {
CfgError ("Input file name already given"); InfoError ("Input file name already given");
} }
InFile = xstrdup (CfgSVal); InFile = xstrdup (InfoSVal);
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_OUTPUTNAME: case INFOTOK_OUTPUTNAME:
CfgNextTok (); InfoNextTok ();
CfgAssureStr (); InfoAssureStr ();
if (OutFile) { if (OutFile) {
CfgError ("Output file name already given"); InfoError ("Output file name already given");
} }
OutFile = xstrdup (CfgSVal); OutFile = xstrdup (InfoSVal);
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_PAGELENGTH: case INFOTOK_PAGELENGTH:
CfgNextTok (); InfoNextTok ();
CfgAssureInt (); InfoAssureInt ();
if (CfgIVal != -1) { if (InfoIVal != -1) {
CfgRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN); InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
} }
PageLength = CfgIVal; PageLength = InfoIVal;
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_STARTADDR: case INFOTOK_STARTADDR:
CfgNextTok (); InfoNextTok ();
CfgAssureInt (); InfoAssureInt ();
CfgRangeCheck (0x0000, 0xFFFF); InfoRangeCheck (0x0000, 0xFFFF);
StartAddr = CfgIVal; StartAddr = InfoIVal;
CfgNextTok (); InfoNextTok ();
break; break;
} }
/* Directive is followed by a semicolon */ /* Directive is followed by a semicolon */
CfgConsumeSemi (); InfoConsumeSemi ();
} }
/* Consume the closing brace */ /* Consume the closing brace */
CfgConsumeRCurly (); InfoConsumeRCurly ();
} }
@ -141,19 +141,19 @@ static void RangeSection (void)
/* Parse a range section */ /* Parse a range section */
{ {
static const IdentTok RangeDefs[] = { static const IdentTok RangeDefs[] = {
{ "START", CFGTOK_START }, { "START", INFOTOK_START },
{ "END", CFGTOK_END }, { "END", INFOTOK_END },
{ "TYPE", CFGTOK_TYPE }, { "TYPE", INFOTOK_TYPE },
}; };
static const IdentTok TypeDefs[] = { static const IdentTok TypeDefs[] = {
{ "CODE", CFGTOK_CODE }, { "CODE", INFOTOK_CODE },
{ "BYTETABLE", CFGTOK_BYTETAB }, { "BYTETABLE", INFOTOK_BYTETAB },
{ "WORDTABLE", CFGTOK_WORDTAB }, { "WORDTABLE", INFOTOK_WORDTAB },
{ "DWORDTABLE", CFGTOK_DWORDTAB }, { "DWORDTABLE", INFOTOK_DWORDTAB },
{ "ADDRTABLE", CFGTOK_ADDRTAB }, { "ADDRTABLE", INFOTOK_ADDRTAB },
{ "RTSTABLE", CFGTOK_RTSTAB }, { "RTSTABLE", INFOTOK_RTSTAB },
{ "TEXTTABLE", CFGTOK_TEXTTAB }, { "TEXTTABLE", INFOTOK_TEXTTAB },
}; };
@ -172,75 +172,75 @@ static void RangeSection (void)
unsigned char Type = 0; unsigned char Type = 0;
/* Skip the token */ /* Skip the token */
CfgNextTok (); InfoNextTok ();
/* Expect the opening curly brace */ /* Expect the opening curly brace */
CfgConsumeLCurly (); InfoConsumeLCurly ();
/* Look for section tokens */ /* Look for section tokens */
while (CfgTok != CFGTOK_RCURLY) { while (InfoTok != INFOTOK_RCURLY) {
/* Convert to special token */ /* Convert to special token */
CfgSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive"); InfoSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
/* Look at the token */ /* Look at the token */
switch (CfgTok) { switch (InfoTok) {
case CFGTOK_START: case INFOTOK_START:
CfgNextTok (); InfoNextTok ();
CfgAssureInt (); InfoAssureInt ();
CfgRangeCheck (0x0000, 0xFFFF); InfoRangeCheck (0x0000, 0xFFFF);
Start = CfgIVal; Start = InfoIVal;
Needed |= tStart; Needed |= tStart;
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_END: case INFOTOK_END:
CfgNextTok (); InfoNextTok ();
CfgAssureInt (); InfoAssureInt ();
CfgRangeCheck (0x0000, 0xFFFF); InfoRangeCheck (0x0000, 0xFFFF);
End = CfgIVal; End = InfoIVal;
Needed |= tEnd; Needed |= tEnd;
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_TYPE: case INFOTOK_TYPE:
CfgNextTok (); InfoNextTok ();
CfgSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type"); InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
switch (CfgTok) { switch (InfoTok) {
case CFGTOK_CODE: Type = atCode; break; case INFOTOK_CODE: Type = atCode; break;
case CFGTOK_BYTETAB: Type = atByteTab; break; case INFOTOK_BYTETAB: Type = atByteTab; break;
case CFGTOK_WORDTAB: Type = atWordTab; break; case INFOTOK_WORDTAB: Type = atWordTab; break;
case CFGTOK_DWORDTAB: Type = atDWordTab; break; case INFOTOK_DWORDTAB: Type = atDWordTab; break;
case CFGTOK_ADDRTAB: Type = atAddrTab; break; case INFOTOK_ADDRTAB: Type = atAddrTab; break;
case CFGTOK_RTSTAB: Type = atRtsTab; break; case INFOTOK_RTSTAB: Type = atRtsTab; break;
case CFGTOK_TEXTTAB: Type = atTextTab; break; case INFOTOK_TEXTTAB: Type = atTextTab; break;
} }
Needed |= tType; Needed |= tType;
CfgNextTok (); InfoNextTok ();
break; break;
} }
/* Directive is followed by a semicolon */ /* Directive is followed by a semicolon */
CfgConsumeSemi (); InfoConsumeSemi ();
} }
/* Did we get all required values? */ /* Did we get all required values? */
if (Needed != tAll) { if (Needed != tAll) {
CfgError ("Required values missing from this section"); InfoError ("Required values missing from this section");
} }
/* Start must be less than end */ /* Start must be less than end */
if (Start > End) { if (Start > End) {
CfgError ("Start value must not be greater than end value"); InfoError ("Start value must not be greater than end value");
} }
/* Set the range */ /* Set the range */
MarkRange (Start, End, Type); MarkRange (Start, End, Type);
/* Consume the closing brace */ /* Consume the closing brace */
CfgConsumeRCurly (); InfoConsumeRCurly ();
} }
@ -249,9 +249,9 @@ static void LabelSection (void)
/* Parse a label section */ /* Parse a label section */
{ {
static const IdentTok LabelDefs[] = { static const IdentTok LabelDefs[] = {
{ "NAME", CFGTOK_NAME }, { "NAME", INFOTOK_NAME },
{ "ADDR", CFGTOK_ADDR }, { "ADDR", INFOTOK_ADDR },
{ "SIZE", CFGTOK_SIZE }, { "SIZE", INFOTOK_SIZE },
}; };
/* Locals - initialize to avoid gcc warnings */ /* Locals - initialize to avoid gcc warnings */
@ -260,77 +260,77 @@ static void LabelSection (void)
long Size = -1; long Size = -1;
/* Skip the token */ /* Skip the token */
CfgNextTok (); InfoNextTok ();
/* Expect the opening curly brace */ /* Expect the opening curly brace */
CfgConsumeLCurly (); InfoConsumeLCurly ();
/* Look for section tokens */ /* Look for section tokens */
while (CfgTok != CFGTOK_RCURLY) { while (InfoTok != INFOTOK_RCURLY) {
/* Convert to special token */ /* Convert to special token */
CfgSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive"); InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive");
/* Look at the token */ /* Look at the token */
switch (CfgTok) { switch (InfoTok) {
case CFGTOK_NAME: case INFOTOK_NAME:
CfgNextTok (); InfoNextTok ();
if (Name) { if (Name) {
CfgError ("Name already given"); InfoError ("Name already given");
} }
CfgAssureStr (); InfoAssureStr ();
if (CfgSVal[0] == '\0') { if (InfoSVal[0] == '\0') {
CfgError ("Name may not be empty"); InfoError ("Name may not be empty");
} }
Name = xstrdup (CfgSVal); Name = xstrdup (InfoSVal);
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_ADDR: case INFOTOK_ADDR:
CfgNextTok (); InfoNextTok ();
if (Value >= 0) { if (Value >= 0) {
CfgError ("Value already given"); InfoError ("Value already given");
} }
CfgAssureInt (); InfoAssureInt ();
CfgRangeCheck (0, 0xFFFF); InfoRangeCheck (0, 0xFFFF);
Value = CfgIVal; Value = InfoIVal;
CfgNextTok (); InfoNextTok ();
break; break;
case CFGTOK_SIZE: case INFOTOK_SIZE:
CfgNextTok (); InfoNextTok ();
if (Size >= 0) { if (Size >= 0) {
CfgError ("Size already given"); InfoError ("Size already given");
} }
CfgAssureInt (); InfoAssureInt ();
CfgRangeCheck (1, 0x10000); InfoRangeCheck (1, 0x10000);
Size = CfgIVal; Size = InfoIVal;
CfgNextTok (); InfoNextTok ();
break; break;
} }
/* Directive is followed by a semicolon */ /* Directive is followed by a semicolon */
CfgConsumeSemi (); InfoConsumeSemi ();
} }
/* Did we get the necessary data */ /* Did we get the necessary data */
if (Name == 0) { if (Name == 0) {
CfgError ("Label name is missing"); InfoError ("Label name is missing");
} }
if (Value < 0) { if (Value < 0) {
CfgError ("Label value is missing"); InfoError ("Label value is missing");
} }
if (Size < 0) { if (Size < 0) {
/* Use default */ /* Use default */
Size = 1; Size = 1;
} }
if (Value + Size > 0x10000) { if (Value + Size > 0x10000) {
CfgError ("Invalid size (address out of range)"); InfoError ("Invalid size (address out of range)");
} }
if (HaveLabel ((unsigned) Value)) { if (HaveLabel ((unsigned) Value)) {
CfgError ("Label for address $%04lX already defined", Value); InfoError ("Label for address $%04lX already defined", Value);
} }
/* Define the label */ /* Define the label */
@ -363,66 +363,63 @@ static void LabelSection (void)
xfree (Name); xfree (Name);
/* Consume the closing brace */ /* Consume the closing brace */
CfgConsumeRCurly (); InfoConsumeRCurly ();
} }
static void CfgParse (void) static void InfoParse (void)
/* Parse the config file */ /* Parse the config file */
{ {
static const IdentTok Globals[] = { static const IdentTok Globals[] = {
{ "GLOBAL", CFGTOK_GLOBAL }, { "GLOBAL", INFOTOK_GLOBAL },
{ "RANGE", CFGTOK_RANGE }, { "RANGE", INFOTOK_RANGE },
{ "LABEL", CFGTOK_LABEL }, { "LABEL", INFOTOK_LABEL },
}; };
while (CfgTok != CFGTOK_EOF) { while (InfoTok != INFOTOK_EOF) {
/* Convert an identifier into a token */ /* Convert an identifier into a token */
CfgSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive"); InfoSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive");
/* Check the token */ /* Check the token */
switch (CfgTok) { switch (InfoTok) {
case CFGTOK_GLOBAL: case INFOTOK_GLOBAL:
GlobalSection (); GlobalSection ();
break; break;
case CFGTOK_RANGE: case INFOTOK_RANGE:
RangeSection (); RangeSection ();
break; break;
case CFGTOK_LABEL: case INFOTOK_LABEL:
LabelSection (); LabelSection ();
break; break;
} }
/* Semicolon expected */ /* Semicolon expected */
CfgConsumeSemi (); InfoConsumeSemi ();
} }
} }
void CfgRead (void) void ReadInfoFile (void)
/* Read the configuration if a configuration file exists */ /* Read the info file */
{ {
/* Check if we have a config file given */ /* Check if we have a info file given */
if (!CfgAvail() || access (CfgGetName(), 0) != 0) { if (InfoAvail()) {
/* No name given or file not found */ /* Open the config file */
return; InfoOpenInput ();
/* Parse the config file */
InfoParse ();
/* Close the file */
InfoCloseInput ();
} }
/* Open the config file */
CfgOpenInput ();
/* Parse the config file */
CfgParse ();
/* Close the file */
CfgCloseInput ();
} }

View file

@ -1,15 +1,15 @@
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* config.h */ /* infofile.h */
/* */ /* */
/* Disassembler configuration file handling */ /* Disassembler info file handling */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Römerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* 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 */
@ -33,8 +33,8 @@
#ifndef CONFIG_H #ifndef INFOFILE_H
#define CONFIG_H #define INFOFILE_H
@ -44,12 +44,12 @@
void CfgRead (void); void ReadInfoFile (void);
/* Read the configuration if a configuration file exists */ /* Read the info file */
/* End of config.h */ /* End of infofile.h */
#endif #endif

View file

@ -50,10 +50,10 @@
/* da65 */ /* da65 */
#include "attrtab.h" #include "attrtab.h"
#include "code.h" #include "code.h"
#include "config.h"
#include "data.h" #include "data.h"
#include "error.h" #include "error.h"
#include "global.h" #include "global.h"
#include "infofile.h"
#include "opctable.h" #include "opctable.h"
#include "output.h" #include "output.h"
#include "scanner.h" #include "scanner.h"
@ -74,6 +74,7 @@ static void Usage (void)
"Short options:\n" "Short options:\n"
" -g\t\t\tAdd debug info to object file\n" " -g\t\t\tAdd debug info to object file\n"
" -h\t\t\tHelp (this text)\n" " -h\t\t\tHelp (this text)\n"
" -i name\t\tSpecify an info file\n"
" -o name\t\tName the output file\n" " -o name\t\tName the output file\n"
" -v\t\t\tIncrease verbosity\n" " -v\t\t\tIncrease verbosity\n"
" -F\t\t\tAdd formfeeds to the output\n" " -F\t\t\tAdd formfeeds to the output\n"
@ -85,6 +86,7 @@ static void Usage (void)
" --debug-info\t\tAdd debug info to object file\n" " --debug-info\t\tAdd debug info to object file\n"
" --formfeeds\t\tAdd formfeeds to the output\n" " --formfeeds\t\tAdd formfeeds to the output\n"
" --help\t\tHelp (this text)\n" " --help\t\tHelp (this text)\n"
" --info name\t\tSpecify an info file\n"
" --pagelength n\tSet the page length for the listing\n" " --pagelength n\tSet the page length for the listing\n"
" --start-addr addr\tSet the start/load address\n" " --start-addr addr\tSet the start/load address\n"
" --verbose\t\tIncrease verbosity\n" " --verbose\t\tIncrease verbosity\n"
@ -159,6 +161,14 @@ static void OptHelp (const char* Opt attribute ((unused)),
static void OptInfo (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --info option */
{
InfoSetName (Arg);
}
static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg) static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --pagelength option */ /* Handle the --pagelength option */
{ {
@ -222,7 +232,7 @@ static void OneOpcode (unsigned RemainingBytes)
if (GetStyleAttr (PC) == atDefault) { if (GetStyleAttr (PC) == atDefault) {
if (D->Size > RemainingBytes) { if (D->Size > RemainingBytes) {
MarkAddr (PC, atIllegal); MarkAddr (PC, atIllegal);
} else if (D->Flags & flIllegal) { } else if (D->Flags & flIllegal) {
MarkAddr (PC, atIllegal); MarkAddr (PC, atIllegal);
} else { } else {
unsigned I; unsigned I;
@ -320,6 +330,7 @@ int main (int argc, char* argv [])
{ "--debug-info", 0, OptDebugInfo }, { "--debug-info", 0, OptDebugInfo },
{ "--formfeeds", 0, OptFormFeeds }, { "--formfeeds", 0, OptFormFeeds },
{ "--help", 0, OptHelp }, { "--help", 0, OptHelp },
{ "--info", 1, OptInfo },
{ "--pagelength", 1, OptPageLength }, { "--pagelength", 1, OptPageLength },
{ "--start-addr", 1, OptStartAddr }, { "--start-addr", 1, OptStartAddr },
{ "--verbose", 0, OptVerbose }, { "--verbose", 0, OptVerbose },
@ -354,6 +365,10 @@ int main (int argc, char* argv [])
OptHelp (Arg, 0); OptHelp (Arg, 0);
break; break;
case 'i':
OptInfo (Arg, GetArg (&I, 2));
break;
case 'o': case 'o':
OutFile = GetArg (&I, 2); OutFile = GetArg (&I, 2);
break; break;
@ -395,13 +410,8 @@ int main (int argc, char* argv [])
AbEnd ("No input file"); AbEnd ("No input file");
} }
/* Make the config file name from the input file if none was given */
if (!CfgAvail ()) {
CfgSetName (MakeFilename (InFile, CfgExt));
}
/* Try to read the configuration file */ /* Try to read the configuration file */
CfgRead (); ReadInfoFile ();
/* Make the output file name from the input file name if none was given */ /* Make the output file name from the input file name if none was given */
if (OutFile == 0) { if (OutFile == 0) {

View file

@ -12,11 +12,11 @@ LDFLAGS=
OBJS = attrtab.o \ OBJS = attrtab.o \
code.o \ code.o \
config.o \
data.o \ data.o \
error.o \ error.o \
global.o \ global.o \
handler.o \ handler.o \
infofile.o \
main.o \ main.o \
opc6502.o \ opc6502.o \
opc65816.o \ opc65816.o \

View file

@ -45,14 +45,18 @@ CFLAGS += -i=..\common
OBJS = attrtab.obj \ OBJS = attrtab.obj \
code.obj \ code.obj \
config.obj \
cpu.obj \ cpu.obj \
data.obj \ data.obj \
error.obj \ error.obj \
global.obj \ global.obj \
handler.obj \ handler.obj \
infofile.obj \
main.obj \ main.obj \
opctable.obj \ opc6502.obj \
opc65816.obj \
opc65c02.obj \
opc65sc02.obj \
opctable.obj \
output.obj \ output.obj \
scanner.obj scanner.obj

View file

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Römerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* 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 */
@ -37,7 +37,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h>
/* common */ /* common */
#include "chartype.h" #include "chartype.h"
@ -57,17 +56,16 @@
/* Current token and attributes */ /* Current token and attributes */
unsigned CfgTok; unsigned InfoTok;
char CfgSVal [CFG_MAX_IDENT_LEN+1]; char InfoSVal [CFG_MAX_IDENT_LEN+1];
long CfgIVal; long InfoIVal;
/* Error location */ /* Error location */
unsigned CfgErrorLine; unsigned InfoErrorLine;
unsigned CfgErrorCol; unsigned InfoErrorCol;
/* Input sources for the configuration */ /* Input sources for the configuration */
static const char* CfgFile = 0; static const char* InfoFile = 0;
static const char* CfgBuf = 0;
/* Other input stuff */ /* Other input stuff */
static int C = ' '; static int C = ' ';
@ -83,7 +81,7 @@ static FILE* InputFile = 0;
void CfgWarning (const char* Format, ...) void InfoWarning (const char* Format, ...)
/* Print a warning message adding file name and line number of the config file */ /* Print a warning message adding file name and line number of the config file */
{ {
char Buf [512]; char Buf [512];
@ -93,12 +91,12 @@ void CfgWarning (const char* Format, ...)
xvsprintf (Buf, sizeof (Buf), Format, ap); xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap); va_end (ap);
Warning ("%s(%u): %s", CfgFile, CfgErrorLine, Buf); Warning ("%s(%u): %s", InfoFile, InfoErrorLine, Buf);
} }
void CfgError (const char* Format, ...) void InfoError (const char* Format, ...)
/* Print an error message adding file name and line number of the config file */ /* Print an error message adding file name and line number of the config file */
{ {
char Buf [512]; char Buf [512];
@ -108,7 +106,7 @@ void CfgError (const char* Format, ...)
xvsprintf (Buf, sizeof (Buf), Format, ap); xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap); va_end (ap);
Error ("%s(%u): %s", CfgFile, CfgErrorLine, Buf); Error ("%s(%u): %s", InfoFile, InfoErrorLine, Buf);
} }
@ -122,18 +120,8 @@ void CfgError (const char* Format, ...)
static void NextChar (void) static void NextChar (void)
/* Read the next character from the input file */ /* Read the next character from the input file */
{ {
if (CfgBuf) { /* Read from the file */
/* Read from buffer */ C = getc (InputFile);
C = (unsigned char)(*CfgBuf);
if (C == 0) {
C = EOF;
} else {
++CfgBuf;
}
} else {
/* Read from the file */
C = getc (InputFile);
}
/* Count columns */ /* Count columns */
if (C != EOF) { if (C != EOF) {
@ -152,7 +140,7 @@ static void NextChar (void)
static unsigned DigitVal (int C) static unsigned DigitVal (int C)
/* Return the value for a numeric digit */ /* Return the value for a numeric digit */
{ {
if (isdigit (C)) { if (IsDigit (C)) {
return C - '0'; return C - '0';
} else { } else {
return toupper (C) - 'A' + 10; return toupper (C) - 'A' + 10;
@ -161,7 +149,7 @@ static unsigned DigitVal (int C)
void CfgNextTok (void) void InfoNextTok (void)
/* Read the next token from the input stream */ /* Read the next token from the input stream */
{ {
unsigned I; unsigned I;
@ -169,13 +157,13 @@ void CfgNextTok (void)
Again: Again:
/* Skip whitespace */ /* Skip whitespace */
while (isspace (C)) { while (IsSpace (C)) {
NextChar (); NextChar ();
} }
/* Remember the current position */ /* Remember the current position */
CfgErrorLine = InputLine; InfoErrorLine = InputLine;
CfgErrorCol = InputCol; InfoErrorCol = InputCol;
/* Identifier? */ /* Identifier? */
if (C == '_' || IsAlpha (C)) { if (C == '_' || IsAlpha (C)) {
@ -184,38 +172,38 @@ Again:
I = 0; I = 0;
while (C == '_' || IsAlNum (C)) { while (C == '_' || IsAlNum (C)) {
if (I < CFG_MAX_IDENT_LEN) { if (I < CFG_MAX_IDENT_LEN) {
CfgSVal [I++] = C; InfoSVal [I++] = C;
} }
NextChar (); NextChar ();
} }
CfgSVal [I] = '\0'; InfoSVal [I] = '\0';
CfgTok = CFGTOK_IDENT; InfoTok = INFOTOK_IDENT;
return; return;
} }
/* Hex number? */ /* Hex number? */
if (C == '$') { if (C == '$') {
NextChar (); NextChar ();
if (!isxdigit (C)) { if (!IsXDigit (C)) {
CfgError ("Hex digit expected"); InfoError ("Hex digit expected");
} }
CfgIVal = 0; InfoIVal = 0;
while (isxdigit (C)) { while (IsXDigit (C)) {
CfgIVal = CfgIVal * 16 + DigitVal (C); InfoIVal = InfoIVal * 16 + DigitVal (C);
NextChar (); NextChar ();
} }
CfgTok = CFGTOK_INTCON; InfoTok = INFOTOK_INTCON;
return; return;
} }
/* Decimal number? */ /* Decimal number? */
if (isdigit (C)) { if (IsDigit (C)) {
CfgIVal = 0; InfoIVal = 0;
while (isdigit (C)) { while (IsDigit (C)) {
CfgIVal = CfgIVal * 10 + DigitVal (C); InfoIVal = InfoIVal * 10 + DigitVal (C);
NextChar (); NextChar ();
} }
CfgTok = CFGTOK_INTCON; InfoTok = INFOTOK_INTCON;
return; return;
} }
@ -224,37 +212,37 @@ Again:
case '{': case '{':
NextChar (); NextChar ();
CfgTok = CFGTOK_LCURLY; InfoTok = INFOTOK_LCURLY;
break; break;
case '}': case '}':
NextChar (); NextChar ();
CfgTok = CFGTOK_RCURLY; InfoTok = INFOTOK_RCURLY;
break; break;
case ';': case ';':
NextChar (); NextChar ();
CfgTok = CFGTOK_SEMI; InfoTok = INFOTOK_SEMI;
break; break;
case '.': case '.':
NextChar (); NextChar ();
CfgTok = CFGTOK_DOT; InfoTok = INFOTOK_DOT;
break; break;
case ',': case ',':
NextChar (); NextChar ();
CfgTok = CFGTOK_COMMA; InfoTok = INFOTOK_COMMA;
break; break;
case '=': case '=':
NextChar (); NextChar ();
CfgTok = CFGTOK_EQ; InfoTok = INFOTOK_EQ;
break; break;
case ':': case ':':
NextChar (); NextChar ();
CfgTok = CFGTOK_COLON; InfoTok = INFOTOK_COLON;
break; break;
case '\"': case '\"':
@ -262,16 +250,16 @@ Again:
I = 0; I = 0;
while (C != '\"') { while (C != '\"') {
if (C == EOF || C == '\n') { if (C == EOF || C == '\n') {
CfgError ("Unterminated string"); InfoError ("Unterminated string");
} }
if (I < CFG_MAX_IDENT_LEN) { if (I < CFG_MAX_IDENT_LEN) {
CfgSVal [I++] = C; InfoSVal [I++] = C;
} }
NextChar (); NextChar ();
} }
NextChar (); NextChar ();
CfgSVal [I] = '\0'; InfoSVal [I] = '\0';
CfgTok = CFGTOK_STRCON; InfoTok = INFOTOK_STRCON;
break; break;
case '#': case '#':
@ -282,143 +270,143 @@ Again:
if (C != EOF) { if (C != EOF) {
goto Again; goto Again;
} }
CfgTok = CFGTOK_EOF; InfoTok = INFOTOK_EOF;
break; break;
case EOF: case EOF:
CfgTok = CFGTOK_EOF; InfoTok = INFOTOK_EOF;
break; break;
default: default:
CfgError ("Invalid character `%c'", C); InfoError ("Invalid character `%c'", C);
} }
} }
void CfgConsume (unsigned T, const char* Msg) void InfoConsume (unsigned T, const char* Msg)
/* Skip a token, print an error message if not found */ /* Skip a token, print an error message if not found */
{ {
if (CfgTok != T) { if (InfoTok != T) {
CfgError (Msg); InfoError (Msg);
} }
CfgNextTok (); InfoNextTok ();
} }
void CfgConsumeLCurly (void) void InfoConsumeLCurly (void)
/* Consume a left curly brace */ /* Consume a left curly brace */
{ {
CfgConsume (CFGTOK_LCURLY, "`{' expected"); InfoConsume (INFOTOK_LCURLY, "`{' expected");
} }
void CfgConsumeRCurly (void) void InfoConsumeRCurly (void)
/* Consume a right curly brace */ /* Consume a right curly brace */
{ {
CfgConsume (CFGTOK_RCURLY, "`}' expected"); InfoConsume (INFOTOK_RCURLY, "`}' expected");
} }
void CfgConsumeSemi (void) void InfoConsumeSemi (void)
/* Consume a semicolon */ /* Consume a semicolon */
{ {
CfgConsume (CFGTOK_SEMI, "`;' expected"); InfoConsume (INFOTOK_SEMI, "`;' expected");
} }
void CfgConsumeColon (void) void InfoConsumeColon (void)
/* Consume a colon */ /* Consume a colon */
{ {
CfgConsume (CFGTOK_COLON, "`:' expected"); InfoConsume (INFOTOK_COLON, "`:' expected");
} }
void CfgOptionalComma (void) void InfoOptionalComma (void)
/* Consume a comma if there is one */ /* Consume a comma if there is one */
{ {
if (CfgTok == CFGTOK_COMMA) { if (InfoTok == INFOTOK_COMMA) {
CfgNextTok (); InfoNextTok ();
} }
} }
void CfgOptionalAssign (void) void InfoOptionalAssign (void)
/* Consume an equal sign if there is one */ /* Consume an equal sign if there is one */
{ {
if (CfgTok == CFGTOK_EQ) { if (InfoTok == INFOTOK_EQ) {
CfgNextTok (); InfoNextTok ();
} }
} }
void CfgAssureInt (void) void InfoAssureInt (void)
/* Make sure the next token is an integer */ /* Make sure the next token is an integer */
{ {
if (CfgTok != CFGTOK_INTCON) { if (InfoTok != INFOTOK_INTCON) {
CfgError ("Integer constant expected"); InfoError ("Integer constant expected");
} }
} }
void CfgAssureStr (void) void InfoAssureStr (void)
/* Make sure the next token is a string constant */ /* Make sure the next token is a string constant */
{ {
if (CfgTok != CFGTOK_STRCON) { if (InfoTok != INFOTOK_STRCON) {
CfgError ("String constant expected"); InfoError ("String constant expected");
} }
} }
void CfgAssureIdent (void) void InfoAssureIdent (void)
/* Make sure the next token is an identifier */ /* Make sure the next token is an identifier */
{ {
if (CfgTok != CFGTOK_IDENT) { if (InfoTok != INFOTOK_IDENT) {
CfgError ("Identifier expected"); InfoError ("Identifier expected");
} }
} }
void CfgRangeCheck (long Lo, long Hi) void InfoRangeCheck (long Lo, long Hi)
/* Check the range of CfgIVal */ /* Check the range of InfoIVal */
{ {
if (CfgIVal < Lo || CfgIVal > Hi) { if (InfoIVal < Lo || InfoIVal > Hi) {
CfgError ("Range error"); InfoError ("Range error");
} }
} }
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
/* Map an identifier to one of the special tokens in the table */ /* Map an identifier to one of the special tokens in the table */
{ {
unsigned I; unsigned I;
/* We need an identifier */ /* We need an identifier */
if (CfgTok == CFGTOK_IDENT) { if (InfoTok == INFOTOK_IDENT) {
/* Make it upper case */ /* Make it upper case */
I = 0; I = 0;
while (CfgSVal [I]) { while (InfoSVal [I]) {
CfgSVal [I] = toupper (CfgSVal [I]); InfoSVal [I] = toupper (InfoSVal [I]);
++I; ++I;
} }
/* Linear search */ /* Linear search */
for (I = 0; I < Size; ++I) { for (I = 0; I < Size; ++I) {
if (strcmp (CfgSVal, Table [I].Ident) == 0) { if (strcmp (InfoSVal, Table [I].Ident) == 0) {
CfgTok = Table [I].Tok; InfoTok = Table [I].Tok;
return; return;
} }
} }
@ -426,81 +414,66 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
} }
/* Not found or no identifier */ /* Not found or no identifier */
CfgError ("%s expected", Name); InfoError ("%s expected", Name);
} }
void CfgBoolToken (void) void InfoBoolToken (void)
/* Map an identifier or integer to a boolean token */ /* Map an identifier or integer to a boolean token */
{ {
static const IdentTok Booleans [] = { static const IdentTok Booleans [] = {
{ "YES", CFGTOK_TRUE }, { "YES", INFOTOK_TRUE },
{ "NO", CFGTOK_FALSE }, { "NO", INFOTOK_FALSE },
{ "TRUE", CFGTOK_TRUE }, { "TRUE", INFOTOK_TRUE },
{ "FALSE", CFGTOK_FALSE }, { "FALSE", INFOTOK_FALSE },
}; };
/* If we have an identifier, map it to a boolean token */ /* If we have an identifier, map it to a boolean token */
if (CfgTok == CFGTOK_IDENT) { if (InfoTok == INFOTOK_IDENT) {
CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean"); InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
} else { } else {
/* We expected an integer here */ /* We expected an integer here */
if (CfgTok != CFGTOK_INTCON) { if (InfoTok != INFOTOK_INTCON) {
CfgError ("Boolean value expected"); InfoError ("Boolean value expected");
} }
CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE; InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE;
} }
} }
void CfgSetName (const char* Name) void InfoSetName (const char* Name)
/* Set a name for a config file */ /* Set a name for a config file */
{ {
CfgFile = Name; InfoFile = Name;
} }
const char* CfgGetName (void) const char* InfoGetName (void)
/* Get the name of the config file */ /* Get the name of the config file */
{ {
return CfgFile? CfgFile : ""; return InfoFile? InfoFile : "";
} }
void CfgSetBuf (const char* Buf) int InfoAvail ()
/* Set a memory buffer for the config */ /* Return true if we have an info file given */
{ {
CfgBuf = Buf; return (InfoFile != 0);
} }
int CfgAvail (void) void InfoOpenInput (void)
/* Return true if we have a configuration available */ /* Open the input file */
{ {
return CfgFile != 0 || CfgBuf != 0; /* Open the file */
} InputFile = fopen (InfoFile, "r");
if (InputFile == 0) {
Error ("Cannot open `%s': %s", InfoFile, strerror (errno));
void CfgOpenInput (void)
/* Open the input file if we have one */
{
/* If we have a config name given, open the file, otherwise we will read
* from a buffer.
*/
if (!CfgBuf) {
/* Open the file */
InputFile = fopen (CfgFile, "r");
if (InputFile == 0) {
Error ("Cannot open `%s': %s", CfgFile, strerror (errno));
}
} }
/* Initialize variables */ /* Initialize variables */
@ -509,12 +482,12 @@ void CfgOpenInput (void)
InputCol = 0; InputCol = 0;
/* Start the ball rolling ... */ /* Start the ball rolling ... */
CfgNextTok (); InfoNextTok ();
} }
void CfgCloseInput (void) void InfoCloseInput (void)
/* Close the input file if we have one */ /* Close the input file if we have one */
{ {
/* Close the input file if we had one */ /* Close the input file if we had one */

View file

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Römerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* 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 */
@ -44,59 +44,59 @@
/* Config file tokens */ /* Info file tokens */
typedef enum token_t { typedef enum token_t {
CFGTOK_NONE, INFOTOK_NONE,
CFGTOK_INTCON, INFOTOK_INTCON,
CFGTOK_STRCON, INFOTOK_STRCON,
CFGTOK_IDENT, INFOTOK_IDENT,
CFGTOK_LCURLY, INFOTOK_LCURLY,
CFGTOK_RCURLY, INFOTOK_RCURLY,
CFGTOK_SEMI, INFOTOK_SEMI,
CFGTOK_COMMA, INFOTOK_COMMA,
CFGTOK_EQ, INFOTOK_EQ,
CFGTOK_COLON, INFOTOK_COLON,
CFGTOK_DOT, INFOTOK_DOT,
CFGTOK_EOF, INFOTOK_EOF,
/* Special tokens */ /* Special tokens */
CFGTOK_GLOBAL, INFOTOK_GLOBAL,
CFGTOK_RANGE, INFOTOK_RANGE,
CFGTOK_LABEL, INFOTOK_LABEL,
/* Global section */ /* Global section */
CFGTOK_INPUTNAME, INFOTOK_INPUTNAME,
CFGTOK_OUTPUTNAME, INFOTOK_OUTPUTNAME,
CFGTOK_PAGELENGTH, INFOTOK_PAGELENGTH,
CFGTOK_STARTADDR, INFOTOK_STARTADDR,
/* Range section */ /* Range section */
CFGTOK_START, INFOTOK_START,
CFGTOK_END, INFOTOK_END,
CFGTOK_TYPE, INFOTOK_TYPE,
CFGTOK_CODE, INFOTOK_CODE,
CFGTOK_BYTETAB, INFOTOK_BYTETAB,
CFGTOK_WORDTAB, INFOTOK_WORDTAB,
CFGTOK_DWORDTAB, INFOTOK_DWORDTAB,
CFGTOK_ADDRTAB, INFOTOK_ADDRTAB,
CFGTOK_RTSTAB, INFOTOK_RTSTAB,
CFGTOK_TEXTTAB, INFOTOK_TEXTTAB,
/* Label section */ /* Label section */
CFGTOK_NAME, INFOTOK_NAME,
CFGTOK_ADDR, INFOTOK_ADDR,
CFGTOK_SIZE, INFOTOK_SIZE,
/* */ /* */
CFGTOK_TRUE, INFOTOK_TRUE,
CFGTOK_FALSE INFOTOK_FALSE
} token_t; } token_t;
/* Mapping table entry, special identifier --> token */ /* Mapping table entry, special identifier --> token */
typedef struct IdentTok_ IdentTok; typedef struct IdentTok IdentTok;
struct IdentTok_ { struct IdentTok {
const char* Ident; /* Identifier */ const char* Ident; /* Identifier */
token_t Tok; /* Token for identifier */ token_t Tok; /* Token for identifier */
}; };
@ -106,13 +106,13 @@ struct IdentTok_ {
/* Current token and attributes */ /* Current token and attributes */
#define CFG_MAX_IDENT_LEN 255 #define CFG_MAX_IDENT_LEN 255
extern unsigned CfgTok; extern unsigned InfoTok;
extern char CfgSVal [CFG_MAX_IDENT_LEN+1]; extern char InfoSVal [CFG_MAX_IDENT_LEN+1];
extern long CfgIVal; extern long InfoIVal;
/* Error location */ /* Error location */
extern unsigned CfgErrorLine; extern unsigned InfoErrorLine;
extern unsigned CfgErrorCol; extern unsigned InfoErrorCol;
@ -122,70 +122,67 @@ extern unsigned CfgErrorCol;
void CfgWarning (const char* Format, ...); void InfoWarning (const char* Format, ...);
/* Print a warning message adding file name and line number of the config file */ /* Print a warning message adding file name and line number of the config file */
void CfgError (const char* Format, ...); void InfoError (const char* Format, ...);
/* Print an error message adding file name and line number of the config file */ /* Print an error message adding file name and line number of the config file */
void CfgNextTok (void); void InfoNextTok (void);
/* Read the next token from the input stream */ /* Read the next token from the input stream */
void CfgConsume (unsigned T, const char* Msg); void InfoConsume (unsigned T, const char* Msg);
/* Skip a token, print an error message if not found */ /* Skip a token, print an error message if not found */
void CfgConsumeLCurly (void); void InfoConsumeLCurly (void);
/* Consume a left curly brace */ /* Consume a left curly brace */
void CfgConsumeRCurly (void); void InfoConsumeRCurly (void);
/* Consume a right curly brace */ /* Consume a right curly brace */
void CfgConsumeSemi (void); void InfoConsumeSemi (void);
/* Consume a semicolon */ /* Consume a semicolon */
void CfgConsumeColon (void); void InfoConsumeColon (void);
/* Consume a colon */ /* Consume a colon */
void CfgOptionalComma (void); void InfoOptionalComma (void);
/* Consume a comma if there is one */ /* Consume a comma if there is one */
void CfgOptionalAssign (void); void InfoOptionalAssign (void);
/* Consume an equal sign if there is one */ /* Consume an equal sign if there is one */
void CfgAssureInt (void); void InfoAssureInt (void);
/* Make sure the next token is an integer */ /* Make sure the next token is an integer */
void CfgAssureStr (void); void InfoAssureStr (void);
/* Make sure the next token is a string constant */ /* Make sure the next token is a string constant */
void CfgAssureIdent (void); void InfoAssureIdent (void);
/* Make sure the next token is an identifier */ /* Make sure the next token is an identifier */
void CfgRangeCheck (long Lo, long Hi); void InfoRangeCheck (long Lo, long Hi);
/* Check the range of CfgIVal */ /* Check the range of InfoIVal */
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name); void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name);
/* Map an identifier to one of the special tokens in the table */ /* Map an identifier to one of the special tokens in the table */
void CfgBoolToken (void); void InfoBoolToken (void);
/* Map an identifier or integer to a boolean token */ /* Map an identifier or integer to a boolean token */
void CfgSetName (const char* Name); void InfoSetName (const char* Name);
/* Set a name for a config file */ /* Set a name for a config file */
const char* CfgGetName (void); const char* InfoGetName (void);
/* Get the name of the config file */ /* Get the name of the config file */
void CfgSetBuf (const char* Buf); int InfoAvail ();
/* Set a memory buffer for the config */ /* Return true if we have an info file given */
int CfgAvail (void); void InfoOpenInput (void);
/* Return true if we have a configuration available */
void CfgOpenInput (void);
/* Open the input file if we have one */ /* Open the input file if we have one */
void CfgCloseInput (void); void InfoCloseInput (void);
/* Close the input file if we have one */ /* Close the input file if we have one */