summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2014-03-20 15:57:46 +0100
committerSebastien Helleu <flashcode@flashtux.org>2014-03-20 15:57:46 +0100
commit3a6313c4b5646e73e3050dc61d22e3d244685a88 (patch)
treeb41df5b16db9ad3d45e4792259b2407651c30add
parente6c775050ba472afd747f2075be729fbab8b1096 (diff)
downloadweechat-3a6313c4b5646e73e3050dc61d22e3d244685a88.zip
api: add support of nested variables in function string_eval_expression and command /eval (closes #35)
-rw-r--r--ChangeLog.asciidoc2
-rw-r--r--doc/en/weechat_plugin_api.en.txt4
-rw-r--r--doc/fr/weechat_plugin_api.fr.txt4
-rw-r--r--doc/it/weechat_plugin_api.it.txt5
-rw-r--r--doc/ja/weechat_plugin_api.ja.txt5
-rw-r--r--src/core/wee-string.c83
6 files changed, 82 insertions, 21 deletions
diff --git a/ChangeLog.asciidoc b/ChangeLog.asciidoc
index 53ab7cc43..d4f3072fa 100644
--- a/ChangeLog.asciidoc
+++ b/ChangeLog.asciidoc
@@ -64,6 +64,8 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
* api: add option "detached" in function hook_process_hashtable
* api: add option "signal" in function hook_set to send a signal to the child
process
+* api: add support of nested variables in function string_eval_expression and
+ command /eval (closes #35)
* api: add support of escaped strings with format `${esc:xxx}` or `${\xxx}` in
function string_eval_expression and command /eval
* api: add functions "hashtable_dup", "string_replace_regex",
diff --git a/doc/en/weechat_plugin_api.en.txt b/doc/en/weechat_plugin_api.en.txt
index 7be917b19..b93ac9143 100644
--- a/doc/en/weechat_plugin_api.en.txt
+++ b/doc/en/weechat_plugin_api.en.txt
@@ -1819,6 +1819,10 @@ Evaluate an expression and return result as a string.
Special variables with format `${variable}` are expanded (see command `/eval` in
'WeeChat User's guide').
+[NOTE]
+Since version 0.4.4, nested variables are supported, for example:
+`${color:${variable}}`.
+
Prototype:
[source,C]
diff --git a/doc/fr/weechat_plugin_api.fr.txt b/doc/fr/weechat_plugin_api.fr.txt
index 36085b3ca..5bae50bf5 100644
--- a/doc/fr/weechat_plugin_api.fr.txt
+++ b/doc/fr/weechat_plugin_api.fr.txt
@@ -1851,6 +1851,10 @@ _WeeChat ≥ 0.4.0, mis à jour dans la 0.4.2._
Les variables spéciales avec le format `${variable}` sont étendues (voir la
commande `/eval` dans le 'Guide utilisateur WeeChat').
+[NOTE]
+Depuis la version 0.4.4, les variables imbriquées sont supportées, par exemple :
+`${color:${variable}}`.
+
Prototype :
[source,C]
diff --git a/doc/it/weechat_plugin_api.it.txt b/doc/it/weechat_plugin_api.it.txt
index 7bd7bc4a4..2846eccf0 100644
--- a/doc/it/weechat_plugin_api.it.txt
+++ b/doc/it/weechat_plugin_api.it.txt
@@ -1861,6 +1861,11 @@ Evaluate an expression and return result as a string.
Special variables with format `${variable}` are expanded (see command `/eval` in
'WeeChat User's guide').
+// TRANSLATION MISSING
+[NOTE]
+Since version 0.4.4, nested variables are supported, for example:
+`${color:${variable}}`.
+
Prototipo:
[source,C]
diff --git a/doc/ja/weechat_plugin_api.ja.txt b/doc/ja/weechat_plugin_api.ja.txt
index 37b613175..64c1c026f 100644
--- a/doc/ja/weechat_plugin_api.ja.txt
+++ b/doc/ja/weechat_plugin_api.ja.txt
@@ -1815,6 +1815,11 @@ _WeeChat バージョン 0.4.0 以上で利用可、バージョン 0.4.2 で更
という書式で書かれた特殊変数は展開される
('WeeChat ユーザガイド' のコマンド `/eval` を参照)。
+// TRANSLATION MISSING
+[NOTE]
+Since version 0.4.4, nested variables are supported, for example:
+`${color:${variable}}`.
+
プロトタイプ:
[source,C]
diff --git a/src/core/wee-string.c b/src/core/wee-string.c
index e8f9ed589..7dfcd3219 100644
--- a/src/core/wee-string.c
+++ b/src/core/wee-string.c
@@ -2578,9 +2578,11 @@ string_input_for_buffer (const char *string)
}
/*
- * Replaces ${codes} using a callback that returns replacement value (this value
+ * Replaces ${vars} using a callback that returns replacement value (this value
* must be newly allocated because it will be freed in this function).
*
+ * Nested variables are supported, for example: "${var1:${var2}}".
+ *
* Argument "errors" is set with number of keys not found by callback.
*
* Note: result must be freed after use.
@@ -2595,8 +2597,8 @@ string_replace_with_callback (const char *string,
int *errors)
{
int length_prefix, length_suffix, length, length_value, index_string;
- int index_result;
- char *result, *result2, *key, *value;
+ int index_result, sub_count, sub_level, sub_errors;
+ char *result, *result2, *key, *key2, *value;
const char *pos_end_name;
*errors = 0;
@@ -2623,43 +2625,82 @@ string_replace_with_callback (const char *string,
}
else if (strncmp (string + index_string, prefix, length_prefix) == 0)
{
- pos_end_name = strstr (string + index_string + length_prefix, suffix);
- if (pos_end_name)
+ sub_count = 0;
+ sub_level = 0;
+ pos_end_name = string + index_string + length_prefix;
+ while (pos_end_name[0])
{
- key = string_strndup (string + index_string + length_prefix,
- pos_end_name - (string + index_string + length_prefix));
- if (key)
+ if (strncmp (pos_end_name, suffix, length_suffix) == 0)
+ {
+ if (sub_level == 0)
+ break;
+ sub_level--;
+ }
+ if ((pos_end_name[0] == '\\')
+ && (pos_end_name[1] == prefix[0]))
+ {
+ pos_end_name++;
+ }
+ else if (strncmp (pos_end_name, prefix, length_prefix) == 0)
+ {
+ sub_count++;
+ sub_level++;
+ }
+ pos_end_name++;
+ }
+ /* prefix without matching suffix => error! */
+ if (!pos_end_name[0])
+ {
+ result[index_result] = '\0';
+ (*errors)++;
+ return result;
+ }
+ key = string_strndup (string + index_string + length_prefix,
+ pos_end_name - (string + index_string + length_prefix));
+ if (key)
+ {
+ if (sub_count > 0)
+ {
+ sub_errors = 0;
+ key2 = string_replace_with_callback (key, prefix,
+ suffix, callback,
+ callback_data,
+ &sub_errors);
+ (*errors) += sub_errors;
+ free (key);
+ key = key2;
+ }
+ value = (*callback) (callback_data, (key) ? key : "");
+ if (value)
{
- value = (*callback) (callback_data, key);
- if (value)
+ length_value = strlen (value);
+ if (length_value > 0)
{
- length_value = strlen (value);
length += length_value;
result2 = realloc (result, length);
if (!result2)
{
if (result)
free (result);
- free (key);
+ if (key)
+ free (key);
free (value);
return NULL;
}
result = result2;
strcpy (result + index_result, value);
index_result += length_value;
- index_string += pos_end_name - string -
- index_string + length_suffix;
- free (value);
- }
- else
- {
- result[index_result++] = string[index_string++];
- (*errors)++;
}
- free (key);
+ index_string = pos_end_name - string + length_suffix;
+ free (value);
}
else
+ {
result[index_result++] = string[index_string++];
+ (*errors)++;
+ }
+ if (key)
+ free (key);
}
else
result[index_result++] = string[index_string++];