diff options
author | Marvin Borner | 2021-05-24 18:50:55 +0200 |
---|---|---|
committer | Marvin Borner | 2021-05-24 19:05:59 +0200 |
commit | 91ba8d02037cc27c7b44f1bfd492c42ccd0af042 (patch) | |
tree | 4006f8b37c2e70ddceb6fbb70dd2c690c5cf6035 | |
parent | a0a1b1318dc886c72eaf60792dbb40f1ea3eeb97 (diff) |
Added more tests and fixed dumb bugs
typical
-rw-r--r-- | apps/test/main.c | 280 | ||||
-rw-r--r-- | libs/libc/conv.c | 10 | ||||
-rw-r--r-- | libs/libc/inc/conv.h | 4 | ||||
-rw-r--r-- | libs/libc/inc/def.h | 28 | ||||
-rw-r--r-- | libs/libc/inc/list.h | 2 | ||||
-rw-r--r-- | libs/libc/inc/math.h | 2 | ||||
-rw-r--r-- | libs/libc/inc/mem.h | 2 | ||||
-rw-r--r-- | libs/libc/inc/str.h | 4 | ||||
-rw-r--r-- | libs/libc/list.c | 2 | ||||
-rw-r--r-- | libs/libc/math.c | 11 | ||||
-rw-r--r-- | libs/libc/mem.c | 20 | ||||
-rw-r--r-- | libs/libc/print.c | 2 | ||||
-rw-r--r-- | libs/libc/str.c | 44 |
13 files changed, 354 insertions, 57 deletions
diff --git a/apps/test/main.c b/apps/test/main.c index 29ec26e..5407ee6 100644 --- a/apps/test/main.c +++ b/apps/test/main.c @@ -1,24 +1,29 @@ // MIT License, Copyright (c) 2020 Marvin Borner +// TODO: Add GUI and sys tests #include "test.h" #include <conv.h> #include <crypto.h> +#include <list.h> #include <math.h> #include <mem.h> #include <print.h> +#include <stack.h> #include <str.h> #include <sys.h> -#define a_mag 0x55 -#define b_mag 0x42 - #define TEST(name) static void test_##name(void) -#define CHECK(exp) pass_or_fail(__FILE__, __LINE__, __func__, #exp, "1", exp); +#define EXEC(name) test_##name() +#define CHECK(exp) pass_or_fail(__FILE__, __LINE__, __func__, #exp, "1", (u8)(exp)); #define EQUALS(first, second) \ - pass_or_fail(__FILE__, __LINE__, __func__, #first, #second, (first) == (second)); + pass_or_fail(__FILE__, __LINE__, __func__, #first, #second, (u32)(first) == (u32)(second)); +#define EQUALS_APPROX(first, second) \ + pass_or_fail(__FILE__, __LINE__, __func__, #first, #second, \ + FABS((f64)(first) - (f64)(second)) < 0.0000005); #define EQUALS_STR(first, second) \ - pass_or_fail(__FILE__, __LINE__, __func__, #first, #second, strcmp((first), (second)) == 0); + pass_or_fail(__FILE__, __LINE__, __func__, #first, #second, \ + strcmp((const char *)(first), (const char *)(second)) == 0); static u32 failed; @@ -30,11 +35,30 @@ static void pass_or_fail(const char *file_name, int line_num, const char *func, line_num, func, first, second); } -TEST(math) +TEST(conv) { - EQUALS(pow(2, 3), 8); - EQUALS(pow(0, 3), 0); - EQUALS(pow(0, 0), 1); + char buf[10]; + memset(buf, 0xff, sizeof(buf)); + + itoa(42, buf, 2); + EQUALS_STR(buf, "101010"); + + itoa(42, buf, 16); + EQUALS_STR(buf, "2a"); + + itoa(-42, buf, 16); + EQUALS_STR(buf, "ffffffd6"); + + itoa(-42, buf, 10); + EQUALS_STR(buf, "-42"); + + memset(buf, 0xff, sizeof(buf)); + + ftoa(0.123456789, buf, 5); + EQUALS_STR(buf, "0.12345"); + + ftoa(-0.123456789, buf, 5); + EQUALS_STR(buf, "-0.12345"); } TEST(crypto) @@ -53,35 +77,233 @@ TEST(crypto) EQUALS(memcmp(md5_res, md5_text, 16), 0); } +TEST(def) +{ + EQUALS(MIN(2, 4), 2); + EQUALS(MIN(4, -2), -2); + EQUALS(MIN(0, -1), -1); + EQUALS(MAX(2, 4), 4); + EQUALS(MAX(4, -2), 4); + EQUALS(MAX(0, -1), 0); + + EQUALS(ABS(42), 42); + EQUALS(ABS(-42), 42); + EQUALS(ABS(-0), 0); + EQUALS(FABS(42.0), 42.0); + EQUALS(FABS(-42.0), 42.0); + EQUALS(FABS(-0.0), 0.0); + + const u8 arr0[] = { 1, 2, 3, 4 }; + EQUALS(COUNT(arr0), 4); + UNUSED(arr0); + + const u8 arr1[] = { 0 }; + EQUALS(COUNT(arr1), 1); + UNUSED(arr1); + + EQUALS(UPPER('0'), 0); + EQUALS(UPPER('a'), 0); + EQUALS(UPPER('A'), 1); + EQUALS(UPPER('Z'), 1); + + EQUALS(LOWER('0'), 0); + EQUALS(LOWER('A'), 0); + EQUALS(LOWER('a'), 1); + EQUALS(LOWER('z'), 1); + + EQUALS(ALPHA('0'), 0); + EQUALS(ALPHA('a'), 1); + EQUALS(ALPHA('z'), 1); + EQUALS(ALPHA('A'), 1); + EQUALS(ALPHA('Z'), 1); + + EQUALS(NUMERIC(')'), 0); + EQUALS(NUMERIC('a'), 0); + EQUALS(NUMERIC('Z'), 0); + EQUALS(NUMERIC('0'), 1); + EQUALS(NUMERIC('9'), 1); + + EQUALS(ALPHANUMERIC(')'), 0); + EQUALS(ALPHANUMERIC('0'), 1); + EQUALS(ALPHANUMERIC('9'), 1); + EQUALS(ALPHANUMERIC('a'), 1); + EQUALS(ALPHANUMERIC('z'), 1); + EQUALS(ALPHANUMERIC('A'), 1); + EQUALS(ALPHANUMERIC('Z'), 1); + +#define TEST_STRING abc + EQUALS_STR(STRINGIFY_PARAM(TEST_STRING), "TEST_STRING"); + EQUALS_STR(STRINGIFY(TEST_STRING), "abc"); + + EQUALS(ALIGN_UP(1, 2), 2); + EQUALS(ALIGN_UP(1, 16), 16); + EQUALS(ALIGN_UP(32, 16), 32); + + EQUALS(ALIGN_DOWN(1, 2), 0); + EQUALS(ALIGN_DOWN(32, 16), 32); + EQUALS(ALIGN_DOWN(31, 16), 16); +} + +TEST(list) +{ + int data0, data1, data2; + + struct list *list = list_new(); + CHECK(!!list); + EQUALS(list->head, NULL); + list_add(list, &data0); + list_add(list, &data1); + list_add(list, &data2); + list_add(list, &data1); + list_add(list, &data0); + EQUALS(list->head->data, &data0); + list_remove(list, list->head); + EQUALS(list->head->data, &data1); + EQUALS(list->head->next->data, &data2); + list_swap(list, list->head, list->head->next); + EQUALS(list->head->data, &data2); + EQUALS(list->head->next->data, &data1); + EQUALS(list_first_data(list, &data0), list->head->next->next->next); + EQUALS(list->head->next->next->next->next, NULL); + + struct node *last = list_last(list); + CHECK(!!last); + if (last) + EQUALS(list_last(list)->data, &data0); + + list_destroy(list); +} + +TEST(math) +{ + EQUALS(pow(2, 3), 8.0); + + EQUALS_APPROX(sqrt(2), 1.4142135); + EQUALS(sqrt(-2), 0.0); // Well... + + EQUALS_APPROX(sin(M_PI), 0.0); + EQUALS_APPROX(sin(1234), 0.601928); + EQUALS_APPROX(cos(1234), -0.798551); + EQUALS_APPROX(tan(1234), -0.753775); + EQUALS_APPROX(sqrt(1234), 35.128336); + EQUALS_APPROX(sin(-1), -0.8414709848078965); + EQUALS_APPROX(cos(-1), 0.5403023058681398); + EQUALS_APPROX(tan(-1), -1.5574077246549023); +} + TEST(mem) { - const char *str0 = ""; - const char *str1 = ""; - const char *str2 = "12345"; - const char *str3 = "12345"; - const char *str4 = "12354"; - EQUALS(memcmp(str4, str2, strlen(str2)), 1); - EQUALS(memcmp(str2, str4, strlen(str2)), -1); - EQUALS(memcmp(str2, str3, strlen(str2)), 0); - EQUALS(memcmp(str0, str1, strlen(str0)), 0); - - char buf[6] = { 0 }; - EQUALS_STR(memcpy(buf, "hallo", 6), "hallo"); - - char buf2[6] = { 0 }; - EQUALS_STR(memset(buf2, 'x', 5), "xxxxx"); + u8 *zero = malloc(1); + CHECK(!!zero); + zero[0] = 42; + EQUALS(zero[0], 42); + free(zero); + + u8 *test = zalloc(0x1000); + CHECK(mememp(test, 0x1000)); + free(test); + + u8 nonemp[] = { 0, 0, 0, 0, 1 }; + CHECK(!mememp(nonemp, sizeof(nonemp))); + nonemp[sizeof(nonemp) - 1] = 0; + CHECK(mememp(nonemp, sizeof(nonemp))); + + EQUALS(memcmp("abc", "cba", 3), -1); + EQUALS(memcmp("cba", "abc", 3), 1); + EQUALS(memcmp("abc", "abc", 3), 0); + + EQUALS_STR(memcchr("abc", 'b', 3), "bc"); + EQUALS(memcchr("abc", 'z', 3), NULL); + + u8 buf[42] = { 0 }; + memset(buf, 42, sizeof(buf)); + memset(buf, 25, 0); + CHECK(buf[0] == 42 && !memcmp(buf, buf + 1, sizeof(buf) - 1)); + + const char *new = "lalala ich bin schlau"; + memcpy(buf + 1, new, strlen(new) + 1); + EQUALS(buf[0], 42); + EQUALS_STR(buf + 1, new); +} + +TEST(print) +{ + char buf[128] = { 0 }; + snprintf(buf, sizeof(buf), "%% %c %s %d %x %f", 'a', "awesome", 4242, 6942, 0.123456789); + EQUALS_STR(buf, "% a awesome 4242 1b1e 0.12345"); +} + +TEST(stack) +{ + int data0, data1; + + struct stack *stack = stack_new(); + CHECK(!!stack); + EQUALS(stack->tail, NULL); + stack_push(stack, &data0); + stack_push_bot(stack, &data1); + CHECK(!stack_empty(stack)); + EQUALS(stack_peek(stack), &data0); + EQUALS(stack_pop(stack), &data0); + EQUALS(stack_peek(stack), &data1); + stack_clear(stack); + CHECK(stack_empty(stack)); + stack_destroy(stack); +} + +TEST(str) +{ + EQUALS(strlen(""), 0); + EQUALS(strlen("melvix"), 6); + EQUALS(strlen("huhu\0abc"), 4); + EQUALS(strnlen("melvix", 3), 3); + EQUALS(strnlen("melvix", 0), 0); + + EQUALS_STR(strcchr("awesome", 's'), "some"); + EQUALS_STR(strcchr("awesome", 'e'), "esome"); + EQUALS(strcchr("awesome", 'z'), NULL); + EQUALS_STR(strcchr("awesome", 's'), "some"); + EQUALS_STR(strrcchr("awesome", 'e'), "e"); + EQUALS(strrcchr("awesome", 'z'), NULL); + + EQUALS(strcmp("aaa", "aaz"), -25); + EQUALS(strcmp("aaa", "aab"), -1); + EQUALS(strcmp("aaa", "aaa"), 0); + EQUALS(strcmp("aaz", "aaa"), 25); + EQUALS(strcmp("aab", "aaa"), 1); + + char *inv = strdup("melvin"); + EQUALS_STR(strinv(inv), "nivlem"); + free(inv); + inv = strdup(""); + EQUALS_STR(strinv(inv), ""); + free(inv); + + char buf[42] = { 0 }; + EQUALS(strlcpy(buf, "apple", sizeof(buf)), 5); + EQUALS_STR(buf, "apple"); + EQUALS(strlcpy(buf, "banana", 4), 6); + EQUALS_STR(buf, "ban"); + EQUALS(strlcat(buf, "elele", sizeof(buf)), 8); + EQUALS_STR(buf, "banelele"); } int main(void) { - test_math(); - test_crypto(); - test_mem(); + EXEC(conv); + EXEC(crypto); + EXEC(def); + EXEC(list); + EXEC(math); + EXEC(mem); + EXEC(print); + EXEC(stack); + EXEC(str); /* fuzz(); */ if (failed) - log("%d tests failed\n", failed); + log("[FAIL] %d tests failed\n", failed); else log("All tests passed\n"); diff --git a/libs/libc/conv.c b/libs/libc/conv.c index 64401ed..72a919b 100644 --- a/libs/libc/conv.c +++ b/libs/libc/conv.c @@ -6,7 +6,7 @@ #include <mem.h> #include <str.h> -int itoa(int value, char *buffer, int base) +int itoa(s32 value, char *buffer, u32 base) { char tmp[16]; char *tp = tmp; @@ -37,6 +37,7 @@ int itoa(int value, char *buffer, int base) while (tp > tmp) *buffer++ = *--tp; + *buffer = '\0'; return len; } @@ -59,8 +60,7 @@ static int normalize(f64 *val) return exp; } -#define FLOAT_WIDTH 5 -char *ftoa(f64 value, char *buffer) +char *ftoa(f64 value, char *buffer, u32 width) { int exp = 0; u32 loc = 0; @@ -91,13 +91,13 @@ char *ftoa(f64 value, char *buffer) *buffer++ = '.'; - while (exp < 0 && loc < FLOAT_WIDTH) { + while (exp < 0 && loc < width) { *buffer++ = '0'; --exp; ++loc; } - while (loc < FLOAT_WIDTH) { + while (loc < width) { int digit = value * 10.0; *buffer++ = digit + '0'; value = value * 10.0 - digit; diff --git a/libs/libc/inc/conv.h b/libs/libc/inc/conv.h index 8b88526..58937c2 100644 --- a/libs/libc/inc/conv.h +++ b/libs/libc/inc/conv.h @@ -5,7 +5,7 @@ #include <def.h> -int itoa(int value, char *buffer, int base); -char *ftoa(f64 value, char *buffer); +int itoa(s32 value, char *buffer, u32 base); +char *ftoa(f64 value, char *buffer, u32 width); #endif diff --git a/libs/libc/inc/def.h b/libs/libc/inc/def.h index 3b173dd..84656b4 100644 --- a/libs/libc/inc/def.h +++ b/libs/libc/inc/def.h @@ -33,6 +33,7 @@ typedef long double f80; #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define ABS(a) ((u32)(((s32)(a) < 0) ? -(a) : (a))) +#define FABS(a) ((f64)(((f64)(a) < 0.0) ? -(a) : (a))) #define COUNT(a) (sizeof(a) / sizeof 0 [a]) @@ -42,8 +43,8 @@ typedef long double f80; #define NUMERIC(a) ((a) >= '0' && ((a) <= '9')) #define ALPHANUMERIC(a) (ALPHA(a) || NUMERIC(a)) -#define __STRINGIFY(a) #a -#define STRINGIFY(a) __STRINGIFY(a) +#define STRINGIFY_PARAM(a) #a +#define STRINGIFY(a) STRINGIFY_PARAM(a) #define ALIGN_UP(addr, align) (((addr) + (align)-1) & ~((align)-1)) #define ALIGN_DOWN(addr, align) ((addr) & ~((align)-1)) @@ -86,18 +87,17 @@ typedef long double f80; #define EOF (-1) #define NULL ((void *)0) -#define U8_MAX 255 -#define S8_MAX 127 -#define S8_MIN -128 -#define U16_MAX 65535 -#define S16_MAX 32767 -#define S16_MIN -32768 -#define U32_MAX 4294967295 -#define S32_MAX 2147483647 -#define S32_MIN -2147483648 - -#define LONG_MAX S32_MAX -#define LONG_MIN S32_MIN +#define U8_MAX ((u8)255) +#define S8_MAX ((s8)127) +#define S8_MIN ((s8)-128) +#define U16_MAX ((u16)65535) +#define S16_MAX ((s16)32767) +#define S16_MIN ((s16)-32768) +#define U32_MAX ((u32)4294967295) +#define S32_MAX ((s32)2147483647) +#define S32_MIN ((s32)-2147483648) +#define F64_MAX ((f64)0x7fefffffffffffff) +#define F64_MIN ((f64)0x10000000000000) #define MILLION 1000000 #define BILLION 1000000000 diff --git a/libs/libc/inc/list.h b/libs/libc/inc/list.h index fea98dc..4e5fe65 100644 --- a/libs/libc/inc/list.h +++ b/libs/libc/inc/list.h @@ -18,8 +18,6 @@ struct node { struct list *list_new(void); void list_destroy(struct list *list) NONNULL; -/* struct node *list_new_node(); */ // TODO: Make node-specific things static/private? -/* void list_add_node(struct list *list, struct node *node); */ struct node *list_add(struct list *list, void *data) NONNULL; struct list *list_remove(struct list *list, struct node *node) NONNULL; struct node *list_last(struct list *list) NONNULL; diff --git a/libs/libc/inc/math.h b/libs/libc/inc/math.h index 8affb72..4a38c5f 100644 --- a/libs/libc/inc/math.h +++ b/libs/libc/inc/math.h @@ -17,7 +17,9 @@ #define M_PI_2 1.57079632679489661923 #define M_PI_4 0.78539816339744830962 +f32 powf(f32 base, f32 exp); f64 pow(f64 base, f64 exp); +f32 sqrtf(f64 num); f64 sqrt(f64 num); f32 sinf(f32 angle); diff --git a/libs/libc/inc/mem.h b/libs/libc/inc/mem.h index 64f74f5..ef53cad 100644 --- a/libs/libc/inc/mem.h +++ b/libs/libc/inc/mem.h @@ -68,6 +68,7 @@ void free_debug(void *ptr, const char *file, int line, const char *func, const c void *memcpy(void *dest, const void *src, u32 n) NONNULL; void *memset(void *dest, u32 val, u32 n) NONNULL; +const void *memcchr(const void *src, char c, u32 n) NONNULL; void *memchr(void *src, char c, u32 n) NONNULL; s32 memcmp(const void *s1, const void *s2, u32 n) NONNULL; u8 mememp(const u8 *buf, u32 n) NONNULL; @@ -75,6 +76,7 @@ u8 mememp(const u8 *buf, u32 n) NONNULL; #ifdef KERNEL void *memcpy_user(void *dest, const void *src, u32 n) NONNULL; void *memset_user(void *dest, u32 val, u32 n) NONNULL; +const void *memcchr_user(const void *src, char c, u32 n) NONNULL; void *memchr_user(void *src, char c, u32 n) NONNULL; s32 memcmp_user(const void *s1, const void *s2, u32 n) NONNULL; u8 mememp_user(const u8 *buf, u32 n) NONNULL; diff --git a/libs/libc/inc/str.h b/libs/libc/inc/str.h index f024aaa..6b5d16f 100644 --- a/libs/libc/inc/str.h +++ b/libs/libc/inc/str.h @@ -8,6 +8,8 @@ PURE u32 strlen(const char *s) NONNULL; PURE u32 strnlen(const char *s, u32 max) NONNULL; u32 strlcpy(char *dst, const char *src, u32 size) NONNULL; +PURE const char *strcchr(const char *s, char c) NONNULL; +PURE const char *strrcchr(const char *s, char c) NONNULL; PURE char *strchr(char *s, char c) NONNULL; PURE char *strrchr(char *s, char c) NONNULL; u32 strlcat(char *dst, const char *src, u32 size) NONNULL; @@ -21,6 +23,8 @@ ATTR((malloc)) char *strdup(const char *s) NONNULL; PURE u32 strlen_user(const char *s) NONNULL; PURE u32 strnlen_user(const char *s, u32 max) NONNULL; u32 strlcpy_user(char *dst, const char *src, u32 size) NONNULL; +PURE const char *strcchr_user(const char *s, char c) NONNULL; +PURE const char *strrcchr_user(const char *s, char c) NONNULL; PURE char *strchr_user(char *s, char c) NONNULL; PURE char *strrchr_user(char *s, char c) NONNULL; u32 strlcat_user(char *dst, const char *src, u32 size) NONNULL; diff --git a/libs/libc/list.c b/libs/libc/list.c index 3f37478..a477285 100644 --- a/libs/libc/list.c +++ b/libs/libc/list.c @@ -61,7 +61,7 @@ NONNULL static struct node *list_add_node(struct list *list, struct node *node) struct node *list_last(struct list *list) { - if (list->head) + if (!list->head) return NULL; struct node *iterator = list->head; diff --git a/libs/libc/math.c b/libs/libc/math.c index b84958b..23b1ca4 100644 --- a/libs/libc/math.c +++ b/libs/libc/math.c @@ -2,6 +2,11 @@ #include <math.h> +f32 powf(f32 base, f32 exp) +{ + return (f32)pow(base, exp); +} + f64 pow(f64 base, f64 exp) { f64 out; @@ -26,6 +31,12 @@ f64 pow(f64 base, f64 exp) } // TODO: More efficient sqrt? + +f32 sqrtf(f64 num) +{ + return powf(num, .5); +} + f64 sqrt(f64 num) { return pow(num, .5); diff --git a/libs/libc/mem.c b/libs/libc/mem.c index 080c88d..27f0416 100644 --- a/libs/libc/mem.c +++ b/libs/libc/mem.c @@ -48,6 +48,18 @@ void *memset(void *dest, u32 val, u32 n) return dest; } +const void *memcchr(const void *src, char c, u32 n) +{ + const u8 *s = (const u8 *)src; + + while (n-- > 0) { + if (*s == c) + return s; + s++; + } + return NULL; +} + void *memchr(void *src, char c, u32 n) { u8 *s = (u8 *)src; @@ -98,6 +110,14 @@ void *memset_user(void *dest, u32 val, u32 n) return ret; } +const void *memcchr_user(const void *src, char c, u32 n) +{ + stac(); + const void *ret = memcchr(src, c, n); + clac(); + return ret; +} + void *memchr_user(void *src, char c, u32 n) { stac(); diff --git a/libs/libc/print.c b/libs/libc/print.c index da8ab25..264f893 100644 --- a/libs/libc/print.c +++ b/libs/libc/print.c @@ -54,7 +54,7 @@ int vsnprintf(char *str, u32 size, const char *format, va_list ap) break; case 'f': temp_double = va_arg(ap, double); - ftoa(temp_double, buffer); + ftoa(temp_double, buffer, 5); length += strlcpy(&str[length], buffer, size - length); break; default: diff --git a/libs/libc/str.c b/libs/libc/str.c index 9e1bb2f..ce0fef6 100644 --- a/libs/libc/str.c +++ b/libs/libc/str.c @@ -34,7 +34,7 @@ u32 strlcpy(char *dst, const char *src, u32 size) break; if (!left) { - if (!size) + if (size) *dst = 0; while (*src++) ; @@ -75,6 +75,29 @@ s32 strncmp(const char *s1, const char *s2, u32 n) return d; } +const char *strcchr(const char *s, char c) +{ + while (*s != c) { + if (!*s) + return NULL; + s++; + } + + return s; +} + +const char *strrcchr(const char *s, char c) +{ + const char *ret = 0; + + do { + if (*s == c) + ret = s; + } while (*s++); + + return ret; +} + char *strchr(char *s, char c) { while (*s != c) { @@ -120,8 +143,7 @@ u32 strlcat(char *dst, const char *src, u32 size) } src++; } - - src = 0; + *dst = 0; return len + (src - orig_src); } @@ -273,6 +295,22 @@ s32 strncmp_user(const char *s1, const char *s2, u32 n) return ret; } +const char *strcchr_user(const char *s, char c) +{ + stac(); + const char *ret = strcchr(s, c); + clac(); + return ret; +} + +const char *strrcchr_user(const char *s, char c) +{ + stac(); + const char *ret = strrcchr(s, c); + clac(); + return ret; +} + char *strchr_user(char *s, char c) { stac(); |