From: Karel Zak Date: Tue, 29 Jan 2013 14:25:47 +0000 (+0100) Subject: lib/strutils: simplify strtosize(), return info about suffix X-Git-Tag: v2.23-rc1~121 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=23106a29b0342ef8ada46bfc3df33b5d8e9c5e77;p=thirdparty%2Futil-linux.git lib/strutils: simplify strtosize(), return info about suffix Signed-off-by: Karel Zak --- diff --git a/include/strutils.h b/include/strutils.h index 38eb1ce6a6..695343405a 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -1,6 +1,7 @@ #ifndef UTIL_LINUX_STRUTILS #define UTIL_LINUX_STRUTILS +#include #include #include #include @@ -11,6 +12,7 @@ #endif +extern int parse_size(const char *str, uintmax_t *res, int *power); extern int strtosize(const char *str, uintmax_t *res); extern uintmax_t strtosize_or_err(const char *str, const char *errmesg); @@ -50,6 +52,25 @@ static inline void xstrncpy(char *dest, const char *src, size_t n) dest[n-1] = 0; } +static inline char *strdup_to_offset(void *stru, size_t offset, const char *str) +{ + char *n = NULL; + char **o = (char **) ((char *) stru + offset); + + if (str) { + n = strdup(str); + if (!n) + return NULL; + } + + free(*o); + *o = n; + return n; +} + +#define strdup_to_struct_member(_s, _m, _str) \ + strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str) + extern void strmode(mode_t mode, char *str); /* Options for size_to_human_string() */ diff --git a/lib/strutils.c b/lib/strutils.c index 8e8ab2f370..53b589a41a 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -32,25 +32,32 @@ static int do_scale_by_power (uintmax_t *x, int base, int power) * Supported suffixes: * * XiB or X for 2^N - * where X = {K,M,G,T,P,E,Y,Z} + * where X = {K,M,G,T,P,E,Z,Y} * or X = {k,m,g,t,p,e} (undocumented for backward compatibility only) * for example: * 10KiB = 10240 * 10K = 10240 * * XB for 10^N - * where X = {K,M,G,T,P,E,Y,Z} + * where X = {K,M,G,T,P,E,Z,Y} * for example: * 10KB = 10000 * + * The optinal 'power' variable returns number associated with used suffix + * {K,M,G,T,P,E,Z,Y} = {1,2,3,4,5,6,7,8}. + * * Note that the function does not accept numbers with '-' (negative sign) * prefix. */ -int strtosize(const char *str, uintmax_t *res) +int parse_size(const char *str, uintmax_t *res, int *power) { char *p; uintmax_t x; - int base = 1024, rc = 0; + int base = 1024, rc = 0, pwr = 0; + + static const char *suf = "KMGTPEYZ"; + static const char *suf2 = "kmgtpeyz"; + const char *sp; *res = 0; @@ -90,41 +97,20 @@ int strtosize(const char *str, uintmax_t *res) else if (*(p + 1)) goto err; /* unexpected suffix */ - switch(*p) { - case 'K': - case 'k': - rc = do_scale_by_power(&x, base, 1); - break; - case 'M': - case 'm': - rc = do_scale_by_power(&x, base, 2); - break; - case 'G': - case 'g': - rc = do_scale_by_power(&x, base, 3); - break; - case 'T': - case 't': - rc = do_scale_by_power(&x, base, 4); - break; - case 'P': - case 'p': - rc = do_scale_by_power(&x, base, 5); - break; - case 'E': - case 'e': - rc = do_scale_by_power(&x, base, 6); - break; - case 'Z': - rc = do_scale_by_power(&x, base, 7); - break; - case 'Y': - rc = do_scale_by_power(&x, base, 8); - break; - default: - goto err; + sp = strchr(suf, *p); + if (sp) + pwr = (sp - suf) + 1; + else { + sp = strchr(suf2, *p); + if (sp) + pwr = (sp - suf2) + 1; + else + goto err; } + rc = do_scale_by_power(&x, base, pwr); + if (power) + *power = pwr; done: *res = x; return rc; @@ -132,6 +118,11 @@ err: return -1; } +int strtosize(const char *str, uintmax_t *res) +{ + return parse_size(str, res, NULL); +} + int isdigit_string(const char *str) { const char *p;