#ifndef UTIL_LINUX_STRUTILS
#define UTIL_LINUX_STRUTILS
+#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#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);
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() */
* 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;
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;
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;