api: add regex replace feature in function string_eval_expression

v2.8-utf8proc
Sébastien Helleu 2014-10-22 21:19:54 +02:00
parent 972bd26e5e
commit 633a32ccd3
8 changed files with 927 additions and 174 deletions

View File

@ -23,6 +23,7 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
of status bar
* core: allow incomplete commands if unambiguous, new option
weechat.look.command_incomplete (task #5419)
* api: add regex replace feature in function string_eval_expression
* api: use microseconds instead of milliseconds in functions util_timeval_diff
and util_timeval_add
* irc: display own nick changes in server buffer (closes #188)

View File

@ -1826,11 +1826,10 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== weechat_string_eval_expression
_WeeChat ≥ 0.4.0, updated in 0.4.2._
_WeeChat ≥ 0.4.0, updated in 0.4.2 and 1.1._
Evaluate an expression and return result as a string.
Special variables with format `${variable}` are expanded (see command `/eval` in
'WeeChat User's guide').
Special variables with format `${variable}` are expanded (see table below).
[NOTE]
Since version 1.0, nested variables are supported, for example:
@ -1848,10 +1847,14 @@ char *weechat_string_eval_expression (const char *expr,
Arguments:
* 'expr': the expression to evaluate
* 'expr': the expression to evaluate (see table below)
* 'pointers': hashtable with pointers (keys must be string, values must be
pointer); pointers "window" and "buffer" are automatically added if they are
not in hashtable (with pointer to current window/buffer) (can be NULL)
not in hashtable (with pointer to current window/buffer) (can be NULL):
** 'regex': pointer to a regular expression ('regex_t' structure) compiled with
WeeChat function <<_weechat_string_regcomp,weechat_string_regcomp>> or
regcomp (see `man regcomp`); this option is similar to 'regex' in hashtable
'options' (below), but is used for better performance
* 'extra_vars': extra variables that will be expanded (can be NULL)
* 'options': a hashtable with some options (keys and values must be string)
(can be NULL):
@ -1861,26 +1864,118 @@ Arguments:
parentheses are used, result is a boolean ("0" or "1")
** 'prefix': prefix before variables to replace (default: "${")
** 'suffix': suffix after variables to replace (default: "}")
** 'regex': a regex used to replace text in 'expr' (which is then not
evaluated)
** 'regex_replace': the replacement text to use with 'regex', to replace
text in 'expr' (the 'regex_replace' is evaluated on each match of 'regex'
against 'expr', until no match is found)
Return value:
* evaluated expression (must be freed by calling "free" after use), or NULL
if problem (invalid expression or not enough memory)
List of variables expanded in expression (by order of priority, from first
expanded to last):
[width="100%",cols="2,8,3,3",options="header"]
|===
| Format | Description | Examples | Results
| `${name}` | Variable `name` from hashtable 'extra_vars' |
`${name}` | `value`
| `${esc:xxx}` +
`${\xxx}` | String with escaped chars |
`${esc:prefix\tmessage}` +
`${\ua9}` |
`prefix<TAB>message` +
`©`
| `${hide:x,value}` |
String with hidden chars (all chars in `value` replaced `x`) |
`${hide:*,password}` |
`********`
| `${re:N}` |
Regex captured group: 0 = whole string matching, 1 to 99 = group captured,
`+` = last group captured |
`${re:1}` |
`test`
| `${color:name}` |
WeeChat color code (the name of color has optional attributes) |
`${color:red}red text` +
`${color:*214}bold orange text` |
`red text` (in red) +
`bold orange text` (in bold orange)
| `${info:name}` +
`${indo:name,arguments}` |
Info from WeeChat or a plugin, see function
<<_weechat_info_get,weechat_info_get>> |
`${info:version}` +
`${info:irc_nick_color_name,foo}` |
`1.0` +
`lightblue`
| `${sec.data.name}` |
Value of the secured data `name` |
`${sec.data.freenode_pass}` |
`my_password`
| `${file.section.option}` |
Value of the option |
`${weechat.look.buffer_time_format}` |
`%H:%M:%S`
| `${name}` |
Value of local variable `name` in buffer |
`${nick}` |
`FlashCode`
| `${hdata.var1.var2...}` +
`${hdata[list].var1.var2...}` |
Hdata value (pointers `window` and `buffer` are set by default with current
window/buffer) |
`${buffer[gui_buffers].full_name}` +
`${window.buffer.number}` |
`core.weechat` +
`1`
|===
C examples:
[source,C]
----
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options)
weechat_hashtable_set (options, "type", "condition");
char *str1 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
char *str2 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options); /* "1" */
char *str3 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options); /* "0" */
/* conditions */
struct t_hashtable *options1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
weechat_hashtable_set (options1, "type", "condition");
char *str1 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options1); /* "1" */
char *str2 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options1); /* "0" */
/* simple expression */
char *str3 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
/* replace with regex */
struct t_hashtable *options2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
/* add brackets around URLs */
weechat_hashtable_set (options2, "regex", "\\w+://\\S+");
weechat_hashtable_set (options2, "regex_replace", "[ ${re:0} ]");
char *str4 = weechat_string_eval_expression ("test: http://weechat.org", NULL, NULL, NULL); /* "test: [ http://weechat.org ]" */
/* hide passwords */
weechat_hashtable_set (options2, "regex", "(password=)(\\S+)");
weechat_hashtable_set (options2, "regex_replace", "${re:1}${hide:*,${re:2}}");
char *str5 = weechat_string_eval_expression ("password=abc password=def", NULL, NULL, NULL); /* "password=*** password=***" */
----
Script (Python):
@ -1891,9 +1986,27 @@ Script (Python):
str = weechat.string_eval_expression(expr, pointers, extra_vars, options)
# examples
str1 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
str2 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str3 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# conditions
str1 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str2 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# simple expression
str3 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
# replace with regex: add brackets around URLs
options = {
"regex": "\\w+://\\S+",
"regex_replace": "[ ${re:0} ]",
}
str4 = weechat.string_eval_expression("test: http://weechat.org", {}, {}, options) # "test: [ http://weechat.org ]"
# replace with regex: hide passwords
options = {
"regex": "(password=)(\\S+)",
"regex_replace": "${re:1}${hide:*,${re:2}}",
}
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
----
[[utf-8]]

View File

