diff options
author | Trygve Aaberge <trygveaa@gmail.com> | 2022-03-02 20:45:04 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2022-03-12 16:00:38 +0100 |
commit | 197a7a01e458255a578c99c7f477dd0bec7e3a47 (patch) | |
tree | 252e3b3aac3dc46dfc584f003b14e869053e5e28 /src/plugins | |
parent | 47e71a1bbd4ff71b8cccd8db4df1187ccf0638f4 (diff) | |
download | weechat-197a7a01e458255a578c99c7f477dd0bec7e3a47.zip |
scripts: allow null values in config_new_option
The plugin API function config_new_option accepts null as the
default_value and/or value however the scripting APIs (except for lua)
didn't allow sending null as a parameter value, so it was impossible to
use it this way. This allows sending a null value for these parameters.
Lua already supported sending in nil for these parameters and it works
as expected, so nothing is changed for this plugin.
For Guile you can now send in #nil, for JavaScript null or undefined,
for Perl undef, for PHP NULL, for Python None, for Ruby nil and for Tcl
$::weechat::WEECHAT_NULL.
In all of these languages except Tcl this is the special value
indicating a missing value. However Tcl only has one type, string, so it
doesn't have a null value. Therefore I created a constant with the value
`\uFFFF\uFFFF\uFFFFWEECHAT_NULL\uFFFF\uFFFF\uFFFF` which is used
instead. This is very unlikely to appear unintentionally. Using the
unicode code point \uFFFF was suggested on
https://wiki.tcl-lang.org/page/null.
I tested this with these scripts:
https://gist.github.com/trygveaa/f91977dde5d2876d502bf55fbf9b50cc
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/guile/weechat-guile-api.c | 6 | ||||
-rw-r--r-- | src/plugins/javascript/weechat-js-api.cpp | 24 | ||||
-rw-r--r-- | src/plugins/perl/weechat-perl-api.c | 4 | ||||
-rw-r--r-- | src/plugins/php/weechat-php-api.c | 6 | ||||
-rw-r--r-- | src/plugins/python/weechat-python-api.c | 2 | ||||
-rw-r--r-- | src/plugins/python/weechat.pyi | 2 | ||||
-rw-r--r-- | src/plugins/ruby/weechat-ruby-api.c | 13 | ||||
-rw-r--r-- | src/plugins/tcl/weechat-tcl-api.c | 15 |
8 files changed, 53 insertions, 19 deletions
diff --git a/src/plugins/guile/weechat-guile-api.c b/src/plugins/guile/weechat-guile-api.c index a48a37d19..85f8561a3 100644 --- a/src/plugins/guile/weechat-guile-api.c +++ b/src/plugins/guile/weechat-guile-api.c @@ -114,6 +114,9 @@ char * weechat_guile_api_scm_to_string (SCM str, char *guile_strings[], int *guile_num_strings) { + if (scm_is_null (str)) + return NULL; + /* * if array is full, just return string without using length * (this should never happen, the array should be large enough for any API @@ -1302,7 +1305,8 @@ weechat_guile_api_config_new_option (SCM args) || !scm_is_string (name) || !scm_is_string (type) || !scm_is_string (description) || !scm_is_string (string_values) || !scm_is_integer (min) || !scm_is_integer (max) - || !scm_is_string (default_value) || !scm_is_string (value) + || !(scm_is_null (default_value) || scm_is_string (default_value)) + || !(scm_is_null (value) || scm_is_string (value)) || !scm_is_integer (null_value_allowed) || !scm_is_string (function_check_value) || !scm_is_string (data_check_value) diff --git a/src/plugins/javascript/weechat-js-api.cpp b/src/plugins/javascript/weechat-js-api.cpp index 7acf0002a..caf992c5f 100644 --- a/src/plugins/javascript/weechat-js-api.cpp +++ b/src/plugins/javascript/weechat-js-api.cpp @@ -73,6 +73,8 @@ extern "C" for (num = 0; num < js_args_len; num++) \ { \ if (((js_args[num] == 's') && (!args[num]->IsString())) \ + || ((js_args[num] == 'S') && (!(args[num]->IsString() \ + || args[num]->IsNull() || args[num]->IsUndefined()))) \ || ((js_args[num] == 'i') && (!args[num]->IsInt32())) \ || ((js_args[num] == 'n') && (!args[num]->IsNumber())) \ || ((js_args[num] == 'h') && (!args[num]->IsObject()))) \ @@ -1188,9 +1190,10 @@ weechat_js_api_config_option_delete_cb (const void *pointer, void *data, API_FUNC(config_new_option) { int min, max, null_value_allowed; + char *default_value, *value; const char *result; - API_INIT_FUNC(1, "config_new_option", "ssssssiississssss", API_RETURN_EMPTY); + API_INIT_FUNC(1, "config_new_option", "ssssssiiSSissssss", API_RETURN_EMPTY); v8::String::Utf8Value config_file(args[0]); v8::String::Utf8Value section(args[1]); @@ -1200,8 +1203,19 @@ API_FUNC(config_new_option) v8::String::Utf8Value string_values(args[5]); min = args[6]->IntegerValue(); max = args[7]->IntegerValue(); - v8::String::Utf8Value default_value(args[8]); - v8::String::Utf8Value value(args[9]); + + v8::String::Utf8Value v8_default_value(args[8]); + if (args[8]->IsNull() || args[8]->IsUndefined()) + default_value = NULL; + else + default_value = *v8_default_value; + + v8::String::Utf8Value v8_value(args[9]); + if (args[8]->IsNull() || args[8]->IsUndefined()) + value = NULL; + else + value = *v8_value; + null_value_allowed = args[10]->IntegerValue(); v8::String::Utf8Value function_check_value(args[11]); v8::String::Utf8Value data_check_value(args[12]); @@ -1222,8 +1236,8 @@ API_FUNC(config_new_option) *string_values, min, max, - *default_value, - *value, + default_value, + value, null_value_allowed, &weechat_js_api_config_option_check_value_cb, *function_check_value, diff --git a/src/plugins/perl/weechat-perl-api.c b/src/plugins/perl/weechat-perl-api.c index 5112fbc50..27438b3ee 100644 --- a/src/plugins/perl/weechat-perl-api.c +++ b/src/plugins/perl/weechat-perl-api.c @@ -1259,8 +1259,8 @@ API_FUNC(config_new_option) type = SvPV_nolen (ST (3)); description = SvPV_nolen (ST (4)); string_values = SvPV_nolen (ST (5)); - default_value = SvPV_nolen (ST (8)); - value = SvPV_nolen (ST (9)); + default_value = SvOK (ST (8)) ? SvPV_nolen (ST (8)) : NULL; + value = SvOK (ST (9)) ? SvPV_nolen (ST (9)) : NULL; function_check_value = SvPV_nolen (ST (11)); data_check_value = SvPV_nolen (ST (12)); function_change = SvPV_nolen (ST (13)); diff --git a/src/plugins/php/weechat-php-api.c b/src/plugins/php/weechat-php-api.c index c48a6fec1..b92580b38 100644 --- a/src/plugins/php/weechat-php-api.c +++ b/src/plugins/php/weechat-php-api.c @@ -1295,7 +1295,7 @@ API_FUNC(config_new_option) API_INIT_FUNC(1, "config_new_option", API_RETURN_EMPTY); if (zend_parse_parameters ( - ZEND_NUM_ARGS(), "SSSSSSllSSlzSzSzS", &z_config_file, &z_section, + ZEND_NUM_ARGS(), "SSSSSSllS!S!lzSzSzS", &z_config_file, &z_section, &z_name, &z_type, &z_description, &z_string_values, &z_min, &z_max, &z_default_value, &z_value, &z_null_value_allowed, &z_callback_check_value, &z_data_check_value, &z_callback_change, @@ -1310,8 +1310,8 @@ API_FUNC(config_new_option) string_values = ZSTR_VAL(z_string_values); min = (int)z_min; max = (int)z_max; - default_value = ZSTR_VAL(z_default_value); - value = ZSTR_VAL(z_value); + default_value = z_default_value ? ZSTR_VAL(z_default_value) : NULL; + value = z_value ? ZSTR_VAL(z_value) : NULL; null_value_allowed = (int)z_null_value_allowed; weechat_php_get_function_name (z_callback_check_value, callback_check_value_name); diff --git a/src/plugins/python/weechat-python-api.c b/src/plugins/python/weechat-python-api.c index 0decc1f80..6398e7d2e 100644 --- a/src/plugins/python/weechat-python-api.c +++ b/src/plugins/python/weechat-python-api.c @@ -1255,7 +1255,7 @@ API_FUNC(config_new_option) data_change = NULL; function_delete = NULL; data_delete = NULL; - if (!PyArg_ParseTuple (args, "ssssssiississssss", &config_file, §ion, &name, + if (!PyArg_ParseTuple (args, "ssssssiizzissssss", &config_file, §ion, &name, &type, &description, &string_values, &min, &max, &default_value, &value, &null_value_allowed, &function_check_value, &data_check_value, diff --git a/src/plugins/python/weechat.pyi b/src/plugins/python/weechat.pyi index b180fced4..312a97a32 100644 --- a/src/plugins/python/weechat.pyi +++ b/src/plugins/python/weechat.pyi @@ -242,7 +242,7 @@ def config_search_section(config_file: str, section_name: str) -> str: def config_new_option(config_file: str, section: str, name: str, type: str, description: str, string_values: str, min: int, max: int, - default_value: str, value: str, null_value_allowed: int, + default_value: str | None, value: str | None, null_value_allowed: int, callback_check_value: str, callback_check_value_data: str, callback_change: str, callback_change_data: str, callback_delete: str, callback_delete_data: str) -> str: diff --git a/src/plugins/ruby/weechat-ruby-api.c b/src/plugins/ruby/weechat-ruby-api.c index 09aad9968..d1883f49f 100644 --- a/src/plugins/ruby/weechat-ruby-api.c +++ b/src/plugins/ruby/weechat-ruby-api.c @@ -1489,8 +1489,7 @@ weechat_ruby_api_config_new_option (VALUE class, VALUE config_file, API_INIT_FUNC(1, "config_new_option", API_RETURN_EMPTY); if (NIL_P (config_file) || NIL_P (section) || NIL_P (name) || NIL_P (type) || NIL_P (description) || NIL_P (string_values) || NIL_P (min) - || NIL_P (max) || NIL_P (default_value) || NIL_P (value) - || NIL_P (null_value_allowed) || NIL_P (callbacks)) + || NIL_P (max) || NIL_P (null_value_allowed) || NIL_P (callbacks)) API_WRONG_ARGS(API_RETURN_EMPTY); Check_Type (config_file, T_STRING); @@ -1501,8 +1500,10 @@ weechat_ruby_api_config_new_option (VALUE class, VALUE config_file, Check_Type (string_values, T_STRING); CHECK_INTEGER(min); CHECK_INTEGER(max); - Check_Type (default_value, T_STRING); - Check_Type (value, T_STRING); + if (!NIL_P (default_value)) + Check_Type (default_value, T_STRING); + if (!NIL_P (value)) + Check_Type (value, T_STRING); CHECK_INTEGER(null_value_allowed); Check_Type (callbacks, T_ARRAY); @@ -1528,8 +1529,8 @@ weechat_ruby_api_config_new_option (VALUE class, VALUE config_file, c_string_values = StringValuePtr (string_values); c_min = NUM2INT (min); c_max = NUM2INT (max); - c_default_value = StringValuePtr (default_value); - c_value = StringValuePtr (value); + c_default_value = NIL_P (default_value) ? NULL : StringValuePtr (default_value); + c_value = NIL_P (value) ? NULL : StringValuePtr (value); c_null_value_allowed = NUM2INT (null_value_allowed); c_function_check_value = StringValuePtr (function_check_value); c_data_check_value = StringValuePtr (data_check_value); diff --git a/src/plugins/tcl/weechat-tcl-api.c b/src/plugins/tcl/weechat-tcl-api.c index cff12283d..a82aa4725 100644 --- a/src/plugins/tcl/weechat-tcl-api.c +++ b/src/plugins/tcl/weechat-tcl-api.c @@ -35,6 +35,14 @@ #include "weechat-tcl.h" +/* Magic value to indicate NULL since Tcl only has string types. The value is + * \uFFFF\uFFFF\uFFFFWEECHAT_NULL\uFFFF\uFFFF\uFFFF. \uFFFF is used because + * it's reserved in Unicode as not a character, so this string is very unlikely + * to appear unintentionally since it's not valid text. */ +#define WEECHAT_NULL_STRING \ + "\xef\xbf\xbf\xef\xbf\xbf\xef\xbf\xbfWEECHAT_NULL\xef\xbf\xbf\xef\xbf\xbf\xef\xbf\xbf" + + #define API_DEF_FUNC(__name) \ Tcl_CreateObjCommand (interp, "weechat::" #__name, \ weechat_tcl_api_##__name, \ @@ -1461,7 +1469,11 @@ API_FUNC(config_new_option) description = Tcl_GetStringFromObj (objv[5], &i); string_values = Tcl_GetStringFromObj (objv[6], &i); default_value = Tcl_GetStringFromObj (objv[9], &i); + if (strcmp (default_value, WEECHAT_NULL_STRING) == 0) + default_value = NULL; value = Tcl_GetStringFromObj (objv[10], &i); + if (strcmp (value, WEECHAT_NULL_STRING) == 0) + value = NULL; function_check_value = Tcl_GetStringFromObj (objv[12], &i); data_check_value = Tcl_GetStringFromObj (objv[13], &i); function_change = Tcl_GetStringFromObj (objv[14], &i); @@ -5710,6 +5722,9 @@ void weechat_tcl_api_init (Tcl_Interp *interp) Tcl_SetIntObj (objp, WEECHAT_RC_ERROR); Tcl_SetVar (interp, "weechat::WEECHAT_RC_ERROR", Tcl_GetStringFromObj (objp, &i), 0); + Tcl_SetStringObj (objp, WEECHAT_NULL_STRING, -1); + Tcl_SetVar (interp, "weechat::WEECHAT_NULL", Tcl_GetStringFromObj (objp, &i), 0); + Tcl_SetIntObj (objp, WEECHAT_CONFIG_READ_OK); Tcl_SetVar (interp, "weechat::WEECHAT_CONFIG_READ_OK", Tcl_GetStringFromObj (objp, &i), 0); Tcl_SetIntObj (objp, WEECHAT_CONFIG_READ_MEMORY_ERROR); |