Fixed bug where doing a 'define label address' without the required

address resulted in a crash.  This was caused by non-existent
error checking in DebuggerParser for this case.  I've reworked the
method in question quite a bit, so I'm not sure if it's completely
bug free ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@806 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-10-02 01:15:53 +00:00
parent da85d8198a
commit ef55ef20e1
1 changed files with 98 additions and 65 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: DebuggerParser.cxx,v 1.82 2005-09-25 20:18:46 urchlay Exp $ // $Id: DebuggerParser.cxx,v 1.83 2005-10-02 01:15:53 stephena Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -997,85 +997,114 @@ string DebuggerParser::trapStatus(int addr) {
return result; return result;
} }
bool DebuggerParser::validateArgs(int cmd) { bool DebuggerParser::validateArgs(int cmd)
// cerr << "entering validateArgs(" << cmd << ")" << endl; {
bool required = commands[cmd].parmsRequired; // cerr << "entering validateArgs(" << cmd << ")" << endl;
parameters *p = commands[cmd].parms; bool required = commands[cmd].parmsRequired;
parameters *p = commands[cmd].parms;
if(argCount == 0) { if(argCount == 0)
if(required) { {
commandResult = red("missing required argument(s)"); if(required)
return false; // needed args. didn't get 'em. {
} else { commandResult = red("missing required argument(s)");
return true; // no args needed, no args got return false; // needed args. didn't get 'em.
} }
} else
return true; // no args needed, no args got
}
int curCount = 0; // Figure out how many arguments are required by the command
int count = 0, argRequiredCount = 0;
while(*p != kARG_END_ARGS && *p != kARG_MULTI_BYTE)
{
count++;
*p++;
}
do { // Evil hack: some commands intentionally take multiple arguments
if(argCount == curCount) { // In this case, the required number of arguments is unbounded
return true; argRequiredCount = (*p == kARG_END_ARGS) ? count : argCount;
}
int curArgInt = args[curCount]; p = commands[cmd].parms;
string curArgStr = argStrings[curCount]; int curCount = 0;
switch(*p) { do {
case kARG_WORD: if(curCount >= argCount)
if(curArgInt < 0 || curArgInt > 0xffff) { break;
commandResult = red("invalid word argument (must be 0-$ffff)");
return false;
}
break;
case kARG_BYTE: int curArgInt = args[curCount];
if(curArgInt < 0 || curArgInt > 0xff) { string& curArgStr = argStrings[curCount];
commandResult = red("invalid byte argument (must be 0-$ff)");
return false;
}
break;
case kARG_BOOL: switch(*p)
if(curArgInt != 0 && curArgInt != 1) { {
commandResult = red("invalid boolean argument (must be 0 or 1)"); case kARG_WORD:
return false; if(curArgInt < 0 || curArgInt > 0xffff)
} {
break; commandResult = red("invalid word argument (must be 0-$ffff)");
return false;
}
break;
case kARG_BASE_SPCL: case kARG_BYTE:
if(curArgInt != 2 && curArgInt != 10 && curArgInt != 16 if(curArgInt < 0 || curArgInt > 0xff)
&& curArgStr != "hex" && curArgStr != "dec" && curArgStr != "bin") {
{ commandResult = red("invalid byte argument (must be 0-$ff)");
commandResult = red("invalid base (must be #2, #10, #16, \"bin\", \"dec\", or \"hex\")"); return false;
return false; }
} break;
break;
case kARG_LABEL: case kARG_BOOL:
case kARG_FILE: if(curArgInt != 0 && curArgInt != 1)
break; // TODO: validate these (for now any string's allowed) {
commandResult = red("invalid boolean argument (must be 0 or 1)");
return false;
}
break;
case kARG_MULTI_BYTE: case kARG_BASE_SPCL:
case kARG_MULTI_WORD: if(curArgInt != 2 && curArgInt != 10 && curArgInt != 16
break; // FIXME: validate these (for now, any number's allowed) && curArgStr != "hex" && curArgStr != "dec" && curArgStr != "bin")
{
commandResult = red("invalid base (must be #2, #10, #16, \"bin\", \"dec\", or \"hex\")");
return false;
}
break;
default: case kARG_LABEL:
commandResult = red("too many arguments"); case kARG_FILE:
return false; break; // TODO: validate these (for now any string's allowed)
break;
}
curCount++; case kARG_MULTI_BYTE:
case kARG_MULTI_WORD:
break; // FIXME: validate these (for now, any number's allowed)
} while(*p++ != kARG_END_ARGS); case kARG_END_ARGS:
break;
}
curCount++;
*p++;
if(curCount < argCount) { } while(*p != kARG_END_ARGS && curCount < argRequiredCount);
commandResult = red("too many arguments");
return false;
}
return true; /*
cerr << "curCount = " << curCount << endl
<< "argRequiredCount = " << argRequiredCount << endl
<< "*p = " << *p << endl << endl;
*/
if(curCount < argRequiredCount)
{
commandResult = red("missing required argument(s)");
return false;
}
else if(argCount > curCount)
{
commandResult = red("too many arguments");
return false;
}
return true;
} }
// main entry point: PromptWidget calls this method. // main entry point: PromptWidget calls this method.
@ -1417,6 +1446,7 @@ void DebuggerParser::executeD() {
void DebuggerParser::executeDefine() { void DebuggerParser::executeDefine() {
// TODO: check if label already defined? // TODO: check if label already defined?
debugger->addLabel(argStrings[0], args[1]); debugger->addLabel(argStrings[0], args[1]);
debugger->myRom->invalidate();
commandResult = "label " + argStrings[0] + " defined as " + debugger->valueToString(args[1]); commandResult = "label " + argStrings[0] + " defined as " + debugger->valueToString(args[1]);
} }
@ -1728,7 +1758,10 @@ void DebuggerParser::executeTrapwrite() {
// "undef" // "undef"
void DebuggerParser::executeUndef() { void DebuggerParser::executeUndef() {
if(debugger->equateList->undefine(argStrings[0])) if(debugger->equateList->undefine(argStrings[0]))
{
debugger->myRom->invalidate();
commandResult = argStrings[0] + " now undefined"; commandResult = argStrings[0] + " now undefined";
}
else else
commandResult = red("no such label"); commandResult = red("no such label");
} }