saner perf_atoll()
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 29 Aug 2014 16:37:29 +0000 (12:37 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 9 Oct 2014 06:39:10 +0000 (02:39 -0400)
That loop in there is both anti-idiomatic *and* completely pointless.
strtoll() is there for purpose; use it and compare what's left with
acceptable suffices.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
tools/perf/util/string.c

index 2553e5b..d87767f 100644 (file)
@@ -9,78 +9,48 @@
  */
 s64 perf_atoll(const char *str)
 {
-       unsigned int i;
-       s64 length = -1, unit = 1;
+       s64 length;
+       char *p;
+       char c;
 
        if (!isdigit(str[0]))
                goto out_err;
 
-       for (i = 1; i < strlen(str); i++) {
-               switch (str[i]) {
-               case 'B':
-               case 'b':
-                       break;
-               case 'K':
-                       if (str[i + 1] != 'B')
-                               goto out_err;
-                       else
-                               goto kilo;
-               case 'k':
-                       if (str[i + 1] != 'b')
-                               goto out_err;
-kilo:
-                       unit = K;
-                       break;
-               case 'M':
-                       if (str[i + 1] != 'B')
-                               goto out_err;
-                       else
-                               goto mega;
-               case 'm':
-                       if (str[i + 1] != 'b')
+       length = strtoll(str, &p, 10);
+       switch (c = *p++) {
+               case 'b': case 'B':
+                       if (*p)
                                goto out_err;
-mega:
-                       unit = K * K;
+               case '\0':
+                       return length;
+               default:
+                       goto out_err;
+               /* two-letter suffices */
+               case 'k': case 'K':
+                       length <<= 10;
                        break;
-               case 'G':
-                       if (str[i + 1] != 'B')
-                               goto out_err;
-                       else
-                               goto giga;
-               case 'g':
-                       if (str[i + 1] != 'b')
-                               goto out_err;
-giga:
-                       unit = K * K * K;
+               case 'm': case 'M':
+                       length <<= 20;
                        break;
-               case 'T':
-                       if (str[i + 1] != 'B')
-                               goto out_err;
-                       else
-                               goto tera;
-               case 't':
-                       if (str[i + 1] != 'b')
-                               goto out_err;
-tera:
-                       unit = K * K * K * K;
+               case 'g': case 'G':
+                       length <<= 30;
                        break;
-               case '\0':      /* only specified figures */
-                       unit = 1;
+               case 't': case 'T':
+                       length <<= 40;
                        break;
-               default:
-                       if (!isdigit(str[i]))
-                               goto out_err;
-                       break;
-               }
        }
-
-       length = atoll(str) * unit;
-       goto out;
+       /* we want the cases to match */
+       if (islower(c)) {
+               if (strcmp(p, "b") != 0)
+                       goto out_err;
+       } else {
+               if (strcmp(p, "B") != 0)
+                       goto out_err;
+       }
+       return length;
 
 out_err:
-       length = -1;
-out:
-       return length;
+       return -1;
 }
 
 /*