1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1999-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                                                                      *
19 ***********************************************************************/
20 #pragma prototyped
21 
22 /*
23  * AT&T Research
24  *
25  * test harness for
26  *
27  *	strtol		strtoul		strton
28  *	strtoll		strtoull	strtonll
29  *	strntol		strntoul	strnton
30  *	strntoll	strntoull	strntonll
31  */
32 
33 #if _PACKAGE_ast
34 #include <ast.h>
35 #else
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #endif
40 
41 #include <stdio.h>
42 #include <errno.h>
43 #include <locale.h>
44 
45 #ifndef ERANGE
46 #define ERANGE	EINVAL
47 #endif
48 
49 #ifndef errno
50 extern int	errno;
51 #endif
52 
53 #if !_PACKAGE_ast
54 
55 static int
base(const char * s)56 base(const char* s)
57 {
58 	const char*	t;
59 	int		n;
60 
61 	for (t = s; *t == '-' || *t == '+' || *t == ' ' || *t == '\t'; t++);
62 	if (!*t)
63 		return 10;
64 	if (*t == '0')
65 		return (*++t == 'x' || *t == 'X') ? (*(t + 1) ? 16 : 10) : *t ? 8 : 0;
66 	n = 0;
67 	while (*t >= '0' && *t <= '9')
68 		n = n * 10 + *t++ - '0';
69 	return *t == '#' ? (*(t + 1) ? n : 10) : 0;
70 }
71 
72 static long
strton(const char * s,char ** e,char * b,int m)73 strton(const char* s, char** e, char* b, int m)
74 {
75 	int		o;
76 
77 	o = *b;
78 	*b = base(s);
79 	return strtol(s, e, o);
80 }
81 
82 static intmax_t
strtonll(const char * s,char ** e,char * b,int m)83 strtonll(const char* s, char** e, char* b, int m)
84 {
85 	int		o;
86 
87 	o = *b;
88 	*b = base(s);
89 	return strtoll(s, e, o);
90 }
91 
92 #endif
93 
94 int
main(int argc,char ** argv)95 main(int argc, char** argv)
96 {
97 	char*			s;
98 	char*			p;
99 	unsigned long		l;
100 	uintmax_t		ll;
101 	char			b;
102 	int			m;
103 	int			decimal;
104 	int			sep = 0;
105 #if _PACKAGE_ast
106 	int			n;
107 #endif
108 
109 	if (argc <= 1)
110 	{
111 		printf("%u/%u\n", sizeof(l) * 8, sizeof(ll) * 8);
112 		return 0;
113 	}
114 	decimal = *localeconv()->decimal_point;
115 	while (s = *++argv)
116 	{
117 		if (!strncmp(s, "LC_ALL=", 7))
118 		{
119 #if _PACKAGE_ast
120 			p = s + 7;
121 #else
122 			p = "de_DE";
123 #endif
124 			if (!setlocale(LC_ALL, p))
125 			{
126 				printf("%s failed\n", s);
127 				return 0;
128 			}
129 			decimal = *localeconv()->decimal_point;
130 			continue;
131 		}
132 		if (sep)
133 			printf("\n");
134 		else
135 			sep = 1;
136 		m = strchr(s, decimal) ? 100 : 0;
137 
138 		errno = 0;
139 		l = strtol(s, &p, 0);
140 		printf("strtol    \"%s\" \"%s\" %ld %s\n", s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
141 
142 		errno = 0;
143 		b = 0;
144 		l = strton(s, &p, &b, m);
145 		printf("strton    \"%s\" \"%s\" %ld %s %d\n", s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR", b);
146 
147 		errno = 0;
148 		l = strtoul(s, &p, 0);
149 		printf("strtoul   \"%s\" \"%s\" %lu %s\n", s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
150 
151 		errno = 0;
152 		ll = strtoll(s, &p, 0);
153 		printf("strtoll   \"%s\" \"%s\" %lld %s\n", s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
154 
155 		errno = 0;
156 		b = 0;
157 		ll = strtonll(s, &p, &b, m);
158 		printf("strtonll  \"%s\" \"%s\" %lld %s %d\n", s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR", b);
159 
160 		errno = 0;
161 		ll = strtoull(s, &p, 0);
162 		printf("strtoull  \"%s\" \"%s\" %llu %s\n", s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
163 
164 #if _PACKAGE_ast
165 		n = strlen(s);
166 
167 		errno = 0;
168 		l = strntol(s, n, &p, 0);
169 		printf("strntol    %2d \"%s\" \"%s\" %ld %s\n", n, s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
170 
171 		errno = 0;
172 		l = strntol(s, n - 1, &p, 0);
173 		printf("strntol    %2d \"%s\" \"%s\" %ld %s\n", n - 1, s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
174 
175 		errno = 0;
176 		b = 0;
177 		l = strnton(s, n, &p, &b, m);
178 		printf("strnton    %2d \"%s\" \"%s\" %ld %s %d\n", n, s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR", b);
179 
180 		errno = 0;
181 		b = 0;
182 		l = strnton(s, n - 1, &p, &b, m);
183 		printf("strnton    %2d \"%s\" \"%s\" %ld %s %d\n", n - 1, s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR", b);
184 
185 		errno = 0;
186 		l = strntoul(s, n, &p, 0);
187 		printf("strntoul   %2d \"%s\" \"%s\" %lu %s\n", n, s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
188 
189 		errno = 0;
190 		l = strntoul(s, n - 1, &p, 0);
191 		printf("strntoul   %2d \"%s\" \"%s\" %lu %s\n", n - 1, s, p, l, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
192 
193 		errno = 0;
194 		ll = strntoll(s, n, &p, 0);
195 		printf("strntoll   %2d \"%s\" \"%s\" %lld %s\n", n, s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
196 
197 		errno = 0;
198 		ll = strntoll(s, n - 1, &p, 0);
199 		printf("strntoll   %2d \"%s\" \"%s\" %lld %s\n", n - 1, s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
200 
201 		errno = 0;
202 		b = 0;
203 		ll = strntonll(s, n, &p, &b, m);
204 		printf("strntonll %2d \"%s\" \"%s\" %lld %s %d\n", n, s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR", b);
205 
206 		errno = 0;
207 		b = 0;
208 		ll = strntonll(s, n - 1, &p, &b, m);
209 		printf("strntonll %2d \"%s\" \"%s\" %lld %s %d\n", n - 1, s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR", b);
210 
211 		errno = 0;
212 		ll = strntoull(s, n, &p, 0);
213 		printf("strntoull %2d \"%s\" \"%s\" %llu %s\n", n, s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
214 
215 		errno = 0;
216 		ll = strntoull(s, n - 1, &p, 0);
217 		printf("strntoull %2d \"%s\" \"%s\" %llu %s\n", n - 1, s, p, ll, errno == 0 ? "OK" : errno == ERANGE ? "ERANGE" : errno == EINVAL ? "EINVAL" : "ERROR");
218 #endif
219 	}
220 	return 0;
221 }
222