From f3c63b0d45bd51286b0145aa3f506c16e2a9c98a Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 2 Feb 2023 18:53:59 -0800 Subject: [PATCH] Got source compiling. --- Makefile | 5 +- src/driver_flighthours.c | 50 ------------------- src/helper.h | 5 ++ src/journal.re.c | 9 ++-- src/source.h | 40 +++++++++++++++ src/source.re.c | 105 +++++++++++++++++++++++++++++++++++++++ test/test_source.c | 21 ++++++++ 7 files changed, 179 insertions(+), 56 deletions(-) delete mode 100644 src/driver_flighthours.c create mode 100644 src/source.h create mode 100644 src/source.re.c create mode 100644 test/test_source.c diff --git a/Makefile b/Makefile index 1e2b6b1..be80ea6 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ else CF += -g endif -projects := bin/test-text bin/test-journal bin/test-kjv bin/kjv bin/flight +projects := bin/test-text bin/test-journal bin/test-source bin/test-kjv bin/kjv bin/flight #docs := $(patsubst test/test_%.c, doc/%.md, $(wildcard test/test_*.c)) default: $(projects) @@ -37,6 +37,7 @@ default: $(projects) bin/test-text: build/text.o build/test_text.o bin/test-journal: build/text.o build/journal.o build/test_journal.o +bin/test-source: build/text.o build/journal.o build/source.o build/test_source.o bin/test-kjv: build/text.o build/kjv.o build/test_kjv.o bin/kjv: build/text.o build/journal.o build/kjv.o build/scan_kjv.o bin/flight: build/text.o build/journal.o build/flight.o build/flighthours.o @@ -69,7 +70,7 @@ build/%.c: src/%.re.c # # https://github.com/neil-edelman/cdoc documentation # -cdoc -o $@ $< -.SECONDARY: build/kjv.c build/journal.c build/scan_kjv.c build/flight.c +.SECONDARY: build/kjv.c build/journal.c build/source.c build/scan_kjv.c build/flight.c .PHONY: clean release test test: $(projects) diff --git a/src/driver_flighthours.c b/src/driver_flighthours.c deleted file mode 100644 index b794c70..0000000 --- a/src/driver_flighthours.c +++ /dev/null @@ -1,50 +0,0 @@ -/** @license 2023 Neil Edelman, distributed under the terms of the - [MIT License](https://opensource.org/licenses/MIT). - - Date _vs_ hours flown. */ - -#include "journal.h" -#include "scan_flight.h" -#include -#include -#include -#include - -int main(void) { - int success = EXIT_SUCCESS; - struct journal j; - struct journal_iterator it; - union date32 k; - union load *v; - size_t i; - j = journal(); - if(!journal_is_valid(&j)) goto catch; - fprintf(stderr, "Journal: %s.\n", journal_to_string(&j)); - printf("set term postscript eps enhanced\n" - "set output \"flighthours.eps\"\n" - "$Data <text, &kj)) goto catch; - printf("EOD\n" - "set monochrome\n" - "set xdata time\n" - "set timefmt \"%%Y-%%m-%%d\"\n" - "set xtics format \"%%Y-%%m-%%d\" rotate by -30\n" - "set ylabel \"words in KJV\"\n" - "set format y \"%%g%%%%\"\n" - "set key top left\n" - "set grid\n" - "unset border\n" - "#set style fill solid 0.1 #pattern 5 (better, but restarts)\n" - "plot $Data using 1:($3)*100/%zu with fillsteps lw 2 title \"set\", \\\n" - "$Data using 1:($4)*100/%zu with steps lw 1 title \"cumulative\"\n", - kj.words.total, kj.words.total); - goto finally; -catch: - success = EXIT_FAILURE; - perror("journal"); -finally: - journal_(&j); - return success; -} diff --git a/src/helper.h b/src/helper.h index fcce8ba..f4b9efc 100644 --- a/src/helper.h +++ b/src/helper.h @@ -17,3 +17,8 @@ static int helper_natural(const char *s, const char *const e, uint32_t *const n) *n = accum; return 1; } + +static void unused_helper_coda(void); +static void unused_helper(void) + { helper_natural(0, 0, 0); unused_helper_coda(); } +static void unused_helper_coda(void) { unused_helper(); } diff --git a/src/journal.re.c b/src/journal.re.c index 6f6def2..190b5c6 100644 --- a/src/journal.re.c +++ b/src/journal.re.c @@ -135,7 +135,7 @@ struct journal journal(void) { *p = year; } if(closedir(dir)) { dir = 0; goto catch; } dir = 0; - /* Sort the years for sensible ordering of parsing. */ + /* Sort the years. */ qsort(years.data, years.size, sizeof *years.data, &void_int_cmp); fprintf(stderr, "Years in <<%s>>: %s.\n", dir_journal, int_array_to_string(&years)); @@ -190,7 +190,8 @@ struct journal journal(void) { case TREE_ERROR: goto catch; case TREE_ABSENT: break; /* Expected. */ } - /* The pointers are not stable while we are loading it. */ + /* Because it's in a flat array, the pointers are not stable + while we are loading it, and we need to store the offsets. */ *v.offset = (uintptr_t)(contents - j.backing.a.data); } d = 0, int_array_clear(&days); @@ -202,7 +203,7 @@ struct journal journal(void) { if(chdir("..") == -1 || !day_tree_bulk_finish(&j.days)) goto catch; /* Structure is now stable because we aren't going to move it; - convert all of offsets to pointers. */ + convert all of offsets back to pointers. */ it = day_tree_begin(&j.days); while(day_tree_next(&it, 0, &v.text)) { /*printf("[%zu]...", *v.offset);*/ @@ -215,7 +216,7 @@ struct journal journal(void) { catch: fprintf(stderr, "On date: %s/%d-%.2d-%.2d.\n", dir_journal, y ? *y : 0, m ? *m : 0, d ? *d : 0 ); - if(intent) fprintf(stderr, "Explanation: %s.\n", intent); + if(intent) fprintf(stderr, "(%s)\n", intent); recatch: journal_(&j); finally: diff --git a/src/source.h b/src/source.h new file mode 100644 index 0000000..2a56bd8 --- /dev/null +++ b/src/source.h @@ -0,0 +1,40 @@ +#if defined BASE \ + || !defined BASE && !defined GENERIC && !defined PROTO /* */ + + +#if defined GENERIC \ + || !defined BASE && !defined GENERIC && !defined PROTO /* */ + + +#if defined PROTO \ + || !defined BASE && !defined GENERIC && !defined PROTO /* */ + +#ifdef BASE +#undef BASE +#endif +#ifdef GENERIC +#undef GENERIC +#endif +#ifdef PROTO +#undef PROTO +#endif diff --git a/src/source.re.c b/src/source.re.c new file mode 100644 index 0000000..45e3332 --- /dev/null +++ b/src/source.re.c @@ -0,0 +1,105 @@ +/** @license 2023 Neil Edelman, distributed under the terms of the + [MIT License](https://opensource.org/licenses/MIT). + @std C11 */ +#define BASE +#include "../src/source.h" /* base */ +#include "../src/journal.h" +#include +#include +#include + + + + + +static void source_to_string(const union line64 line, const struct substring *u, + char (*const a)[12]) { (void)u; date32_to_string(line.date, a); } +static int source_compare(const union line64 a, const union line64 b) + { return a.u64 > b.u64; } +#define TREE_NAME source +#define TREE_KEY union line64 +#define TREE_VALUE struct substring +#define TREE_COMPARE +#define TREE_TO_STRING +#include "../src/tree.h" + + +#define PROTO +#include "../src/source.h" /* proto */ + + +/*!conditions:re2c*/ + +static int scan(union date32 date, const char *const buffer, + struct sources *const s) { + const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *s0, *s1, *t0, *t1; + enum YYCONDTYPE condition = yycline; + size_t line = 1; + char datestr[12] = {0}; + const char *why = "unexpected"; + assert(buffer && s); + YYCURSOR = YYMARKER = yyt1 = buffer; + /*!re2c /**/ + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + re2c:define:YYGETCONDITION = "condition"; + re2c:define:YYSETCONDITION = "condition = @@;"; + re2c:define:YYGETCONDITION:naked = 1; + re2c:define:YYSETCONDITION:naked = 1; + + unix_control = [\x01-\x08\x0b-\x1f\x7f]; + ws = [ \t]; + glyph = [^] \ ("\x00" | "\n" | unix_control | ws); + keyword = [A-Za-z0-9][A-Za-z0-9_-]*; + */ + for( ; ; ) { + /*!re2c /**/ + /* Default ignore. */ + [^\n\x00] { continue; } + "\x00" { why = "no newline at end of file"; goto catch; } + "\x00" { return 1; } + "\n" => line { line++; continue; } + * :=> skip + "--" / [^-] :=> source + + * { why = "default source unrecognized"; goto catch; } + @s0 keyword @s1 / "\n" => skip { + printf("extracted <%.*s>\n", (int)(s1 - s0), s0); + continue; + } + /* This is lazy and will pickup trailing spaces. */ + @s0 keyword @s1 ":" [^\x00\n]+ / "\n" => skip { + printf("new keyword <%.*s>\n", (int)(s1 - s0), s0); + continue; + } + */ } + assert(0); /* Never gets here. */ +catch: + if(!errno) errno = EILSEQ; + date32_to_string(date, &datestr); + fprintf(stderr, "%s\n" + "%s line %zu: %s.\n", buffer, datestr, line, why); + return 0; +} +/** Dynamic memory allocation for `s` will be zero, will + be false. */ +void sources_(struct sources *const s) { + if(!s) return; + source_tree_(&s->_); +} + +struct sources sources(struct journal *const j) { + struct sources s; + struct journal_iterator it; + union date32 k; + const char *v; + assert(j); + s._ = source_tree(); + it = journal_begin(j); + while(journal_next(&it, &k, &v)) if(!scan(k, v, &s)) goto catch; + goto finally; +catch: + sources_(&s); +finally: + return s; +} diff --git a/test/test_source.c b/test/test_source.c new file mode 100644 index 0000000..fee8e93 --- /dev/null +++ b/test/test_source.c @@ -0,0 +1,21 @@ +#include "../src/journal.h" +#include "../src/source.h" +#include +#include +#include + +int main(void) { + int success = EXIT_SUCCESS; + errno = 0; + struct journal j = journal(); + struct sources s = sources(&j); + if(errno) goto catch; + printf("***success\n"); + goto finally; +catch: + success = EXIT_FAILURE, perror("source"); +finally: + sources_(&s); + journal_(&j); + return success; +}