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>
This commit is contained in:
Berthold Stoeger 2019-08-04 22:13:49 +02:00 committed by Dirk Hohndel
parent 52d8d89f73
commit 794066b236
30 changed files with 149 additions and 148 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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, ", ");

View file

@ -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;

View file

@ -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;
}

View file

@ -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++)

View file

@ -445,7 +445,7 @@ void DiveLogExportDialog::export_TeX(const char *filename, const bool selected_o
put_format(&buf, "\n%% Gas use information:\n");
qty_cyl = 0;
for (i = 0; i < dive->cylinders.nr; i++){
const cylinder_t &cyl = dive->cylinders.cylinders[i];
const cylinder_t &cyl = *get_cylinder(dive, i);
if (is_cylinder_used(dive, i) || (prefs.display_unused_tanks && cyl.type.description)){
put_format(&buf, "\\def\\%scyl%cdescription{%s}\n", ssrf, 'a' + i, cyl.type.description);
put_format(&buf, "\\def\\%scyl%cgasname{%s}\n", ssrf, 'a' + i, gasname(cyl.gasmix));

View file

@ -512,7 +512,7 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button)
text << tr("Cylinders:\n");
for (cyl = 0; cyl < displayed_dive.cylinders.nr; cyl++) {
if (is_cylinder_used(&displayed_dive, cyl))
text << displayed_dive.cylinders.cylinders[cyl].type.description << " " << gasname(displayed_dive.cylinders.cylinders[cyl].gasmix) << "\n";
text << get_cylinder(&displayed_dive, cyl)->type.description << " " << gasname(get_cylinder(&displayed_dive, cyl)->gasmix) << "\n";
}
}
if (what->weights) {

View file

@ -66,7 +66,7 @@ void TabDiveInformation::updateProfile()
gaslist.append(separator); volumes.append(separator); SACs.append(separator);
separator = "\n";
gaslist.append(gasname(current_dive->cylinders.cylinders[i].gasmix));
gaslist.append(gasname(get_cylinder(current_dive, i)->gasmix));
if (!gases[i].mliter)
continue;
volumes.append(get_volume_string(gases[i], true));

View file

@ -656,7 +656,7 @@ bool cylinders_equal(const dive *d1, const dive *d2)
if (d1->cylinders.nr != d2->cylinders.nr)
return false;
for (int i = 0; i < d1->cylinders.nr; ++i) {
if (!same_cylinder(d1->cylinders.cylinders[i], d2->cylinders.cylinders[i]))
if (!same_cylinder(*get_cylinder(d1, i), *get_cylinder(d2, i)))
return false;
}
return true;

View file

@ -1125,10 +1125,10 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
if (state != "add" && !is_cylinder_used(d, i))
continue;
d->cylinders.cylinders[i].start.mbar = parsePressureToMbar(startpressure[j]);
d->cylinders.cylinders[i].end.mbar = parsePressureToMbar(endpressure[j]);
if (d->cylinders.cylinders[i].end.mbar > d->cylinders.cylinders[i].start.mbar)
d->cylinders.cylinders[i].end.mbar = d->cylinders.cylinders[i].start.mbar;
get_cylinder(d, i)->start.mbar = parsePressureToMbar(startpressure[j]);
get_cylinder(d, i)->end.mbar = parsePressureToMbar(endpressure[j]);
if (get_cylinder(d, i)->end.mbar > get_cylinder(d, i)->start.mbar)
get_cylinder(d, i)->end.mbar = get_cylinder(d, i)->start.mbar;
j++;
}
@ -1146,8 +1146,8 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
he >= 0 && he <= 1000 &&
o2 + he <= 1000) {
diveChanged = true;
d->cylinders.cylinders[i].gasmix.o2.permille = o2;
d->cylinders.cylinders[i].gasmix.he.permille = he;
get_cylinder(d, i)->gasmix.o2.permille = o2;
get_cylinder(d, i)->gasmix.he.permille = he;
}
j++;
}
@ -1173,9 +1173,9 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
break;
}
}
d->cylinders.cylinders[j].type.description = copy_qstring(usedCylinder[k]);
d->cylinders.cylinders[j].type.size.mliter = size;
d->cylinders.cylinders[j].type.workingpressure.mbar = wp;
get_cylinder(d, j)->type.description = copy_qstring(usedCylinder[k]);
get_cylinder(d, j)->type.size.mliter = size;
get_cylinder(d, j)->type.workingpressure.mbar = wp;
k++;
}
}
@ -1789,8 +1789,8 @@ QStringList QMLManager::cylinderInit() const
int i = 0;
for_each_dive (i, d) {
for (int j = 0; j < d->cylinders.nr; j++) {
if (!empty_string(d->cylinders.cylinders[j].type.description))
cylinders << d->cylinders.cylinders[j].type.description;
if (!empty_string(get_cylinder(d, j)->type.description))
cylinders << get_cylinder(d, j)->type.description;
}
}

