--- a/help/en/hlp_eval.txt Tue Nov 10 18:27:16 2009 +0200
+++ b/help/en/hlp_eval.txt Tue Nov 10 19:36:54 2009 +0200
@@ -4,7 +4,6 @@
Evaluates expression and executes result string as command.
Expression evaluation rules:
* all operators have the same precedence;
-* parenthesis searching will not take into account strings;
* supported operators:
. string concatenation
+ binary plus / string concatenation
@@ -20,9 +19,9 @@
* numbers can be specified as plain decimal numbers, minus in front of digit will be recognized as a part of number;
* mcabber variables can be specified by name, though only subset of possible names is suppoted:
- variable must start from latin alphabetic symbol;
- - inside of variable name also are allowed digits, - and _.
+ - inside of variable name also are allowed digits, - and _;
+* to enable parentheses in character strings current implementation ignores anything after extra closing paren - you may use this as a sort of comment...
Example:
/eval "echo 2 + 2 = " . (2+2)
- /eval "set ping_interval = " . (ping_interval + 1)
-Note: last example probably should use /let command.
+ /eval "set ping_interval = " . (ping_interval + 1) ) this example probably should use /let command.
--- a/yaubil.c Tue Nov 10 18:27:16 2009 +0200
+++ b/yaubil.c Tue Nov 10 19:36:54 2009 +0200
@@ -472,9 +472,9 @@
g_free (value);
}
-static value_t *process_expression (const char *str, gsize len)
+static value_t *process_expression (const char *str, gsize *len)
{
- const char *strend = str + len;
+ const char *strend = str + *len;
const char *p;
op_t *op = NULL;
int state = STATE_LVALUE;
@@ -484,7 +484,7 @@
.str_value = NULL,
};
- for (p = str; *p && p < strend; ++p) {
+ for (p = str; *p && p < strend && *p != ')'; ++p) {
switch (state) {
case STATE_LVALUE:
case STATE_RVALUE:
@@ -585,48 +585,21 @@
} else if (*p == '(') {
- const char *e;
-
- {
- int l = 0;
- gboolean finished = FALSE;
-
- // XXX maybe we should just pass end of line and let it return real length...
- for (e = p + 1; e < strend; ++e) {
- if (*e == '(')
- ++l;
- else if (*e == ')') {
- --l;
- if (l < 0) {
- finished = TRUE;
- break;
- }
- }
- }
-
- if (!finished) {
- scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: Unmatched parenthesis.");
- g_free (val.str_value);
- return NULL;
- }
+ gsize len = strend - p - 1;
+ value_t *n = process_expression (p + 1, &len);
+
+ if (!n) {
+ scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: Error in subexpression.");
+ g_free (val.str_value);
+ return NULL;
}
- {
- value_t *n = process_expression (p + 1, e - p - 1);
-
- if (!n) {
- scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: Error in subexpression.");
- g_free (val.str_value);
- return NULL;
- }
+ rval.type = n->type;
+ rval.int_value = n->int_value;
+ rval.str_value = g_strdup (n->str_value);
+ destroy_value (n);
- rval.type = n->type;
- rval.int_value = n->int_value;
- rval.str_value = g_strdup (n->str_value);
- destroy_value (n);
- }
-
- p = e;
+ p += len + 1;
} else {
scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: unrecognized symbols.");
@@ -687,6 +660,7 @@
}
{ // return value
+ *len = p - str;
value_t *rval = g_new (value_t, 1);
rval->type = val.type;
@@ -699,7 +673,8 @@
static void do_eval (char *arg)
{
- value_t *val = process_expression (arg, strlen (arg));
+ gsize len = strlen (arg);
+ value_t *val = process_expression (arg, &len);
if (!val) {
scr_LogPrint (LPRINT_NORMAL, "eval: Evaluation error.");
@@ -738,8 +713,11 @@
namelen = p + 1 - arg;
}
- // evaluate expression
- value = process_expression (val + 1, strlen (val + 1));
+ { // evaluate expression
+ gsize len = strlen (val + 1);
+
+ value = process_expression (val + 1, &len);
+ }
if (!value) {
scr_LogPrint (LPRINT_NORMAL, "let: Evaluation error.");
@@ -767,7 +745,8 @@
static void do_if (char *arg)
{
- value_t *val = process_expression (arg, strlen (arg));
+ gsize len = strlen (arg);
+ value_t *val = process_expression (arg, &len);
if (!val) {
scr_LogPrint (LPRINT_NORMAL, "if: Evaluation error.");