static int tweak_generic_bytes(struct vsb *vsb, volatile ssize_t *dest, const char *arg, const char *min, const char *max) { uintmax_t r, rmin = 0, rmax = 0; const char *p; if (arg != NULL) { if (min != NULL) { p = VNUM_2bytes(min, &rmin, 0); if (p != NULL) { VSB_printf(vsb, "Invalid min-val: %s\n", min); return (-1); } } if (max != NULL) { p = VNUM_2bytes(max, &rmax, 0); if (p != NULL) { VSB_printf(vsb, "Invalid max-val: %s\n", max); return (-1); } } p = VNUM_2bytes(arg, &r, 0); if (p != NULL) { VSB_printf(vsb, "Could not convert to bytes.\n"); VSB_printf(vsb, "%s\n", p); VSB_printf(vsb, " Try something like '80k' or '120M'\n"); return (-1); } if ((uintmax_t)((ssize_t)r) != r) { fmt_bytes(vsb, r); VSB_printf(vsb, " is too large for this architecture.\n"); return (-1); } if (max != NULL && r > rmax) { VSB_printf(vsb, "Must be no more than %s\n", max); VSB_printf(vsb, "\n"); return (-1); } if (min != NULL && r < rmin) { VSB_printf(vsb, "Must be at least %s\n", min); return (-1); } *dest = r; } else { fmt_bytes(vsb, *dest); } return (0); }
static void sma_init(struct stevedore *parent, int ac, char * const *av) { const char *e; uintmax_t u; struct sma_sc *sc; ASSERT_MGT(); ALLOC_OBJ(sc, SMA_SC_MAGIC); AN(sc); sc->sma_max = SIZE_MAX; assert(sc->sma_max == SIZE_MAX); parent->priv = sc; AZ(av[ac]); if (ac > 1) ARGV_ERR("(-smalloc) too many arguments\n"); if (ac == 0 || *av[0] == '\0') return; e = VNUM_2bytes(av[0], &u, 0); if (e != NULL) ARGV_ERR("(-smalloc) size \"%s\": %s\n", av[0], e); if ((u != (uintmax_t)(size_t)u)) ARGV_ERR("(-smalloc) size \"%s\": too big\n", av[0]); if (u < 1024*1024) ARGV_ERR("(-smalloc) size \"%s\": too small, " "did you forget to specify M or G?\n", av[0]); sc->sma_max = u; }
int main(int argc, char *argv[]) { int ec = 0; struct test_case *tc; uintmax_t val; const char **p; const char *e; double d1, d2; (void)argc; for (p = vec; *p != NULL; p++) { e = *p; d1 = VNUM(e + 1); if (*e == 'N') { if (!isnan(d1)) { ec++; printf("VNUM(%s) not NAN (%g)\n", e + 1, d1); } } else { d2 = atof(e + 1); if (isnan(d1)) { printf("VNUM(%s) is NAN (%g)\n", e + 1, d1); ec++; } else if (fabs((d1 - d2) / d2) > 1e-15) { printf("VNUM(%s) differs from atof() (%g)\n", e + 1, d1); ec++; } } } for (tc = test_cases; tc->str; ++tc) { e = VNUM_2bytes(tc->str, &val, tc->rel); if (e != tc->err) { printf("%s: VNUM_2bytes(\"%s\", %ju) (%s) != (%s)\n", *argv, tc->str, tc->rel, tc->err, e); ++ec; } else if (e == NULL && val != tc->val) { printf("%s: VNUM_2bytes(\"%s\", %ju) %ju != %ju (%s)\n", *argv, tc->str, tc->rel, val, tc->val, e); ++ec; } } if (!isnan(VNUM_duration(NULL))) { printf("%s: VNUM_Duration(NULL) fail\n", *argv); ++ec; } d1 = VNUM_duration(" 365.24219d "); if (d1 < 31556925.2159 || d1 > 31556925.2161) { printf("%s: VNUM_Duration() wrong: %g\n", *argv, d1); ++ec; } /* TODO: test invalid strings */ if (!ec) printf("OK\n"); return (ec > 0); }
static void tweak_generic_bytes(struct cli *cli, volatile ssize_t *dest, const char *arg, double min, double max) { uintmax_t r; const char *p; if (arg != NULL) { p = VNUM_2bytes(arg, &r, 0); if (p != NULL) { VCLI_Out(cli, "Could not convert to bytes.\n"); VCLI_Out(cli, "%s\n", p); VCLI_Out(cli, " Try something like '80k' or '120M'\n"); VCLI_SetResult(cli, CLIS_PARAM); return; } if ((uintmax_t)((ssize_t)r) != r) { fmt_bytes(cli, r); VCLI_Out(cli, " is too large for this architecture.\n"); VCLI_SetResult(cli, CLIS_PARAM); return; } if (max != 0. && r > max) { VCLI_Out(cli, "Must be no more than "); fmt_bytes(cli, (uintmax_t)max); VCLI_Out(cli, "\n"); VCLI_SetResult(cli, CLIS_PARAM); return; } if (r < min) { VCLI_Out(cli, "Must be at least "); fmt_bytes(cli, (uintmax_t)min); VCLI_Out(cli, "\n"); VCLI_SetResult(cli, CLIS_PARAM); return; } *dest = r; } else { fmt_bytes(cli, *dest); } }
static void smu_init(struct stevedore *parent, int ac, char * const *av) { const char *e; uintmax_t u; (void)parent; AZ(av[ac]); if (ac > 1) ARGV_ERR("(-sumem) too many arguments\n"); if (ac == 0 || *av[0] == '\0') return; e = VNUM_2bytes(av[0], &u, 0); if (e != NULL) ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); if ((u != (uintmax_t)(size_t)u)) ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]); smu_max = u; }
uintmax_t STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) { uintmax_t l, fssize; unsigned bs; const char *q; int i; off_t o; struct stat st; AN(granularity); AN(ctx); AZ(fstat(fd, &st)); xxxassert(S_ISREG(st.st_mode)); AZ(VFIL_fsinfo(fd, &bs, &fssize, NULL)); /* Increase granularity if it is lower than the filesystem block size */ if (*granularity < bs) *granularity = bs; if ((size == NULL || *size == '\0') && st.st_size != 0) { /* * We have no size specification, but an existing file, * use its existing size. */ l = st.st_size; } else if (size == NULL || *size == '\0') { ARGV_ERR("(%s) no size specified\n", ctx); } else { AN(size); q = VNUM_2bytes(size, &l, 0); if (q != NULL) ARGV_ERR("(%s) size \"%s\": %s\n", ctx, size, q); if (l < 1024*1024) ARGV_ERR("(%s) size \"%s\": too small, " "did you forget to specify M or G?\n", ctx, size); if (l > fssize) ARGV_ERR("(%s) size \"%s\": larger than file system\n", ctx, size); } /* * This trickery wouldn't be necessary if X/Open would * just add OFF_MAX to <limits.h>... */ i = 0; while(1) { o = l; if (o == l && o > 0) break; l >>= 1; i++; } if (i) fprintf(stderr, "WARNING: (%s) file size reduced" " to %ju due to system \"off_t\" limitations\n", ctx, l); if (sizeof(void *) == 4 && l > INT32_MAX) { /*lint !e506 !e774 !e845 */ fprintf(stderr, "NB: Storage size limited to 2GB on 32 bit architecture,\n" "NB: otherwise we could run out of address space.\n" ); l = INT32_MAX; } /* Round down */ l -= (l % *granularity); return(l); }