View file

@ -748,7 +748,7 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QMo
label_y_offset = -7 * axisLog;
}
plotPressureValue(mbar, entry->sec, alignVar, value_y_offset);
plotGasValue(mbar, entry->sec, displayed_dive.cylinders.cylinders[cyl].gasmix, alignVar, label_y_offset);
plotGasValue(mbar, entry->sec, get_cylinder(&displayed_dive, cyl)->gasmix, alignVar, label_y_offset);
seen_cyl[cyl] = true;
/* Alternate alignment as we see cylinder use.. */

View file

@ -1536,7 +1536,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
int newGasIdx = gasChangeIdx + 1;
const struct plot_data &newGasEntry = plotInfo.entry[newGasIdx];
qDebug() << "after gas change at " << newGasEntry->sec << ": sensor pressure" << newGasEntry->pressure[0] << "interpolated" << newGasEntry->pressure[1];
if (get_plot_sensor_pressure(&plotInfo, gasChangeIdx) == 0 || displayed_dive.cylinders.cylinders[gasChangeEntry->sensor[0]].sample_start.mbar == 0) {
if (get_plot_sensor_pressure(&plotInfo, gasChangeIdx) == 0 || get_cylinder(&displayed_dive, gasChangeEntry->sensor[0])->sample_start.mbar == 0) {
// if we have no sensorpressure or if we have no pressure from samples we can assume that
// we only have interpolated pressure (the pressure in the entry may be stored in the sensor
// pressure field if this is the first or last entry for this tank... see details in gaspressures.c
@ -1545,7 +1545,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
QAction *adjustOldPressure = m.addAction(tr("Adjust pressure of cyl. %1 (currently interpolated as %2)")
.arg(gasChangeEntry->sensor[0] + 1).arg(get_pressure_string(pressure)));
}
if (get_plot_sensor_pressure(&plotInfo, newGasIdx) == 0 || displayed_dive.cylinders.cylinders[newGasEntry->sensor[0]].sample_start.mbar == 0) {
if (get_plot_sensor_pressure(&plotInfo, newGasIdx) == 0 || get_cylinder(&displayed_dive, newGasEntry->sensor[0])->sample_start.mbar == 0) {
// we only have interpolated press -- see commend above
pressure_t pressure;
pressure.mbar = get_plot_interpolated_pressure(&plotInfo, newGasIdx) ? : get_plot_sensor_pressure(&plotInfo, newGasIdx);
@ -1882,7 +1882,7 @@ void ProfileWidget2::repositionDiveHandlers()
QLineF line(p1, p2);
QPointF pos = line.pointAt(0.5);
gases[i]->setPos(pos);
gases[i]->setText(get_gas_string(displayed_dive.cylinders.cylinders[datapoint.cylinderid].gasmix));
gases[i]->setText(get_gas_string(get_cylinder(&displayed_dive, datapoint.cylinderid)->gasmix));
gases[i]->setVisible(datapoint.entered &&
(i == 0 || gases[i]->text() != gases[i-1]->text()));
}

View file

@ -97,7 +97,7 @@ void TankItem::modelDataChanged(const QModelIndex&, const QModelIndex&)
// start with the first gasmix and at the start of the dive
int cyl = explicit_first_cylinder(&displayed_dive, dc);
struct gasmix gasmix = displayed_dive.cylinders.cylinders[cyl].gasmix;
struct gasmix gasmix = get_cylinder(&displayed_dive, cyl)->gasmix;
int startTime = 0;
// work through all the gas changes and add the rectangle for each gas while it was used

View file

@ -134,7 +134,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
if (!index.isValid() || index.row() >= rows)
return QVariant();
const cylinder_t *cyl = &displayed_dive.cylinders.cylinders[index.row()];
const cylinder_t *cyl = get_cylinder(&displayed_dive, index.row());
switch (role) {
case Qt::BackgroundRole: {
@ -259,7 +259,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
cylinder_t *CylindersModel::cylinderAt(const QModelIndex &index)
{
return &displayed_dive.cylinders.cylinders[index.row()];
return get_cylinder(&displayed_dive, index.row());
}
// this is our magic 'pass data in' function that allows the delegate to get
@ -449,7 +449,7 @@ static bool show_cylinder(struct dive *dive, int i)
if (is_cylinder_used(dive, i))
return true;
cylinder_t *cyl = dive->cylinders.cylinders + i;
cylinder_t *cyl = get_cylinder(dive, i);
if (cyl->start.mbar || cyl->sample_start.mbar ||
cyl->end.mbar || cyl->sample_end.mbar)
return true;
@ -533,10 +533,10 @@ void CylindersModel::moveAtFirst(int cylid)
cylinder_t temp_cyl;
beginMoveRows(QModelIndex(), cylid, cylid, QModelIndex(), 0);
memmove(&temp_cyl, &displayed_dive.cylinders.cylinders[cylid], sizeof(temp_cyl));
memmove(&temp_cyl, get_cylinder(&displayed_dive, cylid), sizeof(temp_cyl));
for (int i = cylid - 1; i >= 0; i--)
memmove(&displayed_dive.cylinders.cylinders[i + 1], &displayed_dive.cylinders.cylinders[i], sizeof(temp_cyl));
memmove(&displayed_dive.cylinders.cylinders[0], &temp_cyl, sizeof(temp_cyl));
memmove(get_cylinder(&displayed_dive, i + 1), get_cylinder(&displayed_dive, i), sizeof(temp_cyl));
memmove(get_cylinder(&displayed_dive, 0), &temp_cyl, sizeof(temp_cyl));
// Create a mapping of cylinder indexes:
// 1) Fill mapping[0]..mapping[cyl] with 0..index
@ -558,7 +558,7 @@ void CylindersModel::updateDecoDepths(pressure_t olddecopo2)
pressure_t decopo2;
decopo2.mbar = prefs.decopo2;
for (int i = 0; i < displayed_dive.cylinders.nr; i++) {
cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i];
cylinder_t *cyl = get_cylinder(&displayed_dive, i);
/* If the gas's deco MOD matches the old pO2, it will have been automatically calculated and should be updated.
* If they don't match, we should leave the user entered depth as it is */
if (cyl->depth.mm == gas_mod(cyl->gasmix, olddecopo2, &displayed_dive, M_OR_FT(3, 10)).mm) {
@ -578,7 +578,7 @@ bool CylindersModel::updateBestMixes()
// Check if any of the cylinders are best mixes, update if needed
bool gasUpdated = false;
for (int i = 0; i < displayed_dive.cylinders.nr; i++) {
cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i];
cylinder_t *cyl = get_cylinder(&displayed_dive, i);
if (cyl->bestmix_o2) {
cyl->gasmix.o2 = best_o2(displayed_dive.maxdepth, &displayed_dive);
// fO2 + fHe must not be greater than 1

View file

@ -268,13 +268,13 @@ QVariant DivePlannerPointsModel::data(const QModelIndex &index, int role) const
case GAS:
/* Check if we have the same gasmix two or more times
* If yes return more verbose string */
int same_gas = same_gasmix_cylinder(&displayed_dive.cylinders.cylinders[p.cylinderid], p.cylinderid, &displayed_dive, true);
int same_gas = same_gasmix_cylinder(get_cylinder(&displayed_dive, p.cylinderid), p.cylinderid, &displayed_dive, true);
if (same_gas == -1)
return get_gas_string(displayed_dive.cylinders.cylinders[p.cylinderid].gasmix);
return get_gas_string(get_cylinder(&displayed_dive, p.cylinderid)->gasmix);
else
return get_gas_string(displayed_dive.cylinders.cylinders[p.cylinderid].gasmix) +
return get_gas_string(get_cylinder(&displayed_dive, p.cylinderid)->gasmix) +
QString(" (%1 %2 ").arg(tr("cyl.")).arg(p.cylinderid + 1) +
displayed_dive.cylinders.cylinders[p.cylinderid].type.description + ")";
get_cylinder(&displayed_dive, p.cylinderid)->type.description + ")";
}
} else if (role == Qt::DecorationRole) {
switch (index.column()) {
@ -894,7 +894,7 @@ void DivePlannerPointsModel::createTemporaryPlan()
struct deco_state *cache = NULL;
struct divedatapoint *dp = NULL;
for (int i = 0; i < displayed_dive.cylinders.nr; i++) {
cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i];
cylinder_t *cyl = get_cylinder(&displayed_dive, i);
if (cyl->depth.mm && cyl->cylinder_use != NOT_USED) {
dp = create_dp(0, cyl->depth.mm, i, 0);
if (diveplan.dp) {

View file

@ -157,7 +157,7 @@ QVariant DiveTripModelBase::diveData(const struct dive *d, int column, int role)
case SUIT:
return QString(d->suit);
case CYLINDER:
return d->cylinders.nr > 0 ? QString(d->cylinders.cylinders[0].type.description) : QString();
return d->cylinders.nr > 0 ? QString(get_cylinder(d, 0)->type.description) : QString();
case SAC:
return displaySac(d, prefs.units.show_units_table);
case OTU:
@ -1411,7 +1411,7 @@ bool DiveTripModelList::lessThan(const QModelIndex &i1, const QModelIndex &i2) c
return lessThanHelper(strCmp(d1->suit, d2->suit), row_diff);
case CYLINDER:
if (d1->cylinders.nr > 0 && d2->cylinders.nr > 0)
return lessThanHelper(strCmp(d1->cylinders.cylinders[0].type.description, d2->cylinders.cylinders[0].type.description), row_diff);
return lessThanHelper(strCmp(get_cylinder(d1, 0)->type.description, get_cylinder(d2, 0)->type.description), row_diff);
return d1->cylinders.nr - d2->cylinders.nr < 0;
case GAS:
return lessThanHelper(nitrox_sort_value(d1) - nitrox_sort_value(d2), row_diff);

View file

@ -27,7 +27,7 @@ static QStringList getGasList()
{
QStringList list;
for (int i = 0; i < displayed_dive.cylinders.nr; i++) {
const cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i];
const cylinder_t *cyl = get_cylinder(&displayed_dive, i);
/* Check if we have the same gasmix two or more times
* If yes return more verbose string */
int same_gas = same_gasmix_cylinder(cyl, i, &displayed_dive, true);

View file

@ -507,7 +507,7 @@ static void merge_cylinder_info(cylinder_t *src, cylinder_t *dst)
static int smtk_clean_cylinders(struct dive *d)
{
int i = tanks - 1;
cylinder_t *cyl, *base = &d->cylinders.cylinders[0];
cylinder_t *cyl, *base = get_cylinder(d, 0);
cyl = base + tanks - 1;
while (cyl != base) {
@ -1038,24 +1038,24 @@ void smartrak_import(const char *file, struct dive_table *divetable)
int tankidxcol = coln(TANKIDX);
for (i = 0; i < tanks; i++) {
if (smtkdive->cylinders.cylinders[i].start.mbar == 0)
smtkdive->cylinders.cylinders[i].start.mbar = lrint(strtod(col[(i * 2) + pstartcol]->bind_ptr, NULL) * 1000);
if (get_cylinder(smtkdive, i)->start.mbar == 0)
get_cylinder(smtkdive, i)->start.mbar = lrint(strtod(col[(i * 2) + pstartcol]->bind_ptr, NULL) * 1000);
/*
* If there is a start pressure ensure that end pressure is not zero as
* will be registered in DCs which only keep track of differential pressures,
* and collect the data registered by the user in mdb
*/
if (smtkdive->cylinders.cylinders[i].end.mbar == 0 && smtkdive->cylinders.cylinders[i].start.mbar != 0)
smtkdive->cylinders.cylinders[i].end.mbar = lrint(strtod(col[(i * 2) + 1 + pstartcol]->bind_ptr, NULL) * 1000 ? : 1000);
if (smtkdive->cylinders.cylinders[i].gasmix.o2.permille == 0)
smtkdive->cylinders.cylinders[i].gasmix.o2.permille = lrint(strtod(col[i + o2fraccol]->bind_ptr, NULL) * 10);
if (get_cylinder(smtkdive, i)->end.mbar == 0 && get_cylinder(smtkdive, i)->start.mbar != 0)
get_cylinder(smtkdive, i)->end.mbar = lrint(strtod(col[(i * 2) + 1 + pstartcol]->bind_ptr, NULL) * 1000 ? : 1000);
if (get_cylinder(smtkdive, i)->gasmix.o2.permille == 0)
get_cylinder(smtkdive, i)->gasmix.o2.permille = lrint(strtod(col[i + o2fraccol]->bind_ptr, NULL) * 10);
if (smtk_version == 10213) {
if (smtkdive->cylinders.cylinders[i].gasmix.he.permille == 0)
smtkdive->cylinders.cylinders[i].gasmix.he.permille = lrint(strtod(col[i + hefraccol]->bind_ptr, NULL) * 10);
if (get_cylinder(smtkdive, i)->gasmix.he.permille == 0)
get_cylinder(smtkdive, i)->gasmix.he.permille = lrint(strtod(col[i + hefraccol]->bind_ptr, NULL) * 10);
} else {
smtkdive->cylinders.cylinders[i].gasmix.he.permille = 0;
get_cylinder(smtkdive, i)->gasmix.he.permille = 0;
}
smtk_build_tank_info(mdb_clon, &smtkdive->cylinders.cylinders[i], col[i + tankidxcol]->bind_ptr);
smtk_build_tank_info(mdb_clon, get_cylinder(smtkdive, i), col[i + tankidxcol]->bind_ptr);
}
/* Check for duplicated cylinders and clean them */
smtk_clean_cylinders(smtkdive);