summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bench/ioq.c16
-rw-r--r--src/bfstd.c94
-rw-r--r--src/bfstd.h30
-rw-r--r--tests/bfstd.c84
-rw-r--r--tests/main.c8
-rw-r--r--tests/ptyx.c36
-rw-r--r--tests/xtouch.c4
7 files changed, 218 insertions, 54 deletions
diff --git a/bench/ioq.c b/bench/ioq.c
index 5db585a..61c9714 100644
--- a/bench/ioq.c
+++ b/bench/ioq.c
@@ -177,9 +177,9 @@ int main(int argc, char *argv[]) {
setlocale(LC_ALL, "");
// -d: queue depth
- long depth = 4096;
+ unsigned int depth = 4096;
// -j: threads
- long threads = 0;
+ unsigned int threads = 0;
// -t: timeout
double timeout = 5.0;
// -L|-H: ioq_nop() type
@@ -190,13 +190,13 @@ int main(int argc, char *argv[]) {
while (c = getopt(argc, argv, ":d:j:t:LH"), c != -1) {
switch (c) {
case 'd':
- if (xstrtol(optarg, NULL, 10, &depth) != 0) {
+ if (xstrtoui(optarg, NULL, 10, &depth) != 0) {
fprintf(stderr, "%s: Bad depth '%s': %s\n", cmd, optarg, errstr());
return EXIT_FAILURE;
}
break;
case 'j':
- if (xstrtol(optarg, NULL, 10, &threads) != 0) {
+ if (xstrtoui(optarg, NULL, 10, &threads) != 0) {
fprintf(stderr, "%s: Bad thread count '%s': %s\n", cmd, optarg, errstr());
return EXIT_FAILURE;
}
@@ -222,7 +222,7 @@ int main(int argc, char *argv[]) {
}
}
- if (threads <= 0) {
+ if (!threads) {
threads = nproc();
if (threads > 8) {
threads = 8;
@@ -238,8 +238,8 @@ int main(int argc, char *argv[]) {
printf("I/O queue benchmark (%s)\n\n", bfs_version);
- printf("[-d] depth: %ld\n", depth);
- printf("[-j] threads: %ld (including main)\n", threads + 1);
+ printf("[-d] depth: %u\n", depth);
+ printf("[-j] threads: %u (including main)\n", threads + 1);
if (type == IOQ_NOP_HEAVY) {
printf("[-H] type: heavy (with syscalls)\n");
} else {
@@ -252,7 +252,7 @@ int main(int argc, char *argv[]) {
fflush(stdout);
struct ioq *ioq = ioq_create(depth, threads);
- bfs_everify(ioq, "ioq_create(%ld, %ld)", depth, threads);
+ bfs_everify(ioq, "ioq_create(%u, %u)", depth, threads);
// Pre-allocate all the requests
while (ioq_capacity(ioq) > 0) {
diff --git a/src/bfstd.c b/src/bfstd.c
index 4269d55..b78af7a 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -235,6 +235,36 @@ static int xstrtox_epilogue(const char *str, char **end, char *endp) {
return 0;
}
+int xstrtos(const char *str, char **end, int base, short *value) {
+ long n;
+ if (xstrtol(str, end, base, &n) != 0) {
+ return -1;
+ }
+
+ if (n < SHRT_MIN || n > SHRT_MAX) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *value = n;
+ return 0;
+}
+
+int xstrtoi(const char *str, char **end, int base, int *value) {
+ long n;
+ if (xstrtol(str, end, base, &n) != 0) {
+ return -1;
+ }
+
+ if (n < INT_MIN || n > INT_MAX) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *value = n;
+ return 0;
+}
+
int xstrtol(const char *str, char **end, int base, long *value) {
if (xstrtox_prologue(str) != 0) {
return -1;
@@ -275,6 +305,70 @@ int xstrtod(const char *str, char **end, double *value) {
return xstrtox_epilogue(str, end, endp);
}
+int xstrtous(const char *str, char **end, int base, unsigned short *value) {
+ unsigned long n;
+ if (xstrtoul(str, end, base, &n) != 0) {
+ return -1;
+ }
+
+ if (n > USHRT_MAX) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *value = n;
+ return 0;
+}
+
+int xstrtoui(const char *str, char **end, int base, unsigned int *value) {
+ unsigned long n;
+ if (xstrtoul(str, end, base, &n) != 0) {
+ return -1;
+ }
+
+ if (n > UINT_MAX) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *value = n;
+ return 0;
+}
+
+/** Common epilogue for xstrtou*() wrappers. */
+static int xstrtoux_epilogue(const char *str, char **end, char *endp) {
+ if (xstrtox_epilogue(str, end, endp) != 0) {
+ return -1;
+ }
+
+ if (str[0] == '-') {
+ errno = ERANGE;
+ return -1;
+ }
+
+ return 0;
+}
+
+int xstrtoul(const char *str, char **end, int base, unsigned long *value) {
+ if (xstrtox_prologue(str) != 0) {
+ return -1;
+ }
+
+ char *endp;
+ *value = strtoul(str, &endp, base);
+ return xstrtoux_epilogue(str, end, endp);
+}
+
+int xstrtoull(const char *str, char **end, int base, unsigned long long *value) {
+ if (xstrtox_prologue(str) != 0) {
+ return -1;
+ }
+
+ char *endp;
+ *value = strtoull(str, &endp, base);
+ return xstrtoux_epilogue(str, end, endp);
+}
+
/** Compile and execute a regular expression for xrpmatch(). */
static int xrpregex(nl_item item, const char *response) {
const char *pattern = nl_langinfo(item);
diff --git a/src/bfstd.h b/src/bfstd.h
index 51920c9..15dd949 100644
--- a/src/bfstd.h
+++ b/src/bfstd.h
@@ -169,6 +169,16 @@ char *xgetdelim(FILE *file, char delim);
const char *xgetprogname(void);
/**
+ * Like xstrtol(), but for short.
+ */
+int xstrtos(const char *str, char **end, int base, short *value);
+
+/**
+ * Like xstrtol(), but for int.
+ */
+int xstrtoi(const char *str, char **end, int base, int *value);
+
+/**
* Wrapper for strtol() that forbids leading spaces.
*/
int xstrtol(const char *str, char **end, int base, long *value);
@@ -179,6 +189,26 @@ int xstrtol(const char *str, char **end, int base, long *value);
int xstrtoll(const char *str, char **end, int base, long long *value);
/**
+ * Like xstrtoul(), but for unsigned short.
+ */
+int xstrtous(const char *str, char **end, int base, unsigned short *value);
+
+/**
+ * Like xstrtoul(), but for unsigned int.
+ */
+int xstrtoui(const char *str, char **end, int base, unsigned int *value);
+
+/**
+ * Wrapper for strtoul() that forbids leading spaces, negatives.
+ */
+int xstrtoul(const char *str, char **end, int base, unsigned long *value);
+
+/**
+ * Wrapper for strtoull() that forbids leading spaces, negatives.
+ */
+int xstrtoull(const char *str, char **end, int base, unsigned long long *value);
+
+/**
* Wrapper for strtof() that forbids leading spaces.
*/
int xstrtof(const char *str, char **end, float *value);
diff --git a/tests/bfstd.c b/tests/bfstd.c
index 685aa6c..6e15e2b 100644
--- a/tests/bfstd.c
+++ b/tests/bfstd.c
@@ -4,7 +4,6 @@
#include "tests.h"
#include "bfstd.h"
-#include "bit.h"
#include "diag.h"
#include <errno.h>
@@ -95,37 +94,74 @@ static void check_wordescs(void) {
/** xstrto*() test cases. */
static void check_strtox(void) {
+ short s;
+ unsigned short us;
+ int i;
+ unsigned int ui;
long l;
+ unsigned long ul;
long long ll;
+ unsigned long long ull;
char *end;
+#define check_strtouerr(err, str, end, base) \
+ do { \
+ bfs_echeck(xstrtous(str, end, base, &us) != 0 && errno == err); \
+ bfs_echeck(xstrtoui(str, end, base, &ui) != 0 && errno == err); \
+ bfs_echeck(xstrtoul(str, end, base, &ul) != 0 && errno == err); \
+ bfs_echeck(xstrtoull(str, end, base, &ull) != 0 && errno == err); \
+ } while (0)
+
+ check_strtouerr(ERANGE, "-1", NULL, 0);
+ check_strtouerr(ERANGE, "-0x1", NULL, 0);
+
+ check_strtouerr(EINVAL, "-", NULL, 0);
+ check_strtouerr(EINVAL, "-q", NULL, 0);
+ check_strtouerr(EINVAL, "-1q", NULL, 0);
+ check_strtouerr(EINVAL, "-0x", NULL, 0);
+
#define check_strtoerr(err, str, end, base) \
- bfs_echeck(xstrtol(str, end, base, &l) != 0 && errno == err); \
- bfs_echeck(xstrtoll(str, end, base, &ll) != 0 && errno == err)
+ do { \
+ bfs_echeck(xstrtos(str, end, base, &s) != 0 && errno == err); \
+ bfs_echeck(xstrtoi(str, end, base, &i) != 0 && errno == err); \
+ bfs_echeck(xstrtol(str, end, base, &l) != 0 && errno == err); \
+ bfs_echeck(xstrtoll(str, end, base, &ll) != 0 && errno == err); \
+ check_strtouerr(err, str, end, base); \
+ } while (0)
check_strtoerr(EINVAL, "", NULL, 0);
check_strtoerr(EINVAL, "", &end, 0);
check_strtoerr(EINVAL, " 1 ", &end, 0);
+ check_strtoerr(EINVAL, " -1", NULL, 0);
check_strtoerr(EINVAL, " 123", NULL, 0);
check_strtoerr(EINVAL, "123 ", NULL, 0);
check_strtoerr(EINVAL, "0789", NULL, 0);
check_strtoerr(EINVAL, "789A", NULL, 0);
check_strtoerr(EINVAL, "0x", NULL, 0);
check_strtoerr(EINVAL, "0x789A", NULL, 10);
-
- if (LLONG_WIDTH == 64) {
- check_strtoerr(ERANGE, "9223372036854775808", NULL, 0);
- }
+ check_strtoerr(EINVAL, "0x-1", NULL, 0);
+
+#define check_strtotype(type, min, max, fmt, fn, str, base, v, n) \
+ do { \
+ if ((n) >= min && (n) <= max) { \
+ bfs_echeck(fn(str, NULL, base, &v) == 0); \
+ bfs_check(v == (type)(n), "%s('%s') == " fmt " (!= " fmt ")", #fn, str, v, (type)(n)); \
+ } else { \
+ bfs_echeck(fn(str, NULL, base, &v) != 0 && errno == ERANGE); \
+ } \
+ } while (0)
#define check_strtoint(str, base, n) \
- if ((n) >= LONG_MIN && (n) <= LONG_MAX) { \
- bfs_echeck(xstrtol(str, NULL, base, &l) == 0); \
- bfs_check(l == (n), "xstrtol('%s') == %ld (!= %ld)", str, l, (long)(n)); \
- } else { \
- bfs_echeck(xstrtol(str, NULL, base, &l) != 0 && errno == ERANGE); \
- } \
- bfs_echeck(xstrtoll(str, NULL, base, &ll) == 0); \
- bfs_check(ll == (n), "xstrtoll('%s') == %lld (!= %lld)", str, ll, (long long)(n)) \
+ do { \
+ check_strtotype( signed short, SHRT_MIN, SHRT_MAX, "%d", xstrtos, str, base, s, n); \
+ check_strtotype( signed int, INT_MIN, INT_MAX, "%d", xstrtoi, str, base, i, n); \
+ check_strtotype( signed long, LONG_MIN, LONG_MAX, "%ld", xstrtol, str, base, l, n); \
+ check_strtotype( signed long long, LLONG_MIN, LLONG_MAX, "%lld", xstrtoll, str, base, ll, n); \
+ check_strtotype(unsigned short, 0, USHRT_MAX, "%u", xstrtous, str, base, us, n); \
+ check_strtotype(unsigned int, 0, UINT_MAX, "%u", xstrtoui, str, base, ui, n); \
+ check_strtotype(unsigned long, 0, ULONG_MAX, "%lu", xstrtoul, str, base, ul, n); \
+ check_strtotype(unsigned long long, 0, ULLONG_MAX, "%llu", xstrtoull, str, base, ull, n); \
+ } while (0)
check_strtoint("123", 0, 123);
check_strtoint("+123", 0, 123);
@@ -139,13 +175,21 @@ static void check_strtox(void) {
check_strtoint("123", 16, 0x123);
- check_strtoint("9223372036854775807", 0, 9223372036854775807LL);
- check_strtoint("-9223372036854775808", 0, -9223372036854775807LL - 1);
+ check_strtoint("0x7FFF", 0, 0x7FFF);
+ check_strtoint("-0x8000", 0, -0x8000);
+
+ check_strtoint("0x7FFFFFFF", 0, 0x7FFFFFFFL);
+ check_strtoint("-0x80000000", 0, -0x7FFFFFFFL - 1);
+
+ check_strtoint("0x7FFFFFFFFFFFFFFF", 0, 0x7FFFFFFFFFFFFFFFLL);
+ check_strtoint("-0x8000000000000000", 0, -0x7FFFFFFFFFFFFFFFLL - 1);
#define check_strtoend(str, estr, base, n) \
- bfs_echeck(xstrtoll(str, &end, base, &ll) == 0); \
- bfs_check(ll == (n), "xstrtoll('%s') == %lld (!= %lld)", str, ll, (long long)(n)); \
- bfs_check(strcmp(end, estr) == 0, "xstrtoll('%s'): end == '%s' (!= '%s')", str, end, estr) \
+ do { \
+ bfs_echeck(xstrtoll(str, &end, base, &ll) == 0); \
+ bfs_check(ll == (n), "xstrtoll('%s') == %lld (!= %lld)", str, ll, (long long)(n)); \
+ bfs_check(strcmp(end, estr) == 0, "xstrtoll('%s'): end == '%s' (!= '%s')", str, end, estr); \
+ } while (0)
check_strtoend("123 ", " ", 0, 123);
check_strtoend("0789", "89", 0, 07);
diff --git a/tests/main.c b/tests/main.c
index 4c770bd..9240e1c 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -222,15 +222,15 @@ int main(int argc, char *argv[]) {
}
tzset();
- long jobs = 0;
+ unsigned int jobs = 0;
const char *cmd = argc > 0 ? argv[0] : "units";
int c;
while (c = getopt(argc, argv, ":j:"), c != -1) {
switch (c) {
case 'j':
- if (xstrtol(optarg, NULL, 10, &jobs) != 0 || jobs <= 0) {
- fprintf(stderr, "%s: Bad job count '%s'\n", cmd, optarg);
+ if (xstrtoui(optarg, NULL, 10, &jobs) != 0) {
+ fprintf(stderr, "%s: Bad job count '%s': %s\n", cmd, optarg, errstr());
return EXIT_FAILURE;
}
break;
@@ -243,7 +243,7 @@ int main(int argc, char *argv[]) {
}
}
- if (jobs == 0) {
+ if (!jobs) {
jobs = nproc();
}
diff --git a/tests/ptyx.c b/tests/ptyx.c
index 4d89581..59292df 100644
--- a/tests/ptyx.c
+++ b/tests/ptyx.c
@@ -65,25 +65,21 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE); \
} while (0)
- long width = -1;
- long height = -1;
+ unsigned short width = 0;
+ unsigned short height = 0;
// Parse the command line
int c;
while (c = getopt(argc, argv, "+:w:h:"), c != -1) {
switch (c) {
case 'w':
- if (xstrtol(optarg, NULL, 10, &width) != 0) {
+ if (xstrtous(optarg, NULL, 10, &width) != 0) {
edie("Bad width '%s'", optarg);
- } else if (width < 0 || width > (long)USHRT_MAX) {
- die("Bad width '%s'", optarg);
}
break;
case 'h':
- if (xstrtol(optarg, NULL, 10, &height) != 0) {
+ if (xstrtous(optarg, NULL, 10, &height) != 0) {
edie("Bad height '%s'", optarg);
- } else if (height < 0 || height > (long)USHRT_MAX) {
- die("Bad height '%s'", optarg);
}
break;
case ':':
@@ -135,36 +131,36 @@ int main(int argc, char *argv[]) {
// A new pty starts at 0x0, which is not very useful. Instead, grab the
// default size from the current controlling terminal, if possible.
- if (width < 0 || height < 0) {
+ if (!width || !height) {
int tty = open_cterm(O_RDONLY | O_CLOEXEC);
if (tty >= 0) {
struct winsize ws;
if (xtcgetwinsize(tty, &ws) != 0) {
edie("tcgetwinsize()");
}
- if (width < 0) {
+ if (!width) {
width = ws.ws_col;
}
- if (height < 0) {
+ if (!height) {
height = ws.ws_row;
}
xclose(tty);
}
}
+ if (!width) {
+ width = 80;
+ }
+ if (!height) {
+ height = 24;
+ }
- // Get the current pty size
+ // Update the pty size
struct winsize ws;
if (xtcgetwinsize(pts, &ws) != 0) {
edie("tcgetwinsize()");
}
-
- // Apply our options
- if (width >= 0) {
- ws.ws_col = width;
- }
- if (height >= 0) {
- ws.ws_row = height;
- }
+ ws.ws_col = width;
+ ws.ws_row = height;
if (xtcsetwinsize(pts, &ws) != 0) {
edie("tcsetwinsize()");
}
diff --git a/tests/xtouch.c b/tests/xtouch.c
index 5d65a4c..f33c573 100644
--- a/tests/xtouch.c
+++ b/tests/xtouch.c
@@ -217,8 +217,8 @@ int main(int argc, char *argv[]) {
}
if (marg) {
- long mode;
- if (xstrtol(marg, NULL, 8, &mode) == 0 && mode >= 0 && mode < 01000) {
+ unsigned int mode;
+ if (xstrtoui(marg, NULL, 8, &mode) == 0 && mode < 01000) {
args.fmode = args.dmode = mode;
} else {
fprintf(stderr, "%s: Invalid mode '%s'\n", cmd, marg);