1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-12 14:14:48 +02:00

core: add range of chars in evaluation of expressions with chars:xxx

This commit is contained in:
Sébastien Helleu
2022-10-03 20:56:12 +02:00
parent bc2fb071e2
commit 196a051141
9 changed files with 357 additions and 127 deletions
+28 -4
View File
@@ -2349,7 +2349,7 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== string_eval_expression
_WeeChat ≥ 0.4.0, updated in 0.4.2, 0.4.3, 1.0, 1.1, 1.2, 1.3, 1.6, 1.8, 2.0,
2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6._
2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6, 3.8._
Evaluate an expression and return result as a string.
Special variables with format `+${variable}+` are expanded (see table below).
@@ -2734,20 +2734,44 @@ expanded to last):
>> `+${\ua9}+` +
== `+©+`
| `+${chars:range}+` | 3.8
| String with a range of chars, where `range` is one of: +
- `digit` (`0123456789`) +
- `xdigit` (`0123456789abcdefABCDEF`) +
- `lower` (all lower case letters) +
- `upper` (all upper case letters) +
- `alpha` (all letters) +
- `alnum` (all letters and digits) +
- a range of chars with format `c1-c2` (`c1` code point must be lower or equal to `c2`)
| >> `+${chars:digit}+` +
== `+0123456789+` +
+
>> `+${chars:xdigit}+` +
== `+0123456789abcdefABCDEF+` +
+
>> `+${chars:lower}+` +
== `+abcdefghijklmnopqrstuvwxyz+` +
+
>> `+${chars:J-V}+` +
== `+JKLMNOPQRSTUV+` +
+
>> `+${chars:←-↓}+` +
== `+←↑→↓+`
| `+${lower:string}+` | 3.6
| String converted to lower case.
| >> `+${lower:TEST}+` +
>> `+test+`
== `+test+`
| `+${upper:string}+` | 3.6
| String converted to upper case.
| >> `+${upper:test}+` +
>> `+TEST+`
== `+TEST+`
| `+${hide:x,string}+` | 1.1
| String with hidden chars (all chars in `string` replaced by `x`).
| >> `+${hide:*,password}+` +
>> `+********+`
== `+********+`
| `+${cut:max,suffix,string}+` +
`+${cut:+max,suffix,string}+` | 1.8
+28 -3
View File
@@ -2389,7 +2389,7 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== string_eval_expression
_WeeChat ≥ 0.4.0, mis à jour dans la 0.4.2, 0.4.3, 1.0, 1.1, 1.2, 1.3, 1.6, 1.8,
2.0, 2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6._
2.0, 2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6, 3.8._
Évaluer l'expression et retourner le résultat sous forme de chaîne.
Les variables spéciales avec le format `+${variable}+` sont étendues (voir le
@@ -2780,15 +2780,40 @@ première étendue à la dernière) :
>> `+${\ua9}+` +
== `+©+`
| `+${chars:range}+` | 3.8
| Chaîne avec un intervalle de caractères, où `range` est parmi : +
- `digit` (`0123456789`) +
- `xdigit` (`0123456789abcdefABCDEF`) +
- `lower` (toutes les lettres en minuscules) +
- `upper` (toutes les lettres en majuscules) +
- `alpha` (toutes les lettres) +
- `alnum` (toutes les lettres et chiffres) +
- un intervalle de caractères avec le format `c1-c2` (le code de `c1` doit
être inférieur ou égal à celui de `c2`)
| >> `+${chars:digit}+` +
== `+0123456789+` +
+
>> `+${chars:xdigit}+` +
== `+0123456789abcdefABCDEF+` +
+
>> `+${chars:lower}+` +
== `+abcdefghijklmnopqrstuvwxyz+` +
+
>> `+${chars:J-V}+` +
== `+JKLMNOPQRSTUV+` +
+
>> `+${chars:←-↓}+` +
== `+←↑→↓+`
| `+${lower:string}+` | 3.6
| Chaîne convertie en minuscules.
| >> `+${lower:TEST}+` +
>> `+test+`
== `+test+`
| `+${upper:string}+` | 3.6
| Chaîne convertie en majuscules.
| >> `+${upper:test}+` +
>> `+TEST+`
== `+TEST+`
| `+${hide:x,chaîne}+` | 1.1
| Chaîne avec les caractères masqués (tous les caractères dans `chaîne`
+28 -3
View File
@@ -2459,7 +2459,7 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== string_eval_expression
_WeeChat ≥ 0.4.0, updated in 0.4.2, 0.4.3, 1.0, 1.1, 1.2, 1.3, 1.6, 1.8, 2.0,
2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6._
2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6, 3.8._
Evaluate an expression and return result as a string.
Special variables with format `+${variable}+` are expanded (see table below).
@@ -2844,17 +2844,42 @@ expanded to last):
>> `+${\ua9}+` +
== `+©+`
// TRANSLATION MISSING
| `+${chars:range}+` | 3.8
| String with a range of chars, where `range` is one of: +
- `digit` (`0123456789`) +
- `xdigit` (`0123456789abcdefABCDEF`) +
- `lower` (all lower case letters) +
- `upper` (all upper case letters) +
- `alpha` (all letters) +
- `alnum` (all letters and digits) +
- a range of chars with format `c1-c2` (`c1` code point must be lower or equal to `c2`)
| >> `+${chars:digit}+` +
== `+0123456789+` +
+
>> `+${chars:xdigit}+` +
== `+0123456789abcdefABCDEF+` +
+
>> `+${chars:lower}+` +
== `+abcdefghijklmnopqrstuvwxyz+` +
+
>> `+${chars:J-V}+` +
== `+JKLMNOPQRSTUV+` +
+
>> `+${chars:←-↓}+` +
== `+←↑→↓+`
// TRANSLATION MISSING
| `+${lower:string}+` | 3.6
| String converted to lower case.
| >> `+${lower:TEST}+` +
>> `+test+`
== `+test+`
// TRANSLATION MISSING
| `+${upper:string}+` | 3.6
| String converted to upper case.
| >> `+${upper:test}+` +
>> `+TEST+`
== `+TEST+`
| `+${hide:x,string}+` | 1.1
| String with hidden chars (all chars in `string` replaced `x`).
+28 -3
View File
@@ -2382,7 +2382,7 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
// TRANSLATION MISSING
_WeeChat ≥ 0.4.0, updated in 0.4.2, 0.4.3, 1.0, 1.1, 1.2, 1.3, 1.6, 1.8, 2.0,
2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6._
2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6, 3.8._
式を評価して文字列として返す。`+${variable}+`
という書式で書かれた特殊変数は展開されます (以下の表を参照)。
@@ -2780,17 +2780,42 @@ str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, optio
>> `+${\ua9}+` +
== `+©+`
// TRANSLATION MISSING
| `+${chars:range}+` | 3.8
| String with a range of chars, where `range` is one of: +
- `digit` (`0123456789`) +
- `xdigit` (`0123456789abcdefABCDEF`) +
- `lower` (all lower case letters) +
- `upper` (all upper case letters) +
- `alpha` (all letters) +
- `alnum` (all letters and digits) +
- a range of chars with format `c1-c2` (`c1` code point must be lower or equal to `c2`)
| >> `+${chars:digit}+` +
== `+0123456789+` +
+
>> `+${chars:xdigit}+` +
== `+0123456789abcdefABCDEF+` +
+
>> `+${chars:lower}+` +
== `+abcdefghijklmnopqrstuvwxyz+` +
+
>> `+${chars:J-V}+` +
== `+JKLMNOPQRSTUV+` +
+
>> `+${chars:←-↓}+` +
== `+←↑→↓+`
// TRANSLATION MISSING
| `+${lower:string}+` | 3.6
| String converted to lower case.
| >> `+${lower:TEST}+` +
>> `+test+`
== `+test+`
// TRANSLATION MISSING
| `+${upper:string}+` | 3.6
| String converted to upper case.
| >> `+${upper:test}+` +
>> `+TEST+`
== `+TEST+`
| `+${hide:x,string}+` | 1.1
| 隠す文字を含むテキスト (`string` に含まれる文字をすべて `x` で置換)
+28 -3
View File
@@ -2261,7 +2261,7 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== string_eval_expression
_WeeChat ≥ 0.4.0, ажурирано у верзијама 0.4.2, 0.4.3, 1.0, 1.1, 1.2, 1.3, 1.6, 1.8, 2.0, 2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4 и 3.6._
_WeeChat ≥ 0.4.0, ажурирано у верзијама 0.4.2, 0.4.3, 1.0, 1.1, 1.2, 1.3, 1.6, 1.8, 2.0, 2.2, 2.3, 2.7, 2.9, 3.1, 3.2, 3.3, 3.4, 3.6 и 3.8._
Израчунава израз и враћа вредност као стринг. Специјалне променљиве у формату `+${променљива}+` се развијају (погледајте табелу испод).
@@ -2622,15 +2622,40 @@ str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, optio
>> `+${\ua9}+` +
== `+©+`
// TRANSLATION MISSING
| `+${chars:range}+` | 3.8
| String with a range of chars, where `range` is one of: +
- `digit` (`0123456789`) +
- `xdigit` (`0123456789abcdefABCDEF`) +
- `lower` (all lower case letters) +
- `upper` (all upper case letters) +
- `alpha` (all letters) +
- `alnum` (all letters and digits) +
- a range of chars with format `c1-c2` (`c1` code point must be lower or equal to `c2`)
| >> `+${chars:digit}+` +
== `+0123456789+` +
+
>> `+${chars:xdigit}+` +
== `+0123456789abcdefABCDEF+` +
+
>> `+${chars:lower}+` +
== `+abcdefghijklmnopqrstuvwxyz+` +
+
>> `+${chars:J-V}+` +
== `+JKLMNOPQRSTUV+` +
+
>> `+${chars:←-↓}+` +
== `+←↑→↓+`
| `+${lower:string}+` | 3.6
| Стринг конвертован у мала слова.
| >> `+${lower:TEST}+` +
>> `+test+`
== `+test+`
| `+${upper:string}+` | 3.6
| Стринг конвертован у велика слова.
| >> `+${upper:test}+` +
>> `+TEST+`
== `+TEST+`
| `+${hide:x,стринг}+` | 1.1
| Стринг са скривеним карактерима (сви карактери у `стринг` се замењују са `x`).
+33 -28
View File
@@ -7753,45 +7753,48 @@ command_init ()
"\n"
"Some variables are replaced in expression, using the format "
"${variable}, variable can be, by order of priority:\n"
" 1. the string itself without evaluation (format: \"raw:xxx\")\n"
" 2. a user-defined variable (format: \"name\")\n"
" 3. an evaluated sub-string (format: \"eval:xxx\")\n"
" 4. an evaluated condition (format: \"eval_cond:xxx\")\n"
" 5. a string with escaped chars (format: \"esc:xxx\" or \"\\xxx\")\n"
" 6. a string converted to lower case (format: \"lower:xxx\")\n"
" 7. a string converted to upper case (format: \"upper:xxx\")\n"
" 8. a string with chars to hide (format: \"hide:char,string\")\n"
" 9. a string with max chars (format: \"cut:max,suffix,string\" "
" - the string itself without evaluation (format: \"raw:xxx\")\n"
" - a user-defined variable (format: \"name\")\n"
" - an evaluated sub-string (format: \"eval:xxx\")\n"
" - an evaluated condition (format: \"eval_cond:xxx\")\n"
" - a string with escaped chars (format: \"esc:xxx\" or \"\\xxx\")\n"
" - a string with a range of chars (format: \"chars:xxx\" or "
"\"chars:c1-c2\" where \"xxx\" is one of: \"digit\", \"xdigit\", "
"\"lower\", \"upper\", \"alpha\", \"alnum\")\n"
" - a string converted to lower case (format: \"lower:xxx\")\n"
" - a string converted to upper case (format: \"upper:xxx\")\n"
" - a string with chars to hide (format: \"hide:char,string\")\n"
" - a string with max chars (format: \"cut:max,suffix,string\" "
"or \"cut:+max,suffix,string\")\n"
" or max chars displayed on screen "
"(format: \"cutscr:max,suffix,string\" or "
"\"cutscr:+max,suffix,string\")\n"
" 10. a reversed string (format: \"rev:xxx\" or \"revscr:xxx\")\n"
" 11. a repeated string (format: \"repeat:count,string\")\n"
" 12. length of a string (format: \"length:xxx\" or "
" - a reversed string (format: \"rev:xxx\" or \"revscr:xxx\")\n"
" - a repeated string (format: \"repeat:count,string\")\n"
" - length of a string (format: \"length:xxx\" or "
"\"lengthscr:xxx\")\n"
" 13. split of a string (format: "
" - split of a string (format: "
"\"split:number,separators,flags,xxx\")\n"
" 14. split of shell argmuents (format: \"split_shell:number,xxx\")\n"
" 15. a color (format: \"color:xxx\", see \"Plugin API "
" - split of shell argmuents (format: \"split_shell:number,xxx\")\n"
" - a color (format: \"color:xxx\", see \"Plugin API "
"reference\", function \"color\")\n"
" 16. a modifier (format: \"modifier:name,data,string\")\n"
" 17. an info (format: \"info:name,arguments\", arguments are "
" - a modifier (format: \"modifier:name,data,string\")\n"
" - an info (format: \"info:name,arguments\", arguments are "
"optional)\n"
" 18. a base 16/32/64 encoded/decoded string (format: "
" - a base 16/32/64 encoded/decoded string (format: "
"\"base_encode:base,xxx\" or \"base_decode:base,xxx\")\n"
" 19. current date/time (format: \"date\" or \"date:format\")\n"
" 20. an environment variable (format: \"env:XXX\")\n"
" 21. a ternary operator (format: "
" - current date/time (format: \"date\" or \"date:format\")\n"
" - an environment variable (format: \"env:XXX\")\n"
" - a ternary operator (format: "
"\"if:condition?value_if_true:value_if_false\")\n"
" 22. result of an expression with parentheses and operators "
" - result of an expression with parentheses and operators "
"+ - * / // % ** (format: \"calc:xxx\")\n"
" 23. a random integer number (format: \"random:min,max\")\n"
" 24. a translated string (format: \"translate:xxx\")\n"
" 25. define a user variable (format: \"define:name,value\")\n"
" 26. an option (format: \"file.section.option\")\n"
" 27. a local variable in buffer\n"
" 28. a hdata name/variable (the value is automatically converted "
" - a random integer number (format: \"random:min,max\")\n"
" - a translated string (format: \"translate:xxx\")\n"
" - define a user variable (format: \"define:name,value\")\n"
" - an option (format: \"file.section.option\")\n"
" - a local variable in buffer\n"
" - 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"
@@ -7824,6 +7827,8 @@ command_init ()
" /eval -n ${window.buffer.full_name} ==> core.weechat\n"
" /eval -n ${window.buffer.number} ==> 1\n"
" /eval -n ${\\t} ==> <tab>\n"
" /eval -n ${chars:digit} ==> 0123456789\n"
" /eval -n ${chars:J-T} ==> JKLMNOPQRST\n"
" /eval -n ${lower:TEST} ==> test\n"
" /eval -n ${upper:test} ==> TEST\n"
" /eval -n ${hide:-,${relay.network.password}} ==> --------\n"
+158 -83
View File
@@ -63,10 +63,10 @@
}
char *logical_ops[EVAL_NUM_LOGICAL_OPS] =
char *eval_logical_ops[EVAL_NUM_LOGICAL_OPS] =
{ "||", "&&" };
char *comparisons[EVAL_NUM_COMPARISONS] =
char *eval_comparisons[EVAL_NUM_COMPARISONS] =
{ "=~", "!~", /* regex */
"==*", "!!*", "=*", "!*", /* string match */
"==-", "!!-", "=-", "!-", /* includes */
@@ -74,6 +74,16 @@ char *comparisons[EVAL_NUM_COMPARISONS] =
"<=", "<", ">=", ">", /* less than, greater than */
};
char *eval_range_chars[][2] =
{
{ "digit", EVAL_RANGE_DIGIT },
{ "xdigit", EVAL_RANGE_XDIGIT },
{ "lower", EVAL_RANGE_LOWER },
{ "upper", EVAL_RANGE_UPPER },
{ "alpha", EVAL_RANGE_ALPHA },
{ "alnum", EVAL_RANGE_ALNUM },
{ NULL, NULL },
};
char *eval_replace_vars (const char *expr,
struct t_eval_context *eval_context);
@@ -273,6 +283,65 @@ eval_string_eval_cond (const char *text, struct t_eval_context *eval_context)
return strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
}
/*
* Adds range of chars.
*
* Note: result must be freed after use.
*/
char *
eval_string_range_chars (const char *range)
{
int i, char1, char2;
const char *ptr_char;
char **string, str_char[16], *result;
string = NULL;
result = NULL;
for (i = 0; eval_range_chars[i][0]; i++)
{
if (strcmp (range, eval_range_chars[i][0]) == 0)
return strdup (eval_range_chars[i][1]);
}
char1 = utf8_char_int (range);
/* next char must be '-' */
ptr_char = utf8_next_char (range);
if (!ptr_char || !ptr_char[0] || (ptr_char[0] != '-'))
goto end;
/* next char is the char2 */
ptr_char = utf8_next_char (ptr_char);
if (!ptr_char || !ptr_char[0])
goto end;
char2 = utf8_char_int (ptr_char);
/* output is limited to 1024 chars (not bytes) */
if ((char1 > char2) || (char2 - char1 + 1 > 4096))
goto end;
string = string_dyn_alloc (128);
if (!string)
goto end;
for (i = char1; i <= char2; i++)
{
utf8_int_string (i, str_char);
string_dyn_concat (string, str_char, -1);
}
end:
if (string)
{
result = *string;
string_dyn_free (string, 0);
}
return (result) ? result : strdup ("");
}
/*
* Converts string to lower case.
*
@@ -1414,48 +1483,49 @@ end:
/*
* Replaces variables, which can be, by order of priority:
* 1. the string itself without evaluation (format: raw:xxx)
* 2. a variable from hashtable "user_vars" or "extra_vars"
* 3. a WeeChat home directory, one of: "weechat_config_dir",
* "weechat_data_dir", "weechat_cache_dir", "weechat_runtime_dir"
* 4. a string to evaluate (format: eval:xxx)
* 5. a condition to evaluate (format: eval_cond:xxx)
* 6. a string with escaped chars (format: esc:xxx or \xxx)
* 7. a string converted to lower case (format: lower:xxx)
* 8. a string converted to upper case (format: upper:xxx)
* 9. a string with chars to hide (format: hide:char,string)
* 10. a string with max chars (format: cut:max,suffix,string or
* cut:+max,suffix,string) or max chars on screen
* (format: cutscr:max,suffix,string or cutscr:+max,suffix,string)
* 11. a reversed string (format: rev:xxx) or reversed string for screen,
* color codes are not reversed (format: revscr:xxx)
* 12. a repeated string (format: repeat:count,string)
* 13. length of a string (format: length:xxx) or length of a string on screen
* (format: lengthscr:xxx); color codes are ignored
* 14. split string (format: split:number,separators,flags,xxx
* or split:count,separators,flags,xxx
* or split:random,separators,flags,xxx)
* 15. split shell arguments (format: split:number,xxx or split:count,xxx
* or split:random,xxx)
* 16. a regex group captured (format: re:N (0.99) or re:+)
* 17. a color (format: color:xxx)
* 18. a modifier (format: modifier:name,data,xxx)
* 19. an info (format: info:name,arguments)
* 20. a base 16/32/64 encoded/decoded string (format: base_encode:base,xxx
* or base_decode:base,xxx)
* 21. current date/time (format: date or date:xxx)
* 22. an environment variable (format: env:XXX)
* 23. a ternary operator (format: if:condition?value_if_true:value_if_false)
* 24. calculate result of an expression (format: calc:xxx)
* 25. a random integer number in the range from "min" to "max"
* (format: random:min,max)
* 26. a translated string (format: translate:xxx)
* 27. define a new variable (format: define:name,value)
* 28. an option (format: file.section.option)
* 29. a buffer local variable
* 30. a pointer name from hashtable "pointers"
* 31. a hdata variable (format: hdata.var1.var2 or hdata[list].var1.var2
* or hdata[ptr].var1.var2 or hdata[ptr_name].var1.var2)
* - the string itself without evaluation (format: raw:xxx)
* - a variable from hashtable "user_vars" or "extra_vars"
* - a WeeChat home directory, one of: "weechat_config_dir",
* "weechat_data_dir", "weechat_cache_dir", "weechat_runtime_dir"
* - a string to evaluate (format: eval:xxx)
* - a condition to evaluate (format: eval_cond:xxx)
* - a string with escaped chars (format: esc:xxx or \xxx)
* - a string with a range of chars (format: chars:xxx)
* - a string converted to lower case (format: lower:xxx)
* - a string converted to upper case (format: upper:xxx)
* - a string with chars to hide (format: hide:char,string)
* - a string with max chars (format: cut:max,suffix,string or
* cut:+max,suffix,string) or max chars on screen
* (format: cutscr:max,suffix,string or cutscr:+max,suffix,string)
* - a reversed string (format: rev:xxx) or reversed string for screen,
* color codes are not reversed (format: revscr:xxx)
* - a repeated string (format: repeat:count,string)
* - length of a string (format: length:xxx) or length of a string on screen
* (format: lengthscr:xxx); color codes are ignored
* - split string (format: split:number,separators,flags,xxx
* or split:count,separators,flags,xxx
* or split:random,separators,flags,xxx)
* - split shell arguments (format: split:number,xxx or split:count,xxx
* or split:random,xxx)
* - a regex group captured (format: re:N (0.99) or re:+)
* - a color (format: color:xxx)
* - a modifier (format: modifier:name,data,xxx)
* - an info (format: info:name,arguments)
* - a base 16/32/64 encoded/decoded string (format: base_encode:base,xxx
* or base_decode:base,xxx)
* - current date/time (format: date or date:xxx)
* - an environment variable (format: env:XXX)
* - a ternary operator (format: if:condition?value_if_true:value_if_false)
* - calculate result of an expression (format: calc:xxx)
* - a random integer number in the range from "min" to "max"
* (format: random:min,max)
* - a translated string (format: translate:xxx)
* - define a new variable (format: define:name,value)
* - an option (format: file.section.option)
* - a buffer local variable
* - a pointer name from hashtable "pointers"
* - 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.
*
@@ -1478,16 +1548,14 @@ eval_replace_vars_cb (void *data, const char *text)
EVAL_DEBUG_MSG(1, "eval_replace_vars_cb(\"%s\")", text);
/*
* 1. raw text (no evaluation at all)
*/
/* raw text (no evaluation at all) */
if (strncmp (text, "raw:", 4) == 0)
{
value = strdup (text + 4);
goto end;
}
/* 2. variable in hashtable "user_vars" or "extra_vars" */
/* variable in hashtable "user_vars" or "extra_vars" */
ptr_value = hashtable_get (eval_context->user_vars, text);
if (ptr_value)
{
@@ -1518,7 +1586,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
}
/* 3. WeeChat home directory */
/* WeeChat home directory */
if (strcmp (text, "weechat_config_dir") == 0)
{
value = strdup (weechat_config_dir);
@@ -1541,8 +1609,8 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 4. force evaluation of string (recursive call)
* --> use with caution: the text must be safe!
* force evaluation of string (recursive call)
* --> use with caution: the text must be safe!
*/
if (strncmp (text, "eval:", 5) == 0)
{
@@ -1551,8 +1619,8 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 5. force evaluation of condition (recursive call)
* --> use with caution: the text must be safe!
* force evaluation of condition (recursive call)
* --> use with caution: the text must be safe!
*/
if (strncmp (text, "eval_cond:", 10) == 0)
{
@@ -1560,7 +1628,7 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 6. convert escaped chars */
/* convert escaped chars */
if (strncmp (text, "esc:", 4) == 0)
{
value = string_convert_escaped_chars (text + 4);
@@ -1572,21 +1640,28 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 7. convert to lower case */
/* range of chars */
if (strncmp (text, "chars:", 6) == 0)
{
value = eval_string_range_chars (text + 6);
goto end;
}
/* convert to lower case */
if (strncmp (text, "lower:", 6) == 0)
{
value = eval_string_lower (text + 6);
goto end;
}
/* 8. convert to upper case */
/* convert to upper case */
if (strncmp (text, "upper:", 6) == 0)
{
value = eval_string_upper (text + 6);
goto end;
}
/* 9. hide chars: replace all chars by a given char/string */
/* hide chars: replace all chars by a given char/string */
if (strncmp (text, "hide:", 5) == 0)
{
value = eval_string_hide (text + 5);
@@ -1594,7 +1669,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 10. cut chars:
* cut chars:
* cut: max number of chars, and add an optional suffix when the
* string is cut
* cutscr: max number of chars displayed on screen, and add an optional
@@ -1611,7 +1686,7 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 11. reverse string */
/* reverse string */
if (strncmp (text, "rev:", 4) == 0)
{
value = string_reverse (text + 4);
@@ -1623,7 +1698,7 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 12. repeated string */
/* repeated string */
if (strncmp (text, "repeat:", 7) == 0)
{
value = eval_string_repeat (text + 7);
@@ -1631,7 +1706,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 13. length of string:
* length of string:
* length: number of chars
* lengthscr: number of chars displayed on screen
*/
@@ -1650,49 +1725,49 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 14: split string */
/* split string */
if (strncmp (text, "split:", 6) == 0)
{
value = eval_string_split (text + 6);
goto end;
}
/* 15: split shell */
/* split shell */
if (strncmp (text, "split_shell:", 12) == 0)
{
value = eval_string_split_shell (text + 12);
goto end;
}
/* 16. regex group captured */
/* regex group captured */
if (strncmp (text, "re:", 3) == 0)
{
value = eval_string_regex_group (text + 3, eval_context);
goto end;
}
/* 17. color code */
/* color code */
if (strncmp (text, "color:", 6) == 0)
{
value = eval_string_color (text + 6);
goto end;
}
/* 18. modifier */
/* modifier */
if (strncmp (text, "modifier:", 9) == 0)
{
value = eval_string_modifier (text + 9);
goto end;
}
/* 19. info */
/* info */
if (strncmp (text, "info:", 5) == 0)
{
value = eval_string_info (text + 5);
goto end;
}
/* 20. base_encode/base_decode */
/* base_encode/base_decode */
if (strncmp (text, "base_encode:", 12) == 0)
{
value = eval_string_base_encode (text + 12);
@@ -1704,14 +1779,14 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 21. current date/time */
/* current date/time */
if ((strncmp (text, "date", 4) == 0) && (!text[4] || (text[4] == ':')))
{
value = eval_string_date (text + 4);
goto end;
}
/* 22. environment variable */
/* environment variable */
if (strncmp (text, "env:", 4) == 0)
{
ptr_value = getenv (text + 4);
@@ -1719,7 +1794,7 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 23: ternary operator: if:condition?value_if_true:value_if_false */
/* ternary operator: if:condition?value_if_true:value_if_false */
if (strncmp (text, "if:", 3) == 0)
{
value = eval_string_if (text + 3, eval_context);
@@ -1727,7 +1802,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 24. calculate the result of an expression
* calculate the result of an expression
* (with number, operators and parentheses)
*/
if (strncmp (text, "calc:", 5) == 0)
@@ -1737,7 +1812,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 25. random number
* random number
*/
if (strncmp (text, "random:", 7) == 0)
{
@@ -1746,7 +1821,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
/*
* 26. translated text
* translated text
*/
if (strncmp (text, "translate:", 10) == 0)
{
@@ -1754,7 +1829,7 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 27. define a variable */
/* define a variable */
if (strncmp (text, "define:", 7) == 0)
{
eval_string_define (text + 7, eval_context);
@@ -1762,7 +1837,7 @@ eval_replace_vars_cb (void *data, const char *text)
goto end;
}
/* 28. option: if found, return this value */
/* option: if found, return this value */
if (strncmp (text, "sec.data.", 9) == 0)
{
ptr_value = hashtable_get (secure_hashtable_data, text + 9);
@@ -1805,7 +1880,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
}
/* 29. local variable in buffer */
/* local variable in buffer */
ptr_buffer = hashtable_get (eval_context->pointers, "buffer");
if (ptr_buffer)
{
@@ -1817,7 +1892,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
}
/* 30. hdata */
/* hdata */
value = eval_string_hdata (text, eval_context);
end:
@@ -1889,7 +1964,7 @@ eval_compare (const char *expr1, int comparison, const char *expr2,
char *error, *value;
EVAL_DEBUG_MSG(1, "eval_compare(\"%s\", \"%s\", \"%s\")",
expr1, comparisons[comparison], expr2);
expr1, eval_comparisons[comparison], expr2);
rc = 0;
string_compare = 0;
@@ -2070,7 +2145,7 @@ eval_expression_condition (const char *expr,
*/
for (logic = 0; logic < EVAL_NUM_LOGICAL_OPS; logic++)
{
pos = eval_strstr_level (expr2, logical_ops[logic], eval_context,
pos = eval_strstr_level (expr2, eval_logical_ops[logic], eval_context,
"(", ")", 0);
if (pos > expr2)
{
@@ -2097,7 +2172,7 @@ eval_expression_condition (const char *expr,
value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
goto end;
}
pos += strlen (logical_ops[logic]);
pos += strlen (eval_logical_ops[logic]);
while (pos[0] == ' ')
{
pos++;
@@ -2120,7 +2195,7 @@ eval_expression_condition (const char *expr,
*/
for (comp = 0; comp < EVAL_NUM_COMPARISONS; comp++)
{
pos = eval_strstr_level (expr2, comparisons[comp], eval_context,
pos = eval_strstr_level (expr2, eval_comparisons[comp], eval_context,
"(", ")", 0);
if (pos >= expr2)
{
@@ -2139,7 +2214,7 @@ eval_expression_condition (const char *expr,
}
if (!sub_expr)
goto end;
pos += strlen (comparisons[comp]);
pos += strlen (eval_comparisons[comp]);
while (pos[0] == ' ')
{
pos++;
+7
View File
@@ -30,6 +30,13 @@
#define EVAL_RECURSION_MAX 32
#define EVAL_RANGE_DIGIT "0123456789"
#define EVAL_RANGE_XDIGIT EVAL_RANGE_DIGIT "abcdefABCDEF"
#define EVAL_RANGE_LOWER "abcdefghijklmnopqrstuvwxyz"
#define EVAL_RANGE_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define EVAL_RANGE_ALPHA EVAL_RANGE_LOWER EVAL_RANGE_UPPER
#define EVAL_RANGE_ALNUM EVAL_RANGE_ALPHA EVAL_RANGE_DIGIT
struct t_hashtable;
enum t_eval_logical_op
+19
View File
@@ -516,6 +516,25 @@ TEST(CoreEval, EvalExpression)
WEE_CHECK_EVAL("\t", "${\\t}");
WEE_CHECK_EVAL("\t", "${esc:\t}");
/* test range of chars */
WEE_CHECK_EVAL("0123456789", "${chars:digit}");
WEE_CHECK_EVAL("0123456789abcdefABCDEF", "${chars:xdigit}");
WEE_CHECK_EVAL("abcdefghijklmnopqrstuvwxyz", "${chars:lower}");
WEE_CHECK_EVAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "${chars:upper}");
WEE_CHECK_EVAL("abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "${chars:alpha}");
WEE_CHECK_EVAL("abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789", "${chars:alnum}");
WEE_CHECK_EVAL("0123456789", "${chars:0-9}");
WEE_CHECK_EVAL("abcdefgh", "${chars:a-h}");
WEE_CHECK_EVAL("JKLMNOPQRSTUV", "${chars:J-V}");
WEE_CHECK_EVAL("é", "${chars:é-é}");
WEE_CHECK_EVAL("àáâãäåæçèé", "${chars:à-é}");
WEE_CHECK_EVAL("←↑→↓", "${chars:←-↓}"); /* U+2190 - U+2193 */
WEE_CHECK_EVAL("▁▂▃▄▅▆▇█▉▊▋▌▍▎▏", "${chars:▁-▏}"); /* U+2581 - U+258F */
WEE_CHECK_EVAL("", "${chars:Z-A}"); /* invalid (reverse) */
/* test case conversion: to lower case */
WEE_CHECK_EVAL("", "${lower:}");
WEE_CHECK_EVAL("this is a test", "${lower:This is a TEST}");