]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/strutils: simplify strtosize(), return info about suffix
authorKarel Zak <kzak@redhat.com>
Tue, 29 Jan 2013 14:25:47 +0000 (15:25 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 11 Mar 2013 12:00:54 +0000 (13:00 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/strutils.h
lib/strutils.c

index 38eb1ce6a6df3de6eee751af37e001b69412fa1b..695343405af5d6cb714e4c2dfa38660d57edaada 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef UTIL_LINUX_STRUTILS
 #define UTIL_LINUX_STRUTILS
 
+#include <stdlib.h>
 #include <inttypes.h>
 #include <string.h>
 #include <sys/types.h>
@@ -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() */
index 8e8ab2f3709e0a5a8ef53cd6b038cc587a21c35b..53b589a41acb8ad0ff8b4758e98bf360341560f0 100644 (file)
@@ -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;