currency started
This commit is contained in:
parent
2d11f84bd9
commit
3e5acec91a
32
src/pair.c
32
src/pair.c
@ -31,6 +31,17 @@ int pair_to_natural(const char *a, const char *const b, uint32_t *const n) {
|
||||
return *n = accum, 1;
|
||||
}
|
||||
|
||||
static int pair_to_64(const char *a, const char *const b, uint64_t *const n) {
|
||||
uint64_t accum = 0;
|
||||
while(a < b) {
|
||||
uint64_t next = accum * 10 + (uint64_t)(*a - '0');
|
||||
if(accum > next) return errno = ERANGE, 0;
|
||||
accum = next;
|
||||
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) {
|
||||
@ -117,6 +128,27 @@ 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) {
|
||||
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');
|
||||
} else { /* dollars */
|
||||
if(!pair_to_64(a, b, &d)) return 0;
|
||||
c = 0;
|
||||
}
|
||||
assert(-INT64_MAX >= INT64_MIN);
|
||||
if(INT64_MAX / 100 < d || INT64_MAX - d * 100 < c)
|
||||
return errno = ERANGE, 0;
|
||||
/* Misses one in 2's. Not a very nuanced conversion. */
|
||||
*cents = (is_negative ? -1 : 1) * (int64_t)(d * 100 + c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** @return A djb2 <http://www.cse.yorku.ca/~oz/hash.html> hash of `p`. */
|
||||
uint32_t pair_djb2(struct pair p) {
|
||||
uint32_t hash = 5381, c;
|
||||
|
@ -15,6 +15,7 @@ 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 *);
|
||||
uint32_t pair_djb2(struct pair);
|
||||
|
||||
/* Supporting pair -> size_t for looking up in arrays. */
|
||||
|
21
src/scan.h
21
src/scan.h
@ -19,6 +19,24 @@ struct kvpair { struct pair key, value; };
|
||||
#define TREE_VALUE struct kvpair
|
||||
#define TREE_HEAD
|
||||
#include "../src/tree.h"
|
||||
enum currency {
|
||||
NONE,
|
||||
CAD, /* Canadian $. */
|
||||
USD, /* US Dollar $usd. */
|
||||
EUR, /* Euro €. */
|
||||
GBP, /* Pound £. */
|
||||
MXN, /* Mexican pesos $mxn. */
|
||||
CUP, /* Cuban pesos, (US) $cup. */
|
||||
CUC, /* Cuban convertible $cuc. */
|
||||
};
|
||||
#include <stdint.h>
|
||||
struct money { int64_t cents; enum currency currency; };
|
||||
struct kvmoney { struct pair key; struct money value; };
|
||||
#define TREE_NAME linekvmoney
|
||||
#define TREE_KEY union line64
|
||||
#define TREE_VALUE struct kvmoney
|
||||
#define TREE_HEAD
|
||||
#include "../src/tree.h"
|
||||
|
||||
/* Place array. */
|
||||
struct place { struct pair name; double x, y; };
|
||||
@ -116,7 +134,8 @@ struct scan {
|
||||
struct pairmap_table map;
|
||||
struct linemap_tree dates;
|
||||
} edits;
|
||||
struct linekvpair_tree contacts, books, tvs, movies, ideas;
|
||||
struct linekvpair_tree contacts, books, tvs, movies, ideas, vaccines;
|
||||
struct linekvmoney_tree taxes;
|
||||
struct glider_tree gliders;
|
||||
struct flight_tree flights;
|
||||
struct kjv_tree kjvs;
|
||||
|
153
src/scan.re.c
153
src/scan.re.c
@ -54,6 +54,19 @@ static int linekvpair_compare(const union line64 a, const union line64 b)
|
||||
#define TREE_DEFAULT {{0,0},{0,0}}
|
||||
#define TREE_BODY
|
||||
#include "../src/tree.h"
|
||||
static void linekvmoney_to_string(const union line64 line,
|
||||
const struct kvmoney *const kv,
|
||||
char (*const a)[12]) { (void)kv; date32_to_string(line.date, a); }
|
||||
static int linekvmoney_compare(const union line64 a, const union line64 b)
|
||||
{ return a.u64 > b.u64; }
|
||||
#define TREE_NAME linekvmoney
|
||||
#define TREE_KEY union line64
|
||||
#define TREE_VALUE struct kvmoney
|
||||
#define TREE_COMPARE
|
||||
#define TREE_TO_STRING
|
||||
#define TREE_DEFAULT {{0,0},{0,CAD}}
|
||||
#define TREE_BODY
|
||||
#include "../src/tree.h"
|
||||
|
||||
|
||||
/* Array of places. */
|
||||
@ -134,7 +147,8 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
size_t line = 1;
|
||||
char datestr[12] = {0};
|
||||
const char *fail = "perhaps a bat?";
|
||||
struct pair *future = 0;
|
||||
struct pair *input_text = 0;
|
||||
struct money *input_money = 0;
|
||||
struct score *new_score = 0;
|
||||
struct glider *new_glider = 0;
|
||||
struct flight *new_flight = 0;
|
||||
@ -171,14 +185,13 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
|
||||
keyword = [A-Za-z0-9][A-Za-z0-9_-]*;
|
||||
|
||||
natural = [1-9][0-9]*;
|
||||
zero_natural = [0-9]+;
|
||||
decimal = "-"? zero_natural ("." zero_natural?)?;
|
||||
uint = [0-9]+;
|
||||
natural = [1-9][0-9]*;
|
||||
decimal = "-"? [0-9]+ ("." [0-9]*)?;
|
||||
date = natural "-" [0-1][0-9] "-" [0-3][0-9];
|
||||
minutes = [0-5][0-9];
|
||||
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") " "?;
|
||||
@ -207,16 +220,18 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<bracket> "tv: " :=> tv
|
||||
<bracket> "movie: " :=> movie
|
||||
<bracket> "idea: " :=> idea
|
||||
<bracket> "vaccine: " :=> vaccine
|
||||
<bracket> "tax: " :=> tax
|
||||
|
||||
<document> * { fail = "document title"; goto catch; }
|
||||
<document> @s0 bralabel @s1 "]" => future {
|
||||
<document> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, 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->value.a = 0, doc->value.b = 0;
|
||||
assert(!future), future = &doc->value;
|
||||
assert(!input_text), input_text = &doc->value;
|
||||
switch(linemap_tree_bulk_assign(&scan->documents.dates, key, &pi)) {
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT:
|
||||
@ -228,14 +243,14 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
|
||||
<remark> * { fail = "remark"; goto catch; }
|
||||
<remark> @s0 date "]" => future {
|
||||
<remark> @s0 date "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
size_t *pi;
|
||||
struct edit *ed;
|
||||
if(!(ed = edit_array_new(&scan->edits.array))) goto catch;
|
||||
ed->edit.u32 = 0;
|
||||
ed->desc.a = 0, ed->desc.b = 0;
|
||||
assert(!future), future = &ed->desc;
|
||||
assert(!input_text), input_text = &ed->desc;
|
||||
if(!pair_to_date(s0, &ed->edit)) goto catch;
|
||||
switch(linemap_tree_bulk_assign(&scan->edits.dates, key, &pi)) {
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
@ -249,7 +264,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
|
||||
<contact> * { fail = "contact unrecognized"; goto catch; }
|
||||
<contact> @s0 bralabel @s1 "]" => future {
|
||||
<contact> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->contacts, key, &pair)) {
|
||||
@ -258,14 +273,14 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value.a = pair->value.b = 0;
|
||||
assert(!future), future = &pair->value;
|
||||
assert(!input_text), input_text = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new contact <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<book> * { fail = "book unrecognized"; goto catch; }
|
||||
<book> @s0 bralabel @s1 "]" => future {
|
||||
<book> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->books, key, &pair)) {
|
||||
@ -274,14 +289,14 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value.a = pair->value.b = 0;
|
||||
assert(!future), future = &pair->value;
|
||||
assert(!input_text), input_text = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new book <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<tv> * { fail = "tv unrecognized"; goto catch; }
|
||||
<tv> @s0 bralabel @s1 "]" => future {
|
||||
<tv> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->tvs, key, &pair)) {
|
||||
@ -290,14 +305,14 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value.a = pair->value.b = 0;
|
||||
assert(!future), future = &pair->value;
|
||||
assert(!input_text), input_text = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new tv <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<movie> * { fail = "movie unrecognized"; goto catch; }
|
||||
<movie> @s0 bralabel @s1 "]" => future {
|
||||
<movie> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->contacts, key, &pair)) {
|
||||
@ -306,14 +321,14 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value.a = pair->value.b = 0;
|
||||
assert(!future), future = &pair->value;
|
||||
assert(!input_text), input_text = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new movie <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<idea> * { fail = "idea unrecognized"; goto catch; }
|
||||
<idea> @s0 bralabel @s1 "]" => future {
|
||||
<idea> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->contacts, key, &pair)) {
|
||||
@ -322,12 +337,44 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value.a = pair->value.b = 0;
|
||||
assert(!future), future = &pair->value;
|
||||
assert(!input_text), input_text = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new idea <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<vaccine> * { fail = "vaccine unrecognized"; goto catch; }
|
||||
<vaccine> @s0 bralabel @s1 "]" => input_text {
|
||||
const union line64 key = { { (uint32_t)line, date } };
|
||||
struct kvpair *pair;
|
||||
switch(linekvpair_tree_bulk_assign(&scan->vaccines, key, &pair)) {
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value.a = pair->value.b = 0;
|
||||
assert(!input_text), input_text = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new vaccine <<%.*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 } };
|
||||
struct kvmoney *pair;
|
||||
switch(linekvmoney_tree_bulk_assign(&scan->taxes, key, &pair)) {
|
||||
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
|
||||
case TREE_ABSENT: break;
|
||||
}
|
||||
pair->key.a = s0, pair->key.b = s1;
|
||||
pair->value = (struct money){0, CAD};
|
||||
assert(!input_text), input_money = &pair->value;
|
||||
fprintf(stderr, "%s[%zu]: new tax <<%.*s>>.\n",
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
continue;
|
||||
}
|
||||
|
||||
<place> * { fail = "place unrecognized"; goto catch; }
|
||||
<place> @s0 parlabel @s1 / "\n" => skip { also_place: {
|
||||
const struct pair keyword = pair(s0, s1);
|
||||
@ -397,7 +444,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
datestr, line, (int)(s1 - s0), s0);
|
||||
} continue; }
|
||||
/* New source. */
|
||||
<source> @s0 keyword @s1 ":" => future {
|
||||
<source> @s0 keyword @s1 ":" => input_text {
|
||||
struct pair keyword = pair(s0, s1);
|
||||
size_t *idx;
|
||||
struct kvpair *source;
|
||||
@ -410,7 +457,7 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
*idx = (size_t)(source - scan->sources.array.data);
|
||||
source->key.a = s0, source->key.b = s1;
|
||||
source->value.a = 0, source->value.b = 0;
|
||||
assert(!future), future = &source->value;
|
||||
assert(!input_text), input_text = &source->value;
|
||||
fprintf(stderr, "%s[%zu]: new source <<%.*s>> stored at %zu.\n",
|
||||
datestr, line, (int)(s1 - s0), s0, *idx);
|
||||
goto also_source;
|
||||
@ -588,28 +635,28 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
<flight_dual> * { fail = "flight dual time"; goto catch; }
|
||||
<flight_dual> ws* ";" => flight_pilot
|
||||
{ new_flight->dual_min = 0; continue; }
|
||||
<flight_dual> ws* @s0 zero_natural? @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
<flight_dual> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_pilot { if(!pair_hours_to_minutes(s0, s1, 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 zero_natural? @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
<flight_pilot> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_ifrsim { if(!pair_hours_to_minutes(s0, s1, 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 zero_natural? @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
<flight_ifrsim> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_ifr { if(!pair_hours_to_minutes(s0, s1, 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 zero_natural? @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
<flight_ifr> ws* @s0 [0-9]* @s1 "." @t0 [0-9] @t1 "h" ws* ";"
|
||||
=> flight_remarks { if(!pair_hours_to_minutes(s0, s1, t0, t1,
|
||||
&new_flight->ifr_min)) { fail = "flight ifr time"; goto catch; }
|
||||
continue; }
|
||||
@ -737,41 +784,54 @@ static int scan_day(struct scan *const scan, union date32 date,
|
||||
|
||||
/* fixme: This is a cool way of doing things. Avoid repetition, make
|
||||
all the things this way. */
|
||||
/* "<<\ntext\n>>" or "text\n" used by several. Must have pointers to
|
||||
future input. */
|
||||
<future, future_multi> * { fail = "text input"; goto catch; }
|
||||
<future> ws+ { continue; }
|
||||
<future> "\n" => line { // empty is okay
|
||||
<input_text, input_text_multi> * { fail = "text input"; goto catch; }
|
||||
<input_text> ws { continue; }
|
||||
<input_text> "\n" => line { // empty is okay
|
||||
line++;
|
||||
assert(future);
|
||||
future->a = future->b = 0, future = 0;
|
||||
fprintf(stderr, "text: <empty>\n");
|
||||
assert(input_text);
|
||||
input_text->a = input_text->b = 0, input_text = 0;
|
||||
continue;
|
||||
}
|
||||
<future> "<<\n" @s0 => future_multi { // multi-line
|
||||
<input_text> "<<\n" @s0 => input_text_multi { // multi-line
|
||||
line++;
|
||||
assert(future);
|
||||
future->a = s0;
|
||||
assert(input_text);
|
||||
input_text->a = s0;
|
||||
continue;
|
||||
}
|
||||
<future> @s0 anylabel @s1 "\n" => line { // one line
|
||||
<input_text> @s0 anylabel @s1 "\n" => line { // one line
|
||||
line++;
|
||||
fprintf(stderr, "text: <<%.*s>>\n", (int)(s1 - s0), s0);
|
||||
assert(future);
|
||||
future->a = s0, future->b = s1, future = 0;
|
||||
assert(input_text);
|
||||
input_text->a = s0, input_text->b = s1, input_text = 0;
|
||||
continue;
|
||||
}
|
||||
<future_multi> [^\x00\n] { continue; }
|
||||
<future_multi> [\x00] { fail = "missing closing \">>\""; goto catch; }
|
||||
<future_multi> "\n" { line++; continue; }
|
||||
<input_text_multi> [^\x00\n] { continue; }
|
||||
<input_text_multi> [\x00]
|
||||
{ fail = "missing closing \">>\""; goto catch; }
|
||||
<input_text_multi> "\n" { line++; continue; }
|
||||
/* Restricts this to be the last one; you could imagine that it would
|
||||
be more flexible, "<<\n>>; <<\n>>\n". */
|
||||
<future_multi> @s1 ">>\n" => line {
|
||||
<input_text_multi> @s1 ">>\n" => line {
|
||||
line++;
|
||||
assert(future && future->a);
|
||||
future->b = s1, future = 0;
|
||||
fprintf(stderr, "text: <<\n%.*s>>\n",
|
||||
(int)(s1 - input_text->a), input_text->a);
|
||||
assert(input_text && input_text->a);
|
||||
input_text->b = s1, input_text = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
<input_money, input_money_currency> *
|
||||
{ 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;
|
||||
printf("input_money: amount %" PRId64 "\n", input_money->cents);
|
||||
continue;
|
||||
}
|
||||
<input_money_currency> "$\n" => line
|
||||
{ line++; input_money->currency = CAD; continue; }
|
||||
|
||||
*/ }
|
||||
assert(0); /* Never gets here. */
|
||||
catch:
|
||||
@ -791,6 +851,8 @@ void scan_(struct scan *const scan) {
|
||||
fprintf(stderr, "~scan finished kjv\n");
|
||||
flight_tree_(&scan->flights);
|
||||
glider_tree_(&scan->gliders);
|
||||
linekvmoney_tree_(&scan->taxes);
|
||||
linekvpair_tree_(&scan->vaccines);
|
||||
linekvpair_tree_(&scan->ideas);
|
||||
linekvpair_tree_(&scan->movies);
|
||||
linekvpair_tree_(&scan->tvs);
|
||||
@ -868,13 +930,14 @@ struct scan scan(struct journal *const jrnl) {
|
||||
|| !linekvpair_tree_bulk_finish(&scan.tvs)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.movies)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.ideas)
|
||||
|| !linekvpair_tree_bulk_finish(&scan.vaccines)
|
||||
|| !linekvmoney_tree_bulk_finish(&scan.taxes)
|
||||
|| !glider_tree_bulk_finish(&scan.gliders)
|
||||
|| !flight_tree_bulk_finish(&scan.flights)
|
||||
|| !kjv_tree_bulk_finish(&scan.kjvs)) goto catch;
|
||||
|
||||
goto finally;
|
||||
catch:
|
||||
fprintf(stderr, "Scan failed.\n");
|
||||
scan_(&scan);
|
||||
finally:
|
||||
return scan;
|
||||
|
Loading…
Reference in New Issue
Block a user