1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-02 15:53:12 +02:00

core: add debug option "-d" in command /eval (issue #1434)

This commit is contained in:
Sébastien Helleu
2019-12-18 21:18:59 +01:00
parent 7e833ee60b
commit a13099aa63
23 changed files with 334 additions and 183 deletions
+39 -5
View File
@@ -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 "
+79 -19
View File
@@ -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] =
{ "||", "&&" };
@@ -58,6 +63,24 @@ char *eval_expression_condition (const char *expr,
struct t_eval_context *eval_context);
/*
* 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;
}
+1
View File
@@ -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);