summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2021-08-03 19:46:41 +0200
committerSébastien Helleu <flashcode@flashtux.org>2021-08-03 19:46:41 +0200
commitd89c4f559c817a92da94d98baf9f3829238b0392 (patch)
tree552415606ad46f35bf20cb5d6d376b78b9c480f6 /src
parent0be4020b68e54cbb6fd588175419843b7873f900 (diff)
downloadweechat-d89c4f559c817a92da94d98baf9f3829238b0392.zip
api: add random integer number in evaluation of expressions with "random:min,max"
Diffstat (limited to 'src')
-rw-r--r--src/core/wee-command.c10
-rw-r--r--src/core/wee-eval.c78
-rw-r--r--src/core/weechat.c6
3 files changed, 82 insertions, 12 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 80a1bb444..beacd126f 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -7586,10 +7586,11 @@ command_init ()
"\"if:condition?value_if_true:value_if_false\")\n"
" 17. result of an expression with parentheses and operators "
"+ - * / // % ** (format: \"calc:xxx\")\n"
- " 18. a translated string (format: \"translate:xxx\")\n"
- " 19. an option (format: \"file.section.option\")\n"
- " 20. a local variable in buffer\n"
- " 21. a hdata name/variable (the value is automatically converted "
+ " 18. a random integer number (format: \"random:min,max\")\n"
+ " 19. a translated string (format: \"translate:xxx\")\n"
+ " 20. an option (format: \"file.section.option\")\n"
+ " 21. a local variable in buffer\n"
+ " 22. a hdata name/variable (the value is automatically converted "
"to string), by default \"window\" and \"buffer\" point to current "
"window/buffer.\n"
"Format for hdata can be one of following:\n"
@@ -7631,6 +7632,7 @@ command_init ()
" /eval -n ${repeat:5,-} ==> -----\n"
" /eval -n ${length:test} ==> 4\n"
" /eval -n ${calc:(5+2)*3} ==> 21\n"
+ " /eval -n ${random:0,10} ==> 3\n"
" /eval -n ${base_encode:64,test} ==> dGVzdA==\n"
" /eval -n ${base_decode:64,dGVzdA==} ==> test\n"
" /eval -n ${translate:Plugin} ==> Extension\n"
diff --git a/src/core/wee-eval.c b/src/core/wee-eval.c
index a1020ce9e..397b951ce 100644
--- a/src/core/wee-eval.c
+++ b/src/core/wee-eval.c
@@ -726,13 +726,64 @@ eval_string_if (const char *text, struct t_eval_context *eval_context)
}
/*
+ * Returns a random integer number.
+ *
+ * Note: result must be freed after use.
+ */
+
+char *
+eval_string_random (const char *text)
+{
+ char *pos, *error, *tmp, result[128];
+ long min_number, max_number;
+
+ if (!text || !text[0])
+ goto error;
+
+ pos = strchr (text, ',');
+ if (!pos)
+ goto error;
+
+ tmp = strndup (text, pos - text);
+ if (!tmp)
+ goto error;
+ min_number = strtol (tmp, &error, 10);
+ if (!error || error[0])
+ {
+ free (tmp);
+ goto error;
+ }
+ free (tmp);
+
+ max_number = strtol (pos + 1, &error, 10);
+ if (!error || error[0])
+ goto error;
+
+ if (min_number > max_number)
+ goto error;
+ if (max_number - min_number > RAND_MAX)
+ goto error;
+
+ /*
+ * using modulo division on the random() value produces a biased result,
+ * but this is enough for our usage here
+ */
+ snprintf (result, sizeof (result),
+ "%ld", min_number + (random () % (max_number - min_number + 1)));
+ return strdup (result);
+
+error:
+ return strdup ("0");
+}
+
+/*
* Translates text.
*
* Note: result must be freed after use.
*/
char *
-eval_translate (const char *text)
+eval_string_translate (const char *text)
{
const char *ptr_string;
@@ -1053,11 +1104,13 @@ end:
* 18. an environment variable (format: env:XXX)
* 19. a ternary operator (format: if:condition?value_if_true:value_if_false)
* 20. calculate result of an expression (format: calc:xxx)
- * 21. a translated string (format: translate:xxx)
- * 22. an option (format: file.section.option)
- * 23. a buffer local variable
- * 24. a pointer name from hashtable "pointers"
- * 25. a hdata variable (format: hdata.var1.var2 or hdata[list].var1.var2
+ * 21. a random integer number in the range from "min" to "max"
+ * (format: random:min,max)
+ * 22. a translated string (format: translate:xxx)
+ * 23. an option (format: file.section.option)
+ * 24. a buffer local variable
+ * 25. a pointer name from hashtable "pointers"
+ * 26. a hdata variable (format: hdata.var1.var2 or hdata[list].var1.var2
* or hdata[ptr].var1.var2 or hdata[ptr_name].var1.var2)
*
* See /help in WeeChat for examples.
@@ -1306,11 +1359,20 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
- * 21. translated text
+ * 21. random number
+ */
+ if (strncmp (text, "random:", 7) == 0)
+ {
+ value = eval_string_random (text + 7);
+ goto end;
+ }
+
+ /*
+ * 22. translated text
*/
if (strncmp (text, "translate:", 10) == 0)
{
- value = eval_translate (text + 10);
+ value = eval_string_translate (text + 10);
goto end;
}
diff --git a/src/core/weechat.c b/src/core/weechat.c
index cd83add1f..1900ca6e1 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -47,6 +47,7 @@
#include <getopt.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <time.h>
#include <signal.h>
@@ -610,6 +611,11 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)())
weechat_first_start_time = time (NULL); /* initialize start time */
gettimeofday (&weechat_current_start_timeval, NULL);
+ /* set the seed for the pseudo-random integer generator */
+ srand ((weechat_current_start_timeval.tv_sec
+ * weechat_current_start_timeval.tv_usec)
+ ^ getpid ());
+
signal_init (); /* initialize signals */
hdata_init (); /* initialize hdata */
hook_init (); /* initialize hooks */