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:
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;
}
}