These functions will be used to parse the chaos test's command line. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- lib/alloc.c | 9 +++++++- lib/alloc.h | 1 + lib/libcflat.h | 4 +++- lib/string.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++--- lib/string.h | 3 +++ 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/lib/alloc.c b/lib/alloc.c index a46f464..a56f664 100644 --- a/lib/alloc.c +++ b/lib/alloc.c @@ -1,7 +1,7 @@ #include "alloc.h" #include "bitops.h" #include "asm/page.h" -#include "bitops.h" +#include "string.h" void *malloc(size_t size) { @@ -50,6 +50,13 @@ void *calloc(size_t nmemb, size_t size) return ptr; } +char *strdup(const char *s) +{ + size_t len = strlen(s) + 1; + char *d = malloc(len); + return strcpy(d, s); +} + void free(void *ptr) { if (alloc_ops->free) diff --git a/lib/alloc.h b/lib/alloc.h index 9b4b634..4139465 100644 --- a/lib/alloc.h +++ b/lib/alloc.h @@ -34,5 +34,6 @@ void *malloc(size_t size); void *calloc(size_t nmemb, size_t size); void free(void *ptr); void *memalign(size_t alignment, size_t size); +char *strdup(const char *s); #endif /* _ALLOC_H_ */ diff --git a/lib/libcflat.h b/lib/libcflat.h index 460a123..7d5d02e 100644 --- a/lib/libcflat.h +++ b/lib/libcflat.h @@ -80,9 +80,11 @@ extern int __getchar(void); extern int getchar(void); extern void exit(int code) __attribute__((noreturn)); extern void abort(void) __attribute__((noreturn)); -extern long atol(const char *ptr); extern char *getenv(const char *name); +extern long atol(const char *ptr); +extern int parse_long(const char *s, long *num); + extern int printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); extern int snprintf(char *buf, int size, const char *fmt, ...) diff --git a/lib/string.c b/lib/string.c index 75257f5..1ebefcb 100644 --- a/lib/string.c +++ b/lib/string.c @@ -135,10 +135,9 @@ void *memchr(const void *s, int c, size_t n) return NULL; } -long atol(const char *ptr) +int parse_long(const char *s, long *num) { long acc = 0; - const char *s = ptr; int neg, c; while (*s == ' ' || *s == '\t') @@ -163,7 +162,15 @@ long atol(const char *ptr) if (neg) acc = -acc; - return acc; + *num = acc; + return !*s; +} + +long atol(const char *ptr) +{ + long num; + parse_long(ptr, &num); + return num; } extern char **environ; @@ -224,3 +231,49 @@ bool simple_glob(const char *text, const char *pattern) return !strcmp(text, copy); } + +/* Based on musl libc. */ +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) + +size_t strcspn(const char *s, const char *c) +{ + const char *a = s; + size_t byteset[32/sizeof(size_t)] = { 0 }; + + if (!c[0]) + return 0; + if (!c[1]) { + while (*s != *c) + s++; + } else { + while (*c) { + BITOP(byteset, *(unsigned char *)c, |=); + c++; + } + while (*s && !BITOP(byteset, *(unsigned char *)s, &)) + s++; + } + return s - a; +} + +/* + * Slightly more flexible strsep. The pointer to the token + * must be stashed by the caller, the delimiter is the return value. + */ +char strdelim(char **p, const char *sep) +{ + char *e; + char *s = *p; + char delim; + + e = s + strcspn(s, sep); + delim = *e; + if (delim) { + *e = 0; + *p = ++e; + } else { + *p = e; + } + return delim; +} diff --git a/lib/string.h b/lib/string.h index 493d51b..da31668 100644 --- a/lib/string.h +++ b/lib/string.h @@ -20,4 +20,7 @@ extern int memcmp(const void *s1, const void *s2, size_t n); extern void *memmove(void *dest, const void *src, size_t n); extern void *memchr(const void *s, int c, size_t n); +size_t strcspn(const char *s, const char *c); +char strdelim(char **p, const char *sep); + #endif /* _STRING_H */ -- 2.29.2