Files
exkernel/common.c
Fabio Scotto di Santolo 3a102f1e61 Added libc functions
2025-11-30 18:37:12 +01:00

123 lines
2.7 KiB
C

#include "common.h"
void putchar(char c);
size_t align_up(size_t value, size_t align)
{
/* To align means to compute the smallest value which is greater than a
* given number and that is an exact multiple of another specified
* number */
size_t remainder = value % align;
if (remainder == 0)
return value;
return value + (align - remainder);
}
size_t is_aligned(size_t value, size_t align)
{
return value % align == 0;
}
void *memcpy(void *dst, const void *src, size_t n)
{
uint8_t *d = (uint8_t*)dst;
const uint8_t *s = (uint8_t*)src;
while (n--) {
*d++ = *s++;
}
return dst;
}
void *memset(void *buf, char c, size_t n)
{
uint8_t *p = (uint8_t*)buf;
while (n--) {
*p++ = c;
}
return buf;
}
char *strcpy(char *dst, const char *src)
{
char *d = dst;
while (*src != '\0') {
*d++ = *src++;
}
*d = '\0';
return dst;
}
int strcmp(const char *s1, const char *s2)
{
while (*s1 && *s2 && *s1 == *s2) {
s1++;
s2++;
}
return *((unsigned char *)s1) - *((unsigned char *)s2);
}
void printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
while (*fmt != '\0') {
if (*fmt != '%') {
putchar(*fmt);
fmt++;
} else {
fmt++; // consume %
switch (*fmt) {
case '\0':
putchar('%');
goto end;
case '%':
putchar('%');
break;
case 's':
const char *s = va_arg(args, const char*);
while (*s != '\0') {
putchar(*s);
s++;
}
break;
case 'd':
int num = va_arg(args, int);
unsigned int magnitude = num;
unsigned int power = 1;
if (num < 0) {
putchar('-');
magnitude = -magnitude;
}
while ((magnitude / power) > 9) {
power *= 10;
}
while (power > 0) {
putchar('0' + (magnitude / power));
magnitude %= power;
power /= 10;
}
break;
case 'x':
unsigned int hex = va_arg(args, unsigned int);
putchar('0');
putchar('x');
for (int i = 7; i >= 0; i--) {
unsigned int nibble = (hex >> (4 * i)) & 0xf;
putchar("0123456789abcdef"[nibble]);
}
break;
}
fmt++; // consume modifier
}
}
end:
va_end(args);
return;
}