This commit is contained in:
Neil 2023-02-14 15:07:42 -08:00
parent e35305bbf9
commit d027ad2b21
3 changed files with 33 additions and 22 deletions

View File

@ -111,27 +111,21 @@ static int scan(struct flights *const f,
<glider_pilot> ws* ";" => glider_dual /* not PIC */
{ flight->glider.pilot_min = 0; continue; }
<glider_pilot> ws* @s0 natural? @s1 ":" @t0 minutes @t1 ws* ";"
=> glider_dual {
if(!pair_to_minutes(s0, s1, t0, t1, &flight->glider.pilot_min))
{ why = "pilot time"; goto catch; }
continue;
}
=> glider_dual { if(!pair_colon_to_minutes(s0, s1, t0, t1,
&flight->glider.pilot_min)) { why = "pilot time"; goto catch; }
continue; }
<glider_dual> ws* ";" => glider_instr
{ flight->glider.dual_min = 0; continue; }
<glider_dual> ws* @s0 natural? @s1 ":" @t0 minutes @t1 ws* ";"
=> glider_instr {
if(!pair_to_minutes(s0, s1, t0, t1, &flight->glider.dual_min))
{ why = "dual time"; goto catch; }
continue;
}
=> glider_instr { if(!pair_colon_to_minutes(s0, s1, t0, t1,
&flight->glider.dual_min)) { why = "dual time"; goto catch; }
continue; }
<glider_instr> ws* ";" => glider_remarks
{ flight->glider.instr_min = 0; continue; }
<glider_instr> ws* @s0 natural? @s1 ":" @t0 minutes @t1 ws* ";"
=> glider_remarks {
if(!pair_to_minutes(s0, s1, t0, t1, &flight->glider.instr_min))
{ why = "instr time"; goto catch; }
continue;
}
=> glider_remarks { if(!pair_hours_to_minutes(s0, s1, t0, t1,
&flight->glider.instr_min)) { why = "instr time"; goto catch; }
continue; }
<glider_remarks> ws* @s0 glyph+ (ws+ glyph+)* @s1 "\n" => line
{ flight->glider.remarks.a = s0, flight->glider.remarks.b = s1;
flight = 0; line++; continue; }
@ -175,16 +169,26 @@ static int scan(struct flights *const f,
flight->power.landing.a = t0, flight->power.landing.b = t1;
continue;
}
<flight_pic> ws* @s0 semitext+ (ws+ semitext+)* @s1 ws* ";"
<flight_pic> ws* @s0 semitext+ (ws+ semitext+)* @s1 /* ws*? */";"
=> flight_sic { flight->power.pilot.a = s0,
flight->power.pilot.b = s1; continue; }
<flight_sic> ws* ";" => flight_dual
{ flight->power.copilot.a = flight->power.copilot.b = 0; continue; }
<flight_sic> ws* @s0 semitext+ (ws+ semitext+)* @s1 ws* ";"
<flight_sic> ws* @s0 semitext+ (ws+ semitext+)* @s1 ";"
=> flight_dual { flight->power.copilot.a = s0,
flight->power.copilot.b = s1; continue; }
<flight_dual> ws* ";" => flight_pilot
{ flight->power.dual_min = 0; continue; }
<flight_dual> ws* @s0 natural? @s1 "." @t0 [0-9] @t1 "h" ws* ";"
=> flight_pilot { if(!pair_hours_to_minutes(s0, s1, t0, t1,
&flight->power.dual_min)) { why = "dual time"; goto catch; }
continue; }
<flight_pilot> ws* ";" => flight_ifrsim
{ flight->power.pilot_min = 0; continue; }
<flight_pilot> ws* @s0 natural? @s1 "." @t0 [0-9] @t1 "h" ws* ";"
=> flight_ifrsim { if(!pair_hours_to_minutes(s0, s1, t0, t1,
&flight->power.pilot_min)) { why = "pilot time"; goto catch; }
continue; }
*/ }
assert(0); /* Never gets here. */
catch:

View File

@ -31,7 +31,7 @@ int pair_to_natural(const char *s, const char *const e, uint32_t *const n) {
}
/** `h0` "1" `h1` ":" `m0` "30" `m1` -> 90 `n` @return Valid. */
int pair_to_minutes(const char *h0, const char *const h1,
int pair_colon_to_minutes(const char *h0, const char *const h1,
const char *m0, const char *const m1, uint32_t *const n) {
uint32_t hours, minutes;
return pair_to_natural(h0, h1, &hours) && pair_to_natural(m0, m1, &minutes)
@ -42,6 +42,11 @@ int pair_to_minutes(const char *h0, const char *const h1,
/** `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) {
uint32_t hours, minutes;
/* fixme: more precision? */
return pair_to_natural(h0, h1, &hours) && pair_to_natural(m0, m1, &minutes)
&& minutes <= 9 && hours <= UINT32_MAX / 60 - minutes * 6
? (*n = hours * 60 + minutes * 6, 1) : 0;
}
int pair_is_equal(struct pair x, struct pair y) {

View File

@ -6,8 +6,10 @@
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_to_minutes(const char *, const char *, 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);
int pair_is_equal(struct pair, struct pair);
int pair_is_string(struct pair, const char *);
uint32_t pair_djb2(const struct pair p);