diff --git a/CHANGELOG.md b/CHANGELOG.md index da4339013..e392beac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - core: add option weechat.completion.cycle - core: add hdata for hooks +- api: add functions util_parse_int, util_parse_long and util_parse_longlong ### Removed diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc index 06e589eb4..a13ace9f0 100644 --- a/doc/en/weechat_plugin_api.en.adoc +++ b/doc/en/weechat_plugin_api.en.adoc @@ -4666,6 +4666,159 @@ This function is not available in scripting API. Some useful functions. +==== util_parse_int + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "int" in a string. + +Prototype: + +[source,c] +---- +int weechat_util_parse_int (const char *string, int base, int *result); +---- + +Arguments: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Return value: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < INT_MIN (min value for a variable of type "int") +* number > INT_MAX (max value for a variable of type "int") +* invalid integer for the given _base_ + +C examples: + +[source,c] +---- +int number; +if (weechat_util_parse_int ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_int ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +This function is not available in scripting API. + +==== util_parse_long + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long" in a string. + +Prototype: + +[source,c] +---- +int weechat_util_parse_long (const char *string, int base, long *result); +---- + +Arguments: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Return value: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LONG_MIN (min value for a variable of type "long") +* number > LONG_MAX (max value for a variable of type "long") +* invalid integer for the given _base_ + +C examples: + +[source,c] +---- +long number; +if (weechat_util_parse_long ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_long ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +This function is not available in scripting API. + +==== util_parse_longlong + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long long" in a string. + +Prototype: + +[source,c] +---- +int weechat_util_parse_longlong (const char *string, int base, long long *result); +---- + +Arguments: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Return value: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LLONG_MIN (min value for a variable of type "long long") +* number > LLONG_MAX (max value for a variable of type "long long") +* invalid integer for the given _base_ + +C examples: + +[source,c] +---- +long long number; +if (weechat_util_parse_longlong ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_longlong ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +This function is not available in scripting API. + ==== util_timeval_cmp Compare two "timeval" structures. diff --git a/doc/fr/weechat_plugin_api.fr.adoc b/doc/fr/weechat_plugin_api.fr.adoc index fb8cbee4b..53fcf0e88 100644 --- a/doc/fr/weechat_plugin_api.fr.adoc +++ b/doc/fr/weechat_plugin_api.fr.adoc @@ -4745,6 +4745,159 @@ This function is not available in scripting API. Quelques fonctions utiles. +==== util_parse_int + +_WeeChat ≥ 4.8.0._ + +Analyser un nombre entier de type "int" dans une chaîne. + +Prototype : + +[source,c] +---- +int weechat_util_parse_int (const char *string, int base, int *result); +---- + +Paramètres : + +* _string_ : chaîne à analyser +* _base_ : peut être 0 (automatique) ou un entier entre 2 et 36 (inclus) +* _result_ : pointeur vers une variable mise à jour si la chaîne est correctement analysée + (si le pointeur est NULL, le nombre trouvé n'est pas retourné) + +Valeur de retour : + +* 1 : OK +* 0 : erreur + +Les chaînes suivantes sont invalides et la fonction retourne 0 : + +* chaîne vide +* nombre avec des caractères non numériques après +* nombre < INT_MIN (valeur minimale pour une variable de type "int") +* nombre > INT_MAX (valeur maximale pour une variable de type "int") +* entier invalide pour la _base_ donnée + +Exemples en C : + +[source,c] +---- +int nombre; +if (weechat_util_parse_int ("1234", 10, &nombre)) +{ + /* nombre == 1234 */ +} +if (!weechat_util_parse_int ("abc", 10, &nombre)) +{ + /* erreur d'analyse, nombre est inchangé */ +} +---- + +[NOTE] +Cette fonction n'est pas disponible dans l'API script. + +==== util_parse_long + +_WeeChat ≥ 4.8.0._ + +Analyser un nombre entier de type "long" dans une chaîne. + +Prototype : + +[source,c] +---- +int weechat_util_parse_long (const char *string, int base, long *result); +---- + +Paramètres : + +* _string_ : chaîne à analyser +* _base_ : peut être 0 (automatique) ou un entier entre 2 et 36 (inclus) +* _result_ : pointeur vers une variable mise à jour si la chaîne est correctement analysée + (si le pointeur est NULL, le nombre trouvé n'est pas retourné) + +Valeur de retour : + +* 1 : OK +* 0 : erreur + +Les chaînes suivantes sont invalides et la fonction retourne 0 : + +* chaîne vide +* nombre avec des caractères non numériques après +* nombre < LONG_MIN (valeur minimale pour une variable de type "long") +* nombre > LONG_MAX (valeur maximale pour une variable de type "long") +* entier invalide pour la _base_ donnée + +Exemples en C : + +[source,c] +---- +long nombre; +if (weechat_util_parse_long ("1234", 10, &nombre)) +{ + /* nombre == 1234 */ +} +if (!weechat_util_parse_long ("abc", 10, &nombre)) +{ + /* erreur d'analyse, nombre est inchangé */ +} +---- + +[NOTE] +Cette fonction n'est pas disponible dans l'API script. + +==== util_parse_longlong + +_WeeChat ≥ 4.8.0._ + +Analyser un nombre entier de type "long long" dans une chaîne. + +Prototype : + +[source,c] +---- +int weechat_util_parse_longlong (const char *string, int base, long long *result); +---- + +Paramètres : + +* _string_ : chaîne à analyser +* _base_ : peut être 0 (automatique) ou un entier entre 2 et 36 (inclus) +* _result_ : pointeur vers une variable mise à jour si la chaîne est correctement analysée + (si le pointeur est NULL, le nombre trouvé n'est pas retourné) + +Valeur de retour : + +* 1 : OK +* 0 : erreur + +Les chaînes suivantes sont invalides et la fonction retourne 0 : + +* chaîne vide +* nombre avec des caractères non numériques après +* nombre < LLONG_MIN (valeur minimale pour une variable de type "long long") +* nombre > LLONG_MAX (valeur maximale pour une variable de type "long long") +* entier invalide pour la _base_ donnée + +Exemples en C : + +[source,c] +---- +long long nombre; +if (weechat_util_parse_longlong ("1234", 10, &nombre)) +{ + /* nombre == 1234 */ +} +if (!weechat_util_parse_longlong ("abc", 10, &nombre)) +{ + /* erreur d'analyse, nombre est inchangé */ +} +---- + +[NOTE] +Cette fonction n'est pas disponible dans l'API script. + ==== util_timeval_cmp Comparer deux structures "timeval". diff --git a/doc/it/weechat_plugin_api.it.adoc b/doc/it/weechat_plugin_api.it.adoc index 3205f546f..8f47431bc 100644 --- a/doc/it/weechat_plugin_api.it.adoc +++ b/doc/it/weechat_plugin_api.it.adoc @@ -4874,6 +4874,162 @@ Questa funzione non è disponibile nelle API per lo scripting. Alcune funzioni utili. +// TRANSLATION MISSING +==== util_parse_int + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "int" in a string. + +Prototipo: + +[source,c] +---- +int weechat_util_parse_int (const char *string, int base, int *result); +---- + +Argomenti: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Valore restituito: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < INT_MIN (min value for a variable of type "int") +* number > INT_MAX (max value for a variable of type "int") +* invalid integer for the given _base_ + +Esempi in C: + +[source,c] +---- +int number; +if (weechat_util_parse_int ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_int ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +Questa funzione non è disponibile nelle API per lo scripting. + +// TRANSLATION MISSING +==== util_parse_long + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long" in a string. + +Prototipo: + +[source,c] +---- +int weechat_util_parse_long (const char *string, int base, long *result); +---- + +Argomenti: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Valore restituito: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LONG_MIN (min value for a variable of type "long") +* number > LONG_MAX (max value for a variable of type "long") +* invalid integer for the given _base_ + +Esempi in C: + +[source,c] +---- +long number; +if (weechat_util_parse_long ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_long ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +Questa funzione non è disponibile nelle API per lo scripting. + +// TRANSLATION MISSING +==== util_parse_longlong + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long long" in a string. + +Prototipo: + +[source,c] +---- +int weechat_util_parse_longlong (const char *string, int base, long long *result); +---- + +Argomenti: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Valore restituito: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LLONG_MIN (min value for a variable of type "long long") +* number > LLONG_MAX (max value for a variable of type "long long") +* invalid integer for the given _base_ + +Esempi in C: + +[source,c] +---- +long long number; +if (weechat_util_parse_longlong ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_longlong ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +Questa funzione non è disponibile nelle API per lo scripting. + ==== util_timeval_cmp Confronta due strutture "timeval". diff --git a/doc/ja/weechat_plugin_api.ja.adoc b/doc/ja/weechat_plugin_api.ja.adoc index f1129e795..47dd8b2e3 100644 --- a/doc/ja/weechat_plugin_api.ja.adoc +++ b/doc/ja/weechat_plugin_api.ja.adoc @@ -4799,6 +4799,162 @@ if (weechat_file_compare ("/tmp/test.txt", "/tmp/test2.txt") == 0) 便利な関数。 +// TRANSLATION MISSING +==== util_parse_int + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "int" in a string. + +プロトタイプ: + +[source,c] +---- +int weechat_util_parse_int (const char *string, int base, int *result); +---- + +引数: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +戻り値: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < INT_MIN (min value for a variable of type "int") +* number > INT_MAX (max value for a variable of type "int") +* invalid integer for the given _base_ + +C 言語での使用例: + +[source,c] +---- +int number; +if (weechat_util_parse_int ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_int ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +スクリプト API ではこの関数を利用できません。 + +// TRANSLATION MISSING +==== util_parse_long + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long" in a string. + +プロトタイプ: + +[source,c] +---- +int weechat_util_parse_long (const char *string, int base, long *result); +---- + +引数: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +戻り値: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LONG_MIN (min value for a variable of type "long") +* number > LONG_MAX (max value for a variable of type "long") +* invalid integer for the given _base_ + +C 言語での使用例: + +[source,c] +---- +long number; +if (weechat_util_parse_long ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_long ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +スクリプト API ではこの関数を利用できません。 + +// TRANSLATION MISSING +==== util_parse_longlong + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long long" in a string. + +プロトタイプ: + +[source,c] +---- +int weechat_util_parse_longlong (const char *string, int base, long long *result); +---- + +引数: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +戻り値: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LLONG_MIN (min value for a variable of type "long long") +* number > LLONG_MAX (max value for a variable of type "long long") +* invalid integer for the given _base_ + +C 言語での使用例: + +[source,c] +---- +long long number; +if (weechat_util_parse_longlong ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_longlong ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +スクリプト API ではこの関数を利用できません。 + ==== util_timeval_cmp 2 つの "timeval" 構造体を比較。 diff --git a/doc/sr/weechat_plugin_api.sr.adoc b/doc/sr/weechat_plugin_api.sr.adoc index 8127d8302..182f97ad6 100644 --- a/doc/sr/weechat_plugin_api.sr.adoc +++ b/doc/sr/weechat_plugin_api.sr.adoc @@ -4526,6 +4526,162 @@ if (weechat_file_compare ("/tmp/test.txt", "/tmp/test2.txt") == 0) Неке корисне функције. +// TRANSLATION MISSING +==== util_parse_int + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "int" in a string. + +Прототип: + +[source,c] +---- +int weechat_util_parse_int (const char *string, int base, int *result); +---- + +Аргументи: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Повратна вредност: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < INT_MIN (min value for a variable of type "int") +* number > INT_MAX (max value for a variable of type "int") +* invalid integer for the given _base_ + +C примери: + +[source,c] +---- +int number; +if (weechat_util_parse_int ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_int ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +Ова функција није доступна у API скриптовања. + +// TRANSLATION MISSING +==== util_parse_long + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long" in a string. + +Прототип: + +[source,c] +---- +int weechat_util_parse_long (const char *string, int base, long *result); +---- + +Аргументи: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Повратна вредност: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LONG_MIN (min value for a variable of type "long") +* number > LONG_MAX (max value for a variable of type "long") +* invalid integer for the given _base_ + +C примери: + +[source,c] +---- +long number; +if (weechat_util_parse_long ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_long ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +Ова функција није доступна у API скриптовања. + +// TRANSLATION MISSING +==== util_parse_longlong + +_WeeChat ≥ 4.8.0._ + +Parse an integer number of type "long long" in a string. + +Прототип: + +[source,c] +---- +int weechat_util_parse_longlong (const char *string, int base, long long *result); +---- + +Аргументи: + +* _string_: string to parse +* _base_: can be 0 (automatic) or an integer between 2 and 36 (inclusive) +* _result_: pointer to a variable updated if the string is correctly parsed + (if pointer is NULL, the number found is not returned) + +Повратна вредност: + +* 1: OK +* 0: error + +The following strings are invalid and the function returns 0: + +* empty string +* number with extra non-digits after +* number < LLONG_MIN (min value for a variable of type "long long") +* number > LLONG_MAX (max value for a variable of type "long long") +* invalid integer for the given _base_ + +C примери: + +[source,c] +---- +long long number; +if (weechat_util_parse_longlong ("1234", 10, &number)) +{ + /* number == 1234 */ +} +if (!weechat_util_parse_longlong ("abc", 10, &number)) +{ + /* parsing error, number is unchanged */ +} +---- + +[NOTE] +Ова функција није доступна у API скриптовања. + ==== util_timeval_cmp Пореди две „timeval” структуре. diff --git a/src/core/core-util.c b/src/core/core-util.c index f2e21b4e2..249e02297 100644 --- a/src/core/core-util.c +++ b/src/core/core-util.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #ifdef HAVE_SYS_RESOURCE_H @@ -48,6 +49,118 @@ #include "../plugins/plugin.h" +/* + * Parses an integer. + * + * If result is not NULL, *result is set with the parsed integer in case + * there is no error. + * + * Returns: + * 1: OK + * 0: error + */ + +int +util_parse_int (const char *string, int base, int *result) +{ + long number; + char *error; + + if (!string || !string[0]) + return 0; + + /* base must be 0 or between 2-36 (inclusive) */ + if ((base < 0) || (base == 1) || (base > 36)) + return 0; + + errno = 0; + error = NULL; + number = strtol (string, &error, base); + + if ((errno == ERANGE) || !error || error[0] || (error == string) + || (number < INT_MIN) || (number > INT_MAX)) + return 0; + + if (result) + *result = (int)number; + + return 1; +} + +/* + * Parses a long integer. + * + * If result is not NULL, *result is set with the parsed long integer in case + * there is no error. + * + * Returns: + * 1: OK + * 0: error + */ + +int +util_parse_long (const char *string, int base, long *result) +{ + long number; + char *error; + + if (!string || !string[0]) + return 0; + + /* base must be 0 or between 2-36 (inclusive) */ + if ((base < 0) || (base == 1) || (base > 36)) + return 0; + + errno = 0; + error = NULL; + number = strtol (string, &error, base); + + if ((errno == ERANGE) || !error || error[0] || (error == string)) + return 0; + + if (result) + *result = number; + + return 1; +} + +/* + * Parses a long long integer. + * + * If result is not NULL, *result is set with the parsed long integer in case + * there is no error. + * + * Returns: + * 1: OK + * 0: error + */ + +int +util_parse_longlong (const char *string, int base, long long *result) +{ + long long number; + char *error; + + if (!string || !string[0]) + return 0; + + /* base must be 0 or between 2-36 (inclusive) */ + if ((base < 0) || (base == 1) || (base > 36)) + return 0; + + errno = 0; + error = NULL; + number = strtoll (string, &error, base); + + if ((errno == ERANGE) || !error || error[0] || (error == string)) + return 0; + + if (result) + *result = number; + + return 1; +} + /* * Compares two timeval structures. * diff --git a/src/core/core-util.h b/src/core/core-util.h index 0bad20765..885d871ea 100644 --- a/src/core/core-util.h +++ b/src/core/core-util.h @@ -25,6 +25,11 @@ #include #include +/* parse numbers */ +extern int util_parse_int (const char *string, int base, int *result); +extern int util_parse_long (const char *string, int base, long *result); +extern int util_parse_longlong (const char *string, int base, long long *result); + /* timeval */ extern int util_timeval_cmp (struct timeval *tv1, struct timeval *tv2); extern long long util_timeval_diff (struct timeval *tv1, struct timeval *tv2); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index c23eb2794..f1752cdd2 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -695,6 +695,9 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv) new_plugin->file_compress = &dir_file_compress; new_plugin->file_compare = &dir_file_compare; + new_plugin->util_parse_int = &util_parse_int; + new_plugin->util_parse_long = &util_parse_long; + new_plugin->util_parse_longlong = &util_parse_longlong; new_plugin->util_timeval_cmp = &util_timeval_cmp; new_plugin->util_timeval_diff = &util_timeval_diff; new_plugin->util_timeval_add = &util_timeval_add; diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 548dc2705..426c7cc11 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -76,7 +76,7 @@ struct t_weelist_item; * 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 "20250508-01" +#define WEECHAT_PLUGIN_API_VERSION "20251112-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -460,6 +460,9 @@ struct t_weechat_plugin int (*file_compare) (const char *filename1, const char *filename2); /* util */ + int (*util_parse_int) (const char *string, int base, int *result); + int (*util_parse_long) (const char *string, int base, long *result); + int (*util_parse_longlong) (const char *string, int base, long long *result); int (*util_timeval_cmp) (struct timeval *tv1, struct timeval *tv2); long long (*util_timeval_diff) (struct timeval *tv1, struct timeval *tv2); void (*util_timeval_add) (struct timeval *tv, long long interval); @@ -1533,6 +1536,12 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); (weechat_plugin->file_compress)(__filename1, __filename2) /* util */ +#define weechat_util_parse_int(__string, __base, __result) \ + (weechat_plugin->util_parse_int)(__string, __base, __result) +#define weechat_util_parse_long(__string, __base, __result) \ + (weechat_plugin->util_parse_long)(__string, __base, __result) +#define weechat_util_parse_longlong(__string, __base, __result) \ + (weechat_plugin->util_parse_longlong)(__string, __base, __result) #define weechat_util_timeval_cmp(__time1, __time2) \ (weechat_plugin->util_timeval_cmp)(__time1, __time2) #define weechat_util_timeval_diff(__time1, __time2) \ diff --git a/tests/unit/core/test-core-util.cpp b/tests/unit/core/test-core-util.cpp index 5b5afc2a0..d3e3892ff 100644 --- a/tests/unit/core/test-core-util.cpp +++ b/tests/unit/core/test-core-util.cpp @@ -38,6 +38,33 @@ extern "C" #include "src/core/core-util.h" } +#define WEE_PARSE_NUMBER(__result, __parsed, __string, __base) \ + LONGS_EQUAL( \ + __result, \ + util_parse_int (__string, __base, NULL)); \ + LONGS_EQUAL( \ + __result, \ + util_parse_int (__string, __base, &number_int)); \ + if (__result) \ + LONGS_EQUAL(__parsed, number_int); \ + LONGS_EQUAL( \ + __result, \ + util_parse_long (__string, __base, NULL)); \ + LONGS_EQUAL( \ + __result, \ + util_parse_long (__string, __base, &number_long)); \ + if (__result) \ + LONGS_EQUAL(__parsed, number_long); \ + LONGS_EQUAL( \ + __result, \ + util_parse_longlong (__string, __base, NULL)); \ + LONGS_EQUAL( \ + __result, \ + util_parse_longlong (__string, __base, \ + &number_longlong)); \ + if (__result) \ + CHECK_EQUAL(__parsed, number_longlong); + #define WEE_PARSE_DATE(__result, __sec, __usec, __datetime) \ tv.tv_sec = 0; \ tv.tv_usec = 0; \ @@ -56,6 +83,101 @@ TEST_GROUP(CoreUtil) { }; +/* + * Tests functions: + * util_parse_int + * util_parse_long + * util_parse_longlong + */ + +TEST(CoreUtil, ParseNumber) +{ + int number_int; + long number_long; + long long number_longlong; + char str_number[256]; + + /* NULL string */ + WEE_PARSE_NUMBER(0, 0, NULL, 10); + + /* invalid base */ + WEE_PARSE_NUMBER(0, 0, "123", -1); + WEE_PARSE_NUMBER(0, 0, "123", 1); + WEE_PARSE_NUMBER(0, 0, "123", 37); + + /* invalid number */ + WEE_PARSE_NUMBER(0, 0, "", 10); + WEE_PARSE_NUMBER(0, 0, " ", 10); + WEE_PARSE_NUMBER(0, 0, "-", 10); + WEE_PARSE_NUMBER(0, 0, "+", 10); + WEE_PARSE_NUMBER(0, 0, "3-", 10); + WEE_PARSE_NUMBER(0, 0, "3+", 10); + WEE_PARSE_NUMBER(0, 0, "--3", 10); + WEE_PARSE_NUMBER(0, 0, "++3", 10); + WEE_PARSE_NUMBER(0, 0, ".1", 10); + WEE_PARSE_NUMBER(0, 0, "1.", 10); + WEE_PARSE_NUMBER(0, 0, "1.2", 10); + WEE_PARSE_NUMBER(0, 0, "1,2", 10); + WEE_PARSE_NUMBER(0, 0, "a", 10); + WEE_PARSE_NUMBER(0, 0, "1a", 10); + WEE_PARSE_NUMBER(0, 0, "a1", 10); + WEE_PARSE_NUMBER(0, 0, "123 ", 10); + WEE_PARSE_NUMBER(0, 0, "12", 2); + WEE_PARSE_NUMBER(0, 0, "18", 8); + WEE_PARSE_NUMBER(0, 0, "1g", 16); + + /* invalid int: outside range (INT_MIN, INT_MAX) */ + snprintf (str_number, sizeof (str_number), "%d1", INT_MIN); + LONGS_EQUAL(0, util_parse_int (str_number, 10, &number_int)); + snprintf (str_number, sizeof (str_number), "%d1", INT_MAX); + LONGS_EQUAL(0, util_parse_int (str_number, 10, &number_int)); + + /* invalid long: outside range (LONG_MIN, LONG_MAX) */ + snprintf (str_number, sizeof (str_number), "%ld1", LONG_MIN); + LONGS_EQUAL(0, util_parse_long (str_number, 10, &number_long)); + snprintf (str_number, sizeof (str_number), "%ld1", LONG_MAX); + LONGS_EQUAL(0, util_parse_long (str_number, 10, &number_long)); + + /* invalid long long: outside range (LLONG_MIN, LLONG_MAX) */ + snprintf (str_number, sizeof (str_number), "%lld1", LLONG_MIN); + LONGS_EQUAL(0, util_parse_longlong (str_number, 10, &number_longlong)); + snprintf (str_number, sizeof (str_number), "%lld1", LLONG_MAX); + LONGS_EQUAL(0, util_parse_longlong (str_number, 10, &number_longlong)); + + /* OK */ + WEE_PARSE_NUMBER(1, 12, "12", 10); + WEE_PARSE_NUMBER(1, 15, " 15", 10); + WEE_PARSE_NUMBER(1, -3, "-3", 10); + WEE_PARSE_NUMBER(1, 5, "101", 2); + WEE_PARSE_NUMBER(1, 71, "107", 8); + WEE_PARSE_NUMBER(1, 30, "1e", 16); + WEE_PARSE_NUMBER(1, 31, "1F", 16); + + /* OK, boundary limits for int */ + snprintf (str_number, sizeof (str_number), "%d", INT_MIN); + LONGS_EQUAL(1, util_parse_int (str_number, 10, &number_int)); + LONGS_EQUAL(INT_MIN, number_int); + snprintf (str_number, sizeof (str_number), "%d", INT_MAX); + LONGS_EQUAL(1, util_parse_int (str_number, 10, &number_int)); + LONGS_EQUAL(INT_MAX, number_int); + + /* OK, boundary limits for long */ + snprintf (str_number, sizeof (str_number), "%ld", LONG_MIN); + LONGS_EQUAL(1, util_parse_long (str_number, 10, &number_long)); + LONGS_EQUAL(LONG_MIN, number_long); + snprintf (str_number, sizeof (str_number), "%ld", LONG_MAX); + LONGS_EQUAL(1, util_parse_long (str_number, 10, &number_long)); + LONGS_EQUAL(LONG_MAX, number_long); + + /* OK, boundary limits for long long */ + snprintf (str_number, sizeof (str_number), "%lld", LLONG_MIN); + LONGS_EQUAL(1, util_parse_longlong (str_number, 10, &number_longlong)); + CHECK_EQUAL(LLONG_MIN, number_longlong); + snprintf (str_number, sizeof (str_number), "%lld", LLONG_MAX); + LONGS_EQUAL(1, util_parse_longlong (str_number, 10, &number_longlong)); + CHECK_EQUAL(LLONG_MAX, number_longlong); +} + /* * Tests functions: * util_timeval_cmp