diff options
author | Arun Prakash Jana <engineerarun@gmail.com> | 2018-10-25 00:10:58 +0530 |
---|---|---|
committer | Arun Prakash Jana <engineerarun@gmail.com> | 2018-10-25 00:10:58 +0530 |
commit | efcd223549b29d8d32773799e30296647265ad51 (patch) | |
tree | 001ea0bee6eff0b20f77255ba54b0de47843e015 | |
parent | a39b04c70a95612e95a1f902f4976cf67f3d24ff (diff) |
Support floating point and handle hex in expressions
-rw-r--r-- | src/bcal.c | 70 |
1 files changed, 12 insertions, 58 deletions
@@ -1132,8 +1132,8 @@ static maxuint_t unitconv(Data bunit, char *isunit, int *out) /* Data is a C structure containing a string p and a char * indicating if the string is a unit or a plain number */ - char *numstr = bunit.p, *punit; - int len, count; + char *numstr = bunit.p, *punit = NULL; + int count; maxfloat_t byte_metric = 0; if (numstr == NULL || *numstr == '\0') { @@ -1144,27 +1144,16 @@ static maxuint_t unitconv(Data bunit, char *isunit, int *out) log(DEBUG, "numstr: %s\n", numstr); *out = 0; - len = strlen(numstr) - 1; - if (isdigit(numstr[len])) { - char *pc = NULL; - maxuint_t r; - - /* ensure this is not the result of a previous operation */ - if (*isunit != 1) - *isunit = 0; - r = strtoull(numstr, &pc, 0); - if (*numstr != '\0' && *pc == '\0') - return r; - - log(ERROR, "invalid token: %s\n", pc); - *out = -1; - return 0; - } - while (isalpha(numstr[len])) - --len; + /* ensure this is not the result of a previous operation */ + if (*isunit != 1) + *isunit = 0; + + byte_metric = strtold(numstr, &punit); + log(DEBUG, "byte_metric: %Lf\n", byte_metric); + if (*numstr != '\0' && *punit == '\0') + return (maxuint_t)byte_metric; - punit = numstr + len + 1; log(DEBUG, "punit: %s\n", punit); count = ARRAY_SIZE(units); @@ -1183,66 +1172,31 @@ static maxuint_t unitconv(Data bunit, char *isunit, int *out) } *isunit = 1; - *punit = '\0'; switch (count) { - case 0: { - maxuint_t bytes; - bytes = (maxuint_t)strtold(numstr, &punit); - if (*punit) - goto error; - return bytes; - } + case 0: + return byte_metric; case 1: /* Kibibyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * 1024); case 2: /* Mebibyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * (1 << 20)); case 3: /* Gibibyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * (1 << 30)); case 4: /* Tebibyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * ((maxuint_t)1 << 40)); case 5: /* Kilobyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * 1000); case 6: /* Megabyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * 1000000); case 7: /* Gigabyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * 1000000000); case 8: /* Terabyte */ - byte_metric = strtold(numstr, &punit); - if (*punit) - goto error; return (maxuint_t)(byte_metric * 1000000000000); default: log(ERROR, "unknown unit\n"); *out = -1; return 0; } - -error: - log(ERROR, "malformed input\n"); - *out = -1; - return 0; } /* Get the priority of operators. |