summaryrefslogtreecommitdiffstats
path: root/lib/strutils.c
diff options
context:
space:
mode:
authorKarel Zak2011-07-27 16:41:21 +0200
committerKarel Zak2011-07-27 16:41:21 +0200
commitc87638ad3076f5e7e0c80067631561c356148b79 (patch)
treef6210cb005d910adee8dacf1a7b5bd398a74a1ce /lib/strutils.c
parentinclude; [tt.c] check for array size in columns parser (diff)
downloadkernel-qcow2-util-linux-c87638ad3076f5e7e0c80067631561c356148b79.tar.gz
kernel-qcow2-util-linux-c87638ad3076f5e7e0c80067631561c356148b79.tar.xz
kernel-qcow2-util-linux-c87638ad3076f5e7e0c80067631561c356148b79.zip
include: [strutils.c] add list parsers
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/strutils.c')
-rw-r--r--lib/strutils.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/strutils.c b/lib/strutils.c
index e7a2454a0..31a487228 100644
--- a/lib/strutils.c
+++ b/lib/strutils.c
@@ -11,8 +11,10 @@
#include <sys/stat.h>
#include <locale.h>
#include <string.h>
+
#include "c.h"
#include "strutils.h"
+#include "bitops.h"
static int do_scale_by_power (uintmax_t *x, int base, int power)
{
@@ -341,6 +343,99 @@ char *size_to_human_string(int options, uint64_t bytes)
return strdup(buf);
}
+/*
+ * Parses comma delimited list to array with IDs, for example:
+ *
+ * "aaa,bbb,ccc" --> ary[0] = FOO_AAA;
+ * ary[1] = FOO_BBB;
+ * ary[3] = FOO_CCC;
+ *
+ * The function name2id() provides conversion from string to ID.
+ *
+ * Returns: >= 0 : number of items added to ary[]
+ * -1 : parse error or unknown item
+ * -2 : arysz reached
+ */
+int string_to_idarray(const char *list, int ary[], size_t arysz,
+ int (name2id)(const char *, size_t))
+{
+ const char *begin = NULL, *p;
+ int n = 0;
+
+ if (!list || !*list || !ary || !arysz || !name2id)
+ return -1;
+
+ for (p = list; p && *p; p++) {
+ const char *end = NULL;
+ int id;
+
+ if (!begin)
+ begin = p; /* begin of the column name */
+ if (*p == ',')
+ end = p; /* terminate the name */
+ if (*(p + 1) == '\0')
+ end = p + 1; /* end of string */
+ if (!begin || !end)
+ continue;
+ if (end <= begin)
+ return -1;
+
+ id = name2id(begin, end - begin);
+ if (id == -1)
+ return -1;
+ ary[ n++ ] = id;
+ if (n >= arysz)
+ return -2;
+ begin = NULL;
+ if (end && !*end)
+ break;
+ }
+ return n;
+}
+
+/*
+ * LIST ::= <item> [, <item>]
+ *
+ * The <item> is translated to 'id' by name2id() function and the 'id' is used
+ * as a possition in the 'ary' bit array. It means that the 'id' has to be in
+ * range <0..N> where N < sizeof(ary) * NBBY.
+ *
+ * Returns: 0 on sucess, <0 on error.
+ */
+int string_to_bitarray(const char *list,
+ char *ary,
+ int (*name2bit)(const char *, size_t))
+{
+ const char *begin = NULL, *p;
+
+ if (!list || !name2bit || !ary)
+ return -EINVAL;
+
+ for (p = list; p && *p; p++) {
+ const char *end = NULL;
+ int bit;
+
+ if (!begin)
+ begin = p; /* begin of the level name */
+ if (*p == ',')
+ end = p; /* terminate the name */
+ if (*(p + 1) == '\0')
+ end = p + 1; /* end of string */
+ if (!begin || !end)
+ continue;
+ if (end <= begin)
+ return -1;
+
+ bit = name2bit(begin, end - begin);
+ if (bit < 0)
+ return bit;
+ setbit(ary, bit);
+ begin = NULL;
+ if (end && !*end)
+ break;
+ }
+ return 0;
+}
#ifdef TEST_PROGRAM