@ -1858,11 +1858,11 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== weechat_string_eval_expression
_WeeChat ≥ 0.4.0, mis à jour dans la 0.4.2._
_WeeChat ≥ 0.4.0, mis à jour dans la 0.4.2 et 1.1._
Évaluer l'expression et retourner le résultat sous forme de chaîne.
Les variables spéciales avec le format `${variable}` sont étendues (voir la
commande `/eval` dans le 'Guide utilisateur WeeChat').
Les variables spéciales avec le format `${variable}` sont étendues (voir le
tableau ci-dessous).
[NOTE]
Depuis la version 1.0, les variables imbriquées sont supportées, par exemple :
@ -1880,11 +1880,17 @@ char *weechat_string_eval_expression (const char *expr,
Paramètres :
* 'expr' : l'expression à évaluer
* 'expr' : l'expression à évaluer (voir le tableau ci-dessous)
* 'pointers' : table de hachage avec les pointeurs (les clés doivent être des
chaînes, les valeurs doivent être des pointeurs); les pointeurs "window" et
"buffer" sont automatiquement ajoutés s'ils ne sont pas dans la table de
hachage (avec le pointer vers fenêtre/tampon courants) (peut être NULL)
hachage (avec le pointer vers fenêtre/tampon courants) (peut être NULL) :
** 'regex' : pointeur vers une expression régulière (structure 'regex_t')
compilée avec la fonction WeeChat
<<_weechat_string_regcomp,weechat_string_regcomp>> ou regcomp (voir
`man regcomp`) ; cette option est similaire à 'regex' dans la table de
hachage 'options' (ci-dessous), mais est utilisée pour de meilleures
performances
* 'extra_vars' : variables additionnelles qui seront étendues (peut être NULL)
* 'options' : table de hachage avec des options (les clés et valeurs doivent
être des chaînes) (peut être NULL) :
@ -1894,6 +1900,12 @@ Paramètres :
et parenthèses sont utilisés, le résultat est un booléen ("0" ou "1")
** 'prefix' : préfixe avant les variables à remplacer (par défaut : "${")
** 'suffix' : suffixe après les variables à remplacer (par défaut : "}")
** 'regex' : une expression regulière pour remplacer du texte dans 'expr' (qui
n'est alors pas évalué)
** 'regex_replace' : le texte de remplacement à utiliser avec 'regex', pour
remplacer du texte dans 'expr' ('regex_replace' est évalué sur chaque
correspondance de 'regex' sur 'expr', jusqu'à ce que plus aucune
correspondance ne soit trouvée)
Valeur de retour :
@ -1901,20 +1913,108 @@ Valeur de retour :
utilisation), ou NULL si problème (expression invalide ou pas assez de
mémoire)
Liste des variables étendues dans l'expression (par ordre de priorité, de la
première étendue à la dernière) :
[width="100%",cols="2,8,3,3",options="header"]
|===
| Format | Description | Exemples | Résultats
| `${nom}` | Variable `nom` de la table de hachage 'extra_vars' |
`${nom}` | `valeur`
| `${esc:xxx}` +
`${\xxx}` | Chaîne avec caractères échappés |
`${esc:préfixe\tmessage}` +
`${\ua9}` |
`préfixe<TAB>message` +
`©`
| `${hide:x,valeur}` |
Chaîne avec les caractères masqués (tous les caractères dans `valeur`
remplacés par `x` |
`${hide:*,mot_de_passe}` |
`************`
| `${re:N}` |
Groupe regex capturé : 0 = toute la chaîne correspondante, 1 à 99 = groupe
capturé, `+` = dernier groupe capturé |
`${re:1}` |
`test`
| `${color:nom}` |
Code couleur WeeChat (le nom de couleur a des attributs facultatifs) |
`${color:red}texte rouge` +
`${color:*214}texte orange gras` |
`texte rouge` (en rouge) +
`texte orange gras` (en orange gras)
| `${info:name}` +
`${indo:name,arguments}` |
Info de WeeChat ou d'une extension, voir la fonction
<<_weechat_info_get,weechat_info_get>> |
`${info:version}` +
`${info:irc_nick_color_name,foo}` |
`1.0` +
`lightblue`
| `${sec.data.nom}` |
Valeur de la donnée sécurisée `nom` |
`${sec.data.freenode_pass}` |
`mon_mot_de_passe`
| `${file.section.option}` |
Valeur de l'option |
`${weechat.look.buffer_time_format}` |
`%H:%M:%S`
| `${nom}` |
Valeur de la variable locale `nom` dans le tampon |
`${nick}` |
`FlashCode`
| `${hdata.var1.var2...}` +
`${hdata[list].var1.var2...}` |
Valeur d'un hdata (les pointeurs `window` et `buffer` sont définis par défaut
avec la fenêtre et tampon courants) |
`${buffer[gui_buffers].full_name}` +
`${window.buffer.number}` |
`core.weechat` +
`1`
|===
Exemples en C :
[source,C]
----
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options)
weechat_hashtable_set (options, "type", "condition");
char *str1 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
char *str2 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options); /* "1" */
char *str3 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options); /* "0" */
/* conditions */
struct t_hashtable *options1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
weechat_hashtable_set (options1, "type", "condition");
char *str1 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options1); /* "1" */
char *str2 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options1); /* "0" */
/* expression simple */
char *str3 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
/* remplacement avec regex */
struct t_hashtable *options2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
/* ajout de crochets autour des URLs */
weechat_hashtable_set (options2, "regex", "\\w+://\\S+");
weechat_hashtable_set (options2, "regex_replace", "[ ${re:0} ]");
char *str4 = weechat_string_eval_expression ("test: http://weechat.org", NULL, NULL, NULL); /* "test: [ http://weechat.org ]" */
/* masquage des mots de passe */
weechat_hashtable_set (options2, "regex", "(password=)(\\S+)");
weechat_hashtable_set (options2, "regex_replace", "${re:1}${hide:*,${re:2}}");
char *str5 = weechat_string_eval_expression ("password=abc password=def", NULL, NULL, NULL); /* "password=*** password=***" */
----
Script (Python) :
@ -1925,9 +2025,27 @@ Script (Python) :
str = weechat.string_eval_expression(expr, pointers, extra_vars, options)
# exemples
str1 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
str2 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str3 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# conditions
str1 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str2 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# expression simple
str3 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
# remplacement avec regex : ajout de crochets autour des URLs
options = {
"regex": "\\w+://\\S+",
"regex_replace": "[ ${re:0} ]",
}
str4 = weechat.string_eval_expression("test: http://weechat.org", {}, {}, options) # "test: [ http://weechat.org ]"
# replace with regex : masquage des mots de passe
options = {
"regex": "(password=)(\\S+)",
"regex_replace": "${re:1}${hide:*,${re:2}}",
}
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
----
[[utf-8]]

View File

@ -1879,12 +1879,11 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== weechat_string_eval_expression
// TRANSLATION MISSING
_WeeChat ≥ 0.4.0, updated in 0.4.2._
_WeeChat ≥ 0.4.0, updated in 0.4.2 and 1.1._
// TRANSLATION MISSING
Evaluate an expression and return result as a string.
Special variables with format `${variable}` are expanded (see command `/eval` in
'WeeChat User's guide').
Special variables with format `${variable}` are expanded (see table below).
// TRANSLATION MISSING
[NOTE]
@ -1904,10 +1903,14 @@ char *weechat_string_eval_expression (const char *expr,
Argomenti:
// TRANSLATION MISSING
* 'expr': the expression to evaluate
* 'expr': the expression to evaluate (see table below)
* 'pointers': hashtable with pointers (keys must be string, values must be
pointer); pointers "window" and "buffer" are automatically added if they are
not in hashtable (with pointer to current window/buffer) (can be NULL)
not in hashtable (with pointer to current window/buffer) (can be NULL):
** 'regex': pointer to a regular expression ('regex_t' structure) compiled with
WeeChat function <<_weechat_string_regcomp,weechat_string_regcomp>> or
regcomp (see `man regcomp`); this option is similar to 'regex' in hashtable
'options' (below), but is used for better performance
* 'extra_vars': extra variables that will be expanded (can be NULL)
* 'options': a hashtable with some options (keys and values must be string)
(can be NULL):
@ -1917,6 +1920,11 @@ Argomenti:
parentheses are used, result is a boolean ("0" or "1")
** 'prefix': prefix before variables to replace (default: "${")
** 'suffix': suffix after variables to replace (default: "}")
** 'regex': a regex used to replace text in 'expr' (which is then not
evaluated)
** 'regex_replace': the replacement text to use with 'regex', to replace
text in 'expr' (the 'regex_replace' is evaluated on each match of 'regex'
against 'expr', until no match is found)
Valore restituito:
@ -1924,20 +1932,109 @@ Valore restituito:
* evaluated expression (must be freed by calling "free" after use), or NULL
if problem (invalid expression or not enough memory)
// TRANSLATION MISSING
List of variables expanded in expression (by order of priority, from first
expanded to last):
// TRANSLATION MISSING
[width="100%",cols="2,8,3,3",options="header"]
|===
| Format | Description | Examples | Results
| `${name}` | Variable `name` from hashtable 'extra_vars' |
`${name}` | `value`
| `${esc:xxx}` +
`${\xxx}` | String with escaped chars |
`${esc:prefix\tmessage}` +
`${\ua9}` |
`prefix<TAB>message` +
`©`
| `${hide:x,value}` |
String with hidden chars (all chars in `value` replaced `x`) |
`${hide:*,password}` |
`********`
| `${re:N}` |
Regex captured group: 0 = whole string matching, 1 to 99 = group captured,
`+` = last group captured |
`${re:1}` |
`test`
| `${color:name}` |
WeeChat color code (the name of color has optional attributes) |
`${color:red}red text` +
`${color:*214}bold orange text` |
`red text` (in red) +
`bold orange text` (in bold orange)
| `${info:name}` +
`${indo:name,arguments}` |
Info from WeeChat or a plugin, see function
<<_weechat_info_get,weechat_info_get>> |
`${info:version}` +
`${info:irc_nick_color_name,foo}` |
`1.0` +
`lightblue`
| `${sec.data.name}` |
Value of the secured data `name` |
`${sec.data.freenode_pass}` |
`my_password`
| `${file.section.option}` |
Value of the option |
`${weechat.look.buffer_time_format}` |
`%H:%M:%S`
| `${name}` |
Value of local variable `name` in buffer |
`${nick}` |
`FlashCode`
| `${hdata.var1.var2...}` +
`${hdata[list].var1.var2...}` |
Hdata value (pointers `window` and `buffer` are set by default with current
window/buffer) |
`${buffer[gui_buffers].full_name}` +
`${window.buffer.number}` |
`core.weechat` +
`1`
|===
Esempi in C:
[source,C]
----
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options)
weechat_hashtable_set (options, "type", "condition");
char *str1 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
char *str2 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options); /* "1" */
char *str3 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options); /* "0" */
/* conditions */
struct t_hashtable *options1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
weechat_hashtable_set (options1, "type", "condition");
char *str1 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options1); /* "1" */
char *str2 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options1); /* "0" */
/* simple expression */
char *str3 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
/* replace with regex */
struct t_hashtable *options2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
/* add brackets around URLs */
weechat_hashtable_set (options2, "regex", "\\w+://\\S+");
weechat_hashtable_set (options2, "regex_replace", "[ ${re:0} ]");
char *str4 = weechat_string_eval_expression ("test: http://weechat.org", NULL, NULL, NULL); /* "test: [ http://weechat.org ]" */
/* hide passwords */
weechat_hashtable_set (options2, "regex", "(password=)(\\S+)");
weechat_hashtable_set (options2, "regex_replace", "${re:1}${hide:*,${re:2}}");
char *str5 = weechat_string_eval_expression ("password=abc password=def", NULL, NULL, NULL); /* "password=*** password=***" */
----
Script (Python):
@ -1948,9 +2045,27 @@ Script (Python):
str = weechat.string_eval_expression(expr, pointers, extra_vars, options)
# esempi
str1 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
str2 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str3 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# conditions
str1 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str2 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# simple expression
str3 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
# replace with regex: add brackets around URLs
options = {
"regex": "\\w+://\\S+",
"regex_replace": "[ ${re:0} ]",
}
str4 = weechat.string_eval_expression("test: http://weechat.org", {}, {}, options) # "test: [ http://weechat.org ]"
# replace with regex: hide passwords
options = {
"regex": "(password=)(\\S+)",
"regex_replace": "${re:1}${hide:*,${re:2}}",
}
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
----
[[utf-8]]

View File

