From 6a5543bb8f1f535ca49737bcd7be0cafca3b2a08 Mon Sep 17 00:00:00 2001 From: hachem Date: Mon, 12 Oct 2026 23:08:48 +0200 Subject: feat: lib sea --- user/calc.c | 24 ++--- user/chat.c | 36 +++---- user/hexview.c | 93 ++++++----------- user/membrk.c | 51 ++++------ user/primes.c | 28 ++---- user/save.c | 46 ++++----- user/user.h | 309 --------------------------------------------------------- 7 files changed, 111 insertions(+), 476 deletions(-) delete mode 100644 user/user.h (limited to 'user') diff --git a/user/calc.c b/user/calc.c index cf5b1d2..63fa9c6 100644 --- a/user/calc.c +++ b/user/calc.c @@ -1,20 +1,20 @@ -#include "user.h" +#include static int is_digit(char character) { return character >= '0' && character <= '9'; } -void _start(void) +int main(void) { - put("calc, e.g. 3 + 4 * 2 (left to right), empty line quits\n"); + printf("calc, e.g. 3 + 4 * 2 (left to right), empty line quits\n"); char line[128]; for (;;) { - put("> "); - int length = read_line(line, 128); - put("\n"); + printf("> "); + int length = readline(line, 128); + printf("\n"); if (length == 0) break; @@ -49,7 +49,7 @@ void _start(void) { if (value == 0) { - put("divide by zero\n"); + printf("divide by zero\n"); valid = 0; break; } @@ -66,19 +66,15 @@ void _start(void) } else { - put("bad character\n"); + printf("bad character\n"); valid = 0; break; } } if (valid && saw_number) - { - put("= "); - put_int(accumulator); - put("\n"); - } + printf("= %ld\n", accumulator); } - sys_exit(0); + return 0; } diff --git a/user/chat.c b/user/chat.c index 1657c73..7a1d5c8 100644 --- a/user/chat.c +++ b/user/chat.c @@ -1,32 +1,28 @@ -#include "user.h" +#include +#include +#include -void _start(const char* arg, unsigned long arglen) +int main(int argc, char** argv) { - if (arglen == 0) + if (argc < 2) { - put("usage: run chat \n"); - sys_exit(1); + printf("usage: run chat \n"); + return 1; } - char path[128]; - unsigned long i = 0; - for (; i < arglen && i < sizeof(path) - 1; i++) - path[i] = arg[i]; - path[i] = 0; - - long fd = sys_open(path, 0); + const char* path = argv[1]; + int fd = open(path, O_RDONLY); if (fd < 0) { - put("chat: "); - put(path); - put(": cannot open\n"); - sys_exit(1); + printf("chat: %s: cannot open\n", path); + return 1; } char buffer[256]; long bytes_read; - while ((bytes_read = sys_read(fd, buffer, sizeof(buffer))) > 0) - (void)sys_write(1, buffer, (unsigned long)bytes_read); - (void)sys_close(fd); - sys_exit(0); + while ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) + write(1, buffer, (unsigned long)bytes_read); + + close(fd); + return 0; } diff --git a/user/hexview.c b/user/hexview.c index 5d21711..44bbe38 100644 --- a/user/hexview.c +++ b/user/hexview.c @@ -1,103 +1,75 @@ -#include "user.h" - -static const char HEX[] = "0123456789abcdef"; - -static void put_hex8(unsigned char byte) -{ - char digits[2] = { HEX[byte >> 4], HEX[byte & 15] }; - (void)sys_write(1, digits, 2); -} - -static void put_hex32(unsigned long value) -{ - char digits[8]; - for (int nibble = 0; nibble < 8; nibble++) - digits[nibble] = HEX[(value >> ((7 - nibble) * 4)) & 15]; - (void)sys_write(1, digits, 8); -} +#include +#include +#include #define PAGE 256 #define COLS 16 -void _start(const char* arg, unsigned long arglen) +int main(int argc, char** argv) { - char name[64]; - - if (arglen > 0 && arglen < 64) - { - for (unsigned long i = 0; i < arglen; i++) - name[i] = arg[i]; - name[arglen] = 0; - } + char prompt_name[64]; + const char* name; + if (argc >= 2) + name = argv[1]; else { - put("hexview, type a filename\nfile: "); - (void)read_line(name, 64); - put("\n"); + printf("hexview, type a filename\nfile: "); + readline(prompt_name, 64); + printf("\n"); + name = prompt_name; } - long size = sys_fs_size(name); - if (size < 0) + int fd = open(name, O_RDONLY); + if (fd < 0) { - put("no such file\n"); - sys_exit(1); + printf("no such file\n"); + return 1; } + long size = lseek(fd, 0, SEEK_END); unsigned long offset = 0; char buffer[PAGE]; for (;;) { - long count = sys_fs_read(name, offset, buffer, PAGE); + lseek(fd, (long)offset, SEEK_SET); + long count = read(fd, buffer, PAGE); - put("--- "); - put(name); - put(" @ 0x"); - put_hex32(offset); - put(" / 0x"); - put_hex32((unsigned long)size); - put(" ---\n"); + printf("--- %s @ 0x%08lx / 0x%08lx ---\n", name, offset, (unsigned long)size); for (long row = 0; row < count; row += COLS) { - put_hex32(offset + (unsigned long)row); - put(": "); + printf("%08lx: ", offset + (unsigned long)row); for (int column = 0; column < COLS; column++) { if (row + column < count) - { - put_hex8((unsigned char)buffer[row + column]); - (void)sys_write(1, " ", 1); - } + printf("%02x ", (unsigned char)buffer[row + column]); else - put(" "); + printf(" "); } - put(" "); + printf(" "); for (int column = 0; column < COLS && row + column < count; column++) { char character = buffer[row + column]; - if (character >= 32 && character < 127) - (void)sys_write(1, &character, 1); - else - (void)sys_write(1, ".", 1); + putchar((character >= 32 && character < 127) ? character : '.'); } - put("\n"); + printf("\n"); } - put("[n]ext [p]rev [q]uit (or up/down arrows) > "); - char key = (char)get_char(); + printf("[n]ext [p]rev [q]uit (or up/down arrows) > "); + int key = getchar(); if (key == 27) // ESC { - (void)get_char(); - char final = (char)get_char(); + getchar(); + int final = getchar(); if (final == 'A') key = 'p'; else if (final == 'B') key = 'n'; } - put("\n"); + printf("\n"); if (key == 'q') break; if (key == 'n' && offset + PAGE < (unsigned long)size) @@ -106,5 +78,6 @@ void _start(const char* arg, unsigned long arglen) offset -= PAGE; } - sys_exit(0); + close(fd); + return 0; } diff --git a/user/membrk.c b/user/membrk.c index f1949cc..7d73adf 100644 --- a/user/membrk.c +++ b/user/membrk.c @@ -1,31 +1,26 @@ -#include "user.h" +#include +#include +#include static void check(const char* name, int ok) { - put(ok ? "ok " : "FAIL "); - put(name); - put("\n"); + printf("%s%s\n", ok ? "ok " : "FAIL ", name); } -void _start(const char* arg, unsigned long arglen) +int main(void) { - (void)arg; - (void)arglen; - - long start = (long)sys_sbrk(0); - put("heap base: "); - put_int(start); - put("\n"); + long start = (long)sbrk(0); + printf("heap base: %ld\n", start); // obese alloc test char* run[80]; for (int i = 0; i < 80; i++) - run[i] = (char*)malloc(4000); - long run_after = (long)sys_sbrk(0); + run[i] = malloc(4000); + long run_after = (long)sbrk(0); for (int i = 0; i < 80; i++) free(run[i]); - char* merged = (char*)malloc(80 * 4000 - 8000); - long merge_after = (long)sys_sbrk(0); + char* merged = malloc(80 * 4000 - 8000); + long merge_after = (long)sbrk(0); check("freed neighbours coalesce", merged != 0 && merge_after <= run_after); free(merged); @@ -33,7 +28,7 @@ void _start(const char* arg, unsigned long arglen) char* blocks[16]; for (int i = 0; i < 16; i++) { - blocks[i] = (char*)malloc(64); + blocks[i] = malloc(64); for (int j = 0; j < 64; j++) blocks[i][j] = (char)(i * 7 + j); } @@ -46,7 +41,7 @@ void _start(const char* arg, unsigned long arglen) // a big block spanning several pages written edge to edge unsigned long big = 20000; - unsigned char* buffer = (unsigned char*)malloc(big); + unsigned char* buffer = malloc(big); for (unsigned long k = 0; k < big; k++) buffer[k] = (unsigned char)(k & 0xff); int big_ok = 1; @@ -55,18 +50,18 @@ void _start(const char* arg, unsigned long arglen) big_ok = 0; check("big multi page alloc", big_ok); - // testing that the the heap must doesnt grow across the loop - long churn_before = (long)sys_sbrk(0); + // testing that the heap doesnt grow across the loop + long churn_before = (long)sbrk(0); for (int i = 0; i < 2000; i++) { void* pointer = malloc(500); free(pointer); } - long churn_after = (long)sys_sbrk(0); + long churn_after = (long)sbrk(0); check("alloc/free churn reclaims (no growth)", churn_before == churn_after); // calloc dirty test - unsigned char* zeroed = (unsigned char*)calloc(200, 1); + unsigned char* zeroed = calloc(200, 1); int zero_ok = 1; for (int i = 0; i < 200; i++) if (zeroed[i] != 0) @@ -74,20 +69,18 @@ void _start(const char* arg, unsigned long arglen) check("calloc is zeroed", zero_ok); // realloc test - char* grown = (char*)malloc(32); + char* grown = malloc(32); for (int i = 0; i < 32; i++) grown[i] = (char)(i + 1); - grown = (char*)realloc(grown, 500); + grown = realloc(grown, 500); int grow_ok = 1; for (int i = 0; i < 32; i++) if (grown[i] != (char)(i + 1)) grow_ok = 0; check("realloc grows and preserves data", grow_ok); - long end = (long)sys_sbrk(0); - put("heap high water: "); - put_int(end - start); - put(" bytes\n"); + long end = (long)sbrk(0); + printf("heap high water: %ld bytes\n", end - start); - sys_exit(0); + return 0; } diff --git a/user/primes.c b/user/primes.c index 49c545a..5501c32 100644 --- a/user/primes.c +++ b/user/primes.c @@ -1,22 +1,19 @@ -#include "user.h" +#include +#include -void _start(void) +int main(void) { - put("primes up to N, enter N (empty line quits)\n"); + printf("primes up to N, enter N (empty line quits)\n"); char line[32]; for (;;) { - put("> "); - int length = read_line(line, 32); - put("\n"); + printf("> "); + int length = readline(line, 32); + printf("\n"); if (length == 0) break; - long limit = 0; - for (int position = 0; position < length; position++) - if (line[position] >= '0' && line[position] <= '9') - limit = limit * 10 + (line[position] - '0'); - + long limit = atol(line); int count = 0; for (long candidate = 2; candidate <= limit; candidate++) { @@ -29,14 +26,11 @@ void _start(void) } if (prime) { - put_int(candidate); - put(" "); + printf("%ld ", candidate); count++; } } - put("\n"); - put_int(count); - put(" primes\n"); + printf("\n%d primes\n", count); } - sys_exit(0); + return 0; } diff --git a/user/save.c b/user/save.c index 2ac065f..056e160 100644 --- a/user/save.c +++ b/user/save.c @@ -1,45 +1,37 @@ -#include "user.h" +#include +#include +#include -void _start(const char* arg, unsigned long arglen) +int main(int argc, char** argv) { - if (arglen == 0 || arglen >= 120) + if (argc < 2) { - put("usage: run save \n"); - sys_exit(1); + printf("usage: run save \n"); + return 1; } - char name[128]; - for (unsigned long i = 0; i < arglen; i++) - name[i] = arg[i]; - name[arglen] = 0; - - long fd = sys_open(name, O_CREAT | O_TRUNC | O_WRONLY); + const char* name = argv[1]; + int fd = open(name, O_CREAT | O_TRUNC | O_WRONLY); if (fd < 0) { - put("save: "); - put(name); - put(": cannot open\n"); - sys_exit(1); + printf("save: %s: cannot open\n", name); + return 1; } - put("saving to "); - put(name); - put(" -- type lines, a single . saves\n"); + printf("saving to %s -- type lines, a single . saves\n", name); for (;;) { char line[256]; - int bytes_read = read_line(line, 256); - put("\n"); + int bytes_read = readline(line, 256); + printf("\n"); if (bytes_read == 1 && line[0] == '.') break; - (void)sys_write(fd, line, (unsigned long)bytes_read); - (void)sys_write(fd, "\n", 1); + write(fd, line, (unsigned long)bytes_read); + write(fd, "\n", 1); } - (void)sys_close(fd); - put("saved "); - put(name); - put("\n"); - sys_exit(0); + close(fd); + printf("saved %s\n", name); + return 0; } diff --git a/user/user.h b/user/user.h deleted file mode 100644 index 58a1bc5..0000000 --- a/user/user.h +++ /dev/null @@ -1,309 +0,0 @@ -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -#define O_WRONLY 1 -#define O_CREAT 0x40 -#define O_TRUNC 0x200 -#define O_APPEND 0x400 - -static inline __attribute__((warn_unused_result)) long sys_write(long fd, const char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(1L), "D"(fd), "S"(buffer), "d"(length) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_read(long fd, char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(2L), "D"(fd), "S"(buffer), "d"(length) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_open(const char* path, long flags) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(7L), "D"(path), "S"(flags) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_close(long fd) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(8L), "D"(fd) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_lseek(long fd, long offset, long whence) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(9L), "D"(fd), "S"(offset), "d"(whence) : "memory"); - return result; -} - -static inline void sys_exit(long code) -{ - __asm__ volatile("int $0x80" : : "a"(0L), "D"(code) : "memory"); - for (;;); -} - -static inline __attribute__((warn_unused_result)) long sys_fs_size(const char* name) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(4L), "D"(name) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_fs_read(const char* name, unsigned long offset, char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" - : "=a"(result) - : "a"(5L), "D"(name), "S"(offset), "d"(buffer), "c"(length) - : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_fs_write(const char* name, const char* buffer, unsigned long length) -{ - long result; - __asm__ volatile("int $0x80" - : "=a"(result) - : "a"(6L), "D"(name), "S"(buffer), "d"(length) - : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) long sys_brk(void* address) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(10L), "D"(address) : "memory"); - return result; -} - -static inline __attribute__((warn_unused_result)) void* sys_sbrk(long increment) -{ - long result; - __asm__ volatile("int $0x80" : "=a"(result) : "a"(11L), "D"(increment) : "memory"); - return (void*)result; -} - -// shitty heap implementation -// temporary af this will be in its own libc -#define HEAP_HEADER 16UL -#define HEAP_ALIGN 16UL -#define HEAP_MIN 32UL -#define HEAP_CHUNK (64UL * 1024UL) - -static unsigned long heap_start = 0; -static unsigned long heap_end = 0; -static unsigned long heap_rover = 0; - -static inline __attribute__((warn_unused_result)) unsigned long heap_block_size(unsigned long block) -{ - return *(unsigned long*)block & ~15UL; -} - -static inline __attribute__((warn_unused_result)) int heap_block_used(unsigned long block) -{ - return (int)(*(unsigned long*)block & 1UL); -} - -static inline void heap_set(unsigned long block, unsigned long size, int used) -{ - *(unsigned long*)block = size | (used ? 1UL : 0UL); -} - -static inline __attribute__((warn_unused_result)) unsigned long heap_align(unsigned long value) -{ - return (value + HEAP_ALIGN - 1UL) & ~(HEAP_ALIGN - 1UL); -} - -// pull another hunk off sbrk and drop a free block over it -static inline __attribute__((warn_unused_result)) int heap_grow(unsigned long need) -{ - unsigned long want = heap_align(need); - if (want < HEAP_CHUNK) - want = HEAP_CHUNK; - unsigned long got = (unsigned long)sys_sbrk((long)want); - if ((long)got < 0) - return 0; - if (heap_start == 0) - { - heap_start = got; - heap_end = got; - heap_rover = got; - } - heap_set(heap_end, want, 0); - heap_end += want; - return 1; -} - -// yummy O(n) malloc implementation -static inline __attribute__((warn_unused_result)) void* malloc(unsigned long length) -{ - if (length == 0) - return 0; - unsigned long need = heap_align(HEAP_HEADER + length); - if (need < HEAP_MIN) - need = HEAP_MIN; - - for (;;) - { - if (heap_rover < heap_start || heap_rover >= heap_end) - heap_rover = heap_start; - unsigned long block = heap_rover; - unsigned long limit = heap_end; - for (int pass = 0; pass < 2; pass++) - { - while (block < limit) - { - if (!heap_block_used(block)) - { - unsigned long size = heap_block_size(block); - while (block + size < heap_end && !heap_block_used(block + size)) - size += heap_block_size(block + size); - heap_set(block, size, 0); - if (size >= need) - { - if (size >= need + HEAP_MIN) - { - heap_set(block, need, 1); - heap_set(block + need, size - need, 0); - heap_rover = block + need; - } - else - { - heap_set(block, size, 1); - heap_rover = block + size; - } - if (heap_rover >= heap_end) - heap_rover = heap_start; - return (void*)(block + HEAP_HEADER); - } - } - block += heap_block_size(block); - } - block = heap_start; - limit = heap_rover; - } - if (!heap_grow(need)) - return 0; - } -} - -static inline void free(void* pointer) -{ - if (pointer == 0) - return; - unsigned long block = (unsigned long)pointer - HEAP_HEADER; - heap_set(block, heap_block_size(block), 0); -} - -static inline __attribute__((warn_unused_result)) void* calloc(unsigned long count, unsigned long size) -{ - unsigned long total = count * size; - unsigned char* bytes = (unsigned char*)malloc(total); - if (bytes) - for (unsigned long i = 0; i < total; i++) - bytes[i] = 0; - return bytes; -} - -static inline __attribute__((warn_unused_result)) void* realloc(void* pointer, unsigned long length) -{ - if (pointer == 0) - return malloc(length); - if (length == 0) - { - free(pointer); - return 0; - } - unsigned long block = (unsigned long)pointer - HEAP_HEADER; - unsigned long have = heap_block_size(block) - HEAP_HEADER; - if (length <= have) - return pointer; - unsigned char* new_block = (unsigned char*)malloc(length); - if (!new_block) - return 0; - unsigned char* source = (unsigned char*)pointer; - for (unsigned long i = 0; i < have; i++) - new_block[i] = source[i]; - free(pointer); - return new_block; -} - -static inline void put(const char* string) -{ - unsigned long length = 0; - while (string[length]) - length++; - (void)sys_write(1, string, length); -} - -static inline __attribute__((warn_unused_result)) int get_char(void) -{ - char character; - if (sys_read(0, &character, 1) <= 0) - return -1; - return (unsigned char)character; -} - -static inline __attribute__((warn_unused_result)) int read_line(char* buffer, int max_length) -{ - int length = 0; - for (;;) - { - char character; - if (sys_read(0, &character, 1) <= 0) - break; - if (character == '\n') - break; - if (character == '\b') - { - if (length > 0) - { - length--; - (void)sys_write(1, "\b \b", 3); - } - continue; - } - if (length < max_length - 1) - { - buffer[length++] = character; - (void)sys_write(1, &character, 1); - } - } - buffer[length] = 0; - return length; -} - -static inline void put_int(long value) -{ - char buffer[21]; - int length = 0; - int negative = value < 0; - unsigned long magnitude = negative ? (unsigned long)(-value) : (unsigned long)value; - - if (magnitude == 0) - buffer[length++] = '0'; - - while (magnitude > 0) - { - buffer[length++] = (char)('0' + magnitude % 10); - magnitude /= 10; - } - - if (negative) - buffer[length++] = '-'; - - for (int left = 0, right = length - 1; left < right; left++, right--) - { - char swap = buffer[left]; - buffer[left] = buffer[right]; - buffer[right] = swap; - } - - (void)sys_write(1, buffer, length); -} -- cgit v1.3