1
0
Fork 0

Added support for any value types and done some improvements

This commit is contained in:
xenocidewiki 2021-03-24 21:07:27 +00:00
parent 91a1b9d766
commit dceea084c2
6 changed files with 37 additions and 25 deletions

View File

@ -235,6 +235,7 @@ typedef enum
{
ValueTypeNumber,
ValueTypeString,
ValueTypeAny
} ValueType;
typedef struct

View File

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

View File

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

View File

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

View File

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

View File

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