double VNUM(const char *p) { const char *t; double r; r = VNUMpfx(p, &t); if (t != NULL) r = nan(""); return (r); }
vmod_duration(VRT_CTX, VCL_STRING p, VCL_DURATION d) { const char *e; double r; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (p == NULL) return (d); while(isspace(*p)) p++; if (*p != '+' && *p != '-' && !isdigit(*p)) return (d); e = NULL; r = VNUMpfx(p, &e); if (isnan(r) || e == NULL) return (d); while(isspace(*e)) e++; /* NB: Keep this list synchronized with VCC */ switch (*e++) { case 's': break; case 'm': if (*e == 's') { r *= 1e-3; e++; } else r *= 60.; break; case 'h': r *= 60.*60.; break; case 'd': r *= 60.*60.*24.; break; case 'w': r *= 60.*60.*24.*7.; break; case 'y': r *= 60.*60.*24.*365.; break; default: return (d); } while(isspace(*e)) e++; if (*e != '\0') return (d); return (r); }
double VNUM_duration(const char *p) { const char *t; double r, sc = 1.0; if (p == NULL) return (nan("")); r = VNUMpfx(p, &t); if (isnan(r) || t == NULL) return (nan("")); while (isspace(*t)) t++; // keep in sync with vcc_expr.c vcc_TimeUnit() switch (*t++) { case 's': break; case 'm': if (*t == 's') { sc = 1e-3; t++; } else sc = 60.0; break; case 'h': sc = 60.0 * 60.0; break; case 'd': sc = 60.0 * 60.0 * 24.0; break; case 'w': sc = 60.0 * 60.0 * 24.0 * 7.0; break; case 'y': sc = 60.0 * 60.0 * 24.0 * 365.0; break; default: return (nan("")); } while (isspace(*t)) t++; if (*t != '\0') return (nan("")); return (r * sc); }
vmod_integer(VRT_CTX, VCL_STRING p, VCL_INT i) { const char *e; double r; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (p == NULL) return (i); r = VNUMpfx(p, &e); if (isnan(r) || e != NULL) return (i); r = trunc(r); if (r > LONG_MAX || r < LONG_MIN) return (i); return ((long)r); }
const char * VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel) { double fval; const char *end; if (p == NULL || *p == '\0') return (err_miss_num); fval = VNUMpfx(p, &end); if (isnan(fval)) return (err_invalid_num); if (end == NULL) { *r = (uintmax_t)fval; return (NULL); } if (end[0] == '%' && end[1] == '\0') { if (rel == 0) return (err_abs_req); fval *= rel / 100.0; } else { /* accept a space before the multiplier */ if (end[0] == ' ' && end[1] != '\0') ++end; switch (end[0]) { case 'k': case 'K': fval *= (uintmax_t)1 << 10; ++end; break; case 'm': case 'M': fval *= (uintmax_t)1 << 20; ++end; break; case 'g': case 'G': fval *= (uintmax_t)1 << 30; ++end; break; case 't': case 'T': fval *= (uintmax_t)1 << 40; ++end; break; case 'p': case 'P': fval *= (uintmax_t)1 << 50; ++end; break; default: break; } /* [bB] is a generic suffix of no effect */ if (end[0] == 'b' || end[0] == 'B') end++; if (end[0] != '\0') return (err_invalid_suff); } *r = (uintmax_t)round(fval); return (NULL); }