xref: /netbsd-src/tests/lib/libc/stdlib/t_strtoi.c (revision 5ed3745558946d55fda3f071139ba4ab25c67c4e)
1*5ed37455Skre /*	$NetBSD: t_strtoi.c,v 1.5 2024/07/24 09:26:06 kre Exp $	*/
235d355f3Schristos 
335d355f3Schristos /*-
435d355f3Schristos  * Copyright (c) 2015 The NetBSD Foundation, Inc.
535d355f3Schristos  * All rights reserved.
635d355f3Schristos  *
735d355f3Schristos  * This code is derived from software contributed to The NetBSD Foundation
835d355f3Schristos  * by Jukka Ruohonen.
935d355f3Schristos  *
1035d355f3Schristos  * Redistribution and use in source and binary forms, with or without
1135d355f3Schristos  * modification, are permitted provided that the following conditions
1235d355f3Schristos  * are met:
1335d355f3Schristos  * 1. Redistributions of source code must retain the above copyright
1435d355f3Schristos  *    notice, this list of conditions and the following disclaimer.
1535d355f3Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1635d355f3Schristos  *    notice, this list of conditions and the following disclaimer in the
1735d355f3Schristos  *    documentation and/or other materials provided with the distribution.
1835d355f3Schristos  *
1935d355f3Schristos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2035d355f3Schristos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2135d355f3Schristos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2235d355f3Schristos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2335d355f3Schristos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2435d355f3Schristos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2535d355f3Schristos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2635d355f3Schristos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2735d355f3Schristos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2835d355f3Schristos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2935d355f3Schristos  * POSSIBILITY OF SUCH DAMAGE.
3035d355f3Schristos  */
3135d355f3Schristos 
3235d355f3Schristos /*
33a9391cc9Skamil  * Created by Kamil Rytarowski, based on ID:
3435d355f3Schristos  * NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp
3535d355f3Schristos  */
3635d355f3Schristos 
3735d355f3Schristos #include <sys/cdefs.h>
38*5ed37455Skre __RCSID("$NetBSD: t_strtoi.c,v 1.5 2024/07/24 09:26:06 kre Exp $");
3935d355f3Schristos 
4035d355f3Schristos #include <atf-c.h>
4135d355f3Schristos #include <errno.h>
4235d355f3Schristos #include <inttypes.h>
4335d355f3Schristos #include <stdlib.h>
4435d355f3Schristos #include <string.h>
4535d355f3Schristos #include <limits.h>
4635d355f3Schristos 
4735d355f3Schristos struct test {
4835d355f3Schristos 	const char	*str;
4935d355f3Schristos 	intmax_t	 res;
5035d355f3Schristos 	int		 base;
5135d355f3Schristos 	const char	*end;
5235d355f3Schristos 	intmax_t	 lo;
5335d355f3Schristos 	intmax_t	 hi;
5435d355f3Schristos 	int		 rstatus;
5535d355f3Schristos };
5635d355f3Schristos 
5735d355f3Schristos static void	check(struct test *, intmax_t, char *, int);
5835d355f3Schristos 
5935d355f3Schristos static void
6035d355f3Schristos check(struct test *t, intmax_t rv, char *end, int rstatus)
6135d355f3Schristos {
6235d355f3Schristos 
6335d355f3Schristos 	if (rv != t->res)
64c9ca1aa8Skre 		atf_tc_fail_nonfatal("strtoi(\"%s\", &end, %d, %jd, %jd, "
65c9ca1aa8Skre 		    "&rstatus) failed (rv = %jd)", t->str, t->base,
66c9ca1aa8Skre 		    t->lo, t->hi, rv);
6735d355f3Schristos 
68c9ca1aa8Skre 	if (rstatus != t->rstatus) {
69c9ca1aa8Skre 		char *emsg;
70c9ca1aa8Skre 
71c9ca1aa8Skre 		if (rstatus != 0) {
72c9ca1aa8Skre 			emsg = strerror(rstatus);
73c9ca1aa8Skre 			if (emsg != NULL) {
74c9ca1aa8Skre 				emsg = strdup(emsg);
75c9ca1aa8Skre 				if (emsg == NULL) {
76c9ca1aa8Skre 					atf_tc_fail("Out of Memory");
77c9ca1aa8Skre 					return;
78c9ca1aa8Skre 				}
79c9ca1aa8Skre 			}
80c9ca1aa8Skre 		} else
81c9ca1aa8Skre 			emsg = NULL;
82c9ca1aa8Skre 
83c9ca1aa8Skre 		atf_tc_fail_nonfatal("strtoi(\"%s\", &end, %d, %jd, %jd, &rstatus)"
84c9ca1aa8Skre 		    " failed (rstatus: %d %s%s%sexpected %d%s%s%s)",
85c9ca1aa8Skre 		    t->str, t->base, t->lo, t->hi, rstatus, rstatus ? "('" : "",
86c9ca1aa8Skre 		    emsg != NULL ? emsg : "", rstatus ? "') " : "", t->rstatus,
87c9ca1aa8Skre 		    t->rstatus ? " ('" : "", t->rstatus ? strerror(t->rstatus)
88c9ca1aa8Skre 		    : "", t->rstatus ? "')" : "");
89c9ca1aa8Skre 
90c9ca1aa8Skre 		free(emsg);
91c9ca1aa8Skre 	}
9235d355f3Schristos 
9335d355f3Schristos 	if ((t->end != NULL && strcmp(t->end, end) != 0) ||
9435d355f3Schristos 	    (t->end == NULL && *end != '\0'))
9535d355f3Schristos 		atf_tc_fail_nonfatal("invalid end pointer ('%s') from "
96c9ca1aa8Skre 		    "strtoi(\"%s\", &end, %d, %jd, %jd, &rstatus), "
97c9ca1aa8Skre 		    "expected '%s'", end, t->str, t->base, t->lo, t->hi,
98c9ca1aa8Skre 		     t->end != NULL ? t->end : "\\0");
99c9ca1aa8Skre }
100c9ca1aa8Skre 
101c9ca1aa8Skre static void
102c9ca1aa8Skre check_errno(int e)
103c9ca1aa8Skre {
104c9ca1aa8Skre 	if (e != 0)
105c9ca1aa8Skre 		atf_tc_fail("strtoi(3) changed errno to %d ('%s')",
106c9ca1aa8Skre 			            e, strerror(e));
10735d355f3Schristos }
10835d355f3Schristos 
10935d355f3Schristos ATF_TC(strtoi_base);
11035d355f3Schristos ATF_TC_HEAD(strtoi_base, tc)
11135d355f3Schristos {
11235d355f3Schristos 	atf_tc_set_md_var(tc, "descr", "Test strtoi(3) with different bases");
11335d355f3Schristos }
11435d355f3Schristos 
11535d355f3Schristos ATF_TC_BODY(strtoi_base, tc)
11635d355f3Schristos {
11735d355f3Schristos 	struct test t[] = {
11835d355f3Schristos 		{ "123456789",                  123456789,	0,	NULL,
11935d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
12035d355f3Schristos 		{ "111010110111100110100010101",123456789,	2,	NULL,
12135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
12235d355f3Schristos 		{ "22121022020212200",          123456789,	3,	NULL,
12335d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
12435d355f3Schristos 		{ "13112330310111",	        123456789,	4,	NULL,
12535d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
12635d355f3Schristos 		{ "223101104124",               123456789,	5,	NULL,
12735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
12835d355f3Schristos 		{ "20130035113",                123456789,	6,	NULL,
12935d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
13035d355f3Schristos 		{ "3026236221",	                123456789,	7,	NULL,
13135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
13235d355f3Schristos 		{ "726746425",                  123456789,	8,	NULL,
13335d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
13435d355f3Schristos 		{ "277266780",                  123456789,	9,	NULL,
13535d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
13635d355f3Schristos 		{ "123456789",                  123456789,	10,	NULL,
13735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
13835d355f3Schristos 		{ "63762A05",                   123456789,	11,	NULL,
13935d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
14035d355f3Schristos 		{ "35418A99",                   123456789,	12,	NULL,
14135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
14235d355f3Schristos 		{ "1C767471",                   123456789,	13,	NULL,
14335d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
14435d355f3Schristos 		{ "12579781",                   123456789,	14,	NULL,
14535d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
14635d355f3Schristos 		{ "AC89BC9",                    123456789,	15,	NULL,
14735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
14835d355f3Schristos 		{ "75BCD15",                    123456789,	16,	NULL,
14935d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
15035d355f3Schristos 		{ "1234567",                       342391,	8,	NULL,
15135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
15235d355f3Schristos 		{ "01234567",                      342391,	0,	NULL,
15335d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
15435d355f3Schristos 		{ "0123456789",                 123456789,	10,	NULL,
15535d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
15635d355f3Schristos 		{ "0x75bcd15",                  123456789,	0,	NULL,
15735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
15835d355f3Schristos 	};
159c9ca1aa8Skre 	struct test f[] = {
160c9ca1aa8Skre 		{ "1",                                  0,	1,	"1",
161c9ca1aa8Skre 		  INTMAX_MIN,	INTMAX_MAX,	EINVAL	},
162c9ca1aa8Skre 		{ "2",                                  0,	-1,	"2",
163c9ca1aa8Skre 		  INTMAX_MIN,	INTMAX_MAX,	EINVAL	},
164c9ca1aa8Skre 		{ "3",                                  0,	37,	"3",
165c9ca1aa8Skre 		  INTMAX_MIN,	INTMAX_MAX,	EINVAL	},
166c9ca1aa8Skre 		{ "4",                                  0,	-1,	"4",
167c9ca1aa8Skre 		  INTMAX_MIN,	INTMAX_MAX,	EINVAL	},
168c9ca1aa8Skre 		{ "0x",                                  0,	 0,	"x",
169c9ca1aa8Skre 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP	},
170c9ca1aa8Skre 	};
17135d355f3Schristos 
17235d355f3Schristos 	intmax_t rv;
17335d355f3Schristos 	char *end;
17435d355f3Schristos 	int e;
17535d355f3Schristos 	size_t i;
17635d355f3Schristos 
17735d355f3Schristos 	for (i = 0; i < __arraycount(t); i++) {
17835d355f3Schristos 
17935d355f3Schristos 		errno = 0;
18035d355f3Schristos 		rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e);
18135d355f3Schristos 
182c9ca1aa8Skre 		check_errno(errno);
18335d355f3Schristos 
18435d355f3Schristos 		check(&t[i], rv, end, e);
18535d355f3Schristos 	}
186c9ca1aa8Skre 
187c9ca1aa8Skre 	for (i = 0; i < __arraycount(f); i++) {
188c9ca1aa8Skre 
189c9ca1aa8Skre 		end = NULL;
190c9ca1aa8Skre 		errno = 0;
191c9ca1aa8Skre 		e = -99;
192c9ca1aa8Skre 
193c9ca1aa8Skre 		rv = strtoi(f[i].str, &end, f[i].base, f[i].lo, f[i].hi, &e);
194c9ca1aa8Skre 
195c9ca1aa8Skre 		check_errno(errno);
196c9ca1aa8Skre 
197c9ca1aa8Skre 		check(&f[i], rv, end, e);
198c9ca1aa8Skre 	}
19935d355f3Schristos }
20035d355f3Schristos 
20135d355f3Schristos ATF_TC(strtoi_case);
20235d355f3Schristos ATF_TC_HEAD(strtoi_case, tc)
20335d355f3Schristos {
20435d355f3Schristos 	atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtoi(3)");
20535d355f3Schristos }
20635d355f3Schristos 
20735d355f3Schristos ATF_TC_BODY(strtoi_case, tc)
20835d355f3Schristos {
20935d355f3Schristos 	struct test t[] = {
21035d355f3Schristos 		{ "abcd",	0xabcd,	16,	NULL,
21135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
21235d355f3Schristos 		{ "     dcba",	0xdcba,	16,	NULL,
21335d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
21435d355f3Schristos 		{ "abcd dcba",	0xabcd,	16,	" dcba",
21535d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP	},
21635d355f3Schristos 		{ "abc0x123",	0xabc0, 16,	"x123",
21735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP	},
21835d355f3Schristos 		{ "abcd\0x123",	0xabcd, 16,	"\0x123",
21935d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
22035d355f3Schristos 		{ "ABCD",	0xabcd, 16,	NULL,
22135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
22235d355f3Schristos 		{ "aBcD",	0xabcd, 16,	NULL,
22335d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
22435d355f3Schristos 		{ "0xABCD",	0xabcd, 16,	NULL,
22535d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0	},
22635d355f3Schristos 		{ "0xABCDX",	0xabcd, 16,	"X",
22735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP},
22835d355f3Schristos 	};
22935d355f3Schristos 
23035d355f3Schristos 	intmax_t rv;
23135d355f3Schristos 	char *end;
23235d355f3Schristos 	int e;
23335d355f3Schristos 	size_t i;
23435d355f3Schristos 
23535d355f3Schristos 	for (i = 0; i < __arraycount(t); i++) {
23635d355f3Schristos 
23735d355f3Schristos 		errno = 0;
23835d355f3Schristos 		rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e);
23935d355f3Schristos 
240c9ca1aa8Skre 		check_errno(errno);
24135d355f3Schristos 
24235d355f3Schristos 		check(&t[i], rv, end, e);
24335d355f3Schristos 	}
24435d355f3Schristos }
24535d355f3Schristos 
24635d355f3Schristos ATF_TC(strtoi_range);
24735d355f3Schristos ATF_TC_HEAD(strtoi_range, tc)
24835d355f3Schristos {
24935d355f3Schristos 	atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtoi(3)");
25035d355f3Schristos }
25135d355f3Schristos 
25235d355f3Schristos ATF_TC_BODY(strtoi_range, tc)
25335d355f3Schristos {
25435d355f3Schristos 	struct test t[] = {
25535d355f3Schristos #if INTMAX_MAX == 0x7fffffffffffffff
25635d355f3Schristos 		{ "1000000000000000000000", INTMAX_MAX, 8, NULL,
25735d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ERANGE },
25835d355f3Schristos 		{ "9223372036854775808",    INTMAX_MAX, 10, NULL,
25935d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ERANGE },
26035d355f3Schristos 		{ "8000000000000000",       INTMAX_MAX, 16, NULL,
26135d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ERANGE },
26235d355f3Schristos #else
26335d355f3Schristos #error extend this test to your platform!
26435d355f3Schristos #endif
26535d355f3Schristos 		{ "10",		 1,	10,	NULL,
26635d355f3Schristos 		  -1,	 1,	ERANGE			},
26735d355f3Schristos 		{ "10",		11,	10,	NULL,
26835d355f3Schristos 		  11,	20,	ERANGE			},
269c9ca1aa8Skre 		{ "7",		 7,	0,	NULL,
270c9ca1aa8Skre 		   7,	 7,	0			},
271c9ca1aa8Skre 		{ "6",		 7,	0,	NULL,
272c9ca1aa8Skre 		   7,	 7,	ERANGE			},
273c9ca1aa8Skre 		{ "8",		 7,	0,	NULL,
274c9ca1aa8Skre 		   7,	 7,	ERANGE			},
275c9ca1aa8Skre 		{ "7x",		 7,	0,	"x",
276c9ca1aa8Skre 		   7,	 7,	ENOTSUP			},
277c9ca1aa8Skre 		{ "8x",		 7,	0,	"x",
278c9ca1aa8Skre 		   7,	 7,	ERANGE			},
279c9ca1aa8Skre 		{ "Z",		11,	10,	"Z",
280c9ca1aa8Skre 		  11,	20,	ECANCELED		},
28135d355f3Schristos 	};
28235d355f3Schristos 
28335d355f3Schristos 	intmax_t rv;
28435d355f3Schristos 	char *end;
28535d355f3Schristos 	int e;
28635d355f3Schristos 	size_t i;
28735d355f3Schristos 
28835d355f3Schristos 	for (i = 0; i < __arraycount(t); i++) {
28935d355f3Schristos 
29035d355f3Schristos 		errno = 0;
29135d355f3Schristos 		rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e);
29235d355f3Schristos 
29335d355f3Schristos 		if (errno != 0)
294c9ca1aa8Skre 			atf_tc_fail("Range test %zd set errno=%d", i, errno);
295c9ca1aa8Skre 		check_errno(errno);
29635d355f3Schristos 
29735d355f3Schristos 		check(&t[i], rv, end, e);
29835d355f3Schristos 	}
29935d355f3Schristos }
30035d355f3Schristos 
30116b546eeSchristos ATF_TC(strtoi_range_trail);
30216b546eeSchristos ATF_TC_HEAD(strtoi_range_trail, tc)
30316b546eeSchristos {
30416b546eeSchristos 	atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtoi(3) "
30516b546eeSchristos 		"with trailing characters");
30616b546eeSchristos }
30716b546eeSchristos 
30816b546eeSchristos ATF_TC_BODY(strtoi_range_trail, tc)
30916b546eeSchristos {
31016b546eeSchristos 	struct test t[] = {
31116b546eeSchristos 		{ "11x",    9, 10, "x",  0, 9, ERANGE },
31216b546eeSchristos 		{ " -3y",  -2, 10, "y", -2, 1, ERANGE },
313c9ca1aa8Skre 		{ "11111z", 9, 10, "z",  0, 9, ERANGE },
314c9ca1aa8Skre 		{ "+0xAq",  9, 16, "q",  0, 9, ERANGE },
315c9ca1aa8Skre 		{ "-0xBAr", 0, 16, "r",  0, 9, ERANGE },
31616b546eeSchristos 	};
31716b546eeSchristos 
31816b546eeSchristos 	intmax_t rv;
31916b546eeSchristos 	char *end;
32016b546eeSchristos 	int e;
32116b546eeSchristos 	size_t i;
32216b546eeSchristos 
32316b546eeSchristos 	for (i = 0; i < __arraycount(t); i++) {
32416b546eeSchristos 
32516b546eeSchristos 		errno = 0;
32616b546eeSchristos 		rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e);
32716b546eeSchristos 
328c9ca1aa8Skre 		check_errno(errno);
32916b546eeSchristos 
33016b546eeSchristos 		check(&t[i], rv, end, e);
33116b546eeSchristos 	}
33216b546eeSchristos }
33316b546eeSchristos 
33435d355f3Schristos ATF_TC(strtoi_signed);
33535d355f3Schristos ATF_TC_HEAD(strtoi_signed, tc)
33635d355f3Schristos {
33735d355f3Schristos 	atf_tc_set_md_var(tc, "descr", "A basic test of strtoi(3)");
33835d355f3Schristos }
33935d355f3Schristos 
34035d355f3Schristos ATF_TC_BODY(strtoi_signed, tc)
34135d355f3Schristos {
34235d355f3Schristos 	struct test t[] = {
34335d355f3Schristos 		{ "1",		 1, 0, NULL,
34435d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0 },
34535d355f3Schristos 		{ " 2",		 2, 0, NULL,
34635d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0 },
34735d355f3Schristos 		{ "  3",	 3, 0, NULL,
34835d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0 },
34935d355f3Schristos 		{ " -3",	-3, 0, NULL,
35035d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0 },
35135d355f3Schristos 		{ "--1",	 0, 0, "--1",
35235d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ECANCELED },
35335d355f3Schristos 		{ "+-2",	 0, 0, "+-2",
35435d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ECANCELED },
35535d355f3Schristos 		{ "++3",	 0, 0, "++3",
35635d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ECANCELED },
35735d355f3Schristos 		{ "+9",		 9, 0, NULL,
35835d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0 },
35935d355f3Schristos 		{ "+123",      123, 0, NULL,
36035d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	0 },
36135d355f3Schristos 		{ "-1 3",       -1, 0, " 3",
36235d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP },
36335d355f3Schristos 		{ "-1.3",       -1, 0, ".3",
36435d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP },
36535d355f3Schristos 		{ "-  3",        0, 0, "-  3",
36635d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ECANCELED },
36735d355f3Schristos 		{ "+33.",       33, 0, ".",
36835d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP },
36935d355f3Schristos 		{ "30x0",       30, 0, "x0",
37035d355f3Schristos 		  INTMAX_MIN,	INTMAX_MAX,	ENOTSUP },
37135d355f3Schristos 	};
37235d355f3Schristos 
37335d355f3Schristos 	intmax_t rv;
37435d355f3Schristos 	char *end;
37535d355f3Schristos 	int e;
37635d355f3Schristos 	size_t i;
37735d355f3Schristos 
37835d355f3Schristos 	for (i = 0; i < __arraycount(t); i++) {
37935d355f3Schristos 
38035d355f3Schristos 		errno = 0;
38135d355f3Schristos 		rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e);
38235d355f3Schristos 
383c9ca1aa8Skre 		check_errno(errno);
38435d355f3Schristos 
38535d355f3Schristos 		check(&t[i], rv, end, e);
38635d355f3Schristos 	}
38735d355f3Schristos }
38835d355f3Schristos 
38935d355f3Schristos ATF_TP_ADD_TCS(tp)
39035d355f3Schristos {
39135d355f3Schristos 
39235d355f3Schristos 	ATF_TP_ADD_TC(tp, strtoi_base);
39335d355f3Schristos 	ATF_TP_ADD_TC(tp, strtoi_case);
39435d355f3Schristos 	ATF_TP_ADD_TC(tp, strtoi_range);
39516b546eeSchristos 	ATF_TP_ADD_TC(tp, strtoi_range_trail);
39635d355f3Schristos 	ATF_TP_ADD_TC(tp, strtoi_signed);
39735d355f3Schristos 
39835d355f3Schristos 	return atf_no_error();
39935d355f3Schristos }
400