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:
+39
-5
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user