summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYinon Burgansky <yinonburgansky@gmail.com>2022-10-05 18:20:06 +0300
committerYinon Burgansky <yinonburgansky@gmail.com>2022-11-07 22:32:24 +0200
commiteeae8906dbbb5c0ebd505edfd3de0a6a2532e5c9 (patch)
treebb869daa4c89e41a1aa4eaecb28cadb11353a21f
parente8732802b7a3a45194be242a02ead13027c7fd73 (diff)
downloadlibinput-eeae8906dbbb5c0ebd505edfd3de0a6a2532e5c9.tar.gz
util: return the number of elements from strv_from_string
Signed-off-by: Yinon Burgansky <51504-Yinon@users.noreply.gitlab.freedesktop.org>
-rw-r--r--src/quirks.c15
-rw-r--r--src/util-prop-parsers.c61
-rw-r--r--src/util-strings.c35
-rw-r--r--src/util-strings.h26
-rw-r--r--test/test-utils.c57
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