]> git.sur5r.net Git - cc65/blob - test/val/strtol-test.c
All regression-tests subdirectories are cleaned before the first test starts, so...
[cc65] / test / val / strtol-test.c
1 /*
2   !!DESCRIPTION!! A small test for atoi/strtol. Assumes twos complement
3   !!ORIGIN!!
4   !!LICENCE!!
5   !!AUTHOR!!
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <limits.h>
12 #include <errno.h>
13
14 #define ERROR   0
15 #define OK      1
16
17 static unsigned int Failures = 0;
18
19 static void IncStr (char* Buf)
20 /* Increment a number represented as a string by one. The string MUST not
21  * start with a '9', we cannot handle overflow in this case.
22  */
23 {
24     int Len = strlen (Buf);
25
26     while (--Len >= 0) {
27         switch (Buf[Len]) {
28             case '9':
29                 Buf[Len] = '0';
30                 break;
31
32             default:
33                 ++(Buf[Len]);
34                 return;
35         }
36     }
37 }
38
39 static void CheckStrToL (const char* Str, int Base, long Val, unsigned char Ok)
40 {
41     char* EndPtr;
42     long Res = strtol (Str, &EndPtr, Base);
43     if (Ok) {
44         if (Res != Val) {
45             printf ("strtol error in \"%s\":\n"
46                     "  result = %ld, should be %ld, chars = %d\n",
47                     Str, Res, Val, EndPtr - Str);
48             ++Failures;
49         }
50     } else {
51         if (errno != ERANGE) {
52             printf ("strtol error in \"%s\":\n"
53                     "  should not convert, but errno = %d\n",
54                     Str, errno);
55             ++Failures;
56         }
57         if (Res != Val) {
58             printf ("strtol error in \"%s\":\n"
59                     "  result = %ld, should be %ld, chars = %d\n",
60                     Str, Res, Val, EndPtr - Str);
61             ++Failures;
62         }
63     }
64 }
65
66 int main (void)
67 {
68     char Buf[80];
69
70     /* Prefixed allowed if base = 0 */
71     CheckStrToL ("\t 0x10G ", 0, 16L, OK);
72     CheckStrToL ("\t 0X10G ", 0, 16L, OK);
73     CheckStrToL (" \t0377\t", 0, 255L, OK);
74     CheckStrToL (" 377", 0, 377L, OK);
75
76     CheckStrToL ("\t -0x10G ", 0, -16L, OK);
77     CheckStrToL ("\t -0X10G ", 0, -16L, OK);
78     CheckStrToL (" \t-0377\t", 0, -255L, OK);
79     CheckStrToL (" -377", 0, -377L, OK);
80
81     /* No prefixes if base = 10 */
82     CheckStrToL ("\t 1234 ", 10, 1234L, OK);
83     CheckStrToL ("\t -1234 ", 10, -1234L, OK);
84     CheckStrToL ("\t -0x10G ", 10, 0L, OK);
85     CheckStrToL ("\t -0X10G ", 10, 0L, OK);
86     CheckStrToL (" \t-0377\t", 10, -377L, OK);
87     CheckStrToL (" 0377", 10, 377L, OK);
88
89     /* 0x prefix is allowed if base = 16 */
90     CheckStrToL ("\t 0x1234 ", 16, 0x1234L, OK);
91     CheckStrToL ("\t -0x1234 ", 16, -0x1234L, OK);
92     CheckStrToL ("\t -010G ", 16, -16L, OK);
93     CheckStrToL ("\t 10G ", 16, 16L, OK);
94
95     /* Check LONG_MIN and LONG_MAX */
96     sprintf (Buf, "%ld", LONG_MIN);
97     CheckStrToL (Buf, 0, LONG_MIN, OK);
98     sprintf (Buf, "%ld", LONG_MAX);
99     CheckStrToL (Buf, 0, LONG_MAX, OK);
100
101     /* Check value one smaller */
102     sprintf (Buf+1, "%ld", LONG_MIN);
103     Buf[1] = '0';       /* Overwrite '-' */
104     IncStr (Buf+1);
105     if (Buf[1] == '0') {
106         Buf[1] = '-';
107         Buf[0] = ' ';
108     } else {
109         Buf[0] = '-';
110     }
111     CheckStrToL (Buf, 0, LONG_MIN, ERROR);
112
113     /* Check value one larger */
114     sprintf (Buf+1, "%ld", LONG_MAX);
115     Buf[0] = '0';
116     IncStr (Buf);
117     if (Buf[0] == '0') {
118         Buf[0] = ' ';
119     }
120     CheckStrToL (Buf, 0, LONG_MAX, ERROR);
121
122     /* Check numbers that are much too large or small */
123     CheckStrToL ("-999999999999999999999999999999999999999999999999999999999", 0, LONG_MIN, ERROR);
124     CheckStrToL ("+999999999999999999999999999999999999999999999999999999999", 0, LONG_MAX, ERROR);
125     CheckStrToL (" 999999999999999999999999999999999999999999999999999999999", 0, LONG_MAX, ERROR);
126
127     /* Check a few other bases */
128     CheckStrToL ("aBcD", 36, 481261L, OK);
129     CheckStrToL ("zyaB", 35, 0L, ERROR);
130     CheckStrToL ("zyaB", 36, 1677395L, ERROR);
131
132     printf ("Failures: %u\n", Failures);
133
134     return Failures;
135 }