DebuggerParser now supports labels in input. Labels are treated

case-insensitively!

We look for labels *first*, so if there were a label "aa", it'd
be impossible to input the hex value "aa" (the label would take
precedence). This doesn't matter for now, since the labels are hard-coded
and none of them conflict with anything, but in the future we'll be
loading symbol files... even then, I don't think anyone's dumb enough
to create a label that looks like a hex value, but it could happen...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@495 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-06-14 03:11:03 +00:00
parent 5e911f1453
commit cdb61cddb0
5 changed files with 67 additions and 18 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Debugger.cxx,v 1.4 2005-06-14 00:58:39 urchlay Exp $ // $Id: Debugger.cxx,v 1.5 2005-06-14 03:11:03 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -192,13 +192,18 @@ void Debugger::writeRAM(uInt16 addr, uInt8 value)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::setRAM(int argCount, int *args) { const string Debugger::setRAM(int argCount, int *args) {
char buf[10];
int address = args[0]; int address = args[0];
for(int i=1; i<argCount; i++) for(int i=1; i<argCount; i++)
mySystem->poke(address++, args[i]); mySystem->poke(address++, args[i]);
string ret = "changed "; string ret = "changed ";
ret += args[0]; sprintf(buf, "%d", argCount-1);
ret += " locations"; ret += buf;
ret += " location";
if(argCount > 2)
ret += "s";
return ret; return ret;
} }

View File

