Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / lib / libc / stdlib / strtoul.c
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
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 == 0)
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                         (*PTR)++;
50                         (*PTR)++;
51                 }
52                 else
53                 {
54                         BASE = 10;
55                 }
56         }
57         if (BASE == 16)
58         {
59                 // S may start with "0x"
60                 if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
61                 {
62                         (*PTR)++;
63                         (*PTR)++;
64                 }
65         }
66         //until end of string
67         while (**PTR)
68         {
69                 if (((**PTR) >= '0') && ((**PTR) <='9'))
70                 {
71                         //digit (0..9)
72                         digit = **PTR - '0';
73                 }
74                 else if (((**PTR) >= 'a') && ((**PTR) <='z'))
75                 {
76                         //alphanumeric digit lowercase(a (10) .. z (35) )
77                         digit = (**PTR - 'a') + 10;
78                 }
79                 else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
80                 {
81                         //alphanumeric digit uppercase(a (10) .. z (35) )
82                         digit = (**PTR - 'A') + 10;
83                 }
84                 else
85                 {
86                         //end of parseable number reached...
87                         break;
88                 }
89                 if (digit < BASE)
90                 {
91                         rval = (rval * BASE) + digit;
92                 }
93                 else
94                 {
95                         //digit found, but its too big for current base
96                         //end of parseable number reached...
97                         break;
98                 }
99                 //next...
100                 (*PTR)++;
101         }
102         //done
103         return rval;
104 }
105