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:
parent
11328d8ea6
commit
817b2ac261
7 changed files with 362 additions and 381 deletions
|
@ -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 ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue