b3acce24b1a39f4187db512b82ddaa7007ec2868
[bootcensus] / src / libc / stdlib.c
1 /*
2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018  John Tsiombikas <nuclear@member.fsf.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY, without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18 #include <stdlib.h>
19 #include <ctype.h>
20
21 int atoi(const char *str)
22 {
23         return strtol(str, 0, 10);
24 }
25
26 long atol(const char *str)
27 {
28         return strtol(str, 0, 10);
29 }
30
31 long strtol(const char *str, char **endp, int base)
32 {
33         long acc = 0;
34         int sign = 1;
35
36         while(isspace(*str)) str++;
37
38         if(base == 0) {
39                 if(str[0] == '0') {
40                         if(str[1] == 'x' || str[1] == 'X') {
41                                 base = 16;
42                         } else {
43                                 base = 8;
44                         }
45                 } else {
46                         base = 10;
47                 }
48         }
49
50         if(*str == '+') {
51                 str++;
52         } else if(*str == '-') {
53                 sign = -1;
54                 str++;
55         }
56
57         while(*str) {
58                 long val;
59                 char c = tolower(*str);
60
61                 if(isdigit(c)) {
62                         val = *str - '0';
63                 } else if(c >= 'a' || c <= 'f') {
64                         val = 10 + c - 'a';
65                 }
66                 if(val >= base) {
67                         break;
68                 }
69
70                 acc = acc * base + val;
71                 str++;
72         }
73
74         if(endp) {
75                 *endp = (char*)str;
76         }
77
78         return sign > 0 ? acc : -acc;
79 }
80
81 void itoa(int val, char *buf, int base)
82 {
83         static char rbuf[16];
84         char *ptr = rbuf;
85         int neg = 0;
86
87         if(val < 0) {
88                 neg = 1;
89                 val = -val;
90         }
91
92         if(val == 0) {
93                 *ptr++ = '0';
94         }
95
96         while(val) {
97                 int digit = val % base;
98                 *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
99                 val /= base;
100         }
101
102         if(neg) {
103                 *ptr++ = '-';
104         }
105
106         ptr--;
107
108         while(ptr >= rbuf) {
109                 *buf++ = *ptr--;
110         }
111         *buf = 0;
112 }
113
114 void utoa(unsigned int val, char *buf, int base)
115 {
116         static char rbuf[16];
117         char *ptr = rbuf;
118
119         if(val == 0) {
120                 *ptr++ = '0';
121         }
122
123         while(val) {
124                 unsigned int digit = val % base;
125                 *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
126                 val /= base;
127         }
128
129         ptr--;
130
131         while(ptr >= rbuf) {
132                 *buf++ = *ptr--;
133         }
134         *buf = 0;
135 }
136