From 5fb7f0263a39b11f27ab3d91144723a27e94b9a7 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 13 Jul 2019 11:18:57 -0300 Subject: [PATCH] remove total reliance on the c stdlib for journal.zig --- src/journal/journal.h | 8 +-- src/journal/journal.zig | 106 ++++++++++++++++++++++++++++------------ src/journal/main.c | 10 ++-- 3 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/journal/journal.h b/src/journal/journal.h index 63ffe95..f6cf8bb 100644 --- a/src/journal/journal.h +++ b/src/journal/journal.h @@ -8,9 +8,9 @@ #define STREQ(a, b) strcmp(a, b) == 0 -FILE *journal_open(char *topic); -void journal_write(FILE*, char* message); -void journal_write_topic(FILE*, char *topic, char *message); -void journal_close(FILE*); +int journal_open(char *topic); +void journal_write(int, char* message); +void journal_write_topic(int, char *topic, char *message); +void journal_close(int); #endif diff --git a/src/journal/journal.zig b/src/journal/journal.zig index eecf738..d42d3e2 100644 --- a/src/journal/journal.zig +++ b/src/journal/journal.zig @@ -1,3 +1,6 @@ +const std = @import("std"); +const os = std.os; + const c = @cImport({ @cInclude("stdio.h"); @cInclude("stdlib.h"); @@ -6,7 +9,6 @@ const c = @cImport({ @cInclude("time.h"); }); -const std = @import("std"); const warn = std.debug.warn; const allocator = std.heap.c_allocator; @@ -18,53 +20,97 @@ fn free_str(ptr: [*c]u8) void { c.free(@ptrCast(?*c_void, ptr)); } -export fn journal_open(topic: [*c]u8) [*c](c.FILE) { - var home_path: [*c]const u8 = c.getenv(c"HOME"); +export fn journal_open(topic_opt: [*c]u8) os.fd_t { + const topic_len = c.strlen(topic_opt); + const topic: []u8 = topic_opt[0..topic_len]; - var journal_dir: [*c]u8 = alloc_str(512); - var journal_path: [*c]u8 = alloc_str(1024); + const journal_dir = std.fs.path.resolve(allocator, [_][]const u8{ + std.os.getenvC(c"HOME").?, + ".lunabot", + }) catch |err| { + warn("failed to resolve paths: {}\n", err); + return -1; + }; - _ = c.snprintf(journal_dir, c_ulong(512), c"%s/.lunabot", home_path); + warn("journal_dir = {}\n", journal_dir); - warn("uwu journal_dir = '{}'\n", journal_dir.*); + std.fs.makeDir(journal_dir) catch |err| { + if (err != error.PathAlreadyExists) { + warn("failed to create journal dir {}: {}\n", journal_dir, err); + return -1; + } + }; - //c.mkdir(journal_dir, c.S_IRWXU | c.S_IRGRP | c.S_IROTH); + const journal_path = std.fmt.allocPrint(allocator, "{}/{}", journal_dir, topic) catch |err| { + warn("failed to allocprint journal path: {}\n", err); + return -1; + }; + defer allocator.free(journal_path); - // taken off `zig translate-c`. this is cursed, i'm sorry. - _ = c.mkdir(journal_dir, c.__mode_t((((256 | 128) | 64) | (256 >> @import("std").math.Log2Int(c_int)(3))) | ((256 >> @import("std").math.Log2Int(c_int)(3)) >> @import("std").math.Log2Int(c_int)(3)))); + warn("journal_path = {}\n", journal_path); - _ = c.snprintf(journal_path, c_ulong(1024), c"%s/%s", journal_dir, topic); + const fd = std.os.open( + journal_path, + std.os.O_WRONLY | std.os.O_CREAT | std.os.O_APPEND, + 0o755, + ) catch |err| { + warn("failed to open {}: {}\n", journal_path, err); + return -1; + }; - warn("journal_path = {}\n", journal_path.*); - - var res: [*c](c.FILE) = c.fopen(journal_path, c"a"); - - free_str(journal_path); - free_str(journal_dir); - - return res; + return fd; } -export fn journal_write(journal: [*c]c.FILE, message: [*c]u8) void { - _ = c.fwrite(message, c.strlen(message), 1, journal); +export fn journal_write(journal: os.fd_t, message: [*c]u8) void { + const msglen = c.strlen(message); + + std.os.write(journal, message[0..msglen]) catch |err| { + std.debug.warn("Error while writing to file: {}\n", err); + return; + }; } -export fn journal_close(journal: [*c]c.FILE) void { - _ = c.fclose(journal); +export fn journal_close(journal: os.fd_t) void { + std.os.close(journal); } -export fn journal_write_topic(journal: *c.FILE, topic: [*c]u8, message: [*c]u8) void { - var tstamp: [*c]u8 = alloc_str(128); - var fmt_msg: [*c]u8 = alloc_str(128); +export fn journal_write_topic( + journal: os.fd_t, + topic_opt: [*c]u8, + message_opt: [*c]u8, +) void { + var topic = topic_opt[0..c.strlen(topic_opt)]; + var message = message_opt[0..c.strlen(message_opt)]; + + var tstamp_cstr: [*c]u8 = alloc_str(128); var rawtime: c.time_t = undefined; _ = c.time(&rawtime); var cur_time: [*c]const c.struct_tm = c.gmtime(&rawtime); + _ = c.strftime(tstamp_cstr, usize(128), c"%c", cur_time); - _ = c.strftime(tstamp, usize(128), c"%c", cur_time); - _ = c.sprintf(fmt_msg, c"[%s] [%s]: %s\n", tstamp, topic, message); + var tstamp = tstamp_cstr[0..c.strlen(tstamp_cstr)]; - free_str(tstamp); + std.debug.warn("tstamp: {}\ntopic: {}\nmsg: {}\n", tstamp, topic, message); - journal_write(journal, fmt_msg); + // catch unreachable is intended. + var fmt_msg = std.fmt.allocPrint( + allocator, + "[{}] [{}]: {}\n", + tstamp, + topic, + message, + ) catch |err| { + warn("Failed to make formatted message: {}\n", err); + return; + }; + + var fmt_msg_cstr = std.cstr.addNullByte( + allocator, + fmt_msg, + ) catch unreachable; + + free_str(tstamp_cstr); + + journal_write(journal, fmt_msg_cstr.ptr); } diff --git a/src/journal/main.c b/src/journal/main.c index da0d023..d145905 100644 --- a/src/journal/main.c +++ b/src/journal/main.c @@ -63,7 +63,7 @@ int main(int argc, char** argv) // default handling by journal_write_topic is marked // as the NULL values in this array. - void (*handlers[])(FILE*, char*) = { + void (*handlers[])(int, char*) = { NULL, NULL, NULL }; @@ -91,9 +91,13 @@ int main(int argc, char** argv) if(strcmp(topic, cur_topic) == 0) { - void (*fun_ptr)(FILE*, char*) = handlers[i]; + void (*fun_ptr)(int, char*) = handlers[i]; - FILE* journal_file = journal_open(topic); + int journal_file = journal_open(topic); + if(journal_file == -1) { + printf("failed to open journal file.\n"); + return 1; + } char *handler_message = extract_handler_msg(argc, argv); printf("[%s] said '%s'\n", topic, handler_message);