mirror of https://github.com/stella-emu/stella.git
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:
parent
9bce69cd2b
commit
5702496cdc
|
@ -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 += ": ";
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 += ")";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("");
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue