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

core: add configuration version, add API function config_set_version

This commit is contained in:
Sébastien Helleu
2023-02-21 07:06:01 +01:00
parent 7b8e5b36c0
commit 66571a0b63
27 changed files with 1792 additions and 41 deletions
+176
View File
@@ -6366,6 +6366,182 @@ def my_config_reload_cb(data: str, config_file: str) -> int:
config_file = weechat.config_new("test", "my_config_reload_cb", "")
----
==== config_set_version
_WeeChat ≥ 3.9._
Set configuration file version and a callback to update config sections/options
on-the-fly when the config is read.
Prototype:
[source,c]
----
int config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
----
Arguments:
* _config_file_: configuration file pointer
* _version_: version, must be ≥ 2
* _callback_update_: function called when configuration file is read, for each
section and each option, if the version read is less than the expected version,
(optional, can be NULL, see below), arguments and return value:
** _const void *pointer_: pointer
** _void *data_: pointer
** _struct t_config_file *config_file_: configuration file pointer
** _int version_read_: version read in configuration file (1 by default)
** _struct t_hashtable *data_read_: hashtable with data read from configuration file
(see below)
** return value:
*** either "data_read" pointer (hashtable completed), or pointer to a new
hashtable (created by callback, with keys and values of type "string")
* _callback_update_pointer_: pointer given to callback when it is called by
WeeChat
* _callback_update_data_: pointer given to callback when it is called by
WeeChat; if not NULL, it must have been allocated with malloc (or similar
function) and it is automatically freed when the configuration file is freed
Update callback:
* The callback receives a hashtable with data read from configuration file:
[width="100%",cols="1m,2,8",options="header"]
|===
| Key | Availability | Value
| config | Always set | Name of configuration file, without extension (eg: `weechat`)
| section | Always set | Name of section being read
| option | For option only | Name of the option
| value | For option only | Value of the option (if not NULL)
| value_null | For option only | Option as NULL value (value is always `1`)
|===
* The callback can update "section" for a line with a section and "option", "value"
and "value_null" for a line with an option.
* If "option" is set to empty string by the callback, the line read in
configuration file is ignored.
* Field "value_null" is set to force a NULL value for the option.
Return value:
* 1 if OK, 0 if error
C example:
[source,c]
----
struct t_hashtable *
my_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_section, *ptr_option;
/* return now if version is already up-to-date */
if (version_read >= 2)
return NULL;
ptr_section = hashtable_get (data_read, "section");
ptr_option = hashtable_get (data_read, "option");
/* rename section "abc" to "def" */
if (ptr_section && !ptr_option && (strcmp (ptr_section, "abc") == 0))
{
hashtable_set (data_read, "section", "def");
return data_read;
}
/* limit other changes to section "test" */
if (!ptr_section || !ptr_option || (strcmp (ptr_section, "test") != 0))
return NULL;
/* rename option "test1" to "test2" */
if (strcmp (ptr_option, "test1") == 0)
{
hashtable_set (data_read, "option", "test2");
return data_read;
}
/* set value to "xxx" for option "test" */
if (strcmp (ptr_option, "test") == 0)
{
hashtable_set (data_read, "value", "xxx");
return data_read;
}
/* set value to NULL for option "test_null" */
if (strcmp (ptr_option, "test_null") == 0)
{
hashtable_set (data_read, "value_null", "1");
return data_read;
}
/* no changes */
return NULL;
}
struct t_config_file *config_file = weechat_config_new ("test", NULL, NULL, NULL);
weechat_config_set_version (config_file, 2, &my_config_update_cb, NULL, NULL);
weechat_config_read (config_file);
----
Script (Python):
[source,python]
----
# prototype
def config_set_version(config_file: str, version: int, callback_update: str, callback_update_data: str) -> int: ...
# example
def my_config_update_cb(data: str, config_file: str, version_read: int, data_read: Dict[str, str]) -> Dict[str, str]:
# return now if version is already up-to-date
if version_read >= 2:
return {}
section = data_read.get("section")
option = data_read.get("option")
# rename section "abc" to "def"
if section and not option and section == "abc":
data_read["section"] = "def"
return data_read
# limit other changes to section "test"
if not section or not option or section != "test":
return {}
# rename option "test1" to "test2"
if option == "test1":
data_read["option"] = "test2"
return data_read
# set value to "xxx" for option "test"
if option == "test":
data_read["value"] = "xxx"
return data_read
# set value to NULL for option "test_null"
if option == "test_null":
data_read["value_null"] = "1"
return data_read
# no changes
return {}
config_file = weechat.config_new("test", "", "")
weechat.config_set_version(config_file, 2, "my_config_update_cb", "")
weechat.config_read(config_file)
----
==== config_new_section
_Updated in 1.5._
+182
View File
@@ -6469,6 +6469,188 @@ def my_config_reload_cb(data: str, config_file: str) -> int:
config_file = weechat.config_new("test", "my_config_reload_cb", "")
----
==== config_set_version
_WeeChat ≥ 3.9._
Définir la version du fichier de configuration et une fonction de rappel pour
la mise à jour des sections/options à la volée lorsque la configuration est lue.
Prototype :
[source,c]
----
int config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
----
Paramètres :
* _config_file_ : pointeur vers le fichier de configuration
* _version_ : version, doit être ≥ 2
* _callback_update_ : fonction appelée lorsque le fichier de configuration est
lu, pour chaque section et option, si la version lue est inférieure à la
version attendue (optionnelle, peut être NULL, voir ci-dessous), paramètres
et valeur de retour :
** _const void *pointer_ : pointeur
** _void *data_ : pointeur
** _struct t_config_file *config_file_ : pointeur vers le fichier de configuration
** _int version_read_ : version lue dans le fichier de configuration (1 par défaut)
** _struct t_hashtable *data_read_ : table de hachage avec les données lues du
fichier de configuration (voir ci-dessous)
** valeur de retour :
*** soit le pointeur vers la table de hachage "data_read" (avec la
table de hachage complétée), ou un pointeur vers une nouvelle table de
hachage (créée par la fonction de rappel, avec clés et valeurs de type
"string")
* _callback_update_pointer_: pointeur donné à la fonction de rappel lorsqu'elle
est appelée par WeeChat
* _callback_update_data_ : pointeur donné à la fonction de rappel lorsqu'elle est
appelée par WeeChat; si non NULL, doit avoir été alloué par malloc (ou une
fonction similaire) et est automatiquement libéré (par free) lorsque le
fichier de configuration est libéré
Fonction de rappel de mise à jour :
* La fonction de rappel reçoit une table de hachage avec les données lues du
fichier de configuration :
[width="100%",cols="1m,2,8",options="header"]
|===
| Clé | Disponibilité | Valeur
| config | Toujours définie | Nom du fichier de configuration sans l'extension (par exemple : `weechat`)
| section | Toujours définie | Nom de la section lue
| option | Pour une option seulement | Nom de l'option
| value | Pour une option seulement | Valeur de l'option (si non NULL)
| value_null | Pour une option seulement | L'option a une valeur NULL (la valeur est toujours `1`)
|===
* La fonction de rappel peut mettre à jour la "section" pour une ligne avec une
section et "option", "value" et "value_null" pour une ligne avec une option.
* Si "option" est changée en chaîne vide par la fonction de rappel, la ligne lue
dans le fichier de configuration est ignorée.
* Le champ "value_null" peut être positionné pour forcer une valeur NULL dans
l'option.
Valeur de retour :
* 1 si OK, 0 si erreur
Exemple en C :
[source,c]
----
struct t_hashtable *
my_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_section, *ptr_option;
/* retourner maintenant si la version est déjà la dernière */
if (version_read >= 2)
return NULL;
ptr_section = hashtable_get (data_read, "section");
ptr_option = hashtable_get (data_read, "option");
/* renommer la section "abc" en "def" */
if (ptr_section && !ptr_option && (strcmp (ptr_section, "abc") == 0))
{
hashtable_set (data_read, "section", "def");
return data_read;
}
/* limiter les autres changements à la section "test" */
if (!ptr_section || !ptr_option || (strcmp (ptr_section, "test") != 0))
return NULL;
/* renommer l'option "test1" en "test2" */
if (strcmp (ptr_option, "test1") == 0)
{
hashtable_set (data_read, "option", "test2");
return data_read;
}
/* définir la valeur à "xxx" pour l'option "test" */
if (strcmp (ptr_option, "test") == 0)
{
hashtable_set (data_read, "value", "xxx");
return data_read;
}
/* définir la valeur à NULL pour l'option "test_null" */
if (strcmp (ptr_option, "test_null") == 0)
{
hashtable_set (data_read, "value_null", "1");
return data_read;
}
/* aucun changement */
return NULL;
}
struct t_config_file *config_file = weechat_config_new ("test", NULL, NULL, NULL);
weechat_config_set_version (config_file, 2, &my_config_update_cb, NULL, NULL);
weechat_config_read (config_file);
----
Script (Python) :
[source,python]
----
# prototype
def config_set_version(config_file: str, version: int, callback_update: str, callback_update_data: str) -> int: ...
# exemple
def my_config_update_cb(data: str, config_file: str, version_read: int, data_read: Dict[str, str]) -> Dict[str, str]:
# retourner maintenant si la version est déjà la dernière
if version_read >= 2:
return {}
section = data_read.get("section")
option = data_read.get("option")
# renommer la section "abc" en "def"
if section and not option and section == "abc":
data_read["section"] = "def"
return data_read
# limiter les autres changements à la section "test"
if not section or not option or section != "test":
return {}
# renommer l'option "test1" en "test2"
if option == "test1":
data_read["option"] = "test2"
return data_read
# définir la valeur à "xxx" pour l'option "test"
if option == "test":
data_read["value"] = "xxx"
return data_read
# définir la valeur à NULL pour l'option "test_null"
if option == "test_null":
data_read["value_null"] = "1"
return data_read
# aucun changement
return {}
config_file = weechat.config_new("test", "", "")
weechat.config_set_version(config_file, 2, "my_config_update_cb", "")
weechat.config_read(config_file)
----
==== config_new_section
_Mis à jour dans la 1.5._
+177
View File
@@ -6638,6 +6638,183 @@ def my_config_reload_cb(data: str, config_file: str) -> int:
config_file = weechat.config_new("test", "my_config_reload_cb", "")
----
// TRANSLATION MISSING
==== config_set_version
_WeeChat ≥ 3.9._
Set configuration file version and a callback to update config sections/options
on-the-fly when the config is read.
Prototipo:
[source,c]
----
int config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
----
Argomenti:
* _config_file_: configuration file pointer
* _version_: version, must be ≥ 2
* _callback_update_: function called when configuration file is read, for each
section and each option, if the version read is less than the expected version,
(optional, can be NULL, see below), arguments and return value:
** _const void *pointer_: pointer
** _void *data_: pointer
** _struct t_config_file *config_file_: configuration file pointer
** _int version_read_: version read in configuration file (1 by default)
** _struct t_hashtable *data_read_: hashtable with data read from configuration file
(see below)
** return value:
*** either "data_read" pointer (hashtable completed), or pointer to a new
hashtable (created by callback, with keys and values of type "string")
* _callback_update_pointer_: pointer given to callback when it is called by
WeeChat
* _callback_update_data_: pointer given to callback when it is called by
WeeChat; if not NULL, it must have been allocated with malloc (or similar
function) and it is automatically freed when the configuration file is freed
Update callback:
* The callback receives a hashtable with data read from configuration file:
[width="100%",cols="1m,2,8",options="header"]
|===
| Key | Availability | Value
| config | Always set | Name of configuration file, without extension (eg: `weechat`)
| section | Always set | Name of section being read
| option | For option only | Name of the option
| value | For option only | Value of the option (if not NULL)
| value_null | For option only | Option as NULL value (value is always `1`)
|===
* The callback can update "section" for a line with a section and "option", "value"
and "value_null" for a line with an option.
* If "option" is set to empty string by the callback, the line read in
configuration file is ignored.
* Field "value_null" is set to force a NULL value for the option.
Valore restituito:
* 1 if OK, 0 if error
Esempio in C:
[source,c]
----
struct t_hashtable *
my_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_section, *ptr_option;
/* return now if version is already up-to-date */
if (version_read >= 2)
return NULL;
ptr_section = hashtable_get (data_read, "section");
ptr_option = hashtable_get (data_read, "option");
/* rename section "abc" to "def" */
if (ptr_section && !ptr_option && (strcmp (ptr_section, "abc") == 0))
{
hashtable_set (data_read, "section", "def");
return data_read;
}
/* limit other changes to section "test" */
if (!ptr_section || !ptr_option || (strcmp (ptr_section, "test") != 0))
return NULL;
/* rename option "test1" to "test2" */
if (strcmp (ptr_option, "test1") == 0)
{
hashtable_set (data_read, "option", "test2");
return data_read;
}
/* set value to "xxx" for option "test" */
if (strcmp (ptr_option, "test") == 0)
{
hashtable_set (data_read, "value", "xxx");
return data_read;
}
/* set value to NULL for option "test_null" */
if (strcmp (ptr_option, "test_null") == 0)
{
hashtable_set (data_read, "value_null", "1");
return data_read;
}
/* no changes */
return NULL;
}
struct t_config_file *config_file = weechat_config_new ("test", NULL, NULL, NULL);
weechat_config_set_version (config_file, 2, &my_config_update_cb, NULL, NULL);
weechat_config_read (config_file);
----
Script (Python):
[source,python]
----
# prototipo
def config_set_version(config_file: str, version: int, callback_update: str, callback_update_data: str) -> int: ...
# esempio
def my_config_update_cb(data: str, config_file: str, version_read: int, data_read: Dict[str, str]) -> Dict[str, str]:
# return now if version is already up-to-date
if version_read >= 2:
return {}
section = data_read.get("section")
option = data_read.get("option")
# rename section "abc" to "def"
if section and not option and section == "abc":
data_read["section"] = "def"
return data_read
# limit other changes to section "test"
if not section or not option or section != "test":
return {}
# rename option "test1" to "test2"
if option == "test1":
data_read["option"] = "test2"
return data_read
# set value to "xxx" for option "test"
if option == "test":
data_read["value"] = "xxx"
return data_read
# set value to NULL for option "test_null"
if option == "test_null":
data_read["value_null"] = "1"
return data_read
# no changes
return {}
config_file = weechat.config_new("test", "", "")
weechat.config_set_version(config_file, 2, "my_config_update_cb", "")
weechat.config_read(config_file)
----
==== config_new_section
// TRANSLATION MISSING
+177
View File
@@ -6448,6 +6448,183 @@ def my_config_reload_cb(data: str, config_file: str) -> int:
config_file = weechat.config_new("test", "my_config_reload_cb", "")
----
// TRANSLATION MISSING
==== config_set_version
_WeeChat ≥ 3.9._
Set configuration file version and a callback to update config sections/options
on-the-fly when the config is read.
プロトタイプ:
[source,c]
----
int config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
----
引数:
* _config_file_: configuration file pointer
* _version_: version, must be ≥ 2
* _callback_update_: function called when configuration file is read, for each
section and each option, if the version read is less than the expected version,
(optional, can be NULL, see below), arguments and return value:
** _const void *pointer_: pointer
** _void *data_: pointer
** _struct t_config_file *config_file_: configuration file pointer
** _int version_read_: version read in configuration file (1 by default)
** _struct t_hashtable *data_read_: hashtable with data read from configuration file
(see below)
** return value:
*** either "data_read" pointer (hashtable completed), or pointer to a new
hashtable (created by callback, with keys and values of type "string")
* _callback_update_pointer_: pointer given to callback when it is called by
WeeChat
* _callback_update_data_: pointer given to callback when it is called by
WeeChat; if not NULL, it must have been allocated with malloc (or similar
function) and it is automatically freed when the configuration file is freed
Update callback:
* The callback receives a hashtable with data read from configuration file:
[width="100%",cols="1m,2,8",options="header"]
|===
| Key | Availability | Value
| config | Always set | Name of configuration file, without extension (eg: `weechat`)
| section | Always set | Name of section being read
| option | For option only | Name of the option
| value | For option only | Value of the option (if not NULL)
| value_null | For option only | Option as NULL value (value is always `1`)
|===
* The callback can update "section" for a line with a section and "option", "value"
and "value_null" for a line with an option.
* If "option" is set to empty string by the callback, the line read in
configuration file is ignored.
* Field "value_null" is set to force a NULL value for the option.
戻り値:
* 1 if OK, 0 if error
C 言語での使用例:
[source,c]
----
struct t_hashtable *
my_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_section, *ptr_option;
/* return now if version is already up-to-date */
if (version_read >= 2)
return NULL;
ptr_section = hashtable_get (data_read, "section");
ptr_option = hashtable_get (data_read, "option");
/* rename section "abc" to "def" */
if (ptr_section && !ptr_option && (strcmp (ptr_section, "abc") == 0))
{
hashtable_set (data_read, "section", "def");
return data_read;
}
/* limit other changes to section "test" */
if (!ptr_section || !ptr_option || (strcmp (ptr_section, "test") != 0))
return NULL;
/* rename option "test1" to "test2" */
if (strcmp (ptr_option, "test1") == 0)
{
hashtable_set (data_read, "option", "test2");
return data_read;
}
/* set value to "xxx" for option "test" */
if (strcmp (ptr_option, "test") == 0)
{
hashtable_set (data_read, "value", "xxx");
return data_read;
}
/* set value to NULL for option "test_null" */
if (strcmp (ptr_option, "test_null") == 0)
{
hashtable_set (data_read, "value_null", "1");
return data_read;
}
/* no changes */
return NULL;
}
struct t_config_file *config_file = weechat_config_new ("test", NULL, NULL, NULL);
weechat_config_set_version (config_file, 2, &my_config_update_cb, NULL, NULL);
weechat_config_read (config_file);
----
スクリプト (Python) での使用例:
[source,python]
----
# プロトタイプ
def config_set_version(config_file: str, version: int, callback_update: str, callback_update_data: str) -> int: ...
# 例
def my_config_update_cb(data: str, config_file: str, version_read: int, data_read: Dict[str, str]) -> Dict[str, str]:
# return now if version is already up-to-date
if version_read >= 2:
return {}
section = data_read.get("section")
option = data_read.get("option")
# rename section "abc" to "def"
if section and not option and section == "abc":
data_read["section"] = "def"
return data_read
# limit other changes to section "test"
if not section or not option or section != "test":
return {}
# rename option "test1" to "test2"
if option == "test1":
data_read["option"] = "test2"
return data_read
# set value to "xxx" for option "test"
if option == "test":
data_read["value"] = "xxx"
return data_read
# set value to NULL for option "test_null"
if option == "test_null":
data_read["value_null"] = "1"
return data_read
# no changes
return {}
config_file = weechat.config_new("test", "", "")
weechat.config_set_version(config_file, 2, "my_config_update_cb", "")
weechat.config_read(config_file)
----
==== config_new_section
_WeeChat バージョン 1.5 で更新。_
+179 -2
View File
@@ -6136,7 +6136,7 @@ struct t_config_file *weechat_config_new (const char *name,
* _name_: име конфигурационог фајла (без путање или екстензије); приоритет
је дозвољен испред имена, у формату `nnn|име` где је `nnn` цео позитиван број
који представља приоритет; подразумевани приоритет је 1000; када се извршава
команда `/reload` фајлови се сортирају према приоритету, од вишег ка нижем
команда `/reload` фајлови се сортирају према приоритету, од вишег ка нижем
(погледајте приоритет конфигурационих фајлова испод)
* _callback_reload_: функција која се позива када се командом `/reload` поново учита конфигурациони фајл (није обавезна, може да буде NULL, погледајте испод), аргументи и повратна вредност су:
** _const void *pointer_: показивач
@@ -6199,6 +6199,183 @@ def my_config_reload_cb(data: str, config_file: str) -> int:
config_file = weechat.config_new("test", "my_config_reload_cb", "")
----
// TRANSLATION MISSING
==== config_set_version
_WeeChat ≥ 3.9._
Set configuration file version and a callback to update config sections/options
on-the-fly when the config is read.
Прототип:
[source,c]
----
int config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
----
Аргументи:
* _config_file_: configuration file pointer
* _version_: version, must be ≥ 2
* _callback_update_: function called when configuration file is read, for each
section and each option, if the version read is less than the expected version,
(optional, can be NULL, see below), arguments and return value:
** _const void *pointer_: pointer
** _void *data_: pointer
** _struct t_config_file *config_file_: configuration file pointer
** _int version_read_: version read in configuration file (1 by default)
** _struct t_hashtable *data_read_: hashtable with data read from configuration file
(see below)
** return value:
*** either "data_read" pointer (hashtable completed), or pointer to a new
hashtable (created by callback, with keys and values of type "string")
* _callback_update_pointer_: pointer given to callback when it is called by
WeeChat
* _callback_update_data_: pointer given to callback when it is called by
WeeChat; if not NULL, it must have been allocated with malloc (or similar
function) and it is automatically freed when the configuration file is freed
Update callback:
* The callback receives a hashtable with data read from configuration file:
[width="100%",cols="1m,2,8",options="header"]
|===
| Key | Availability | Value
| config | Always set | Name of configuration file, without extension (eg: `weechat`)
| section | Always set | Name of section being read
| option | For option only | Name of the option
| value | For option only | Value of the option (if not NULL)
| value_null | For option only | Option as NULL value (value is always `1`)
|===
* The callback can update "section" for a line with a section and "option", "value"
and "value_null" for a line with an option.
* If "option" is set to empty string by the callback, the line read in
configuration file is ignored.
* Field "value_null" is set to force a NULL value for the option.
Повратна вредност:
* 1 if OK, 0 if error
C пример:
[source,c]
----
struct t_hashtable *
my_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_section, *ptr_option;
/* return now if version is already up-to-date */
if (version_read >= 2)
return NULL;
ptr_section = hashtable_get (data_read, "section");
ptr_option = hashtable_get (data_read, "option");
/* rename section "abc" to "def" */
if (ptr_section && !ptr_option && (strcmp (ptr_section, "abc") == 0))
{
hashtable_set (data_read, "section", "def");
return data_read;
}
/* limit other changes to section "test" */
if (!ptr_section || !ptr_option || (strcmp (ptr_section, "test") != 0))
return NULL;
/* rename option "test1" to "test2" */
if (strcmp (ptr_option, "test1") == 0)
{
hashtable_set (data_read, "option", "test2");
return data_read;
}
/* set value to "xxx" for option "test" */
if (strcmp (ptr_option, "test") == 0)
{
hashtable_set (data_read, "value", "xxx");
return data_read;
}
/* set value to NULL for option "test_null" */
if (strcmp (ptr_option, "test_null") == 0)
{
hashtable_set (data_read, "value_null", "1");
return data_read;
}
/* no changes */
return NULL;
}
struct t_config_file *config_file = weechat_config_new ("test", NULL, NULL, NULL);
weechat_config_set_version (config_file, 2, &my_config_update_cb, NULL, NULL);
weechat_config_read (config_file);
----
Script (Python):
[source,python]
----
# прототип
def config_set_version(config_file: str, version: int, callback_update: str, callback_update_data: str) -> int: ...
# пример
def my_config_update_cb(data: str, config_file: str, version_read: int, data_read: Dict[str, str]) -> Dict[str, str]:
# return now if version is already up-to-date
if version_read >= 2:
return {}
section = data_read.get("section")
option = data_read.get("option")
# rename section "abc" to "def"
if section and not option and section == "abc":
data_read["section"] = "def"
return data_read
# limit other changes to section "test"
if not section or not option or section != "test":
return {}
# rename option "test1" to "test2"
if option == "test1":
data_read["option"] = "test2"
return data_read
# set value to "xxx" for option "test"
if option == "test":
data_read["value"] = "xxx"
return data_read
# set value to NULL for option "test_null"
if option == "test_null":
data_read["value_null"] = "1"
return data_read
# no changes
return {}
config_file = weechat.config_new("test", "", "")
weechat.config_set_version(config_file, 2, "my_config_update_cb", "")
weechat.config_read(config_file)
----
==== config_new_section
_Ажурирано у верзији 1.5._
@@ -10993,7 +11170,7 @@ struct t_hook *weechat_hook_signal (const char *signal,
| weechat | [[hook_signal_upgrade]] upgrade |
| Стринг: „quit” ако је уз /upgrade наведен аргумент „-quit”, „save”
ако је уз /upgrade наведен аргумент „-save”, у супротном NULL.
ако је уз /upgrade наведен аргумент „-save”, у супротном NULL.
| Корисник је задао команду `/upgrade`.
| weechat | [[hook_signal_upgrade_ended]] upgrade_ended | 0.3.4
+241 -23
View File
@@ -37,6 +37,7 @@
#include "wee-config-file.h"
#include "wee-arraylist.h"
#include "wee-config.h"
#include "wee-hashtable.h"
#include "wee-hdata.h"
#include "wee-hook.h"
#include "wee-infolist.h"
@@ -239,6 +240,10 @@ config_file_new (struct t_weechat_plugin *plugin, const char *name,
return NULL;
}
new_config_file->file = NULL;
new_config_file->version = 1;
new_config_file->callback_update = NULL;
new_config_file->callback_update_pointer = NULL;
new_config_file->callback_update_data = NULL;
new_config_file->callback_reload = callback_reload;
new_config_file->callback_reload_pointer = callback_reload_pointer;
new_config_file->callback_reload_data = callback_reload_data;
@@ -251,6 +256,38 @@ config_file_new (struct t_weechat_plugin *plugin, const char *name,
return new_config_file;
}
/*
* Sets configuration file version and a callback to update config
* sections/options on-the-fly when the config is read.
*
* Returns:
* 1: OK
* 0: error
*/
int
config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data)
{
if (version < 1)
return 0;
config_file->version = version;
config_file->callback_update = callback_update;
config_file->callback_update_pointer = callback_update_pointer;
config_file->callback_update_data = callback_update_data;
return 1;
}
/*
* Compares two configuration files to sort them by priority (highest priority
* at beginning of list).
@@ -2693,6 +2730,17 @@ config_file_write_internal (struct t_config_file *config_file,
goto error;
}
/* write config version (if different from 1) */
if (config_file->version > 1)
{
if (!string_fprintf (config_file->file,
"\nconfig_version = %d\n",
config_file->version))
{
goto error;
}
}
/* write all sections */
for (ptr_section = config_file->sections; ptr_section;
ptr_section = ptr_section->next_section)
@@ -2796,6 +2844,142 @@ config_file_write (struct t_config_file *config_file)
return config_file_write_internal (config_file, 0);
}
/*
* Parses configuration version.
*
* Returns:
* >= 1: configuration version
* -1: error
*/
int
config_file_parse_version (const char *version)
{
long number;
char *error;
number = strtoll (version, &error, 10);
if (!error || error[0])
return -1;
return (number < 1) ? -1 : (int)number;
}
/*
* Updates data read from config file: either section or option + value.
* The update callback (if defined in config) is called if the config version
* read in file is less than to the current config version.
*
* Parameters "section", "option" and "value" are updated in place: if the
* callback gives a new value, they are first freed and allocated again with
* the new value (or set to NULL for the value if the callback returns
* special key "value_null").
*
* Section can be updated only if option and value are NULL (ie if we are
* reading a section line like "[section]").
*/
void
config_file_update_data_read (struct t_config_file *config_file,
const char *section,
const char *option,
const char *value,
char **ret_section,
char **ret_option,
char **ret_value)
{
struct t_hashtable *data_read, *hashtable;
const char *ptr_section, *ptr_option, *ptr_value;
int value_null;
/* do nothing if config is already the latest version */
if (config_file->version_read >= config_file->version)
return;
/* do nothing if there's no update callback */
if (!config_file->callback_update)
return;
value_null = 0;
data_read = hashtable_new (
32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!data_read)
return;
hashtable_set (data_read, "config", config_file->name);
if (section)
hashtable_set (data_read, "section", section);
if (option)
{
hashtable_set (data_read, "option", option);
if (value)
{
hashtable_set (data_read, "value", value);
}
else
{
hashtable_set (data_read, "value_null", "1");
value_null = 1;
}
}
hashtable = (config_file->callback_update)
(config_file->callback_update_pointer,
config_file->callback_update_data,
config_file,
config_file->version_read,
data_read);
if (hashtable)
{
/* if reading a section line, we can update its name */
if (section && !option && ret_section)
{
ptr_section = hashtable_get (hashtable, "section");
if (ptr_section && ptr_section[0])
{
if (*ret_section)
free (*ret_section);
*ret_section = strdup (ptr_section);
}
}
/* if reading an option line, we can update its name and value */
if (section && option)
{
/* option name */
if (ret_option)
{
ptr_option = hashtable_get (hashtable, "option");
if (ptr_option)
{
if (*ret_option)
free (*ret_option);
*ret_option = strdup (ptr_option);
}
}
/* value */
if (ret_value)
{
ptr_value = hashtable_get (hashtable, "value");
if (!value_null && hashtable_has_key (hashtable, "value_null"))
ptr_value = NULL;
if (*ret_value)
free (*ret_value);
*ret_value = (ptr_value) ? strdup (ptr_value) : NULL;
}
}
}
if (hashtable && (hashtable != data_read))
hashtable_free (hashtable);
hashtable_free (data_read);
}
/*
* Reads a configuration file (this function must not be called directly).
*
@@ -2808,7 +2992,7 @@ config_file_write (struct t_config_file *config_file)
int
config_file_read_internal (struct t_config_file *config_file, int reload)
{
int filename_length, line_number, rc, length;
int filename_length, line_number, rc, length, version;
char *filename, *section, *option, *value;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
@@ -2817,6 +3001,8 @@ config_file_read_internal (struct t_config_file *config_file, int reload)
if (!config_file)
return WEECHAT_CONFIG_READ_FILE_NOT_FOUND;
config_file->version_read = 1;
/* build filename */
filename_length = strlen (weechat_config_dir) + strlen (DIR_SEPARATOR) +
strlen (config_file->filename) + 1;
@@ -2911,6 +3097,9 @@ config_file_read_internal (struct t_config_file *config_file, int reload)
section = string_strndup (ptr_line + 1, pos - ptr_line - 1);
if (section)
{
config_file_update_data_read (config_file,
section, NULL, NULL,
&section, NULL, NULL);
ptr_section = config_file_search_section (config_file,
section);
if (!ptr_section)
@@ -2983,7 +3172,46 @@ config_file_read_internal (struct t_config_file *config_file, int reload)
option = strdup (ptr_line);
}
if (ptr_section && ptr_section->callback_read)
if (!ptr_section && (strcmp (option, CONFIG_VERSION_OPTION) == 0))
{
version = config_file_parse_version (pos);
if (version < 0)
{
gui_chat_printf (
NULL,
_("%sWarning: %s, line %d: invalid config "
"version: %s"),
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
filename, line_number,
line);
}
else
{
config_file->version_read = version;
}
continue;
}
if (!ptr_section)
{
gui_chat_printf (NULL,
_("%sWarning: %s, line %d: "
"option outside section: %s"),
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
filename, line_number,
line);
continue;
}
config_file_update_data_read (config_file,
ptr_section->name, option, value,
NULL, &option, &value);
/* option has been ignored by the update callback? */
if (!option || !option[0])
continue;
if (ptr_section->callback_read)
{
ptr_option = NULL;
rc = (ptr_section->callback_read)
@@ -3007,8 +3235,7 @@ config_file_read_internal (struct t_config_file *config_file, int reload)
}
else
{
if (ptr_section
&& ptr_section->callback_create_option)
if (ptr_section->callback_create_option)
{
rc = (int) (ptr_section->callback_create_option) (
ptr_section->callback_create_option_pointer,
@@ -3024,25 +3251,13 @@ config_file_read_internal (struct t_config_file *config_file, int reload)
switch (rc)
{
case WEECHAT_CONFIG_OPTION_SET_OPTION_NOT_FOUND:
if (ptr_section)
{
gui_chat_printf (NULL,
_("%sWarning: %s, line %d: "
"unknown option for section \"%s\": %s"),
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
filename, line_number,
ptr_section->name,
line);
}
else
{
gui_chat_printf (NULL,
_("%sWarning: %s, line %d: "
"option outside section: %s"),
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
filename, line_number,
line);
}
gui_chat_printf (NULL,
_("%sWarning: %s, line %d: "
"unknown option for section \"%s\": %s"),
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
filename, line_number,
ptr_section->name,
line);
break;
case WEECHAT_CONFIG_OPTION_SET_ERROR:
gui_chat_printf (NULL,
@@ -3315,6 +3530,8 @@ config_file_free (struct t_config_file *config_file)
(config_file->next_config)->prev_config = config_file->prev_config;
/* free data */
if (config_file->callback_update_data)
free (config_file->callback_update_data);
if (config_file->callback_reload_data)
free (config_file->callback_reload_data);
@@ -3380,6 +3597,7 @@ config_file_hdata_config_file_cb (const void *pointer, void *data,
HDATA_VAR(struct t_config_file, name, STRING, 0, NULL, NULL);
HDATA_VAR(struct t_config_file, filename, STRING, 0, NULL, NULL);
HDATA_VAR(struct t_config_file, file, POINTER, 0, NULL, NULL);
HDATA_VAR(struct t_config_file, version, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_config_file, callback_reload, POINTER, 0, NULL, NULL);
HDATA_VAR(struct t_config_file, callback_reload_pointer, POINTER, 0, NULL, NULL);
HDATA_VAR(struct t_config_file, callback_reload_data, POINTER, 0, NULL, NULL);
+22 -1
View File
@@ -23,6 +23,8 @@
#include <stdio.h>
#define CONFIG_VERSION_OPTION "config_version"
#define CONFIG_PRIORITY_DEFAULT 1000
#define CONFIG_BOOLEAN(option) (*((int *)((option)->value)))
@@ -54,7 +56,17 @@ struct t_config_file
char *filename; /* filename (without path) */
/* (example: "weechat.conf") */
FILE *file; /* file pointer */
int (*callback_reload) /* callback for reloading file */
int version; /* config version (default=1) */
int version_read; /* config version read in file */
struct t_hashtable *(*callback_update) /* callback for version update */
(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read);
const void *callback_update_pointer; /* pointer sent to callback */
void *callback_update_data; /* data sent to callback */
int (*callback_reload) /* callback for config reload */
(const void *pointer,
void *data,
struct t_config_file *config_file);
@@ -178,6 +190,15 @@ extern struct t_config_file *config_file_new (struct t_weechat_plugin *plugin,
struct t_config_file *config_file),
const void *callback_reload_pointer,
void *callback_reload_data);
extern int config_file_set_version (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
extern struct t_arraylist *config_file_get_configs_by_priority ();
extern struct t_config_section *config_file_new_section (struct t_config_file *config_file,
const char *name,
+57
View File
@@ -902,6 +902,62 @@ weechat_guile_api_config_new (SCM name, SCM function, SCM data)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_guile_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = weechat_guile_exec (script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
SCM
weechat_guile_api_config_set_version (SCM config_file, SCM version,
SCM function, SCM data)
{
int rc;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
if (!scm_is_string (config_file) || !scm_is_integer (version)
|| !scm_is_string (function) || !scm_is_string (data))
API_WRONG_ARGS(API_RETURN_INT(0));
rc = plugin_script_api_config_set_version (
weechat_guile_plugin,
guile_current_script,
API_STR2PTR(API_SCM_TO_STRING(config_file)),
scm_to_int (version),
&weechat_guile_api_config_update_cb,
API_SCM_TO_STRING(function),
API_SCM_TO_STRING(data));
API_RETURN_INT(rc);
}
int
weechat_guile_api_config_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -5150,6 +5206,7 @@ weechat_guile_api_module_init (void *data)
API_DEF_FUNC(list_remove_all, 1);
API_DEF_FUNC(list_free, 1);
API_DEF_FUNC(config_new, 3);
API_DEF_FUNC(config_set_version, 4);
API_DEF_FUNC(config_new_section, 1);
API_DEF_FUNC(config_search_section, 2);
API_DEF_FUNC(config_new_option, 1);
+58
View File
@@ -835,6 +835,63 @@ API_FUNC(config_new)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_js_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = (struct t_hashtable *)weechat_js_exec (
script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
API_FUNC(config_set_version)
{
int rc, version;
API_INIT_FUNC(1, "config_set_version", "siss", API_RETURN_INT(0));
v8::String::Utf8Value config_file(args[0]);
version = args[1]->IntegerValue();
v8::String::Utf8Value function(args[2]);
v8::String::Utf8Value data(args[3]);
rc = plugin_script_api_config_set_version (
weechat_js_plugin,
js_current_script,
(struct t_config_file *)API_STR2PTR(*config_file),
version,
&weechat_js_api_config_update_cb,
*function,
*data);
API_RETURN_INT(rc);
}
int
weechat_js_api_config_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -5092,6 +5149,7 @@ WeechatJsV8::loadLibs()
API_DEF_FUNC(list_remove_all);
API_DEF_FUNC(list_free);
API_DEF_FUNC(config_new);
API_DEF_FUNC(config_set_version);
API_DEF_FUNC(config_new_section);
API_DEF_FUNC(config_search_section);
API_DEF_FUNC(config_new_option);
+60
View File
@@ -940,6 +940,65 @@ API_FUNC(config_new)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_lua_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = weechat_lua_exec (script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
API_FUNC(config_set_version)
{
const char *config_file, *function, *data;
int rc, version;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
if (lua_gettop (L) < 4)
API_WRONG_ARGS(API_RETURN_INT(0));
config_file = lua_tostring (L, -4);
version = lua_tonumber (L, -3);
function = lua_tostring (L, -2);
data = lua_tostring (L, -1);
rc = plugin_script_api_config_set_version (
weechat_lua_plugin,
lua_current_script,
API_STR2PTR(config_file),
version,
&weechat_lua_api_config_update_cb,
function,
data);
API_RETURN_INT(rc);
}
int
weechat_lua_api_config_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -5451,6 +5510,7 @@ const struct luaL_Reg weechat_lua_api_funcs[] = {
API_DEF_FUNC(list_remove_all),
API_DEF_FUNC(list_free),
API_DEF_FUNC(config_new),
API_DEF_FUNC(config_set_version),
API_DEF_FUNC(config_new_section),
API_DEF_FUNC(config_search_section),
API_DEF_FUNC(config_new_option),
+63 -3
View File
@@ -881,6 +881,65 @@ API_FUNC(config_new)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_perl_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = weechat_perl_exec (script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
API_FUNC(config_set_version)
{
char *config_file, *function, *data;
int rc;
dXSARGS;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
if (items < 4)
API_WRONG_ARGS(API_RETURN_INT(0));
config_file = SvPV_nolen (ST (0));
function = SvPV_nolen (ST (2));
data = SvPV_nolen (ST (3));
rc = plugin_script_api_config_set_version (
weechat_perl_plugin,
perl_current_script,
API_STR2PTR(config_file),
SvIV (ST (1)), /* version */
&weechat_perl_api_config_update_cb,
function,
data);
API_RETURN_INT(rc);
}
int
weechat_perl_api_config_section_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -1088,7 +1147,7 @@ weechat_perl_api_config_section_delete_option_cb (const void *pointer, void *dat
API_FUNC(config_new_section)
{
char *cfg_file, *name, *function_read, *data_read;
char *config_file, *name, *function_read, *data_read;
char *function_write, *data_write, *function_write_default;
char *data_write_default, *function_create_option, *data_create_option;
char *function_delete_option, *data_delete_option;
@@ -1100,7 +1159,7 @@ API_FUNC(config_new_section)
if (items < 14)
API_WRONG_ARGS(API_RETURN_EMPTY);
cfg_file = SvPV_nolen (ST (0));
config_file = SvPV_nolen (ST (0));
name = SvPV_nolen (ST (1));
function_read = SvPV_nolen (ST (4));
data_read = SvPV_nolen (ST (5));
@@ -1117,7 +1176,7 @@ API_FUNC(config_new_section)
plugin_script_api_config_new_section (
weechat_perl_plugin,
perl_current_script,
API_STR2PTR(cfg_file),
API_STR2PTR(config_file),
name,
SvIV (ST (2)), /* user_can_add_options */
SvIV (ST (3)), /* user_can_delete_options */
@@ -5400,6 +5459,7 @@ weechat_perl_api_init (pTHX)
API_DEF_FUNC(list_remove_all);
API_DEF_FUNC(list_free);
API_DEF_FUNC(config_new);
API_DEF_FUNC(config_set_version);
API_DEF_FUNC(config_new_section);
API_DEF_FUNC(config_search_section);
API_DEF_FUNC(config_new_option);
+52
View File
@@ -1072,6 +1072,58 @@ API_FUNC(config_new)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_php_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_hashtable *rc;
void *func_argv[4];
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
weechat_php_cb (pointer, data, func_argv, "ssih",
WEECHAT_SCRIPT_EXEC_HASHTABLE, &rc);
return rc;
}
API_FUNC(config_set_version)
{
zend_string *z_config_file;
zend_long z_version;
zval *z_callback_update;
zend_string *z_data;
struct t_config_file *config_file;
char *data;
int rc, version;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
if (zend_parse_parameters (ZEND_NUM_ARGS(), "SlzS", &z_config_file,
&z_version, &z_callback_update,
&z_data) == FAILURE)
API_WRONG_ARGS(API_RETURN_INT(0));
config_file = (struct t_config_file *)API_STR2PTR(ZSTR_VAL(z_config_file));
version = (int)z_version;
weechat_php_get_function_name (z_callback_update, callback_update_name);
data = ZSTR_VAL(z_data);
rc = plugin_script_api_config_set_version (
weechat_php_plugin,
php_current_script,
config_file,
version,
&weechat_php_api_config_update_cb,
(const char *)callback_update_name,
(const char *)data);
API_RETURN_INT(rc);
}
static int
weechat_php_api_config_section_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
+1
View File
@@ -85,6 +85,7 @@ PHP_FUNCTION(weechat_list_remove);
PHP_FUNCTION(weechat_list_remove_all);
PHP_FUNCTION(weechat_list_free);
PHP_FUNCTION(weechat_config_new);
PHP_FUNCTION(weechat_config_set_version);
PHP_FUNCTION(weechat_config_new_section);
PHP_FUNCTION(weechat_config_search_section);
PHP_FUNCTION(weechat_config_new_option);
+1
View File
@@ -143,6 +143,7 @@ const zend_function_entry weechat_functions[] = {
PHP_FE(weechat_list_remove_all, arginfo_weechat_list_remove_all)
PHP_FE(weechat_list_free, arginfo_weechat_list_free)
PHP_FE(weechat_config_new, arginfo_weechat_config_new)
PHP_FE(weechat_config_set_version, arginfo_weechat_config_set_version)
PHP_FE(weechat_config_new_section, arginfo_weechat_config_new_section)
PHP_FE(weechat_config_search_section, arginfo_weechat_config_search_section)
PHP_FE(weechat_config_new_option, arginfo_weechat_config_new_option)
+1
View File
@@ -51,6 +51,7 @@ function weechat_list_remove(string $p0, string $p1): int {}
function weechat_list_remove_all(string $p0): int {}
function weechat_list_free(string $p0): int {}
function weechat_config_new(string $p0, mixed $p1, string $p2): string {}
function weechat_config_set_version(string $p0, int $p1, mixed $p2, string $p3): int {}
function weechat_config_new_section(): string {}
function weechat_config_search_section(string $p0, string $p1): string {}
function weechat_config_new_option(): string {}
+8 -1
View File
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: a89a2f8dfa145afbf1c86bf246715c88babebb07 */
* Stub hash: 5c460494eac0e2ed6729ab210df6679f990070d6 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_weechat_register, 0, 7, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, p0, IS_STRING, 0)
@@ -130,6 +130,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_weechat_config_new, 0, 3, IS_STR
ZEND_ARG_TYPE_INFO(0, p2, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_weechat_config_set_version, 0, 4, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, p0, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, p1, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, p2, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, p3, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_weechat_config_new_section arginfo_weechat_list_new
#define arginfo_weechat_config_search_section arginfo_weechat_iconv_to_internal
+4 -2
View File
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: a89a2f8dfa145afbf1c86bf246715c88babebb07 */
* Stub hash: 5c460494eac0e2ed6729ab210df6679f990070d6 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_weechat_register, 0, 0, 7)
ZEND_ARG_INFO(0, p0)
@@ -46,7 +46,7 @@ ZEND_END_ARG_INFO()
#define arginfo_weechat_string_format_size arginfo_weechat_plugin_get_name
#define arginfo_weechat_string_parse_size arginfo_weechat_charset_set
#define arginfo_weechat_string_parse_size arginfo_weechat_plugin_get_name
#define arginfo_weechat_string_color_code_size arginfo_weechat_plugin_get_name
@@ -104,6 +104,8 @@ ZEND_END_ARG_INFO()
#define arginfo_weechat_config_new arginfo_weechat_ngettext
#define arginfo_weechat_config_set_version arginfo_weechat_string_eval_expression
#define arginfo_weechat_config_new_section arginfo_weechat_list_new
#define arginfo_weechat_config_search_section arginfo_weechat_iconv_to_internal
+43 -5
View File
@@ -110,15 +110,53 @@ plugin_script_api_config_new (struct t_weechat_plugin *weechat_plugin,
script,
function_and_data);
if (!new_config_file)
{
if (function_and_data)
free (function_and_data);
}
if (!new_config_file && function_and_data)
free (function_and_data);
return new_config_file;
}
/*
* Sets configuration file version and a callback to update config
* sections/options on-the-fly when the config is read.
*
* Returns pointer to new configuration file, NULL if error.
*/
int
plugin_script_api_config_set_version (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const char *function,
const char *data)
{
char *function_and_data;
int rc;
if (!script)
return 0;
function_and_data = plugin_script_build_function_and_data (function, data);
rc = weechat_config_set_version (
config_file,
version,
(function_and_data) ? callback_update : NULL,
script,
function_and_data);
if (!rc && function_and_data)
free (function_and_data);
return rc;
}
/*
* Creates a new section in configuration file.
*
+11
View File
@@ -37,6 +37,17 @@ extern struct t_config_file *plugin_script_api_config_new (struct t_weechat_plug
struct t_config_file *config_file),
const char *function,
const char *data);
extern int plugin_script_api_config_set_version (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const char *function,
const char *data);
extern struct t_config_section *plugin_script_api_config_new_section (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
struct t_config_file *config_file,
+1
View File
@@ -736,6 +736,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
new_plugin->hashtable_free = &hashtable_free;
new_plugin->config_new = &config_file_new;
new_plugin->config_set_version = &config_file_set_version;
new_plugin->config_new_section = &config_file_new_section;
new_plugin->config_search_section = &config_file_search_section;
new_plugin->config_new_option = &config_file_new_option;
+59
View File
@@ -869,6 +869,64 @@ API_FUNC(config_new)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_python_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = weechat_python_exec (script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
API_FUNC(config_set_version)
{
char *config_file, *function, *data;
int rc, version;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
config_file = NULL;
version = 0;
function = NULL;
data = NULL;
if (!PyArg_ParseTuple (args, "siss", &config_file, &version, &function, &data))
API_WRONG_ARGS(API_RETURN_INT(0));
rc = plugin_script_api_config_set_version (
weechat_python_plugin,
python_current_script,
API_STR2PTR(config_file),
version,
&weechat_python_api_config_update_cb,
function,
data);
API_RETURN_INT(rc);
}
int
weechat_python_api_config_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -5315,6 +5373,7 @@ PyMethodDef weechat_python_funcs[] =
API_DEF_FUNC(list_remove_all),
API_DEF_FUNC(list_free),
API_DEF_FUNC(config_new),
API_DEF_FUNC(config_set_version),
API_DEF_FUNC(config_new_section),
API_DEF_FUNC(config_search_section),
API_DEF_FUNC(config_new_option),
+47
View File
@@ -481,6 +481,53 @@ def config_new(name: str, callback_reload: str, callback_reload_data: str) -> st
...
def config_set_version(config_file: str, version: int, callback_update: str, callback_update_data: str) -> int:
"""`config_set_version in WeeChat plugin API reference <https://weechat.org/doc/api/#_config_set_version>`_
::
# example
def my_config_update_cb(data: str, config_file: str, version_read: int, data_read: Dict[str, str]) -> Dict[str, str]:
# return now if version is already up-to-date
if version_read >= 2:
return {}
section = data_read.get("section")
option = data_read.get("option")
# rename section "abc" to "def"
if section and not option and section == "abc":
data_read["section"] = "def"
return data_read
# limit other changes to section "test"
if not section or not option or section != "test":
return {}
# rename option "test1" to "test2"
if option == "test1":
data_read["option"] = "test2"
return data_read
# set value to "xxx" for option "test"
if option == "test":
data_read["value"] = "xxx"
return data_read
# set value to NULL for option "test_null"
if option == "test_null":
data_read["value_null"] = "1"
return data_read
# no changes
return {}
config_file = weechat.config_new("test", "", "")
weechat.config_set_version(config_file, 2, "my_config_update_cb", "")
weechat.config_read(config_file)
"""
...
def config_new_section(config_file: str, name: str,
user_can_add_options: int, user_can_delete_options: int,
callback_read: str, callback_read_data: str,
+69
View File
@@ -1077,6 +1077,74 @@ weechat_ruby_api_config_new (VALUE class, VALUE name, VALUE function,
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_ruby_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = weechat_ruby_exec (script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
static VALUE
weechat_ruby_api_config_set_version (VALUE class, VALUE config_file,
VALUE version, VALUE function,
VALUE data)
{
char *c_config_file, *c_function, *c_data;
int rc, c_version;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
if (NIL_P (config_file) || NIL_P (version) || NIL_P (function)
|| NIL_P (data))
API_WRONG_ARGS(API_RETURN_INT(0));
Check_Type (config_file, T_STRING);
CHECK_INTEGER(version);
Check_Type (function, T_STRING);
Check_Type (data, T_STRING);
c_config_file = StringValuePtr (config_file);
c_version = NUM2INT (version);
c_function = StringValuePtr (function);
c_data = StringValuePtr (data);
rc = plugin_script_api_config_set_version (
weechat_ruby_plugin,
ruby_current_script,
API_STR2PTR(c_config_file),
c_version,
&weechat_ruby_api_config_update_cb,
c_function,
c_data);
API_RETURN_INT(rc);
}
int
weechat_ruby_api_config_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -6600,6 +6668,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat)
API_DEF_FUNC(list_remove_all, 1);
API_DEF_FUNC(list_free, 1);
API_DEF_FUNC(config_new, 3);
API_DEF_FUNC(config_set_version, 4);
API_DEF_FUNC(config_new_section, 14);
API_DEF_FUNC(config_search_section, 2);
API_DEF_FUNC(config_new_option, 12);
+67 -3
View File
@@ -1080,6 +1080,69 @@ API_FUNC(config_new)
API_RETURN_STRING(result);
}
struct t_hashtable *
weechat_tcl_api_config_update_cb (const void *pointer, void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read)
{
struct t_plugin_script *script;
void *func_argv[4];
char empty_arg[1] = { '\0' };
const char *ptr_function, *ptr_data;
struct t_hashtable *ret_hashtable;
script = (struct t_plugin_script *)pointer;
plugin_script_get_function_and_data (data, &ptr_function, &ptr_data);
if (ptr_function && ptr_function[0])
{
func_argv[0] = (ptr_data) ? (char *)ptr_data : empty_arg;
func_argv[1] = (char *)API_PTR2STR(config_file);
func_argv[2] = &version_read;
func_argv[3] = data_read;
ret_hashtable = weechat_tcl_exec (script,
WEECHAT_SCRIPT_EXEC_HASHTABLE,
ptr_function,
"ssih", func_argv);
return ret_hashtable;
}
return NULL;
}
API_FUNC(config_set_version)
{
Tcl_Obj *objp;
char *config_file, *function, *data;
int i, rc, version;
API_INIT_FUNC(1, "config_set_version", API_RETURN_INT(0));
if (objc < 5)
API_WRONG_ARGS(API_RETURN_INT(0));
if (Tcl_GetIntFromObj (interp, objv[2], &version) != TCL_OK)
API_WRONG_ARGS(API_RETURN_EMPTY);
config_file = Tcl_GetStringFromObj (objv[1], &i);
function = Tcl_GetStringFromObj (objv[3], &i);
data = Tcl_GetStringFromObj (objv[4], &i);
rc = plugin_script_api_config_set_version (
weechat_tcl_plugin,
tcl_current_script,
API_STR2PTR(config_file),
version,
&weechat_tcl_api_config_update_cb,
function,
data);
API_RETURN_INT(rc);
}
int
weechat_tcl_api_config_section_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
@@ -1287,7 +1350,7 @@ weechat_tcl_api_config_section_delete_option_cb (const void *pointer, void *data
API_FUNC(config_new_section)
{
Tcl_Obj *objp;
char *cfg_file, *name, *function_read, *data_read;
char *config_file, *name, *function_read, *data_read;
char *function_write, *data_write, *function_write_default;
char *data_write_default, *function_create_option, *data_create_option;
char *function_delete_option, *data_delete_option;
@@ -1305,7 +1368,7 @@ API_FUNC(config_new_section)
|| (Tcl_GetIntFromObj (interp, objv[4], &can_delete) != TCL_OK))
API_WRONG_ARGS(API_RETURN_EMPTY);
cfg_file = Tcl_GetStringFromObj (objv[1], &i);
config_file = Tcl_GetStringFromObj (objv[1], &i);
name = Tcl_GetStringFromObj (objv[2], &i);
function_read = Tcl_GetStringFromObj (objv[5], &i);
data_read = Tcl_GetStringFromObj (objv[6], &i);
@@ -1322,7 +1385,7 @@ API_FUNC(config_new_section)
plugin_script_api_config_new_section (
weechat_tcl_plugin,
tcl_current_script,
API_STR2PTR(cfg_file),
API_STR2PTR(config_file),
name,
can_add, /* user_can_add_options */
can_delete, /* user_can_delete_options */
@@ -5904,6 +5967,7 @@ void weechat_tcl_api_init (Tcl_Interp *interp)
API_DEF_FUNC(list_remove_all);
API_DEF_FUNC(list_free);
API_DEF_FUNC(config_new);
API_DEF_FUNC(config_set_version);
API_DEF_FUNC(config_new_section);
API_DEF_FUNC(config_search_section);
API_DEF_FUNC(config_new_option);
+18 -1
View File
@@ -68,7 +68,7 @@ struct timeval;
* please change the date with current one; for a second change at same
* date, increment the 01, otherwise please keep 01.
*/
#define WEECHAT_PLUGIN_API_VERSION "20221224-02"
#define WEECHAT_PLUGIN_API_VERSION "20230220-01"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@@ -529,6 +529,15 @@ struct t_weechat_plugin
struct t_config_file *config_file),
const void *callback_reload_pointer,
void *callback_reload_data);
int (*config_set_version) (struct t_config_file *config_file,
int version,
struct t_hashtable *(*callback_update)(const void *pointer,
void *data,
struct t_config_file *config_file,
int version_read,
struct t_hashtable *data_read),
const void *callback_update_pointer,
void *callback_update_data);
struct t_config_section *(*config_new_section) (struct t_config_file *config_file,
const char *name,
int user_can_add_options,
@@ -1573,6 +1582,14 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
__callback_reload, \
__callback_reload_pointer, \
__callback_reload_data)
#define weechat_config_set_version(__config, __version, \
__callback_update, \
__callback_update_pointer, \
__callback_update_data) \
(weechat_plugin->config_set_version)(__config, __version, \
__callback_update, \
__callback_update_pointer, \
__callback_update_data)
#define weechat_config_new_section(__config, __name, \
__user_can_add_options, \
__user_can_delete_options, \
+8
View File
@@ -151,6 +151,11 @@ def config_reload_cb(data, config_file):
return weechat.WEECHAT_RC_OK
def config_update_cb(data, config_file, version, data_read):
"""Config update callback."""
return weechat.WEECHAT_RC_OK
def section_read_cb(data, config_file, section, option_name, value):
"""Section read callback."""
return weechat.WEECHAT_RC_OK
@@ -199,6 +204,9 @@ def test_config():
'config_reload_cb', 'config_reload_data',
)
check(ptr_config != '')
# set version
weechat.config_set_version(ptr_config, 2,
'config_update_cb', 'config_update_data')
# section
ptr_section = weechat.config_new_section(
ptr_config, 'section1', 0, 0,
+10
View File
@@ -106,6 +106,16 @@ TEST(CoreConfigFile, New)
/* TODO: write tests */
}
/*
* Tests functions:
* config_file_set_version
*/
TEST(CoreConfigFile, SetVersion)
{
/* TODO: write tests */
}
/*
* Tests functions:
* config_file_arraylist_cmp_config_cb