diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2014-04-04 16:52:12 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2014-04-04 16:52:12 +0200 |
commit | 37144535a55f5e06b3a1f92f11758db6ba8e39c7 (patch) | |
tree | be5b228ac8a23a5206d72aab015a9a171411623f /src/core | |
parent | e143518e4becad620741f2ed53ca399ff21ad5e1 (diff) | |
download | weechat-37144535a55f5e06b3a1f92f11758db6ba8e39c7.zip |
core: fix evaluation of expression with regex when a comparison char is in the regex
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/wee-eval.c | 201 | ||||
-rw-r--r-- | src/core/wee-eval.h | 6 |
2 files changed, 131 insertions, 76 deletions
diff --git a/src/core/wee-eval.c b/src/core/wee-eval.c index 23af934de..378dccb35 100644 --- a/src/core/wee-eval.c +++ b/src/core/wee-eval.c @@ -41,9 +41,11 @@ #include "../plugins/plugin.h" -char *logical_ops[EVAL_NUM_LOGICAL_OPS] = { "||", "&&" }; -char *comparisons[EVAL_NUM_COMPARISONS] = { "==", "!=", "<=", "<", ">=", ">", - "=~", "!~" }; +char *logical_ops[EVAL_NUM_LOGICAL_OPS] = +{ "||", "&&" }; + +char *comparisons[EVAL_NUM_COMPARISONS] = +{ "=~", "!~", "==", "!=", "<=", "<", ">=", ">" }; struct t_hashtable *eval_hashtable_pointers = NULL; @@ -519,12 +521,16 @@ end: */ char * -eval_expression_condition (const char *expr, struct t_hashtable *pointers, +eval_expression_condition (const char *expr, + struct t_hashtable *pointers, struct t_hashtable *extra_vars, int keep_parentheses, - const char *prefix, const char *suffix) + int search_logical_op, + int search_comparison, + const char *prefix, + const char *suffix) { - int logic, comp, length, level, rc; + int logic, comp, length, level, regex, rc; const char *pos_end; char *expr2, *sub_expr, *pos, *pos2, *value, *tmp_value, *tmp_value2; @@ -583,9 +589,15 @@ eval_expression_condition (const char *expr, struct t_hashtable *pointers, sub_expr = string_strndup (pos + 1, pos2 - pos - 1); if (!sub_expr) goto end; - tmp_value = eval_expression_condition (sub_expr, pointers, + tmp_value = eval_expression_condition (sub_expr, + pointers, extra_vars, - 0, prefix, suffix); + /* keep parentheses */ + 0, + search_logical_op, + search_comparison, + prefix, + suffix); free (sub_expr); if (!pos[1]) { @@ -635,48 +647,64 @@ eval_expression_condition (const char *expr, struct t_hashtable *pointers, * - if needed, evaluate second sub-expression * - return result */ - for (logic = 0; logic < EVAL_NUM_LOGICAL_OPS; logic++) + if (search_logical_op) { - pos = strstr (expr2, logical_ops[logic]); - if (pos > expr2) + for (logic = 0; logic < EVAL_NUM_LOGICAL_OPS; logic++) { - pos_end = pos - 1; - while ((pos_end > expr2) && (pos_end[0] == ' ')) - { - pos_end--; - } - sub_expr = string_strndup (expr2, pos_end + 1 - expr2); - if (!sub_expr) - goto end; - tmp_value = eval_expression_condition (sub_expr, pointers, - extra_vars, - 0, prefix, suffix); - free (sub_expr); - rc = eval_is_true (tmp_value); - if (tmp_value) - free (tmp_value); - /* - * if rc == 0 with "&&" or rc == 1 with "||", no need to evaluate - * second sub-expression, just return the rc - */ - if ((!rc && (logic == EVAL_LOGICAL_OP_AND)) - || (rc && (logic == EVAL_LOGICAL_OP_OR))) + pos = strstr (expr2, logical_ops[logic]); + if (pos > expr2) { + pos_end = pos - 1; + while ((pos_end > expr2) && (pos_end[0] == ' ')) + { + pos_end--; + } + sub_expr = string_strndup (expr2, pos_end + 1 - expr2); + if (!sub_expr) + goto end; + tmp_value = eval_expression_condition (sub_expr, + pointers, + extra_vars, + /* keep parentheses */ + 0, + search_logical_op, + search_comparison, + prefix, + suffix); + free (sub_expr); + rc = eval_is_true (tmp_value); + if (tmp_value) + free (tmp_value); + /* + * if rc == 0 with "&&" or rc == 1 with "||", no need to + * evaluate second sub-expression, just return the rc + */ + if ((!rc && (logic == EVAL_LOGICAL_OP_AND)) + || (rc && (logic == EVAL_LOGICAL_OP_OR))) + { + value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE); + goto end; + } + pos += strlen (logical_ops[logic]); + while (pos[0] == ' ') + { + pos++; + } + tmp_value = eval_expression_condition (pos, + pointers, + extra_vars, + /* keep parentheses */ + 0, + search_logical_op, + search_comparison, + prefix, + suffix); + rc = eval_is_true (tmp_value); + if (tmp_value) + free (tmp_value); value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE); goto end; } - pos += strlen (logical_ops[logic]); - while (pos[0] == ' ') - { - pos++; - } - tmp_value = eval_expression_condition (pos, pointers, extra_vars, - 0, prefix, suffix); - rc = eval_is_true (tmp_value); - if (tmp_value) - free (tmp_value); - value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE); - goto end; } } @@ -687,38 +715,56 @@ eval_expression_condition (const char *expr, struct t_hashtable *pointers, * - compare sub-expressions * - return result */ - for (comp = 0; comp < EVAL_NUM_COMPARISONS; comp++) + if (search_comparison) { - pos = strstr (expr2, comparisons[comp]); - if (pos > expr2) + for (comp = 0; comp < EVAL_NUM_COMPARISONS; comp++) { - pos_end = pos - 1; - while ((pos_end > expr2) && (pos_end[0] == ' ')) + pos = strstr (expr2, comparisons[comp]); + if (pos > expr2) { - pos_end--; - } - sub_expr = string_strndup (expr2, pos_end + 1 - expr2); - if (!sub_expr) + pos_end = pos - 1; + while ((pos_end > expr2) && (pos_end[0] == ' ')) + { + pos_end--; + } + sub_expr = string_strndup (expr2, pos_end + 1 - expr2); + if (!sub_expr) + goto end; + tmp_value = eval_expression_condition (sub_expr, + pointers, + extra_vars, + /* keep parentheses */ + 0, + search_logical_op, + search_comparison, + prefix, + suffix); + free (sub_expr); + pos += strlen (comparisons[comp]); + while (pos[0] == ' ') + { + pos++; + } + regex = ((comp == EVAL_COMPARE_REGEX_MATCHING) + || (comp == EVAL_COMPARE_REGEX_NOT_MATCHING)); + tmp_value2 = eval_expression_condition (pos, + pointers, + extra_vars, + /* keep parentheses */ + (regex) ? 1 : 0, + /* search logical op */ + 0, + /* search comparison */ + 0, + prefix, + suffix); + value = eval_compare (tmp_value, comp, tmp_value2); + if (tmp_value) + free (tmp_value); + if (tmp_value2) + free (tmp_value2); goto end; - tmp_value = eval_expression_condition (sub_expr, pointers, - extra_vars, - 0, prefix, suffix); - free (sub_expr); - pos += strlen (comparisons[comp]); - while (pos[0] == ' ') - { - pos++; } - tmp_value2 = eval_expression_condition (pos, pointers, extra_vars, - ((comp == EVAL_COMPARE_REGEX_MATCHING) - || (comp == EVAL_COMPARE_REGEX_NOT_MATCHING)) ? 1 : 0, - prefix, suffix); - value = eval_compare (tmp_value, comp, tmp_value2); - if (tmp_value) - free (tmp_value); - if (tmp_value2) - free (tmp_value2); - goto end; } } @@ -846,8 +892,17 @@ eval_expression (const char *expr, struct t_hashtable *pointers, if (condition) { /* evaluate as condition (return a boolean: "0" or "1") */ - value = eval_expression_condition (expr, pointers, extra_vars, - 0, prefix, suffix); + value = eval_expression_condition (expr, + pointers, + extra_vars, + /* keep parentheses */ + 0, + /* search logical op */ + 1, + /* search comparison */ + 1, + prefix, + suffix); rc = eval_is_true (value); if (value) free (value); diff --git a/src/core/wee-eval.h b/src/core/wee-eval.h index 98c7957bf..5f0ae7202 100644 --- a/src/core/wee-eval.h +++ b/src/core/wee-eval.h @@ -35,14 +35,14 @@ enum t_eval_logical_op enum t_eval_comparison { - EVAL_COMPARE_EQUAL = 0, + EVAL_COMPARE_REGEX_MATCHING = 0, + EVAL_COMPARE_REGEX_NOT_MATCHING, + EVAL_COMPARE_EQUAL, EVAL_COMPARE_NOT_EQUAL, EVAL_COMPARE_LESS_EQUAL, EVAL_COMPARE_LESS, EVAL_COMPARE_GREATER_EQUAL, EVAL_COMPARE_GREATER, - EVAL_COMPARE_REGEX_MATCHING, - EVAL_COMPARE_REGEX_NOT_MATCHING, /* number of comparison strings */ EVAL_NUM_COMPARISONS, }; |