@ -1822,11 +1822,12 @@ str3 = weechat.string_input_for_buffer("//test") # "/test"
==== weechat_string_eval_expression
_WeeChat バージョン 0.4.0 以上で利用可、バージョン 0.4.2 で更新。_
// TRANSLATION MISSING
_WeeChat ≥ 0.4.0, updated in 0.4.2 and 1.1._
式を評価して文字列として返す。`${variable}`
という書式で書かれた特殊変数は展開される
('WeeChat ユーザガイド' のコマンド `/eval` を参照)。
// TRANSLATION MISSING
Evaluate an expression and return result as a string.
Special variables with format `${variable}` are expanded (see table below).
[NOTE]
バージョン 1.0 以降、入れ子変数を使えるようになりました、例:
@ -1844,10 +1845,16 @@ char *weechat_string_eval_expression (const char *expr,
引数:
* 'expr': 評価する式
// TRANSLATION MISSING
* 'expr': 評価する式 (see table below)
* 'pointers': ポインタを含むハッシュテーブル (キーは文字列、値はポインタ);
(現在のウィンドウやバッファへのポインタを持つ) ハッシュテーブルが "window" と
"buffer" ポインタを持たない場合はこれらは自動的に追加される (NULL でも可)
"buffer" ポインタを持たない場合はこれらは自動的に追加される (NULL でも可):
// TRANSLATION MISSING
** 'regex': pointer to a regular expression ('regex_t' structure) compiled with
WeeChat function <<_weechat_string_regcomp,weechat_string_regcomp>> or
regcomp (see `man regcomp`); this option is similar to 'regex' in hashtable
'options' (below), but is used for better performance
* 'extra_vars': 展開される追加変数 (NULL でも可)
* 'options': いくつかのオプションを含むハッシュテーブル (キーと値は必ず文字列)
(NULL でも可):
@ -1857,39 +1864,155 @@ char *weechat_string_eval_expression (const char *expr,
演算子と括弧が使われます、結果はブール値 ("0" または "1") です
** 'prefix': 置換する変数のプレフィックス (デフォルト: "${")
** 'suffix': 置換する変数のサフィックス (デフォルト: "}")
// TRANSLATION MISSING
** 'regex': a regex used to replace text in 'expr' (which is then not
evaluated)
// TRANSLATION MISSING
** 'regex_replace': the replacement text to use with 'regex', to replace
text in 'expr' (the 'regex_replace' is evaluated on each match of 'regex'
against 'expr', until no match is found)
戻り値:
* 評価された式 (使用後には必ず "free" を呼び出して領域を開放してください)、失敗した場合は
NULL (式が不正な場合やメモリが不足している場合)
// TRANSLATION MISSING
List of variables expanded in expression (by order of priority, from first
expanded to last):
// TRANSLATION MISSING
[width="100%",cols="2,8,3,3",options="header"]
|===
| Format | Description | Examples | Results
| `${name}` | Variable `name` from hashtable 'extra_vars' |
`${name}` | `value`
| `${esc:xxx}` +
`${\xxx}` | String with escaped chars |
`${esc:prefix\tmessage}` +
`${\ua9}` |
`prefix<TAB>message` +
`©`
| `${hide:x,value}` |
String with hidden chars (all chars in `value` replaced `x`) |
`${hide:*,password}` |
`********`
| `${re:N}` |
Regex captured group: 0 = whole string matching, 1 to 99 = group captured,
`+` = last group captured |
`${re:1}` |
`test`
| `${color:name}` |
WeeChat color code (the name of color has optional attributes) |
`${color:red}red text` +
`${color:*214}bold orange text` |
`red text` (in red) +
`bold orange text` (in bold orange)
| `${info:name}` +
`${indo:name,arguments}` |
Info from WeeChat or a plugin, see function
<<_weechat_info_get,weechat_info_get>> |
`${info:version}` +
`${info:irc_nick_color_name,foo}` |
`1.0` +
`lightblue`
| `${sec.data.name}` |
Value of the secured data `name` |
`${sec.data.freenode_pass}` |
`my_password`
| `${file.section.option}` |
Value of the option |
`${weechat.look.buffer_time_format}` |
`%H:%M:%S`
| `${name}` |
Value of local variable `name` in buffer |
`${nick}` |
`FlashCode`
| `${hdata.var1.var2...}` +
`${hdata[list].var1.var2...}` |
Hdata value (pointers `window` and `buffer` are set by default with current
window/buffer) |
`${buffer[gui_buffers].full_name}` +
`${window.buffer.number}` |
`core.weechat` +
`1`
|===
C 言語での使用例:
// TRANSLATION MISSING
[source,C]
----
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options)
weechat_hashtable_set (options, "type", "condition");
char *str1 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
char *str2 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options); /* "1" */
char *str3 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options); /* "0" */
/* conditions */
struct t_hashtable *options1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
weechat_hashtable_set (options1, "type", "condition");
char *str1 = weechat_string_eval_expression ("${window.win_width} > 100", NULL, NULL, options1); /* "1" */
char *str2 = weechat_string_eval_expression ("abc =~ def", NULL, NULL, options1); /* "0" */
/* simple expression */
char *str3 = weechat_string_eval_expression ("${buffer.full_name}", NULL, NULL, NULL); /* "core.weechat" */
/* replace with regex */
struct t_hashtable *options2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
/* add brackets around URLs */
weechat_hashtable_set (options2, "regex", "\\w+://\\S+");
weechat_hashtable_set (options2, "regex_replace", "[ ${re:0} ]");
char *str4 = weechat_string_eval_expression ("test: http://weechat.org", NULL, NULL, NULL); /* "test: [ http://weechat.org ]" */
/* hide passwords */
weechat_hashtable_set (options2, "regex", "(password=)(\\S+)");
weechat_hashtable_set (options2, "regex_replace", "${re:1}${hide:*,${re:2}}");
char *str5 = weechat_string_eval_expression ("password=abc password=def", NULL, NULL, NULL); /* "password=*** password=***" */
----
スクリプト (Python) での使用例:
// TRANSLATION MISSING
[source,python]
----
# プロトタイプ
str = weechat.string_eval_expression(expr, pointers, extra_vars, options)
# 例s
str1 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
str2 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str3 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# conditions
str1 = weechat.string_eval_expression("${window.win_width} > 100", {}, {}, {"type": "condition"}) # "1"
str2 = weechat.string_eval_expression("abc =~ def", {}, {}, {"type": "condition"}) # "0"
# simple expression
str3 = weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) # "core.weechat"
# replace with regex: add brackets around URLs
options = {
"regex": "\\w+://\\S+",
"regex_replace": "[ ${re:0} ]",
}
str4 = weechat.string_eval_expression("test: http://weechat.org", {}, {}, options) # "test: [ http://weechat.org ]"
# replace with regex: hide passwords
options = {
"regex": "(password=)(\\S+)",
"regex_replace": "${re:1}${hide:*,${re:2}}",
}
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
----
[[utf-8]]

