jdict

command line tool for looking up terms in yomidict dictionaries
git clone anongit@rnpnr.xyz:jdict.git
Log | Files | Refs | Feed | README | LICENSE

Commit: 5742fd0f2ba55cdb382cc64eae2d0b130ec25ef0
Parent: c1bea4cf97eb69e402ba5207a7aea34dda583aa2
Author: Randy Palamar
Date:   Wed, 16 Oct 2024 08:18:03 -0600

push PathStream file opening/reading into the platform layer

really the caller just wants the file data and doesn't care about the name.

Diffstat:
Mjdict.c | 39+++++++++++++++++----------------------
Mplatform_posix.c | 25++++++++++++++++---------
2 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/jdict.c b/jdict.c @@ -46,7 +46,10 @@ typedef struct { #endif } Arena; -typedef struct { void *dirfd; } PathStream; +typedef struct { + Stream *dir_name; + void *dirfd; +} PathStream; #include "yomidict.c" @@ -87,8 +90,8 @@ 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 PathStream os_begin_path_stream(Stream *); +static s8 os_get_valid_file(PathStream *, s8, Arena *, u32); static void os_end_path_stream(PathStream *); static Stream error_stream; @@ -322,11 +325,8 @@ intern(struct ht *t, s8 key) } static void -parse_term_bank(Arena *a, struct ht *ht, char *tbank) +parse_term_bank(Arena *a, struct ht *ht, s8 data) { - Arena start = *a; - s8 data = os_read_whole_file(tbank, a, ARENA_ALLOC_END); - /* allocate tokens */ size ntoks = (1 << HT_EXP) * YOMI_TOKS_PER_ENT + 1; YomiTok *toks = alloc(a, YomiTok, ntoks, ARENA_ALLOC_END|ARENA_NO_CLEAR); @@ -408,14 +408,12 @@ parse_term_bank(Arena *a, struct ht *ht, char *tbank) cleanup: stream_flush(&error_stream); - /* NOTE: clear temporary allocations */ - a->end = start.end; } static int make_dict(Arena *a, Dict *d) { - Arena start = *a; + u8 *starting_arena_end = a->end; Stream path = {.cap = 1 * MEGABYTE}; path.data = alloc(a, u8, path.cap, ARENA_ALLOC_END|ARENA_NO_CLEAR); d->ht.ents = alloc(a, DictEnt *, 1 << HT_EXP, 0); @@ -423,23 +421,20 @@ make_dict(Arena *a, Dict *d) stream_append_s8(&path, prefix); stream_append_s8(&path, os_path_sep); stream_append_s8(&path, d->rom); - stream_append_byte(&path, 0); - PathStream ps = os_begin_path_stream((char *)path.data); - - path.widx -= 1; - stream_append_s8(&path, os_path_sep); - i32 start_widx = path.widx; + PathStream ps = os_begin_path_stream(&path); + u8 *arena_end = a->end; s8 fn_pre = s8("term"); - 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); + for (s8 filedata = os_get_valid_file(&ps, fn_pre, a, ARENA_ALLOC_END); + filedata.len; + filedata = os_get_valid_file(&ps, fn_pre, a, ARENA_ALLOC_END)) + { + parse_term_bank(a, &d->ht, filedata); + a->end = arena_end; } os_end_path_stream(&ps); - /* NOTE: clear temporary allocations */ - a->end = start.end; + a->end = starting_arena_end; return 1; } diff --git a/platform_posix.c b/platform_posix.c @@ -84,19 +84,22 @@ os_write(iptr file, s8 raw) } static PathStream -os_begin_path_stream(char *directory) +os_begin_path_stream(Stream *dir_name) { - DIR *dir; - if (!(dir = opendir(directory))) { + stream_append_byte(dir_name, 0); + DIR *dir = opendir((char *)dir_name->data); + dir_name->widx--; + if (!dir) { stream_append_s8(&error_stream, s8("opendir: failed to open: ")); - stream_append_s8(&error_stream, cstr_to_s8(directory)); + stream_append_s8(&error_stream, (s8){.len = dir_name->widx, .s = dir_name->data}); die(&error_stream); } - return (PathStream){.dirfd = dir}; + stream_append_byte(dir_name, '/'); + return (PathStream){.dir_name = dir_name, .dirfd = dir}; } static s8 -os_get_valid_file(PathStream *ps, s8 match_prefix) +os_get_valid_file(PathStream *ps, s8 match_prefix, Arena *a, u32 arena_flags) { s8 result = {0}; if (ps->dirfd) { @@ -111,9 +114,13 @@ os_get_valid_file(PathStream *ps, s8 match_prefix) } } if (valid) { - result = cstr_to_s8(dent->d_name); - /* NOTE: include the NUL terminator */ - result.len++; + Stream dir_name = *ps->dir_name; + s8 d_name = cstr_to_s8(dent->d_name); + /* NOTE: include NUL */ + d_name.len++; + stream_append_s8(&dir_name, d_name); + result = os_read_whole_file((char *)dir_name.data, a, + arena_flags); break; } }