Commit: c1bea4cf97eb69e402ba5207a7aea34dda583aa2
Parent: b1f0d632a045db27f4de3c86579b3e6b392894c9
Author: Randy Palamar
Date: Wed, 16 Oct 2024 06:25:09 -0600
split platform code into seperate file
Diffstat:
M | build.sh | | | 7 | ++++--- |
M | jdict.c | | | 185 | ++++++++++++++----------------------------------------------------------------- |
A | platform_posix.c | | | 146 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 181 insertions(+), 157 deletions(-)
diff --git a/build.sh b/build.sh
@@ -1,6 +1,5 @@
#!/bin/sh
-cflags="-march=native -O3 -std=c99 -Wall -Wextra"
-cflags="${cflags} -D_DEFAULT_SOURCE"
+cflags="-march=native -O3 -std=c99 -Wall -Wextra -fno-builtin"
#cflags="${cflags} -fproc-stat-report"
#cflags="${cflags} -Rpass-missed=.*"
ldflags="-static"
@@ -8,7 +7,9 @@ ldflags="-static"
cc=${CC:-cc}
debug=${DEBUG}
+src=platform_posix.c
+
[ $debug ] && cflags="$cflags -O0 -ggdb -D_DEBUG"
[ ! $debug ] && ldflags="-s $ldflags"
-${cc} $cflags $ldflags jdict.c -o jdict
+${cc} $cflags $ldflags $src -o jdict
diff --git a/jdict.c b/jdict.c
@@ -1,10 +1,4 @@
/* See LICENSE for license details. */
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
#include <stdint.h>
#include <stddef.h>
typedef uint8_t u8;
@@ -14,6 +8,7 @@ typedef int32_t i32;
typedef uint32_t u32;
typedef uint32_t b32;
typedef ptrdiff_t size;
+typedef ptrdiff_t iptr;
#ifdef _DEBUG
#define ASSERT(c) do { __asm("int3; nop"); } while (0)
@@ -86,10 +81,16 @@ typedef struct {
#include "config.h"
-#define os_path_sep s8("/")
-static b32 os_write(i32, s8);
static void __attribute__((noreturn)) os_exit(i32);
+static void os_write(iptr, s8);
+static s8 os_read_whole_file(char *, Arena *, u32);
+static b32 os_read_stdin(u8 *, size);
+
+static PathStream os_begin_path_stream(char *);
+static s8 os_get_valid_file(PathStream *, s8);
+static void os_end_path_stream(PathStream *);
+
static Stream error_stream;
static Stream stdout_stream;
@@ -150,81 +151,6 @@ die(Stream *s)
os_exit(1);
}
-static void
-os_exit(i32 code)
-{
- _exit(code);
- unreachable();
-}
-
-static Arena
-os_new_arena(size cap)
-{
- Arena a;
-
- size pagesize = sysconf(_SC_PAGESIZE);
- if (cap % pagesize != 0)
- cap += pagesize - cap % pagesize;
-
- a.beg = mmap(0, cap, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
- if (a.beg == MAP_FAILED)
- return (Arena){0};
- a.end = a.beg + cap;
-#ifdef _DEBUG_ARENA
- a.min_capacity_remaining = cap;
-#endif
- return a;
-}
-
-static size
-os_file_size(char *file)
-{
- struct stat st;
- if (stat(file, &st) < 0) {
- stream_append_s8(&error_stream, s8("failed to stat: "));
- stream_append_s8(&error_stream, cstr_to_s8(file));
- die(&error_stream);
- }
- return st.st_size;
-}
-
-static b32
-os_read(i32 fd, size count, u8 *buf)
-{
- size rlen = read(fd, buf, count);
- return rlen == count;
-}
-
-static s8
-os_read_file(char *file, u8 *buf, size file_size)
-{
- i32 fd = open(file, O_RDONLY);
- if (fd < 0) {
- stream_append_s8(&error_stream, s8("failed to open: "));
- stream_append_s8(&error_stream, cstr_to_s8(file));
- die(&error_stream);
- }
-
- s8 result = {.len = file_size, .s = buf};
- size rlen = read(fd, result.s, result.len);
- close(fd);
-
- if (rlen != result.len) {
- stream_append_s8(&error_stream, s8("failed to read whole file: "));
- stream_append_s8(&error_stream, cstr_to_s8(file));
- die(&error_stream);
- }
-
- return result;
-}
-
-static b32
-os_write(i32 file, s8 raw)
-{
- b32 result = write(file, raw.s, raw.len) == raw.len;
- return result;
-}
-
static void *
mem_clear(void *p_, u8 c, size len)
{
@@ -306,6 +232,15 @@ s8_cmp(s8 a, s8 b)
return result;
}
+static s8
+s8_cut_head(s8 s, size count)
+{
+ s8 result = s;
+ result.s += count;
+ result.len -= count;
+ return result;
+}
+
/*
* trim whitespace from start and end of str
* returns a new s8 (same memory)
@@ -390,10 +325,7 @@ static void
parse_term_bank(Arena *a, struct ht *ht, char *tbank)
{
Arena start = *a;
-
- size file_size = os_file_size(tbank);
- u8 *file_buf = alloc(a, u8, file_size, ARENA_ALLOC_END|ARENA_NO_CLEAR);
- s8 data = os_read_file(tbank, file_buf, file_size);
+ s8 data = os_read_whole_file(tbank, a, ARENA_ALLOC_END);
/* allocate tokens */
size ntoks = (1 << HT_EXP) * YOMI_TOKS_PER_ENT + 1;
@@ -480,52 +412,6 @@ cleanup:
a->end = start.end;
}
-static PathStream
-begin_path_stream(char *dirname)
-{
- DIR *dir;
- if (!(dir = opendir(dirname))) {
- stream_append_s8(&error_stream, s8("opendir: failed to open: "));
- stream_append_s8(&error_stream, cstr_to_s8(dirname));
- die(&error_stream);
- }
- return (PathStream){.dirfd = dir};
-}
-
-static s8
-get_valid_file(PathStream *ps, s8 prefix)
-{
- s8 result = {0};
- if (ps->dirfd) {
- struct dirent *dent;
- while ((dent = readdir(ps->dirfd)) != NULL) {
- if (dent->d_type == DT_REG) {
- b32 valid = 1;
- for (size i = 0; i < prefix.len; i++) {
- if (prefix.s[i] != dent->d_name[i]) {
- valid = 0;
- break;
- }
- }
- if (valid) {
- result = cstr_to_s8(dent->d_name);
- /* NOTE: include the NUL terminator */
- result.len++;
- break;
- }
- }
- }
- }
- return result;
-}
-
-static void
-end_path_stream(PathStream *ps)
-{
- closedir(ps->dirfd);
- ps->dirfd = 0;
-}
-
static int
make_dict(Arena *a, Dict *d)
{
@@ -538,19 +424,19 @@ make_dict(Arena *a, Dict *d)
stream_append_s8(&path, os_path_sep);
stream_append_s8(&path, d->rom);
stream_append_byte(&path, 0);
- PathStream ps = begin_path_stream((char *)path.data);
+ PathStream ps = os_begin_path_stream((char *)path.data);
path.widx -= 1;
stream_append_s8(&path, os_path_sep);
i32 start_widx = path.widx;
s8 fn_pre = s8("term");
- for (s8 fn = get_valid_file(&ps, fn_pre); fn.len; fn = get_valid_file(&ps, fn_pre)) {
+ for (s8 fn = os_get_valid_file(&ps, fn_pre); fn.len; fn = os_get_valid_file(&ps, fn_pre)) {
path.widx = start_widx;
stream_append_s8(&path, fn);
parse_term_bank(a, &d->ht, (char *)path.data);
}
- end_path_stream(&ps);
+ os_end_path_stream(&ps);
/* NOTE: clear temporary allocations */
a->end = start.end;
@@ -618,7 +504,7 @@ get_stdin_line(Stream *buf)
b32 result = 0;
for (; buf->widx < buf->cap; buf->widx++) {
u8 *c = buf->data + buf->widx;
- if (!os_read(STDIN_FILENO, 1, c) || *c == (u8)-1) {
+ if (!os_read_stdin(c, 1) || *c == (u8)-1) {
break;
} else if (*c == '\n') {
result = 1;
@@ -653,21 +539,12 @@ repl(Arena *a, Dict *dicts, size_t ndicts)
stream_flush(&stdout_stream);
}
-int
-main(int argc, char *argv[])
+static i32
+jdict(Arena *a, i32 argc, char *argv[])
{
- Arena memory = os_new_arena(1024 * MEGABYTE);
Dict *dicts = NULL;
- size_t ndicts = 0, nterms = 0;
- int iflag = 0;
-
- error_stream.fd = STDERR_FILENO;
- error_stream.cap = 4096;
- error_stream.data = alloc(&memory, u8, error_stream.cap, ARENA_NO_CLEAR);
-
- stdout_stream.fd = STDOUT_FILENO;
- stdout_stream.cap = 8 * MEGABYTE;
- stdout_stream.data = alloc(&memory, u8, error_stream.cap, ARENA_NO_CLEAR);
+ i32 ndicts = 0, nterms = 0;
+ i32 iflag = 0;
s8 argv0 = cstr_to_s8(argv[0]);
for (argv++, argc--; argv[0] && argv[0][0] == '-' && argv[0][1]; argc--, argv++) {
@@ -714,7 +591,7 @@ main(int argc, char *argv[])
/* NOTE: remaining argv elements are search terms */
nterms = argc;
- s8 *terms = alloc(&memory, s8, nterms, 0);
+ s8 *terms = alloc(a, s8, nterms, 0);
for (i32 i = 0; argc && *argv; argv++, i++, argc--)
terms[i] = cstr_to_s8(*argv);
@@ -722,10 +599,10 @@ main(int argc, char *argv[])
usage(argv0);
if (iflag == 0)
- for (size_t i = 0; i < ndicts; i++)
- find_and_print_defs(&memory, &dicts[i], terms, nterms);
+ for (i32 i = 0; i < ndicts; i++)
+ find_and_print_defs(a, &dicts[i], terms, nterms);
else
- repl(&memory, dicts, ndicts);
+ repl(a, dicts, ndicts);
#ifdef _DEBUG_ARENA
stream_append_s8(&error_stream, s8("min remaining arena capacity: "));
diff --git a/platform_posix.c b/platform_posix.c
@@ -0,0 +1,146 @@
+#define _DEFAULT_SOURCE 1
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define os_path_sep s8("/")
+
+#include "jdict.c"
+
+static void
+os_exit(i32 code)
+{
+ _exit(code);
+ unreachable();
+}
+
+static Arena
+os_new_arena(size cap)
+{
+ Arena a;
+
+ size pagesize = sysconf(_SC_PAGESIZE);
+ if (cap % pagesize != 0)
+ cap += pagesize - cap % pagesize;
+
+ a.beg = mmap(0, cap, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ if (a.beg == MAP_FAILED)
+ return (Arena){0};
+ a.end = a.beg + cap;
+#ifdef _DEBUG_ARENA
+ a.min_capacity_remaining = cap;
+#endif
+ return a;
+}
+
+static b32
+os_read_stdin(u8 *buf, size count)
+{
+ size rlen = read(STDIN_FILENO, buf, count);
+ return rlen == count;
+}
+
+static s8
+os_read_whole_file(char *file, Arena *a, u32 arena_flags)
+{
+
+ struct stat st;
+ if (stat(file, &st) < 0) {
+ stream_append_s8(&error_stream, s8("failed to stat: "));
+ stream_append_s8(&error_stream, cstr_to_s8(file));
+ die(&error_stream);
+ }
+
+ i32 fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ stream_append_s8(&error_stream, s8("failed to open: "));
+ stream_append_s8(&error_stream, cstr_to_s8(file));
+ die(&error_stream);
+ }
+
+ s8 result = {.len = st.st_size, .s = alloc(a, u8, st.st_size, arena_flags|ARENA_NO_CLEAR)};
+ size rlen = read(fd, result.s, result.len);
+ close(fd);
+
+ if (rlen != result.len) {
+ stream_append_s8(&error_stream, s8("failed to read whole file: "));
+ stream_append_s8(&error_stream, cstr_to_s8(file));
+ die(&error_stream);
+ }
+
+ return result;
+}
+
+static void
+os_write(iptr file, s8 raw)
+{
+ while (raw.len) {
+ size r = write(file, raw.s, raw.len);
+ if (r < 0) os_exit(1);
+ raw = s8_cut_head(raw, r);
+ }
+}
+
+static PathStream
+os_begin_path_stream(char *directory)
+{
+ DIR *dir;
+ if (!(dir = opendir(directory))) {
+ stream_append_s8(&error_stream, s8("opendir: failed to open: "));
+ stream_append_s8(&error_stream, cstr_to_s8(directory));
+ die(&error_stream);
+ }
+ return (PathStream){.dirfd = dir};
+}
+
+static s8
+os_get_valid_file(PathStream *ps, s8 match_prefix)
+{
+ s8 result = {0};
+ if (ps->dirfd) {
+ struct dirent *dent;
+ while ((dent = readdir(ps->dirfd)) != NULL) {
+ if (dent->d_type == DT_REG) {
+ b32 valid = 1;
+ for (size i = 0; i < match_prefix.len; i++) {
+ if (match_prefix.s[i] != dent->d_name[i]) {
+ valid = 0;
+ break;
+ }
+ }
+ if (valid) {
+ result = cstr_to_s8(dent->d_name);
+ /* NOTE: include the NUL terminator */
+ result.len++;
+ break;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+static void
+os_end_path_stream(PathStream *ps)
+{
+ closedir(ps->dirfd);
+ ps->dirfd = 0;
+}
+
+i32
+main(i32 argc, char *argv[])
+{
+ Arena memory = os_new_arena(1024 * MEGABYTE);
+
+ error_stream.fd = STDERR_FILENO;
+ error_stream.cap = 4096;
+ error_stream.data = alloc(&memory, u8, error_stream.cap, ARENA_NO_CLEAR);
+
+ stdout_stream.fd = STDOUT_FILENO;
+ stdout_stream.cap = 8 * MEGABYTE;
+ stdout_stream.data = alloc(&memory, u8, error_stream.cap, ARENA_NO_CLEAR);
+
+ return jdict(&memory, argc, argv);
+}