A toy operating system written in C.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
freywaros/src/lib/string.c

251 lines
4.5 KiB

#include "src/lib/string.h"
#include <stdarg.h>
uint8_t bytes_equal(const char *l, const char *r, uint64_t count) {
while (count--) {
if (*l++ != *r++) {
return 0;
}
}
return 1;
}
uint8_t string_empty(const char *s) {
return *s == '\0';
}
uint64_t string_length(const char *s) {
const char *e = s;
while (*e) {
e++;
}
return (uint64_t)(e - s);
}
uint8_t string_equal(const char *l, const char *r) {
while (*l && *r) {
if (*l != *r) {
return 0;
}
l++;
r++;
}
return *l == *r;
}
uint64_t string_trim(char *string, char character, char **result) {
while (*string == character) {
string++;
}
*result = string;
if (*string == '\0') {
return 0;
}
char *end = string;
while (*end != '\0') {
end++;
}
end--;
while (string < end && *end == character) {
*end = '\0';
end--;
}
return (uint64_t)(end - string + 1);
}
uint64_t string_split(char *string, char separator, uint64_t max, char **result) {
uint64_t count = 1;
*result = string;
while (*string && count < max) {
if (*string == separator) {
*string = '\0';
result++;
*result = string + 1;
count++;
}
string++;
}
return count;
}
uint64_t string_byte_to_hex(uint8_t value, uint64_t max, char *result) {
if (max == 0) {
return 0;
}
if (max == 1) {
result[0] = '\0';
return 0;
}
if (max == 2) {
result[0] = '0';
result[1] = '\0';
return 1;
}
char tmp[3] = "00";
uint8_t i = 0;
while (value) {
uint8_t nibble = value & 0xF;
tmp[i++] = nibble < 10 ? '0' + nibble : 'a' + nibble - 10;
value >>= 4;
}
result[0] = '0';
result[1] = 'x';
i = 2;
while (i < 4 && i < max - 1) {
result[i] = tmp[3 - i];
i++;
}
result[i] = '\0';
return i;
}
uint64_t string_uint_to_decimal(uint64_t value, uint64_t max, char *result) {
if (max == 0) {
return 0;
}
char tmp[20];
uint8_t len = 0;
if (value == 0) {
tmp[len++] = '0';
} else {
while (value && len < 20) {
tmp[len++] = '0' + (value % 10);
value /= 10;
}
}
uint8_t i = 0;
while (i < len && i < max - 1) {
result[i] = tmp[len - 1 - i];
i++;
}
result[i] = '\0';
return i;
}
uint64_t string_int_to_decimal(int64_t value, uint64_t max, char *result) {
if (max == 0) {
return 0;
}
if (value >= 0) {
return string_uint_to_decimal((uint64_t)value, max, result);
}
result[0] = '-';
return 1 + string_uint_to_decimal((uint64_t)(-value), max - 1, result + 1);
}
uint64_t string_uint_to_hex(uint64_t value, uint64_t max, char *result) {
if (max == 0) {
return 0;
}
if (max == 1) {
result[0] = '\0';
return 0;
}
if (max == 2) {
result[0] = '0';
result[1] = '\0';
return 1;
}
char tmp[17] = "0000000000000000";
uint8_t i = 0;
while (value) {
uint8_t nibble = value & 0xF;
tmp[i++] = nibble < 10 ? '0' + nibble : 'A' + nibble - 10;
value >>= 4;
}
result[0] = '0';
result[1] = 'x';
i = 2;
while (i < 18 && i < max - 1) {
result[i] = tmp[17 - i];
i++;
}
result[i] = '\0';
return i;
}
uint64_t string_format(const char *format, uint64_t max, char *output, ...) {
va_list args;
va_start(args, output);
uint64_t limit = max - 1;
uint64_t fi = 0, ri = 0;
while (format[fi] && ri < limit) {
if (format[fi] != '%') {
output[ri++] = format[fi++];
} else {
switch (format[fi + 1]) {
case 'c':
output[ri++] = (char)va_arg(args, int);
fi += 2;
break;
case 'd':
string_int_to_decimal(va_arg(args, int64_t), limit - ri, output + ri);
while (output[ri]) {
ri++;
}
fi += 2;
break;
case 'u':
string_uint_to_decimal(va_arg(args, uint64_t), limit - ri, output + ri);
while (output[ri]) {
ri++;
}
fi += 2;
break;
case 'x':
string_uint_to_hex(va_arg(args, uint64_t), limit - ri, output + ri);
while (output[ri]) {
ri++;
}
fi += 2;
break;
case 's': {
char *s = va_arg(args, char *);
while (*s && ri < limit) {
output[ri++] = *s;
s++;
}
fi += 2;
break;
}
case '%': {
output[ri++] = '%';
fi += 2;
break;
}
default:
output[ri++] = format[fi++];
output[ri++] = format[fi++];
break;
}
}
}
output[ri] = '\0';
va_end(args);
return ri;
}