mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 05:40:04 +01:00
util: return the number of elements from strv_from_string
Signed-off-by: Yinon Burgansky <51504-Yinon@users.noreply.gitlab.freedesktop.org>
This commit is contained in:
parent
e8732802b7
commit
eeae8906db
5 changed files with 91 additions and 103 deletions
15
src/quirks.c
15
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue