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:
@@ -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._
|
||||
|
||||
@@ -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._
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 で更新。_
|
||||
|
||||
@@ -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
@@ -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,
|
||||
§ion, 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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, \
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user