diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-08-04 22:13:49 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-11-09 19:19:04 +0100 |
commit | 794066b2367082851858d4e0da8b6e388d2acabb (patch) | |
tree | 81aad4f5e50c096a25d4bf59491a05ec250b6bc9 /core/planner.c | |
parent | 52d8d89f73542eb8ab3577bc55b466e7ca73bfc7 (diff) | |
download | subsurface-794066b2367082851858d4e0da8b6e388d2acabb.tar.gz |
Cylinders: access cylinders with get_cylinder()
Instead of accessing the cylinder table directly, use the get_cylinder()
function. This gives less unwieldy expressions. But more importantly,
the function does bound checking. This is crucial for now as the code
hasn't be properly audited since the change to arbitrarily sized
cylinder tables. Accesses of invalid cylinder indexes may lead to
silent data-corruption that is sometimes not even noticed by
valgrind. Returning NULL instead of an invalid pointer will make
debugging much easier.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/planner.c')
-rw-r--r-- | core/planner.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/core/planner.c b/core/planner.c index 4a480640d..51453e1ee 100644 --- a/core/planner.c +++ b/core/planner.c @@ -409,7 +409,7 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive int nr = 0; struct gaschanges *gaschanges = NULL; struct divedatapoint *dp = diveplan->dp; - int best_depth = dive->cylinders.cylinders[*asc_cylinder].depth.mm; + int best_depth = get_cylinder(dive, *asc_cylinder)->depth.mm; bool total_time_zero = true; while (dp) { if (dp->time == 0 && total_time_zero) { @@ -444,7 +444,7 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive for (nr = 0; nr < *gaschangenr; nr++) { int idx = gaschanges[nr].gasidx; printf("gaschange nr %d: @ %5.2lfm gasidx %d (%s)\n", nr, gaschanges[nr].depth / 1000.0, - idx, gasname(dive->cylinders.cylinders[idx].gasmix)); + idx, gasname(&get_cylinder(&dive, idx)->gasmix)); } #endif return gaschanges; @@ -527,7 +527,7 @@ int ascent_velocity(int depth, int avg_depth, int bottom_time) static void track_ascent_gas(int depth, struct dive *dive, int cylinder_id, int avg_depth, int bottom_time, bool safety_stop, enum divemode_t divemode) { - cylinder_t *cylinder = &dive->cylinders.cylinders[cylinder_id]; + cylinder_t *cylinder = get_cylinder(dive, cylinder_id); while (depth > 0) { int deltad = ascent_velocity(depth, avg_depth, bottom_time) * TIMESTEP; if (deltad > depth) @@ -598,7 +598,7 @@ static bool enough_gas(const struct dive *dive, int current_cylinder) cylinder_t *cyl; if (current_cylinder < 0 || current_cylinder >= dive->cylinders.nr) return false; - cyl = &dive->cylinders.cylinders[current_cylinder]; + cyl = get_cylinder(dive, current_cylinder); if (!cyl->start.mbar) return true; @@ -732,7 +732,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i const struct event *ev = NULL; divemode = UNDEF_COMP_TYPE; divemode = get_current_divemode(&dive->dc, bottom_time, &ev, &divemode); - gas = dive->cylinders.cylinders[current_cylinder].gasmix; + gas = get_cylinder(dive, current_cylinder)->gasmix; po2 = sample->setpoint.mbar; depth = dive->dc.sample[dive->dc.samples - 1].depth.mm; @@ -787,11 +787,11 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i // How long can we stay at the current depth and still directly ascent to the surface? do { add_segment(ds, depth_to_bar(depth, dive), - dive->cylinders.cylinders[current_cylinder].gasmix, + get_cylinder(dive, current_cylinder)->gasmix, timestep, po2, divemode, prefs.bottomsac); - update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, &dive->cylinders.cylinders[current_cylinder], false, divemode); + update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, get_cylinder(dive, current_cylinder), false, divemode); clock += timestep; - } while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, dive->cylinders.cylinders[current_cylinder].gasmix, + } while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) && enough_gas(dive, current_cylinder) && clock < 6 * 3600); @@ -799,7 +799,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i // In the best of all worlds, we would roll back also the last add_segment in terms of caching deco state, but // let's ignore that since for the eventual ascent in recreational mode, nobody looks at the ceiling anymore, // so we don't really have to compute the deco state. - update_cylinder_pressure(dive, depth, depth, -timestep, prefs.bottomsac, &dive->cylinders.cylinders[current_cylinder], false, divemode); + update_cylinder_pressure(dive, depth, depth, -timestep, prefs.bottomsac, get_cylinder(dive, current_cylinder), false, divemode); clock -= timestep; plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, true, divemode); previous_point_time = clock; @@ -837,7 +837,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i if (best_first_ascend_cylinder != current_cylinder) { current_cylinder = best_first_ascend_cylinder; - gas = dive->cylinders.cylinders[current_cylinder].gasmix; + gas = get_cylinder(dive, current_cylinder)->gasmix; #if DEBUG_PLAN & 16 printf("switch to gas %d (%d/%d) @ %5.2lfm\n", best_first_ascend_cylinder, @@ -851,7 +851,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i divemode = OC; po2 = 0; add_segment(ds, depth_to_bar(depth, dive), - dive->cylinders.cylinders[current_cylinder].gasmix, + get_cylinder(dive, current_cylinder)->gasmix, prefs.min_switch_duration, po2, divemode, prefs.bottomsac); plan_add_segment(diveplan, prefs.min_switch_duration, depth, current_cylinder, po2, false, divemode); clock += prefs.min_switch_duration; @@ -893,7 +893,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); /* Always prefer the best_first_ascend_cylinder if it has the right gasmix. * Otherwise take first cylinder from list with rightgasmix */ - if (same_gasmix(gas, dive->cylinders.cylinders[best_first_ascend_cylinder].gasmix)) + if (same_gasmix(gas, get_cylinder(dive, best_first_ascend_cylinder)->gasmix)) current_cylinder = best_first_ascend_cylinder; else current_cylinder = get_gasidx(dive, gas); @@ -918,7 +918,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i deltad = depth - stoplevels[stopidx]; add_segment(ds, depth_to_bar(depth, dive), - dive->cylinders.cylinders[current_cylinder].gasmix, + get_cylinder(dive, current_cylinder)->gasmix, TIMESTEP, po2, divemode, prefs.decosac); last_segment_min_switch = false; clock += TIMESTEP; @@ -943,21 +943,21 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i if (current_cylinder != gaschanges[gi].gasidx) { if (!prefs.switch_at_req_stop || !trial_ascent(ds, 0, depth, stoplevels[stopidx - 1], avg_depth, bottom_time, - dive->cylinders.cylinders[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) || get_o2(dive->cylinders.cylinders[current_cylinder].gasmix) < 160) { + get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) || get_o2(get_cylinder(dive, current_cylinder)->gasmix) < 160) { if (is_final_plan) plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode); stopping = true; previous_point_time = clock; current_cylinder = gaschanges[gi].gasidx; - gas = dive->cylinders.cylinders[current_cylinder].gasmix; + gas = get_cylinder(dive, current_cylinder)->gasmix; #if DEBUG_PLAN & 16 printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi].depth / 1000.0); #endif /* Stop for the minimum duration to switch gas unless we switch to o2 */ - if (!last_segment_min_switch && get_o2(dive->cylinders.cylinders[current_cylinder].gasmix) != 1000) { + if (!last_segment_min_switch && get_o2(get_cylinder(dive, current_cylinder)->gasmix) != 1000) { add_segment(ds, depth_to_bar(depth, dive), - dive->cylinders.cylinders[current_cylinder].gasmix, + get_cylinder(dive, current_cylinder)->gasmix, prefs.min_switch_duration, po2, divemode, prefs.decosac); clock += prefs.min_switch_duration; last_segment_min_switch = true; @@ -977,7 +977,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i while (1) { /* Check if ascending to next stop is clear, go back and wait if we hit the ceiling on the way */ if (trial_ascent(ds, 0, depth, stoplevels[stopidx], avg_depth, bottom_time, - dive->cylinders.cylinders[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode)) { + get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode)) { decostoptable[decostopcounter].depth = depth; decostoptable[decostopcounter].time = 0; decostopcounter++; @@ -1003,15 +1003,15 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i */ if (pendinggaschange) { current_cylinder = gaschanges[gi + 1].gasidx; - gas = dive->cylinders.cylinders[current_cylinder].gasmix; + gas = get_cylinder(dive, current_cylinder)->gasmix; #if DEBUG_PLAN & 16 printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi + 1].gasidx, (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi + 1].depth / 1000.0); #endif /* Stop for the minimum duration to switch gas unless we switch to o2 */ - if (!last_segment_min_switch && get_o2(dive->cylinders.cylinders[current_cylinder].gasmix) != 1000) { + if (!last_segment_min_switch && get_o2(get_cylinder(dive, current_cylinder)->gasmix) != 1000) { add_segment(ds, depth_to_bar(depth, dive), - dive->cylinders.cylinders[current_cylinder].gasmix, + get_cylinder(dive, current_cylinder)->gasmix, prefs.min_switch_duration, po2, divemode, prefs.decosac); clock += prefs.min_switch_duration; last_segment_min_switch = true; @@ -1020,7 +1020,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i } int new_clock = wait_until(ds, dive, clock, clock, laststoptime * 2 + 1, timestep, depth, stoplevels[stopidx], avg_depth, - bottom_time, dive->cylinders.cylinders[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, divemode); + bottom_time, get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, divemode); laststoptime = new_clock - clock; /* Finish infinite deco */ if (laststoptime >= 48 * 3600 && depth >= 6000) { @@ -1035,12 +1035,12 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i * backgas. This could be customized if there were demand. */ if (break_cylinder == -1) { - if (get_o2(dive->cylinders.cylinders[best_first_ascend_cylinder].gasmix) <= 320) + if (get_o2(get_cylinder(dive, best_first_ascend_cylinder)->gasmix) <= 320) break_cylinder = best_first_ascend_cylinder; else break_cylinder = 0; } - if (get_o2(dive->cylinders.cylinders[current_cylinder].gasmix) == 1000) { + if (get_o2(get_cylinder(dive, current_cylinder)->gasmix) == 1000) { if (laststoptime >= 12 * 60) { laststoptime = 12 * 60; new_clock = clock + laststoptime; @@ -1051,7 +1051,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i plan_add_segment(diveplan, laststoptime, depth, current_cylinder, po2, false, divemode); previous_point_time = clock + laststoptime; current_cylinder = break_cylinder; - gas = dive->cylinders.cylinders[current_cylinder].gasmix; + gas = get_cylinder(dive, current_cylinder)->gasmix; } } else if (o2break_next) { if (laststoptime >= 6 * 60) { @@ -1063,11 +1063,11 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i plan_add_segment(diveplan, laststoptime, depth, current_cylinder, po2, false, divemode); previous_point_time = clock + laststoptime; current_cylinder = breakfrom_cylinder; - gas = dive->cylinders.cylinders[current_cylinder].gasmix; + gas = get_cylinder(dive, current_cylinder)->gasmix; } } } - add_segment(ds, depth_to_bar(depth, dive), dive->cylinders.cylinders[stop_cylinder].gasmix, + add_segment(ds, depth_to_bar(depth, dive), get_cylinder(dive, stop_cylinder)->gasmix, laststoptime, po2, divemode, prefs.decosac); last_segment_min_switch = false; decostoptable[decostopcounter].depth = depth; |