Added support for any value types and done some improvements
This commit is contained in:
parent
91a1b9d766
commit
dceea084c2
|
@ -235,6 +235,7 @@ typedef enum
|
|||
{
|
||||
ValueTypeNumber,
|
||||
ValueTypeString,
|
||||
ValueTypeAny
|
||||
} ValueType;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -29,7 +29,6 @@ static duint callFunc(const T* argv, duint(*cbFunction)(Ts...), seq<S...>)
|
|||
template<typename... Ts>
|
||||
static bool RegisterEasy(const String & name, duint(*cbFunction)(Ts...))
|
||||
{
|
||||
auto aliases = StringUtils::Split(name, ',');
|
||||
auto tempFunc = [cbFunction](ExpressionValue * result, int argc, const ExpressionValue * argv, void* userdata) -> bool
|
||||
{
|
||||
result->type = ValueTypeNumber;
|
||||
|
@ -42,11 +41,7 @@ static bool RegisterEasy(const String & name, duint(*cbFunction)(Ts...))
|
|||
for(auto & arg : args)
|
||||
arg = ValueTypeNumber;
|
||||
|
||||
if(!ExpressionFunctions::Register(aliases[0], ValueTypeNumber, args, tempFunc))
|
||||
return false;
|
||||
for(size_t i = 1; i < aliases.size(); i++)
|
||||
ExpressionFunctions::RegisterAlias(aliases[0], aliases[i]);
|
||||
return true;
|
||||
return ExpressionFunctions::Register(name, ValueTypeNumber, args, tempFunc);
|
||||
}
|
||||
|
||||
void ExpressionFunctions::Init()
|
||||
|
@ -152,8 +147,9 @@ void ExpressionFunctions::Init()
|
|||
//Undocumented
|
||||
RegisterEasy("bpgoto", bpgoto);
|
||||
|
||||
ExpressionFunctions::Register("strcmp", ValueTypeNumber, { ValueTypeString, ValueTypeString }, Exprfunc::strcmp, nullptr);
|
||||
ExpressionFunctions::Register("streq", ValueTypeNumber, { ValueTypeString, ValueTypeString }, Exprfunc::strcmp, nullptr);
|
||||
ExpressionFunctions::Register("strstr", ValueTypeNumber, { ValueTypeString, ValueTypeString }, Exprfunc::strstr, nullptr);
|
||||
ExpressionFunctions::Register("strlen", ValueTypeNumber, { ValueTypeString }, Exprfunc::strlen, nullptr);
|
||||
ExpressionFunctions::Register("utf16", ValueTypeString, { ValueTypeNumber }, Exprfunc::utf16, nullptr);
|
||||
ExpressionFunctions::Register("utf8", ValueTypeString, { ValueTypeNumber }, Exprfunc::utf8, nullptr);
|
||||
ExpressionFunctions::Register("mod.fromname", ValueTypeNumber, { ValueTypeString }, Exprfunc::modbasefromname, nullptr);
|
||||
|
@ -161,18 +157,24 @@ void ExpressionFunctions::Init()
|
|||
|
||||
bool ExpressionFunctions::Register(const String & name, const ValueType & returnType, const std::vector<ValueType> & argTypes, const CBEXPRESSIONFUNCTION & cbFunction, void* userdata)
|
||||
{
|
||||
if(!isValidName(name))
|
||||
return false;
|
||||
EXCLUSIVE_ACQUIRE(LockExpressionFunctions);
|
||||
if(mFunctions.count(name))
|
||||
auto aliases = StringUtils::Split(name, ',');
|
||||
if(!isValidName(aliases[0]))
|
||||
return false;
|
||||
if(mFunctions.count(aliases[0]))
|
||||
return false;
|
||||
|
||||
Function f;
|
||||
f.name = name;
|
||||
f.name = aliases[0];
|
||||
f.argTypes = argTypes;
|
||||
f.returnType = returnType;
|
||||
f.cbFunction = cbFunction;
|
||||
f.userdata = userdata;
|
||||
mFunctions[name] = f;
|
||||
mFunctions[aliases[0]] = f;
|
||||
|
||||
for(size_t i = 1; i < aliases.size(); i++)
|
||||
ExpressionFunctions::RegisterAlias(aliases[0], aliases[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -214,7 +216,7 @@ bool ExpressionFunctions::Call(const String & name, ExpressionValue & result, st
|
|||
return false;
|
||||
for(size_t i = 0; i < argv.size(); i++)
|
||||
{
|
||||
if(argv[i].type != f.argTypes[i])
|
||||
if(argv[i].type != f.argTypes[i] && f.argTypes[i] != ValueTypeAny)
|
||||
return false;
|
||||
}
|
||||
return f.cbFunction(&result, argv.size(), argv.data(), f.userdata);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
class ExpressionFunctions
|
||||
{
|
||||
public:
|
||||
// TODO: also register the argument types
|
||||
using CBEXPRESSIONFUNCTION = std::function<bool(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata)>;
|
||||
|
||||
static void Init();
|
||||
|
|
|
@ -376,11 +376,7 @@ void ExpressionParser::addOperatorToken(const String & data, Token::Type type)
|
|||
|
||||
ExpressionParser::Token::Type ExpressionParser::resolveQuotedData() const
|
||||
{
|
||||
auto allQuoted = std::all_of(mCurTokenQuoted.begin(), mCurTokenQuoted.end(), [](bool b)
|
||||
{
|
||||
return b;
|
||||
});
|
||||
|
||||
auto allQuoted = std::find(mCurTokenQuoted.begin(), mCurTokenQuoted.end(), false) == mCurTokenQuoted.end();
|
||||
return allQuoted ? Token::Type::QuotedData : Token::Type::Data;
|
||||
}
|
||||
|
||||
|
@ -925,7 +921,7 @@ bool ExpressionParser::Calculate(duint & value, bool signedcalc, bool allowassig
|
|||
arg = { ValueTypeNumber, result };
|
||||
}
|
||||
|
||||
if(arg.type != argTypes[i])
|
||||
if(arg.type != argTypes[i] && argTypes[i] != ValueTypeAny)
|
||||
{
|
||||
if(!silent)
|
||||
{
|
||||
|
@ -957,6 +953,9 @@ bool ExpressionParser::Calculate(duint & value, bool signedcalc, bool allowassig
|
|||
if(!ExpressionFunctions::Call(name, result, argv))
|
||||
return false;
|
||||
|
||||
if(result.type == ValueTypeAny)
|
||||
return false;
|
||||
|
||||
for(size_t i = 0; i < argv.size(); i++)
|
||||
{
|
||||
stack.pop_back();
|
||||
|
|
|
@ -484,7 +484,7 @@ namespace Exprfunc
|
|||
std::vector<wchar_t> tempStr(MAX_STRING_SIZE + 1);
|
||||
if(!DbgMemRead(addr, tempStr.data(), sizeof(wchar_t) * (tempStr.size() - 1)))
|
||||
{
|
||||
// TODO: fail or just return ""?
|
||||
return false;
|
||||
}
|
||||
|
||||
auto utf8Str = StringUtils::Utf16ToUtf8(tempStr.data());
|
||||
|
@ -515,7 +515,7 @@ namespace Exprfunc
|
|||
std::vector<char> tempStr(MAX_STRING_SIZE + 1);
|
||||
if(!DbgMemRead(addr, tempStr.data(), tempStr.size() - 1))
|
||||
{
|
||||
//Todo
|
||||
return false;
|
||||
}
|
||||
|
||||
auto strlen = ::strlen(tempStr.data());
|
||||
|
@ -561,13 +561,23 @@ namespace Exprfunc
|
|||
result->type = ValueTypeNumber;
|
||||
result->number = 0;
|
||||
|
||||
//Todo: find a way to cancel this action if the user does not use the utf functions
|
||||
//I.e. argv[0].string.ptr will point to the address from the debugger 0xABAB as a string: strstr(0xABAB, "A")
|
||||
|
||||
if(argc > 2 || argc <= 1)
|
||||
return false;
|
||||
|
||||
result->number = ::strstr(argv[0].string.ptr, argv[1].string.ptr) != nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool strlen(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata)
|
||||
{
|
||||
assert(argv[0].type == ValueTypeString);
|
||||
result->type = ValueTypeNumber;
|
||||
result->number = 0;
|
||||
|
||||
if(argc != 1)
|
||||
return false;
|
||||
|
||||
result->number = ::strlen(argv[0].string.ptr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace Exprfunc
|
|||
|
||||
bool strcmp(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool strstr(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool strlen(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool utf16(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool utf8(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool modbasefromname(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
|
|
Loading…
Reference in New Issue