View File

@ -220,11 +220,15 @@ end:
/*
* Replaces variables, which can be, by order of priority:
* 1. an extra variable (from hashtable "extra_vars")
* 2. a color (format: color:xxx)
* 3. an option (format: file.section.option)
* 4. a buffer local variable
* 5. a hdata name/variable
* 1. an extra variable from hashtable "extra_vars"
* 2. a string with escaped chars (format: esc:xxx or \xxx)
* 3. a string with chars to hide (format: hide:char,string)
* 4. a regex group captured (format: re:N (0.99) or re:+)
* 5. a color (format: color:xxx)
* 6. an info (format: info:name,arguments)
* 7. an option (format: file.section.option)
* 8. a buffer local variable
* 9. a hdata variable (format: hdata.var1.var2 or hdata[list].var1.var2)
*
* Examples:
* option: ${weechat.look.scroll_amount}
@ -236,19 +240,22 @@ char *
eval_replace_vars_cb (void *data, const char *text)
{
struct t_hashtable *pointers, *extra_vars;
struct t_eval_regex *eval_regex;
struct t_config_option *ptr_option;
struct t_gui_buffer *ptr_buffer;
char str_value[64], *value, *pos, *pos1, *pos2, *hdata_name, *list_name;
char *tmp, *info_name, *hide_char, *hidden_string;
char *tmp, *info_name, *hide_char, *hidden_string, *error;
const char *ptr_value, *ptr_arguments, *ptr_string;
struct t_hdata *hdata;
void *pointer;
int i, length_hide_char, length, index;
long number;
pointers = (struct t_hashtable *)(((void **)data)[0]);
extra_vars = (struct t_hashtable *)(((void **)data)[1]);
eval_regex = (struct t_eval_regex *)(((void **)data)[2]);
/* 1. look for var in hashtable "extra_vars" */
/* 1. variable in hashtable "extra_vars" */
if (extra_vars)
{
ptr_value = hashtable_get (extra_vars, text);
@ -262,7 +269,7 @@ eval_replace_vars_cb (void *data, const char *text)
if ((text[0] == '\\') && text[1] && (text[1] != '\\'))
return string_convert_escaped_chars (text);
/* 3. hide chars: replace all chars by a given char */
/* 3. hide chars: replace all chars by a given char/string */
if (strncmp (text, "hide:", 5) == 0)
{
hidden_string = NULL;
@ -292,14 +299,37 @@ eval_replace_vars_cb (void *data, const char *text)
return (hidden_string) ? hidden_string : strdup ("");
}
/* 4. look for a color */
/* 4. regex group captured */
if (strncmp (text, "re:", 3) == 0)
{
if (eval_regex && eval_regex->result)
{
if (strcmp (text + 3, "+") == 0)
number = eval_regex->last_match;
else
{
number = strtol (text + 3, &error, 10);
if (!error || error[0])
number = -1;
}
if ((number >= 0) && (number <= eval_regex->last_match))
{
return string_strndup (
eval_regex->result + eval_regex->match[number].rm_so,
eval_regex->match[number].rm_eo - eval_regex->match[number].rm_so);
}
}
return strdup ("");
}
/* 5. color code */
if (strncmp (text, "color:", 6) == 0)
{
ptr_value = gui_color_get_custom (text + 6);
return strdup ((ptr_value) ? ptr_value : "");
}
/* 5. look for an info */
/* 6. info */
if (strncmp (text, "info:", 5) == 0)
{
ptr_value = NULL;
@ -319,7 +349,7 @@ eval_replace_vars_cb (void *data, const char *text)
return strdup ((ptr_value) ? ptr_value : "");
}
/* 6. look for name of option: if found, return this value */
/* 7. option: if found, return this value */
if (strncmp (text, "sec.data.", 9) == 0)
{
ptr_value = hashtable_get (secure_hashtable_data, text + 9);
@ -352,7 +382,7 @@ eval_replace_vars_cb (void *data, const char *text)
}
}
/* 7. look for local variable in buffer */
/* 8. local variable in buffer */
ptr_buffer = hashtable_get (pointers, "buffer");
if (ptr_buffer)
{
@ -361,7 +391,7 @@ eval_replace_vars_cb (void *data, const char *text)
return strdup (ptr_value);
}
/* 8. look for hdata */
/* 9. hdata */
value = NULL;
hdata_name = NULL;
list_name = NULL;
@ -425,12 +455,14 @@ end:
char *
eval_replace_vars (const char *expr, struct t_hashtable *pointers,
struct t_hashtable *extra_vars,
const char *prefix, const char *suffix)
const char *prefix, const char *suffix,
struct t_eval_regex *eval_regex)
{
void *ptr[2];
void *ptr[3];
ptr[0] = pointers;
ptr[1] = extra_vars;
ptr[2] = eval_regex;
return string_replace_with_callback (expr, prefix, suffix,
&eval_replace_vars_cb, ptr, NULL);
@ -712,10 +744,12 @@ eval_expression_condition (const char *expr,
/* for regex: just replace vars in both expressions */
tmp_value = eval_replace_vars (sub_expr, pointers,
extra_vars,
prefix, suffix);
prefix, suffix,
NULL);
tmp_value2 = eval_replace_vars (pos, pointers,
extra_vars,
prefix, suffix);
prefix, suffix,
NULL);
}
else
{
@ -799,7 +833,8 @@ eval_expression_condition (const char *expr,
* at this point, there is no more logical operator neither comparison,
* so we just replace variables in string and return the result
*/
value = eval_replace_vars (expr2, pointers, extra_vars, prefix, suffix);
value = eval_replace_vars (expr2, pointers, extra_vars, prefix, suffix,
NULL);
end:
if (expr2)
@ -808,6 +843,125 @@ end:
return value;
}
/*
* Replaces text in a string using a regular expression and replacement text.
*
* The argument "regex" is a pointer to a regex compiled with WeeChat function
* string_regcomp (or function regcomp).
*
* The argument "replace" is evaluated and can contain any valid expression,
* and these ones:
* ${re:0} .. ${re:99} match 0 to 99 (0 is whole match, 1 .. 99 are groups
* captured)
* ${re:+} the last match (with highest number)
*
* Examples:
*
* string | regex | replace | result
* ----------+---------------+----------------------------+-------------
* test foo | test | Z | Z foo
* test foo | ^(test +)(.*) | ${re:2} | foo
* test foo | ^(test +)(.*) | ${re:1}/ ${hide:*,${re:2}} | test / ***
* test foo | ^(test +)(.*) | ${hide:%,${re:+}} | %%%
*
* Note: result must be freed after use.
*/
char *
eval_replace_regex (const char *string, regex_t *regex, const char *replace,
struct t_hashtable *pointers,
struct t_hashtable *extra_vars,
const char *prefix, const char *suffix)
{
char *result, *result2, *str_replace;
int length, length_replace, start_offset, i, rc, end;
struct t_eval_regex eval_regex;
if (!string || !regex || !replace)
return NULL;
length = strlen (string) + 1;
result = malloc (length);
if (!result)
return NULL;
snprintf (result, length, "%s", string);
start_offset = 0;
while (result && result[start_offset])
{
for (i = 0; i < 100; i++)
{
eval_regex.match[i].rm_so = -1;
}
rc = regexec (regex, result + start_offset, 100, eval_regex.match, 0);
/*
* no match found: exit the loop (if rm_eo == 0, it is an empty match
* at beginning of string: we consider there is no match, to prevent an
* infinite loop)
*/
if ((rc != 0)
|| (eval_regex.match[0].rm_so < 0)
|| (eval_regex.match[0].rm_eo <= 0))
{
break;
}
/* adjust the start/end offsets */
eval_regex.last_match = 0;
for (i = 0; i < 100; i++)
{
if (eval_regex.match[i].rm_so >= 0)
{
eval_regex.last_match = i;
eval_regex.match[i].rm_so += start_offset;
eval_regex.match[i].rm_eo += start_offset;
}
}
/* check if the regex matched the end of string */
end = !result[eval_regex.match[0].rm_eo];
eval_regex.result = result;
str_replace = eval_replace_vars (replace, pointers, extra_vars,
prefix, suffix, &eval_regex);
length_replace = (str_replace) ? strlen (str_replace) : 0;
length = eval_regex.match[0].rm_so + length_replace +
strlen (result + eval_regex.match[0].rm_eo) + 1;
result2 = malloc (length);
if (!result2)
{
free (result);
return NULL;
}
result2[0] = '\0';
if (eval_regex.match[0].rm_so > 0)
{
memcpy (result2, result, eval_regex.match[0].rm_so);
result2[eval_regex.match[0].rm_so] = '\0';
}
if (str_replace)
strcat (result2, str_replace);
strcat (result2, result + eval_regex.match[0].rm_eo);
free (result);
result = result2;
if (str_replace)
free (str_replace);
if (end)
break;
start_offset = eval_regex.match[0].rm_so + length_replace;
}
return result;
}
/*
* Evaluates an expression.
*
@ -853,25 +1007,33 @@ char *
eval_expression (const char *expr, struct t_hashtable *pointers,
struct t_hashtable *extra_vars, struct t_hashtable *options)
{
int condition, rc, pointers_allocated;
int condition, rc, pointers_allocated, regex_allocated;
char *value;
const char *prefix, *suffix;
const char *default_prefix = EVAL_DEFAULT_PREFIX;
const char *default_suffix = EVAL_DEFAULT_SUFFIX;
const char *ptr_value;
const char *ptr_value, *regex_replace;
struct t_gui_window *window;
regex_t *regex;
if (!expr)
return NULL;
condition = 0;
pointers_allocated = 0;
regex_allocated = 0;
prefix = default_prefix;
suffix = default_suffix;
regex = NULL;
regex_replace = NULL;
/* create hashtable pointers if it's NULL */
if (!pointers)
if (pointers)
{
regex = (regex_t *)hashtable_get (pointers, "regex");
}
else
{
/* create hashtable pointers if it's NULL */
pointers = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
@ -915,6 +1077,30 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
ptr_value = hashtable_get (options, "suffix");
if (ptr_value && ptr_value[0])
suffix = ptr_value;
/* check for regex */
ptr_value = hashtable_get (options, "regex");
if (ptr_value && ptr_value[0])
{
regex = malloc (sizeof (*regex));
if (string_regcomp (regex, ptr_value,
REG_EXTENDED | REG_ICASE) == 0)
{
regex_allocated = 1;
}
else
{
free (regex);
regex = NULL;
}
}
/* check for regex replacement (evaluated later) */
ptr_value = hashtable_get (options, "regex_replace");
if (ptr_value && ptr_value[0])
{
regex_replace = ptr_value;
}
}
/* evaluate expression */
@ -930,12 +1116,28 @@ eval_expression (const char *expr, struct t_hashtable *pointers,
}
else
{
/* only replace variables in expression */
value = eval_replace_vars (expr, pointers, extra_vars, prefix, suffix);
if (regex && regex_replace)
{
/* replace with regex */
value = eval_replace_regex (expr, regex, regex_replace,
pointers, extra_vars,
prefix, suffix);
}
else
{
/* only replace variables in expression */
value = eval_replace_vars (expr, pointers, extra_vars,
prefix, suffix, NULL);
}
}
if (pointers_allocated)
hashtable_free (pointers);
if (regex && regex_allocated)
{
regfree (regex);
free (regex);
}
return value;
}

