1*640235e2SEnji Cooper /* $NetBSD: t_strtoi.c,v 1.1 2015/05/01 14:17:56 christos Exp $ */ 2*640235e2SEnji Cooper 3*640235e2SEnji Cooper /*- 4*640235e2SEnji Cooper * Copyright (c) 2015 The NetBSD Foundation, Inc. 5*640235e2SEnji Cooper * All rights reserved. 6*640235e2SEnji Cooper * 7*640235e2SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation 8*640235e2SEnji Cooper * by Jukka Ruohonen. 9*640235e2SEnji Cooper * 10*640235e2SEnji Cooper * Redistribution and use in source and binary forms, with or without 11*640235e2SEnji Cooper * modification, are permitted provided that the following conditions 12*640235e2SEnji Cooper * are met: 13*640235e2SEnji Cooper * 1. Redistributions of source code must retain the above copyright 14*640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer. 15*640235e2SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 16*640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer in the 17*640235e2SEnji Cooper * documentation and/or other materials provided with the distribution. 18*640235e2SEnji Cooper * 19*640235e2SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20*640235e2SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21*640235e2SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22*640235e2SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23*640235e2SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*640235e2SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*640235e2SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*640235e2SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*640235e2SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*640235e2SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*640235e2SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 30*640235e2SEnji Cooper */ 31*640235e2SEnji Cooper 32*640235e2SEnji Cooper /* 33*640235e2SEnji Cooper * Created by Kamil Rytarowski, vesed on ID: 34*640235e2SEnji Cooper * NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp 35*640235e2SEnji Cooper */ 36*640235e2SEnji Cooper 37*640235e2SEnji Cooper #include <sys/cdefs.h> 38*640235e2SEnji Cooper __RCSID("$NetBSD: t_strtoi.c,v 1.1 2015/05/01 14:17:56 christos Exp $"); 39*640235e2SEnji Cooper 40*640235e2SEnji Cooper #include <atf-c.h> 41*640235e2SEnji Cooper #include <errno.h> 42*640235e2SEnji Cooper #include <inttypes.h> 43*640235e2SEnji Cooper #include <stdlib.h> 44*640235e2SEnji Cooper #include <string.h> 45*640235e2SEnji Cooper #include <limits.h> 46*640235e2SEnji Cooper 47*640235e2SEnji Cooper struct test { 48*640235e2SEnji Cooper const char *str; 49*640235e2SEnji Cooper intmax_t res; 50*640235e2SEnji Cooper int base; 51*640235e2SEnji Cooper const char *end; 52*640235e2SEnji Cooper intmax_t lo; 53*640235e2SEnji Cooper intmax_t hi; 54*640235e2SEnji Cooper int rstatus; 55*640235e2SEnji Cooper }; 56*640235e2SEnji Cooper 57*640235e2SEnji Cooper static void check(struct test *, intmax_t, char *, int); 58*640235e2SEnji Cooper 59*640235e2SEnji Cooper static void 60*640235e2SEnji Cooper check(struct test *t, intmax_t rv, char *end, int rstatus) 61*640235e2SEnji Cooper { 62*640235e2SEnji Cooper 63*640235e2SEnji Cooper if (rv != t->res) 64*640235e2SEnji Cooper atf_tc_fail_nonfatal("strtoi(%s, &end, %d, %jd, %jd, &rstatus)" 65*640235e2SEnji Cooper " failed (rv = %jd)", t->str, t->base, t->lo, t->hi, rv); 66*640235e2SEnji Cooper 67*640235e2SEnji Cooper if (rstatus != t->rstatus) 68*640235e2SEnji Cooper atf_tc_fail_nonfatal("strtoi(%s, &end, %d, %jd, %jd, &rstatus)" 69*640235e2SEnji Cooper " failed (rstatus: %d ('%s'))", 70*640235e2SEnji Cooper t->str, t->base, t->lo, t->hi, rstatus, strerror(rstatus)); 71*640235e2SEnji Cooper 72*640235e2SEnji Cooper if ((t->end != NULL && strcmp(t->end, end) != 0) || 73*640235e2SEnji Cooper (t->end == NULL && *end != '\0')) 74*640235e2SEnji Cooper atf_tc_fail_nonfatal("invalid end pointer ('%s') from " 75*640235e2SEnji Cooper "strtoi(%s, &end, %d, %jd, %jd, &rstatus)", 76*640235e2SEnji Cooper end, t->str, t->base, t->lo, t->hi); 77*640235e2SEnji Cooper } 78*640235e2SEnji Cooper 79*640235e2SEnji Cooper ATF_TC(strtoi_base); 80*640235e2SEnji Cooper ATF_TC_HEAD(strtoi_base, tc) 81*640235e2SEnji Cooper { 82*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test strtoi(3) with different bases"); 83*640235e2SEnji Cooper } 84*640235e2SEnji Cooper 85*640235e2SEnji Cooper ATF_TC_BODY(strtoi_base, tc) 86*640235e2SEnji Cooper { 87*640235e2SEnji Cooper struct test t[] = { 88*640235e2SEnji Cooper { "123456789", 123456789, 0, NULL, 89*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 90*640235e2SEnji Cooper { "111010110111100110100010101",123456789, 2, NULL, 91*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 92*640235e2SEnji Cooper { "22121022020212200", 123456789, 3, NULL, 93*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 94*640235e2SEnji Cooper { "13112330310111", 123456789, 4, NULL, 95*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 96*640235e2SEnji Cooper { "223101104124", 123456789, 5, NULL, 97*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 98*640235e2SEnji Cooper { "20130035113", 123456789, 6, NULL, 99*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 100*640235e2SEnji Cooper { "3026236221", 123456789, 7, NULL, 101*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 102*640235e2SEnji Cooper { "726746425", 123456789, 8, NULL, 103*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 104*640235e2SEnji Cooper { "277266780", 123456789, 9, NULL, 105*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 106*640235e2SEnji Cooper { "123456789", 123456789, 10, NULL, 107*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 108*640235e2SEnji Cooper { "63762A05", 123456789, 11, NULL, 109*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 110*640235e2SEnji Cooper { "35418A99", 123456789, 12, NULL, 111*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 112*640235e2SEnji Cooper { "1C767471", 123456789, 13, NULL, 113*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 114*640235e2SEnji Cooper { "12579781", 123456789, 14, NULL, 115*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 116*640235e2SEnji Cooper { "AC89BC9", 123456789, 15, NULL, 117*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 118*640235e2SEnji Cooper { "75BCD15", 123456789, 16, NULL, 119*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 120*640235e2SEnji Cooper { "1234567", 342391, 8, NULL, 121*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 122*640235e2SEnji Cooper { "01234567", 342391, 0, NULL, 123*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 124*640235e2SEnji Cooper { "0123456789", 123456789, 10, NULL, 125*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 126*640235e2SEnji Cooper { "0x75bcd15", 123456789, 0, NULL, 127*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 128*640235e2SEnji Cooper }; 129*640235e2SEnji Cooper 130*640235e2SEnji Cooper intmax_t rv; 131*640235e2SEnji Cooper char *end; 132*640235e2SEnji Cooper int e; 133*640235e2SEnji Cooper size_t i; 134*640235e2SEnji Cooper 135*640235e2SEnji Cooper for (i = 0; i < __arraycount(t); i++) { 136*640235e2SEnji Cooper 137*640235e2SEnji Cooper errno = 0; 138*640235e2SEnji Cooper rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); 139*640235e2SEnji Cooper 140*640235e2SEnji Cooper if (errno != 0) 141*640235e2SEnji Cooper atf_tc_fail("strtoi(3) changed errno to %d ('%s')", 142*640235e2SEnji Cooper e, strerror(e)); 143*640235e2SEnji Cooper 144*640235e2SEnji Cooper check(&t[i], rv, end, e); 145*640235e2SEnji Cooper } 146*640235e2SEnji Cooper } 147*640235e2SEnji Cooper 148*640235e2SEnji Cooper ATF_TC(strtoi_case); 149*640235e2SEnji Cooper ATF_TC_HEAD(strtoi_case, tc) 150*640235e2SEnji Cooper { 151*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtoi(3)"); 152*640235e2SEnji Cooper } 153*640235e2SEnji Cooper 154*640235e2SEnji Cooper ATF_TC_BODY(strtoi_case, tc) 155*640235e2SEnji Cooper { 156*640235e2SEnji Cooper struct test t[] = { 157*640235e2SEnji Cooper { "abcd", 0xabcd, 16, NULL, 158*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 159*640235e2SEnji Cooper { " dcba", 0xdcba, 16, NULL, 160*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 161*640235e2SEnji Cooper { "abcd dcba", 0xabcd, 16, " dcba", 162*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP }, 163*640235e2SEnji Cooper { "abc0x123", 0xabc0, 16, "x123", 164*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP }, 165*640235e2SEnji Cooper { "abcd\0x123", 0xabcd, 16, "\0x123", 166*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 167*640235e2SEnji Cooper { "ABCD", 0xabcd, 16, NULL, 168*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 169*640235e2SEnji Cooper { "aBcD", 0xabcd, 16, NULL, 170*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 171*640235e2SEnji Cooper { "0xABCD", 0xabcd, 16, NULL, 172*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 173*640235e2SEnji Cooper { "0xABCDX", 0xabcd, 16, "X", 174*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP}, 175*640235e2SEnji Cooper }; 176*640235e2SEnji Cooper 177*640235e2SEnji Cooper intmax_t rv; 178*640235e2SEnji Cooper char *end; 179*640235e2SEnji Cooper int e; 180*640235e2SEnji Cooper size_t i; 181*640235e2SEnji Cooper 182*640235e2SEnji Cooper for (i = 0; i < __arraycount(t); i++) { 183*640235e2SEnji Cooper 184*640235e2SEnji Cooper errno = 0; 185*640235e2SEnji Cooper rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); 186*640235e2SEnji Cooper 187*640235e2SEnji Cooper if (errno != 0) 188*640235e2SEnji Cooper atf_tc_fail("strtoi(3) changed errno to %d ('%s')", 189*640235e2SEnji Cooper e, strerror(e)); 190*640235e2SEnji Cooper 191*640235e2SEnji Cooper check(&t[i], rv, end, e); 192*640235e2SEnji Cooper } 193*640235e2SEnji Cooper } 194*640235e2SEnji Cooper 195*640235e2SEnji Cooper ATF_TC(strtoi_range); 196*640235e2SEnji Cooper ATF_TC_HEAD(strtoi_range, tc) 197*640235e2SEnji Cooper { 198*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtoi(3)"); 199*640235e2SEnji Cooper } 200*640235e2SEnji Cooper 201*640235e2SEnji Cooper ATF_TC_BODY(strtoi_range, tc) 202*640235e2SEnji Cooper { 203*640235e2SEnji Cooper struct test t[] = { 204*640235e2SEnji Cooper #if INTMAX_MAX == 0x7fffffffffffffff 205*640235e2SEnji Cooper { "1000000000000000000000", INTMAX_MAX, 8, NULL, 206*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ERANGE }, 207*640235e2SEnji Cooper { "9223372036854775808", INTMAX_MAX, 10, NULL, 208*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ERANGE }, 209*640235e2SEnji Cooper { "8000000000000000", INTMAX_MAX, 16, NULL, 210*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ERANGE }, 211*640235e2SEnji Cooper #else 212*640235e2SEnji Cooper #error extend this test to your platform! 213*640235e2SEnji Cooper #endif 214*640235e2SEnji Cooper { "10", 1, 10, NULL, 215*640235e2SEnji Cooper -1, 1, ERANGE }, 216*640235e2SEnji Cooper { "10", 11, 10, NULL, 217*640235e2SEnji Cooper 11, 20, ERANGE }, 218*640235e2SEnji Cooper }; 219*640235e2SEnji Cooper 220*640235e2SEnji Cooper intmax_t rv; 221*640235e2SEnji Cooper char *end; 222*640235e2SEnji Cooper int e; 223*640235e2SEnji Cooper size_t i; 224*640235e2SEnji Cooper 225*640235e2SEnji Cooper for (i = 0; i < __arraycount(t); i++) { 226*640235e2SEnji Cooper 227*640235e2SEnji Cooper errno = 0; 228*640235e2SEnji Cooper rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); 229*640235e2SEnji Cooper 230*640235e2SEnji Cooper if (errno != 0) 231*640235e2SEnji Cooper atf_tc_fail("strtoi(3) changed errno to %d ('%s')", 232*640235e2SEnji Cooper e, strerror(e)); 233*640235e2SEnji Cooper 234*640235e2SEnji Cooper check(&t[i], rv, end, e); 235*640235e2SEnji Cooper } 236*640235e2SEnji Cooper } 237*640235e2SEnji Cooper 238*640235e2SEnji Cooper ATF_TC(strtoi_signed); 239*640235e2SEnji Cooper ATF_TC_HEAD(strtoi_signed, tc) 240*640235e2SEnji Cooper { 241*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "A basic test of strtoi(3)"); 242*640235e2SEnji Cooper } 243*640235e2SEnji Cooper 244*640235e2SEnji Cooper ATF_TC_BODY(strtoi_signed, tc) 245*640235e2SEnji Cooper { 246*640235e2SEnji Cooper struct test t[] = { 247*640235e2SEnji Cooper { "1", 1, 0, NULL, 248*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 249*640235e2SEnji Cooper { " 2", 2, 0, NULL, 250*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 251*640235e2SEnji Cooper { " 3", 3, 0, NULL, 252*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 253*640235e2SEnji Cooper { " -3", -3, 0, NULL, 254*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 255*640235e2SEnji Cooper { "--1", 0, 0, "--1", 256*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ECANCELED }, 257*640235e2SEnji Cooper { "+-2", 0, 0, "+-2", 258*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ECANCELED }, 259*640235e2SEnji Cooper { "++3", 0, 0, "++3", 260*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ECANCELED }, 261*640235e2SEnji Cooper { "+9", 9, 0, NULL, 262*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 263*640235e2SEnji Cooper { "+123", 123, 0, NULL, 264*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, 0 }, 265*640235e2SEnji Cooper { "-1 3", -1, 0, " 3", 266*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP }, 267*640235e2SEnji Cooper { "-1.3", -1, 0, ".3", 268*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP }, 269*640235e2SEnji Cooper { "- 3", 0, 0, "- 3", 270*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ECANCELED }, 271*640235e2SEnji Cooper { "+33.", 33, 0, ".", 272*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP }, 273*640235e2SEnji Cooper { "30x0", 30, 0, "x0", 274*640235e2SEnji Cooper INTMAX_MIN, INTMAX_MAX, ENOTSUP }, 275*640235e2SEnji Cooper }; 276*640235e2SEnji Cooper 277*640235e2SEnji Cooper intmax_t rv; 278*640235e2SEnji Cooper char *end; 279*640235e2SEnji Cooper int e; 280*640235e2SEnji Cooper size_t i; 281*640235e2SEnji Cooper 282*640235e2SEnji Cooper for (i = 0; i < __arraycount(t); i++) { 283*640235e2SEnji Cooper 284*640235e2SEnji Cooper errno = 0; 285*640235e2SEnji Cooper rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); 286*640235e2SEnji Cooper 287*640235e2SEnji Cooper if (errno != 0) 288*640235e2SEnji Cooper atf_tc_fail("strtoi(3) changed errno to %d ('%s')", 289*640235e2SEnji Cooper e, strerror(e)); 290*640235e2SEnji Cooper 291*640235e2SEnji Cooper check(&t[i], rv, end, e); 292*640235e2SEnji Cooper } 293*640235e2SEnji Cooper } 294*640235e2SEnji Cooper 295*640235e2SEnji Cooper ATF_TP_ADD_TCS(tp) 296*640235e2SEnji Cooper { 297*640235e2SEnji Cooper 298*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, strtoi_base); 299*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, strtoi_case); 300*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, strtoi_range); 301*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, strtoi_signed); 302*640235e2SEnji Cooper 303*640235e2SEnji Cooper return atf_no_error(); 304*640235e2SEnji Cooper } 305