diff --git a/core/planner.h b/core/planner.h index cf08fa152..d48c55e8f 100644 --- a/core/planner.h +++ b/core/planner.h @@ -48,7 +48,6 @@ extern int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, du extern bool diveplan_empty(struct diveplan *diveplan); extern void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_disclaimer, int error); extern const char *get_planner_disclaimer(); -extern char *get_planner_disclaimer_formatted(); extern void free_dps(struct diveplan *diveplan); @@ -64,6 +63,8 @@ struct decostop { #ifdef __cplusplus } +#include +extern std::string get_planner_disclaimer_formatted(); extern bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer); #endif #endif // PLANNER_H diff --git a/core/plannernotes.cpp b/core/plannernotes.cpp index 494f24348..1ae0c5f0c 100644 --- a/core/plannernotes.cpp +++ b/core/plannernotes.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* plannernotes.cpp * - * code that allows us to plan future dives + * format notes describing a dive plan * * (c) Dirk Hohndel 2013 */ @@ -19,8 +19,8 @@ #include "libdivecomputer/parser.h" #include "qthelper.h" #include "format.h" +#include "subsurface-string.h" #include "version.h" -#include "membuffer.h" static int diveplan_duration(struct diveplan *diveplan) { @@ -47,21 +47,22 @@ static int diveplan_duration(struct diveplan *diveplan) * 5) Pointers to gas mixes in the gas change: gas-from and gas-to. * Returns: The size of the output buffer that has been used after the new results have been added. */ -static void add_icd_entry(struct membuffer *b, struct icd_data *icdvalues, bool printheader, int time_seconds, int ambientpressure_mbar, struct gasmix gas_from, struct gasmix gas_to) +static std::string icd_entry(struct icd_data *icdvalues, bool printheader, int time_seconds, int ambientpressure_mbar, struct gasmix gas_from, struct gasmix gas_to) { + std::string b; if (printheader) { // Create a table description and a table header if no icd data have been written yet. - put_format(b, "
%s:", translate("gettextFromC","Isobaric counterdiffusion information")); - put_format(b, "", translate("gettextFromC", "runtime")); - put_format(b, "", translate("gettextFromC", "gaschange")); - put_format(b, "", translate("gettextFromC", "ΔHe")); - put_format(b, "", translate("gettextFromC", "ΔN₂")); - put_format(b, "", translate("gettextFromC", "max ΔN₂")); + b += format_string_std("
%s:", translate("gettextFromC","Isobaric counterdiffusion information")); + b += format_string_std("
%s%s%s%s%s
", translate("gettextFromC", "runtime")); + b += format_string_std("", translate("gettextFromC", "gaschange")); + b += format_string_std("", translate("gettextFromC", "ΔHe")); + b += format_string_std("", translate("gettextFromC", "ΔN₂")); + b += format_string_std("", translate("gettextFromC", "max ΔN₂")); } // Add one entry to the icd table: - put_format_loc(b, + b += casprintf_loc( "" "" "" "" @@ -73,6 +74,7 @@ static void add_icd_entry(struct membuffer *b, struct icd_data *icdvalues, bool ambientpressure_mbar * icdvalues->dHe / 1e6f, translate("gettextFromC", "bar"), ((5 * icdvalues->dN2) > -icdvalues->dHe) ? "red" : "#383838", ambientpressure_mbar * icdvalues->dN2 / 1e6f, translate("gettextFromC", "bar"), ambientpressure_mbar * -icdvalues->dHe / 5e6f, translate("gettextFromC", "bar")); + return b; } extern "C" const char *get_planner_disclaimer() @@ -84,19 +86,17 @@ extern "C" const char *get_planner_disclaimer() } /* Returns newly allocated buffer. Must be freed by caller */ -extern "C" char *get_planner_disclaimer_formatted() +extern std::string get_planner_disclaimer_formatted() { - struct membuffer buf = { 0 }; const char *deco = decoMode(true) == VPMB ? translate("gettextFromC", "VPM-B") : translate("gettextFromC", "BUHLMANN"); - put_format(&buf, get_planner_disclaimer(), deco); - return detach_cstring(&buf); + return format_string_std(get_planner_disclaimer(), deco); } extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_disclaimer, int error) { - struct membuffer buf = { 0 }; - struct membuffer icdbuf = { 0 }; + std::string buf; + std::string icdbuf; const char *segmentsymbol; int lastdepth = 0, lasttime = 0, lastsetpoint = -1, newdepth = 0, lastprintdepth = 0, lastprintsetpoint = -1; struct gasmix lastprintgasmix = gasmix_invalid; @@ -115,69 +115,68 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, struct divedatapoint *nextdp = NULL; struct divedatapoint *lastbottomdp = NULL; struct icd_data icdvalues; - char *temp; if (!dp) return; if (error) { - put_format(&buf, "%s %s
", + buf += format_string_std("%s %s
", translate("gettextFromC", "Warning:"), translate("gettextFromC", "Decompression calculation aborted due to excessive time")); - goto finished; + // TODO: avoid copy + free(dive->notes); + dive->notes = strdup(buf.c_str()); + return; } if (show_disclaimer) { - char *disclaimer = get_planner_disclaimer_formatted(); - put_string(&buf, "
"); - put_string(&buf, disclaimer); - put_string(&buf, "
\n
\n"); - free(disclaimer); + buf += "
"; + buf += get_planner_disclaimer_formatted(); + buf += "
\n
\n"; } - put_string(&buf, "
\n"); + buf += "
\n"; if (diveplan->surface_interval < 0) { - put_format(&buf, "%s (%s) %s", + buf += format_string_std("%s (%s) %s", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan (overlapping dives detected)")); - goto finished; + // TODO: avoid copy + free(dive->notes); + dive->notes = strdup(buf.c_str()); + return; } else if (diveplan->surface_interval >= 48 * 60 *60) { - char *current_date = get_current_date(); - put_format(&buf, "%s (%s) %s %s", + buf += format_string_std("%s (%s) %s %s", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan created on"), - current_date); - free(current_date); + get_current_date().c_str()); } else { - char *current_date = get_current_date(); - put_format_loc(&buf, "%s (%s) %s %d:%02d) %s %s", + buf += casprintf_loc("%s (%s) %s %d:%02d) %s %s", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan (surface interval "), FRACTION(diveplan->surface_interval / 60, 60), translate("gettextFromC", "created on"), - current_date); - free(current_date); + get_current_date().c_str()); } - put_string(&buf, "
\n"); + buf += "
\n"; if (prefs.display_variations && decoMode(true) != RECREATIONAL) - put_format_loc(&buf, translate("gettextFromC", "Runtime: %dmin%s"), + buf += casprintf_loc(translate("gettextFromC", "Runtime: %dmin%s"), diveplan_duration(diveplan), "VARIATIONS"); else - put_format_loc(&buf, translate("gettextFromC", "Runtime: %dmin%s"), + buf += casprintf_loc(translate("gettextFromC", "Runtime: %dmin%s"), diveplan_duration(diveplan), ""); - put_string(&buf, "
\n
\n"); + buf += "
\n
\n"; if (!plan_verbatim) { - put_format(&buf, "
%s%s%s%s%s
%3d%s%s➙", (time_seconds + 30) / 60, translate("gettextFromC", "min"), gasname(gas_from)); - put_format_loc(b, + b += casprintf_loc( "%s%+5.1f%%%+5.1f%%%+5.1f%%
\n\n", translate("gettextFromC", "depth")); + buf += format_string_std("
%s
\n\n", translate("gettextFromC", "depth")); if (plan_display_duration) - put_format(&buf, "", translate("gettextFromC", "duration")); + buf += format_string_std("", translate("gettextFromC", "duration")); if (plan_display_runtime) - put_format(&buf, "", translate("gettextFromC", "runtime")); - put_format(&buf, "\n\n\n", + buf += format_string_std("", translate("gettextFromC", "runtime")); + buf += format_string_std("\n\n\n", translate("gettextFromC", "gas")); } @@ -232,7 +231,7 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, if (dp->depth.mm != lastprintdepth) { if (plan_display_transitions || dp->entered || !dp->next || (gaschange_after && dp->next && dp->depth.mm != nextdp->depth.mm)) { if (dp->setpoint) { - put_format_loc(&buf, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), + buf += casprintf_loc(translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), dp->depth.mm < lastprintdepth ? translate("gettextFromC", "Ascend") : translate("gettextFromC", "Descend"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), @@ -240,7 +239,7 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, gasname(gasmix), (double) dp->setpoint / 1000.0); } else { - put_format_loc(&buf, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s"), + buf += casprintf_loc(translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s"), dp->depth.mm < lastprintdepth ? translate("gettextFromC", "Ascend") : translate("gettextFromC", "Descend"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), @@ -248,28 +247,28 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, gasname(gasmix)); } - put_string(&buf, "
\n"); + buf += "
\n"; } newdepth = dp->depth.mm; lasttime = dp->time; } else { if ((nextdp && dp->depth.mm != nextdp->depth.mm) || gaschange_after) { if (dp->setpoint) { - put_format_loc(&buf, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar CCR)"), + buf += casprintf_loc(translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar CCR)"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), gasname(gasmix), (double) dp->setpoint / 1000.0); } else { - put_format_loc(&buf, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s %s"), + buf += casprintf_loc(translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s %s"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), gasname(gasmix), translate("gettextFromC", divemode_text_ui[dp->divemode])); } - put_string(&buf, "
\n"); + buf += "
\n"; newdepth = dp->depth.mm; lasttime = dp->time; } @@ -307,20 +306,17 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, else segmentsymbol = "-"; // minus sign (a.k.a. horizontal line) for deco stop - put_format(&buf, "", segmentsymbol); + buf += format_string_std("", segmentsymbol); - asprintf_loc(&temp, translate("gettextFromC", "%3.0f%s"), depthvalue, depth_unit); - put_format(&buf, "", temp); - free(temp); + std::string temp = casprintf_loc(translate("gettextFromC", "%3.0f%s"), depthvalue, depth_unit); + buf += format_string_std("", temp.c_str()); if (plan_display_duration) { - asprintf_loc(&temp, translate("gettextFromC", "%3dmin"), (dp->time - lasttime + 30) / 60); - put_format(&buf, "", temp); - free(temp); + temp = casprintf_loc(translate("gettextFromC", "%3dmin"), (dp->time - lasttime + 30) / 60); + buf += format_string_std("", temp.c_str()); } if (plan_display_runtime) { - asprintf_loc(&temp, translate("gettextFromC", "%3dmin"), (dp->time + 30) / 60); - put_format(&buf, "", temp); - free(temp); + temp = casprintf_loc(translate("gettextFromC", "%3dmin"), (dp->time + 30) / 60); + buf += format_string_std("", temp.c_str()); } /* Normally a gas change is displayed on the stopping segment, so only display a gas change at the end of @@ -328,18 +324,17 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, */ if (isascent && gaschange_after && dp->next && nextdp && nextdp->entered) { if (nextdp->setpoint) { - asprintf_loc(&temp, translate("gettextFromC", "(SP = %.1fbar CCR)"), nextdp->setpoint / 1000.0); - put_format(&buf, "", - gasname(newgasmix), temp); - free(temp); + temp = casprintf_loc(translate("gettextFromC", "(SP = %.1fbar CCR)"), nextdp->setpoint / 1000.0); + buf += format_string_std("", + gasname(newgasmix), temp.c_str()); } else { - put_format(&buf, "", + buf += format_string_std("", gasname(newgasmix), 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; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, newgasmix); // .. then print calculations to buffer. + icdbuf += icd_entry(&icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, newgasmix); // .. then print calculations to buffer. icdtableheader = false; } } @@ -351,17 +346,16 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, } else if (gaschange_before || rebreatherchange_before) { // If a new gas has been used for this segment, now is the time to show it if (dp->setpoint) { - asprintf_loc(&temp, translate("gettextFromC", "(SP = %.1fbar CCR)"), (double) dp->setpoint / 1000.0); - put_format(&buf, "", gasname(gasmix), temp); - free(temp); + temp = casprintf_loc(translate("gettextFromC", "(SP = %.1fbar CCR)"), (double) dp->setpoint / 1000.0); + buf += format_string_std("", gasname(gasmix), temp.c_str()); } else { - put_format(&buf, "", gasname(gasmix), + buf += format_string_std("", gasname(gasmix), 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 icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - add_icd_entry(&icdbuf, &icdvalues, icdtableheader, lasttime, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, gasmix); // .. then print data to buffer. + icdbuf += icd_entry(&icdvalues, icdtableheader, lasttime, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, gasmix); // .. then print data to buffer. icdtableheader = false; } } @@ -372,9 +366,9 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, lastdivemode = dp->divemode; gaschange_after = false; } else { - put_string(&buf, ""); + buf += ""; } - put_string(&buf, "\n"); + buf += "\n"; newdepth = dp->depth.mm; // Only add the time we actually displayed so rounding errors dont accumulate lasttime += ((dp->time - lasttime + 30) / 60) * 60; @@ -385,19 +379,19 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, if (plan_verbatim) { if (lastsetpoint >= 0) { if (nextdp && nextdp->setpoint) { - put_format_loc(&buf, 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)"), gasname(newgasmix), (double) nextdp->setpoint / 1000.0); } else { - put_format(&buf, translate("gettextFromC", "Switch gas to %s"), gasname(newgasmix)); + buf += format_string_std(translate("gettextFromC", "Switch gas to %s"), gasname(newgasmix)); if ((isascent) && (get_he(lastprintgasmix) > 0)) { // For a trimix gas change on ascent: if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calculations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, newgasmix); // ... then print data to buffer. + icdbuf += icd_entry(&icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, newgasmix); // ... then print data to buffer. icdtableheader = false; } } } - put_string(&buf, "
\n"); + buf += "
\n"; } lastprintgasmix = newgasmix; gaschange_after = false; @@ -410,37 +404,37 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, lastentered = dp->entered; } while ((dp = nextdp) != NULL); if (!plan_verbatim) - put_string(&buf, "\n
%s%s%s%s%s
%s%s
%s
%s%s%s%s%s%s%s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s  
\n
\n"); + buf += "\n\n
\n"; /* Print the CNS and OTU next.*/ dive->cns = 0; dive->maxcns = 0; update_cylinder_related_info(dive); - put_format_loc(&buf, "
\n%s: %i%%", translate("gettextFromC", "CNS"), dive->cns); - put_format_loc(&buf, "
\n%s: %i
\n
\n", translate("gettextFromC", "OTU"), dive->otu); + buf += casprintf_loc("
\n%s: %i%%", translate("gettextFromC", "CNS"), dive->cns); + buf += casprintf_loc("
\n%s: %i
\n
\n", translate("gettextFromC", "OTU"), dive->otu); /* Print the settings for the diveplan next. */ - put_string(&buf, "
\n"); + buf += "
\n"; if (decoMode(true) == BUEHLMANN) { - put_format_loc(&buf, translate("gettextFromC", "Deco model: Bühlmann ZHL-16C with GFLow = %d%% and GFHigh = %d%%"), diveplan->gflow, diveplan->gfhigh); + buf += casprintf_loc(translate("gettextFromC", "Deco model: Bühlmann ZHL-16C with GFLow = %d%% and GFHigh = %d%%"), diveplan->gflow, diveplan->gfhigh); } else if (decoMode(true) == VPMB) { if (diveplan->vpmb_conservatism == 0) - put_string(&buf, translate("gettextFromC", "Deco model: VPM-B at nominal conservatism")); + buf += translate("gettextFromC", "Deco model: VPM-B at nominal conservatism"); else - put_format_loc(&buf, translate("gettextFromC", "Deco model: VPM-B at +%d conservatism"), diveplan->vpmb_conservatism); + buf += casprintf_loc(translate("gettextFromC", "Deco model: VPM-B at +%d conservatism"), diveplan->vpmb_conservatism); if (diveplan->eff_gflow) - put_format_loc(&buf, translate("gettextFromC", ", effective GF=%d/%d"), diveplan->eff_gflow, diveplan->eff_gfhigh); + buf += casprintf_loc( translate("gettextFromC", ", effective GF=%d/%d"), diveplan->eff_gflow, diveplan->eff_gfhigh); } else if (decoMode(true) == RECREATIONAL) { - put_format_loc(&buf, translate("gettextFromC", "Deco model: Recreational mode based on Bühlmann ZHL-16B with GFLow = %d%% and GFHigh = %d%%"), + buf += casprintf_loc(translate("gettextFromC", "Deco model: Recreational mode based on Bühlmann ZHL-16B with GFLow = %d%% and GFHigh = %d%%"), diveplan->gflow, diveplan->gfhigh); } - put_string(&buf, "
\n"); + buf += "
\n"; { const char *depth_unit; int altitude = (int) get_depth_units((int) (pressure_to_altitude(diveplan->surface_pressure)), NULL, &depth_unit); - put_format_loc(&buf, translate("gettextFromC", "ATM pressure: %dmbar (%d%s)
\n
\n"), diveplan->surface_pressure, altitude, depth_unit); + buf += casprintf_loc(translate("gettextFromC", "ATM pressure: %dmbar (%d%s)
\n
\n"), diveplan->surface_pressure, altitude, depth_unit); } /* Get SAC values and units for printing it in gas consumption */ @@ -456,21 +450,22 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, if (sacdecimals==1) sacdecimals--; /* Print the gas consumption next.*/ + std::string temp; if (dive->dc.divemode == CCR) - temp = strdup(translate("gettextFromC", "Gas consumption (CCR legs excluded):")); + temp = translate("gettextFromC", "Gas consumption (CCR legs excluded):"); else - asprintf_loc(&temp, "%s %.*f|%.*f%s/min):", translate("gettextFromC", "Gas consumption (based on SAC"), + temp = casprintf_loc("%s %.*f|%.*f%s/min):", translate("gettextFromC", "Gas consumption (based on SAC"), sacdecimals, bottomsacvalue, sacdecimals, decosacvalue, sacunit); - put_format(&buf, "
\n%s
\n", temp); - free(temp); + buf += format_string_std("
\n%s
\n", temp.c_str()); } /* Print gas consumption: This loop covers all cylinders */ for (int gasidx = 0; gasidx < dive->cylinders.nr; gasidx++) { double volume, pressure, deco_volume, deco_pressure, mingas_volume, mingas_pressure, mingas_d_pressure, mingas_depth; const char *unit, *pressure_unit, *depth_unit; - char warning[1000] = ""; - char mingas[1000] = ""; + std::string temp; + std::string warning; + std::string mingas; cylinder_t *cyl = get_cylinder(dive, gasidx); if (cyl->cylinder_use == NOT_USED) continue; @@ -487,13 +482,13 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, * This only works if we have working pressure for the cylinder * 10bar is a made up number - but it seemed silly to pretend you could breathe cylinder down to 0 */ if (cyl->end.mbar < 10000) - snprintf(warning, sizeof(warning), "
\n — %s %s", + warning = format_string_std("
\n — %s %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "this is more gas than available in the specified cylinder!")); else if (cyl->end.mbar / 1000.0 * cyl->type.size.mliter / gas_compressibility_factor(cyl->gasmix, cyl->end.mbar / 1000.0) < cyl->deco_gas_used.mliter) - snprintf(warning, sizeof(warning), "
\n — %s %s", + warning = format_string_std("
\n — %s %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "not enough reserve for gas sharing on ascent!")); @@ -517,7 +512,7 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, mingas_depth = get_depth_units(lastbottomdp->depth.mm, NULL, &depth_unit); /* Print it to results */ if (cyl->start.mbar > lastbottomdp->minimum_gas.mbar) { - snprintf_loc(mingas, sizeof(mingas), "
\n — %s (%s %.1fx%s/+%d%s@%.0f%s): " + mingas = casprintf_loc("
\n — %s (%s %.1fx%s/+%d%s@%.0f%s): " "%.0f%s/%.0f%s/Δ:%+.0f%s", mingas_d_pressure > 0 ? "green" :"red", translate("gettextFromC", "Minimum gas"), @@ -532,47 +527,44 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, mingas_d_pressure > 0 ? "grey" :"indianred", mingas_d_pressure, pressure_unit); } else { - snprintf(warning, sizeof(warning), "
\n — %s %s", + warning = format_string_std("
\n — %s %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "required minimum gas for ascent already exceeding start pressure of cylinder!")); } } /* Print the gas consumption for every cylinder here to temp buffer. */ if (lrint(volume) > 0) { - asprintf_loc(&temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s (%.0f%s/%.0f%s in planned ascent)"), + temp = casprintf_loc(translate("gettextFromC", "%.0f%s/%.0f%s of %s (%.0f%s/%.0f%s in planned ascent)"), volume, unit, pressure, pressure_unit, gasname(cyl->gasmix), deco_volume, unit, deco_pressure, pressure_unit); } else { - asprintf_loc(&temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s"), + temp = casprintf_loc(translate("gettextFromC", "%.0f%s/%.0f%s of %s"), volume, unit, pressure, pressure_unit, gasname(cyl->gasmix)); } } else { if (lrint(volume) > 0) { - asprintf_loc(&temp, translate("gettextFromC", "%.0f%s of %s (%.0f%s during planned ascent)"), + temp = casprintf_loc(translate("gettextFromC", "%.0f%s of %s (%.0f%s during planned ascent)"), volume, unit, gasname(cyl->gasmix), deco_volume, unit); } else { - asprintf_loc(&temp, translate("gettextFromC", "%.0f%s of %s"), + temp = casprintf_loc(translate("gettextFromC", "%.0f%s of %s"), volume, unit, gasname(cyl->gasmix)); } } /* Gas consumption: Now finally print all strings to output */ - put_format(&buf, "%s%s%s
\n", temp, warning, mingas); - free(temp); + buf += format_string_std("%s%s%s
\n", temp.c_str(), warning.c_str(), mingas.c_str()); } - put_format(&buf, "
\n"); + buf += "
\n"; /* For trimix OC dives, if an icd table header and icd data were printed to buffer, then add the ICD table here */ if (!icdtableheader && prefs.show_icd) { - put_string(&icdbuf, "\n"); // End the ICD table - mb_cstring(&icdbuf); - put_string(&buf, icdbuf.buffer); // ..and add it to the html buffer + icdbuf += "\n"; // End the ICD table + buf += icdbuf; if (icdwarning) { // If necessary, add warning - put_format(&buf, "%s %s", + buf += format_string_std("%s %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "Isobaric counterdiffusion conditions exceeded")); } - put_string(&buf, "
\n"); + buf += "
\n"; } - free_buffer(&icdbuf); /* Print warnings for pO2 (move into separate function?) */ { @@ -586,6 +578,7 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, if (dive->dc.divemode != CCR) { while (dp) { if (dp->time != 0) { + std::string temp; struct gas_pressures pressures; struct gasmix gasmix = get_cylinder(dive, dp->cylinderid)->gasmix; @@ -598,34 +591,32 @@ extern "C" void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, int decimals; double depth_value = get_depth_units(dp->depth.mm, &decimals, &depth_unit); if (!o2warning_exist) - put_string(&buf, "
\n"); + buf += "
\n"; o2warning_exist = true; - asprintf_loc(&temp, translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), + temp = casprintf_loc(translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); - put_format(&buf, "%s %s
\n", translate("gettextFromC", "Warning:"), temp); - free(temp); + buf += format_string_std("%s %s
\n", translate("gettextFromC", "Warning:"), temp.c_str()); } else if (pressures.o2 < 0.16) { const char *depth_unit; int decimals; double depth_value = get_depth_units(dp->depth.mm, &decimals, &depth_unit); if (!o2warning_exist) - put_string(&buf, "
"); + buf += "
"; o2warning_exist = true; - asprintf_loc(&temp, translate("gettextFromC", "low pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), + temp = casprintf_loc(translate("gettextFromC", "low pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); - put_format(&buf, "%s %s
\n", translate("gettextFromC", "Warning:"), temp); - free(temp); + buf += format_string_std("%s %s
\n", translate("gettextFromC", "Warning:"), temp.c_str()); } } dp = dp->next; } } if (o2warning_exist) - put_string(&buf, "
\n"); + buf += "
\n"; } -finished: + // TODO: avoid copy free(dive->notes); - dive->notes = detach_cstring(&buf); + dive->notes = strdup(buf.c_str()); #ifdef DEBUG_PLANNER_NOTES printf("\n\n\tplannernotes\n\t\n%s\t\n\n", dive->notes); #endif diff --git a/core/qthelper.cpp b/core/qthelper.cpp index 8bde6a53d..1ae9ecfa7 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1025,14 +1025,14 @@ QString get_last_dive_date_string() return dives->nr > 0 ? get_dive_only_date_string(dives->dives[dives->nr - 1]->when) : gettextFromC::tr("no dives"); } -extern "C" char *get_current_date() +std::string get_current_date() { QDateTime ts(QDateTime::currentDateTime());; QString current_date; current_date = loc.toString(ts, QString(prefs.date_format_short)); - return copy_qstring(current_date); + return current_date.toStdString(); } static QMutex hashOfMutex; diff --git a/core/qthelper.h b/core/qthelper.h index c3cb84165..66bbce5c8 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -97,6 +97,7 @@ QString printGPSCoords(const location_t *loc); std::string printGPSCoordsC(const location_t *loc); std::vector get_cylinder_map_for_remove(int count, int n); std::vector get_cylinder_map_for_add(int count, int n); +std::string get_current_date(); extern QString (*changesCallback)(); void uiNotification(const QString &msg); @@ -132,7 +133,6 @@ char *cloud_url(); char *hashfile_name_string(); enum deco_mode decoMode(bool in_planner); void parse_seabear_header(const char *filename, struct xml_params *params); -char *get_current_date(); time_t get_dive_datetime_from_isostring(char *when); void print_qt_versions(); void lock_planner(); diff --git a/desktop-widgets/diveplanner.cpp b/desktop-widgets/diveplanner.cpp index cd0c19a3a..98508d3d9 100644 --- a/desktop-widgets/diveplanner.cpp +++ b/desktop-widgets/diveplanner.cpp @@ -609,13 +609,12 @@ void PlannerWidgets::replanDive(int currentDC) void PlannerWidgets::printDecoPlan() { #ifndef NO_PRINTING - char *disclaimer = get_planner_disclaimer_formatted(); + std::string disclaimer = get_planner_disclaimer_formatted(); // Prepend a logo and a disclaimer to the plan. // Save the old plan so that it can be restored at the end of the function. QString origPlan = plannerDetails.divePlanOutput()->toHtml(); QString diveplan = QStringLiteral(" ") + - QString(disclaimer) + origPlan; - free(disclaimer); + QString::fromStdString(disclaimer) + origPlan; QPrinter printer; QPrintDialog dialog(&printer, MainWindow::instance());