View File

@ -20,6 +20,8 @@
#ifndef WEECHAT_EVAL_H
#define WEECHAT_EVAL_H 1
#include <regex.h>
#define EVAL_STR_FALSE "0"
#define EVAL_STR_TRUE "1"
@ -50,6 +52,13 @@ enum t_eval_comparison
EVAL_NUM_COMPARISONS,
};
struct t_eval_regex
{
const char *result;
regmatch_t match[100];
int last_match;
};
extern int eval_is_true (const char *value);
extern char *eval_expression (const char *expr,
struct t_hashtable *pointers,

View File

@ -24,23 +24,20 @@
extern "C"
{
#include <stdio.h>
#include <regex.h>
#include "src/core/wee-eval.h"
#include "src/core/wee-config.h"
#include "src/core/wee-hashtable.h"
#include "src/core/wee-string.h"
#include "src/core/wee-version.h"
#include "src/gui/gui-color.h"
#include "src/plugins/plugin.h"
}
#define WEE_CHECK_EVAL(__result, __expr) \
value = eval_expression (__expr, NULL, extra_vars, NULL); \
value = eval_expression (__expr, pointers, extra_vars, options); \
STRCMP_EQUAL(__result, value); \
free (value);
#define WEE_CHECK_EVAL_COND(__result, __expr) \
value = eval_expression (__expr, NULL, extra_vars, options); \
STRCMP_EQUAL(__result, value); \
free (value);
TEST_GROUP(Eval)
{
};
@ -71,94 +68,96 @@ TEST(Eval, Boolean)
TEST(Eval, EvalCondition)
{
struct t_hashtable *extra_vars, *options;
struct t_hashtable *pointers, *extra_vars, *options;
char *value;
pointers = NULL;
extra_vars = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
hashtable_set (extra_vars, "test", "value");
CHECK(extra_vars);
hashtable_set (extra_vars, "test", "value");
options = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
hashtable_set (options, "type", "condition");
CHECK(options);
hashtable_set (options, "type", "condition");
POINTERS_EQUAL(NULL, eval_expression (NULL, NULL, NULL, options));
/* conditions evaluated as false */
WEE_CHECK_EVAL_COND("0", "");
WEE_CHECK_EVAL_COND("0", "0");
WEE_CHECK_EVAL_COND("0", "1 == 2");
WEE_CHECK_EVAL_COND("0", "1 >= 2");
WEE_CHECK_EVAL_COND("0", "2 <= 1");
WEE_CHECK_EVAL_COND("0", "2 != 2");
WEE_CHECK_EVAL_COND("0", "18 < 5");
WEE_CHECK_EVAL_COND("0", "5 > 18");
WEE_CHECK_EVAL_COND("0", "1 == 5 > 18");
WEE_CHECK_EVAL_COND("0", "abc == def");
WEE_CHECK_EVAL_COND("0", "()");
WEE_CHECK_EVAL_COND("0", "(5 > 26)");
WEE_CHECK_EVAL_COND("0", "((5 > 26))");
WEE_CHECK_EVAL_COND("0", "(26 < 5)");
WEE_CHECK_EVAL_COND("0", "abc > def");
WEE_CHECK_EVAL_COND("0", "1 && 0");
WEE_CHECK_EVAL_COND("0", "abc && 0");
WEE_CHECK_EVAL_COND("0", "0 || 0");
WEE_CHECK_EVAL_COND("0", "0 || 0 || 0");
WEE_CHECK_EVAL_COND("0", "0 || 1 && 0");
WEE_CHECK_EVAL_COND("0", "0 || (1 && 0)");
WEE_CHECK_EVAL_COND("0", "0 || (0 || (1 && 0))");
WEE_CHECK_EVAL_COND("0", "1 && (0 || 0)");
WEE_CHECK_EVAL_COND("0", "(0 || 1) && 0");
WEE_CHECK_EVAL_COND("0", "((0 || 1) && 1) && 0");
WEE_CHECK_EVAL_COND("0", "abcd =~ (?-i)^ABC");
WEE_CHECK_EVAL_COND("0", "abcd =~ \\(abcd\\)");
WEE_CHECK_EVAL_COND("0", "(abcd) =~ \\(\\(abcd\\)\\)");
WEE_CHECK_EVAL_COND("0", "${test} == test");
WEE_CHECK_EVAL_COND("0", "${test2} == value2");
WEE_CHECK_EVAL_COND("0", "${buffer.number} == 2");
WEE_CHECK_EVAL_COND("0", "${window.buffer.number} == 2");
WEE_CHECK_EVAL("0", "");
WEE_CHECK_EVAL("0", "0");
WEE_CHECK_EVAL("0", "1 == 2");
WEE_CHECK_EVAL("0", "1 >= 2");
WEE_CHECK_EVAL("0", "2 <= 1");
WEE_CHECK_EVAL("0", "2 != 2");
WEE_CHECK_EVAL("0", "18 < 5");
WEE_CHECK_EVAL("0", "5 > 18");
WEE_CHECK_EVAL("0", "1 == 5 > 18");
WEE_CHECK_EVAL("0", "abc == def");
WEE_CHECK_EVAL("0", "()");
WEE_CHECK_EVAL("0", "(5 > 26)");
WEE_CHECK_EVAL("0", "((5 > 26))");
WEE_CHECK_EVAL("0", "(26 < 5)");
WEE_CHECK_EVAL("0", "abc > def");
WEE_CHECK_EVAL("0", "1 && 0");
WEE_CHECK_EVAL("0", "abc && 0");
WEE_CHECK_EVAL("0", "0 || 0");
WEE_CHECK_EVAL("0", "0 || 0 || 0");
WEE_CHECK_EVAL("0", "0 || 1 && 0");
WEE_CHECK_EVAL("0", "0 || (1 && 0)");
WEE_CHECK_EVAL("0", "0 || (0 || (1 && 0))");
WEE_CHECK_EVAL("0", "1 && (0 || 0)");
WEE_CHECK_EVAL("0", "(0 || 1) && 0");
WEE_CHECK_EVAL("0", "((0 || 1) && 1) && 0");
WEE_CHECK_EVAL("0", "abcd =~ (?-i)^ABC");
WEE_CHECK_EVAL("0", "abcd =~ \\(abcd\\)");
WEE_CHECK_EVAL("0", "(abcd) =~ \\(\\(abcd\\)\\)");
WEE_CHECK_EVAL("0", "${test} == test");
WEE_CHECK_EVAL("0", "${test2} == value2");
WEE_CHECK_EVAL("0", "${buffer.number} == 2");
WEE_CHECK_EVAL("0", "${window.buffer.number} == 2");
/* conditions evaluated as true */
WEE_CHECK_EVAL_COND("1", "1");
WEE_CHECK_EVAL_COND("1", "123");
WEE_CHECK_EVAL_COND("1", "abc");
WEE_CHECK_EVAL_COND("1", "2 == 2");
WEE_CHECK_EVAL_COND("1", "2 >= 1");
WEE_CHECK_EVAL_COND("1", "1 <= 2");
WEE_CHECK_EVAL_COND("1", "1 != 2");
WEE_CHECK_EVAL_COND("1", "18 > 5");
WEE_CHECK_EVAL_COND("1", "5 < 18");
WEE_CHECK_EVAL_COND("1", "1 == 18 > 5");
WEE_CHECK_EVAL_COND("1", "abc == abc");
WEE_CHECK_EVAL_COND("1", "(26 > 5)");
WEE_CHECK_EVAL_COND("1", "((26 > 5))");
WEE_CHECK_EVAL_COND("1", "(5 < 26)");
WEE_CHECK_EVAL_COND("1", "def > abc");
WEE_CHECK_EVAL_COND("1", "1 && 1");
WEE_CHECK_EVAL_COND("1", "abc && 1");
WEE_CHECK_EVAL_COND("1", "0 || 1");
WEE_CHECK_EVAL_COND("1", "0 || 0 || 1");
WEE_CHECK_EVAL_COND("1", "1 || 1 && 0");
WEE_CHECK_EVAL_COND("1", "0 || (1 && 1)");
WEE_CHECK_EVAL_COND("1", "0 || (0 || (1 && 1))");
WEE_CHECK_EVAL_COND("1", "1 && (0 || 1)");
WEE_CHECK_EVAL_COND("1", "(0 || 1) && 1");
WEE_CHECK_EVAL_COND("1", "((0 || 1) && 1) && 1");
WEE_CHECK_EVAL_COND("1", "abcd =~ ^ABC");
WEE_CHECK_EVAL_COND("1", "abcd =~ (?-i)^abc");
WEE_CHECK_EVAL_COND("1", "(abcd) =~ (abcd)");
WEE_CHECK_EVAL_COND("1", "(abcd) =~ \\(abcd\\)");
WEE_CHECK_EVAL_COND("1", "((abcd)) =~ \\(\\(abcd\\)\\)");
WEE_CHECK_EVAL_COND("1", "${test} == value");
WEE_CHECK_EVAL_COND("1", "${test2} ==");
WEE_CHECK_EVAL_COND("1", "${buffer.number} == 1");
WEE_CHECK_EVAL_COND("1", "${window.buffer.number} == 1");
WEE_CHECK_EVAL("1", "1");
WEE_CHECK_EVAL("1", "123");
WEE_CHECK_EVAL("1", "abc");
WEE_CHECK_EVAL("1", "2 == 2");
WEE_CHECK_EVAL("1", "2 >= 1");
WEE_CHECK_EVAL("1", "1 <= 2");
WEE_CHECK_EVAL("1", "1 != 2");
WEE_CHECK_EVAL("1", "18 > 5");
WEE_CHECK_EVAL("1", "5 < 18");
WEE_CHECK_EVAL("1", "1 == 18 > 5");
WEE_CHECK_EVAL("1", "abc == abc");
WEE_CHECK_EVAL("1", "(26 > 5)");
WEE_CHECK_EVAL("1", "((26 > 5))");
WEE_CHECK_EVAL("1", "(5 < 26)");
WEE_CHECK_EVAL("1", "def > abc");
WEE_CHECK_EVAL("1", "1 && 1");
WEE_CHECK_EVAL("1", "abc && 1");
WEE_CHECK_EVAL("1", "0 || 1");
WEE_CHECK_EVAL("1", "0 || 0 || 1");
WEE_CHECK_EVAL("1", "1 || 1 && 0");
WEE_CHECK_EVAL("1", "0 || (1 && 1)");
WEE_CHECK_EVAL("1", "0 || (0 || (1 && 1))");
WEE_CHECK_EVAL("1", "1 && (0 || 1)");
WEE_CHECK_EVAL("1", "(0 || 1) && 1");
WEE_CHECK_EVAL("1", "((0 || 1) && 1) && 1");
WEE_CHECK_EVAL("1", "abcd =~ ^ABC");
WEE_CHECK_EVAL("1", "abcd =~ (?-i)^abc");
WEE_CHECK_EVAL("1", "(abcd) =~ (abcd)");
WEE_CHECK_EVAL("1", "(abcd) =~ \\(abcd\\)");
WEE_CHECK_EVAL("1", "((abcd)) =~ \\(\\(abcd\\)\\)");
WEE_CHECK_EVAL("1", "${test} == value");
WEE_CHECK_EVAL("1", "${test2} ==");
WEE_CHECK_EVAL("1", "${buffer.number} == 1");
WEE_CHECK_EVAL("1", "${window.buffer.number} == 1");
hashtable_free (extra_vars);
hashtable_free (options);
@ -171,16 +170,20 @@ TEST(Eval, EvalCondition)
TEST(Eval, EvalExpression)
{
struct t_hashtable *extra_vars;
struct t_hashtable *pointers, *extra_vars, *options;
char *value, str_value[256];
void *toto;
pointers = NULL;
extra_vars = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
hashtable_set (extra_vars, "test", "value");
CHECK(extra_vars);
hashtable_set (extra_vars, "test", "value");
options = NULL;
POINTERS_EQUAL(NULL, eval_expression (NULL, NULL, NULL, NULL));
@ -228,3 +231,72 @@ TEST(Eval, EvalExpression)
hashtable_free (extra_vars);
}
/*
* Tests functions:
* eval_expression (replace with regex)
*/
TEST(Eval, EvalReplaceRegex)
{
struct t_hashtable *pointers, *extra_vars, *options;
char *value;
regex_t regex;
pointers = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL, NULL);
CHECK(pointers);
extra_vars = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
CHECK(extra_vars);
hashtable_set (extra_vars, "test", "value");
options = hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
CHECK(options);
/* add brackets around URLs (regex as string) */
hashtable_remove (pointers, "regex");
hashtable_set (options, "regex", "\\w+://\\S+");
hashtable_set (options, "regex_replace", "[ ${re:0} ]");
WEE_CHECK_EVAL("test: [ http://weechat.org ]",
"test: http://weechat.org");
/* add brackets around URLs (compiled regex) */
LONGS_EQUAL(0, string_regcomp (&regex, "\\w+://\\S+",
REG_EXTENDED | REG_ICASE));
hashtable_set (pointers, "regex", &regex);
hashtable_remove (options, "regex");
hashtable_set (options, "regex_replace", "[ ${re:0} ]");
WEE_CHECK_EVAL("test: [ http://weechat.org ]",
"test: http://weechat.org");
regfree (&regex);
/* hide passwords (regex as string) */
hashtable_remove (pointers, "regex");
hashtable_set (options, "regex", "(password=)(\\S+)");
hashtable_set (options, "regex_replace", "${re:1}${hide:*,${re:2}}");
WEE_CHECK_EVAL("password=*** password=***",
"password=abc password=def");
/* hide passwords (compiled regex) */
LONGS_EQUAL(0, string_regcomp (&regex, "(password=)(\\S+)",
REG_EXTENDED | REG_ICASE));
hashtable_set (pointers, "regex", &regex);
hashtable_remove (options, "regex");
hashtable_set (options, "regex_replace", "${re:1}${hide:*,${re:2}}");
WEE_CHECK_EVAL("password=*** password=***",
"password=abc password=def");
regfree (&regex);
hashtable_free (pointers);
hashtable_free (extra_vars);
hashtable_free (options);
}