Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / lib / libc / stdlib / strtol.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 long int strtol(const char *S, char **PTR,int BASE)
16 {
17         long rval = 0;
18         short int negative = 0;
19         short int digit;
20         // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr
21         char* ptr;
22         if (PTR == 0)
23         {
24                 //override
25                 PTR = &ptr;
26         }
27         // i use PTR to advance through the string
28         *PTR = (char *) S;
29         //check if BASE is ok
30         if ((BASE < 0) || BASE > 36)
31         {
32                 return 0;
33         }
34         // ignore white space at beginning of S
35         while ((**PTR == ' ')
36                         || (**PTR == '\t')
37                         || (**PTR == '\n')
38                         || (**PTR == '\r')
39                         )
40         {
41                 (*PTR)++;
42         }
43         // check if S starts with "-" in which case the return value is negative
44         if (**PTR == '-')
45         {
46                 negative = 1;
47                 (*PTR)++;
48         }
49         // if BASE is 0... determine the base from the first chars...
50         if (BASE == 0)
51         {
52                 // if S starts with "0x", BASE = 16, else 10
53                 if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
54                 {
55                         BASE = 16;
56                         (*PTR)++;
57                         (*PTR)++;
58                 }
59                 else
60                 {
61                         BASE = 10;
62                 }
63         }
64         if (BASE == 16)
65         {
66                 // S may start with "0x"
67                 if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
68                 {
69                         (*PTR)++;
70                         (*PTR)++;
71                 }
72         }
73         //until end of string
74         while (**PTR)
75         {
76                 if (((**PTR) >= '0') && ((**PTR) <= '9'))
77                 {
78                         //digit (0..9)
79                         digit = **PTR - '0';
80                 }
81                 else if (((**PTR) >= 'a') && ((**PTR) <='z'))
82                 {
83                         //alphanumeric digit lowercase(a (10) .. z (35) )
84                         digit = (**PTR - 'a') + 10;
85                 }
86                 else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
87                 {
88                         //alphanumeric digit uppercase(a (10) .. z (35) )
89                         digit = (**PTR - 'A') + 10;
90                 }
91                 else
92                 {
93                         //end of parseable number reached...
94                         break;
95                 }
96                 if (digit < BASE)
97                 {
98                         rval = (rval * BASE) + digit;
99                 }
100                 else
101                 {
102                         //digit found, but its too big for current base
103                         //end of parseable number reached...
104                         break;
105                 }
106                 //next...
107                 (*PTR)++;
108         }
109         if (negative)
110         {
111                 return rval * -1;
112         }
113         //else
114         return rval;
115 }