core: move gasname() to struct gasmix

Also, turn it to use std::string instead of writing into a
global(!) buffer. This was not reentrant.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-07-02 12:38:36 +02:00 committed by bstoeger
parent 9c726d8d6f
commit 22a1120b30
14 changed files with 46 additions and 52 deletions

View file

@ -200,7 +200,7 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall
for (auto [i, cyl]: enumerated_range(dive->cylinders)) {
if (dive->is_cylinder_used(i) || (prefs.include_unused_tanks && !cyl.type.description.empty())){
put_format(&buf, "\\def\\%scyl%cdescription{%s}\n", ssrf, 'a' + i, cyl.type.description.c_str());
put_format(&buf, "\\def\\%scyl%cgasname{%s}\n", ssrf, 'a' + i, gasname(cyl.gasmix));
put_format(&buf, "\\def\\%scyl%cgasname{%s}\n", ssrf, 'a' + i, cyl.gasmix.name().c_str());
put_format(&buf, "\\def\\%scyl%cmixO2{%.1f\\%%}\n", ssrf, 'a' + i, get_o2(cyl.gasmix)/10.0);
put_format(&buf, "\\def\\%scyl%cmixHe{%.1f\\%%}\n", ssrf, 'a' + i, get_he(cyl.gasmix)/10.0);
put_format(&buf, "\\def\\%scyl%cmixN2{%.1f\\%%}\n", ssrf, 'a' + i, (100.0 - (get_o2(cyl.gasmix)/10.0) - (get_he(cyl.gasmix)/10.0)));

View file

@ -178,26 +178,6 @@ bool weightsystem_t::operator==(const weightsystem_t &w2) const
std::tie(w2.weight.grams, w2.description);
}
void get_gas_string(struct gasmix gasmix, char *text, int len)
{
if (gasmix_is_air(gasmix))
snprintf(text, len, "%s", translate("gettextFromC", "air"));
else if (get_he(gasmix) == 0 && get_o2(gasmix) < 1000)
snprintf(text, len, translate("gettextFromC", "EAN%d"), (get_o2(gasmix) + 5) / 10);
else if (get_he(gasmix) == 0 && get_o2(gasmix) == 1000)
snprintf(text, len, "%s", translate("gettextFromC", "oxygen"));
else
snprintf(text, len, "(%d/%d)", (get_o2(gasmix) + 5) / 10, (get_he(gasmix) + 5) / 10);
}
/* Returns a static char buffer - only good for immediate use by printf etc */
const char *gasname(struct gasmix gasmix)
{
static char gas[64];
get_gas_string(gasmix, gas, sizeof(gas));
return gas;
}
volume_t cylinder_t::gas_volume(pressure_t p) const
{
double bar = p.mbar / 1000.0;

View file

@ -93,9 +93,6 @@ extern void dump_cylinders(struct dive *dive, bool verbose);
/* Cylinder table functions */
extern void add_cylinder(struct cylinder_table *, int idx, cylinder_t cyl);
void get_gas_string(struct gasmix gasmix, char *text, int len);
const char *gasname(struct gasmix gasmix);
struct ws_info {
std::string name;
weight_t weight;

View file

@ -2,6 +2,7 @@
#include "gas.h"
#include "pref.h"
#include "errorhelper.h"
#include "format.h"
#include "gettext.h"
#include <stdio.h>
#include <string.h>
@ -183,3 +184,15 @@ const char *gastype_name(enum gastype type)
return "";
return translate("gettextFromC", gastype_names[type]);
}
std::string gasmix::name() const
{
if (gasmix_is_air(*this))
return translate("gettextFromC", "air");
else if (get_he(*this) == 0 && get_o2(*this) < 1000)
return format_string_std(translate("gettextFromC", "EAN%d"), (get_o2(*this) + 5) / 10);
else if (get_he(*this) == 0 && get_o2(*this) == 1000)
return translate("gettextFromC", "oxygen");
else
return format_string_std("(%d/%d)", (get_o2(*this) + 5) / 10, (get_he(*this) + 5) / 10);
}

View file

@ -5,6 +5,8 @@
#include "divemode.h"
#include "units.h"
#include <string>
enum gas_component { N2, HE, O2 };
// o2 == 0 && he == 0 -> air
@ -12,6 +14,7 @@ enum gas_component { N2, HE, O2 };
struct gasmix {
fraction_t o2;
fraction_t he;
std::string name() const;
};
static const struct gasmix gasmix_invalid = { { -1 }, { -1 } };
static const struct gasmix gasmix_air = { { 0 }, { 0 } };

View file

@ -422,7 +422,7 @@ static std::vector<gaschanges> analyze_gaslist(struct diveplan *diveplan, struct
for (size_t nr = 0; nr < gaschanges.size(); 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.get_cylinder(idx)->gasmix));
idx, dive.get_cylinder(idx)->gasmix.name().c_str());
}
#endif
return gaschanges;
@ -737,7 +737,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
}
#if DEBUG_PLAN & 4
printf("gas %s\n", gasname(&gas));
printf("gas %s\n", gas.name().c_str());
printf("depth %5.2lfm \n", depth / 1000.0);
printf("current_cylinder %i\n", current_cylinder);
#endif
@ -876,7 +876,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
else
current_cylinder = get_gasidx(dive, gas);
if (current_cylinder == -1) {
report_error(translate("gettextFromC", "Can't find gas %s"), gasname(gas));
report_error(translate("gettextFromC", "Can't find gas %s"), gas.name().c_str());
current_cylinder = 0;
}
reset_regression(ds);

