diff options
author | Marvin Borner | 2019-11-22 22:17:54 +0100 |
---|---|---|
committer | Marvin Borner | 2019-11-22 22:17:54 +0100 |
commit | 4b178c0feb4c415be36be0e4c0def8c447ed42af (patch) | |
tree | 694f0226b419ec5b043830e12f96aa5e09c9305f | |
parent | 0ba991750314310a5e53b0d8135aef5b1352b261 (diff) |
Added the most awesome c lib
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | src/mlibc/math.h | 6 | ||||
-rw-r--r-- | src/mlibc/math/pow.c | 9 | ||||
-rw-r--r-- | src/mlibc/stdio.h | 10 | ||||
-rw-r--r-- | src/mlibc/stdio/printf.c | 53 | ||||
-rw-r--r-- | src/mlibc/stdio/writec.c | 5 | ||||
-rw-r--r-- | src/mlibc/stdlib.h | 22 | ||||
-rw-r--r-- | src/mlibc/stdlib/atoi.c | 23 | ||||
-rw-r--r-- | src/mlibc/stdlib/htoa.c | 29 | ||||
-rw-r--r-- | src/mlibc/stdlib/htoi.c | 22 | ||||
-rw-r--r-- | src/mlibc/stdlib/itoa.c | 43 | ||||
-rw-r--r-- | src/mlibc/stdlib/liballoc.c | 446 | ||||
-rw-r--r-- | src/mlibc/stdlib/liballoc.h | 24 | ||||
-rw-r--r-- | src/mlibc/string.h | 22 | ||||
-rw-r--r-- | src/mlibc/string/strcat.c | 9 | ||||
-rw-r--r-- | src/mlibc/string/strcati.c | 7 | ||||
-rw-r--r-- | src/mlibc/string/strcmp.c | 9 | ||||
-rw-r--r-- | src/mlibc/string/strcpy.c | 8 | ||||
-rw-r--r-- | src/mlibc/string/strdisp.c | 10 | ||||
-rw-r--r-- | src/mlibc/string/strdup.c | 9 | ||||
-rw-r--r-- | src/mlibc/string/strinv.c | 12 | ||||
-rw-r--r-- | src/mlibc/string/strlen.c | 7 |
22 files changed, 787 insertions, 2 deletions
@@ -18,7 +18,7 @@ build: clean nasm -f elf ./src/kernel/boot.asm -o ./build/boot.o || exit; \ # Make all C files - find ./src/kernel/ ./src/userspace/ -name \*.c >./build/tmp; \ + find ./src/kernel/ ./src/userspace/ ./src/mlibc/ -name \*.c >./build/tmp; \ while read -r line; do \ stripped=$$(echo "$${line}" | sed -r 's/\//_/g'); \ stripped=$${stripped#??????}; \ @@ -69,7 +69,7 @@ debug: @echo "Starting simulation" @echo "[SERIAL OUTPUT]" @head -c 10485760 /dev/zero > ./build/hdd10M.img - @qemu-system-x86_64 -no-reboot -M accel=kvm:tcg -vga std -serial stdio -rtc base=localtime -d int,in_asm -D qemu.log -m 512M -cdrom ./build/melvix.iso -hda ./build/hdd10M.img + @qemu-system-x86_64 -no-reboot -M accel=kvm:tcg -vga std -serial stdio -rtc base=localtime -d int,in_asm -D qemu.log -m 128M -cdrom ./build/melvix.iso -hda ./build/hdd10M.img @echo "[END OF CONNECTION]" .PHONY: build clean cross test debug
\ No newline at end of file diff --git a/src/mlibc/math.h b/src/mlibc/math.h new file mode 100644 index 0000000..c9abf7d --- /dev/null +++ b/src/mlibc/math.h @@ -0,0 +1,6 @@ +#ifndef MELVIX_MATH_H +#define MELVIX_MATH_H + +int pow(int base, int exp); + +#endif diff --git a/src/mlibc/math/pow.c b/src/mlibc/math/pow.c new file mode 100644 index 0000000..4f040bb --- /dev/null +++ b/src/mlibc/math/pow.c @@ -0,0 +1,9 @@ +int pow(int base, int exp) { + if (exp < 0) return 0; + + if (!exp) return 1; + + int ret = base; + for (int i = 1; i < exp; i++) ret *= base; + return ret; +}
\ No newline at end of file diff --git a/src/mlibc/stdio.h b/src/mlibc/stdio.h new file mode 100644 index 0000000..ae377a2 --- /dev/null +++ b/src/mlibc/stdio.h @@ -0,0 +1,10 @@ +#ifndef MELVIX_STDIO_H +#define MELVIX_STDIO_H + +// TODO: Input methods + +void writec(char c); + +void printf(const char *format, ...); + +#endif diff --git a/src/mlibc/stdio/printf.c b/src/mlibc/stdio/printf.c new file mode 100644 index 0000000..11516cf --- /dev/null +++ b/src/mlibc/stdio/printf.c @@ -0,0 +1,53 @@ +#include <stdarg.h> +#include <stdint.h> +#include <mlibc/stdio.h> +#include <mlibc/string.h> +#include <mlibc/stdlib.h> + +void __writes(const char *data) { + for (size_t i = 0; i < strlen(data); i++) writec(data[i]); +} + +void printf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + + uint8_t readyToFormat = 0; + + char buff = 0; + + for (; *fmt; fmt++) { + if (readyToFormat) { + if (*fmt == '%') { + writec('%'); + readyToFormat = 0; + continue; + } + + buff = *fmt; + if (buff == 's') { + const char *str = va_arg(args, const char*); + __writes(str); + readyToFormat = 0; + } else if (buff == 'x') { + char *p = htoa((uint32_t) va_arg(args, int)); + __writes(p); + kfree(p); + readyToFormat = 0; + } else if (buff == 'd') { + char *p = itoa(va_arg(args, int)); + __writes(p); + kfree(p); + readyToFormat = 0; + } else if (buff == 'c') { + writec((char) va_arg(args, int)); + readyToFormat = 0; + } + } else { + if (*fmt == '%') + readyToFormat = 1; + else + writec(*fmt); + } + } +}
\ No newline at end of file diff --git a/src/mlibc/stdio/writec.c b/src/mlibc/stdio/writec.c new file mode 100644 index 0000000..60f69e8 --- /dev/null +++ b/src/mlibc/stdio/writec.c @@ -0,0 +1,5 @@ +#include <kernel/graphics/vesa.h> + +void writec(char c) { + vesa_draw_char(c); +}
\ No newline at end of file diff --git a/src/mlibc/stdlib.h b/src/mlibc/stdlib.h new file mode 100644 index 0000000..7ae9c5a --- /dev/null +++ b/src/mlibc/stdlib.h @@ -0,0 +1,22 @@ +#ifndef MELVIX_STDLIB_H +#define MELVIX_STDLIB_H + +#include <stdint.h> + +#ifndef MELVIX_ALLOC_H +#include <mlibc/stdlib/liballoc.h> +#endif + +#ifndef MELVIX_STRING_H +#include <mlibc/string.h> +#endif + +char *itoa(int n); + +int atoi(char *str); + +char *htoa(uint32_t n); + +int htoi(char *str); + +#endif diff --git a/src/mlibc/stdlib/atoi.c b/src/mlibc/stdlib/atoi.c new file mode 100644 index 0000000..34f9991 --- /dev/null +++ b/src/mlibc/stdlib/atoi.c @@ -0,0 +1,23 @@ +#include <mlibc/math.h> +#include <stddef.h> +#include <stdint.h> +#include <mlibc/string.h> + +int atoi(char *str) { + size_t s_str = strlen(str); + if (!s_str) return 0; + + uint8_t negative = 0; + if (str[0] == '-') negative = 1; + + size_t i = 0; + if (negative) i++; + + int ret = 0; + for (; i < s_str; i++) { + ret += (str[i] - '0') * pow(10, (s_str - i) - 1); + } + + if (negative) ret *= -1; + return ret; +}
\ No newline at end of file diff --git a/src/mlibc/stdlib/htoa.c b/src/mlibc/stdlib/htoa.c new file mode 100644 index 0000000..5290c74 --- /dev/null +++ b/src/mlibc/stdlib/htoa.c @@ -0,0 +1,29 @@ +#include <stdint.h> +#include <mlibc/string.h> +#include <mlibc/stdlib.h> + +static const char __HTOA_TABLE[] = "0123456789ABCDEF"; + +char *htoa(uint32_t n) { + char *ret = kmalloc(10); + + int i = 0; + while (n) { + ret[i++] = __HTOA_TABLE[n & 0xF]; + n >>= 4; + } + + if (!i) { + ret[0] = '0'; + i++; + } + + for (; i <= 9; i++) ret[i] = 0; + + char *aux = strdup(ret); + kfree(ret); + ret = aux; + + strinv(ret); + return ret; +}
\ No newline at end of file diff --git a/src/mlibc/stdlib/htoi.c b/src/mlibc/stdlib/htoi.c new file mode 100644 index 0000000..73a583b --- /dev/null +++ b/src/mlibc/stdlib/htoi.c @@ -0,0 +1,22 @@ +#include <mlibc/math.h> +#include <stddef.h> +#include <mlibc/string.h> + +int htoi(char *str) { + size_t s_str = strlen(str); + + size_t i = 0; + int ret = 0; + for (; i < s_str; i++) { + char c = str[i]; + int aux = 0; + if (c >= '0' && c <= '9') + aux = c - '0'; + else if (c >= 'A' && c <= 'F') + aux = (c - 'A') + 10; + + ret += aux * pow(16, (s_str - i) - 1); + } + + return ret; +}
\ No newline at end of file diff --git a/src/mlibc/stdlib/itoa.c b/src/mlibc/stdlib/itoa.c new file mode 100644 index 0000000..e9c40c1 --- /dev/null +++ b/src/mlibc/stdlib/itoa.c @@ -0,0 +1,43 @@ +#include <mlibc/math.h> +#include <stdint.h> +#include <mlibc/string.h> +#include <mlibc/stdlib.h> + +static const char __ITOA_TABLE[] = "0123456789"; + +char *itoa(int n) { + // Special cases + if (!n) { + char *ret = kmalloc(2); + ret[0] = '0'; + ret[1] = 0; + return ret; + } + uint8_t negative = (uint8_t) (n < 0); + if (negative) n *= -1; + + // First get the number of digits. + int sz; + for (sz = 0; n % pow(10, sz) != n; sz++) {} + + char *ret = kmalloc(sz + 1); + + // Iterate all digits again. + for (int i = 0; i < sz; i++) { + int digit = (n % pow(10, i + 1)) / pow(10, i); + ret[i] = __ITOA_TABLE[digit]; + } + ret[sz] = 0; + + if (negative) { + char *aux = kmalloc(sz + 2); + strcpy(aux, ret); + aux[sz] = '-'; + aux[sz + 1] = 0; + kfree(ret); + ret = aux; + } + + strinv(ret); + return ret; +}
\ No newline at end of file diff --git a/src/mlibc/stdlib/liballoc.c b/src/mlibc/stdlib/liballoc.c new file mode 100644 index 0000000..f4015f2 --- /dev/null +++ b/src/mlibc/stdlib/liballoc.c @@ -0,0 +1,446 @@ +#include <stddef.h> +#include <stdint.h> +#include <kernel/paging/paging.h> +#include <mlibc/stdlib/liballoc.h> + +int liballoc_lock() { + // asm volatile ("cli"); + return 0; +} + +int liballoc_unlock() { + // asm volatile ("sti"); + return 0; +} + +void *liballoc_alloc(size_t p) { + uint32_t ptr = paging_alloc_pages((uint32_t) p); + return (void *) ptr; +} + +int liballoc_free(void *ptr, size_t p) { + paging_set_free((uint32_t) ptr, (uint32_t) p); + return 0; +} + +#define ALIGNMENT 16ul +#define ALIGN_TYPE char +#define ALIGN_INFO sizeof(ALIGN_TYPE) * 16 +#define USE_CASE1 +#define USE_CASE2 +#define USE_CASE3 +#define USE_CASE4 +#define USE_CASE5 + +#define ALIGN(ptr) \ + if ( ALIGNMENT > 1 ) { \ + uintptr_t diff; \ + ptr = (void*) ((uintptr_t) ptr + ALIGN_INFO); \ + diff = (uintptr_t) ptr & (ALIGNMENT - 1); \ + if (diff != 0) { \ + diff = ALIGNMENT - diff; \ + ptr = (void*) ((uintptr_t) ptr + diff); \ + } \ + *((ALIGN_TYPE*) ((uintptr_t) ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \ + } + +#define UNALIGN(ptr) \ + if (ALIGNMENT > 1) { \ + uintptr_t diff = *((ALIGN_TYPE*) ((uintptr_t) ptr - ALIGN_INFO)); \ + if (diff < (ALIGNMENT + ALIGN_INFO)) { \ + ptr = (void*) ((uintptr_t) ptr - diff); \ + } \ + } + +#define LIBALLOC_MAGIC 0xc001c0de +#define LIBALLOC_DEAD 0xdeaddead + +struct liballoc_major { + struct liballoc_major *prev; + struct liballoc_major *next; + unsigned int pages; + unsigned int size; + unsigned int usage; + struct liballoc_minor *first; +}; + +struct liballoc_minor { + struct liballoc_minor *prev; + struct liballoc_minor *next; + struct liballoc_major *block; + unsigned int magic; + unsigned int size; + unsigned int req_size; +}; + +static struct liballoc_major *l_memRoot = NULL; +static struct liballoc_major *l_bestBet = NULL; + +static unsigned int l_pageSize = 4096; +static unsigned int l_pageCount = 16; +static unsigned long long l_allocated = 0; +static unsigned long long l_inuse = 0; + +static long long l_warningCount = 0; +static long long l_errorCount = 0; +static long long l_possibleOverruns = 0; + +static void *liballoc_memset(void *s, int c, size_t n) { + unsigned int i; + for (i = 0; i < n; i++) + ((char *) s)[i] = c; + + return s; +} + +static void *liballoc_memcpy(void *s1, const void *s2, size_t n) { + char *cdest; + char *csrc; + unsigned int *ldest = (unsigned int *) s1; + unsigned int *lsrc = (unsigned int *) s2; + + while (n >= sizeof(unsigned int)) { + *ldest++ = *lsrc++; + n -= sizeof(unsigned int); + } + + cdest = (char *) ldest; + csrc = (char *) lsrc; + + while (n > 0) { + *cdest++ = *csrc++; + n -= 1; + } + return s1; +} + +static struct liballoc_major *allocate_new_page(unsigned int size) { + unsigned int st; + struct liballoc_major *maj; + + st = size + sizeof(struct liballoc_major); + st += sizeof(struct liballoc_minor); + + if ((st % l_pageSize) == 0) + st = st / (l_pageSize); + else + st = st / (l_pageSize) + 1; + + if (st < l_pageCount) st = l_pageCount; + + maj = (struct liballoc_major *) liballoc_alloc(st); + + if (maj == NULL) { + l_warningCount += 1; + return NULL; + } + + maj->prev = NULL; + maj->next = NULL; + maj->pages = st; + maj->size = st * l_pageSize; + maj->usage = sizeof(struct liballoc_major); + maj->first = NULL; + + l_allocated += maj->size; + + return maj; +} + +void *PREFIX(malloc)(size_t req_size) { + int startedBet = 0; + unsigned long long bestSize = 0; + void *p = NULL; + uintptr_t diff; + struct liballoc_major *maj; + struct liballoc_minor *min; + struct liballoc_minor *new_min; + unsigned long size = req_size; + + if (ALIGNMENT > 1) { + size += ALIGNMENT + ALIGN_INFO; + } + + liballoc_lock(); + + if (size == 0) { + l_warningCount += 1; + liballoc_unlock(); + return PREFIX(malloc)(1); + } + + if (l_memRoot == NULL) { + l_memRoot = allocate_new_page(size); + if (l_memRoot == NULL) { + liballoc_unlock(); + return NULL; + } + } + + maj = l_memRoot; + startedBet = 0; + + if (l_bestBet != NULL) { + bestSize = l_bestBet->size - l_bestBet->usage; + + if (bestSize > (size + sizeof(struct liballoc_minor))) { + maj = l_bestBet; + startedBet = 1; + } + } + + while (maj != NULL) { + diff = maj->size - maj->usage; + if (bestSize < diff) { + l_bestBet = maj; + bestSize = diff; + } + +#ifdef USE_CASE1 + if (diff < (size + sizeof(struct liballoc_minor))) { + if (maj->next != NULL) { + maj = maj->next; + continue; + } + + if (startedBet == 1) { + maj = l_memRoot; + startedBet = 0; + continue; + } + + maj->next = allocate_new_page(size); + if (maj->next == NULL) break; + maj->next->prev = maj; + maj = maj->next; + } +#endif + +#ifdef USE_CASE2 + if (maj->first == NULL) { + maj->first = (struct liballoc_minor *) ((uintptr_t) maj + sizeof(struct liballoc_major)); + + maj->first->magic = LIBALLOC_MAGIC; + maj->first->prev = NULL; + maj->first->next = NULL; + maj->first->block = maj; + maj->first->size = size; + maj->first->req_size = req_size; + maj->usage += size + sizeof(struct liballoc_minor); + l_inuse += size; + p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor)); + ALIGN(p); + liballoc_unlock(); + return p; + } +#endif + +#ifdef USE_CASE3 + diff = (uintptr_t) (maj->first); + diff -= (uintptr_t) maj; + diff -= sizeof(struct liballoc_major); + + if (diff >= (size + sizeof(struct liballoc_minor))) { + maj->first->prev = (struct liballoc_minor *) ((uintptr_t) maj + sizeof(struct liballoc_major)); + maj->first->prev->next = maj->first; + maj->first = maj->first->prev; + maj->first->magic = LIBALLOC_MAGIC; + maj->first->prev = NULL; + maj->first->block = maj; + maj->first->size = size; + maj->first->req_size = req_size; + maj->usage += size + sizeof(struct liballoc_minor); + l_inuse += size; + p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor)); + ALIGN(p); + liballoc_unlock(); + return p; + } +#endif + +#ifdef USE_CASE4 + min = maj->first; + + while (min != NULL) { + if (min->next == NULL) { + diff = (uintptr_t) (maj) + maj->size; + diff -= (uintptr_t) min; + diff -= sizeof(struct liballoc_minor); + diff -= min->size; + if (diff >= (size + sizeof(struct liballoc_minor))) { + min->next = (struct liballoc_minor *) ((uintptr_t) min + sizeof(struct liballoc_minor) + min->size); + min->next->prev = min; + min = min->next; + min->next = NULL; + min->magic = LIBALLOC_MAGIC; + min->block = maj; + min->size = size; + min->req_size = req_size; + maj->usage += size + sizeof(struct liballoc_minor); + l_inuse += size; + p = (void *) ((uintptr_t) min + sizeof(struct liballoc_minor)); + ALIGN(p); + liballoc_unlock(); + return p; + } + } + + if (min->next != NULL) { + diff = (uintptr_t) (min->next); + diff -= (uintptr_t) min; + diff -= sizeof(struct liballoc_minor); + diff -= min->size; + + if (diff >= (size + sizeof(struct liballoc_minor))) { + new_min = (struct liballoc_minor *) ((uintptr_t) min + sizeof(struct liballoc_minor) + min->size); + new_min->magic = LIBALLOC_MAGIC; + new_min->next = min->next; + new_min->prev = min; + new_min->size = size; + new_min->req_size = req_size; + new_min->block = maj; + min->next->prev = new_min; + min->next = new_min; + maj->usage += size + sizeof(struct liballoc_minor); + l_inuse += size; + p = (void *) ((uintptr_t) new_min + sizeof(struct liballoc_minor)); + ALIGN(p); + liballoc_unlock(); + return p; + } + } + + min = min->next; + } +#endif + +#ifdef USE_CASE5 + if (maj->next == NULL) { + if (startedBet == 1) { + maj = l_memRoot; + startedBet = 0; + continue; + } + maj->next = allocate_new_page(size); + if (maj->next == NULL) break; + maj->next->prev = maj; + } +#endif + maj = maj->next; + } + + liballoc_unlock(); + + return NULL; +} + +void PREFIX(free)(void *ptr) { + struct liballoc_minor *min; + struct liballoc_major *maj; + + if (ptr == NULL) { + l_warningCount += 1; + return; + } + + UNALIGN(ptr); + liballoc_lock(); + + min = (struct liballoc_minor *) ((uintptr_t) ptr - sizeof(struct liballoc_minor)); + + if (min->magic != LIBALLOC_MAGIC) { + l_errorCount += 1; + + if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || + ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || + ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { + l_possibleOverruns += 1; + } + + liballoc_unlock(); + return; + } + + maj = min->block; + l_inuse -= min->size; + maj->usage -= (min->size + sizeof(struct liballoc_minor)); + min->magic = LIBALLOC_DEAD; + + if (min->next != NULL) min->next->prev = min->prev; + if (min->prev != NULL) min->prev->next = min->next; + if (min->prev == NULL) maj->first = min->next; + if (maj->first == NULL) { + if (l_memRoot == maj) l_memRoot = maj->next; + if (l_bestBet == maj) l_bestBet = NULL; + if (maj->prev != NULL) maj->prev->next = maj->next; + if (maj->next != NULL) maj->next->prev = maj->prev; + l_allocated -= maj->size; + liballoc_free(maj, maj->pages); + } else { + if (l_bestBet != NULL) { + int bestSize = l_bestBet->size - l_bestBet->usage; + int majSize = maj->size - maj->usage; + if (majSize > bestSize) l_bestBet = maj; + } + } + liballoc_unlock(); +} + +void *PREFIX(calloc)(size_t nobj, size_t size) { + int real_size; + void *p; + + real_size = nobj * size; + + p = PREFIX(malloc)(real_size); + + liballoc_memset(p, 0, real_size); + + return p; +} + +void *PREFIX(realloc)(void *p, size_t size) { + void *ptr; + struct liballoc_minor *min; + unsigned int real_size; + + if (size == 0) { + PREFIX(free)(p); + return NULL; + } + + if (p == NULL) return PREFIX(malloc)(size); + + ptr = p; + UNALIGN(ptr); + liballoc_lock(); + min = (struct liballoc_minor *) ((uintptr_t) ptr - sizeof(struct liballoc_minor)); + + if (min->magic != LIBALLOC_MAGIC) { + l_errorCount += 1; + if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || + ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || + ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { + l_possibleOverruns += 1; + } + + liballoc_unlock(); + return NULL; + } + + real_size = min->req_size; + + if (real_size >= size) { + min->req_size = size; + liballoc_unlock(); + return p; + } + + liballoc_unlock(); + + ptr = PREFIX(malloc)(size); + liballoc_memcpy(ptr, p, real_size); + PREFIX(free)(p); + + return ptr; +} diff --git a/src/mlibc/stdlib/liballoc.h b/src/mlibc/stdlib/liballoc.h new file mode 100644 index 0000000..6ed9efb --- /dev/null +++ b/src/mlibc/stdlib/liballoc.h @@ -0,0 +1,24 @@ +#ifndef MELVIX_ALLOC_H +#define MELVIX_ALLOC_H + +#include <stddef.h> + +#define PREFIX(func) k ## func + +int liballoc_lock(); + +int liballoc_unlock(); + +void *liballoc_alloc(size_t); + +int liballoc_free(void *, size_t); + +void *PREFIX(malloc)(size_t); + +void *PREFIX(realloc)(void *, size_t); + +void *PREFIX(calloc)(size_t, size_t); + +void PREFIX(free)(void *); + +#endif diff --git a/src/mlibc/string.h b/src/mlibc/string.h new file mode 100644 index 0000000..fe925cb --- /dev/null +++ b/src/mlibc/string.h @@ -0,0 +1,22 @@ +#ifndef MELVIX_STRING_H +#define MELVIX_STRING_H + +#include <stddef.h> + +size_t strlen(const char *str); + +void strcpy(char *dest, const char *orig); + +void strdisp(char *str, int n); + +void strcat(char *dest, const char *orig); + +void strcati(char *dest, const char *orig); + +char strcmp(const char *a, const char *b); + +char *strdup(const char *orig); + +void strinv(char *str); + +#endif diff --git a/src/mlibc/string/strcat.c b/src/mlibc/string/strcat.c new file mode 100644 index 0000000..3cc56f1 --- /dev/null +++ b/src/mlibc/string/strcat.c @@ -0,0 +1,9 @@ +#include <mlibc/string.h> + +void strcat(char *dest, const char *orig) { + size_t s_dest = strlen(dest); + size_t s_orig = strlen(orig); + + for (size_t i = 0; i < s_orig; i++) dest[s_dest + i] = orig[i]; + dest[s_dest + s_orig] = 0; +}
\ No newline at end of file diff --git a/src/mlibc/string/strcati.c b/src/mlibc/string/strcati.c new file mode 100644 index 0000000..d925eb7 --- /dev/null +++ b/src/mlibc/string/strcati.c @@ -0,0 +1,7 @@ +#include <mlibc/string.h> + +void strcati(char *dest, const char *orig) { + size_t s_orig = strlen(orig); + strdisp(dest, (int) s_orig); + for (size_t i = 0; i < s_orig; i++) dest[i] = orig[i]; +}
\ No newline at end of file diff --git a/src/mlibc/string/strcmp.c b/src/mlibc/string/strcmp.c new file mode 100644 index 0000000..cc719da --- /dev/null +++ b/src/mlibc/string/strcmp.c @@ -0,0 +1,9 @@ +#include <mlibc/string.h> + +char strcmp(const char *a, const char *b) { + if (strlen(a) != strlen(b)) return 1; + + for (size_t i = 0; i < strlen(a); i++) if (a[i] != b[i]) return 1; + + return 0; +}
\ No newline at end of file diff --git a/src/mlibc/string/strcpy.c b/src/mlibc/string/strcpy.c new file mode 100644 index 0000000..5a1ff4e --- /dev/null +++ b/src/mlibc/string/strcpy.c @@ -0,0 +1,8 @@ +#include <mlibc/string.h> + +void strcpy(char *dest, const char *orig) { + size_t s_orig = strlen(orig); + + for (size_t i = 0; i < s_orig; i++) dest[i] = orig[i]; + dest[s_orig] = 0; +}
\ No newline at end of file diff --git a/src/mlibc/string/strdisp.c b/src/mlibc/string/strdisp.c new file mode 100644 index 0000000..6feb4ca --- /dev/null +++ b/src/mlibc/string/strdisp.c @@ -0,0 +1,10 @@ +#include <mlibc/string.h> + +void strdisponce(char *str) { + for (size_t i = sizeof(str) + 2; i > 0; i--) str[i] = str[i - 1]; + str[0] = 0; +} + +void strdisp(char *str, int n) { + for (int i = 0; i < n; i++) strdisponce(str); +}
\ No newline at end of file diff --git a/src/mlibc/string/strdup.c b/src/mlibc/string/strdup.c new file mode 100644 index 0000000..0cddd79 --- /dev/null +++ b/src/mlibc/string/strdup.c @@ -0,0 +1,9 @@ +#include <mlibc/string.h> +#include <mlibc/stdlib.h> + +char *strdup(const char *orig) { + size_t s_orig = strlen(orig); + char *ret = kmalloc(s_orig + 1); + strcpy(ret, orig); + return ret; +}
\ No newline at end of file diff --git a/src/mlibc/string/strinv.c b/src/mlibc/string/strinv.c new file mode 100644 index 0000000..c6dd7fd --- /dev/null +++ b/src/mlibc/string/strinv.c @@ -0,0 +1,12 @@ +#include <mlibc/string.h> + +void strinv(char *str) { + size_t s_str = strlen(str); + + int iterations = (int) s_str / 2; + for (int i = 0; i < iterations; i++) { + char aux = str[i]; + str[i] = str[(s_str - i) - 1]; + str[(s_str - i) - 1] = aux; + } +}
\ No newline at end of file diff --git a/src/mlibc/string/strlen.c b/src/mlibc/string/strlen.c new file mode 100644 index 0000000..1143683 --- /dev/null +++ b/src/mlibc/string/strlen.c @@ -0,0 +1,7 @@ +#include <mlibc/string.h> + +size_t strlen(const char *str) { + size_t len = 0; + while (str[len]) len++; + return len; +}
\ No newline at end of file |