diff options
-rw-r--r-- | src/quirks.c | 15 | ||||
-rw-r--r-- | src/util-prop-parsers.c | 61 | ||||
-rw-r--r-- | src/util-strings.c | 35 | ||||
-rw-r--r-- | src/util-strings.h | 26 | ||||
-rw-r--r-- | test/test-utils.c | 57 |
5 files changed, 91 insertions, 103 deletions
diff --git a/src/quirks.c b/src/quirks.c index ed1a9038..5651c51e 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -879,18 +879,15 @@ out: static bool parse_value_line(struct quirks_context *ctx, struct section *s, const char *line) { - char **strv; - const char *key, *value; bool rc = false; - - strv = strv_from_string(line, "="); - if (strv[0] == NULL || strv[1] == NULL || strv[2] != NULL) { + + size_t nelem; + char **strv = strv_from_string(line, "=", &nelem); + if (!strv || nelem != 2) goto out; - } - - key = strv[0]; - value = strv[1]; + const char *key = strv[0]; + const char *value = strv[1]; if (strlen(key) == 0 || strlen(value) == 0) goto out; diff --git a/src/util-prop-parsers.c b/src/util-prop-parsers.c index 20d301f8..2e4b514b 100644 --- a/src/util-prop-parsers.c +++ b/src/util-prop-parsers.c @@ -176,32 +176,31 @@ parse_dimension_property(const char *prop, size_t *w, size_t *h) bool parse_calibration_property(const char *prop, float calibration_out[6]) { - int idx; - char **strv; - float calibration[6]; - if (!prop) return false; + + bool rc = false; - strv = strv_from_string(prop, " "); - if (!strv) - return false; + size_t num_calibration; + char **strv = strv_from_string(prop, " ", &num_calibration); + if (!strv || num_calibration < 6) + goto out; - for (idx = 0; idx < 6; idx++) { + float calibration[6]; + for (size_t idx = 0; idx < 6; idx++) { double v; - if (strv[idx] == NULL || !safe_atod(strv[idx], &v)) { - strv_free(strv); - return false; - } + if (!safe_atod(strv[idx], &v)) + goto out; calibration[idx] = v; } - strv_free(strv); - memcpy(calibration_out, calibration, sizeof(calibration)); + rc = true; - return true; +out: + strv_free(strv); + return rc; } bool @@ -367,27 +366,19 @@ parse_evcode_string(const char *s, int *type_out, int *code_out) bool parse_evcode_property(const char *prop, struct input_event *events, size_t *nevents) { - char **strv = NULL; bool rc = false; - size_t ncodes = 0; - size_t idx; /* A randomly chosen max so we avoid crazy quirks */ struct input_event evs[32]; memset(evs, 0, sizeof evs); - strv = strv_from_string(prop, ";"); - if (!strv) - goto out; - - for (idx = 0; strv[idx]; idx++) - ncodes++; - - if (ncodes == 0 || ncodes > ARRAY_LENGTH(evs)) + size_t ncodes; + char **strv = strv_from_string(prop, ";", &ncodes); + if (!strv || ncodes == 0 || ncodes > ARRAY_LENGTH(evs)) goto out; ncodes = min(*nevents, ncodes); - for (idx = 0; strv[idx]; idx++) { + for (size_t idx = 0; strv[idx]; idx++) { char *s = strv[idx]; int type, code; @@ -434,24 +425,16 @@ out: bool parse_input_prop_property(const char *prop, unsigned int *props_out, size_t *nprops) { - char **strv = NULL; bool rc = false; - size_t count = 0; - size_t idx; unsigned int props[INPUT_PROP_CNT]; /* doubling up on quirks is a bug */ - strv = strv_from_string(prop, ";"); - if (!strv) - goto out; - - for (idx = 0; strv[idx]; idx++) - count++; - - if (count == 0 || count > ARRAY_LENGTH(props)) + size_t count; + char **strv = strv_from_string(prop, ";", &count); + if (!strv || count == 0 || count > ARRAY_LENGTH(props)) goto out; count = min(*nprops, count); - for (idx = 0; strv[idx]; idx++) { + for (size_t idx = 0; strv[idx]; idx++) { char *s = strv[idx]; unsigned int prop; diff --git a/src/util-strings.c b/src/util-strings.c index 33a7ac8a..525edc18 100644 --- a/src/util-strings.c +++ b/src/util-strings.c @@ -91,47 +91,54 @@ strv_from_argv(int argc, char **argv) /** * Return a null-terminated string array with the tokens in the input * string, e.g. "one two\tthree" with a separator list of " \t" will return - * an array [ "one", "two", "three", NULL ]. + * an array [ "one", "two", "three", NULL ] and num elements 3. * * Use strv_free() to free the array. * + * Another example: + * result = strv_from_string("+1-2++3--4++-+5-+-", "+-", &nelem) + * result == [ "1", "2", "3", "4", "5", NULL ] and nelem == 5 + * * @param in Input string * @param separators List of separator characters + * @param num_elements Number of elements found in the input string * * @return A null-terminated string array or NULL on errors */ char ** -strv_from_string(const char *in, const char *separators) +strv_from_string(const char *in, const char *separators, size_t *num_elements) { - const char *s, *word; - char **strv = NULL; - int nelems = 0, idx; - size_t l; - assert(in != NULL); - s = in; + + const char *s = in; + size_t l, nelems = 0; while (next_word(&s, &l, separators) != NULL) - nelems++; + nelems++; - if (nelems == 0) + if (nelems == 0) { + *num_elements = 0; return NULL; + } - nelems++; /* NULL-terminated */ - strv = zalloc(nelems * sizeof *strv); - - idx = 0; + size_t strv_len = nelems + 1; /* NULL-terminated */ + char **strv = zalloc(strv_len * sizeof *strv); + size_t idx = 0; + const char *word; s = in; while ((word = next_word(&s, &l, separators)) != NULL) { char *copy = strndup(word, l); if (!copy) { strv_free(strv); + *num_elements = 0; return NULL; } strv[idx++] = copy; } + + *num_elements = nelems; return strv; } diff --git a/src/util-strings.h b/src/util-strings.h index d5a84146..0bbd6f67 100644 --- a/src/util-strings.h +++ b/src/util-strings.h @@ -255,7 +255,7 @@ safe_atod(const char *str, double *val) } char **strv_from_argv(int argc, char **argv); -char **strv_from_string(const char *in, const char *separator); +char **strv_from_string(const char *in, const char *separator, size_t *num_elements); char *strv_join(char **strv, const char *joiner); static inline void @@ -291,33 +291,26 @@ kv_double_from_string(const char *string, struct key_value_double **result_out) { - char **pairs; - char **pair; struct key_value_double *result = NULL; - ssize_t npairs = 0; - unsigned int idx = 0; if (!pair_separator || pair_separator[0] == '\0' || !kv_separator || kv_separator[0] == '\0') return -1; - pairs = strv_from_string(string, pair_separator); - if (!pairs) - return -1; - - for (pair = pairs; *pair; pair++) - npairs++; - - if (npairs == 0) + size_t npairs; + char **pairs = strv_from_string(string, pair_separator, &npairs); + if (!pairs || npairs == 0) goto error; result = zalloc(npairs * sizeof *result); - for (pair = pairs; *pair; pair++) { - char **kv = strv_from_string(*pair, kv_separator); + for (size_t idx = 0; idx < npairs; idx++) { + char *pair = pairs[idx]; + size_t nelem; + char **kv = strv_from_string(pair, kv_separator, &nelem); double k, v; - if (!kv || !kv[0] || !kv[1] || kv[2] || + if (!kv || nelem != 2 || !safe_atod(kv[0], &k) || !safe_atod(kv[1], &v)) { strv_free(kv); @@ -326,7 +319,6 @@ kv_double_from_string(const char *string, result[idx].key = k; result[idx].value = v; - idx++; strv_free(kv); } diff --git a/test/test-utils.c b/test/test-utils.c index 0ae3668f..08bdd59a 100644 --- a/test/test-utils.c +++ b/test/test-utils.c @@ -1070,39 +1070,48 @@ START_TEST(strsplit_test) const char *string; const char *delim; const char *results[10]; + const size_t nresults; } tests[] = { - { "one two three", " ", { "one", "two", "three", NULL } }, - { "one", " ", { "one", NULL } }, - { "one two ", " ", { "one", "two", NULL } }, - { "one two", " ", { "one", "two", NULL } }, - { " one two", " ", { "one", "two", NULL } }, - { "one", "\t \r", { "one", NULL } }, - { "one two three", " t", { "one", "wo", "hree", NULL } }, - { " one two three", "te", { " on", " ", "wo ", "hr", NULL } }, - { "one", "ne", { "o", NULL } }, - { "onene", "ne", { "o", NULL } }, - { NULL, NULL, { NULL }} + { "one two three", " ", { "one", "two", "three", NULL }, 3 }, + { "one two\tthree", " \t", { "one", "two", "three", NULL }, 3 }, + { "one", " ", { "one", NULL }, 1 }, + { "one two ", " ", { "one", "two", NULL }, 2 }, + { "one two", " ", { "one", "two", NULL }, 2 }, + { " one two", " ", { "one", "two", NULL }, 2 }, + { "one", "\t \r", { "one", NULL }, 1 }, + { "one two three", " t", { "one", "wo", "hree", NULL }, 3 }, + { " one two three", "te", { " on", " ", "wo ", "hr", NULL }, 4 }, + { "one", "ne", { "o", NULL }, 1 }, + { "onene", "ne", { "o", NULL }, 1 }, + { "+1-2++3--4++-+5-+-", "+-", { "1", "2", "3", "4", "5", NULL }, 5 }, + /* special cases */ + { "", " ", { NULL }, 0 }, + { " ", " ", { NULL }, 0 }, + { " ", " ", { NULL }, 0 }, + { "oneoneone", "one", { NULL} , 0 }, + { NULL, NULL, { NULL }, 0} }; struct strsplit_test *t = tests; while (t->string) { - char **strv; - int idx = 0; - strv = strv_from_string(t->string, t->delim); - while (t->results[idx]) { + size_t nelem; + char **strv = strv_from_string(t->string, t->delim, &nelem); + + for (size_t idx = 0; idx < t->nresults; idx++) ck_assert_str_eq(t->results[idx], strv[idx]); - idx++; - } - ck_assert_ptr_eq(strv[idx], NULL); + + ck_assert_uint_eq(nelem, t->nresults); + + /* When there are no elements validate return value is Null, + otherwise validate result array is Null terminated. */ + if(t->nresults == 0) + ck_assert_ptr_null(strv); + else + ck_assert_ptr_null(strv[t->nresults]); + strv_free(strv); t++; } - - /* Special cases */ - ck_assert_ptr_eq(strv_from_string("", " "), NULL); - ck_assert_ptr_eq(strv_from_string(" ", " "), NULL); - ck_assert_ptr_eq(strv_from_string(" ", " "), NULL); - ck_assert_ptr_eq(strv_from_string("oneoneone", "one"), NULL); } END_TEST |