feat: some extensions to kernel standard c library. Other minor
improvements and formats
This commit is contained in:
38
include/ctype.h
Normal file
38
include/ctype.h
Normal file
@@ -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
|
||||||
@@ -38,6 +38,8 @@ void setbuf(FILE *, char *);
|
|||||||
|
|
||||||
int vfprintf(FILE *, const char *, va_list);
|
int vfprintf(FILE *, const char *, va_list);
|
||||||
|
|
||||||
|
int vprintf(const char* fmt, va_list args);
|
||||||
|
|
||||||
int printf(const char *fmt, ...);
|
int printf(const char *fmt, ...);
|
||||||
|
|
||||||
int sprintf(char *target, const char *fmt, ...);
|
int sprintf(char *target, const char *fmt, ...);
|
||||||
|
|||||||
@@ -13,12 +13,20 @@ int memset(void *dst, int data, size_t amount);
|
|||||||
|
|
||||||
int strcpy(char *dst, const char *src);
|
int strcpy(char *dst, const char *src);
|
||||||
|
|
||||||
|
int strncpy(char *dst, const char *src, size_t n);
|
||||||
|
|
||||||
size_t strlen(const char *str);
|
size_t strlen(const char *str);
|
||||||
|
|
||||||
const char *strchr(const char *s, char c);
|
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 strcmp(const char *s1, const char *s2);
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, int n);
|
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
|
#endif //NEW_KERNEL_STRING_H
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ gdt_t gdts[num_gdts] = {
|
|||||||
.executable = true,
|
.executable = true,
|
||||||
.read_write = true,
|
.read_write = true,
|
||||||
.privilege = 0,
|
.privilege = 0,
|
||||||
}, { // 0x10 kernel data
|
},
|
||||||
|
{ // 0x10 kernel data
|
||||||
.present = true,
|
.present = true,
|
||||||
.base = 0,
|
.base = 0,
|
||||||
.limit = 0xFFFFFFFF,
|
.limit = 0xFFFFFFFF,
|
||||||
@@ -115,7 +116,8 @@ gdt_t gdts[num_gdts] = {
|
|||||||
.granularity = true,
|
.granularity = true,
|
||||||
.executable = false,
|
.executable = false,
|
||||||
.read_write = true,
|
.read_write = true,
|
||||||
}, { // 0x18 user code
|
},
|
||||||
|
{ // 0x18 user code
|
||||||
.present = true,
|
.present = true,
|
||||||
.base = 0,
|
.base = 0,
|
||||||
.limit = 0xFFFFFFFF,
|
.limit = 0xFFFFFFFF,
|
||||||
@@ -125,7 +127,8 @@ gdt_t gdts[num_gdts] = {
|
|||||||
.granularity = true,
|
.granularity = true,
|
||||||
.executable = true,
|
.executable = true,
|
||||||
.read_write = true,
|
.read_write = true,
|
||||||
}, { // 0x20 user data
|
},
|
||||||
|
{ // 0x20 user data
|
||||||
.present = true,
|
.present = true,
|
||||||
.base = 0,
|
.base = 0,
|
||||||
.limit = 0xFFFFFFFF,
|
.limit = 0xFFFFFFFF,
|
||||||
@@ -135,7 +138,8 @@ gdt_t gdts[num_gdts] = {
|
|||||||
.granularity = true,
|
.granularity = true,
|
||||||
.executable = true,
|
.executable = true,
|
||||||
.read_write = true,
|
.read_write = true,
|
||||||
}, { // 0x28 tss
|
},
|
||||||
|
{ // 0x28 tss
|
||||||
.base = (uint32_t) &tss,
|
.base = (uint32_t) &tss,
|
||||||
.limit = sizeof(tss_t),
|
.limit = sizeof(tss_t),
|
||||||
.present = true,
|
.present = true,
|
||||||
|
|||||||
81
kernel/libc/ctype.c
Normal file
81
kernel/libc/ctype.c
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 25-03-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -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 vasprintf(char *buf, const char *fmt, va_list args) {
|
||||||
uint32_t ptr = 0;
|
uint32_t ptr = 0;
|
||||||
for (int i = 0; i < strlen(fmt); ++i) {
|
for (size_t i = 0; i < strlen(fmt); ++i) {
|
||||||
if (fmt[i] != '%') {
|
if (fmt[i] != '%') {
|
||||||
buf[ptr++] = fmt[i];
|
buf[ptr++] = fmt[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
uint32_t arg_width = 0;
|
uint32_t field_width = 0;
|
||||||
while (fmt[i] >= '0' && fmt[i] <= '9') {
|
uint32_t precision = 0; // todo
|
||||||
arg_width *= 10;
|
bool negative_field_width = false; // todo
|
||||||
arg_width += fmt[i] - '0';
|
if (fmt[i] == '-') {
|
||||||
|
// invert
|
||||||
|
negative_field_width = true;
|
||||||
++i;
|
++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]) {
|
switch (fmt[i]) {
|
||||||
case 's': { // string
|
case 's': { // string
|
||||||
|
uint32_t j = 0;
|
||||||
const char *s_fmt = (char *) va_arg(args, char*);
|
const char *s_fmt = (char *) va_arg(args, char*);
|
||||||
if (s_fmt == NULL) {
|
if (s_fmt == NULL) {
|
||||||
s_fmt = printf_null_str;
|
s_fmt = printf_null_str;
|
||||||
}
|
}
|
||||||
while (*s_fmt) {
|
while (*s_fmt && (precision == 0 || j != precision)) {
|
||||||
buf[ptr++] = *s_fmt++;
|
buf[ptr++] = *s_fmt++;
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -62,18 +85,19 @@ uint32_t vasprintf(char *buf, const char *fmt, va_list args) {
|
|||||||
buf[ptr++] = (char) va_arg(args, int);
|
buf[ptr++] = (char) va_arg(args, int);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
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;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd':
|
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;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
buf[ptr++] = '%';
|
buf[ptr++] = '%';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("FMT '%c' is not supported\n", fmt[i]);
|
vasprintf_unsupported(fmt[i]);
|
||||||
k_panic();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,14 +105,20 @@ uint32_t vasprintf(char *buf, const char *fmt, va_list args) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf(const char *fmt, ...) {
|
int vprintf(const char *fmt, va_list args) {
|
||||||
int result;
|
int result;
|
||||||
char buf[1024] = {-1};
|
char buf[1024] = {-1};
|
||||||
|
result = vasprintf(buf, fmt, args);
|
||||||
|
kprint(buf);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const char *fmt, ...) {
|
||||||
|
int result;
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
result = vasprintf(buf, fmt, args);
|
result = vprintf(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
kprint(buf);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
int memcpy(void *dst, const void *src, size_t amount) {
|
int memcpy(void *dst, const void *src, size_t amount) {
|
||||||
for (size_t i = 0; i < amount; i++) {
|
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);
|
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) {
|
size_t strlen(const char *str) {
|
||||||
int length = 0;
|
int length = 0;
|
||||||
while (str[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) {
|
int strncmp(const char *s1, const char *s2, int n) {
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
if (s1[i] == 0 && s2[i] == 0) {
|
if (s1[i] == 0 && s2[i] == 0) {
|
||||||
@@ -71,3 +87,21 @@ int strncmp(const char *s1, const char *s2, int n) {
|
|||||||
}
|
}
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -126,7 +126,9 @@ void mutex_free(mutex_t *mutex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinlock_t *spinlock_create() {
|
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) {
|
void spinlock_acquire(spinlock_t *spinlock) {
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
// stack smashing protector
|
// stack smashing protector
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if __STDC_HOSTED__
|
#if __STDC_HOSTED__
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <myke/libk/libk.h>
|
#include <myke/libk/libk.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UINT32_MAX == UINTPTR_MAX
|
#if UINT32_MAX == UINTPTR_MAX
|
||||||
|
|||||||
Reference in New Issue
Block a user