41
41
#include "../plugins/plugin.h"
44
char *logical_ops[EVAL_NUM_LOGICAL_OPS] = { "||", "&&" };
45
char *comparisons[EVAL_NUM_COMPARISONS] = { "==", "!=", "<=", "<", ">=", ">",
44
char *logical_ops[EVAL_NUM_LOGICAL_OPS] =
47
char *comparisons[EVAL_NUM_COMPARISONS] =
48
{ "=~", "!~", "==", "!=", "<=", "<", ">=", ">" };
48
50
struct t_hashtable *eval_hashtable_pointers = NULL;
252
254
return strdup (ptr_value);
255
/* 2. look for a color */
257
/* 2. convert escaped chars */
258
if (strncmp (text, "esc:", 4) == 0)
259
return string_convert_escaped_chars (text + 4);
260
if ((text[0] == '\\') && text[1] && (text[1] != '\\'))
261
return string_convert_escaped_chars (text);
263
/* 3. look for a color */
256
264
if (strncmp (text, "color:", 6) == 0)
258
266
ptr_value = gui_color_get_custom (text + 6);
259
267
return strdup ((ptr_value) ? ptr_value : "");
262
/* 3. look for an info */
270
/* 4. look for an info */
263
271
if (strncmp (text, "info:", 5) == 0)
265
273
ptr_value = NULL;
279
287
return strdup ((ptr_value) ? ptr_value : "");
282
/* 4. look for name of option: if found, return this value */
290
/* 5. look for name of option: if found, return this value */
283
291
if (strncmp (text, "sec.data.", 9) == 0)
285
293
ptr_value = hashtable_get (secure_hashtable_data, text + 9);
387
395
struct t_hashtable *extra_vars,
388
396
const char *prefix, const char *suffix)
393
400
ptr[0] = pointers;
394
401
ptr[1] = extra_vars;
396
403
return string_replace_with_callback (expr, prefix, suffix,
397
&eval_replace_vars_cb,
404
&eval_replace_vars_cb, ptr, NULL);
510
* Searches a string in another at same level (skip sub-expressions between
513
* For example: eval_strstr_level ("(x || y) || z", "||")
514
* will return a pointer on "|| z" (because the first "||" is
515
* in a sub-expression, which is skipped).
517
* Returns pointer to string found, or NULL if not found.
521
eval_strstr_level (const char *string, const char *search)
523
const char *ptr_string;
526
if (!string || !search)
529
length = strlen (search);
533
while (ptr_string[0])
535
if (ptr_string[0] == '(')
539
else if (ptr_string[0] == ')')
545
if ((level == 0) && (strncmp (ptr_string, search, length) == 0))
505
555
* Evaluates a condition (this function must not be called directly).
507
* Argument keep_parentheses is almost always 0, it is 1 only if the expression
508
* is a regex (to keep flags inside the parentheses).
510
557
* For return value, see function eval_expression().
512
559
* Note: result must be freed after use (if not NULL).
516
eval_expression_condition (const char *expr, struct t_hashtable *pointers,
563
eval_expression_condition (const char *expr,
564
struct t_hashtable *pointers,
517
565
struct t_hashtable *extra_vars,
518
int keep_parentheses,
519
const char *prefix, const char *suffix)
521
569
int logic, comp, length, level, rc;
523
char *expr2, *sub_expr, *pos, *pos2, *value, *tmp_value, *tmp_value2;
570
const char *pos, *pos_end;
571
char *expr2, *sub_expr, *value, *tmp_value, *tmp_value2;
553
* evaluate sub-expressions between parentheses and replace them with their
556
if (!keep_parentheses)
558
while ((pos = strchr (expr2, '(')) != NULL)
566
else if (pos2[0] == ')')
574
/* closing parenthesis not found */
577
sub_expr = string_strndup (pos + 1, pos2 - pos - 1);
580
tmp_value = eval_expression_condition (sub_expr, pointers,
586
/* nothing around parentheses, then return value of sub-expression as-is */
591
* build a string with string before '(' +
592
* result of sub-expression + string after ')'
594
length = (pos - expr2) + 1
595
+ ((tmp_value) ? strlen (tmp_value) : 0)
596
+ 1 + strlen (pos2 + 1)
598
tmp_value2 = malloc (length);
601
tmp_value2[0] = '\0';
604
strncat (tmp_value2, expr2, pos - expr2);
605
strcat (tmp_value2, " ");
608
strcat (tmp_value2, tmp_value);
611
strcat (tmp_value2, " ");
612
strcat (tmp_value2, pos2 + 1);
620
601
* search for a logical operator, and if one is found:
621
602
* - split expression into two sub-expressions
622
603
* - evaluate first sub-expression
639
620
tmp_value = eval_expression_condition (sub_expr, pointers,
643
624
rc = eval_is_true (tmp_value);
645
626
free (tmp_value);
647
* if rc == 0 with "&&" or rc == 1 with "||", no need to evaluate
648
* second sub-expression, just return the rc
628
* if rc == 0 with "&&" or rc == 1 with "||", no need to
629
* evaluate second sub-expression, just return the rc
650
631
if ((!rc && (logic == EVAL_LOGICAL_OP_AND))
651
632
|| (rc && (logic == EVAL_LOGICAL_OP_OR)))
688
669
sub_expr = string_strndup (expr2, pos_end + 1 - expr2);
691
tmp_value = eval_expression_condition (sub_expr, pointers,
695
672
pos += strlen (comparisons[comp]);
696
673
while (pos[0] == ' ')
700
tmp_value2 = eval_expression_condition (pos, pointers, extra_vars,
701
((comp == EVAL_COMPARE_REGEX_MATCHING)
702
|| (comp == EVAL_COMPARE_REGEX_NOT_MATCHING)) ? 1 : 0,
677
if ((comp == EVAL_COMPARE_REGEX_MATCHING)
678
|| (comp == EVAL_COMPARE_REGEX_NOT_MATCHING))
680
/* for regex: just replace vars in both expressions */
681
tmp_value = eval_replace_vars (sub_expr, pointers,
684
tmp_value2 = eval_replace_vars (pos, pointers,
690
/* other comparison: fully evaluate both expressions */
691
tmp_value = eval_expression_condition (sub_expr, pointers,
694
tmp_value2 = eval_expression_condition (pos, pointers,
704
699
value = eval_compare (tmp_value, comp, tmp_value2);
706
701
free (tmp_value);
709
* evaluate sub-expressions between parentheses and replace them with their
712
while (expr2[0] == '(')
720
else if (pos[0] == ')')
728
/* closing parenthesis not found */
731
sub_expr = string_strndup (expr2 + 1, pos - expr2 - 1);
734
tmp_value = eval_expression_condition (sub_expr, pointers, extra_vars,
740
* nothing around parentheses, then return value of
741
* sub-expression as-is
746
length = ((tmp_value) ? strlen (tmp_value) : 0) + 1 +
747
strlen (pos + 1) + 1;
748
tmp_value2 = malloc (length);
755
tmp_value2[0] = '\0';
757
strcat (tmp_value2, tmp_value);
758
strcat (tmp_value2, " ");
759
strcat (tmp_value2, pos + 1);
714
767
* at this point, there is no more logical operator neither comparison,
715
768
* so we just replace variables in string and return the result
768
821
eval_expression (const char *expr, struct t_hashtable *pointers,
769
822
struct t_hashtable *extra_vars, struct t_hashtable *options)
824
int condition, rc, pointers_allocated;
773
826
const char *prefix, *suffix, *default_prefix = "${", *default_suffix = "}";
774
827
const char *ptr_value;
834
pointers_allocated = 0;
781
835
prefix = default_prefix;
782
836
suffix = default_suffix;
784
838
/* create hashtable pointers if it's NULL */
787
if (eval_hashtable_pointers)
788
hashtable_remove_all (eval_hashtable_pointers);
791
eval_hashtable_pointers = hashtable_new (32,
792
WEECHAT_HASHTABLE_STRING,
793
WEECHAT_HASHTABLE_POINTER,
796
if (!eval_hashtable_pointers)
799
pointers = eval_hashtable_pointers;
841
pointers = hashtable_new (32,
842
WEECHAT_HASHTABLE_STRING,
843
WEECHAT_HASHTABLE_POINTER,
848
pointers_allocated = 1;
840
889
/* evaluate as condition (return a boolean: "0" or "1") */
841
890
value = eval_expression_condition (expr, pointers, extra_vars,
843
892
rc = eval_is_true (value);
851
900
value = eval_replace_vars (expr, pointers, extra_vars, prefix, suffix);
903
if (pointers_allocated)
904
hashtable_free (pointers);
858
* Frees all allocated data.
864
if (eval_hashtable_pointers)
866
hashtable_free (eval_hashtable_pointers);
867
eval_hashtable_pointers = NULL;