compiled flighthours

This commit is contained in:
Neil 2023-02-01 23:18:20 -08:00
parent ebe78d18cc
commit 21729f8679
8 changed files with 193 additions and 30 deletions

View File

@ -29,7 +29,7 @@ else
CF += -g
endif
projects := bin/test-text bin/test-kjv bin/test-journal bin/kjv bin/flight
projects := bin/test-text bin/test-journal bin/test-kjv bin/kjv bin/flight
#docs := $(patsubst test/test_%.c, doc/%.md, $(wildcard test/test_*.c))
default: $(projects)
@ -39,7 +39,7 @@ 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-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/driver_flighthours.o
bin/flight: build/text.o build/journal.o build/flight.o build/flighthours.o
bin/%:
@echo "\033[1;36mlinking $@\033[0m"
@ -69,7 +69,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
.SECONDARY: build/kjv.c build/journal.c build/scan_kjv.c build/flight.c
.PHONY: clean release test
test: $(projects)

View File

@ -1,4 +1,5 @@
#ifndef OMIT_BASE /* <!-- base */
#if defined BASE \
|| !defined BASE && !defined GENERIC && !defined PROTO /* <!-- base */
#define LAUNCH_TYPE \
X(MotorCarTow),\
X(Winch),\
@ -22,6 +23,8 @@ static const char *flight_type_string[] = { FLIGHT_TYPE };
#undef X
#undef FLIGHT_TYPE
#include "helper.h"
struct glider {
struct substring type, reg, launch;
enum launch_type how;
@ -41,12 +44,11 @@ struct flight {
};
/*void kjvcite_to_string(const union kjvcite, char (*)[12]);*/
#else /* base --><!-- !base */
#undef OMIT_BASE
#endif /* !base --> */
#endif /* base --> */
#ifndef OMIT_INTERNAL /* <!-- external */
#if defined GENERIC \
|| !defined BASE && !defined GENERIC && !defined PROTO /* <!-- generic */
struct tree_flight_node;
struct tree_flight_tree { struct tree_flight_node *node; unsigned height; };
struct flight_tree { struct tree_flight_tree root; };
@ -55,18 +57,25 @@ struct tree_flight_iterator {
struct tree_flight_tree *root; struct tree_flight_ref ref; int seen;
};
struct flight_tree_iterator { struct tree_flight_iterator _; };
#else /* external --><!-- internal */
#undef OMIT_INTERNAL
#endif /* internal --> */
#endif /* generic --> */
#ifndef OMIT_PROTO /* <!-- proto */
#if defined PROTO \
|| !defined BASE && !defined GENERIC && !defined PROTO /* <!-- proto */
#include <stddef.h>
struct flights { struct flight_tree flights; };
struct flights flights(void);
struct flights { struct flight_tree _; };
struct flight *flights_add(struct flights *, const union line64);
struct flights flights(/*const*/ struct journal *);
void flights_(struct flights *);
int flights_is_valid(const struct flights *);
int flights_add(struct flights *, const struct flight);
const char *flight_to_string(const struct flight *);
#else /* proto --><!-- !proto */
#undef OMIT_PROTO
#endif /* !proto --> */
const char *flights_to_string(const struct flights *);
#endif /* proto --> */
#ifdef BASE
#undef BASE
#endif
#ifdef GENERIC
#undef GENERIC
#endif
#ifdef PROTO
#undef PROTO
#endif

113
src/flight.re.c Normal file
View File

@ -0,0 +1,113 @@
/** @license 2023 Neil Edelman, distributed under the terms of the
[MIT License](https://opensource.org/licenses/MIT).
@std C11 */
#define BASE
#include "../src/flight.h" /* base */
#include "../src/journal.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static void flight_to_string(const union line64 line, const struct flight *u,
char (*const a)[12]) { (void)u; date32_to_string(line.date, a); }
static int flight_compare(const union line64 a, const union line64 b)
{ return a.u64 > b.u64; }
#define TREE_NAME flight
#define TREE_KEY union line64
#define TREE_VALUE struct flight
#define TREE_COMPARE
#define TREE_TO_STRING
#include "../src/tree.h"
#define PROTO
#include "../src/flight.h" /* proto */
/*!conditions:re2c*/
static int scan(union date32 date, const char *const buffer,
struct flights *const f) {
const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3, *s0, *s1, *t0, *t1;
enum flight_type type = Glider;
enum YYCONDTYPE condition = yycline;
size_t line = 1;
char datestr[12] = {0};
const char *why = "unexpected";
assert(buffer && f);
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);
natural = [1-9][0-9]*;
*/
for( ; ; ) { /*!re2c /**/
/* Default ignore. */
<skip> [^\n\x00] { continue; }
<skip> "\x00" { why = "no newline at end of file"; goto catch; }
<line> "\x00" { return 1; }
<line, skip> "\n" => line { line++; continue; }
<line> * :=> skip
/* Except these two. */
<line> "[glider]" :=> glider
<line> "[flight]" :=> flight
/* "M" - Motor Car Tow
"W" - Winch
"A" - Aero Tow */
/* type; registration; launch -- landing; pic; sic;
single engine day dual; pilot; instrument simulated; actual; remarks */
<glider, flight> * { why = "default unrecognized"; goto catch; }
*/ }
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 `f` will be zero, <fn:flights_is_valid> will
be false. */
void flights_(struct flights *const f) {
if(!f) return;
flight_tree_(&f->_);
}
struct flights flights(/*const*/ struct journal *const j) {
struct flights f;
struct journal_iterator it;
union date32 k;
const char *v;
assert(j);
f._ = flight_tree();
it = journal_begin(j);
while(journal_next(&it, &k, &v)) if(!scan(k, v, &f)) goto catch;
goto finally;
catch:
flights_(&f);
finally:
return f;
}
struct flight *flights_add(struct flights *const flights,
const union line64 line) {
struct flight *flight;
assert(flights);
/* We assert that the flights are unique. */
switch(flight_tree_try(&flights->_, line, &flight)) {
case TREE_PRESENT: errno = EDOM;
case TREE_ERROR: return 0;
case TREE_ABSENT: return flight;
}
}

