mirror of https://github.com/stella-emu/stella.git
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:
parent
5e911f1453
commit
cdb61cddb0
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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"
|
||||
|
@ -192,13 +192,18 @@ void Debugger::writeRAM(uInt16 addr, uInt8 value)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string Debugger::setRAM(int argCount, int *args) {
|
||||
char buf[10];
|
||||
|
||||
int address = args[0];
|
||||
for(int i=1; i<argCount; i++)
|
||||
mySystem->poke(address++, args[i]);
|
||||
|
||||
string ret = "changed ";
|
||||
ret += args[0];
|
||||
ret += " locations";
|
||||
sprintf(buf, "%d", argCount-1);
|
||||
ret += buf;
|
||||
ret += " location";
|
||||
if(argCount > 2)
|
||||
ret += "s";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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 "Debugger.hxx"
|
||||
#include "DebuggerParser.hxx"
|
||||
#include "EquateList.hxx"
|
||||
|
||||
// Constants for argument processing
|
||||
enum {
|
||||
|
@ -32,10 +33,12 @@ enum {
|
|||
DebuggerParser::DebuggerParser(Debugger* d)
|
||||
: debugger(d)
|
||||
{
|
||||
equateList = new EquateList();
|
||||
done = false;
|
||||
}
|
||||
|
||||
DebuggerParser::~DebuggerParser() {
|
||||
delete equateList;
|
||||
}
|
||||
|
||||
string DebuggerParser::currentAddress() {
|
||||
|
@ -53,13 +56,35 @@ int DebuggerParser::conv_hex_digit(char d) {
|
|||
return d - 'a' + 10;
|
||||
else if(d >= 'A' && d <= 'F')
|
||||
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 deref = 0;
|
||||
int curArg = 0;
|
||||
string curArg = "";
|
||||
argCount = 0;
|
||||
verb = "";
|
||||
const char *c = command.c_str();
|
||||
|
@ -85,8 +110,9 @@ void DebuggerParser::getArgs(const string& command) {
|
|||
break;
|
||||
|
||||
case kIN_ARG_START:
|
||||
curArg = 0;
|
||||
curArg = "";
|
||||
state = kIN_ARG_CONT;
|
||||
// FIXME: actually use this.
|
||||
if(*c == '*') {
|
||||
deref = 1;
|
||||
c++;
|
||||
|
@ -95,7 +121,7 @@ void DebuggerParser::getArgs(const string& command) {
|
|||
} // FALL THROUGH!
|
||||
|
||||
case kIN_ARG_CONT:
|
||||
if(isxdigit(*c)) {
|
||||
/*if(isxdigit(*c)) {
|
||||
int dig = conv_hex_digit(*c);
|
||||
curArg = (curArg << 4) + dig;
|
||||
*c++;
|
||||
|
@ -103,23 +129,37 @@ void DebuggerParser::getArgs(const string& command) {
|
|||
args[argCount++] = curArg;
|
||||
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) {
|
||||
cerr << "reached max 10 args" << endl;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// pick up last arg, if any:
|
||||
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++)
|
||||
// cerr << "args[" << i << "] == " << args[i] << endl;
|
||||
|
||||
// cerr << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
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 result;
|
||||
|
||||
getArgs(command);
|
||||
if(!getArgs(command))
|
||||
return "invalid label or address";
|
||||
|
||||
// "verb" is the command, stripped of any arguments.
|
||||
// In the if/else below, put shorter command names first.
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// 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
|
||||
|
@ -22,6 +22,7 @@
|
|||
class Debugger;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "EquateList.hxx"
|
||||
|
||||
class DebuggerParser
|
||||
{
|
||||
|
@ -32,13 +33,15 @@ class DebuggerParser
|
|||
string currentAddress();
|
||||
void setDone();
|
||||
string run(const string& command);
|
||||
void getArgs(const string& command);
|
||||
bool getArgs(const string& command);
|
||||
|
||||
private:
|
||||
int DebuggerParser::conv_hex_digit(char d);
|
||||
bool DebuggerParser::subStringMatch(const string& needle, const string& haystack);
|
||||
int decipher_arg(string &arg);
|
||||
|
||||
Debugger* debugger;
|
||||
EquateList *equateList;
|
||||
|
||||
bool done;
|
||||
|
||||
|
|
|
@ -102,9 +102,9 @@ char *EquateList::getFormatted(int addr, int places) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
int EquateList::getAddress(char *label) {
|
||||
int EquateList::getAddress(const char *label) {
|
||||
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 -1;
|
||||
|
|
|
@ -7,7 +7,7 @@ class EquateList {
|
|||
EquateList();
|
||||
char *getLabel(int addr);
|
||||
char *EquateList::getFormatted(int addr, int places);
|
||||
int getAddress(char *label);
|
||||
int getAddress(const char *label);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue