]> git.sur5r.net Git - cc65/blob - test/val/strtoul-test.c
All regression-tests subdirectories are cleaned before the first test starts, so...
[cc65] / test / val / strtoul-test.c
1 /*
2   !!DESCRIPTION!! A small test for strtuol. 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 CheckStrToUL (const char* Str, int Base, unsigned long Val, unsigned char Ok)
40 {
41     char* EndPtr;
42     unsigned long Res = strtoul (Str, &EndPtr, Base);
43     if (Ok) {
44         if (Res != Val) {
45             printf ("strtol error in \"%s\":\n"
46                     "  result = %lu, should be %lu, 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 = %lu, should be %lu, 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     CheckStrToUL ("\t 0x10G ", 0, 16UL, OK);
72     CheckStrToUL ("\t 0X10G ", 0, 16UL, OK);
73     CheckStrToUL (" \t0377\t", 0, 255UL, OK);
74     CheckStrToUL (" 377", 0, 377UL, OK);
75
76     CheckStrToUL ("\t -0x10G ", 0, (unsigned long) -16L, OK);
77     CheckStrToUL ("\t -0X10G ", 0, (unsigned long) -16L, OK);
78     CheckStrToUL (" \t-0377\t", 0, (unsigned long) -255L, OK);
79     CheckStrToUL (" -377", 0, (unsigned long) -377L, OK);
80
81     /* No prefixes if base = 10 */
82     CheckStrToUL ("\t 1234 ", 10, 1234UL, OK);
83     CheckStrToUL ("\t -1234 ", 10, (unsigned long) -1234L, OK);
84     CheckStrToUL ("\t -0x10G ", 10, 0UL, OK);
85     CheckStrToUL ("\t -0X10G ", 10, 0UL, OK);
86     CheckStrToUL (" \t-0377\t", 10, (unsigned long) -377L, OK);
87     CheckStrToUL (" 0377", 10, 377UL, OK);
88
89     /* 0x prefix is allowed if base = 16 */
90     CheckStrToUL ("\t 0x1234 ", 16, 0x1234UL, OK);
91     CheckStrToUL ("\t -0x1234 ", 16, (unsigned long) -0x1234L, OK);
92     CheckStrToUL ("\t -010G ", 16, (unsigned long) -16L, OK);
93     CheckStrToUL ("\t 10G ", 16, 16UL, OK);
94
95     /* Check ULONG_MAX */
96     sprintf (Buf, "%lu", ULONG_MAX);
97     CheckStrToUL (Buf, 0, ULONG_MAX, OK);
98
99     /* Check value one larger */
100     sprintf (Buf+1, "%lu", ULONG_MAX);
101     Buf[0] = '0';
102     IncStr (Buf);
103     if (Buf[0] == '0') {
104         Buf[0] = ' ';
105     }
106     CheckStrToUL (Buf, 0, ULONG_MAX, ERROR);
107
108     /* Check numbers that are much too large or small */
109     CheckStrToUL ("-999999999999999999999999999999999999999999999999999999999", 0, ULONG_MAX, ERROR);
110     CheckStrToUL ("+999999999999999999999999999999999999999999999999999999999", 0, ULONG_MAX, ERROR);
111     CheckStrToUL (" 999999999999999999999999999999999999999999999999999999999", 0, ULONG_MAX, ERROR);
112
113     /* Check a few other bases */
114     CheckStrToUL ("aBcD", 36, 481261UL, OK);
115     CheckStrToUL ("zyaB", 35, 0UL, ERROR);
116     CheckStrToUL ("zyaB", 36, 1677395UL, ERROR);
117
118     printf ("Failures: %u\n", Failures);
119
120     return Failures;
121 }