43
src/flighthours.c Normal file
View File

@ -0,0 +1,43 @@
/** @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 "flight.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
int main(void) {
int success = EXIT_SUCCESS;
struct journal j = journal();
union date32 k;
struct flights f = flights(&j);
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 <<EOD\n"
"# date\tminutes\tcumulative\n");
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 \"hours\"\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) with fillsteps lw 2\n");
goto finally;
catch:
success = EXIT_FAILURE;
perror("journal");
finally:
journal_(&j);
return success;
}

View File

@ -1,4 +1,4 @@
#include "helper.h"
#include "flight.h"
int scan(union date32, const char *, struct flights *);
int flight_scan(union date32, const char *, struct flight_tree *);

View File

@ -13,7 +13,7 @@
/*!conditions:re2c*/
int scan(union date32 date, const char *const buffer,
int flight_scan(union date32 date, const char *const buffer,
struct flights *const f) {
const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3, *s0, *s1, *t0, *t1;
enum flight_type type = Glider;

View File

@ -1 +0,0 @@

View File

@ -185,19 +185,18 @@ int main(void) {
int success = EXIT_SUCCESS;
struct journal j;
struct journal_iterator it;
struct kjv kj = kjv();
struct kjv bible = kjv();
union date32 k;
union load *v;
size_t i;
const char *v;
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 \"kjv.eps\"\n"
"$Data <<EOD\n"
"# date\tverse\tset\tcumulative / %zu\n", kj.words.total);
it = journal_begin(&j), i = 0; while(journal_next(&it, &k, &v))
if(!scan(k, v->text, &kj)) goto catch;
"# date\tverse\tset\tcumulative / %zu\n", bible.words.total);
it = journal_begin(&j);
while(journal_next(&it, &k, &v)) if(!scan(k, v, &bible)) goto catch;
printf("EOD\n"
"set monochrome\n"
"set xdata time\n"
@ -211,7 +210,7 @@ int main(void) {
"#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);
bible.words.total, bible.words.total);
goto finally;
catch:
success = EXIT_FAILURE;