1*223750d9SAndy Fiddaman /*
2*223750d9SAndy Fiddaman  * This file and its contents are supplied under the terms of the
3*223750d9SAndy Fiddaman  * Common Development and Distribution License ("CDDL"), version 1.0.
4*223750d9SAndy Fiddaman  * You may only use this file in accordance with the terms of version
5*223750d9SAndy Fiddaman  * 1.0 of the CDDL.
6*223750d9SAndy Fiddaman  *
7*223750d9SAndy Fiddaman  * A full copy of the text of the CDDL should have accompanied this
8*223750d9SAndy Fiddaman  * source.  A copy of the CDDL is also available via the Internet at
9*223750d9SAndy Fiddaman  * http://www.illumos.org/license/CDDL.
10*223750d9SAndy Fiddaman  */
11*223750d9SAndy Fiddaman 
12*223750d9SAndy Fiddaman /*
13*223750d9SAndy Fiddaman  * Copyright 2023 Oxide Computer Company
14*223750d9SAndy Fiddaman  */
15*223750d9SAndy Fiddaman 
16*223750d9SAndy Fiddaman /*
17*223750d9SAndy Fiddaman  * Test the implementation of strtonum() and strtonumx()
18*223750d9SAndy Fiddaman  */
19*223750d9SAndy Fiddaman 
20*223750d9SAndy Fiddaman #include <limits.h>
21*223750d9SAndy Fiddaman #include <stdbool.h>
22*223750d9SAndy Fiddaman #include <stdio.h>
23*223750d9SAndy Fiddaman #include <stdlib.h>
24*223750d9SAndy Fiddaman #include <string.h>
25*223750d9SAndy Fiddaman 
26*223750d9SAndy Fiddaman bool fail = false;
27*223750d9SAndy Fiddaman 
28*223750d9SAndy Fiddaman static void
runtestx(const char * nstr,long long minval,long long maxval,int base,long long expval,bool expect_pass)29*223750d9SAndy Fiddaman runtestx(const char *nstr, long long minval, long long maxval,
30*223750d9SAndy Fiddaman     int base, long long expval, bool expect_pass)
31*223750d9SAndy Fiddaman {
32*223750d9SAndy Fiddaman 	const char *errstr;
33*223750d9SAndy Fiddaman 	char key[0x100];
34*223750d9SAndy Fiddaman 	long long val;
35*223750d9SAndy Fiddaman 
36*223750d9SAndy Fiddaman 	if (base == -1) {
37*223750d9SAndy Fiddaman 		val = strtonum(nstr, minval, maxval, &errstr);
38*223750d9SAndy Fiddaman 		(void) snprintf(key, sizeof (key), "strtonum(%s)", nstr);
39*223750d9SAndy Fiddaman 	} else {
40*223750d9SAndy Fiddaman 		val = strtonumx(nstr, minval, maxval, &errstr, base);
41*223750d9SAndy Fiddaman 		(void) snprintf(key, sizeof (key), "strtonumx(%s, %d)",
42*223750d9SAndy Fiddaman 		    nstr, base);
43*223750d9SAndy Fiddaman 	}
44*223750d9SAndy Fiddaman 
45*223750d9SAndy Fiddaman 	if (expect_pass) {
46*223750d9SAndy Fiddaman 		if (errstr != NULL) {
47*223750d9SAndy Fiddaman 			fprintf(stderr, "FAIL %s was rejected: "
48*223750d9SAndy Fiddaman 			    "%s [%lld,%lld]\n",
49*223750d9SAndy Fiddaman 			    key, errstr, minval, maxval);
50*223750d9SAndy Fiddaman 			fail = true;
51*223750d9SAndy Fiddaman 		} else {
52*223750d9SAndy Fiddaman 			fprintf(stdout, "PASS %s was accepted: "
53*223750d9SAndy Fiddaman 			    "[%lld,%lld] = %lld\n",
54*223750d9SAndy Fiddaman 			    key, minval, maxval, val);
55*223750d9SAndy Fiddaman 			if (val != expval) {
56*223750d9SAndy Fiddaman 				fprintf(stderr, "FAIL %s returned wrong value: "
57*223750d9SAndy Fiddaman 				    "[%lld,%lld] = %lld vs. %lld\n", key,
58*223750d9SAndy Fiddaman 				    minval, maxval, val, expval);
59*223750d9SAndy Fiddaman 				fail = true;
60*223750d9SAndy Fiddaman 			}
61*223750d9SAndy Fiddaman 		}
62*223750d9SAndy Fiddaman 	} else {
63*223750d9SAndy Fiddaman 		if (errstr == NULL) {
64*223750d9SAndy Fiddaman 			fprintf(stderr, "FAIL %s was accepted: "
65*223750d9SAndy Fiddaman 			    "[%lld,%lld] = %lld\n",
66*223750d9SAndy Fiddaman 			    key, minval, maxval, val);
67*223750d9SAndy Fiddaman 			fail = true;
68*223750d9SAndy Fiddaman 		} else {
69*223750d9SAndy Fiddaman 			fprintf(stdout, "PASS %s was rejected: "
70*223750d9SAndy Fiddaman 			    "%s [%lld,%lld]\n",
71*223750d9SAndy Fiddaman 			    key, errstr, minval, maxval);
72*223750d9SAndy Fiddaman 		}
73*223750d9SAndy Fiddaman 	}
74*223750d9SAndy Fiddaman }
75*223750d9SAndy Fiddaman 
76*223750d9SAndy Fiddaman static void
runtest(const char * nstr,long long minval,long long maxval,long long expval,bool expect_pass)77*223750d9SAndy Fiddaman runtest(const char *nstr, long long minval, long long maxval, long long expval,
78*223750d9SAndy Fiddaman     bool expect_pass)
79*223750d9SAndy Fiddaman {
80*223750d9SAndy Fiddaman 	runtestx(nstr, minval, maxval, -1, expval, expect_pass);
81*223750d9SAndy Fiddaman 	runtestx(nstr, minval, maxval, 10, expval, expect_pass);
82*223750d9SAndy Fiddaman 	runtestx(nstr, minval, maxval,  0, expval, expect_pass);
83*223750d9SAndy Fiddaman }
84*223750d9SAndy Fiddaman 
85*223750d9SAndy Fiddaman int
main(void)86*223750d9SAndy Fiddaman main(void)
87*223750d9SAndy Fiddaman {
88*223750d9SAndy Fiddaman 	runtest("1", 0, 100, 1, true);
89*223750d9SAndy Fiddaman 	runtest("0", -3, 7, 0, true);
90*223750d9SAndy Fiddaman 	runtest("0", 2, 10, 0, false);
91*223750d9SAndy Fiddaman 	runtest("0", 2, LLONG_MAX, 0, false);
92*223750d9SAndy Fiddaman 	runtest("-2", 0, LLONG_MAX, 0, false);
93*223750d9SAndy Fiddaman 	runtest("0", -5, LLONG_MAX, 0, true);
94*223750d9SAndy Fiddaman 	runtest("-3", -3, LLONG_MAX, -3, true);
95*223750d9SAndy Fiddaman 	runtest("-2", 10, -1, 0, false);
96*223750d9SAndy Fiddaman 	runtest("-2", -10, -1, -2, true);
97*223750d9SAndy Fiddaman 	runtest("-20", -10, -1, 0, false);
98*223750d9SAndy Fiddaman 	runtest("20", -10, -1, 0, false);
99*223750d9SAndy Fiddaman 
100*223750d9SAndy Fiddaman 	runtest("-9223372036854775808", LLONG_MIN, LLONG_MAX, LLONG_MIN, true);
101*223750d9SAndy Fiddaman 	runtest("-9223372036854775809", LLONG_MIN, LLONG_MAX, 0, false);
102*223750d9SAndy Fiddaman 
103*223750d9SAndy Fiddaman 	runtest("9223372036854775807", LLONG_MIN, LLONG_MAX, LLONG_MAX, true);
104*223750d9SAndy Fiddaman 	runtest("9223372036854775808", LLONG_MIN, LLONG_MAX, 0, false);
105*223750d9SAndy Fiddaman 
106*223750d9SAndy Fiddaman 	for (int base = 2; base <= 36; base++)
107*223750d9SAndy Fiddaman 		runtestx("1", 0, 100, base, 1, true);
108*223750d9SAndy Fiddaman 
109*223750d9SAndy Fiddaman 	runtestx("1", 0, 100, -2, 0, false);
110*223750d9SAndy Fiddaman 	runtestx("1", 0, 100, 1, 0, false);
111*223750d9SAndy Fiddaman 	runtestx("1", 0, 100, 37, 0, false);
112*223750d9SAndy Fiddaman 
113*223750d9SAndy Fiddaman 	runtestx("0x1234", 0, LLONG_MAX, 16, 0x1234, true);
114*223750d9SAndy Fiddaman 	runtestx("0x1234", 0, LLONG_MAX, 0, 0x1234, true);
115*223750d9SAndy Fiddaman 	runtestx("0x1234", 0, LLONG_MAX, 10, 0, false);
116*223750d9SAndy Fiddaman 
117*223750d9SAndy Fiddaman 	runtestx("AZbc123", 0, LLONG_MAX, 36, 23903176539, true);
118*223750d9SAndy Fiddaman 	runtestx("AZbc123", 0, LLONG_MAX, 35, 0, false);
119*223750d9SAndy Fiddaman 	runtestx("AYBC123", 0, LLONG_MAX, 35, 20185422673, true);
120*223750d9SAndy Fiddaman 	runtestx("AYBC123", 0, LLONG_MAX, 34, 0, false);
121*223750d9SAndy Fiddaman 
122*223750d9SAndy Fiddaman 	runtestx("01234", 0, LLONG_MAX, 8, 01234, true);
123*223750d9SAndy Fiddaman 	runtestx("01234", 0, LLONG_MAX, 0, 01234, true);
124*223750d9SAndy Fiddaman 	runtestx("01234", 0, LLONG_MAX, 10, 1234, true);
125*223750d9SAndy Fiddaman 
126*223750d9SAndy Fiddaman 	if (fail) {
127*223750d9SAndy Fiddaman 		printf("\nOverall status: FAIL\n");
128*223750d9SAndy Fiddaman 		return (EXIT_FAILURE);
129*223750d9SAndy Fiddaman 	}
130*223750d9SAndy Fiddaman 
131*223750d9SAndy Fiddaman 	printf("\nOverall status: PASS\n");
132*223750d9SAndy Fiddaman 	return (EXIT_SUCCESS);
133*223750d9SAndy Fiddaman }
134