View file

@ -64,7 +64,7 @@ static std::string icd_entry(struct icd_data *icdvalues, bool printheader, int t
b += casprintf_loc(
"<tr><td rowspan='2' style= 'vertical-align:top;'>%3d%s</td>"
"<td rowspan=2 style= 'vertical-align:top;'>%s&#10137;",
(time_seconds + 30) / 60, translate("gettextFromC", "min"), gasname(gas_from));
(time_seconds + 30) / 60, translate("gettextFromC", "min"), gas_from.name().c_str());
b += casprintf_loc(
"%s</td><td style='padding-left: 10px;'>%+5.1f%%</td>"
"<td style= 'padding-left: 15px; color:%s;'>%+5.1f%%</td>"
@ -72,7 +72,7 @@ static std::string icd_entry(struct icd_data *icdvalues, bool printheader, int t
"<tr><td style='padding-left: 10px;'>%+5.2f%s</td>"
"<td style='padding-left: 15px; color:%s;'>%+5.2f%s</td>"
"<td style='padding-left: 15px;'>%+5.2f%s</td></tr>",
gasname(gas_to), icdvalues->dHe / 10.0,
gas_to.name().c_str(), icdvalues->dHe / 10.0,
((5 * icdvalues->dN2) > -icdvalues->dHe) ? "red" : "#383838", icdvalues->dN2 / 10.0 , 0.2 * (-icdvalues->dHe / 10.0),
ambientpressure_mbar * icdvalues->dHe / 1e6f, translate("gettextFromC", "bar"), ((5 * icdvalues->dN2) > -icdvalues->dHe) ? "red" : "#383838",
ambientpressure_mbar * icdvalues->dN2 / 1e6f, translate("gettextFromC", "bar"),
@ -237,7 +237,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
decimals, depthvalue, depth_unit,
FRACTION_TUPLE(dp->time - lasttime, 60),
FRACTION_TUPLE(dp->time, 60),
gasname(gasmix),
gasmix.name().c_str(),
(double) dp->setpoint / 1000.0);
} else {
buf += casprintf_loc(translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s"),
@ -245,7 +245,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
decimals, depthvalue, depth_unit,
FRACTION_TUPLE(dp->time - lasttime, 60),
FRACTION_TUPLE(dp->time, 60),
gasname(gasmix));
gasmix.name().c_str());
}
buf += "<br/>\n";
@ -259,14 +259,14 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
decimals, depthvalue, depth_unit,
FRACTION_TUPLE(dp->time - lasttime, 60),
FRACTION_TUPLE(dp->time, 60),
gasname(gasmix),
gasmix.name().c_str(),
(double) dp->setpoint / 1000.0);
} else {
buf += casprintf_loc(translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s %s"),
decimals, depthvalue, depth_unit,
FRACTION_TUPLE(dp->time - lasttime, 60),
FRACTION_TUPLE(dp->time, 60),
gasname(gasmix),
gasmix.name().c_str(),
translate("gettextFromC", divemode_text_ui[dp->divemode]));
}
buf += "<br/>\n";
@ -327,10 +327,10 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
if (nextdp->setpoint) {
temp = casprintf_loc(translate("gettextFromC", "(SP = %.1fbar CCR)"), nextdp->setpoint / 1000.0);
buf += format_string_std("<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>",
gasname(newgasmix), temp.c_str());
newgasmix.name().c_str(), temp.c_str());
} else {
buf += format_string_std("<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>",
gasname(newgasmix), dp->divemode == UNDEF_COMP_TYPE || dp->divemode == nextdp->divemode ? "" : translate("gettextFromC", divemode_text_ui[nextdp->divemode]));
newgasmix.name().c_str(), dp->divemode == UNDEF_COMP_TYPE || dp->divemode == nextdp->divemode ? "" : translate("gettextFromC", divemode_text_ui[nextdp->divemode]));
if (isascent && (get_he(lastprintgasmix) > 0)) { // For a trimix gas change on ascent, save ICD info if previous cylinder had helium
if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calulations
icdwarning = true;
@ -348,9 +348,9 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
// If a new gas has been used for this segment, now is the time to show it
if (dp->setpoint) {
temp = casprintf_loc(translate("gettextFromC", "(SP = %.1fbar CCR)"), (double) dp->setpoint / 1000.0);
buf += format_string_std("<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(gasmix), temp.c_str());
buf += format_string_std("<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasmix.name().c_str(), temp.c_str());
} else {
buf += format_string_std("<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(gasmix),
buf += format_string_std("<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasmix.name().c_str(),
lastdivemode == UNDEF_COMP_TYPE || lastdivemode == dp->divemode ? "" : translate("gettextFromC", divemode_text_ui[dp->divemode]));
if (get_he(lastprintgasmix) > 0) { // For a trimix gas change, save ICD info if previous cylinder had helium
if (isobaric_counterdiffusion(lastprintgasmix, gasmix, &icdvalues)) // Do icd calculations
@ -380,9 +380,9 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
if (plan_verbatim) {
if (lastsetpoint >= 0) {
if (nextdp && nextdp->setpoint) {
buf += casprintf_loc(translate("gettextFromC", "Switch gas to %s (SP = %.1fbar)"), gasname(newgasmix), (double) nextdp->setpoint / 1000.0);
buf += casprintf_loc(translate("gettextFromC", "Switch gas to %s (SP = %.1fbar)"), newgasmix.name().c_str(), (double) nextdp->setpoint / 1000.0);
} else {
buf += format_string_std(translate("gettextFromC", "Switch gas to %s"), gasname(newgasmix));
buf += format_string_std(translate("gettextFromC", "Switch gas to %s"), newgasmix.name().c_str());
if ((isascent) && (get_he(lastprintgasmix) > 0)) { // For a trimix gas change on ascent:
if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calculations
icdwarning = true;
@ -535,18 +535,18 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
/* Print the gas consumption for every cylinder here to temp buffer. */
if (lrint(volume) > 0) {
temp = casprintf_loc(translate("gettextFromC", "%.0f%s/%.0f%s of <span style='color: red;'><b>%s</b></span> (%.0f%s/%.0f%s in planned ascent)"),
volume, unit, pressure, pressure_unit, gasname(cyl.gasmix), deco_volume, unit, deco_pressure, pressure_unit);
volume, unit, pressure, pressure_unit, cyl.gasmix.name().c_str(), deco_volume, unit, deco_pressure, pressure_unit);
} else {
temp = casprintf_loc(translate("gettextFromC", "%.0f%s/%.0f%s of <span style='color: red;'><b>%s</b></span>"),
volume, unit, pressure, pressure_unit, gasname(cyl.gasmix));
volume, unit, pressure, pressure_unit, cyl.gasmix.name().c_str());
}
} else {
if (lrint(volume) > 0) {
temp = casprintf_loc(translate("gettextFromC", "%.0f%s of <span style='color: red;'><b>%s</b></span> (%.0f%s during planned ascent)"),
volume, unit, gasname(cyl.gasmix), deco_volume, unit);
volume, unit, cyl.gasmix.name().c_str(), deco_volume, unit);
} else {
temp = casprintf_loc(translate("gettextFromC", "%.0f%s of <span style='color: red;'><b>%s</b></span>"),
volume, unit, gasname(cyl.gasmix));
volume, unit, cyl.gasmix.name().c_str());
}
}
/* Gas consumption: Now finally print all strings to output */
@ -591,7 +591,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
buf += "<div>\n";
o2warning_exist = true;
temp = casprintf_loc(translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"),
pressures.o2, FRACTION_TUPLE(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit);
pressures.o2, FRACTION_TUPLE(dp->time, 60), gasmix.name().c_str(), decimals, depth_value, depth_unit);
buf += format_string_std("<span style='color: red;'>%s </span> %s<br/>\n", translate("gettextFromC", "Warning:"), temp.c_str());
} else if (pressures.o2 < 0.16) {
const char *depth_unit;
@ -601,7 +601,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
buf += "<div>";
o2warning_exist = true;
temp = casprintf_loc(translate("gettextFromC", "low pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"),
pressures.o2, FRACTION_TUPLE(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit);
pressures.o2, FRACTION_TUPLE(dp->time, 60), gasmix.name().c_str(), decimals, depth_value, depth_unit);
buf += format_string_std("<span style='color: red;'>%s </span> %s<br/>\n", translate("gettextFromC", "Warning:"), temp.c_str());
}
}

View file

@ -1281,7 +1281,7 @@ static std::vector<std::string> plot_string(const struct dive *d, const struct p
continue;
struct gasmix mix = d->get_cylinder(cyl)->gasmix;
pressurevalue = get_pressure_units(mbar, &pressure_unit);
res.push_back(casprintf_loc(translate("gettextFromC", "P: %d%s (%s)"), pressurevalue, pressure_unit, gasname(mix)));
res.push_back(casprintf_loc(translate("gettextFromC", "P: %d%s (%s)"), pressurevalue, pressure_unit, mix.name().c_str()));
}
if (entry.temperature) {
tempvalue = get_temp_units(entry.temperature, &temp_unit);

View file

@ -351,7 +351,7 @@ QVector<QPair<QString, int>> selectedDivesGasUsed()
std::vector<volume_t> diveGases = get_gas_used(d);
for (size_t j = 0; j < d->cylinders.size(); j++) {
if (diveGases[j].mliter) {
QString gasName = gasname(d->get_cylinder(j)->gasmix);
QString gasName = QString::fromStdString(d->get_cylinder(j)->gasmix.name());
gasUsed[gasName] += diveGases[j].mliter;
}
}

View file

@ -179,7 +179,7 @@ QString formatGas(const dive *d)
QString gas = QString::fromStdString(cyl.type.description);
if (!gas.isEmpty())
gas += QChar(' ');
gas += gasname(cyl.gasmix);
gas += QString::fromStdString(cyl.gasmix.name());
// if has a description and if such gas is not already present
if (!gas.isEmpty() && gases.indexOf(gas) == -1) {
if (!gases.isEmpty())

View file

@ -347,7 +347,8 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button)
text << tr("Cylinders:\n");
for (auto [idx, cyl]: enumerated_range(current_dive->cylinders)) {
if (current_dive->is_cylinder_used(idx))
text << QString::fromStdString(cyl.type.description) << " " << gasname(cyl.gasmix) << "\n";
text << QString::fromStdString(cyl.type.description) << " "
<< QString::fromStdString(cyl.gasmix.name()) << "\n";
}
}
if (what->weights) {

View file

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

View file

@ -125,7 +125,7 @@ void DiveEventItem::setupToolTipString(struct gasmix lastgasmix)
struct icd_data icd_data;
struct gasmix mix = dive->get_gasmix_from_event(ev);
name += ": ";
name += gasname(mix);
name += QString::fromStdString(mix.name());
/* Do we have an explicit cylinder index? Show it. */
if (ev.gas.index >= 0)

View file

@ -57,7 +57,7 @@ void TankItem::createBar(int startTime, int stopTime, struct gasmix gas)
rect->setPen(QPen(QBrush(), 0.0)); // get rid of the thick line around the rectangle
rects.push_back(rect);
DiveTextItem *label = new DiveTextItem(dpr, 1.0, Qt::AlignVCenter | Qt::AlignRight, rect);
label->set(gasname(gas), Qt::black);
label->set(QString::fromStdString(gas.name()), Qt::black);
label->setPos(x + 2.0 * dpr, height() / 2.0);
label->setZValue(101);
}