diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-08-08 09:40:17 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-10-12 11:29:52 +0200 |
commit | 3a886d848dadd98eda8dff354c1d10450d7613fe (patch) | |
tree | 94e5b92cb513f3aa595a28c5c7c1f95ef3edca9f /src/mm-modem-helpers.c | |
parent | 37bd61421245de87d2c04852109d2a1b14d338cb (diff) |
modem-helpers: new uint list parser, including interval support
Diffstat (limited to 'src/mm-modem-helpers.c')
-rw-r--r-- | src/mm-modem-helpers.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index e6e158cc..8b4f0f08 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -131,6 +131,105 @@ mm_split_string_groups (const gchar *str) /*****************************************************************************/ +static int uint_compare_func (gconstpointer a, gconstpointer b) +{ + return (*(guint *)a - *(guint *)b); +} + +GArray * +mm_parse_uint_list (const gchar *str, + GError **error) +{ + GArray *array; + gchar *dupstr; + gchar *aux; + GError *inner_error = NULL; + + if (!str || !str[0]) + return NULL; + + /* Parses into a GArray of guints, the list of numbers given in the string, + * also supporting number intervals. + * E.g.: + * 1-6 --> 1,2,3,4,5,6 + * 1,2,4-6 --> 1,2,4,5,6 + */ + array = g_array_new (FALSE, FALSE, sizeof (guint)); + aux = dupstr = g_strdup (str); + + while (aux) { + gchar *next; + gchar *interval; + + next = strchr (aux, ','); + if (next) { + *next = '\0'; + next++; + } + + interval = strchr (aux, '-'); + if (interval) { + guint start = 0; + guint stop = 0; + + *interval = '\0'; + interval++; + + if (!mm_get_uint_from_str (aux, &start)) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "couldn't parse interval start integer: '%s'", aux); + goto out; + } + if (!mm_get_uint_from_str (interval, &stop)) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "couldn't parse interval stop integer: '%s'", interval); + goto out; + } + + if (start > stop) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "interval start (%u) cannot be bigger than interval stop (%u)", start, stop); + goto out; + } + + for (; start <= stop; start++) + g_array_append_val (array, start); + } else { + guint num; + + if (!mm_get_uint_from_str (aux, &num)) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "couldn't parse integer: '%s'", aux); + goto out; + } + + g_array_append_val (array, num); + } + + aux = next; + } + + if (!array->len) + inner_error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "couldn't parse list of integers: '%s'", str); + else + g_array_sort (array, uint_compare_func); + +out: + g_free (dupstr); + + if (inner_error) { + g_propagate_error (error, inner_error); + g_array_unref (array); + return NULL; + } + + return array; +} + +/*****************************************************************************/ + guint mm_count_bits_set (gulong number) { |