summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-01-22 09:49:21 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-01-22 09:49:21 +0100
commit5ebdae4863f64a32826c25c6e0d1dfbc1612d904 (patch)
treef7c8ae79050fd00a708bfcda11f6681ebb9a32ce /lib
parent034637fbd9dfc5cbcffca1f8f392c6ab0dd6f229 (diff)
parent2f9b25f41362e99e2b31684b5c9a1a02abc1ae8b (diff)
downloadbarebox-5ebdae4863f64a32826c25c6e0d1dfbc1612d904.tar.gz
barebox-5ebdae4863f64a32826c25c6e0d1dfbc1612d904.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile1
-rw-r--r--lib/libscan.c9
-rw-r--r--lib/misc.c35
-rw-r--r--lib/parseopt.c124
-rw-r--r--lib/string.c20
5 files changed, 177 insertions, 12 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 0d5ac6586c..66c59fe15e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -60,3 +60,4 @@ obj-y += reed_solomon/
obj-$(CONFIG_RATP) += ratp.o
obj-y += list_sort.o
obj-y += int_sqrt.o
+obj-y += parseopt.o
diff --git a/lib/libscan.c b/lib/libscan.c
index 74a24b5011..c4139e69d1 100644
--- a/lib/libscan.c
+++ b/lib/libscan.c
@@ -39,6 +39,7 @@ int libscan_ubi_scan(struct mtd_info *mtd, struct ubi_scan_info **info,
int eb, v = (verbose == 2), pr = (verbose == 1), eb_cnt;
struct ubi_scan_info *si;
unsigned long long sum = 0;
+ uint64_t lastprint = 0;
eb_cnt = mtd_div_by_eb(mtd->size, mtd);
@@ -66,8 +67,12 @@ int libscan_ubi_scan(struct mtd_info *mtd, struct ubi_scan_info **info,
if (v)
normsg_cont("scanning eraseblock %d", eb);
if (pr) {
- printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2u %% complete ",
- eb, (eb + 1) * 100 / eb_cnt);
+ if (is_timeout(lastprint, 300 * MSECOND) ||
+ eb == eb_cnt - 1) {
+ printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2u %% complete ",
+ eb, (eb + 1) * 100 / eb_cnt);
+ lastprint = get_time_ns();
+ }
}
ret = mtd_peb_is_bad(mtd, eb);
diff --git a/lib/misc.c b/lib/misc.c
index 62ddd66779..1d20e1b092 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -79,38 +79,53 @@ EXPORT_SYMBOL(strtoul_suffix);
int parse_area_spec(const char *str, loff_t *start, loff_t *size)
{
char *endp;
- loff_t end;
+ loff_t end, _start, _size;
if (!isdigit(*str))
return -1;
- *start = strtoull_suffix(str, &endp, 0);
+ _start = strtoull_suffix(str, &endp, 0);
str = endp;
if (!*str) {
/* beginning given, but no size, assume maximum size */
- *size = ~0;
- return 0;
+ _size = ~0;
+ goto success;
}
if (*str == '-') {
/* beginning and end given */
- end = strtoull_suffix(str + 1, NULL, 0);
- if (end < *start) {
+ if (!isdigit(*(str + 1)))
+ return -1;
+
+ end = strtoull_suffix(str + 1, &endp, 0);
+ str = endp;
+ if (end < _start) {
printf("end < start\n");
return -1;
}
- *size = end - *start + 1;
- return 0;
+ _size = end - _start + 1;
+ goto success;
}
if (*str == '+') {
/* beginning and size given */
- *size = strtoull_suffix(str + 1, NULL, 0);
- return 0;
+ if (!isdigit(*(str + 1)))
+ return -1;
+
+ _size = strtoull_suffix(str + 1, &endp, 0);
+ str = endp;
+ goto success;
}
return -1;
+
+success:
+ if (*str && !isspace(*str))
+ return -1;
+ *start = _start;
+ *size = _size;
+ return 0;
}
EXPORT_SYMBOL(parse_area_spec);
diff --git a/lib/parseopt.c b/lib/parseopt.c
new file mode 100644
index 0000000000..8211733e3b
--- /dev/null
+++ b/lib/parseopt.c
@@ -0,0 +1,124 @@
+#include <common.h>
+
+#include "parseopt.h"
+
+void parseopt_b(const char *options, const char *opt, bool *val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+
+again:
+ start = strstr(options, opt);
+
+ if (!start) {
+ *val = false;
+ return;
+ }
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != ',' && start[optlen] != '\0') {
+ options = start;
+ goto again;
+ }
+
+ *val = true;
+}
+
+void parseopt_hu(const char *options, const char *opt, unsigned short *val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+ ulong v;
+ char *endp;
+
+again:
+ start = strstr(options, opt);
+
+ if (!start)
+ return;
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != '=') {
+ options = start;
+ goto again;
+ }
+
+ v = simple_strtoul(start + optlen + 1, &endp, 0);
+ if (v > USHRT_MAX)
+ return;
+
+ if (*endp == ',' || *endp == '\0')
+ *val = v;
+}
+
+void parseopt_u16(const char *options, const char *opt, uint16_t *val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+ ulong v;
+ char *endp;
+
+again:
+ start = strstr(options, opt);
+
+ if (!start)
+ return;
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != '=') {
+ options = start;
+ goto again;
+ }
+
+ v = simple_strtoul(start + optlen + 1, &endp, 0);
+ if (v > U16_MAX)
+ return;
+
+ if (*endp == ',' || *endp == '\0')
+ *val = v;
+}
+
+void parseopt_str(const char *options, const char *opt, char **val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+ char *endp;
+ char *parsed;
+
+again:
+ start = strstr(options, opt);
+
+ if (!start)
+ return;
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != '=') {
+ options = start;
+ goto again;
+ }
+
+ parsed = (char *)start + optlen + 1;
+ endp = parsed;
+ while (*endp != '\0' && *endp != ',') {
+
+ endp++;
+ }
+
+ *val = xstrndup(parsed, endp - parsed);
+}
diff --git a/lib/string.c b/lib/string.c
index 1d491c9c2f..f588933e81 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -323,6 +323,26 @@ char * strdup(const char *s)
#endif
EXPORT_SYMBOL(strdup);
+#ifndef __HAVE_ARCH_STRNDUP
+char *strndup(const char *s, size_t n)
+{
+ char *new;
+ size_t len = strnlen(s, n);
+
+ if ((s == NULL) ||
+ ((new = malloc(len + 1)) == NULL)) {
+ return NULL;
+ }
+
+ memcpy(new, s, len);
+ new[len] = '\0';
+
+ return new;
+}
+
+#endif
+EXPORT_SYMBOL(strndup);
+
#ifndef __HAVE_ARCH_STRSPN
/**
* strspn - Calculate the length of the initial substring of @s which only