From 35616993f874fadfa37c70f008e7acc52c02fe5e Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 23 Oct 2022 12:26:48 +0200 Subject: [PATCH] libc: Add div(), ldiv(), and lldiv() --- libs/libc/include/stdlib.h | 30 +++++++++++++++++++++++++++++ libs/libc/include/sys/mman.h | 2 +- libs/libc/src/stdlib.cpp | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/libs/libc/include/stdlib.h b/libs/libc/include/stdlib.h index 08254063..3504c358 100644 --- a/libs/libc/include/stdlib.h +++ b/libs/libc/include/stdlib.h @@ -10,6 +10,24 @@ #define RAND_MAX INT_MAX +typedef struct +{ + int quot; + int rem; +} div_t; + +typedef struct +{ + long quot; + long rem; +} ldiv_t; + +typedef struct +{ + long long quot; + long long rem; +} lldiv_t; + #ifdef __cplusplus extern "C" { @@ -39,6 +57,9 @@ extern "C" /* Returns an integer (of type unsigned long) parsed from the string str. */ unsigned long strtoul(const char* str, char** endptr, int base); + /* Returns an integer (of type long) parsed from the string str. */ + long strtol(const char* str, char** endptr, int base); + /* Not implemented. */ char* getenv(const char*); @@ -74,6 +95,15 @@ extern "C" /* Returns the absolute value of an integer. */ long long llabs(long long val); + /* Returns the result of dividing a by b. */ + div_t div(int a, int b); + + /* Returns the result of dividing a by b. */ + ldiv_t ldiv(long a, long b); + + /* Returns the result of dividing a by b. */ + lldiv_t lldiv(long long a, long long b); + void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented. #ifdef __cplusplus diff --git a/libs/libc/include/sys/mman.h b/libs/libc/include/sys/mman.h index 93652ba1..054e9c48 100644 --- a/libs/libc/include/sys/mman.h +++ b/libs/libc/include/sys/mman.h @@ -30,7 +30,7 @@ extern "C" * address space. */ int munmap(void* addr, size_t size); - /* Changes the permissions of size bytes of memory at addr according to the prot argument. */ + /* Changes the permissions of size bytes of memory at addr zaccording to the prot argument. */ int mprotect(void* addr, size_t size, int prot); #ifdef __cplusplus diff --git a/libs/libc/src/stdlib.cpp b/libs/libc/src/stdlib.cpp index bbd5bd8b..8b524cc9 100644 --- a/libs/libc/src/stdlib.cpp +++ b/libs/libc/src/stdlib.cpp @@ -24,6 +24,21 @@ template T string_to_integer_type(const char* str) return (neg ? -val : val); } +template static inline Struct common_div(Arg a, Arg b) +{ + Struct result; + result.quot = a / b; + result.rem = a % b; + + if (a >= 0 && result.rem < 0) + { + result.quot++; + result.rem -= b; + } + + return result; +} + extern "C" { __lc_noreturn void abort() @@ -53,6 +68,13 @@ extern "C" return string_to_integer_type(str); } + long strtol(const char* str, char** endptr, int base) + { + if (base != 0 && base != 10) NOT_IMPLEMENTED("strtol with base not in (0,10)"); + if (endptr) NOT_IMPLEMENTED("strtol with non-null endptr"); + return string_to_integer_type(str); + } + char* getenv(const char*) { return NULL; // FIXME: Not implemented :) @@ -79,6 +101,21 @@ extern "C" return __builtin_llabs(val); } + div_t div(int a, int b) + { + return common_div(a, b); + } + + ldiv_t ldiv(long a, long b) + { + return common_div(a, b); + } + + lldiv_t lldiv(long long a, long long b) + { + return common_div(a, b); + } + void qsort(void*, size_t, size_t, int (*)(const void*, const void*)) { NOT_IMPLEMENTED("qsort");