1
0
Fork 0

DBG: nicely cut away the hacky command processing crap

This commit is contained in:
mrexodia 2016-07-07 06:45:37 +02:00
parent 5788ada378
commit 608bc275cd
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
7 changed files with 29 additions and 131 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);