Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
9ea7416ba6 | |||
b38c6d3155 | |||
d277afc48c | |||
b9cb570691 | |||
1f6f226943 | |||
7f8937db55 | |||
81fc10966d | |||
5d111433c3 |
2
Makefile
2
Makefile
@@ -64,7 +64,7 @@ build/%.o: build/%.c #src/%.h
|
||||
build/%.c: src/%.re.c
|
||||
@echo "\033[0;34mhttps://re2c.org/ generate $@\033[0m"
|
||||
@mkdir -p build
|
||||
re2c -W --tags --conditions -o $@ $<
|
||||
re2c -W -8 --tags --conditions -o $@ $<
|
||||
|
||||
#doc/%.md: src/%.h
|
||||
# # https://github.com/neil-edelman/cdoc documentation
|
||||
|
3
derived/.gitignore
vendored
3
derived/.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
*
|
||||
!.gitignore
|
||||
!interpret
|
||||
!kjv/
|
||||
!kjv/*
|
||||
|
1
derived/interpret
Normal file
1
derived/interpret
Normal file
@@ -0,0 +1 @@
|
||||
../../../Documents/journal/
|
65
src/driver.c
65
src/driver.c
@@ -10,41 +10,81 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h> /* getcwd, chdir */
|
||||
|
||||
int main(void) {
|
||||
const char *intent = "start";
|
||||
struct journal jrnl = {0};
|
||||
struct scan scn = {0};
|
||||
int showhelp = 1;
|
||||
FILE *fpwhere = 0;
|
||||
char cwd[PATH_MAX], jdir[PATH_MAX];
|
||||
|
||||
errno = 0;
|
||||
|
||||
intent = "journal (cwd)";
|
||||
intent = "current directory";
|
||||
if(!getcwd(cwd, sizeof(cwd))) goto catch;
|
||||
|
||||
intent = "interpret";
|
||||
if(!(fpwhere = fopen(intent, "r"))) goto catch;
|
||||
if(!fgets(jdir, sizeof jdir, fpwhere)) {
|
||||
if(!errno) errno = EDOM;
|
||||
fprintf(stderr, "first line error\n");
|
||||
goto catch;
|
||||
}
|
||||
if(fgetc(fpwhere) != EOF) {
|
||||
fprintf(stderr, "expected eof\n");
|
||||
errno = EDOM; goto catch;
|
||||
}
|
||||
/* Could be something other than EOF. */
|
||||
if(errno || (fclose(fpwhere) == EOF && (fpwhere = 0, 1))) goto catch;
|
||||
fpwhere = 0;
|
||||
jdir[strcspn(jdir, "\n")] = '\0'; /* Strip. */
|
||||
if(chdir(jdir)) {
|
||||
fprintf(stderr, "while switching to directory: %s\n", jdir);
|
||||
goto catch;
|
||||
}
|
||||
showhelp = 0;
|
||||
|
||||
intent = "interesting";
|
||||
perror("errno");
|
||||
if(errno) goto catch;
|
||||
|
||||
intent = "journal";
|
||||
jrnl = journal();
|
||||
fprintf(stderr, "Journal: %s.\n", journal_to_string(&jrnl));
|
||||
if(errno) goto catch;
|
||||
|
||||
intent = cwd;
|
||||
if(chdir(cwd)) goto catch;
|
||||
|
||||
intent = "parse";
|
||||
scn = scan(&jrnl);
|
||||
//fprintf(stderr, "Scan: %s.\n", scan_to_string(&scrs));
|
||||
// <- Not sure what that would do.
|
||||
if(errno) goto catch;
|
||||
|
||||
intent = "derived/score.gnu";
|
||||
intent = "score.gnu";
|
||||
if(!freopen(intent, "w", stdout)) goto catch;
|
||||
scan_score_graph(&scn);
|
||||
|
||||
intent = "derived/glider.gnu";
|
||||
intent = "labs.csv";
|
||||
if(!freopen(intent, "w", stdout)) goto catch;
|
||||
scan_labs_graph(&scn);
|
||||
|
||||
intent = "glider.gnu";
|
||||
if(!freopen(intent, "w", stdout)) goto catch;
|
||||
scan_glider_graph(&scn);
|
||||
|
||||
intent = "derived/flight.gnu";
|
||||
intent = "flight.gnu";
|
||||
if(!freopen(intent, "w", stdout)) goto catch;
|
||||
scan_flight_graph(&scn);
|
||||
|
||||
intent = "derived/kjv.gnu";
|
||||
intent = "kjv.gnu";
|
||||
if(!freopen(intent, "w", stdout)) goto catch;
|
||||
scan_kjv_graph(&scn);
|
||||
|
||||
intent = "derived/dream.gnu";
|
||||
intent = "dream.gnu";
|
||||
if(!freopen(intent, "w", stdout)) goto catch;
|
||||
scan_dream_graph(&scn);
|
||||
|
||||
@@ -52,10 +92,23 @@ int main(void) {
|
||||
goto finally;
|
||||
catch:
|
||||
perror(intent);
|
||||
/* Don't know if that will give real insight into the problem… */
|
||||
if(freopen("error.txt", "w", stdout)) {
|
||||
printf("Journal: %s.\n", journal_to_string(&jrnl));
|
||||
}
|
||||
finally:
|
||||
/* fixme: ~scan should be idempotent but it's not on disabling ASLR, which
|
||||
debug mode is in. */
|
||||
if(fpwhere && fclose(fpwhere) == EOF)
|
||||
intent = "interpret", perror(intent);
|
||||
scan_(&scn);
|
||||
journal_(&jrnl);
|
||||
if(intent && showhelp)
|
||||
fprintf(stderr, "\nMeant to be run in a directory with a file called "
|
||||
"\"interpret\".\n"
|
||||
"The contents of that file shall be a directory wherein\n"
|
||||
"<year>/<month>/<day>.txt, eg 2000/12/01.txt.\n"
|
||||
"Loads all journal entries and parses them, outputting to the "
|
||||
"current directory.\n\n");
|
||||
return intent ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
@@ -215,7 +215,7 @@ struct journal journal(void/*const char *const dir_journal*/) {
|
||||
m = 0, int_array_clear(&months);
|
||||
if(chdir("..") == -1) goto catch;
|
||||
}
|
||||
if(/*chdir("../..") == -1 ||*/ !day_tree_bulk_finish(&j.days)) goto catch;
|
||||
if(!day_tree_bulk_finish(&j.days)) goto catch;
|
||||
|
||||
/* Structure is now stable because we aren't going to move it;
|
||||
convert all of offsets back to pointers. */
|
||||
|
18
src/kjv.re.c
18
src/kjv.re.c
@@ -78,7 +78,7 @@ static void kjvcount_to_string(const union kjvcite x, const unsigned count,
|
||||
/* Parse filename of books. */
|
||||
/*!re2c /**/
|
||||
re2c:yyfill:enable = 0;
|
||||
re2c:define:YYCTYPE = char;
|
||||
re2c:define:YYCTYPE = "unsigned char";
|
||||
natural = [1-9][0-9]*;
|
||||
whitespace = [ \t\v\f];
|
||||
word = [^ \t\v\f\n\x00]+;
|
||||
@@ -86,13 +86,14 @@ word = [^ \t\v\f\n\x00]+;
|
||||
/** `fn` contains "<number>[*].txt", sticks that in `book_no`, otherwise
|
||||
returns false. */
|
||||
static int looks_like_book_fn(const char *fn, unsigned *const book_no) {
|
||||
const char *YYCURSOR = fn, *YYMARKER, *yyt1, *yyt2, *s0, *s1;
|
||||
const unsigned char *YYCURSOR = (const unsigned char *)fn,
|
||||
*YYMARKER, *yyt1, *yyt2, *s0, *s1;
|
||||
assert(fn && book_no);
|
||||
/*!re2c /**/
|
||||
*
|
||||
{ return 0; }
|
||||
@s0 natural @s1 [^.\x00]* ".txt" "\x00"
|
||||
{ return pair_to_natural(s0, s1, book_no); }
|
||||
{ return pair_to_natural(pair_u(s0, s1), book_no); }
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -100,22 +101,23 @@ static int looks_like_book_fn(const char *fn, unsigned *const book_no) {
|
||||
/* This is the contents of the <fn:looks_like_book_fn>. */
|
||||
struct lex {
|
||||
size_t line;
|
||||
const char *cursor;
|
||||
const unsigned char *cursor;
|
||||
int error;
|
||||
uint32_t chapter, verse, words;
|
||||
};
|
||||
static struct lex lex(const char *cursor) {
|
||||
struct lex lex;
|
||||
union { const unsigned char *u; const char *s; } flex = { .s = cursor };
|
||||
assert(cursor);
|
||||
lex.line = 1;
|
||||
lex.cursor = cursor;
|
||||
lex.cursor = flex.u;
|
||||
lex.error = 0;
|
||||
lex.chapter = lex.verse = lex.words = 0;
|
||||
return lex;
|
||||
}
|
||||
/*!conditions:re2c*/
|
||||
static int lex_next_verse(struct lex *const lex) {
|
||||
const char *YYMARKER, *yyt1 = 0, *yyt2 = 0, *s0, *s1, *t0, *t1;
|
||||
const unsigned char *YYMARKER, *yyt1 = 0, *yyt2 = 0, *s0, *s1, *t0, *t1;
|
||||
enum YYCONDTYPE condition = yycline;
|
||||
/*!re2c /**/
|
||||
re2c:define:YYCURSOR = lex->cursor;
|
||||
@@ -131,8 +133,8 @@ scan:
|
||||
<line> [^[\]\n\x00]* "\n" { lex->line++; goto scan; }
|
||||
<line> "\x00" { return 0; }
|
||||
<line> "[" @s0 natural @s1 ":" @t0 natural @t1 "]" => verse {
|
||||
if(!pair_to_natural(s0, s1, &lex->chapter)
|
||||
|| !pair_to_natural(t0, t1, &lex->verse))
|
||||
if(!pair_to_natural(pair_u(s0, s1), &lex->chapter)
|
||||
|| !pair_to_natural(pair_u(t0, t1), &lex->verse))
|
||||
return errno = EILSEQ, lex->error = 1, 0;
|
||||
lex->words = 0;
|
||||
/*printf("%u:%u", lex->chapter, lex->verse);*/
|
||||
|
56
src/pair.c
56
src/pair.c
@@ -18,45 +18,48 @@ struct pair pair(const char *const a, const char *const b) {
|
||||
return p;
|
||||
}
|
||||
|
||||
/** @returns Constructs `a` and `b` as unsigned. */
|
||||
struct pair pair_u(const unsigned char *const a, const unsigned char *const b)
|
||||
{ return pair((const char *)a, (const char *)b); }
|
||||
|
||||
/** Doesn't check if the number is actually in [0, 9].
|
||||
@return Whether it was able to parse unsigned [`a`, `b`] to `n`. */
|
||||
int pair_to_natural(const char *a, const char *const b, uint32_t *const n) {
|
||||
int pair_to_natural(struct pair p, uint32_t *const n) {
|
||||
uint32_t accum = 0;
|
||||
while(a < b) {
|
||||
unsigned next = accum * 10 + (unsigned)(*a - '0');
|
||||
while(p.a < p.b) {
|
||||
uint32_t next = accum * 10 + (uint32_t)(*p.a - '0');
|
||||
if(accum > next) return errno = ERANGE, 0;
|
||||
accum = next;
|
||||
a++;
|
||||
p.a++;
|
||||
}
|
||||
return *n = accum, 1;
|
||||
}
|
||||
|
||||
static int pair_to_64(const char *a, const char *const b, uint64_t *const n) {
|
||||
static int pair_to_64(struct pair p, uint64_t *const n) {
|
||||
uint64_t accum = 0;
|
||||
while(a < b) {
|
||||
uint64_t next = accum * 10 + (uint64_t)(*a - '0');
|
||||
while(p.a < p.b) {
|
||||
uint64_t next = accum * 10 + (uint64_t)(*p.a - '0');
|
||||
if(accum > next) return errno = ERANGE, 0;
|
||||
accum = next;
|
||||
a++;
|
||||
p.a++;
|
||||
}
|
||||
return *n = accum, 1;
|
||||
}
|
||||
|
||||
/** `h0` "1" `h1` ":" `m0` "30" `m1` -> 90 `n` @return Valid. */
|
||||
int pair_colon_to_minutes(const char *h0, const char *const h1,
|
||||
const char *m0, const char *const m1, uint32_t *const n) {
|
||||
/** `h` "1" ":" `m` "30" -> 90 `n` @return Valid. */
|
||||
int pair_colon_to_minutes(struct pair h, struct pair m, uint32_t *const n) {
|
||||
uint32_t hours, minutes;
|
||||
return pair_to_natural(h0, h1, &hours) && pair_to_natural(m0, m1, &minutes)
|
||||
return pair_to_natural(h, &hours) && pair_to_natural(m, &minutes)
|
||||
&& minutes < 60 && hours <= UINT32_MAX / 60 - minutes
|
||||
? (*n = hours * 60 + minutes, 1) : 0;
|
||||
}
|
||||
|
||||
/** `h0` "1" `h1` "." `m0` "5" `m1` -> 90 `n` @return Valid. */
|
||||
int pair_hours_to_minutes(const char *h0, const char *const h1,
|
||||
const char *m0, const char *const m1, uint32_t *const n) {
|
||||
int pair_decimal_hours_to_minutes(struct pair h, struct pair m,
|
||||
uint32_t *const n) {
|
||||
uint32_t hours, minutes;
|
||||
/* fixme: more precision? */
|
||||
return pair_to_natural(h0, h1, &hours) && pair_to_natural(m0, m1, &minutes)
|
||||
return pair_to_natural(h, &hours) && pair_to_natural(m, &minutes)
|
||||
&& minutes <= 9 && hours <= UINT32_MAX / 60 - minutes * 6
|
||||
? (*n = hours * 60 + minutes * 6, 1) : 0;
|
||||
}
|
||||
@@ -109,12 +112,12 @@ no:
|
||||
@return Success.
|
||||
@throws[ERANGE] Year is more then 23 bits.
|
||||
@throws[EILSEQ] The is not a date? */
|
||||
int pair_to_date(const char *a, union date32 *const d) {
|
||||
int pair_to_date(const unsigned char *a, union date32 *const d) {
|
||||
uint32_t year = 0, month, day;
|
||||
union date32 temp;
|
||||
assert(a && d);
|
||||
while(*a >= '0' && *a <= '9') {
|
||||
year = year * 10 + (unsigned)(*a - '0');
|
||||
assert(d);
|
||||
while(a[0] >= '0' && a[0] <= '9') {
|
||||
year = year * 10 + (unsigned)(a[0] - '0');
|
||||
if(year > 0x7FFFFF) return errno = ERANGE, 0; /* 23 bits */
|
||||
a++;
|
||||
}
|
||||
@@ -128,17 +131,16 @@ int pair_to_date(const char *a, union date32 *const d) {
|
||||
return *d = temp, 1;
|
||||
}
|
||||
|
||||
int pair_to_cents(const char *a, const char *b, int64_t *const cents) {
|
||||
int pair_to_cents(struct pair p, int64_t *const cents) {
|
||||
uint64_t d, c;
|
||||
int is_negative;
|
||||
assert(a && a < b && cents);
|
||||
if(a[0] == '-') is_negative = 1, a++, assert(a < b);
|
||||
else is_negative = 0;
|
||||
if(a + 2 < b && b[-3] == '.') { /* dollars.cents */
|
||||
if(!pair_to_64(a, b - 3, &d)) return 0;
|
||||
c = (uint64_t)(b[-2] - '0') * 10 + (uint64_t)(b[-1] - '0');
|
||||
assert(p.a < p.b && cents);
|
||||
if(p.a[0] == '-') is_negative = 1, p.a++; else is_negative = 0;
|
||||
if(p.a + 2 < p.b && p.b[-3] == '.') { /* dollars.cents */
|
||||
if(!pair_to_64(pair(p.a, p.b - 3), &d)) return 0;
|
||||
c = (uint64_t)(p.b[-2] - '0') * 10 + (uint64_t)(p.b[-1] - '0');
|
||||
} else { /* dollars */
|
||||
if(!pair_to_64(a, b, &d)) return 0;
|
||||
if(!pair_to_64(pair(p.a, p.b), &d)) return 0;
|
||||
c = 0;
|
||||
}
|
||||
assert(-INT64_MAX >= INT64_MIN);
|
||||
|
15
src/pair.h
15
src/pair.h
@@ -5,17 +5,16 @@
|
||||
|
||||
struct pair { const char *a, *b; };
|
||||
|
||||
struct pair pair(const char *const a, const char *const b);
|
||||
int pair_to_natural(const char *, const char *, uint32_t *);
|
||||
int pair_colon_to_minutes(const char *, const char *,
|
||||
const char *, const char *, uint32_t *);
|
||||
int pair_hours_to_minutes(const char *h0, const char *const h1,
|
||||
const char *m0, const char *const m1, uint32_t *const n);
|
||||
struct pair pair(const char *, const char *);
|
||||
struct pair pair_u(const unsigned char *, const unsigned char *);
|
||||
int pair_to_natural(struct pair, uint32_t *);
|
||||
int pair_colon_to_minutes(struct pair h, struct pair m, uint32_t *);
|
||||
int pair_decimal_hours_to_minutes(struct pair h, struct pair m, uint32_t *const n);
|
||||
int pair_is_equal(struct pair, struct pair);
|
||||
int pair_is_string(struct pair, const char *);
|
||||
#include "journal.h" /* date32 */
|
||||
int pair_to_date(const char *, union date32 *);
|
||||
int pair_to_cents(const char *, const char *, int64_t *);
|
||||
int pair_to_date(const unsigned char *a, union date32 *);
|
||||
int pair_to_cents(struct pair p, int64_t *);
|
||||
uint32_t pair_djb2(struct pair);
|
||||
|
||||
/* Supporting pair -> size_t for looking up in arrays. */
|
||||
|
@@ -147,7 +147,7 @@ struct scan {
|
||||
} edits;
|
||||
struct linepair_tree dreams;
|
||||
struct linekvpair_tree contacts, books, tvs, movies, ideas,
|
||||
vaccines, medications, mails, couches;
|
||||
vaccines, medications, labs, mails, couches;
|
||||
struct linekvdate_tree froms;
|
||||
struct linekvmoney_tree taxes, incomes;
|
||||
struct glider_tree gliders;
|
||||
@@ -159,6 +159,7 @@ void scan_(struct scan *);
|
||||
struct scan scan(struct journal *);
|
||||
const struct kvpair *scan_source_lookup(struct scan *, const union line64);
|
||||
void scan_score_graph(struct scan *);
|
||||
void scan_labs_graph(struct scan *);
|
||||
void scan_glider_graph(struct scan *);
|
||||
void scan_flight_graph(struct scan *);
|
||||
void scan_kjv_graph(struct scan *);
|
||||
|
216
src/scan.re.c
216
src/scan.re.c
@@ -164,16 +164,21 @@ static int kjv_compare(const union line64 a, const union line64 b)
|
||||
|
||||
|
||||
/*!conditions:re2c */
|
||||
/*!flags:utf-8 */
|
||||
/*!include:re2c "unicode_categories.re" */
|
||||
|
||||
|
||||
static int scan_day(struct scan *const scan, union date32 date,
|
||||
const char *const buffer) {
|
||||
const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3, *s0, *s1, *t0, *t1;
|
||||
const unsigned char *const buffer_u = (const unsigned char *)buffer,
|
||||
*YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3,
|
||||
*lastnl = buffer_u, *s0 = 0, *s1, *t0, *t1;
|
||||
enum YYCONDTYPE condition = yycline;
|
||||
/* All '\n' might overflow on last, but it wouldn't matter because there's
|
||||
no content. */
|
||||
size_t line = 1;
|
||||
char datestr[12] = {0};
|
||||
const char *fail = "perhaps a bat?", *lastnl = buffer;
|
||||
const char *fail = "perhaps a bat?";
|
||||
struct {
|
||||
enum YYCONDTYPE future;
|
||||
union {
|
||||
@@ -189,11 +194,11 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
} kjv = { Revelation, 0, 0, 0 };
|
||||
|
||||
assert(scan && date.u32 && buffer);
|
||||
YYCURSOR = YYMARKER = yyt1 = buffer;
|
||||
YYCURSOR = YYMARKER = yyt1 = buffer_u;
|
||||
date32_to_string(date, &datestr);
|
||||
|
||||
/*!re2c /**/
|
||||
re2c:define:YYCTYPE = char;
|
||||
re2c:define:YYCTYPE = "unsigned char";
|
||||
re2c:yyfill:enable = 0;
|
||||
re2c:define:YYGETCONDITION = "condition";
|
||||
re2c:define:YYSETCONDITION = "condition = @@;";
|
||||
@@ -215,7 +220,11 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
// label except start "()"; used in location
|
||||
parlabel = (parchar glyph*) (ws+ glyph+)*;
|
||||
|
||||
keyword = [A-Za-z0-9][A-Za-z0-9_-]*;
|
||||
//keyword = [A-Za-z0-9][A-Za-z0-9_-]*;
|
||||
//keyword = [A-Za-z0-9_-é]+;
|
||||
//keyword = [A-Za-z0-9_-]_;
|
||||
// letter number dash connector
|
||||
keyword = (L|N) (L|N|Pd|Pc)*;
|
||||
|
||||
uint = [0-9]+;
|
||||
natural = [1-9][0-9]*;
|
||||
@@ -225,13 +234,14 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
airport = [A-Z0-9]{4,4};
|
||||
moneyamount = "-"? [0-9]+ ("." [0-9][0-9])?; // fixme?
|
||||
kjvlookat = ws* natural ":" natural [ab]? ("-" natural [ab]?)? ws+ "--" ws+;
|
||||
first = ("I" | "1") " "?;
|
||||
second = ("II" | "2") " "?;
|
||||
third = ("III" | "3") " "?;
|
||||
first = ("I" | "1" | "Ⅰ") " "?;
|
||||
second = ("II" | "2" | "Ⅱ") " "?;
|
||||
third = ("III" | "3" | "Ⅲ") " "?;
|
||||
*/
|
||||
for( ; ; ) {
|
||||
/*!re2c /**/
|
||||
<skip> [^\n\x00] { continue; } /* Default ignore. */
|
||||
//<skip> [^\n\x00] { continue; } /* Default ignore. */
|
||||
<skip> * { continue; }
|
||||
<newline> * { fail = "newline expected"; goto catch; }
|
||||
<skip> "\x00" { fail = "no newline at end of file"; goto catch; }
|
||||
<line> "\x00" { return 1; } /* End of day. */
|
||||
@@ -256,6 +266,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<bracket> "idea: " :=> idea
|
||||
<bracket> "vaccine: " :=> vaccine
|
||||
<bracket> "medication: " :=> medication
|
||||
<bracket> "lab: " :=> lab
|
||||
<bracket> "tax: " :=> tax
|
||||
<bracket> "in: " :=> income
|
||||
<bracket> "mail: " :=> mail
|
||||
@@ -290,7 +301,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
size_t *pi;
|
||||
struct kvpair *doc;
|
||||
if(!(doc = kvpair_array_new(&scan->documents.array))) goto catch;
|
||||
doc->key.a = s0, doc->key.b = s1;
|
||||
doc->key.a = (const char *)s0, doc->key.b = (const char *)s1;
|
||||
doc->value.a = 0, doc->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &doc->value;
|
||||
switch(linemap_tree_bulk_assign(&scan->documents.dates, key, &pi)) {
|
||||
@@ -332,7 +343,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new contact <<%.*s>>.\n",
|
||||
@@ -348,7 +359,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new book <<%.*s>>.\n",
|
||||
@@ -364,7 +375,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new tv <<%.*s>>.\n",
|
||||
@@ -380,7 +391,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new movie <<%.*s>>.\n",
|
||||
@@ -396,7 +407,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new idea <<%.*s>>.\n",
|
||||
@@ -412,7 +423,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new vaccine <<%.*s>>.\n",
|
||||
@@ -428,7 +439,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new medication <<%.*s>>.\n",
|
||||
@@ -436,6 +447,22 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
continue;
|
||||
}
|
||||
|
||||
<lab> * { fail = "lab unrecognized"; goto catch; }
|
||||
<lab> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->labs, key, &pair)) {
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new lab <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<tax> * { fail = "tax unrecognized"; goto catch; }
|
||||
<tax> @s0 bralabel @s1 "]" => input_money {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
@@ -444,7 +471,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value = (struct money){0, CAD};
|
||||
input.future = yycnewline, input.money = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new tax <<%.*s>>.\n",
|
||||
@@ -460,7 +487,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value = (struct money){0, CAD};
|
||||
input.future = yycline, input.money = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new income <<%.*s>>.\n",
|
||||
@@ -476,7 +503,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new mail <<%.*s>>.\n",
|
||||
@@ -492,7 +519,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->key = pair_u(s0, s1);
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new couch <<%.*s>>.\n",
|
||||
@@ -508,7 +535,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
if(!pair_to_date(s0, &pair->key)) goto catch;
|
||||
if(!pair_to_date(s0, &pair->key)) goto catch; /* hmm */
|
||||
pair->value.a = pair->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &pair->value;
|
||||
fprintf(stderr, "%s:%zu: new from.\n", datestr, line);
|
||||
@@ -517,7 +544,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
|
||||
<place> * { fail = "place unrecognized"; goto catch; }
|
||||
<place> @s0 parlabel @s1 / "\n" => skip { also_place: {
|
||||
const struct pair keyword = pair(s0, s1);
|
||||
const struct pair keyword = pair_u(s0, s1);
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
size_t i, *pi;
|
||||
/*fprintf(stderr, "map: <<%.*s>> out of %s\n", (int)(s1 - s0), s0,
|
||||
@@ -533,8 +560,8 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
} continue; }
|
||||
<place> "(" @t0 decimal "," @t1 decimal ")"
|
||||
ws+ @s0 parlabel @s1 / "\n" => skip {
|
||||
const struct pair keyword = pair(s0, s1);
|
||||
const double x = strtod(t0, 0), y = strtod(t1, 0); /* Safe? */
|
||||
const struct pair keyword = pair_u(s0, s1);
|
||||
const double x = strtod(keyword.a, 0), y = strtod(keyword.b, 0);
|
||||
size_t *idx;
|
||||
struct place *place;
|
||||
switch(pair_map_table_assign(&scan->places.map, keyword, &idx)) {
|
||||
@@ -544,7 +571,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
if(!(place = place_array_new(&scan->places.array))) goto catch;
|
||||
*idx = (size_t)(place - scan->places.array.data);
|
||||
place->name.a = s0, place->name.b = s1;
|
||||
place->name = keyword;
|
||||
place->x = x, place->y = y;
|
||||
fprintf(stderr,
|
||||
"%s:%zu: new place: <<%.*s>> at (%f,%f) stored at %zu.\n",
|
||||
@@ -555,7 +582,8 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<place> "(" @t0 decimal "," @t1 decimal ")" / "\n" => skip {
|
||||
size_t *idx;
|
||||
struct place *place;
|
||||
const double x = strtod(t0, 0), y = strtod(t1, 0); /* Safe? */
|
||||
const struct pair t = pair_u(t0, t1);
|
||||
const double x = strtod(t.a, 0), y = strtod(t.b, 0); /* Safe? */
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
if(!(place = place_array_new(&scan->places.array))) goto catch;
|
||||
place->name.a = place->name.b = 0;
|
||||
@@ -572,7 +600,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
|
||||
<source> * { fail = "source unrecognized"; goto catch; }
|
||||
<source> @s0 keyword @s1 / "\n" => skip { also_source: {
|
||||
const struct pair keyword = pair(s0, s1);
|
||||
const struct pair keyword = pair_u(s0, s1);
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
size_t i, *pi;
|
||||
if(!(i = pair_map_table_get(&scan->sources.map, keyword)))
|
||||
@@ -586,7 +614,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
} continue; }
|
||||
/* New source. */
|
||||
<source> @s0 keyword @s1 ":" => input_text {
|
||||
struct pair keyword = pair(s0, s1);
|
||||
struct pair keyword = pair_u(s0, s1);
|
||||
size_t *idx;
|
||||
struct kvpair *source;
|
||||
switch(pair_map_table_assign(&scan->sources.map, keyword, &idx)) {
|
||||
@@ -596,7 +624,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
if(!(source = kvpair_array_new(&scan->sources.array))) goto catch;
|
||||
*idx = (size_t)(source - scan->sources.array.data);
|
||||
source->key.a = s0, source->key.b = s1;
|
||||
source->key = keyword;
|
||||
source->value.a = 0, source->value.b = 0;
|
||||
input.future = yycnewline, input.pair = &source->value;
|
||||
fprintf(stderr, "%s:%zu: new source <<%.*s>> stored at %zu.\n",
|
||||
@@ -609,7 +637,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
/* Already there. Use the map to get the index from the keyword and
|
||||
then stick a marker in the tree with that index. */
|
||||
<score> @s0 keyword @s1 / "\n" => skip { new_score: {
|
||||
const struct pair keyword = pair(s0, s1);
|
||||
const struct pair keyword = pair_u(s0, s1);
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
size_t idx, *pidx;
|
||||
if(!(idx = pair_map_table_get(&scan->scores.map, keyword)))
|
||||
@@ -628,10 +656,10 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
/* New score. */
|
||||
<score> @s0 keyword @s1 ":" => score_name {
|
||||
size_t *idx;
|
||||
const struct pair keyword = pair_u(s0, s1);
|
||||
assert(!new_score);
|
||||
/* Create a new mapping from dateline to scores array. */
|
||||
switch(pair_map_table_assign(&scan->scores.map,
|
||||
pair(s0, s1), &idx)) {
|
||||
switch(pair_map_table_assign(&scan->scores.map, keyword, &idx)) {
|
||||
case TABLE_PRESENT: errno = EDOM; fail = "new keyword already used";
|
||||
case TABLE_ERROR: goto catch; /* _Sic_. */
|
||||
case TABLE_ABSENT: *idx = 0; break;
|
||||
@@ -640,7 +668,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
if(!(new_score = score_array_new(&scan->scores.array))) goto catch;
|
||||
*idx = (size_t)(new_score - scan->scores.array.data); /* Offset. */
|
||||
/*struct pair key, name; union date32 date, last; unsigned edges;*/
|
||||
new_score->key.a = s0, new_score->key.b = s1;
|
||||
new_score->key = keyword;
|
||||
new_score->name.a = 0, new_score->name.b = 0;
|
||||
new_score->date.u32 = new_score->last.u32 = 0;
|
||||
new_score->edges = 0, new_score->score = 0;
|
||||
@@ -651,7 +679,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<score_name> * { fail = "name unrecognized"; goto catch; }
|
||||
<score_name> ws* @s0 semilabel @s1 ";" => score_date {
|
||||
assert(new_score);
|
||||
new_score->name.a = s0, new_score->name.b = s1;
|
||||
new_score->name = pair_u(s0, s1);
|
||||
continue;
|
||||
}
|
||||
<score_date> * { fail = "date unrecognized"; goto catch; }
|
||||
@@ -662,8 +690,9 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
<score_edges> * { fail = "edges unrecognized"; goto catch; }
|
||||
<score_edges> ws* "~"? @s0 uint @s1 / "\n" => skip {
|
||||
const struct pair s = pair_u(s0, s1);
|
||||
assert(new_score);
|
||||
if(!pair_to_natural(s0, s1, &new_score->edges)) goto catch;
|
||||
if(!pair_to_natural(s, &new_score->edges)) goto catch;
|
||||
new_score = 0; /* Done. */
|
||||
continue;
|
||||
}
|
||||
@@ -679,15 +708,15 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
new_glider->type.a = s0, new_glider->type.b = s1;
|
||||
new_glider->type = pair_u(s0, s1);
|
||||
continue;
|
||||
}
|
||||
<glider_reg> * { fail = "glider reg"; goto catch; }
|
||||
<glider_reg> ws* @s0 semilabel @s1 ";" => glider_launch
|
||||
{ new_glider->reg.a = s0, new_glider->reg.b = s1; continue; }
|
||||
{ new_glider->reg = pair_u(s0, s1); continue; }
|
||||
<glider_launch> * { fail = "glider launch"; goto catch; }
|
||||
<glider_launch> ws* @s0 airport @s1 ";" => glider_how {
|
||||
new_glider->launch.a = s0, new_glider->launch.b = s1;
|
||||
new_glider->launch = pair_u(s0, s1);
|
||||
fprintf(stderr, "%s:%zu: glider <<%.*s>> at <<%.*s>>\n",
|
||||
datestr, line, (int)(new_glider->reg.b - new_glider->reg.a),
|
||||
new_glider->reg.a, (int)(s1 - s0), s0);
|
||||
@@ -703,38 +732,46 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
continue;
|
||||
}
|
||||
<glider_height> * { fail = "glider height"; goto catch; }
|
||||
<glider_height> ws* @s0 natural @s1 "';" => glider_landing
|
||||
{ if(!pair_to_natural(s0, s1, &new_glider->height_ft)); continue; }
|
||||
<glider_height> ws* @s0 natural @s1 "';" => glider_landing {
|
||||
const struct pair s = pair_u(s0, s1);
|
||||
if(!pair_to_natural(s, &new_glider->height_ft));
|
||||
continue;
|
||||
}
|
||||
<glider_landing> * { fail = "glider landing"; goto catch; }
|
||||
<glider_landing> ws* @s0 airport @s1 ";" => glider_pilot
|
||||
{ new_glider->landing.a = s0, new_glider->landing.b = s1; continue;}
|
||||
{ new_glider->landing = pair_u(s0, s1); continue;}
|
||||
<glider_pilot> * { fail = "glider pilot time"; goto catch; }
|
||||
<glider_pilot> ws* ";" => glider_dual /* not PIC */
|
||||
{ new_glider->pilot_min = 0; continue; }
|
||||
<glider_pilot> ws* @s0 natural? @s1 ":" @t0 minutes @t1 ws* ";"
|
||||
=> glider_dual { if(!pair_colon_to_minutes(s0, s1, t0, t1,
|
||||
=> glider_dual {
|
||||
if(!pair_colon_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_glider->pilot_min)) { fail = "glider pilot time"; goto catch; }
|
||||
continue; }
|
||||
<glider_dual> * { fail = "glider dual time"; goto catch; }
|
||||
<glider_dual> ws* ";" => glider_instr
|
||||
{ new_glider->dual_min = 0; continue; }
|
||||
<glider_dual> ws* @s0 natural? @s1 ":" @t0 minutes @t1 ws* ";"
|
||||
=> glider_instr { if(!pair_colon_to_minutes(s0, s1, t0, t1,
|
||||
=> glider_instr {
|
||||
if(!pair_colon_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_glider->dual_min)) { fail = "glider dual time"; goto catch; }
|
||||
continue; }
|
||||
continue;
|
||||
}
|
||||
<glider_instr> * { fail = "glider instr time"; goto catch; }
|
||||
<glider_instr> ws* ";" => glider_remarks
|
||||
{ new_glider->instr_min = 0; continue; }
|
||||
<glider_instr> ws* @s0 natural? @s1 ":" @t0 minutes @t1 ws* ";"
|
||||
=> glider_remarks { if(!pair_hours_to_minutes(s0, s1, t0, t1,
|
||||
=> glider_remarks {
|
||||
if(!pair_decimal_hours_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_glider->instr_min)) { fail = "glider instr time"; goto catch; }
|
||||
continue; }
|
||||
continue;
|
||||
}
|
||||
<glider_remarks> * { fail = "glider remarks"; goto catch; }
|
||||
<glider_remarks> "\n" @s1 => line
|
||||
{ new_glider->remarks.a = new_glider->remarks.b = 0;
|
||||
new_glider = 0; line++; lastnl = s1; continue; }
|
||||
<glider_remarks> ws* @s0 anylabel @s1 "\n" @t1 => line
|
||||
{ new_glider->remarks.a = s0, new_glider->remarks.b = s1;
|
||||
{ new_glider->remarks = pair_u(s0, s1);
|
||||
new_glider = 0; line++; lastnl = t1; continue; }
|
||||
|
||||
|
||||
@@ -749,17 +786,17 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
new_flight->type.a = s0, new_flight->type.b = s1;
|
||||
new_flight->type = pair_u(s0, s1);
|
||||
continue;
|
||||
}
|
||||
<flight_reg> * { fail = "flight reg"; goto catch; }
|
||||
<flight_reg> ws* @s0 semilabel @s1 ";" => flight_airports
|
||||
{ new_flight->reg.a = s0, new_flight->reg.b = s1; continue; }
|
||||
{ new_flight->reg = pair_u(s0, s1); continue; }
|
||||
<flight_airports> * { fail = "flight airports"; goto catch; }
|
||||
<flight_airports> ws* @s0 airport @s1 ws* "--"
|
||||
ws* @t0 airport @t1 ws* ";" => flight_pic {
|
||||
new_flight->launch.a = s0, new_flight->launch.b = s1;
|
||||
new_flight->landing.a = t0, new_flight->landing.b = t1;
|
||||
new_flight->launch = pair_u(s0, s1);
|
||||
new_flight->landing = pair_u(t0, t1);
|
||||
fprintf(stderr, "%s:%zu: flight <<%.*s>> at <<%.*s>>\n",
|
||||
datestr, line, (int)(new_flight->reg.b - new_flight->reg.a),
|
||||
new_flight->reg.a, (int)(s1 - s0), s0);
|
||||
@@ -767,38 +804,42 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
<flight_pic> * { fail = "flight pic"; goto catch; }
|
||||
<flight_pic> ws* @s0 semilabel @s1 ";" => flight_sic
|
||||
{ new_flight->pilot.a = s0, new_flight->pilot.b = s1; continue; }
|
||||
{ new_flight->pilot = pair_u(s0, s1); continue; }
|
||||
<flight_sic> * { fail = "flight sic"; goto catch; }
|
||||
<flight_sic> ws* ";" => flight_dual
|
||||
{ new_flight->copilot.a = new_flight->copilot.b = 0; continue; }
|
||||
<flight_sic> ws* @s0 semilabel @s1 ";" => flight_dual
|
||||
{ new_flight->copilot.a = s0, new_flight->copilot.b = s1; continue; }
|
||||
{ new_flight->copilot = pair_u(s0, s1); continue; }
|
||||
<flight_dual> * { fail = "flight dual time"; goto catch; }
|
||||
<flight_dual> ws* ";" => flight_pilot
|
||||
{ new_flight->dual_min = 0; continue; }
|
||||
<flight_dual> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_pilot { if(!pair_hours_to_minutes(s0, s1, t0, t1,
|
||||
=> flight_pilot {
|
||||
if(!pair_decimal_hours_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_flight->dual_min)) { fail = "flight dual time"; goto catch; }
|
||||
continue; }
|
||||
<flight_pilot> * { fail = "flight pilot time"; goto catch; }
|
||||
<flight_pilot> ws* ";" => flight_ifrsim
|
||||
{ new_flight->pilot_min = 0; continue; }
|
||||
<flight_pilot> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_ifrsim { if(!pair_hours_to_minutes(s0, s1, t0, t1,
|
||||
=> flight_ifrsim {
|
||||
if(!pair_decimal_hours_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_flight->pilot_min)) { fail = "flight pilot time";
|
||||
goto catch; } continue; }
|
||||
<flight_ifrsim> * { fail = "flight simulated ifr time"; goto catch; }
|
||||
<flight_ifrsim> ws* ";" => flight_ifr
|
||||
{ new_flight->ifrsim_min = 0; continue; }
|
||||
<flight_ifrsim> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_ifr { if(!pair_hours_to_minutes(s0, s1, t0, t1,
|
||||
=> flight_ifr {
|
||||
if(!pair_decimal_hours_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_flight->ifrsim_min)) { fail = "flight simulated ifr time";
|
||||
goto catch; } continue; }
|
||||
<flight_ifr> * { fail = "flight ifr time"; goto catch; }
|
||||
<flight_ifr> ws* ";" => flight_remarks
|
||||
{ new_flight->ifr_min = 0; continue; }
|
||||
<flight_ifr> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_remarks { if(!pair_hours_to_minutes(s0, s1, t0, t1,
|
||||
=> flight_remarks {
|
||||
if(!pair_decimal_hours_to_minutes(pair_u(s0, s1), pair_u(t0, t1),
|
||||
&new_flight->ifr_min)) { fail = "flight ifr time"; goto catch; }
|
||||
continue; }
|
||||
<flight_remarks> * { fail = "flight remarks"; goto catch; }
|
||||
@@ -806,7 +847,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
{ new_flight->remarks.a = new_flight->remarks.b = 0;
|
||||
new_flight = 0; line++; lastnl = s1; continue; }
|
||||
<flight_remarks> ws* @s0 anylabel @s1 "\n" @t1 => line
|
||||
{ new_flight->remarks.a = s0, new_flight->remarks.b = s1;
|
||||
{ new_flight->remarks = pair_u(s0, s1);
|
||||
new_flight = 0; line++; lastnl = t1; continue; }
|
||||
|
||||
|
||||
@@ -884,19 +925,19 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<kjvbook> " " @s0 natural @s1 ":" @t0 natural @t1 [ab]? {
|
||||
if(kjv.chapter || kjv.verse || kjv.verse_end)
|
||||
{ fail = "kjv reference"; goto catch; }
|
||||
if(!pair_to_natural(s0, s1, &kjv.chapter)
|
||||
|| !pair_to_natural(t0, t1, &kjv.verse))
|
||||
if(!pair_to_natural(pair_u(s0, s1), &kjv.chapter)
|
||||
|| !pair_to_natural(pair_u(t0, t1), &kjv.verse))
|
||||
{ fail = "kjv reference numerical error"; goto catch; }
|
||||
continue;
|
||||
}
|
||||
<kjvbook> "-" @s0 natural @s1 [ab]? { /* Verse range. */
|
||||
<kjvbook> "–" @s0 natural @s1 [ab]? { /* Verse range. */
|
||||
if(!kjv.chapter || !kjv.verse || kjv.verse_end)
|
||||
{ fail = "kjv range unrecognized"; goto catch; }
|
||||
if(!pair_to_natural(s0, s1, &kjv.verse_end))
|
||||
if(!pair_to_natural(pair_u(s0, s1), &kjv.verse_end))
|
||||
{ fail = "kjv range numerical error"; goto catch; }
|
||||
continue;
|
||||
}
|
||||
<kjvbook> " -- " => skip {
|
||||
<kjvbook> " — " => skip {
|
||||
if(!kjv.chapter || !kjv.verse)
|
||||
{ fail = "kjv missing information"; goto catch; }
|
||||
if(kjv.verse_end && kjv.verse_end <= kjv.verse)
|
||||
@@ -927,14 +968,13 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
all the things this way. */
|
||||
<input_text, input_text_multi> * { fail = "text input"; goto catch; }
|
||||
<input_text> ws { continue; }
|
||||
<input_text> "<<\n" @s0 => input_text_multi { // multi-line
|
||||
input.pair->a = s0;
|
||||
<input_text> "<<\n" @s0 => input_text_multi { // multi-line: set `s0`.
|
||||
line++; lastnl = s0;
|
||||
continue;
|
||||
}
|
||||
<input_text> @s0 anylabel? @s1 "\n" @t0 => line { // one line; last one
|
||||
/*fprintf(stderr, "text: <<%.*s>>\n", (int)(s1 - s0), s0);*/
|
||||
input.pair->a = s0, input.pair->b = s1;
|
||||
*input.pair = pair_u(s0, s1);
|
||||
if(input.future != yycnewline)
|
||||
{ fail = "use <<text>>"; goto catch; }
|
||||
line++; lastnl = t0;
|
||||
@@ -944,10 +984,9 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<input_text_multi> [\x00]
|
||||
{ fail = "missing closing \">>\""; goto catch; }
|
||||
<input_text_multi> "\n" @s1 { line++; lastnl = s1; continue; }
|
||||
<input_text_multi> @s1 ">>" / [^>] /*future*/ {
|
||||
/*fprintf(stderr, "text: <<\n%.*s>>\n",
|
||||
(int)(s1 - input.pair->a), input.pair->a);*/
|
||||
input.pair->b = s1;
|
||||
<input_text_multi> @s1 ">>" / [^>] /* future, `s0` */ {
|
||||
*input.pair = pair_u(s0, s1);
|
||||
fprintf(stderr, "text: <<\n%.*s>>\n", (int)(s1 - s0), s0);
|
||||
condition = input.future;
|
||||
continue;
|
||||
}
|
||||
@@ -956,7 +995,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
{ fail = "money input"; goto catch; }
|
||||
<input_money> ws { continue; }
|
||||
<input_money> @s0 moneyamount @s1 => input_money_currency {
|
||||
if(!pair_to_cents(s0, s1, &input.money->cents)) goto catch;
|
||||
if(!pair_to_cents(pair_u(s0, s1), &input.money->cents)) goto catch;
|
||||
printf("input_money: amount %" PRId64 "\n", input.money->cents);
|
||||
continue;
|
||||
}
|
||||
@@ -971,8 +1010,12 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
catch:
|
||||
if(!errno) errno = EILSEQ;
|
||||
date32_to_string(date, &datestr);
|
||||
if(s1 = strchr(lastnl, '\n')) {
|
||||
fprintf(stderr, "%.*s\n", (int)(s1 - lastnl), lastnl);
|
||||
{
|
||||
const char *const lastnl_s = (const char *)lastnl;
|
||||
char *result;
|
||||
if(result = strchr(lastnl_s, '\n')) {
|
||||
fprintf(stderr, "%.*s\n", (int)(result - lastnl_s), lastnl_s);
|
||||
}
|
||||
}
|
||||
fprintf(stderr,
|
||||
"%s:%zu fail: %s" /*" condition %d"*/ ".\n",
|
||||
@@ -989,6 +1032,7 @@ void scan_(struct scan *const scan) {
|
||||
linekvmoney_tree_(&scan->taxes);
|
||||
linekvdate_tree_(&scan->froms);
|
||||
linekvpair_tree_(&scan->couches);
|
||||
linekvpair_tree_(&scan->labs);
|
||||
linekvpair_tree_(&scan->medications);
|
||||
linekvpair_tree_(&scan->vaccines);
|
||||
linekvpair_tree_(&scan->ideas);
|
||||
@@ -1070,6 +1114,7 @@ struct scan scan(struct journal *const jrnl) {
|
||||
|| !linekvpair_tree_bulk_finish(&scan.ideas)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.vaccines)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.medications)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.labs)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.couches)
|
||||
|| !linekvdate_tree_bulk_finish(&scan.froms)
|
||||
|| !linekvmoney_tree_bulk_finish(&scan.taxes)
|
||||
@@ -1166,7 +1211,7 @@ void scan_score_graph(struct scan *const scan) {
|
||||
"myTimeFmt = \"%%Y-%%m-%%d\"\n"
|
||||
"set format x myTimeFmt timedate\n"
|
||||
"set xtics format myTimeFmt rotate by -30\n"
|
||||
"set ylabel \"meaning CDF (person·day)\"\n"
|
||||
"set ylabel \"person·day cdf\"\n"
|
||||
"set grid\n"
|
||||
"set key out reverse Left noautotitle\n"
|
||||
"set style fill solid 0.5\n"
|
||||
@@ -1193,6 +1238,27 @@ void scan_score_graph(struct scan *const scan) {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void scan_labs_graph(struct scan *const scan) {
|
||||
struct linekvpair_tree_iterator it
|
||||
= linekvpair_tree_iterator(&scan->labs);
|
||||
union line64 line;
|
||||
struct kvpair *kv;
|
||||
assert(scan);
|
||||
|
||||
fprintf(stderr, "*** Labs graph %s.\n",
|
||||
linekvpair_tree_to_string(&scan->labs));
|
||||
while(linekvpair_tree_next(&it)) {
|
||||
char datestr[12];
|
||||
line = linekvpair_tree_key(&it);
|
||||
kv = linekvpair_tree_value(&it);
|
||||
date32_to_string(line.date, &datestr);
|
||||
printf("%s, \"%.*s\", \"%.*s\"\n",
|
||||
datestr, (int)(kv->key.b - kv->key.a), kv->key.a,
|
||||
(int)(kv->value.b - kv->value.a), kv->value.a);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void scan_glider_graph(struct scan *const scan) {
|
||||
|
Reference in New Issue
Block a user