aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-08-04 22:13:49 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-11-09 19:19:04 +0100
commit794066b2367082851858d4e0da8b6e388d2acabb (patch)
tree81aad4f5e50c096a25d4bf59491a05ec250b6bc9 /core
parent52d8d89f73542eb8ab3577bc55b466e7ca73bfc7 (diff)
downloadsubsurface-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')
-rw-r--r--core/datatrak.c10
-rw-r--r--core/dive.c53
-rw-r--r--core/divelist.c4
-rw-r--r--core/equipment.c8
-rw-r--r--core/gaspressures.c6
-rw-r--r--core/import-divinglog.c2
-rw-r--r--core/import-shearwater.c2
-rw-r--r--core/parse-xml.c6
-rw-r--r--core/planner.c54
-rw-r--r--core/plannernotes.c8
-rw-r--r--core/profile.c16
-rw-r--r--core/qthelper.cpp4
-rw-r--r--core/save-git.c2
-rw-r--r--core/save-html.c2
-rw-r--r--core/save-xml.c2
-rw-r--r--core/statistics.c6
-rw-r--r--core/subsurface-qt/DiveObjectHelper.cpp18
17 files changed, 102 insertions, 101 deletions
diff --git a/core/datatrak.c b/core/datatrak.c
index f9f577c73..728efe5ab 100644
--- a/core/datatrak.c
+++ b/core/datatrak.c
@@ -356,7 +356,7 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive
*/
read_bytes(2);
if (tmp_2bytes != 0x7FFF && dt_dive->cylinders.nr > 0)
- dt_dive->cylinders.cylinders[0].gas_used.mliter = lrint(dt_dive->cylinders.cylinders[0].type.size.mliter * (tmp_2bytes / 100.0));
+ get_cylinder(dt_dive, 0)->gas_used.mliter = lrint(get_cylinder(dt_dive, 0)->type.size.mliter * (tmp_2bytes / 100.0));
/*
* Dive Type 1 - Bit table. Subsurface don't have this record, but
@@ -532,10 +532,10 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive
goto bail;
}
if (is_nitrox && dt_dive->cylinders.nr > 0)
- dt_dive->cylinders.cylinders[0].gasmix.o2.permille =
+ get_cylinder(dt_dive, 0)->gasmix.o2.permille =
lrint(membuf[23] & 0x0F ? 20.0 + 2 * (membuf[23] & 0x0F) : 21.0) * 10;
if (is_O2 && dt_dive->cylinders.nr > 0)
- dt_dive->cylinders.cylinders[0].gasmix.o2.permille = membuf[23] * 10;
+ get_cylinder(dt_dive, 0)->gasmix.o2.permille = membuf[23] * 10;
free(compl_buffer);
}
JUMP(membuf, profile_length);
@@ -550,8 +550,8 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive
create_device_node(dt_dive->dc.model, dt_dive->dc.deviceid, "", "", dt_dive->dc.model);
dt_dive->dc.next = NULL;
if (!is_SCR && dt_dive->cylinders.nr > 0) {
- dt_dive->cylinders.cylinders[0].end.mbar = dt_dive->cylinders.cylinders[0].start.mbar -
- ((dt_dive->cylinders.cylinders[0].gas_used.mliter / dt_dive->cylinders.cylinders[0].type.size.mliter) * 1000);
+ get_cylinder(dt_dive, 0)->end.mbar = get_cylinder(dt_dive, 0)->start.mbar -
+ ((get_cylinder(dt_dive, 0)->gas_used.mliter / get_cylinder(dt_dive, 0)->type.size.mliter) * 1000);
}
free(devdata);
return membuf;
diff --git a/core/dive.c b/core/dive.c
index 7255416ac..20b39b6a3 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -264,7 +264,7 @@ struct gasmix get_gasmix_from_event(const struct dive *dive, const struct event
if (ev && event_is_gaschange(ev)) {
int index = ev->gas.index;
if (index >= 0 && index < dive->cylinders.nr)
- return dive->cylinders.cylinders[index].gasmix;
+ return get_cylinder(dive, index)->gasmix;
return ev->gas.mix;
}
return dummy;
@@ -526,8 +526,8 @@ void copy_used_cylinders(const struct dive *s, struct dive *d, bool used_only)
clear_cylinder_table(&d->cylinders);
for (i = 0; i < s->cylinders.nr; i++) {
- if (!used_only || is_cylinder_used(s, i) || s->cylinders.cylinders[i].cylinder_use == NOT_USED)
- add_cloned_cylinder(&d->cylinders, s->cylinders.cylinders[i]);
+ if (!used_only || is_cylinder_used(s, i) || get_cylinder(s, i)->cylinder_use == NOT_USED)
+ add_cloned_cylinder(&d->cylinders, *get_cylinder(s, i));
}
}
@@ -696,7 +696,7 @@ static int get_cylinder_used(const struct dive *dive, bool used[])
int i, num = 0;
for (i = 0; i < dive->cylinders.nr; i++) {
- used[i] = cylinder_used(dive->cylinders.cylinders + i);
+ used[i] = cylinder_used(get_cylinder(dive, i));
if (used[i])
num++;
}
@@ -1000,8 +1000,8 @@ static void sanitize_cylinder_info(struct dive *dive)
int i;
for (i = 0; i < dive->cylinders.nr; i++) {
- sanitize_gasmix(&dive->cylinders.cylinders[i].gasmix);
- sanitize_cylinder_type(&dive->cylinders.cylinders[i].type);
+ sanitize_gasmix(&get_cylinder(dive, i)->gasmix);
+ sanitize_cylinder_type(&get_cylinder(dive, i)->type);
}
}
@@ -1334,7 +1334,7 @@ static void simplify_dc_pressures(struct divecomputer *dc)
static void fixup_start_pressure(struct dive *dive, int idx, pressure_t p)
{
if (idx >= 0 && idx < dive->cylinders.nr) {
- cylinder_t *cyl = dive->cylinders.cylinders + idx;
+ cylinder_t *cyl = get_cylinder(dive, idx);
if (p.mbar && !cyl->sample_start.mbar)
cyl->sample_start = p;
}
@@ -1343,7 +1343,7 @@ static void fixup_start_pressure(struct dive *dive, int idx, pressure_t p)
static void fixup_end_pressure(struct dive *dive, int idx, pressure_t p)
{
if (idx >= 0 && idx < dive->cylinders.nr) {
- cylinder_t *cyl = dive->cylinders.cylinders + idx;
+ cylinder_t *cyl = get_cylinder(dive, idx);
if (p.mbar && !cyl->sample_end.mbar)
cyl->sample_end = p;
}
@@ -1415,7 +1415,7 @@ static bool validate_gaschange(struct dive *dive, struct event *event)
/* Fix up the event to have the right information */
event->gas.index = index;
- event->gas.mix = dive->cylinders.cylinders[index].gasmix;
+ event->gas.mix = get_cylinder(dive, index)->gasmix;
/* Convert to odd libdivecomputer format */
o2 = get_o2(event->gas.mix);
@@ -1540,7 +1540,7 @@ struct dive *fixup_dive(struct dive *dive)
fixup_watertemp(dive);
fixup_airtemp(dive);
for (i = 0; i < dive->cylinders.nr; i++) {
- cylinder_t *cyl = dive->cylinders.cylinders + i;
+ cylinder_t *cyl = get_cylinder(dive, i);
add_cylinder_description(&cyl->type);
if (same_rounded_pressure(cyl->sample_start, cyl->start))
cyl->start.mbar = 0;
@@ -1923,7 +1923,7 @@ extern int get_cylinder_idx_by_use(const struct dive *dive, enum cylinderuse cyl
{
int cylinder_index;
for (cylinder_index = 0; cylinder_index < dive->cylinders.nr; cylinder_index++) {
- if (dive->cylinders.cylinders[cylinder_index].cylinder_use == cylinder_use_type)
+ if (get_cylinder(dive, cylinder_index)->cylinder_use == cylinder_use_type)
return cylinder_index; // return the index of the cylinder with that cylinder use type
}
return -1; // negative number means cylinder_use_type not found in list of cylinders
@@ -2073,7 +2073,7 @@ int same_gasmix_cylinder(const cylinder_t *cyl, int cylid, const struct dive *di
for (int i = 0; i < dive->cylinders.nr; i++) {
if (i == cylid)
continue;
- struct gasmix gas2 = dive->cylinders.cylinders[i].gasmix;
+ struct gasmix gas2 = get_cylinder(dive, i)->gasmix;
if (gasmix_distance(mygas, gas2) == 0 && (is_cylinder_used(dive, i) || check_unused))
return i;
}
@@ -2108,7 +2108,7 @@ static int match_cylinder(const cylinder_t *cyl, const struct dive *dive, const
if (!used[i])
continue;
- target = dive->cylinders.cylinders + i;
+ target = get_cylinder(dive, i);
if (!same_gasmix(cyl->gasmix, target->gasmix))
continue;
if (cyl->cylinder_use != target->cylinder_use)
@@ -2197,7 +2197,7 @@ static void merge_cylinders(struct dive *res, const struct dive *a, const struct
if (!used_in_b[i])
continue;
- j = match_cylinder(b->cylinders.cylinders + i, a, used_in_a);
+ j = match_cylinder(get_cylinder(b, i), a, used_in_a);
if (j < 0)
continue;
@@ -2216,14 +2216,14 @@ static void merge_cylinders(struct dive *res, const struct dive *a, const struct
mapping_a[j] = res->cylinders.nr;
used_in_a[i] = false;
used_in_b[j] = false;
- merge_one_cylinder(&res->cylinders, a->cylinders.cylinders + j, b->cylinders.cylinders + i);
+ merge_one_cylinder(&res->cylinders, get_cylinder(a, j), get_cylinder(b, i));
}
/* Now copy all the used cylinders from 'a' that are used but have not been matched */
for (i = 0; i < a->cylinders.nr; i++) {
if (used_in_a[i]) {
mapping_a[i] = res->weightsystems.nr;
- add_cloned_cylinder(&res->cylinders, a->cylinders.cylinders[i]);
+ add_cloned_cylinder(&res->cylinders, *get_cylinder(a, i));
}
}
@@ -2231,7 +2231,7 @@ static void merge_cylinders(struct dive *res, const struct dive *a, const struct
for (i = 0; i < b->cylinders.nr; i++) {
if (used_in_b[i]) {
mapping_b[i] = res->weightsystems.nr;
- add_cloned_cylinder(&res->cylinders, b->cylinders.cylinders[i]);
+ add_cloned_cylinder(&res->cylinders, *get_cylinder(b, i));
}
}
@@ -3018,10 +3018,11 @@ static void force_fixup_dive(struct dive *d)
d->maxtemp.mkelvin = 0;
d->mintemp.mkelvin = 0;
for (int i = 0; i < d->cylinders.nr; i++) {
- old_pressures[i].start = d->cylinders.cylinders[i].start;
- old_pressures[i].end = d->cylinders.cylinders[i].end;
- d->cylinders.cylinders[i].start.mbar = 0;
- d->cylinders.cylinders[i].end.mbar = 0;
+ cylinder_t *cyl = get_cylinder(d, i);
+ old_pressures[i].start = cyl->start;
+ old_pressures[i].end = cyl->end;
+ cyl->start.mbar = 0;
+ cyl->end.mbar = 0;
}
fixup_dive(d);
@@ -3041,10 +3042,10 @@ static void force_fixup_dive(struct dive *d)
if (!d->duration.seconds)
d->duration = old_duration;
for (int i = 0; i < d->cylinders.nr; i++) {
- if (!d->cylinders.cylinders[i].start.mbar)
- d->cylinders.cylinders[i].start = old_pressures[i].start;
- if (!d->cylinders.cylinders[i].end.mbar)
- d->cylinders.cylinders[i].end = old_pressures[i].end;
+ if (!get_cylinder(d, i)->start.mbar)
+ get_cylinder(d, i)->start = old_pressures[i].start;
+ if (!get_cylinder(d, i)->end.mbar)
+ get_cylinder(d, i)->end = old_pressures[i].end;
}
free(old_pressures);
}
@@ -4009,7 +4010,7 @@ struct gasmix get_gasmix(const struct dive *dive, const struct divecomputer *dc,
if (!ev) {
/* on first invocation, get initial gas mix and first event (if any) */
int cyl = explicit_first_cylinder(dive, dc);
- res = dive->cylinders.cylinders[cyl].gasmix;
+ res = get_cylinder(dive, cyl)->gasmix;
ev = dc ? get_next_event(dc->events, "gaschange") : NULL;
} else {
res = gasmix;
diff --git a/core/divelist.c b/core/divelist.c
index 5eae5e638..451ed70a7 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -66,7 +66,7 @@ void get_dive_gas(const struct dive *dive, int *o2_p, int *he_p, int *o2max_p)
for (i = 0; i < dive->cylinders.nr; i++) {
- const cylinder_t *cyl = dive->cylinders.cylinders + i;
+ const cylinder_t *cyl = get_cylinder(dive, i);
int o2 = get_o2(cyl->gasmix);
int he = get_he(cyl->gasmix);
@@ -349,7 +349,7 @@ static double calculate_airuse(const struct dive *dive)
for (i = 0; i < dive->cylinders.nr; i++) {
pressure_t start, end;
- const cylinder_t *cyl = dive->cylinders.cylinders + i;
+ const cylinder_t *cyl = get_cylinder(dive, i);
start = cyl->start.mbar ? cyl->start : cyl->sample_start;
end = cyl->end.mbar ? cyl->end : cyl->sample_end;
diff --git a/core/equipment.c b/core/equipment.c
index 3a2e6db4b..39505a39d 100644
--- a/core/equipment.c
+++ b/core/equipment.c
@@ -279,7 +279,7 @@ void reset_cylinders(struct dive *dive, bool track_gas)
pressure_t decopo2 = {.mbar = prefs.decopo2};
for (int i = 0; i < dive->cylinders.nr; i++) {
- cylinder_t *cyl = &dive->cylinders.cylinders[i];
+ cylinder_t *cyl = get_cylinder(dive, i);
if (cyl->depth.mm == 0) /* if the gas doesn't give a mod, calculate based on prefs */
cyl->depth = gas_mod(cyl->gasmix, decopo2, dive, M_OR_FT(3,10));
if (track_gas)
@@ -308,10 +308,10 @@ void copy_cylinder_types(const struct dive *s, struct dive *d)
return;
for (i = 0; i < s->cylinders.nr && i < d->cylinders.nr; i++)
- copy_cylinder_type(s->cylinders.cylinders + i, d->cylinders.cylinders + i);
+ copy_cylinder_type(get_cylinder(s, i), get_cylinder(d, i));
for ( ; i < s->cylinders.nr; i++)
- add_cloned_cylinder(&d->cylinders, s->cylinders.cylinders[i]);
+ add_cloned_cylinder(&d->cylinders, *get_cylinder(s, i));
}
cylinder_t *add_empty_cylinder(struct cylinder_table *t)
@@ -355,7 +355,7 @@ void dump_cylinders(struct dive *dive, bool verbose)
{
printf("Cylinder list:\n");
for (int i = 0; i < dive->cylinders; i++) {
- cylinder_t *cyl = &dive->cylinders.cylinders[i];
+ cylinder_t *cyl = get_cylinder(dive, i);
printf("%02d: Type %s, %3.1fl, %3.0fbar\n", i, cyl->type.description, cyl->type.size.mliter / 1000.0, cyl->type.workingpressure.mbar / 1000.0);
printf(" Gasmix O2 %2.0f%% He %2.0f%%\n", cyl->gasmix.o2.permille / 10.0, cyl->gasmix.he.permille / 10.0);
diff --git a/core/gaspressures.c b/core/gaspressures.c
index a69dbb295..bf329add4 100644
--- a/core/gaspressures.c
+++ b/core/gaspressures.c
@@ -238,7 +238,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
if (!track_pr)
return;
- if (dive->cylinders.cylinders[cyl].cylinder_use == OC_GAS)
+ if (get_cylinder(dive, cyl)->cylinder_use == OC_GAS)
strategy = SAC;
else
strategy = TIME;
@@ -302,7 +302,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
last_segment = segment;
}
- if(dive->cylinders.cylinders[cyl].cylinder_use == OC_GAS) {
+ if(get_cylinder(dive, cyl)->cylinder_use == OC_GAS) {
/* if this segment has pressure_time, then calculate a new interpolated pressure */
if (interpolate.pressure_time) {
@@ -366,7 +366,7 @@ void populate_pressure_information(struct dive *dive, struct divecomputer *dc, s
{
UNUSED(dc);
int first, last, cyl;
- cylinder_t *cylinder = dive->cylinders.cylinders + sensor;
+ cylinder_t *cylinder = get_cylinder(dive, sensor);
pr_track_t *track = NULL;
pr_track_t *current = NULL;
const struct event *ev, *b_ev;
diff --git a/core/import-divinglog.c b/core/import-divinglog.c
index 5b9e4be3b..f3a62eaff 100644
--- a/core/import-divinglog.c
+++ b/core/import-divinglog.c
@@ -130,7 +130,7 @@ static int divinglog_profile(void *param, int columns, char **data, char **colum
state->cur_sample->pressure[0].mbar = pressure * 100;
state->cur_sample->rbt.seconds = rbt;
if (oldcyl != tank && tank >= 0 && tank < state->cur_dive->cylinders.nr) {
- struct gasmix mix = state->cur_dive->cylinders.cylinders[tank].gasmix;
+ struct gasmix mix = get_cylinder(state->cur_dive, tank)->gasmix;
int o2 = get_o2(mix);
int he = get_he(mix);
diff --git a/core/import-shearwater.c b/core/import-shearwater.c
index 1c1e68eb4..3cedb3f22 100644
--- a/core/import-shearwater.c
+++ b/core/import-shearwater.c
@@ -61,7 +61,7 @@ static int shearwater_changes(void *param, int columns, char **data, char **colu
int i;
bool found = false;
for (i = 0; i < state->cur_dive->cylinders.nr; ++i) {
- const cylinder_t *cyl = &state->cur_dive->cylinders.cylinders[i];
+ const cylinder_t *cyl = get_cylinder(state->cur_dive, i);
if (cyl->gasmix.o2.permille == o2 && cyl->gasmix.he.permille == he) {
found = true;
break;
diff --git a/core/parse-xml.c b/core/parse-xml.c
index 0f297bf9a..bca0269a3 100644
--- a/core/parse-xml.c
+++ b/core/parse-xml.c
@@ -704,7 +704,7 @@ void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int second
return;
}
/* The gas switch event format is insane for historical reasons */
- struct gasmix mix = dive->cylinders.cylinders[idx].gasmix;
+ struct gasmix mix = get_cylinder(dive, idx)->gasmix;
int o2 = get_o2(mix);
int he = get_he(mix);
struct event *ev;
@@ -1242,7 +1242,7 @@ static void gps_picture_location(char *buffer, struct picture *pic)
static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, struct parser_state *state)
{
char *hash = NULL;
- cylinder_t *cyl = dive->cylinders.nr > 0 ? &dive->cylinders.cylinders[dive->cylinders.nr - 1] : NULL;
+ cylinder_t *cyl = dive->cylinders.nr > 0 ? get_cylinder(dive, dive->cylinders.nr - 1) : NULL;
pressure_t p;
start_match("dive", name, buf);
@@ -1904,7 +1904,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct dive_table *tabl
found = false;
for (i = 0; i < state.cur_dive->cylinders.nr; ++i) {
- const cylinder_t *cyl = &state.cur_dive->cylinders.cylinders[i];
+ const cylinder_t *cyl = get_cylinder(state.cur_dive, i);
if (cyl->gasmix.o2.permille == ptr[6] * 10 && cyl->gasmix.he.permille == ptr[7] * 10) {
found = true;
break;
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;
diff --git a/core/plannernotes.c b/core/plannernotes.c
index dd909108a..6b3095082 100644
--- a/core/plannernotes.c
+++ b/core/plannernotes.c
@@ -190,13 +190,13 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
nextdp = dp->next;
if (dp->time == 0)
continue;
- gasmix = dive->cylinders.cylinders[dp->cylinderid].gasmix;
+ gasmix = get_cylinder(dive, dp->cylinderid)->gasmix;
depthvalue = get_depth_units(dp->depth.mm, &decimals, &depth_unit);
/* analyze the dive points ahead */
while (nextdp && nextdp->time == 0)
nextdp = nextdp->next;
if (nextdp)
- newgasmix = dive->cylinders.cylinders[nextdp->cylinderid].gasmix;
+ newgasmix = get_cylinder(dive, nextdp->cylinderid)->gasmix;
gaschange_after = (nextdp && (gasmix_distance(gasmix, newgasmix)));
gaschange_before = (gasmix_distance(lastprintgasmix, gasmix));
rebreatherchange_after = (nextdp && (dp->setpoint != nextdp->setpoint || dp->divemode != nextdp->divemode));
@@ -466,7 +466,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
const char *unit, *pressure_unit, *depth_unit;
char warning[1000] = "";
char mingas[1000] = "";
- cylinder_t *cyl = &dive->cylinders.cylinders[gasidx];
+ cylinder_t *cyl = get_cylinder(dive, gasidx);
if (cyl->cylinder_use == NOT_USED)
continue;
@@ -581,7 +581,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
while (dp) {
if (dp->time != 0) {
struct gas_pressures pressures;
- struct gasmix gasmix = dive->cylinders.cylinders[dp->cylinderid].gasmix;
+ struct gasmix gasmix = get_cylinder(dive, dp->cylinderid)->gasmix;
current_divemode = get_current_divemode(&dive->dc, dp->time, &evd, &current_divemode);
amb = depth_to_atm(dp->depth.mm, dive);
diff --git a/core/profile.c b/core/profile.c
index 4d35155b2..bee2b7a4a 100644
--- a/core/profile.c
+++ b/core/profile.c
@@ -189,7 +189,7 @@ static int get_local_sac(struct plot_info *pi, int idx1, int idx2, struct dive *
depth = (entry1->depth + entry2->depth) / 2;
atm = depth_to_atm(depth, dive);
- cyl = dive->cylinders.cylinders + index;
+ cyl = get_cylinder(dive, index);
airuse = gas_volume(cyl, a) - gas_volume(cyl, b);
@@ -414,7 +414,7 @@ static void calculate_max_limits_new(struct dive *dive, struct divecomputer *giv
/* Get the per-cylinder maximum pressure if they are manual */
for (cyl = 0; cyl < dive->cylinders.nr; cyl++) {
- int mbar = dive->cylinders.cylinders[cyl].start.mbar;
+ int mbar = get_cylinder(dive, cyl)->start.mbar;
if (mbar > maxpressure)
maxpressure = mbar;
if (mbar < minpressure)
@@ -677,7 +677,7 @@ static int sac_between(struct dive *dive, struct plot_info *pi, int first, int l
a.mbar = get_plot_pressure(pi, first, i);
b.mbar = get_plot_pressure(pi, last, i);
- cyl = dive->cylinders.cylinders + i;
+ cyl = get_cylinder(dive, i);
cyluse = gas_volume(cyl, a) - gas_volume(cyl, b);
if (cyluse > 0)
airuse += cyluse;
@@ -800,7 +800,7 @@ static void matching_gases(struct dive *dive, struct gasmix gasmix, bool gases[]
int i;
for (i = 0; i < dive->cylinders.nr; i++)
- gases[i] = same_gasmix(gasmix, dive->cylinders.cylinders[i].gasmix);
+ gases[i] = same_gasmix(gasmix, get_cylinder(dive, i)->gasmix);
}
static void calculate_sac(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
@@ -890,7 +890,7 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
// Fill in "seen[]" array - mark cylinders we're not interested
// in as negative.
for (i = 0; i < pi->nr_cylinders; i++) {
- const cylinder_t *cyl = dive->cylinders.cylinders + i;
+ const cylinder_t *cyl = get_cylinder(dive, i);
int start = cyl->start.mbar;
int end = cyl->end.mbar;
@@ -920,7 +920,7 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
for (i = 0; i < pi->nr_cylinders; i++) {
if (seen[i] >= 0) {
- const cylinder_t *cyl = dive->cylinders.cylinders + i;
+ const cylinder_t *cyl = get_cylinder(dive, i);
add_plot_pressure(pi, first[i], i, cyl->start);
add_plot_pressure(pi, last[i], i, cyl->end);
@@ -1442,7 +1442,7 @@ static void plot_string(struct plot_info *pi, int idx, struct membuffer *b)
int mbar = get_plot_pressure(pi, idx, cyl);
if (!mbar)
continue;
- struct gasmix mix = displayed_dive.cylinders.cylinders[cyl].gasmix;
+ struct gasmix mix = get_cylinder(&displayed_dive, cyl)->gasmix;
pressurevalue = get_pressure_units(mbar, &pressure_unit);
put_format_loc(b, translate("gettextFromC", "P: %d%s (%s)\n"), pressurevalue, pressure_unit, gasname(mix));
}
@@ -1706,7 +1706,7 @@ void compare_samples(struct plot_info *pi, int idx1, int idx2, char *buf, int bu
pressurevalue = get_pressure_units(bar_used, &pressure_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ΔP:%d%s"), buf2, pressurevalue, pressure_unit);
- cylinder_t *cyl = displayed_dive.cylinders.cylinders + 0;
+ cylinder_t *cyl = get_cylinder(&displayed_dive, 0);
/* if we didn't cross a tank change and know the cylidner size as well, show SAC rate */
if (!crossed_tankchange && cyl->type.size.mliter) {
double volume_value;
diff --git a/core/qthelper.cpp b/core/qthelper.cpp
index b8afd8267..6d33be383 100644
--- a/core/qthelper.cpp
+++ b/core/qthelper.cpp
@@ -391,7 +391,7 @@ QVector<QPair<QString, int>> selectedDivesGasUsed()
volume_t *diveGases = get_gas_used(d);
for (j = 0; j < d->cylinders.nr; j++) {
if (diveGases[j].mliter) {
- QString gasName = gasname(d->cylinders.cylinders[j].gasmix);
+ QString gasName = gasname(get_cylinder(d, j)->gasmix);
gasUsed[gasName] += diveGases[j].mliter;
}
}
@@ -1186,7 +1186,7 @@ QString get_gas_string(struct gasmix gas)
QString get_divepoint_gas_string(struct dive *d, const divedatapoint &p)
{
int idx = p.cylinderid;
- return get_gas_string(d->cylinders.cylinders[idx].gasmix);
+ return get_gas_string(get_cylinder(d, idx)->gasmix);
}
QString get_taglist_string(struct tag_entry *tag_list)
diff --git a/core/save-git.c b/core/save-git.c
index 662891153..9e14784fe 100644
--- a/core/save-git.c
+++ b/core/save-git.c
@@ -138,7 +138,7 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
nr = nr_cylinders(dive);
for (i = 0; i < nr; i++) {
- cylinder_t *cylinder = dive->cylinders.cylinders + i;
+ cylinder_t *cylinder = get_cylinder(dive, i);
int volume = cylinder->type.size.mliter;
const char *description = cylinder->type.description;
int use = cylinder->cylinder_use;
diff --git a/core/save-html.c b/core/save-html.c
index 380f2fa8e..4c9b428cb 100644
--- a/core/save-html.c
+++ b/core/save-html.c
@@ -132,7 +132,7 @@ static void put_cylinder_HTML(struct membuffer *b, struct dive *dive)
put_string(b, separator);
for (i = 0; i < nr; i++) {
- cylinder_t *cylinder = dive->cylinders.cylinders + i;
+ cylinder_t *cylinder = get_cylinder(dive, i);
put_format(b, "%s{", separator);
separator = ", ";
write_attribute(b, "Type", cylinder->type.description, ", ");
diff --git a/core/save-xml.c b/core/save-xml.c
index a7bf6b23e..f1fbdc831 100644
--- a/core/save-xml.c
+++ b/core/save-xml.c
@@ -179,7 +179,7 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
nr = nr_cylinders(dive);
for (i = 0; i < nr; i++) {
- cylinder_t *cylinder = dive->cylinders.cylinders + i;
+ cylinder_t *cylinder = get_cylinder(dive, i);
int volume = cylinder->type.size.mliter;
const char *description = cylinder->type.description;
int use = cylinder->cylinder_use;
diff --git a/core/statistics.c b/core/statistics.c
index fa7985c90..7adffa2f0 100644
--- a/core/statistics.c
+++ b/core/statistics.c
@@ -334,7 +334,7 @@ bool is_cylinder_used(const struct dive *dive, int idx)
if (idx < 0 || idx >= dive->cylinders.nr)
return false;
- cyl = &dive->cylinders.cylinders[idx];
+ cyl = get_cylinder(dive, idx);
if ((cyl->start.mbar - cyl->end.mbar) > SOME_GAS)
return true;
@@ -369,7 +369,7 @@ volume_t *get_gas_used(struct dive *dive)
volume_t *gases = malloc(dive->cylinders.nr * sizeof(volume_t));
for (idx = 0; idx < dive->cylinders.nr; idx++) {
- cylinder_t *cyl = &dive->cylinders.cylinders[idx];
+ cylinder_t *cyl = get_cylinder(dive, idx);
pressure_t start, end;
start = cyl->start.mbar ? cyl->start : cyl->sample_start;
@@ -408,7 +408,7 @@ void selected_dives_gas_parts(volume_t *o2_tot, volume_t *he_tot)
for (j = 0; j < d->cylinders.nr; j++) {
if (diveGases[j].mliter) {
volume_t o2 = {}, he = {};
- get_gas_parts(d->cylinders.cylinders[j].gasmix, diveGases[j], O2_IN_AIR, &o2, &he);
+ get_gas_parts(get_cylinder(d, j)->gasmix, diveGases[j], O2_IN_AIR, &o2, &he);
o2_tot->mliter += o2.mliter;
he_tot->mliter += he.mliter;
}
diff --git a/core/subsurface-qt/DiveObjectHelper.cpp b/core/subsurface-qt/DiveObjectHelper.cpp
index 8e289d6e1..606614b05 100644
--- a/core/subsurface-qt/DiveObjectHelper.cpp
+++ b/core/subsurface-qt/DiveObjectHelper.cpp
@@ -32,7 +32,7 @@ static QString getFormattedWeight(const struct dive *dive, int idx)
static QString getFormattedCylinder(const struct dive *dive, int idx)
{
- const cylinder_t *cyl = &dive->cylinders.cylinders[idx];
+ const cylinder_t *cyl = get_cylinder(dive, idx);
const char *desc = cyl->type.description;
if (!desc && idx > 0)
return QString();
@@ -46,7 +46,7 @@ static QString getFormattedCylinder(const struct dive *dive, int idx)
static QString getPressures(const struct dive *dive, int i, enum returnPressureSelector ret)
{
- const cylinder_t *cyl = &dive->cylinders.cylinders[i];
+ const cylinder_t *cyl = get_cylinder(dive, i);
QString fmt;
if (ret == START_PRESSURE) {
if (cyl->start.mbar)
@@ -104,10 +104,10 @@ static QString formatGas(const dive *d)
for (int i = 0; i < d->cylinders.nr; i++) {
if (!is_cylinder_used(d, i))
continue;
- gas = d->cylinders.cylinders[i].type.description;
+ gas = get_cylinder(d, i)->type.description;
if (!gas.isEmpty())
gas += QChar(' ');
- gas += gasname(d->cylinders.cylinders[i].gasmix);
+ gas += gasname(get_cylinder(d, i)->gasmix);
// if has a description and if such gas is not already present
if (!gas.isEmpty() && gases.indexOf(gas) == -1) {
if (!gases.isEmpty())
@@ -167,8 +167,8 @@ static QVector<CylinderObjectHelper> makeCylinderObjects(const dive *d)
QVector<CylinderObjectHelper> res;
for (int i = 0; i < d->cylinders.nr; i++) {
//Don't add blank cylinders, only those that have been defined.
- if (d->cylinders.cylinders[i].type.description)
- res.append(CylinderObjectHelper(&d->cylinders.cylinders[i])); // no emplace for QVector. :(
+ if (get_cylinder(d, i)->type.description)
+ res.append(CylinderObjectHelper(get_cylinder(d, i))); // no emplace for QVector. :(
}
return res;
}
@@ -178,7 +178,7 @@ QStringList formatGetCylinder(const dive *d)
QStringList getCylinder;
for (int i = 0; i < d->cylinders.nr; i++) {
if (is_cylinder_used(d, i))
- getCylinder << d->cylinders.cylinders[i].type.description;
+ getCylinder << get_cylinder(d, i)->type.description;
}
return getCylinder;
}
@@ -208,7 +208,7 @@ QStringList getFirstGas(const dive *d)
QStringList gas;
for (int i = 0; i < d->cylinders.nr; i++) {
if (is_cylinder_used(d, i))
- gas << get_gas_string(d->cylinders.cylinders[i].gasmix);
+ gas << get_gas_string(get_cylinder(d, i)->gasmix);
}
return gas;
}
@@ -239,7 +239,7 @@ QStringList getFullCylinderList()
int i = 0;
for_each_dive (i, d) {
for (int j = 0; j < d->cylinders.nr; j++)
- addStringToSortedList(cylinders, d->cylinders.cylinders[j].type.description);
+ addStringToSortedList(cylinders, get_cylinder(d, j)->type.description);
}
for (int ti = 0; ti < MAX_TANK_INFO; ti++)