From 4beba07146b277c8ca169c82e387687f6f8d0645 Mon Sep 17 00:00:00 2001 From: cancel Date: Tue, 7 Jan 2020 01:45:49 +0900 Subject: [PATCH] Add start of prefs reading --- prefs.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ prefs.h | 16 ++++++++ tool | 2 +- 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 prefs.c create mode 100644 prefs.h diff --git a/prefs.c b/prefs.c new file mode 100644 index 0000000..b5a9cd2 --- /dev/null +++ b/prefs.c @@ -0,0 +1,111 @@ +#include "prefs.h" +#include + +ORCA_FORCE_NO_INLINE +Readprefs_result prefs_read_line(FILE* file, char* buf, Usz bufsize, + Usz* out_strlen, char** out_left, + Usz* out_leftsize, char** out_right, + Usz* out_rightsize) { + Usz len, a0, a1, b0, b1; + char* s; + *out_strlen = 0; + if (bufsize < 2) + goto insufficient_buffer; +#if SIZE_MAX > INT_MAX + if (bufsize > (Usz)INT_MAX) + exit(1); // he boot too big +#endif + s = fgets(buf, (int)bufsize, file); + if (!s) { + if (feof(file)) + goto eof; + goto ioerror; + } + len = strlen(buf); + if (len == bufsize - 1 && buf[len - 1] != '\n' && !feof(file)) + goto insufficient_buffer; + *out_strlen = len - 1; + a0 = 0; // start of left + for (;;) { + if (a0 == len) + goto ignore; + char c = s[a0]; + if (c == ';' || c == '#') // comment line, ignore + goto ignore; + if (c == '=') // '=' before any other char, bad + goto ignore; + if (!isspace(c)) + break; + a0++; + } + a1 = a0; // end of left + for (;;) { + a1++; + if (a1 == len) + goto ignore; + char c = s[a1]; + Usz x = a1; + while (isspace(c)) { + x++; + if (x == len) + goto ignore; + c = s[x]; + } + if (c == '=') { + b0 = x; + break; + } + a1 = x; + } + for (;;) { + b0++; + if (b0 == len) + goto ignore; + char c = s[b0]; + if (!isspace(c)) + break; + } + b1 = b0; // end of right + for (;;) { + b1++; + if (b1 == len) + goto ok; + char c = s[b1]; + Usz x = b1; + while (isspace(c)) { + x++; + if (x == len) + goto ok; + c = s[x]; + } + b1 = x; + } + Readprefs_result err; +insufficient_buffer: + err = Readprefs_buffer_too_small; + goto fail; +eof: + err = Readprefs_eof; + goto fail; +ioerror: + err = Readprefs_io_error; + goto fail; +ignore: + s[len - 1] = '\0'; + err = Readprefs_irrelevant; + goto fail; +fail: + *out_left = NULL; + *out_leftsize = 0; + *out_right = NULL; + *out_rightsize = 0; + return err; +ok: + s[a1] = '\0'; + s[b1] = '\0'; + *out_left = s + a0; + *out_leftsize = a1 - a0; + *out_right = s + b0; + *out_rightsize = b1 - b0; + return Readprefs_left_and_right; +} diff --git a/prefs.h b/prefs.h new file mode 100644 index 0000000..f1ef48f --- /dev/null +++ b/prefs.h @@ -0,0 +1,16 @@ +#pragma once +#include "base.h" +#include // FILE cannot be forward declared + +typedef enum { + Readprefs_left_and_right = 0, + Readprefs_irrelevant, + Readprefs_buffer_too_small, + Readprefs_eof, + Readprefs_io_error, +} Readprefs_result; + +Readprefs_result prefs_read_line(FILE* file, char* buf, Usz bufsize, + Usz* out_linelen, char** out_left, + Usz* out_leftlen, char** out_right, + Usz* out_rightlen); diff --git a/tool b/tool index 8d0e7ec..69b6016 100755 --- a/tool +++ b/tool @@ -308,7 +308,7 @@ build_target() { out_exe=cli ;; orca|tui) - add source_files osc_out.c term_util.c cboard.c tui_main.c + add source_files osc_out.c term_util.c cboard.c prefs.c tui_main.c add cc_flags -D_XOPEN_SOURCE_EXTENDED=1 # thirdparty headers (like sokol_time.h) should get -isystem for their # include dir so that any warnings they generate with our warning flags