1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 
13 #include <stdlib.h>
14 
strtoul(const char * S,char ** PTR,int BASE)15 unsigned long int strtoul(const char *S, char **PTR,int BASE)
16 {
17 	unsigned long rval = 0;
18 	short int digit;
19 	// *PTR is S, unless PTR is NULL, in which case i override it with my own ptr
20 	char* ptr;
21 	if (PTR == NULL)
22 	{
23 		//override
24 		PTR = &ptr;
25 	}
26 	// i use PTR to advance through the string
27 	*PTR = (char *) S;
28 	//check if BASE is ok
29 	if ((BASE < 0) || BASE > 36)
30 	{
31 		return 0;
32 	}
33 	// ignore white space at beginning of S
34 	while ((**PTR == ' ')
35 			|| (**PTR == '\t')
36 			|| (**PTR == '\n')
37 			|| (**PTR == '\r')
38 			)
39 	{
40 		(*PTR)++;
41 	}
42 	// if BASE is 0... determine the base from the first chars...
43 	if (BASE == 0)
44 	{
45 		// if S starts with "0x", BASE = 16, else 10
46 		if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
47 		{
48 			BASE = 16;
49 		}
50 		else
51 		{
52 			BASE = 10;
53 		}
54 	}
55 	if (BASE == 16)
56 	{
57 		// S may start with "0x"
58 		if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
59 		{
60 			(*PTR)++;
61 			(*PTR)++;
62 		}
63 	}
64 	//until end of string
65 	while (**PTR)
66 	{
67 		if (((**PTR) >= '0') && ((**PTR) <='9'))
68 		{
69 			//digit (0..9)
70 			digit = **PTR - '0';
71 		}
72 		else if (((**PTR) >= 'a') && ((**PTR) <='z'))
73 		{
74 			//alphanumeric digit lowercase(a (10) .. z (35) )
75 			digit = (**PTR - 'a') + 10;
76 		}
77 		else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
78 		{
79 			//alphanumeric digit uppercase(a (10) .. z (35) )
80 			digit = (**PTR - 'A') + 10;
81 		}
82 		else
83 		{
84 			//end of parseable number reached...
85 			break;
86 		}
87 		if (digit < BASE)
88 		{
89 			rval = (rval * BASE) + digit;
90 		}
91 		else
92 		{
93 			//digit found, but its too big for current base
94 			//end of parseable number reached...
95 			break;
96 		}
97 		//next...
98 		(*PTR)++;
99 	}
100 	//done
101 	return rval;
102 }
103 
104