+
+ /* If kb_base is 1000, use true units.
+ * If kb_base is 1024, use opposite units.
+ */
+ if (!strncmp("pib", c, 3)) {
+ pow = 5;
+ if (kb_base == 1000)
+ mult = 1024;
+ else if (kb_base == 1024)
+ mult = 1000;
+ } else if (!strncmp("tib", c, 3)) {
+ pow = 4;
+ if (kb_base == 1000)
+ mult = 1024;
+ else if (kb_base == 1024)
+ mult = 1000;
+ } else if (!strncmp("gib", c, 3)) {
+ pow = 3;
+ if (kb_base == 1000)
+ mult = 1024;
+ else if (kb_base == 1024)
+ mult = 1000;
+ } else if (!strncmp("mib", c, 3)) {
+ pow = 2;
+ if (kb_base == 1000)
+ mult = 1024;
+ else if (kb_base == 1024)
+ mult = 1000;
+ } else if (!strncmp("kib", c, 3)) {
+ pow = 1;
+ if (kb_base == 1000)
+ mult = 1024;
+ else if (kb_base == 1024)
+ mult = 1000;
+ } else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2)) {
+ pow = 5;
+ } else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2)) {
+ pow = 4;
+ } else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2)) {
+ pow = 3;
+ } else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2)) {
+ pow = 2;
+ } else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2)) {
+ pow = 1;
+ } else if (!strncmp("%", c, 1)) {
+ *percent = 1;
+ free(c);
+ return ret;
+ }
+
+ while (pow--)
+ ret *= (unsigned long long) mult;
+
+ free(c);
+ return ret;
+}
+
+static unsigned long long get_mult_bytes(const char *str, int len, void *data,
+ int *percent)
+{
+ const char *p = str;
+ int digit_seen = 0;
+
+ if (len < 2)
+ return __get_mult_bytes(str, data, percent);
+
+ /*
+ * Go forward until we hit a non-digit, or +/- sign
+ */
+ while ((p - str) <= len) {
+ if (!isdigit((int) *p) &&
+ (((*p != '+') && (*p != '-')) || digit_seen))
+ break;
+ digit_seen |= isdigit((int) *p);
+ p++;
+ }
+
+ if (!isalpha((int) *p) && (*p != '%'))
+ p = NULL;
+
+ return __get_mult_bytes(p, data, percent);
+}
+
+extern int evaluate_arithmetic_expression(const char *buffer, long long *ival,
+ double *dval, double implied_units,
+ int is_time);
+
+/*
+ * Convert string into a floating number. Return 1 for success and 0 otherwise.
+ */
+int str_to_float(const char *str, double *val, int is_time)
+{
+#ifdef CONFIG_ARITHMETIC
+ int rc;
+ long long ival;
+ double dval;
+
+ if (str[0] == '(') {
+ rc = evaluate_arithmetic_expression(str, &ival, &dval, 1.0, is_time);
+ if (!rc) {
+ *val = dval;
+ return 1;
+ }
+ }
+#endif
+ return 1 == sscanf(str, "%lf", val);