#include <string>
#include <sstream>
#include <iomanip>
#include "cmd_gpsim.h"
#include "sim_context.h"
#include "symbol.h"
#include "cmd_manager.h"
const char * s_psEnglishMessages[] = {
"", // Place holder so we don't have a zero
"break reading register %s\n", // IDS_BREAK_READING_REG
"break reading register %s with value %u\n", // IDS_BREAK_READING_REG_VALUE
"break reading register %s %s %u\n", // IDS_BREAK_READING_REG_OP_VALUE
"break writing register %s\n", // IDS_BREAK_WRITING_REG
"break writing register %s with value %u\n", // IDS_BREAK_WRITING_REG_VALUE
"break writing register %s %s %u\n", // IDS_BREAK_WRITING_REG_OP_VALUE
"execution break at address %s\n", // IDS_BREAK_ON_EXEC_ADDRESS
"unrecognized processor in the program file\n", // IDS_PROGRAM_FILE_PROCESSOR_NOT_KNOWN
"file name '%s' is too long\n", // IDS_FILE_NAME_TOO_LONG
"file %s not found\n", // IDS_FILE_NOT_FOUND
"file %s is not formatted properly\n", // IDS_FILE_BAD_FORMAT
"no processor has been specified\n", // IDS_NO_PROCESSOR_SPECIFIED
"processor %s initialization failed\n", // IDS_PROCESSOR_INIT_FAILED
"the program file type does not contain processor\n" // first part of IDS_FILE_NEED_PROCESSOR_SPECIFIED
"you need to specify processor with the processor command\n", // IDS_FILE_NEED_PROCESSOR_SPECIFIED
"an appropriate list file for %s was not found\n", // IDS_LIST_FILE_NOT_FOUND
"Hit breakpoint %d\n", // IDS_HIT_BREAK
NULL, // IDS_
};
class CGpsimUserInterface : public IUserInterface {
public:
CGpsimUserInterface(const char *paStrings[]);
virtual ~CGpsimUserInterface() {}
void SetStreams(FILE *in, FILE *out);
virtual ISimConsole &GetConsole();
virtual void SetConsole(ISimConsole *pConsole);
virtual void DisplayMessage(unsigned int uStringID, ...);
virtual void DisplayMessage(FILE * pOut, unsigned int uStringID, ...);
virtual void DisplayMessage(const char *fmt, ...);
virtual void DisplayMessage(FILE * pOut, const char *fmt, ...);
virtual const char * FormatProgramAddress(unsigned int uAddress,
unsigned int uMask);
virtual const char * FormatProgramAddress(unsigned int uAddress,
unsigned int uMask, int iRadix);
virtual const char * FormatRegisterAddress(Register *);
virtual const char * FormatRegisterAddress(unsigned int uAddress,
unsigned int uMask);
virtual const char * FormatLabeledValue(const char * pLabel,
unsigned int uValue);
virtual const char * FormatLabeledValue(const char * pLabel,
unsigned int uValue, unsigned int uMask, int iRadix,
const char *pHexPrefix);
virtual const char * FormatValue(unsigned int uValue);
virtual const char * FormatValue(gint64 uValue);
virtual const char * FormatValue(gint64 uValue, guint64 uMask);
virtual const char * FormatValue(gint64 uValue, guint64 uMask,
int iRadix);
virtual const char * FormatValue(gint64 uValue,
guint64 uMask, int iRadix, const char * pHexPrefix);
virtual char * FormatValue(char *str, int len,
int iRegisterSize, RegisterValue value);
// virtual char * FormatValueAsBinary(char *str, int len,
// int iRegisterSize, RegisterValue value);
virtual void SetProgramAddressRadix(int iRadix);
virtual void SetRegisterAddressRadix(int iRadix);
virtual void SetValueRadix(int iRadix);
virtual void SetProgramAddressMask(unsigned int uMask);
virtual void SetRegisterAddressMask(unsigned int uMask);
virtual void SetValueMask(unsigned int uMask);
virtual void SetExitOnBreak(FNNOTIFYEXITONBREAK);
virtual void NotifyExitOnBreak(int iExitCode);
static Integer s_iValueRadix;
static String s_sValueHexPrefix;
static Integer s_iProgAddrRadix;
static String s_sProgAddrHexPrefix;
static Integer s_iRAMAddrRadix;
static String s_sRAMAddrHexPrefix;
static Integer s_iValueMask;
static Integer s_iProgAddrMask;
static Integer s_iRAMAddrMask;
protected:
string m_sLabeledAddr;
string m_sFormatValueGint64;
const char ** m_paStrings;
// CGpsimConsole m_Console;
};
Integer CGpsimUserInterface::s_iValueRadix( "UIValueRadix", IUserInterface::eHex);
String CGpsimUserInterface::s_sValueHexPrefix( "UIValueHexPrefix", "$");
Integer CGpsimUserInterface::s_iProgAddrRadix( "UIProgamAddressRadix", IUserInterface::eHex);
String CGpsimUserInterface::s_sProgAddrHexPrefix("UIProgamAddressHexPrefix", "$");
Integer CGpsimUserInterface::s_iRAMAddrRadix( "UIRAMAddressRadix", IUserInterface::eHex);
String CGpsimUserInterface::s_sRAMAddrHexPrefix( "UIRAMAddressHexPrefix", "$");
Integer CGpsimUserInterface::s_iValueMask( "UIValueMask", 0xff);
Integer CGpsimUserInterface::s_iProgAddrMask( "UIProgamAddressMask", 0xff);
Integer CGpsimUserInterface::s_iRAMAddrMask( "UIRAMAddressMask", 0xff);
class NullConsole : public ISimConsole {
public:
virtual void Printf(const char *fmt, ...) {}
virtual void VPrintf(const char *fmt, va_list argptr) {}
virtual void Puts(const char*) {}
virtual void Putc(const char) {}
virtual char* Gets(char *, int) { return "";}
};
NullConsole g_NullConsole;
static ISimConsole *g_pConsole = &g_NullConsole;
class NullUserInterface : public IUserInterface {
// NullConsole m_Console;
public:
virtual ISimConsole &GetConsole() { return *g_pConsole; }
virtual void SetConsole(ISimConsole *pConsole) { g_pConsole = pConsole; }
virtual void DisplayMessage(unsigned int uStringID, ...) {}
virtual void DisplayMessage(FILE * pOut, unsigned int uStringID, ...) {}
virtual void DisplayMessage(const char *fmt, ...) {}
virtual void DisplayMessage(FILE * pOut, const char *fmt, ...) {}
virtual const char * FormatProgramAddress(unsigned int uAddress,
unsigned int uMask) {return "";}
virtual const char * FormatProgramAddress(unsigned int uAddress,
unsigned int uMask, int iRadix) {return "";}
virtual const char * FormatRegisterAddress(Register *)
{ return ""; }
virtual const char * FormatRegisterAddress(unsigned int uAddress,
unsigned int uMask) {return "";}
virtual const char * FormatLabeledValue(const char * pLabel,
unsigned int uValue) {return "";}
virtual const char * FormatValue(unsigned int uValue) {return "";}
virtual const char * FormatValue(gint64 uValue) {return "";}
virtual const char * FormatValue(gint64 uValue, guint64 uMask) {return "";}
virtual const char * FormatValue(gint64 uValue, guint64 uMask,
int iRadix) {return "";}
virtual char * FormatValue(char *str, int len,
int iRegisterSize, RegisterValue value) {return "";}
virtual void SetProgramAddressRadix(int iRadix) {}
virtual void SetRegisterAddressRadix(int iRadix) {}
virtual void SetValueRadix(int iRadix) {}
virtual void SetProgramAddressMask(unsigned int uMask) {}
virtual void SetRegisterAddressMask(unsigned int uMask) {}
virtual void SetValueMask(unsigned int uMask) {}
virtual void SetExitOnBreak(FNNOTIFYEXITONBREAK) {}
virtual void NotifyExitOnBreak(int iExitCode) {}
};
CGpsimUserInterface g_DefaultUI(s_psEnglishMessages);
static IUserInterface *g_GpsimUI = &g_DefaultUI;
LIBGPSIM_EXPORT IUserInterface & GetUserInterface(void) {
return *g_GpsimUI;
}
LIBGPSIM_EXPORT void SetUserInterface(IUserInterface * pGpsimUI) {
if(pGpsimUI) {
g_GpsimUI = pGpsimUI;
}
else {
g_GpsimUI = &g_DefaultUI;
}
}
static streambuf *s_pSavedCout = 0;
LIBGPSIM_EXPORT void SetUserInterface(std::streambuf * pOutStreamBuf) {
if(pOutStreamBuf == NULL && s_pSavedCout != 0) {
cout.rdbuf(s_pSavedCout);
s_pSavedCout = 0;
}
else {
s_pSavedCout = cout.rdbuf(pOutStreamBuf);;
}
}
///
/// CGpsimUserInterface
///
CGpsimUserInterface::CGpsimUserInterface(const char *paStrings[]) {
m_paStrings = paStrings;
m_pfnNotifyOnExit = NULL;
}
void CGpsimUserInterface::SetStreams(FILE *in, FILE *out) {
// m_Console.SetOut(out);
// m_Console.SetIn(in);
}
ISimConsole &CGpsimUserInterface::GetConsole(void) {
return *g_pConsole;
}
void CGpsimUserInterface::SetConsole(ISimConsole *pConsole) {
g_pConsole = pConsole;
}
void CGpsimUserInterface::DisplayMessage(unsigned int uStringID, ...) {
va_list ap;
va_start(ap,uStringID);
g_pConsole->VPrintf(m_paStrings[uStringID], ap);
va_end(ap);
}
void CGpsimUserInterface::DisplayMessage(FILE * pOut, unsigned int uStringID, ...) {
va_list ap;
va_start(ap,uStringID);
if (pOut == NULL || pOut == stdout) {
g_pConsole->VPrintf(m_paStrings[uStringID], ap);
}
else {
vfprintf(pOut, m_paStrings[uStringID], ap);
}
va_end(ap);
}
void CGpsimUserInterface::DisplayMessage(const char *fmt, ...) {
va_list ap;
va_start(ap,fmt);
g_pConsole->VPrintf(fmt, ap);
va_end(ap);
}
void CGpsimUserInterface::DisplayMessage(FILE * pOut, const char *fmt, ...) {
va_list ap;
va_start(ap,fmt);
if (pOut == NULL || pOut == stdout) {
g_pConsole->VPrintf(fmt, ap);
}
else {
vfprintf(pOut, fmt, ap);
}
va_end(ap);
}
void CGpsimUserInterface::SetProgramAddressRadix(int iRadix) {
s_iProgAddrRadix = iRadix;
}
void CGpsimUserInterface::SetRegisterAddressRadix(int iRadix) {
s_iRAMAddrRadix = iRadix;
}
void CGpsimUserInterface::SetValueRadix(int iRadix) {
s_iValueRadix = iRadix;
}
void CGpsimUserInterface::SetProgramAddressMask(unsigned int uMask) {
s_iProgAddrMask = uMask;
}
void CGpsimUserInterface::SetRegisterAddressMask(unsigned int uMask) {
s_iRAMAddrMask = uMask;
}
void CGpsimUserInterface::SetValueMask(unsigned int uMask) {
s_iValueMask = uMask;
}
void CGpsimUserInterface::SetExitOnBreak(FNNOTIFYEXITONBREAK pFunc) {
m_pfnNotifyOnExit = pFunc;
}
void CGpsimUserInterface::NotifyExitOnBreak(int iExitCode) {
if(m_pfnNotifyOnExit != NULL) {
m_pfnNotifyOnExit(iExitCode);
}
}
const char * CGpsimUserInterface::FormatProgramAddress(unsigned int uAddress,
unsigned int uMask) {
const char * pLabel = get_symbol_table().findProgramAddressLabel(uAddress);
return FormatLabeledValue(pLabel, uAddress, uMask,
s_iProgAddrRadix, s_sProgAddrHexPrefix);
}
const char * CGpsimUserInterface::FormatProgramAddress(unsigned int uAddress,
unsigned int uMask, int iRadix) {
return FormatValue((gint64)uAddress, uMask, iRadix, s_sProgAddrHexPrefix);
}
const char * CGpsimUserInterface::FormatRegisterAddress(Register *pReg)
{
if (!pReg)
return "";
return FormatLabeledValue(pReg->name().c_str(),
pReg->address,
s_iRAMAddrMask, s_iRAMAddrRadix, s_sRAMAddrHexPrefix);
}
const char * CGpsimUserInterface::FormatRegisterAddress(unsigned int uAddress,
unsigned int uMask) {
register_symbol * pRegSym = get_symbol_table().findRegisterSymbol(uAddress, uMask);
const char * pLabel = pRegSym == NULL ? "" : pRegSym->name().c_str();
return FormatLabeledValue(pLabel, uAddress, s_iRAMAddrMask, s_iRAMAddrRadix, s_sRAMAddrHexPrefix);
}
const char * CGpsimUserInterface::FormatLabeledValue(const char * pLabel,
unsigned int uValue) {
return FormatLabeledValue(pLabel, uValue, s_iValueMask, s_iValueRadix, s_sValueHexPrefix);
}
const char * CGpsimUserInterface::FormatLabeledValue(const char * pLabel,
unsigned int uValue,
unsigned int uMask,
int iRadix,
const char * pHexPrefix) {
m_sLabeledAddr.clear();
const char *pValue = FormatValue(uValue, uMask, iRadix, pHexPrefix);
if(pLabel != NULL && *pLabel != 0) {
m_sLabeledAddr.append(pLabel);
m_sLabeledAddr.append("(");
m_sLabeledAddr.append(pValue);
m_sLabeledAddr.append(")");
}
else {
m_sLabeledAddr = pValue;
}
return m_sLabeledAddr.c_str();
}
const char * CGpsimUserInterface::FormatValue(unsigned int uValue) {
return FormatLabeledValue(NULL, uValue, s_iValueMask, s_iValueRadix, s_sValueHexPrefix);
}
const char * CGpsimUserInterface::FormatValue(gint64 uValue) {
return FormatValue(uValue, s_iValueMask, s_iValueRadix);
}
const char * CGpsimUserInterface::FormatValue(gint64 uValue,
guint64 uMask) {
return FormatValue(uValue, uMask, s_iValueRadix, s_sValueHexPrefix);
}
const char * CGpsimUserInterface::FormatValue(gint64 uValue,
guint64 uMask, int iRadix) {
return FormatValue(uValue, uMask, iRadix, s_sValueHexPrefix);
}
const char * CGpsimUserInterface::FormatValue(gint64 uValue,
guint64 uMask, int iRadix, const char * pHexPrefix) {
ostringstream osValue;
string sPrefix;
int iBytes = 0;
guint64 l_uMask = uMask;
int iDigits;
while(l_uMask) {
iBytes++;
l_uMask >>= 8;
}
switch(iRadix) {
case eHex:
iDigits = iBytes * 2;
osValue << pHexPrefix;
osValue << hex << setw(iDigits) << setfill('0');
break;
case eDec:
osValue << dec;
break;
case eOct:
iDigits = iBytes * 3;
osValue << "0";
osValue << oct << setw(iDigits) << setfill('0');
break;
}
osValue << (uValue & uMask);
m_sFormatValueGint64 = osValue.str();
return m_sFormatValueGint64.c_str();
}
char * CGpsimUserInterface::FormatValue(char *str, int len,
int iRegisterSize,
RegisterValue value)
{
if(!str || !len)
return 0;
char hex2ascii[] = "0123456789ABCDEF";
int i;
int min = (len < iRegisterSize*2) ? len : iRegisterSize*2;
if(value.data == INVALID_VALUE)
value.init = 0xfffffff;
for(i=0; i < min; i++) {
if(value.init & 0x0f)
str[min-i-1] = '?';
else
str[min-i-1] = hex2ascii[value.data & 0x0f];
value >>= 4;
}
str[min] = 0;
return str;
}
syntax highlighted by Code2HTML, v. 0.9.1