1 /* Test program for strtol family of funtions,
2    Copyright (C) 2014-2018 Free Software Foundation, Inc.
3    Written by Yury Gribov <y.gribov@samsung.com>
4 
5    This file is part of the libiberty library, which is part of GCC.
6 
7    This file is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    In addition to the permissions in the GNU General Public License, the
13    Free Software Foundation gives you unlimited permission to link the
14    compiled version of this file into combinations with other programs,
15    and to distribute those combinations without any restriction coming
16    from the use of this file.  (The General Public License restrictions
17    do apply in other respects; for example, they cover modification of
18    the file, and distribution when not linked into a combined
19    executable.)
20 
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25 
26    You should have received a copy of the GNU General Public License
27    along with this program; if not, write to the Free Software
28    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
29 */
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 #include "libiberty.h"
35 #include <stdio.h>
36 #include <errno.h>
37 #ifdef HAVE_STDLIB_H
38 #include <stdlib.h>
39 #endif
40 #ifdef HAVE_STRING_H
41 #include <string.h>
42 #endif
43 #ifdef HAVE_UNISTD_H
44 #include <unistd.h>
45 #endif
46 
47 #ifndef EXIT_SUCCESS
48 #define EXIT_SUCCESS 0
49 #endif
50 
51 #ifndef EXIT_FAILURE
52 #define EXIT_FAILURE 1
53 #endif
54 
55 
56 /* Test input data. */
57 
58 enum conversion_fun
59 {
60   STRTOL,
61   STRTOLL,
62   STRTOUL,
63   STRTOULL,
64 };
65 
66 #ifdef HAVE_LONG_LONG
67 typedef unsigned long long integer_type;
68 #else
69 typedef unsigned long integer_type;
70 #endif
71 
72 struct test_data_t
73 {
74   enum conversion_fun fun;
75   const char *nptr;
76   int base;
77   integer_type res;
78   int errnum;
79 };
80 
81 const struct test_data_t test_data[] = {
82   { STRTOL,  "0x123",       0, 0x123L,        0      },
83   { STRTOL,  "123",         0, 123L,          0      },
84   { STRTOL,  "0123",        0, 0123L,         0      },
85   { STRTOL,  "0x7FFFFFFF",  0, 0x7fffffffL,   0      },
86   { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
87   { STRTOUL, "0x123",       0, 0x123UL,       0      },
88   { STRTOUL, "123",         0, 123UL,         0      },
89   { STRTOUL, "0123",        0, 0123UL,        0      },
90   { STRTOUL, "0xFFFFFFFF",  0, 0xffffffffUL,  0      },
91 #if SIZEOF_LONG == 4
92   { STRTOL,  "0x80000000",  0, 0x7fffffffL,   ERANGE },
93   { STRTOL,  "-0x80000001", 0, -0x80000000L,  ERANGE },
94   { STRTOUL, "0x100000000", 0, 0xffffffffUL,  ERANGE },
95 #endif
96 #ifdef HAVE_LONG_LONG
97   { STRTOLL,  "0x123",               0, 0x123LL,               0      },
98   { STRTOLL,  "123",                 0, 123LL,                 0      },
99   { STRTOLL,  "0123",                0, 0123LL,                0      },
100   { STRTOLL,  "0x7FFFFFFFFFFFFFFF",  0, 0x7fffffffffffffffLL,  0      },
101   { STRTOLL,  "-0x8000000000000000", 0, -0x8000000000000000LL, 0      },
102   { STRTOULL, "0x123",               0, 0x123ULL,              0      },
103   { STRTOULL, "123",                 0, 123ULL,                0      },
104   { STRTOULL, "0123",                0, 0123ULL,               0      },
105   { STRTOULL, "0xFFFFFFFFFFFFFFFF",  0, 0xffffffffffffffffULL, 0      },
106 #if SIZEOF_LONG_LONG == 8
107   { STRTOLL,  "0x8000000000000000",  0, 0x7fffffffffffffffLL,  ERANGE },
108   { STRTOLL,  "-0x8000000000000001", 0, -0x8000000000000000LL, ERANGE },
109   { STRTOULL, "0x10000000000000000", 0, 0xffffffffffffffffULL, ERANGE },
110 #endif
111 #endif
112 };
113 
114 /* run_tests:
115     Run conversion function
116     Compare results
117     Return number of fails */
118 
119 int
run_tests(const struct test_data_t * test_data,size_t ntests)120 run_tests (const struct test_data_t *test_data, size_t ntests)
121 {
122   int fails = 0, failed;
123   size_t i;
124 
125   for (i = 0; i < ntests; ++i)
126     {
127       integer_type res;
128       int saved_errno;
129 
130       errno = 0;
131 
132       switch (test_data[i].fun)
133 	{
134 	case STRTOL:
135 	  res = (unsigned long) strtol (test_data[i].nptr,
136 					0, test_data[i].base);
137 	  break;
138 	case STRTOUL:
139 	  res = strtoul (test_data[i].nptr, 0, test_data[i].base);
140 	  break;
141 #ifdef HAVE_LONG_LONG
142 	case STRTOLL:
143 	  res = strtoll (test_data[i].nptr, 0, test_data[i].base);
144 	  break;
145 	case STRTOULL:
146 	  res = strtoull (test_data[i].nptr, 0, test_data[i].base);
147 	  break;
148 #endif
149 	}
150 
151       saved_errno = errno;
152 
153       failed = 0;
154 
155       /* Compare result */
156       if (res != test_data[i].res)
157         {
158           printf ("FAIL: test-strtol-%zd. Results don't match.\n", i);
159 	  failed++;
160         }
161 
162       /* Compare errno */
163       if (saved_errno != test_data[i].errnum)
164         {
165           printf ("FAIL: test-strtol-%zd. Errnos don't match.\n", i);
166 	  failed++;
167         }
168 
169       if (!failed)
170         printf ("PASS: test-strtol-%zd.\n", i);
171       else
172         fails++;
173     }
174 
175   return fails;
176 }
177 
178 int
main(int argc,char ** argv)179 main(int argc, char **argv)
180 {
181   int fails;
182   fails = run_tests (test_data, sizeof (test_data) / sizeof (test_data[0]));
183   exit (fails ? EXIT_FAILURE : EXIT_SUCCESS);
184 }
185 
186