supporting string function in logical expression: name.left(cnt)/name.right(cnt)/name.mid(start, cnt)
This commit is contained in:
parent
71ce3ed2e0
commit
b2a999c605
|
@ -140,6 +140,32 @@ static std::string get_real_value(gb_json* jsn, const char* type)
|
|||
return "";
|
||||
}
|
||||
|
||||
static bool pick_bracket(const char* exp, const char** end)
|
||||
{
|
||||
bool ret = false;
|
||||
int balance = 1;
|
||||
|
||||
exp = strstr(exp, "[");
|
||||
if (exp++)
|
||||
{
|
||||
while (*exp && balance)
|
||||
{
|
||||
if (*exp == '[')
|
||||
balance++;
|
||||
else if (*exp == ']')
|
||||
balance--;
|
||||
exp++;
|
||||
}
|
||||
if (balance == 0)
|
||||
{
|
||||
*end = exp - 1;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
std::string name;
|
||||
|
@ -550,6 +576,52 @@ bool device_option::get_between(const char* type, bool(**f)(gb_json*, void*, voi
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool device_option::is_string_function(const char* expr, std::string& name, int& start, int& cnt)
|
||||
{
|
||||
bool ret = false;
|
||||
std::string exp(expr);
|
||||
size_t pos = exp.find(".");
|
||||
|
||||
cnt = 0;
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
name = exp.substr(0, pos++);
|
||||
exp.erase(0, pos);
|
||||
if (exp.find("left[") == 0)
|
||||
{
|
||||
exp.erase(0, 5);
|
||||
start = 0;
|
||||
cnt = atoi(exp.c_str());
|
||||
pos = 0;
|
||||
}
|
||||
else if (exp.find("right[") == 0)
|
||||
{
|
||||
exp.erase(0, 6);
|
||||
start = -1 * atoi(exp.c_str());
|
||||
cnt = -1;
|
||||
pos = 0;
|
||||
}
|
||||
else if (exp.find("mid[") == 0)
|
||||
{
|
||||
exp.erase(0, 4);
|
||||
start = atoi(exp.c_str());
|
||||
pos = exp.find(",");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
exp.erase(0, pos + 1);
|
||||
cnt = atoi(exp.c_str());
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
if (pos == 0)
|
||||
{
|
||||
pos = exp.find("]");
|
||||
ret = pos != std::string::npos && (cnt > 0 || cnt == -1);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
std::string device_option::from_text_value(const char* type, const char* text_val)
|
||||
{
|
||||
std::string real_v("");
|
||||
|
@ -578,7 +650,7 @@ std::string device_option::from_text_value(const char* type, const char* text_va
|
|||
}
|
||||
bool device_option::parse_simple_logic_expression(gb_json* root, const char* expr, std::string* name, EXPRCALC& calc)
|
||||
{
|
||||
const char* opers[] = { ">", "<", "!", "=", "." }, * tag = nullptr;
|
||||
const char* opers[] = { ">", "<", "!", "=", "." }, * tag = nullptr, * dot = strstr(expr, ".");
|
||||
|
||||
for (auto& v : opers)
|
||||
{
|
||||
|
@ -590,6 +662,10 @@ bool device_option::parse_simple_logic_expression(gb_json* root, const char* exp
|
|||
if (!tag)
|
||||
return false;
|
||||
|
||||
if (dot && dot < tag) // is mode.!enable ?
|
||||
{
|
||||
tag = dot;
|
||||
}
|
||||
|
||||
std::string n(expr, tag - expr);
|
||||
bool ret = true;
|
||||
|
@ -686,6 +762,25 @@ bool device_option::parse_simple_logic_expression(gb_json* root, const char* exp
|
|||
}
|
||||
else
|
||||
{
|
||||
// substr function ...
|
||||
if (strstr(tag, "left[") || strstr(tag, "right[") || strstr(tag, "mid["))
|
||||
{
|
||||
const char* end = nullptr;
|
||||
bool ret = pick_bracket(tag, &end);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
std::string exp(calc.name + (end + 1)),
|
||||
name1(tag, end - tag + 1);
|
||||
name1.insert(0, calc.name + ".");
|
||||
ret = device_option::parse_simple_logic_expression(root, exp.c_str(), name, calc);
|
||||
if (ret)
|
||||
calc.name = std::move(name1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
tag = "";
|
||||
|
@ -752,11 +847,26 @@ bool device_option::calc_simple_logic_expression(const char* expr, void* param)
|
|||
if (obj->compare_.count(expr))
|
||||
{
|
||||
gb_json* child = nullptr;
|
||||
bool substr = false;
|
||||
int start = 0, cnt = 0;
|
||||
|
||||
if(obj->now_)
|
||||
obj->now_->get_value(obj->compare_[expr].name.c_str(), child);
|
||||
else
|
||||
obj->origin_->get_value(obj->compare_[expr].name.c_str(), child);
|
||||
if (!child)
|
||||
{
|
||||
// check string function ...
|
||||
std::string name("");
|
||||
substr = device_option::is_string_function(expr, name, start, cnt);
|
||||
if (substr)
|
||||
{
|
||||
if (obj->now_)
|
||||
obj->now_->get_value(name.c_str(), child);
|
||||
else
|
||||
obj->origin_->get_value(name.c_str(), child);
|
||||
}
|
||||
}
|
||||
if (child)
|
||||
{
|
||||
bool bv = false;
|
||||
|
@ -781,6 +891,15 @@ bool device_option::calc_simple_logic_expression(const char* expr, void* param)
|
|||
else if (strcmp(sv.c_str(), JSON_SANE_TYPE_STRING) == 0)
|
||||
{
|
||||
child->get_value("cur", sv);
|
||||
if (substr)
|
||||
{
|
||||
if (start < 0)
|
||||
start = sv.length() + start;
|
||||
if (start > 0 && start < sv.length())
|
||||
sv.erase(0, start);
|
||||
if (cnt > 0 && cnt < sv.length())
|
||||
sv.erase(cnt);
|
||||
}
|
||||
}
|
||||
val = &sv[0];
|
||||
ret = obj->compare_[expr].compare(child, val, &obj->compare_[expr].val1[0], &obj->compare_[expr].val2[0]) ^ obj->compare_[expr].not_op;
|
||||
|
|
|
@ -155,6 +155,18 @@ class device_option
|
|||
static bool get_great(const char* type, bool(**f)(gb_json*, void*, void*, void*));
|
||||
static bool get_between(const char* type, bool(**f)(gb_json*, void*, void*, void*));
|
||||
|
||||
// Function: parse string function - .left(cnt), .right(cnt), .mid(start, cnt)
|
||||
//
|
||||
// Parameter: expr - expression of string function, e.g. mode.left(2)
|
||||
//
|
||||
// name - to receive the final option name, e.g. mode
|
||||
//
|
||||
// start - to receive the starting position of the sub-string, negative is for right()
|
||||
//
|
||||
// cnt - to receive the length of the sub string, -1 is to end
|
||||
//
|
||||
// Return: true if was string function
|
||||
static bool is_string_function(const char* expr, std::string& name, int& start, int& cnt);
|
||||
static std::string from_text_value(const char* type, const char* text_val);
|
||||
static bool parse_simple_logic_expression(gb_json* root, const char* expr, std::string* name, EXPRCALC& calc);
|
||||
static void init_condition(const char* expr, void* param);
|
||||
|
|
Loading…
Reference in New Issue