1/* Test program for strtol family of funtions,
2   Copyright (C) 2014 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
58enum conversion_fun
59{
60  STRTOL,
61  STRTOLL,
62  STRTOUL,
63  STRTOULL,
64};
65
66#ifdef HAVE_LONG_LONG
67typedef unsigned long long integer_type;
68#else
69typedef unsigned long integer_type;
70#endif
71
72struct 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
81const 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
119int
120run_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
178int
179main(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