diff --git a/include/ctype.h b/include/ctype.h new file mode 100644 index 0000000..e85269d --- /dev/null +++ b/include/ctype.h @@ -0,0 +1,38 @@ +// +// Created by rick on 25-03-21. +// + +#ifndef NEW_KERNEL_CTYPE_H +#define NEW_KERNEL_CTYPE_H + +inline int tolower(int c); + +int toupper(int c); + +int isalnum(int c); + +int isalpha(int c); + +int iscntrl(int c); + +int isdigit(int c); + +int isgraph(int c); + +int islower(int c); + +int isprint(int c); + +int ispunct(int c); + +int isspace(int c); + +int isupper(int c); + +int isxdigit(int c); + +int isascii(int c); + +int isblank(int c); + +#endif //NEW_KERNEL_CTYPE_H diff --git a/include/stdio.h b/include/stdio.h index 01e5bda..1a24f9f 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -38,6 +38,8 @@ void setbuf(FILE *, char *); int vfprintf(FILE *, const char *, va_list); +int vprintf(const char* fmt, va_list args); + int printf(const char *fmt, ...); int sprintf(char *target, const char *fmt, ...); diff --git a/include/string.h b/include/string.h index 745fd7a..12aefd2 100644 --- a/include/string.h +++ b/include/string.h @@ -13,12 +13,20 @@ int memset(void *dst, int data, size_t amount); int strcpy(char *dst, const char *src); +int strncpy(char *dst, const char *src, size_t n); + size_t strlen(const char *str); const char *strchr(const char *s, char c); +int memcmp(const void *s1, const void *s2, size_t n); + int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, int n); +char *strcat(char *dest, const char *src); + +char *strncat(char *dest, const char *src, size_t n); + #endif //NEW_KERNEL_STRING_H diff --git a/kernel/command.c b/kernel/command.c index c66dd57..ea5c52d 100644 --- a/kernel/command.c +++ b/kernel/command.c @@ -72,7 +72,7 @@ cmd_handler cmd_handlers[] = { {NULL, NULL}, }; -void smash(const char* args) { +void smash(const char *args) { char data[16]; memset(data, 'A', 32); } diff --git a/kernel/cpu/gdt.c b/kernel/cpu/gdt.c index 164af63..a584997 100644 --- a/kernel/cpu/gdt.c +++ b/kernel/cpu/gdt.c @@ -106,7 +106,8 @@ gdt_t gdts[num_gdts] = { .executable = true, .read_write = true, .privilege = 0, - }, { // 0x10 kernel data + }, + { // 0x10 kernel data .present = true, .base = 0, .limit = 0xFFFFFFFF, @@ -115,7 +116,8 @@ gdt_t gdts[num_gdts] = { .granularity = true, .executable = false, .read_write = true, - }, { // 0x18 user code + }, + { // 0x18 user code .present = true, .base = 0, .limit = 0xFFFFFFFF, @@ -125,7 +127,8 @@ gdt_t gdts[num_gdts] = { .granularity = true, .executable = true, .read_write = true, - }, { // 0x20 user data + }, + { // 0x20 user data .present = true, .base = 0, .limit = 0xFFFFFFFF, @@ -135,7 +138,8 @@ gdt_t gdts[num_gdts] = { .granularity = true, .executable = true, .read_write = true, - }, { // 0x28 tss + }, + { // 0x28 tss .base = (uint32_t) &tss, .limit = sizeof(tss_t), .present = true, diff --git a/kernel/libc/ctype.c b/kernel/libc/ctype.c new file mode 100644 index 0000000..9eacac2 --- /dev/null +++ b/kernel/libc/ctype.c @@ -0,0 +1,81 @@ +// +// Created by rick on 25-03-21. +// + +#include + +int tolower(int c) { + if (c > 0xFF) { + // uh own + return c; + } + if (c >= 'A' && c <= 'Z') { + return c - 'A' + 'a'; + } + return c; +} + +int toupper(int c) { + if (c > 0xFF) { + // uh own + return c; + } + if (c >= 'a' && c <= 'z') { + return c - 'a' + 'A'; + } + return c; +} + +int isascii(int c) { + return c <= 0x7F; +} + +int isblank(int c) { + return c == ' ' || c == '\t'; +} + +int iscntrl(int c) { + return c <= 0x1F || c == 0x7F; +} + +int isdigit(int c) { + return c >= '0' && c <= '9'; +} + +int isgraph(int c) { + return c > ' ' && c < 0x7F; +} + +int islower(int c) { + return c >= 'a' && c <= 'z'; +} + +int isprint(int c) { + return c >= ' ' && c < 0x7F; +} + +int ispunct(int c) { + return (c > ' ' && c <= '@') + || (c >= '[' && c <= '`') + || (c >= '{' && c <= '~'); +} + +int isspace(int c) { + return c == ' ' || (c >= '\t' && c <= '\r'); +} + +int isupper(int c) { + return c >= 'A' && c <= 'Z'; +} + +int isxdigit(int c) { + return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +int isalpha(int c) { + return isupper(c) | islower(c); +} + +int isalnum(int c) { + return isalpha(c) || isdigit(c); +} diff --git a/kernel/libc/kprintf.c b/kernel/libc/kprintf.c index 35d2116..da942d9 100644 --- a/kernel/libc/kprintf.c +++ b/kernel/libc/kprintf.c @@ -33,28 +33,51 @@ void print_int(uint32_t value, uint32_t width, char *buf, uint32_t *ptr, uint8_t } } +void vasprintf_unsupported(char c) { + char *msg = "FMT '%x' is not supported\n"; + msg[6] = c; + k_panics(msg); +} + uint32_t vasprintf(char *buf, const char *fmt, va_list args) { uint32_t ptr = 0; - for (int i = 0; i < strlen(fmt); ++i) { + for (size_t i = 0; i < strlen(fmt); ++i) { if (fmt[i] != '%') { buf[ptr++] = fmt[i]; continue; } ++i; - uint32_t arg_width = 0; - while (fmt[i] >= '0' && fmt[i] <= '9') { - arg_width *= 10; - arg_width += fmt[i] - '0'; + uint32_t field_width = 0; + uint32_t precision = 0; // todo + bool negative_field_width = false; // todo + if (fmt[i] == '-') { + // invert + negative_field_width = true; ++i; } + while (fmt[i] >= '0' && fmt[i] <= '9') { + field_width *= 10; + field_width += fmt[i] - '0'; + ++i; + } + if (fmt[i] == '.') { + ++i; + while (fmt[i] >= '0' && fmt[i] <= '9') { + precision *= 10; + precision += fmt[i] - '0'; + ++i; + } + } switch (fmt[i]) { case 's': { // string + uint32_t j = 0; const char *s_fmt = (char *) va_arg(args, char*); if (s_fmt == NULL) { s_fmt = printf_null_str; } - while (*s_fmt) { + while (*s_fmt && (precision == 0 || j != precision)) { buf[ptr++] = *s_fmt++; + j++; } break; } @@ -62,18 +85,19 @@ uint32_t vasprintf(char *buf, const char *fmt, va_list args) { buf[ptr++] = (char) va_arg(args, int); break; case 'x': - print_int((uint32_t) va_arg(args, uint32_t), arg_width, buf, &ptr, 16); + case 'X': // todo capitalize + print_int((uint32_t) va_arg(args, uint32_t), field_width, buf, &ptr, 16); break; case 'i': case 'd': - print_int((uint32_t) va_arg(args, uint32_t), arg_width, buf, &ptr, 10); + case 'u': + print_int((uint32_t) va_arg(args, uint32_t), field_width, buf, &ptr, 10); break; case '%': buf[ptr++] = '%'; break; default: - printf("FMT '%c' is not supported\n", fmt[i]); - k_panic(); + vasprintf_unsupported(fmt[i]); break; } } @@ -81,14 +105,20 @@ uint32_t vasprintf(char *buf, const char *fmt, va_list args) { return ptr; } -int printf(const char *fmt, ...) { +int vprintf(const char *fmt, va_list args) { int result; char buf[1024] = {-1}; + result = vasprintf(buf, fmt, args); + kprint(buf); + return result; +} + +int printf(const char *fmt, ...) { + int result; va_list args; va_start(args, fmt); - result = vasprintf(buf, fmt, args); + result = vprintf(fmt, args); va_end(args); - kprint(buf); return result; } diff --git a/kernel/libc/string.c b/kernel/libc/string.c index a97b54c..365012b 100644 --- a/kernel/libc/string.c +++ b/kernel/libc/string.c @@ -4,6 +4,7 @@ #include #include +#include int memcpy(void *dst, const void *src, size_t amount) { for (size_t i = 0; i < amount; i++) { @@ -24,6 +25,10 @@ int strcpy(char *dst, const char *src) { return memcpy(dst, src, strlen(src) + 1); } +int strncpy(char *dst, const char *src, size_t n) { + return memcpy(dst, src, MIN(strlen(src), n) + 1); +} + size_t strlen(const char *str) { int length = 0; while (str[length] != 0) { @@ -51,6 +56,17 @@ const char *strchr(const char *s, char c) { } } +int memcmp(const void *s1, const void *s2, size_t n) { + uint8_t a, b; + for (size_t i = 0; i < n; ++i) { + a = ((uint8_t *) s1)[i]; + b = ((uint8_t *) s2)[i]; + if (a > b) return 1; + if (b < a) return -1; + } + return 0; +} + int strncmp(const char *s1, const char *s2, int n) { for (int i = 0; i < n; ++i) { if (s1[i] == 0 && s2[i] == 0) { @@ -71,3 +87,21 @@ int strncmp(const char *s1, const char *s2, int n) { } return 0; } + +char *strcat(char *dest, const char *src) { + size_t count = strlen(src); + return strncat(dest, src, count); +} + +char *strncat(char *dest, const char *src, size_t n) { + size_t start = strlen(dest); + for (size_t index = 0; index < n; index++) { + char val = src[index]; + dest[start + index] = val; + if (val == 0) { + dest[start + index] = 0; + break; + } + } + return dest; +} diff --git a/kernel/tasks/locking.c b/kernel/tasks/locking.c index cb74032..a763020 100644 --- a/kernel/tasks/locking.c +++ b/kernel/tasks/locking.c @@ -126,7 +126,9 @@ void mutex_free(mutex_t *mutex) { } spinlock_t *spinlock_create() { - return malloc(sizeof(spinlock_t)); + spinlock_t *lock = malloc(sizeof(spinlock_t)); + lock->lock = false; + return lock; } void spinlock_acquire(spinlock_t *spinlock) { diff --git a/kernel/util/ssp.c b/kernel/util/ssp.c index 7fe1cd0..d2cf94a 100644 --- a/kernel/util/ssp.c +++ b/kernel/util/ssp.c @@ -4,10 +4,13 @@ // stack smashing protector #include + #if __STDC_HOSTED__ #include #else + #include + #endif #if UINT32_MAX == UINTPTR_MAX