diff options
-rw-r--r-- | include/strutils.h | 5 | ||||
-rw-r--r-- | lib/strutils.c | 95 | ||||
-rw-r--r-- | lib/tt.c | 41 | ||||
-rw-r--r-- | misc-utils/findmnt.c | 6 | ||||
-rw-r--r-- | misc-utils/lsblk.c | 3 | ||||
-rw-r--r-- | partx/partx.c | 3 | ||||
-rw-r--r-- | sys-utils/dmesg.c | 47 |
7 files changed, 110 insertions, 90 deletions
diff --git a/include/strutils.h b/include/strutils.h index aa5ea7cc8..08ba09c01 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -39,4 +39,9 @@ enum extern char *size_to_human_string(int options, uint64_t bytes); +extern int string_to_idarray(const char *list, int ary[], size_t arysz, + int (name2id)(const char *, size_t)); +extern int string_to_bitarray(const char *list, char *ary, + int (*name2bit)(const char *, size_t)); + #endif 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 @@ -661,47 +661,6 @@ int tt_print_table(struct tt *tb) return 0; } -/* Returns: >= 0 : number of items added to ary[] - * -1 : parse error or unknown item - * -2 : arysz reached - */ -int tt_parse_columns_list(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; -} - #ifdef TEST_PROGRAM #include <errno.h> diff --git a/misc-utils/findmnt.c b/misc-utils/findmnt.c index 2dbb60e5a..4d0029186 100644 --- a/misc-utils/findmnt.c +++ b/misc-utils/findmnt.c @@ -897,8 +897,7 @@ int main(int argc, char *argv[]) disable_columns_truncate(); break; case 'o': - ncolumns = tt_parse_columns_list( - optarg, + ncolumns = string_to_idarray(optarg, columns, ARRAY_SIZE(columns), column_name_to_id); if (ncolumns < 0) @@ -909,8 +908,7 @@ int main(int argc, char *argv[]) break; case 'p': if (optarg) { - nactions = tt_parse_columns_list( - optarg, + nactions = string_to_idarray(optarg, actions, ARRAY_SIZE(actions), poll_action_name_to_id); if (nactions < 0) diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index b458486f0..e8e9a62c1 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -971,8 +971,7 @@ int main(int argc, char *argv[]) tt_flags |= TT_FL_NOHEADINGS; break; case 'o': - ncolumns = tt_parse_columns_list( - optarg, + ncolumns = string_to_idarray(optarg, columns, ARRAY_SIZE(columns), column_name_to_id); if (ncolumns < 0) diff --git a/partx/partx.c b/partx/partx.c index 2451993e4..a42c1894f 100644 --- a/partx/partx.c +++ b/partx/partx.c @@ -676,8 +676,7 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, _("failed to parse --nr <M-N> range")); break; case 'o': - ncolumns = tt_parse_columns_list( - optarg, + ncolumns = string_to_idarray(optarg, columns, ARRAY_SIZE(columns), column_name_to_id); if (ncolumns < 0) diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c index 7123c7fb6..d9beb9c5d 100644 --- a/sys-utils/dmesg.c +++ b/sys-utils/dmesg.c @@ -311,45 +311,6 @@ static double time_diff(struct timeval *a, struct timeval *b) return (a->tv_sec - b->tv_sec) + (a->tv_usec - b->tv_usec) / 1E6; } -/* - * 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. - */ -static int list_to_bitarray(const char *list, - int (*name2id)(const char *name, size_t namesz), - char *ary) -{ - const char *begin = NULL, *p; - - for (p = list; p && *p; p++) { - const char *end = NULL; - int id; - - 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; - - id = name2id(begin, end - begin); - if (id < 0) - return id; - setbit(ary, id); - begin = NULL; - if (end && !*end) - break; - } - return 0; -} - static int get_buffer_size() { int n = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0); @@ -674,7 +635,9 @@ int main(int argc, char *argv[]) break; case 'f': ctl.fltr_fac = 1; - list_to_bitarray(optarg, parse_facility, ctl.facilities); + if (string_to_bitarray(optarg, + ctl.facilities, parse_facility) < 0) + return EXIT_FAILURE; break; case 'h': usage(stdout); @@ -685,7 +648,9 @@ int main(int argc, char *argv[]) break; case 'l': ctl.fltr_lev= 1; - list_to_bitarray(optarg, parse_level, ctl.levels); + if (string_to_bitarray(optarg, + ctl.levels, parse_level) < 0) + return EXIT_FAILURE; break; case 'n': cmd = SYSLOG_ACTION_CONSOLE_LEVEL; |