1 #define ANYSINT_MAX(t) ((((t) 1 << (sizeof(t) * 8 - 2)) - (t) 1) * (t) 2 + (t) 1)
   2 
   3 static ssize_t hprint(char *buf, int64_t v)
   4 {
   5         static const char units[] = "\0kMGTPEZY";
   6         char dec[3] = "";
   7         int u, t;
   8 
   9         for (u = 0; v >= 1024 || v <= -1024; u++)
  10                 t = do_div(v, 1024);
  11 
  12         if (u && v < 10 && v > -10)
  13                 sprintf(dec, ".%i", t / 100);
  14 
  15         return sprintf(buf, "%lli%s%c", v, dec, units[u]);
  16 }
  17 
  18 #define STRTO_H(name, type)                                     \
  19 static int name ## _h(const char *cp, type *res)                \
  20 {                                                               \
  21         int u = 0;                                              \
  22         char *e;                                                \
  23         type i = simple_ ## name(cp, &e, 10);                   \
  24                                                                 \
  25         switch (tolower(*e)) {                                  \
  26         default:                                                \
  27                 return -EINVAL;                                 \
  28         case 'y':                                               \
  29         case 'z':                                               \
  30                 u++;                                            \
  31         case 'e':                                               \
  32                 u++;                                            \
  33         case 'p':                                               \
  34                 u++;                                            \
  35         case 't':                                               \
  36                 u++;                                            \
  37         case 'g':                                               \
  38                 u++;                                            \
  39         case 'm':                                               \
  40                 u++;                                            \
  41         case 'k':                                               \
  42                 u++;                                            \
  43                 if (e++ == cp)                                  \
  44                         return -EINVAL;                         \
  45         case '\n':                                              \
  46         case '\0':                                              \
  47                 if (*e == '\n')                                 \
  48                         e++;                                    \
  49         }                                                       \
  50                                                                 \
  51         if (*e)                                                 \
  52                 return -EINVAL;                                 \
  53                                                                 \
  54         while (u--) {                                           \
  55                 if ((type) ~0 > 0 &&                            \
  56                     (type) ~0 / 1024 <= i)                      \
  57                         return -EINVAL;                         \
  58                 if ((i > 0 && ANYSINT_MAX(type) / 1024 < i) ||  \
  59                     (i < 0 && -ANYSINT_MAX(type) / 1024 > i))   \
  60                         return -EINVAL;                         \
  61                 i *= 1024;                                      \
  62         }                                                       \
  63                                                                 \
  64         *res = i;                                               \
  65         return 0;                                               \
  66 }
  67 
  68 STRTO_H(strtol, long)
  69 STRTO_H(strtoll, long long)
  70 STRTO_H(strtoul, unsigned long)
  71 STRTO_H(strtoull, unsigned long long)
  72 
  73 #define strtoi_h(cp, res)                                               \
  74         (__builtin_types_compatible_p(typeof(*res), long)               \
  75         ? strtol_h(cp, (void*) res)                                     \
  76         : __builtin_types_compatible_p(typeof(*res), long long)         \
  77         ? strtoll_h(cp, (void*) res)                                    \
  78         : __builtin_types_compatible_p(typeof(*res), unsigned long)     \
  79         ? strtoul_h(cp, (void*) res)                                    \
  80         : __builtin_types_compatible_p(typeof(*res), unsigned long long)\
  81         ? strtoull_h(cp, (void*) res) : -EINVAL)                        \
  82 

BcacheWiki: HumanReadableUnits (last edited 2010-06-29 04:46:38 by Kent)