| /* Test program for strtol family of funtions, |
| Copyright (C) 2014-2021 Free Software Foundation, Inc. |
| Written by Yury Gribov <y.gribov@samsung.com> |
| |
| This file is part of the libiberty library, which is part of GCC. |
| |
| This file is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| In addition to the permissions in the GNU General Public License, the |
| Free Software Foundation gives you unlimited permission to link the |
| compiled version of this file into combinations with other programs, |
| and to distribute those combinations without any restriction coming |
| from the use of this file. (The General Public License restrictions |
| do apply in other respects; for example, they cover modification of |
| the file, and distribution when not linked into a combined |
| executable.) |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| #include "libiberty.h" |
| #include <stdio.h> |
| #include <errno.h> |
| #ifdef HAVE_STDLIB_H |
| #include <stdlib.h> |
| #endif |
| #ifdef HAVE_STRING_H |
| #include <string.h> |
| #endif |
| #ifdef HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| |
| #ifndef EXIT_SUCCESS |
| #define EXIT_SUCCESS 0 |
| #endif |
| |
| #ifndef EXIT_FAILURE |
| #define EXIT_FAILURE 1 |
| #endif |
| |
| |
| /* Test input data. */ |
| |
| enum conversion_fun |
| { |
| STRTOL, |
| STRTOLL, |
| STRTOUL, |
| STRTOULL, |
| }; |
| |
| #ifdef HAVE_LONG_LONG |
| typedef unsigned long long integer_type; |
| #else |
| typedef unsigned long integer_type; |
| #endif |
| |
| struct test_data_t |
| { |
| enum conversion_fun fun; |
| const char *nptr; |
| int base; |
| integer_type res; |
| int errnum; |
| }; |
| |
| const struct test_data_t test_data[] = { |
| { STRTOL, "0x123", 0, 0x123L, 0 }, |
| { STRTOL, "123", 0, 123L, 0 }, |
| { STRTOL, "0123", 0, 0123L, 0 }, |
| { STRTOL, "0x7FFFFFFF", 0, 0x7fffffffL, 0 }, |
| { STRTOL, "-0x80000000", 0, -0x80000000L, 0 }, |
| { STRTOUL, "0x123", 0, 0x123UL, 0 }, |
| { STRTOUL, "123", 0, 123UL, 0 }, |
| { STRTOUL, "0123", 0, 0123UL, 0 }, |
| { STRTOUL, "0xFFFFFFFF", 0, 0xffffffffUL, 0 }, |
| #if SIZEOF_LONG == 4 |
| { STRTOL, "0x80000000", 0, 0x7fffffffL, ERANGE }, |
| { STRTOL, "-0x80000001", 0, -0x80000000L, ERANGE }, |
| { STRTOUL, "0x100000000", 0, 0xffffffffUL, ERANGE }, |
| #endif |
| #ifdef HAVE_LONG_LONG |
| { STRTOLL, "0x123", 0, 0x123LL, 0 }, |
| { STRTOLL, "123", 0, 123LL, 0 }, |
| { STRTOLL, "0123", 0, 0123LL, 0 }, |
| { STRTOLL, "0x7FFFFFFFFFFFFFFF", 0, 0x7fffffffffffffffLL, 0 }, |
| { STRTOLL, "-0x8000000000000000", 0, -0x8000000000000000LL, 0 }, |
| { STRTOULL, "0x123", 0, 0x123ULL, 0 }, |
| { STRTOULL, "123", 0, 123ULL, 0 }, |
| { STRTOULL, "0123", 0, 0123ULL, 0 }, |
| { STRTOULL, "0xFFFFFFFFFFFFFFFF", 0, 0xffffffffffffffffULL, 0 }, |
| #if SIZEOF_LONG_LONG == 8 |
| { STRTOLL, "0x8000000000000000", 0, 0x7fffffffffffffffLL, ERANGE }, |
| { STRTOLL, "-0x8000000000000001", 0, -0x8000000000000000LL, ERANGE }, |
| { STRTOULL, "0x10000000000000000", 0, 0xffffffffffffffffULL, ERANGE }, |
| #endif |
| #endif |
| }; |
| |
| /* run_tests: |
| Run conversion function |
| Compare results |
| Return number of fails */ |
| |
| int |
| run_tests (const struct test_data_t *test_data, size_t ntests) |
| { |
| int fails = 0, failed; |
| size_t i; |
| |
| for (i = 0; i < ntests; ++i) |
| { |
| integer_type res; |
| int saved_errno; |
| |
| errno = 0; |
| |
| switch (test_data[i].fun) |
| { |
| case STRTOL: |
| res = (unsigned long) strtol (test_data[i].nptr, |
| 0, test_data[i].base); |
| break; |
| case STRTOUL: |
| res = strtoul (test_data[i].nptr, 0, test_data[i].base); |
| break; |
| #ifdef HAVE_LONG_LONG |
| case STRTOLL: |
| res = strtoll (test_data[i].nptr, 0, test_data[i].base); |
| break; |
| case STRTOULL: |
| res = strtoull (test_data[i].nptr, 0, test_data[i].base); |
| break; |
| #endif |
| } |
| |
| saved_errno = errno; |
| |
| failed = 0; |
| |
| /* Compare result */ |
| if (res != test_data[i].res) |
| { |
| printf ("FAIL: test-strtol-%zd. Results don't match.\n", i); |
| failed++; |
| } |
| |
| /* Compare errno */ |
| if (saved_errno != test_data[i].errnum) |
| { |
| printf ("FAIL: test-strtol-%zd. Errnos don't match.\n", i); |
| failed++; |
| } |
| |
| if (!failed) |
| printf ("PASS: test-strtol-%zd.\n", i); |
| else |
| fails++; |
| } |
| |
| return fails; |
| } |
| |
| int |
| main(int argc, char **argv) |
| { |
| int fails; |
| fails = run_tests (test_data, sizeof (test_data) / sizeof (test_data[0])); |
| exit (fails ? EXIT_FAILURE : EXIT_SUCCESS); |
| } |
| |