summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2019-12-18 21:18:59 +0100
committerSébastien Helleu <flashcode@flashtux.org>2019-12-18 21:18:59 +0100
commita13099aa635d7587f00bdd375c129b3e081e98b2 (patch)
treeedca338815ff62d5fccb37183f199c6eadd16f7c /src/core
parent7e833ee60b6ef3fc251a5fc85b1edd7b700c92a6 (diff)
downloadweechat-a13099aa635d7587f00bdd375c129b3e081e98b2.zip
core: add debug option "-d" in command /eval (issue #1434)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/wee-command.c44
-rw-r--r--src/core/wee-eval.c98
-rw-r--r--src/core/wee-eval.h1
3 files changed, 119 insertions, 24 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 85939a89c..a7354cc3d 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -1936,8 +1936,9 @@ COMMAND_CALLBACK(debug)
COMMAND_CALLBACK(eval)
{
- int i, print_only, split_command, condition, error;
+ int i, print_only, split_command, condition, debug, error;
char *result, *ptr_args, *expr, **commands;
+ const char **debug_output;
struct t_hashtable *pointers, *options;
/* make C compiler happy */
@@ -1948,6 +1949,7 @@ COMMAND_CALLBACK(eval)
print_only = 0;
split_command = 0;
condition = 0;
+ debug = 0;
error = 0;
COMMAND_MIN_ARGS(2, "");
@@ -1970,6 +1972,11 @@ COMMAND_CALLBACK(eval)
condition = 1;
ptr_args = argv_eol[i + 1];
}
+ else if (string_strcasecmp (argv[i], "-d") == 0)
+ {
+ debug = 1;
+ ptr_args = argv_eol[i + 1];
+ }
else
{
ptr_args = argv_eol[i];
@@ -1992,7 +1999,7 @@ COMMAND_CALLBACK(eval)
}
options = NULL;
- if (condition)
+ if (condition || debug)
{
options = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
@@ -2000,7 +2007,12 @@ COMMAND_CALLBACK(eval)
NULL,
NULL);
if (options)
- hashtable_set (options, "type", "condition");
+ {
+ if (condition)
+ hashtable_set (options, "type", "condition");
+ if (debug)
+ hashtable_set (options, "debug", "1");
+ }
}
if (print_only)
@@ -2028,6 +2040,13 @@ COMMAND_CALLBACK(eval)
GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS));
}
free (expr);
+ if (options && debug)
+ {
+ debug_output = hashtable_get (options,
+ "debug_output");
+ if (debug_output)
+ gui_chat_printf (NULL, "%s", debug_output);
+ }
}
}
else
@@ -2050,6 +2069,13 @@ COMMAND_CALLBACK(eval)
{
error = 1;
}
+ if (options && debug)
+ {
+ debug_output = hashtable_get (options,
+ "debug_output");
+ if (debug_output)
+ gui_chat_printf (NULL, "%s", debug_output);
+ }
}
string_free_split_command (commands);
}
@@ -2066,6 +2092,13 @@ COMMAND_CALLBACK(eval)
{
error = 1;
}
+ if (options && debug)
+ {
+ debug_output = hashtable_get (options,
+ "debug_output");
+ if (debug_output)
+ gui_chat_printf (NULL, "%s", debug_output);
+ }
}
}
@@ -7304,12 +7337,13 @@ command_init ()
hook_command (
NULL, "eval",
N_("evaluate expression"),
- N_("[-n|-s] <expression>"
- " || [-n] -c <expression1> <operator> <expression2>"),
+ N_("[-n|-s] [-d] <expression>"
+ " || [-n] [-d] -c <expression1> <operator> <expression2>"),
N_(" -n: display result without sending it to buffer "
"(debug mode)\n"
" -s: split expression before evaluating it "
"(many commands can be separated by semicolons)\n"
+ " -d: display debug output after evaluation\n"
" -c: evaluate as condition: use operators and parentheses, "
"return a boolean value (\"0\" or \"1\")\n"
"expression: expression to evaluate, variables with format "
diff --git a/src/core/wee-eval.c b/src/core/wee-eval.c
index 1bcd96a4b..c63151291 100644
--- a/src/core/wee-eval.c
+++ b/src/core/wee-eval.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <regex.h>
#include <time.h>
@@ -45,6 +46,10 @@
#include "../plugins/plugin.h"
+#define EVAL_DEBUG(msg, argz...) \
+ if (eval_context->debug) \
+ eval_debug_message (eval_context, msg, ##argz);
+
char *logical_ops[EVAL_NUM_LOGICAL_OPS] =
{ "||", "&&" };
@@ -59,6 +64,24 @@ char *eval_expression_condition (const char *expr,
/*
+ * Adds a debug message in the debug output.
+ */
+
+void
+eval_debug_message (struct t_eval_context *eval_context, char *message, ...)
+{
+ weechat_va_format (message);
+ if (!vbuffer)
+ return;
+
+ if (*(eval_context->debug)[0])
+ string_dyn_concat (eval_context->debug, "\n");
+ string_dyn_concat (eval_context->debug, vbuffer);
+
+ free (vbuffer);
+}
+
+/*
* Checks if a value is true: a value is true if string is non-NULL, non-empty
* and different from "0".
*
@@ -140,13 +163,17 @@ eval_strstr_level (const char *string, const char *search,
*/
char *
-eval_hdata_get_value (struct t_hdata *hdata, void *pointer, const char *path)
+eval_hdata_get_value (struct t_hdata *hdata, void *pointer, const char *path,
+ struct t_eval_context *eval_context)
{
char *value, *old_value, *var_name, str_value[128], *pos;
const char *ptr_value, *hdata_name, *ptr_var_name;
int type;
struct t_hashtable *hashtable;
+ EVAL_DEBUG("eval_hdata_get_value(\"%s\", 0x%lx, \"%s\")",
+ hdata->name, pointer, path);
+
value = NULL;
var_name = NULL;
@@ -274,7 +301,10 @@ eval_hdata_get_value (struct t_hdata *hdata, void *pointer, const char *path)
hdata = hook_hdata_get (NULL, hdata_name);
old_value = value;
- value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL);
+ value = eval_hdata_get_value (hdata,
+ pointer,
+ (pos) ? pos + 1 : NULL,
+ eval_context);
if (old_value)
free (old_value);
}
@@ -339,6 +369,8 @@ eval_replace_vars_cb (void *data, const char *text)
eval_context = (struct t_eval_context *)data;
+ EVAL_DEBUG("eval_replace_vars_cb(\"%s\")", text);
+
/* 1. variable in hashtable "extra_vars" */
if (eval_context->extra_vars)
{
@@ -785,7 +817,10 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
- value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL);
+ value = eval_hdata_get_value (hdata,
+ pointer,
+ (pos) ? pos + 1 : NULL,
+ eval_context);
end:
if (hdata_name)
@@ -808,6 +843,8 @@ eval_replace_vars (const char *expr, struct t_eval_context *eval_context)
const char *no_replace_prefix_list[] = { "if:", NULL };
char *result;
+ EVAL_DEBUG("eval_replace_vars(\"%s\")", expr);
+
eval_context->recursion_count++;
if (eval_context->recursion_count < EVAL_RECURSION_MAX)
@@ -845,13 +882,17 @@ eval_replace_vars (const char *expr, struct t_eval_context *eval_context)
*/
char *
-eval_compare (const char *expr1, int comparison, const char *expr2)
+eval_compare (const char *expr1, int comparison, const char *expr2,
+ struct t_eval_context *eval_context)
{
int rc, string_compare, length1, length2;
regex_t regex;
double value1, value2;
char *error;
+ EVAL_DEBUG("eval_compare(\"%s\", \"%s\", \"%s\")",
+ expr1, comparisons[comparison], expr2);
+
rc = 0;
string_compare = 0;
@@ -958,6 +999,8 @@ eval_expression_condition (const char *expr,
const char *pos, *pos_end;
char *expr2, *sub_expr, *value, *tmp_value, *tmp_value2;
+ EVAL_DEBUG("eval_expression_condition(\"%s\")", expr);
+
value = NULL;
if (!expr)
@@ -1080,7 +1123,7 @@ eval_expression_condition (const char *expr,
tmp_value2 = eval_expression_condition (pos, eval_context);
}
free (sub_expr);
- value = eval_compare (tmp_value, comp, tmp_value2);
+ value = eval_compare (tmp_value, comp, tmp_value2, eval_context);
if (tmp_value)
free (tmp_value);
if (tmp_value2)
@@ -1192,6 +1235,9 @@ eval_replace_regex (const char *string, regex_t *regex, const char *replace,
int empty_replace_allowed;
struct t_eval_regex eval_regex;
+ EVAL_DEBUG("eval_replace_regex(\"%s\", 0x%lx, \"%s\")",
+ string, regex, replace);
+
if (!string || !regex || !replace)
return NULL;
@@ -1334,7 +1380,7 @@ char *
eval_expression (const char *expr, struct t_hashtable *pointers,
struct t_hashtable *extra_vars, struct t_hashtable *options)
{
- struct t_eval_context eval_context;
+ struct t_eval_context context, *eval_context;
int condition, rc, pointers_allocated, regex_allocated;
int ptr_window_added, ptr_buffer_added;
char *value;
@@ -1372,13 +1418,16 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
pointers_allocated = 1;
}
- eval_context.pointers = pointers;
- eval_context.extra_vars = extra_vars;
- eval_context.extra_vars_eval = 0;
- eval_context.prefix = default_prefix;
- eval_context.suffix = default_suffix;
- eval_context.regex = NULL;
- eval_context.recursion_count = 0;
+ eval_context = &context;
+
+ eval_context->pointers = pointers;
+ eval_context->extra_vars = extra_vars;
+ eval_context->extra_vars_eval = 0;
+ eval_context->prefix = default_prefix;
+ eval_context->suffix = default_suffix;
+ eval_context->regex = NULL;
+ eval_context->recursion_count = 0;
+ eval_context->debug = NULL;
/*
* set window/buffer with pointer to current window/buffer
@@ -1413,17 +1462,17 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
/* check if extra vars must be evaluated */
ptr_value = hashtable_get (options, "extra");
if (ptr_value && (strcmp (ptr_value, "eval") == 0))
- eval_context.extra_vars_eval = 1;
+ eval_context->extra_vars_eval = 1;
/* check for custom prefix */
ptr_value = hashtable_get (options, "prefix");
if (ptr_value && ptr_value[0])
- eval_context.prefix = ptr_value;
+ eval_context->prefix = ptr_value;
/* check for custom suffix */
ptr_value = hashtable_get (options, "suffix");
if (ptr_value && ptr_value[0])
- eval_context.suffix = ptr_value;
+ eval_context->suffix = ptr_value;
/* check for regex */
ptr_value = hashtable_get (options, "regex");
@@ -1448,13 +1497,19 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
{
regex_replace = ptr_value;
}
+
+ /* check for debug */
+ if (hashtable_has_key (options, "debug"))
+ eval_context->debug = string_dyn_alloc (256);
}
+ EVAL_DEBUG("eval_expression(\"%s\")", expr);
+
/* evaluate expression */
if (condition)
{
/* evaluate as condition (return a boolean: "0" or "1") */
- value = eval_expression_condition (expr, &eval_context);
+ value = eval_expression_condition (expr, eval_context);
rc = eval_is_true (value);
if (value)
free (value);
@@ -1466,12 +1521,12 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
{
/* replace with regex */
value = eval_replace_regex (expr, regex, regex_replace,
- &eval_context);
+ eval_context);
}
else
{
/* only replace variables in expression */
- value = eval_replace_vars (expr, &eval_context);
+ value = eval_replace_vars (expr, eval_context);
}
}
@@ -1492,5 +1547,10 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
free (regex);
}
+ if (options && eval_context->debug)
+ hashtable_set (options, "debug_output", *(eval_context->debug));
+ if (eval_context->debug)
+ string_dyn_free (eval_context->debug, 1);
+
return value;
}
diff --git a/src/core/wee-eval.h b/src/core/wee-eval.h
index 565b051df..a6c2d1229 100644
--- a/src/core/wee-eval.h
+++ b/src/core/wee-eval.h
@@ -72,6 +72,7 @@ struct t_eval_context
const char *suffix;
struct t_eval_regex *regex;
int recursion_count;
+ char **debug;
};
extern int eval_is_true (const char *value);