@ -13,12 +13,13 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: DebuggerParser.cxx,v 1.2 2005-06-13 02:47:44 urchlay Exp $ // $Id: DebuggerParser.cxx,v 1.3 2005-06-14 03:11:03 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
#include "Debugger.hxx" #include "Debugger.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
#include "EquateList.hxx"
// Constants for argument processing // Constants for argument processing
enum { enum {
@ -32,10 +33,12 @@ enum {
DebuggerParser::DebuggerParser(Debugger* d) DebuggerParser::DebuggerParser(Debugger* d)
: debugger(d) : debugger(d)
{ {
equateList = new EquateList();
done = false; done = false;
} }
DebuggerParser::~DebuggerParser() { DebuggerParser::~DebuggerParser() {
delete equateList;
} }
string DebuggerParser::currentAddress() { string DebuggerParser::currentAddress() {
@ -53,13 +56,35 @@ int DebuggerParser::conv_hex_digit(char d) {
return d - 'a' + 10; return d - 'a' + 10;
else if(d >= 'A' && d <= 'F') else if(d >= 'A' && d <= 'F')
return d - 'A' + 10; return d - 'A' + 10;
else return 0; else return -1;
} }
void DebuggerParser::getArgs(const string& command) { // Given a string argument that's either a label or a
// hex value, either dereference the label or convert
// the hex to an int. Returns -1 on error.
int DebuggerParser::decipher_arg(string &arg) {
const char *a = arg.c_str();
int address = equateList->getAddress(a);
// cerr << "decipher_arg: equateList->getAddress(" << a << ") == " << address << endl;
if(address >= 0)
return address;
address = 0;
while(*a != '\0') {
int hex = conv_hex_digit(*a++);
if(hex < 0)
return -1;
address = (address << 4) + hex;
}
return address;
}
bool DebuggerParser::getArgs(const string& command) {
int state = kIN_COMMAND; int state = kIN_COMMAND;
int deref = 0; int deref = 0;
int curArg = 0; string curArg = "";
argCount = 0; argCount = 0;
verb = ""; verb = "";
const char *c = command.c_str(); const char *c = command.c_str();
@ -85,8 +110,9 @@ void DebuggerParser::getArgs(const string& command) {
break; break;
case kIN_ARG_START: case kIN_ARG_START:
curArg = 0; curArg = "";
state = kIN_ARG_CONT; state = kIN_ARG_CONT;
// FIXME: actually use this.
if(*c == '*') { if(*c == '*') {
deref = 1; deref = 1;
c++; c++;
@ -95,7 +121,7 @@ void DebuggerParser::getArgs(const string& command) {
} // FALL THROUGH! } // FALL THROUGH!
case kIN_ARG_CONT: case kIN_ARG_CONT:
if(isxdigit(*c)) { /*if(isxdigit(*c)) {
int dig = conv_hex_digit(*c); int dig = conv_hex_digit(*c);
curArg = (curArg << 4) + dig; curArg = (curArg << 4) + dig;
*c++; *c++;
@ -103,23 +129,37 @@ void DebuggerParser::getArgs(const string& command) {
args[argCount++] = curArg; args[argCount++] = curArg;
state = kIN_SPACE; state = kIN_SPACE;
} }
break; break;*/
if(isalpha(*c) || isdigit(*c) || *c == '_') {
curArg += *c++;
// cerr << "curArg: " << curArg << endl;
} else {
args[argCount] = decipher_arg(curArg);
if(args[argCount] < 0)
return false;
argCount++;
curArg = "";
state = kIN_SPACE;
}
} }
if(argCount == 10) { if(argCount == 10) {
cerr << "reached max 10 args" << endl; cerr << "reached max 10 args" << endl;
return; return true;
} }
} }
// pick up last arg, if any: // pick up last arg, if any:
if(state == kIN_ARG_CONT || state == kIN_ARG_START) if(state == kIN_ARG_CONT || state == kIN_ARG_START)
args[argCount++] = curArg; if( (args[argCount++] = decipher_arg(curArg)) < 0)
return false;
// for(int i=0; i<argCount; i++) // for(int i=0; i<argCount; i++)
// cerr << "args[" << i << "] == " << args[i] << endl; // cerr << "args[" << i << "] == " << args[i] << endl;
// cerr << endl; // cerr << endl;
return true;
} }
bool DebuggerParser::subStringMatch(const string& needle, const string& haystack) { bool DebuggerParser::subStringMatch(const string& needle, const string& haystack) {
@ -135,7 +175,8 @@ bool DebuggerParser::subStringMatch(const string& needle, const string& haystack
string DebuggerParser::run(const string& command) { string DebuggerParser::run(const string& command) {
string result; string result;
getArgs(command); if(!getArgs(command))
return "invalid label or address";
// "verb" is the command, stripped of any arguments. // "verb" is the command, stripped of any arguments.
// In the if/else below, put shorter command names first. // In the if/else below, put shorter command names first.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: DebuggerParser.hxx,v 1.3 2005-06-13 17:24:42 urchlay Exp $ // $Id: DebuggerParser.hxx,v 1.4 2005-06-14 03:11:03 urchlay Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_PARSER_HXX #ifndef DEBUGGER_PARSER_HXX
@ -22,6 +22,7 @@
class Debugger; class Debugger;
#include "bspf.hxx" #include "bspf.hxx"
#include "EquateList.hxx"
class DebuggerParser class DebuggerParser
{ {
@ -32,13 +33,15 @@ class DebuggerParser
string currentAddress(); string currentAddress();
void setDone(); void setDone();
string run(const string& command); string run(const string& command);
void getArgs(const string& command); bool getArgs(const string& command);
private: private:
int DebuggerParser::conv_hex_digit(char d); int DebuggerParser::conv_hex_digit(char d);
bool DebuggerParser::subStringMatch(const string& needle, const string& haystack); bool DebuggerParser::subStringMatch(const string& needle, const string& haystack);
int decipher_arg(string &arg);
Debugger* debugger; Debugger* debugger;
EquateList *equateList;
bool done; bool done;

View File

@ -102,9 +102,9 @@ char *EquateList::getFormatted(int addr, int places) {
return buf; return buf;
} }
int EquateList::getAddress(char *label) { int EquateList::getAddress(const char *label) {
for(int i=0; ourVcsEquates[i].label != NULL; i++) for(int i=0; ourVcsEquates[i].label != NULL; i++)
if( strcmp(ourVcsEquates[i].label, label) == 0 ) if( strcasecmp(ourVcsEquates[i].label, label) == 0 )
return ourVcsEquates[i].address; return ourVcsEquates[i].address;
return -1; return -1;

View File

@ -7,7 +7,7 @@ class EquateList {
EquateList(); EquateList();
char *getLabel(int addr); char *getLabel(int addr);
char *EquateList::getFormatted(int addr, int places); char *EquateList::getFormatted(int addr, int places);
int getAddress(char *label); int getAddress(const char *label);
}; };
#endif #endif