diff --git a/src/option_parser.c b/src/option_parser.c index 2a11d6c..4f16d59 100644 --- a/src/option_parser.c +++ b/src/option_parser.c @@ -260,6 +260,15 @@ gint64 ini_get_time(const char *section, const char *key, gint64 def) return val; } +char **ini_get_list(const char *section, const char *key, const char *def) +{ + const char *value = get_value(section, key); + if (value) + return string_to_array(value); + else + return string_to_array(def); +} + int ini_get_int(const char *section, const char *key, int def) { const char *value = get_value(section, key); @@ -475,6 +484,16 @@ char *cmdline_get_path(const char *key, const char *def, const char *description return string_to_path(g_strdup(def)); } +char **cmdline_get_list(const char *key, const char *def, const char *description){ + cmdline_usage_append(key, "list", description); + const char *str = cmdline_get_value(key); + + if (str) + return string_to_array(str); + else + return string_to_array(def); +} + gint64 cmdline_get_time(const char *key, gint64 def, const char *description) { cmdline_usage_append(key, "time", description); @@ -574,6 +593,23 @@ gint64 option_get_time(const char *ini_section, return cmdline_get_time(cmdline_key, ini_val, description); } + +char **option_get_list(const char *ini_section, + const char *ini_key, + const char *cmdline_key, + const char *def, + const char *description) +{ + char **val = NULL; + if (cmdline_key) + val = cmdline_get_list(cmdline_key, NULL, description); + + if (val) + return val; + else + return ini_get_list(ini_section, ini_key, def); +} + int option_get_int(const char *ini_section, const char *ini_key, const char *cmdline_key, diff --git a/src/option_parser.h b/src/option_parser.h index f3861bc..88a7659 100644 --- a/src/option_parser.h +++ b/src/option_parser.h @@ -24,6 +24,7 @@ int load_ini_file(FILE *); char *ini_get_path(const char *section, const char *key, const char *def); char *ini_get_string(const char *section, const char *key, const char *def); gint64 ini_get_time(const char *section, const char *key, gint64 def); +char **ini_get_list(const char *section, const char *key, const char *def); int ini_get_int(const char *section, const char *key, int def); double ini_get_double(const char *section, const char *key, double def); int ini_get_bool(const char *section, const char *key, int def); @@ -34,6 +35,7 @@ void cmdline_load(int argc, char *argv[]); /* for all cmdline_get_* key can be either "-key" or "-key/-longkey" */ char *cmdline_get_string(const char *key, const char *def, const char *description); char *cmdline_get_path(const char *key, const char *def, const char *description); +char **cmdline_get_list(const char *key, const char *def, const char *description); int cmdline_get_int(const char *key, int def, const char *description); double cmdline_get_double(const char *key, double def, const char *description); int cmdline_get_bool(const char *key, int def, const char *description); @@ -55,6 +57,11 @@ gint64 option_get_time(const char *ini_section, const char *cmdline_key, gint64 def, const char *description); +char **option_get_list(const char *ini_section, + const char *ini_key, + const char *cmdline_key, + const char *def, + const char *description); int option_get_int(const char *ini_section, const char *ini_key, const char *cmdline_key, diff --git a/src/utils.c b/src/utils.c index 6a1d2fb..d837774 100644 --- a/src/utils.c +++ b/src/utils.c @@ -13,6 +13,17 @@ #include "log.h" +/* see utils.h */ +void free_string_array(char **arr) +{ + if (arr){ + for (int i = 0; arr[i]; i++){ + g_free(arr[i]); + } + } + g_free(arr); +} + /* see utils.h */ char *string_replace_char(char needle, char replacement, char *haystack) { @@ -135,6 +146,27 @@ void string_strip_delimited(char *str, char a, char b) str[iwrite] = 0; } +/* see utils.h */ +char **string_to_array(const char *string) +{ + char **arr = NULL; + if (string) { + char* dup = g_strdup(string); + char* tmp = dup; + int num_tokens = 0; + char *token = strsep(&tmp, ","); + while (token) { + arr = g_realloc_n(arr, num_tokens + 2, sizeof(char*)); + arr[num_tokens] = g_strdup(g_strstrip(token)); + num_tokens++; + token = strsep(&tmp, ","); + } + arr[num_tokens] = NULL; + g_free(dup); + } + return arr; +} + /* see utils.h */ char *string_to_path(char *string) { diff --git a/src/utils.h b/src/utils.h index 2278f6d..eea44c0 100644 --- a/src/utils.h +++ b/src/utils.h @@ -22,6 +22,15 @@ //! Convert a second into the internal time representation #define S2US(s) (((gint64)(s)) * 1000 * 1000) +/** + * Frees an array of strings whose last element is a NULL pointer. + * + * Assumes the last element is a NULL pointer, otherwise will result in a buffer overflow. + + * @param arr The array of strings to free + */ +void free_string_array(char **arr); + /** * Replaces all occurrences of the char \p needle with the char \p replacement in \p haystack. * @@ -82,6 +91,17 @@ char *string_strip_quotes(const char *value); */ void string_strip_delimited(char *str, char a, char b); +/** + * Parse a comma-delimited string into a dynamic array of tokens + * + * The string is split on commas and strips spaces from tokens. The last element + * of the array is NULL in order to avoid passing around a length variable. + * + * @param string The string to convert to an array + * @returns The array of tokens. + */ +char **string_to_array(const char *string); + /** * Replace tilde and path-specific values with its equivalents *