2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018-2019 John Tsiombikas <nuclear@member.fsf.org>
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.
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.
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/>.
25 int atoi(const char *str)
27 return strtol(str, 0, 10);
30 long atol(const char *str)
32 return strtol(str, 0, 10);
35 long strtol(const char *str, char **endp, int base)
40 const char *start = str;
42 while(isspace(*str)) str++;
46 if(str[1] == 'x' || str[1] == 'X') {
58 } else if(*str == '-') {
65 char c = tolower(*str);
69 } else if(c >= 'a' && c <= 'f') {
79 acc = acc * base + val;
84 *endp = (char*)(valid ? str : start);
87 return sign > 0 ? acc : -acc;
90 void itoa(int val, char *buf, int base)
106 int digit = val % base;
107 *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
123 void utoa(unsigned int val, char *buf, int base)
125 static char rbuf[16];
133 unsigned int digit = val % base;
134 *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
146 double atof(const char *str)
148 return strtod(str, 0);
152 double strtod(const char *str, char **endp)
155 const char *start = str;
157 long ival = 0, dval = 0;
162 ival = strtol(str, &ep, 10);
163 if(ep == str && *str != '.') {
164 if(endp) *endp = (char*)str;
167 if(ep != str) valid = 1;
168 str = *ep == '.' ? ep + 1 : ep;
174 dval = strtol(str, &ep, 10);
181 *endp = (char*)(valid ? str : start);
186 double d = (double)dval;
195 int atexit(void (*func)(void))
197 /* there's no concept of exiting at the moment, so this does nothing */
206 #define QSORT_THRESHOLD 4
207 #define ITEM(idx) ((char*)arr + (idx) * itemsz)
221 static void ins_sort(void *arr, size_t count, size_t itemsz, int (*cmp)(const void*, const void*))
226 if(count <= 1) return;
228 it = (char*)arr + itemsz;
229 for(i=1; i<count; i++) {
232 while(a > (char*)arr && cmp(a, (b = a - itemsz)) < 0) {
239 void qsort(void *arr, size_t count, size_t itemsz, int (*cmp)(const void*, const void*))
241 char *ma, *mb, *mc, *left, *right;
242 size_t sepidx, nleft, nright;
244 if(count <= 1) return;
246 if(count < QSORT_THRESHOLD) {
247 ins_sort(arr, count, itemsz, cmp);
252 mb = ITEM(count / 2);
253 mc = ITEM(count - 1);
254 if(cmp(ma, mb) < 0) SWAP(ma, mb);
255 if(cmp(mc, ma) < 0) SWAP(mc, ma);
260 while(cmp(left, ma) < 0) left += itemsz;
261 while(cmp(ma, right) < 0) right -= itemsz;
262 if(left >= right) break;
266 sepidx = (right - (char*)arr) / itemsz;
268 nright = count - nleft - 1;
270 qsort(ma, nleft, itemsz, cmp);
271 qsort(right + itemsz, nright, itemsz, cmp);