LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
string.c
Go to the documentation of this file.
1#include <string.h>
2#include <stdarg.h>
3#include <stdbool.h>
4#include <stdint.h>
5#include <stddef.h>
6
7int strcmp(const char* a, const char* b) {
8 while(*a && *b && *a == *b) { a++; b++; }
9
10 return *a - *b;
11}
12
13char tolower(const char c) {
14 if(c >= 'A' && c <= 'Z') {
15 return c - ('A' - 'a');
16 }
17
18 return c;
19}
20
21int strcasecmp(const char* a, const char* b) {
22 while(
23 *a && *b &&
24 tolower(*a) == tolower(*b)
25 ) { a++; b++; }
26
27 return tolower(*a) - tolower(*b);
28}
29
30size_t strlen(const char* str) {
31 if(!str) return 0;
32
33 size_t i = 0;
34
35 while(*(str + i)) {
36 ++i;
37 }
38
39 return i;
40}
41
42char* strncpy(char* dest, const char* src, size_t n) {
43 size_t i;
44 for(i = 0; i < n && src[i]; ++i) {
45 dest[i] = src[i];
46 }
47 for(; i < n; ++i) {
48 dest[i] = 0;
49 }
50
51 return dest;
52}
53
54size_t wcslen(const wchar_t* str) {
55 if(!str) return 0;
56
57 size_t i = 0;
58
59 while(*(str + i)) {
60 ++i;
61 }
62
63 return i;
64}
65
66void memset32(uint32_t* dest, uint32_t c, size_t size) {
67 for(size_t i = 0; i < size; ++i) {
68 dest[i] = c;
69 }
70}
71
72void* memset(void* dest, int c, size_t size) {
73 for(size_t i = 0; i < size; ++i) {
74 *((uint8_t*)dest + i) = c;
75 }
76
77 return dest;
78}
79
80void* memcpy(void* dest, void const* source, size_t size) {
81 uint8_t* dst_8 = (uint8_t*)dest;
82 uint8_t* src_8 = (uint8_t*)source;
83
84 for(size_t i = 0; i < size; ++i) {
85 dst_8[i] = src_8[i];
86 }
87
88 return dest;
89}
90
91int memcmp(const void* a, const void* b, size_t n) {
92 const uint8_t* _a = (const uint8_t*)a;
93 const uint8_t* _b = (const uint8_t*)b;
94
95 size_t i = 0;
96 for(i = 0; i < n && _a[i] == _b[i]; ++i) {
97 }
98
99 if(i == n) {
100 return 0;
101 }
102
103 return _a[i] - _b[i];
104}
105
106void* memmove(void* dest, const void* src, size_t n) {
107 if(src > dest) {
108 for(size_t i = 0; i < n; ++i) {
109 ((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
110 }
111 }
112 else {
113 for(size_t i = n - 1; i >= 0; --i) {
114 ((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
115 }
116 }
117
118 return dest;
119}
120
121int sputs(char* buffer, int buffer_size, char* string, int length) {
122 int i;
123
124 for(i = 0; i < length; ++i) {
125 if(i < buffer_size) {
126 buffer[i] = string[i];
127 }
128 }
129
130 return i;
131}
132
133int sputls(char* buffer, int buffer_size, wchar_t* string, int length) {
134 int i;
135
136 for(i = 0; i < length && i < buffer_size; ++i) {
137 buffer[i] = (char)string[i]; // XXX: we only support ASCII code points in wchar_t
138 }
139
140 return i;
141}
142
143int sputui(char* buffer, int buffer_size, uint64_t number, int base) {
144 const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
145
146 int count = 0;
147
148 const int size = 64;
149 int i = size - 1;
150 char num_buffer[size];
151
152 do {
153 char c = chars[number % base];
154 num_buffer[i--] = c;
155 number /= base;
156 count++;
157 } while(number && i >= 0 && count < buffer_size);
158
159 sputs(buffer, buffer_size, num_buffer + (size - count), count);
160 return count;
161}
162
163int sputi(char* buffer, int buffer_size, int64_t number, int base) {
164 const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
165
166 int count = 0;
167
168 if(number < 0) {
169 *buffer++ = '-';
170 buffer_size--;
171 count++;
172 number *= -1;
173 }
174
175 const int size = 64;
176 int i = size - 1;
177 char num_buffer[size];
178
179 do {
180 char c = chars[number % base];
181 num_buffer[i--] = c;
182 number /= base;
183 count++;
184 } while(number && i >= 0 && count < buffer_size);
185
186 sputs(buffer, buffer_size, num_buffer + (size - count), count);
187 return count;
188}
189
190int sputbytes(char* buffer, int buffer_size, int64_t number) {
191 const char *prefixes = " KMGT";
192 static const int div = 1024;
193
194 size_t prefix = 0;
195 bool exact = true;
196
197 while(number / div >= 1 && prefix < strlen(prefixes)) {
198 if((number / div) * div != number) {
199 exact = false;
200 }
201
202 number /= div;
203 prefix++;
204 }
205
206 int len = 0;
207
208 if(!exact) {
209 buffer[len++] = '~';
210 }
211
212 len += sputi(buffer + len, buffer_size, number, 10);
213
214 if(prefix && len < buffer_size) {
215 buffer[len++] = prefixes[prefix];
216 buffer[len++] = 'i';
217 }
218
219 buffer[len++] = 'B';
220
221 return len;
222}
223
224size_t kvsnprintf(char* buffer, size_t buffer_size, const char* format, va_list args) {
225 size_t i = 0;
226 char c = 0;
227 bool placeholder = false;
228 char placeholderChar = ' ';
229 int minLength = 0;
230 char lengthModifier = 0; // store length in bytes
231
232 while((c = *format++)) {
233 if(c == '%') {
234 placeholder = true;
235 placeholderChar = ' ';
236 minLength = 0;
237 lengthModifier = 0;
238 continue;
239 }
240
241 if(placeholder) {
242 if((minLength == 0 && c == '0') || c == ' ') {
243 placeholderChar = c;
244 continue;
245 }
246 else if(c >= '0' && c <= '9') {
247 minLength *= 10;
248 minLength += c - '0';
249 }
250 else if(c == 'l') {
251 lengthModifier = 16;
252 }
253 else {
254 char argBuffer[256];
255 int length;
256
257 size_t argSize = buffer_size - i;
258 char* argDestination = buffer + i;
259
260 if(minLength || !buffer) {
261 argSize = sizeof(argBuffer);
262 argDestination = argBuffer;
263 memset((void*)argBuffer, 0, argSize);
264 }
265
266 switch(c) {
267 case 'c':
268 *argDestination = va_arg(args, int);
269 length = 1;
270 break;
271 case 'u':
272 length = sputui(argDestination, argSize, va_arg(args, uint64_t), 10);
273 break;
274 case 'd':
275 length = sputi(argDestination, argSize, va_arg(args, int), 10);
276 break;
277 case 'x':
278 length = sputui(argDestination, argSize, va_arg(args, uint64_t), 16);
279 break;
280 case 'B':
281 length = sputbytes(argDestination, argSize, va_arg(args, long));
282 break;
283 case 's':
284 switch(lengthModifier) {
285 case 0:
286 {
287 char* sarg = va_arg(args, char*);
288 length = sputs(argDestination, argSize, sarg, strlen(sarg));
289 }
290 break;
291 case 16:
292 {
293 wchar_t* lsarg = va_arg(args, wchar_t*);
294 length = sputls(argDestination, argSize, lsarg, wcslen(lsarg));
295 }
296 break;
297 }
298 break;
299 default:
300 length = 1;
301 argDestination[0] = c;
302 break;
303 }
304
305 if(argDestination == argBuffer) {
306 while(length < minLength) {
307 if(i < buffer_size) {
308 buffer[i] = placeholderChar;
309 }
310 ++i;
311 --minLength;
312 }
313
314 sputs(buffer + i, buffer_size - i, argBuffer, length);
315 }
316
317 i += length;
318
319 placeholder = false;
320 }
321 }
322 else {
323 if(i < buffer_size) {
324 buffer[i] = c;
325 }
326 ++i;
327 }
328 }
329
330 if(i < buffer_size) {
331 buffer[i] = 0;
332 } else if(buffer_size) {
333 buffer[buffer_size-1] = 0;
334 }
335
336 return i;
337}
338
339size_t ksnprintf(char* buffer, size_t buffer_size, const char* format, ...) {
340 va_list args;
341 va_start(args, format);
342 size_t count = kvsnprintf(buffer, buffer_size, format, args);
343 va_end(args);
344
345 return count;
346}
uint32_t length
Definition acpi.c:5
unsigned int uint32_t
Definition arch.h:11
unsigned long uint64_t
Definition arch.h:14
unsigned char uint8_t
Definition arch.h:5
signed long int64_t
Definition arch.h:13
size_t strlen(const char *str)
Definition string.c:30
int strcmp(const char *a, const char *b)
Definition string.c:7
int sputui(char *buffer, int buffer_size, uint64_t number, int base)
Definition string.c:143
void * memcpy(void *dest, void const *source, size_t size)
Definition string.c:80
void * memmove(void *dest, const void *src, size_t n)
Definition string.c:106
int sputls(char *buffer, int buffer_size, wchar_t *string, int length)
Definition string.c:133
int strcasecmp(const char *a, const char *b)
Definition string.c:21
int sputbytes(char *buffer, int buffer_size, int64_t number)
Definition string.c:190
char tolower(const char c)
Definition string.c:13
void * memset(void *dest, int c, size_t size)
Definition string.c:72
size_t ksnprintf(char *buffer, size_t buffer_size, const char *format,...)
Definition string.c:339
int memcmp(const void *a, const void *b, size_t n)
Definition string.c:91
int sputi(char *buffer, int buffer_size, int64_t number, int base)
Definition string.c:163
void memset32(uint32_t *dest, uint32_t c, size_t size)
Definition string.c:66
char * strncpy(char *dest, const char *src, size_t n)
Definition string.c:42
int sputs(char *buffer, int buffer_size, char *string, int length)
Definition string.c:121
size_t wcslen(const wchar_t *str)
Definition string.c:54
size_t kvsnprintf(char *buffer, size_t buffer_size, const char *format, va_list args)
Definition string.c:224
uint16_t size
Size of the loaded file.
Definition loader.h:5
uint64_t base
Definition sc.c:1
#define va_start(ap, X)
Definition stdarg.h:6
#define va_arg(ap, type)
Definition stdarg.h:7
#define va_end(ap)
Definition stdarg.h:8
__builtin_va_list va_list
Definition stdarg.h:4
static enum @5 format