DBG: nicely cut away the hacky command processing crap
This commit is contained in:
parent
5788ada378
commit
608bc275cd
|
@ -8,6 +8,8 @@
|
|||
#include "value.h"
|
||||
#include "console.h"
|
||||
#include "commandparser.h"
|
||||
#include "expressionparser.h"
|
||||
#include "variable.h"
|
||||
|
||||
COMMAND* cmd_list = 0;
|
||||
|
||||
|
@ -253,124 +255,6 @@ CMDRESULT cmdloop(CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvide
|
|||
return STATUS_EXIT;
|
||||
}
|
||||
|
||||
/*
|
||||
- custom command formatting rules
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Query if a string is a valid expression.
|
||||
\param expression The expression to check.
|
||||
\return true if the string is a valid expression.
|
||||
*/
|
||||
static bool isvalidexpression(const char* expression)
|
||||
{
|
||||
duint value;
|
||||
return valfromstring(expression, &value);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Check if a character is a mathematical operator. Used to determine stuff like "a *= b"
|
||||
\param ch The character to check.
|
||||
\return true if the character is an operator, false otherwise.
|
||||
*/
|
||||
static bool mathisoperator(const char ch)
|
||||
{
|
||||
switch(ch)
|
||||
{
|
||||
case '*':
|
||||
case '`':
|
||||
case '/':
|
||||
case '%':
|
||||
case '+':
|
||||
case '-':
|
||||
case '<':
|
||||
case '>':
|
||||
case '&':
|
||||
case '^':
|
||||
case '|':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Special formats a given command. Used as a little hack to support stuff like 'x++' and 'x=y'
|
||||
\param [in,out] string String to format.
|
||||
*/
|
||||
static void specialformat(char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
char* found = strstr(string, "=");
|
||||
char str[deflen] = "";
|
||||
char backup[deflen] = "";
|
||||
strcpy_s(backup, string); //create a backup of the string
|
||||
if(found && found != string) //contains =
|
||||
{
|
||||
auto a = found - 1;
|
||||
*found = '\0';
|
||||
found++;
|
||||
|
||||
if(mathisoperator(*a)) //x*=3 -> x=x*3
|
||||
{
|
||||
char op = *a;
|
||||
*a = 0;
|
||||
if(isvalidexpression(found))
|
||||
{
|
||||
len = int(strlen(string));
|
||||
if(len > 1 && string[len - 1] == '<' || string[len - 1] == '>') //TODO: never look at this again, ever (used for x<<=1 and x>>=1)
|
||||
{
|
||||
string[len - 1] = '\0';
|
||||
sprintf_s(str, "mov %s,%s%c%c%s", string, string, op, op, found);
|
||||
}
|
||||
else
|
||||
sprintf_s(str, "mov %s,%s%c%s", string, string, op, found);
|
||||
}
|
||||
else
|
||||
strcpy_s(str, backup);
|
||||
}
|
||||
else //x=y
|
||||
{
|
||||
if(isvalidexpression(found))
|
||||
sprintf_s(str, "mov %s,%s", string, found);
|
||||
else
|
||||
strcpy_s(str, backup);
|
||||
}
|
||||
strcpy_s(string, deflen, str);
|
||||
}
|
||||
else if((string[len - 1] == '+' && string[len - 2] == '+') || (string[len - 1] == '-' && string[len - 2] == '-')) //eax++/eax--
|
||||
{
|
||||
string[len - 2] = 0;
|
||||
char op = string[len - 1];
|
||||
if(isvalidexpression(string))
|
||||
sprintf_s(str, "mov %s,%s%c1", string, string, op);
|
||||
else
|
||||
strcpy_s(str, backup);
|
||||
strcpy_s(string, deflen, str);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- 'default' command finder, with some custom rules
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Default command finder. It uses specialformat() and mathformat() to make sure the command is optimally checked.
|
||||
\param [in] cmd_list Command list.
|
||||
\param [in] command Command name.
|
||||
\return null if it fails, else a COMMAND*.
|
||||
*/
|
||||
COMMAND* cmdfindmain(char* command)
|
||||
{
|
||||
COMMAND* cmd = cmdfind(command, 0);
|
||||
if(!cmd)
|
||||
{
|
||||
specialformat(command);
|
||||
cmd = cmdget(command);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Directly execute a command.
|
||||
\param [in,out] cmd_list Command list.
|
||||
|
@ -393,9 +277,17 @@ CMDRESULT cmddirectexec(const char* cmd, ...)
|
|||
va_end(ap);
|
||||
|
||||
strcpy_s(command, StringUtils::Trim(command).c_str());
|
||||
COMMAND* found = cmdfindmain(command);
|
||||
COMMAND* found = cmdfind(command, 0);
|
||||
if(!found || !found->cbCommand)
|
||||
return STATUS_ERROR;
|
||||
{
|
||||
ExpressionParser parser(command);
|
||||
duint result;
|
||||
if(!parser.Calculate(result, valuesignedcalc(), true))
|
||||
return STATUS_ERROR;
|
||||
varset("$result", result, false);
|
||||
varset("$ans", result, true);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(found->debugonly && !DbgIsDebugging())
|
||||
return STATUS_ERROR;
|
||||
Command cmdParsed(command);
|
||||
|
|
|
@ -36,7 +36,6 @@ COMMAND* cmdget(const char* cmd);
|
|||
CBCOMMAND cmdset(const char* name, CBCOMMAND cbCommand, bool debugonly);
|
||||
bool cmddel(const char* name);
|
||||
CMDRESULT cmdloop(CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal);
|
||||
COMMAND* cmdfindmain(char* command);
|
||||
CMDRESULT cmddirectexec(const char* cmd, ...);
|
||||
|
||||
#endif // _COMMAND_H
|
||||
|
|
|
@ -51,8 +51,9 @@ CMDRESULT cbBadCmd(int argc, char* argv[])
|
|||
int valsize = 0;
|
||||
bool isvar = false;
|
||||
bool hexonly = false;
|
||||
if(valfromstring(*argv, &value, false, false, &valsize, &isvar, &hexonly)) //dump variable/value/register/etc
|
||||
if(valfromstring(*argv, &value, false, false, &valsize, &isvar, &hexonly, true)) //dump variable/value/register/etc
|
||||
{
|
||||
varset("$ans", value, true);
|
||||
//dprintf("[DEBUG] valsize: %d\n", valsize);
|
||||
if(valsize)
|
||||
valsize *= 2;
|
||||
|
|
|
@ -320,9 +320,17 @@ static CMDRESULT scriptinternalcmdexec(const char* cmd)
|
|||
return STATUS_CONTINUE;
|
||||
char command[deflen] = "";
|
||||
strcpy_s(command, StringUtils::Trim(cmd).c_str());
|
||||
COMMAND* found = cmdfindmain(command);
|
||||
COMMAND* found = cmdfind(command, nullptr);
|
||||
if(!found) //invalid command
|
||||
return STATUS_ERROR;
|
||||
{
|
||||
ExpressionParser parser(command);
|
||||
duint result;
|
||||
if(!parser.Calculate(result, valuesignedcalc(), true))
|
||||
return STATUS_ERROR;
|
||||
varset("$result", result, false);
|
||||
varset("$ans", result, true);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(arraycontains(found->name, "var")) //var
|
||||
{
|
||||
cmddirectexec(command);
|
||||
|
|
|
@ -1712,7 +1712,7 @@ bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool ba
|
|||
\param [out] hexonly This function can output if the output value should only be printed as hexadecimal (for example addresses). Can be null.
|
||||
\return true if the expression was parsed successful, false otherwise.
|
||||
*/
|
||||
bool valfromstring(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly)
|
||||
bool valfromstring(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly, bool allowassign)
|
||||
{
|
||||
if(!value || !string)
|
||||
return false;
|
||||
|
@ -1723,7 +1723,7 @@ bool valfromstring(const char* string, duint* value, bool silent, bool baseonly,
|
|||
}
|
||||
ExpressionParser parser(string);
|
||||
duint result;
|
||||
if(!parser.Calculate(result, valuesignedcalc(), false, silent, baseonly, value_size, isvar, hexonly))
|
||||
if(!parser.Calculate(result, valuesignedcalc(), allowassign, silent, baseonly, value_size, isvar, hexonly))
|
||||
return false;
|
||||
*value = result;
|
||||
return true;
|
||||
|
|
|
@ -10,7 +10,7 @@ bool valapifromstring(const char* name, duint* value, int* value_size, bool prin
|
|||
bool convertNumber(const char* str, duint & result, int radix);
|
||||
bool convertLongLongNumber(const char* str, unsigned long long & result, int radix);
|
||||
bool valfromstring_noexpr(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = nullptr, bool* isvar = nullptr, bool* hexonly = nullptr);
|
||||
bool valfromstring(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = nullptr, bool* isvar = nullptr, bool* hexonly = nullptr);
|
||||
bool valfromstring(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = nullptr, bool* isvar = nullptr, bool* hexonly = nullptr, bool allowassign = false);
|
||||
bool valflagfromstring(duint eflags, const char* string);
|
||||
bool valtostring(const char* string, duint value, bool silent);
|
||||
bool valmxcsrflagfromstring(duint mxcsrflags, const char* string);
|
||||
|
|
|
@ -318,7 +318,7 @@ extern "C" DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd)
|
|||
|
||||
static DWORD WINAPI DbgCommandLoopThread(void* a)
|
||||
{
|
||||
cmdloop(cbBadCmd, cbCommandProvider, cmdfindmain, false);
|
||||
cmdloop(cbBadCmd, cbCommandProvider, nullptr, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -515,11 +515,9 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
info.execute = DbgCmdExec;
|
||||
info.completeCommand = nullptr;
|
||||
GuiRegisterScriptLanguage(&info);
|
||||
SCRIPTTYPEINFO infoDll;
|
||||
dputs("Registering Script DLL command handler...");
|
||||
strcpy_s(info.name, "Script DLL");
|
||||
infoDll.id = 0;
|
||||
info.execute = DbgScriptDllExec;
|
||||
info.completeCommand = nullptr;
|
||||
GuiRegisterScriptLanguage(&info);
|
||||
dputs("Starting command loop...");
|
||||
hCommandLoopThread = CreateThread(0, 0, DbgCommandLoopThread, 0, 0, 0);
|
||||
|
|
Loading…
Reference in New Issue