Made EquateList use a couple of STL maps to store address => label and

label => address mappings. It should be faster than the linear search,
and it's a damn sight cleaner. Still TODO is to restore the case-insensitive
string matching from the original version.

Changed a few EquateList methods that used to return char*, so they now
return string or string&. Changed other classes that call them so they
work with the new return types.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@633 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-07-12 02:27:07 +00:00
parent 9bce69cd2b
commit 5702496cdc
8 changed files with 100 additions and 145 deletions

View File

@ -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.59 2005-07-10 02:15:55 stephena Exp $
// $Id: Debugger.cxx,v 1.60 2005-07-12 02:27:04 urchlay Exp $
//============================================================================
#include "bspf.hxx"
@ -607,12 +607,13 @@ int Debugger::cycles() {
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Debugger::disassemble(int start, int lines) {
const string& Debugger::disassemble(int start, int lines) {
char buf[255], bbuf[255];
string result;
static string result;
result = "";
do {
char *label = equateList->getFormatted(start, 4);
const char *label = equateList->getFormatted(start, 4);
result += label;
result += ": ";

View File

@ -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.hxx,v 1.47 2005-07-10 02:15:57 stephena Exp $
// $Id: Debugger.hxx,v 1.48 2005-07-12 02:27:05 urchlay Exp $
//============================================================================
#ifndef DEBUGGER_HXX
@ -52,7 +52,7 @@ enum {
for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony
@version $Id: Debugger.hxx,v 1.47 2005-07-10 02:15:57 stephena Exp $
@version $Id: Debugger.hxx,v 1.48 2005-07-12 02:27:05 urchlay Exp $
*/
class Debugger : public DialogContainer
{
@ -149,7 +149,7 @@ class Debugger : public DialogContainer
Disassemble from the starting address the specified number of lines
and place result in a string.
*/
string disassemble(int start, int lines);
const string& disassemble(int start, int lines);
int step();
int trace();

View File

@ -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.cxx,v 1.50 2005-07-11 18:56:26 urchlay Exp $
// $Id: DebuggerParser.cxx,v 1.51 2005-07-12 02:27:06 urchlay Exp $
//============================================================================
#include "bspf.hxx"
@ -451,7 +451,7 @@ int DebuggerParser::conv_hex_digit(char d) {
int DebuggerParser::decipher_arg(const string &str) {
bool derefByte=false, derefWord=false, lobyte=false, hibyte=false, bin=false, dec=false;
int result;
string arg = str;
string arg = str;
if(defaultBase == kBASE_2) {
bin=true; dec=false;
@ -506,7 +506,7 @@ int DebuggerParser::decipher_arg(const string &str) {
else if(arg == "pc" || arg == ".") result = state.PC;
else { // Not a special, must be a regular arg: check for label first
const char *a = arg.c_str();
result = debugger->equateList->getAddress(a);
result = debugger->equateList->getAddress(arg);
if(result < 0) { // if not label, must be a number
if(bin) { // treat as binary
@ -697,8 +697,8 @@ string DebuggerParser::eval() {
char buf[50];
string ret;
for(int i=0; i<argCount; i++) {
char *label = debugger->equates()->getLabel(args[i]);
if(label != NULL) {
string label = debugger->equates()->getLabel(args[i]);
if(label != "") {
ret += label;
ret += ": ";
}
@ -783,8 +783,8 @@ string DebuggerParser::trapStatus(int addr) {
else
result += " none ";
char *l = debugger->equateList->getLabel(addr);
if(l != NULL) {
string l = debugger->equateList->getLabel(addr);
if(l != "") {
result += " (";
result += l;
result += ")";

View File

@ -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: EquateList.cxx,v 1.16 2005-06-25 01:13:00 urchlay Exp $
// $Id: EquateList.cxx,v 1.17 2005-07-12 02:27:06 urchlay Exp $
//============================================================================
#include <string>
@ -99,44 +99,44 @@ static Equate hardCodedEquates[] = {
};
EquateList::EquateList() {
// cerr << sizeof(hardCodedEquates)/sizeof(struct Equate) << endl;
int size = sizeof(hardCodedEquates)/sizeof(struct Equate);
for(int i=0; i<size; i++)
ourVcsEquates.push_back(hardCodedEquates[i]);
for(int i=0; i<size; i++) {
string l = hardCodedEquates[i].label;
int a = hardCodedEquates[i].address;
myFwdMap.insert(make_pair(l, a));
myRevMap.insert(make_pair(a, l));
}
calcSize();
}
EquateList::~EquateList() {
ourVcsEquates.clear();
myFwdMap.clear();
myRevMap.clear();
}
int EquateList::calcSize() {
currentSize = ourVcsEquates.size();
currentSize = myFwdMap.size();
return currentSize;
}
// FIXME: use something smarter than a linear search in the future.
char *EquateList::getLabel(int addr) {
// cerr << "getLabel(" << addr << ")" << endl;
for(int i=0; i<currentSize; i++) {
// cerr << "Checking ourVcsEquates[" << i << "] (" << ourVcsEquates[i].label << ")" << endl;
if(ourVcsEquates[i].address == addr) {
// cerr << "Found label " << ourVcsEquates[i].label << endl;
return ourVcsEquates[i].label;
}
}
return NULL;
const string& EquateList::getLabel(int addr) {
static string nothing = "";
addrToLabel::const_iterator iter = myRevMap.find(addr);
if(iter == myRevMap.end())
return nothing;
else
return iter->second;
}
// returns either the label, or a formatted hex string
// if no label found.
char *EquateList::getFormatted(int addr, int places) {
const char *EquateList::getFormatted(int addr, int places) {
static char fmt[10], buf[255];
char *res = getLabel(addr);
if(res != NULL)
return res;
string res = getLabel(addr);
if(res != "")
return res.c_str();
sprintf(fmt, "$%%0%dx", places);
//cerr << addr << ", " << fmt << ", " << places << endl;
@ -144,33 +144,25 @@ char *EquateList::getFormatted(int addr, int places) {
return buf;
}
int EquateList::getAddress(const char *lbl) {
// cerr << "getAddress(" << lbl << ")" << endl;
// cerr << ourVcsEquates[0].label << endl;
// cerr << "shit" << endl;
for(int i=0; i<currentSize; i++) {
// cerr << "Looking at " << ourVcsEquates[i].label << endl;
if( STR_CASE_CMP(ourVcsEquates[i].label, lbl) == 0 )
if(ourVcsEquates[i].address >= 0)
return ourVcsEquates[i].address;
}
return -1;
int EquateList::getAddress(const string& label) {
labelToAddr::const_iterator iter = myFwdMap.find(label);
if(iter == myFwdMap.end())
return -1;
else
return iter->second;
}
bool EquateList::undefine(string& label) {
return undefine(label.c_str());
}
bool EquateList::undefine(const char *lbl) {
for(int i=0; i<currentSize; i++) {
if( STR_CASE_CMP(ourVcsEquates[i].label, lbl) == 0 ) {
ourVcsEquates[i].address = -1;
return true;
}
}
return false;
labelToAddr::iterator iter = myFwdMap.find(label);
if(iter == myFwdMap.end()) {
return false;
} else {
myRevMap.erase( myRevMap.find(iter->second) ); // FIXME: error check?
myFwdMap.erase(iter);
return true;
}
}
bool EquateList::saveFile(string file) {
@ -182,16 +174,10 @@ bool EquateList::saveFile(string file) {
out << "--- Symbol List (sorted by symbol)" << endl;
// we don't have these pre-loaded any more.
// int hardSize = sizeof(hardCodedEquates)/sizeof(struct Equate);
// for(int i=hardSize; i<currentSize; i++)
for(int i=0; i<currentSize; i++) {
int a = ourVcsEquates[i].address;
if(a >= 0) {
sprintf(buf, "%-24s %04x \n", ourVcsEquates[i].label, a);
out << buf;
}
labelToAddr::iterator iter;
for(iter = myFwdMap.begin(); iter != myFwdMap.end(); iter++) {
sprintf(buf, "%-24s %04x \n", iter->first.c_str(), iter->second);
out << buf;
}
out << "--- End of Symbol List." << endl;
@ -202,28 +188,14 @@ string EquateList::loadFile(string file) {
int lines = 0;
string curLabel;
int curVal;
// string::size_type p;
char buffer[256]; // FIXME: static buffers suck
// cerr << "loading file " << file << endl;
ifstream in(file.c_str());
if(!in.is_open())
return "Unable to read symbols from " + file;
// Make sure the hard-coded equates show up first
ourVcsEquates.clear();
/*
// Don't preload these: they cause more trouble than they're worth
// Besides which, any sane symfile will already have them all.
int hardSize = sizeof(hardCodedEquates)/sizeof(struct Equate);
for(int i=0; i<hardSize; i++) {
ourVcsEquates.push_back(hardCodedEquates[i]);
}
*/
myFwdMap.clear();
myRevMap.clear();
while( !in.eof() ) {
curVal = 0;
@ -239,8 +211,6 @@ string EquateList::loadFile(string file) {
addEquate(curLabel, curVal);
// cerr << "label: " << curLabel << ", address: " << curVal << endl;
// cerr << buffer;
lines++;
}
}
@ -248,22 +218,15 @@ string EquateList::loadFile(string file) {
calcSize();
// dumpAll();
return "loaded " + file + " OK";
}
void EquateList::addEquate(string label, int address) {
// FIXME - this is a memleak and *must* be fixed
// ideally, the Equate class should hold a string, not a char*
Equate e;
e.label = strdup(label.c_str());
e.address = address;
ourVcsEquates.push_back(e);
calcSize();
myFwdMap.insert(make_pair(label, address));
myRevMap.insert(make_pair(address, label));
}
int EquateList::parse4hex(char *c) {
//cerr << c << endl;
int ret = 0;
for(int i=0; i<4; i++) {
if(*c >= '0' && *c <= '9')
@ -302,49 +265,31 @@ string EquateList::extractLabel(char *c) {
return l;
}
string EquateList::dumpAll() {
string ret;
for(int i=0; i<currentSize; i++) {
if(ourVcsEquates[i].address != -1) {
ret += ourVcsEquates[i].label;
ret += ": ";
ret += Debugger::to_hex_16(ourVcsEquates[i].address);
if(i != currentSize - 1) ret += "\n";
}
}
return ret;
}
int EquateList::countCompletions(const char *in) {
int count = 0;
completions = compPrefix = "";
// cerr << "Attempting to complete \"" << in << "\"" << endl;
for(int i=0; i<currentSize; i++) {
if(ourVcsEquates[i].address != -1) {
const char *l = ourVcsEquates[i].label;
labelToAddr::iterator iter;
for(iter = myFwdMap.begin(); iter != myFwdMap.end(); iter++) {
const char *l = iter->first.c_str();
if(STR_N_CASE_CMP(l, in, strlen(in)) == 0) {
if(compPrefix == "")
compPrefix += l;
else {
int nonMatch = 0;
const char *c = compPrefix.c_str();
while(*c != '\0' && tolower(*c) == tolower(l[nonMatch])) {
c++;
nonMatch++;
}
compPrefix.erase(nonMatch, compPrefix.length());
// cerr << "compPrefix==" << compPrefix << endl;
if(STR_N_CASE_CMP(l, in, strlen(in)) == 0) {
if(compPrefix == "")
compPrefix += l;
else {
int nonMatch = 0;
const char *c = compPrefix.c_str();
while(*c != '\0' && tolower(*c) == tolower(l[nonMatch])) {
c++;
nonMatch++;
}
if(count++) completions += " ";
completions += l;
compPrefix.erase(nonMatch, compPrefix.length());
}
if(count++) completions += " ";
completions += l;
}
}
// cerr << "Found " << count << " label(s):" << endl << completions << endl;
return count;
}

View File

@ -13,31 +13,38 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EquateList.hxx,v 1.10 2005-06-25 01:13:00 urchlay Exp $
// $Id: EquateList.hxx,v 1.11 2005-07-12 02:27:06 urchlay Exp $
//============================================================================
#ifndef EQUATELIST_HXX
#define EQUATELIST_HXX
#include <map>
#include "bspf.hxx"
#include "Equate.hxx"
#include "Array.hxx"
using namespace std;
typedef map<int, string> addrToLabel;
typedef map<string, int> labelToAddr;
typedef GUI::Array<Equate> Equates;
class EquateList {
public:
EquateList();
~EquateList();
char *getLabel(int addr);
char *getFormatted(int addr, int places);
int getAddress(const char *label);
const string& getLabel(int addr);
const char *getFormatted(int addr, int places);
int getAddress(const string& label);
void addEquate(string label, int address);
bool saveFile(string file);
string loadFile(string file);
bool undefine(string& label);
bool undefine(const char *lbl);
string dumpAll();
//string dumpAll();
int countCompletions(const char *in);
const char *getCompletions();
const char *getCompletionPrefix();
@ -51,8 +58,10 @@ class EquateList {
string compPrefix;
private:
Equates ourVcsEquates;
//Equates ourVcsEquates;
int currentSize;
labelToAddr myFwdMap;
addrToLabel myRevMap;
};
#endif

View File

@ -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: CpuWidget.cxx,v 1.14 2005-07-08 14:36:18 stephena Exp $
// $Id: CpuWidget.cxx,v 1.15 2005-07-12 02:27:07 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -264,8 +264,8 @@ void CpuWidget::fillGrid()
const char* buf;
Debugger& dbg = instance()->debugger();
buf = dbg.equates()->getLabel(pc);
if(buf)
buf = dbg.equates()->getLabel(pc).c_str();
if(*buf)
myPCLabel->setEditString(buf);
else
myPCLabel->setEditString("");

View File

@ -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: RamWidget.cxx,v 1.18 2005-07-07 20:51:10 stephena Exp $
// $Id: RamWidget.cxx,v 1.19 2005-07-12 02:27:07 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -174,8 +174,8 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
addr = myRamGrid->getSelectedAddr();
value = myRamGrid->getSelectedValue();
buf = instance()->debugger().equates()->getLabel(addr+kRamStart);
if(buf) myLabel->setEditString(buf);
buf = instance()->debugger().equates()->getLabel(addr+kRamStart).c_str();
if(*buf) myLabel->setEditString(buf);
else myLabel->setEditString("");
myDecValue->setEditString(instance()->debugger().valueToString(value, kBASE_10));

View File

@ -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: TiaWidget.cxx,v 1.8 2005-07-10 02:16:01 stephena Exp $
// $Id: TiaWidget.cxx,v 1.9 2005-07-12 02:27:07 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -201,8 +201,8 @@ void TiaWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
addr = myRamGrid->getSelectedAddr();
value = myRamGrid->getSelectedValue();
buf = instance()->debugger().equates()->getLabel(addr);
if(buf) myLabel->setEditString(buf);
buf = instance()->debugger().equates()->getLabel(addr).c_str();
if(*buf) myLabel->setEditString(buf);
else myLabel->setEditString("");
myDecValue->setEditString(instance()->debugger().valueToString(value, kBASE_10));