1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2023 Oxide Computer Company 14 */ 15 16 /* 17 * Test the implementation of strtonum() and strtonumx() 18 */ 19 20 #include <limits.h> 21 #include <stdbool.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 bool fail = false; 27 28 static void 29 runtestx(const char *nstr, long long minval, long long maxval, 30 int base, long long expval, bool expect_pass) 31 { 32 const char *errstr; 33 char key[0x100]; 34 long long val; 35 36 if (base == -1) { 37 val = strtonum(nstr, minval, maxval, &errstr); 38 (void) snprintf(key, sizeof (key), "strtonum(%s)", nstr); 39 } else { 40 val = strtonumx(nstr, minval, maxval, &errstr, base); 41 (void) snprintf(key, sizeof (key), "strtonumx(%s, %d)", 42 nstr, base); 43 } 44 45 if (expect_pass) { 46 if (errstr != NULL) { 47 fprintf(stderr, "FAIL %s was rejected: " 48 "%s [%lld,%lld]\n", 49 key, errstr, minval, maxval); 50 fail = true; 51 } else { 52 fprintf(stdout, "PASS %s was accepted: " 53 "[%lld,%lld] = %lld\n", 54 key, minval, maxval, val); 55 if (val != expval) { 56 fprintf(stderr, "FAIL %s returned wrong value: " 57 "[%lld,%lld] = %lld vs. %lld\n", key, 58 minval, maxval, val, expval); 59 fail = true; 60 } 61 } 62 } else { 63 if (errstr == NULL) { 64 fprintf(stderr, "FAIL %s was accepted: " 65 "[%lld,%lld] = %lld\n", 66 key, minval, maxval, val); 67 fail = true; 68 } else { 69 fprintf(stdout, "PASS %s was rejected: " 70 "%s [%lld,%lld]\n", 71 key, errstr, minval, maxval); 72 } 73 } 74 } 75 76 static void 77 runtest(const char *nstr, long long minval, long long maxval, long long expval, 78 bool expect_pass) 79 { 80 runtestx(nstr, minval, maxval, -1, expval, expect_pass); 81 runtestx(nstr, minval, maxval, 10, expval, expect_pass); 82 runtestx(nstr, minval, maxval, 0, expval, expect_pass); 83 } 84 85 int 86 main(void) 87 { 88 runtest("1", 0, 100, 1, true); 89 runtest("0", -3, 7, 0, true); 90 runtest("0", 2, 10, 0, false); 91 runtest("0", 2, LLONG_MAX, 0, false); 92 runtest("-2", 0, LLONG_MAX, 0, false); 93 runtest("0", -5, LLONG_MAX, 0, true); 94 runtest("-3", -3, LLONG_MAX, -3, true); 95 runtest("-2", 10, -1, 0, false); 96 runtest("-2", -10, -1, -2, true); 97 runtest("-20", -10, -1, 0, false); 98 runtest("20", -10, -1, 0, false); 99 100 runtest("-9223372036854775808", LLONG_MIN, LLONG_MAX, LLONG_MIN, true); 101 runtest("-9223372036854775809", LLONG_MIN, LLONG_MAX, 0, false); 102 103 runtest("9223372036854775807", LLONG_MIN, LLONG_MAX, LLONG_MAX, true); 104 runtest("9223372036854775808", LLONG_MIN, LLONG_MAX, 0, false); 105 106 for (int base = 2; base <= 36; base++) 107 runtestx("1", 0, 100, base, 1, true); 108 109 runtestx("1", 0, 100, -2, 0, false); 110 runtestx("1", 0, 100, 1, 0, false); 111 runtestx("1", 0, 100, 37, 0, false); 112 113 runtestx("0x1234", 0, LLONG_MAX, 16, 0x1234, true); 114 runtestx("0x1234", 0, LLONG_MAX, 0, 0x1234, true); 115 runtestx("0x1234", 0, LLONG_MAX, 10, 0, false); 116 117 runtestx("AZbc123", 0, LLONG_MAX, 36, 23903176539, true); 118 runtestx("AZbc123", 0, LLONG_MAX, 35, 0, false); 119 runtestx("AYBC123", 0, LLONG_MAX, 35, 20185422673, true); 120 runtestx("AYBC123", 0, LLONG_MAX, 34, 0, false); 121 122 runtestx("01234", 0, LLONG_MAX, 8, 01234, true); 123 runtestx("01234", 0, LLONG_MAX, 0, 01234, true); 124 runtestx("01234", 0, LLONG_MAX, 10, 1234, true); 125 126 if (fail) { 127 printf("\nOverall status: FAIL\n"); 128 return (EXIT_FAILURE); 129 } 130 131 printf("\nOverall status: PASS\n"); 132 return (EXIT_SUCCESS); 133 } 134