Can you show the heartrate in Subsurface?
Linus Torvalds
torvalds at linux-foundation.org
Fri Jan 17 14:24:45 UTC 2014
On Fri, Jan 17, 2014 at 1:50 PM, Linus Torvalds
<torvalds at linux-foundation.org> wrote:
>
> Ok. So here's a slightly updated patch that replaces the previous
> patch, fixing an extraneous space in the XML output, and also adding
> the heartbeat and bearing information to the profile "info" box, so
> now you can actually see it in subsurface too.
On top of that patch, here's a second patch that makes the dive info
text generation use the new "struct membuffer", which has the ability
to sanely append a formatted string to an existing string. The old
code used a nasty pattern of
memcpy(buf2, buf, bufsize);
snprintf(buf, bufsize, "%s\nnew-format-string", buf2, ...);
which is just disgusting. The new model just does
put_format(b, "new-format-string\n", ...);
instead, which does that nice "append formatted string" thing in a
imho much more readable manner.
Linus
-------------- next part --------------
profile.c | 118 +++++++++++++++++++++++++-------------------------------------
1 file changed, 48 insertions(+), 70 deletions(-)
diff --git a/profile.c b/profile.c
index 59ff2dade715..2a62dcbeb6f5 100644
--- a/profile.c
+++ b/profile.c
@@ -13,6 +13,7 @@
#include "deco.h"
#include "libdivecomputer/parser.h"
#include "libdivecomputer/version.h"
+#include "membuffer.h"
int selected_dive = -1; /* careful: 0 is a valid value */
char zoomed_plot = 0;
@@ -1330,97 +1331,75 @@ struct divecomputer *select_dc(struct divecomputer *main)
return main;
}
-static void plot_string(struct plot_data *entry, char *buf, int bufsize,
- bool has_ndl)
+static void plot_string(struct plot_data *entry, struct membuffer *b, bool has_ndl)
{
int pressurevalue, mod, ead, end, eadd;
const char *depth_unit, *pressure_unit, *temp_unit, *vertical_speed_unit;
- char *buf2 = malloc(bufsize);
double depthvalue, tempvalue, speedvalue;
depthvalue = get_depth_units(entry->depth, NULL, &depth_unit);
- snprintf(buf, bufsize, translate("gettextFromC","@:%d:%02d\nD:%.1f %s"), FRACTION(entry->sec, 60), depthvalue, depth_unit);
+ put_format(b, translate("gettextFromC","@:%d:%02d\nD:%.1f %s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit);
if (GET_PRESSURE(entry)) {
pressurevalue = get_pressure_units(GET_PRESSURE(entry), &pressure_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nP:%d %s"), buf2, pressurevalue, pressure_unit);
+ put_format(b, translate("gettextFromC","P:%d %s\n"), pressurevalue, pressure_unit);
}
if (entry->temperature) {
tempvalue = get_temp_units(entry->temperature, &temp_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nT:%.1f %s"), buf2, tempvalue, temp_unit);
+ put_format(b, translate("gettextFromC","T:%.1f %s\n"), tempvalue, temp_unit);
}
speedvalue = get_vertical_speed_units(abs(entry->speed), NULL, &vertical_speed_unit);
- memcpy(buf2, buf, bufsize);
/* Ascending speeds are positive, descending are negative */
if (entry->speed > 0)
speedvalue *= -1;
- snprintf(buf, bufsize, translate("gettextFromC","%s\nV:%.2f %s"), buf2, speedvalue, vertical_speed_unit);
-
- if (entry->sac && prefs.show_sac) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nSAC:%2.1fl/min"), buf2, entry->sac / 1000.0);
- }
- if (entry->cns) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nCNS:%u%%"), buf2, entry->cns);
- }
- if (prefs.pp_graphs.po2) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\npO%s:%.2fbar"), buf2, UTF8_SUBSCRIPT_2, entry->po2);
- }
- if (prefs.pp_graphs.pn2) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\npN%s:%.2fbar"), buf2, UTF8_SUBSCRIPT_2, entry->pn2);
- }
- if (prefs.pp_graphs.phe) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\npHe:%.2fbar"), buf2, entry->phe);
- }
+ put_format(b, translate("gettextFromC","V:%.2f %s\n"), speedvalue, vertical_speed_unit);
+
+ if (entry->sac && prefs.show_sac)
+ put_format(b, translate("gettextFromC","SAC:%2.1fl/min\n"), entry->sac / 1000.0);
+ if (entry->cns)
+ put_format(b, translate("gettextFromC","CNS:%u%%\n"), entry->cns);
+ if (prefs.pp_graphs.po2)
+ put_format(b, translate("gettextFromC","pO%s:%.2fbar\n"), UTF8_SUBSCRIPT_2, entry->po2);
+ if (prefs.pp_graphs.pn2)
+ put_format(b, translate("gettextFromC","pN%s:%.2fbar\n"), UTF8_SUBSCRIPT_2, entry->pn2);
+ if (prefs.pp_graphs.phe)
+ put_format(b, translate("gettextFromC","pHe:%.2fbar\n"), entry->phe);
if (prefs.mod) {
mod = (int)get_depth_units(entry->mod, NULL, &depth_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nMOD:%d%s"), buf2, mod, depth_unit);
+ put_format(b, translate("gettextFromC","MOD:%d%s\n"), mod, depth_unit);
}
if (prefs.ead) {
ead = (int)get_depth_units(entry->ead, NULL, &depth_unit);
end = (int)get_depth_units(entry->end, NULL, &depth_unit);
eadd = (int)get_depth_units(entry->eadd, NULL, &depth_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nEAD:%d%s\nEND:%d%s\nEADD:%d%s"), buf2, ead, depth_unit, end, depth_unit, eadd, depth_unit);
+ put_format(b, translate("gettextFromC","EAD:%d%s\nEND:%d%s\nEADD:%d%s\n"), ead, depth_unit, end, depth_unit, eadd, depth_unit);
}
if (entry->stopdepth) {
depthvalue = get_depth_units(entry->stopdepth, NULL, &depth_unit);
- memcpy(buf2, buf, bufsize);
if (entry->ndl) {
/* this is a safety stop as we still have ndl */
if (entry->stoptime)
- snprintf(buf, bufsize, translate("gettextFromC","%s\nSafetystop:%umin @ %.0f %s"), buf2, DIV_UP(entry->stoptime, 60),
+ put_format(b, translate("gettextFromC","Safetystop:%umin @ %.0f %s\n"), DIV_UP(entry->stoptime, 60),
depthvalue, depth_unit);
else
- snprintf(buf, bufsize, translate("gettextFromC","%s\nSafetystop:unkn time @ %.0f %s"), buf2,
+ put_format(b, translate("gettextFromC","Safetystop:unkn time @ %.0f %s\n"),
depthvalue, depth_unit);
} else {
/* actual deco stop */
if (entry->stoptime)
- snprintf(buf, bufsize, translate("gettextFromC","%s\nDeco:%umin @ %.0f %s"), buf2, DIV_UP(entry->stoptime, 60),
+ put_format(b, translate("gettextFromC","Deco:%umin @ %.0f %s\n"), DIV_UP(entry->stoptime, 60),
depthvalue, depth_unit);
else
- snprintf(buf, bufsize, translate("gettextFromC","%s\nDeco:unkn time @ %.0f %s"), buf2,
+ put_format(b, translate("gettextFromC","Deco:unkn time @ %.0f %s\n"),
depthvalue, depth_unit);
}
} else if (entry->in_deco) {
- /* this means we had in_deco set but don't have a stop depth */
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nIn deco"), buf2);
+ put_format(b, translate("gettextFromC","In deco\n"));
} else if (has_ndl) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nNDL:%umin"), buf2, DIV_UP(entry->ndl, 60));
+ put_format(b, translate("gettextFromC","NDL:%umin\n"), DIV_UP(entry->ndl, 60));
}
if (entry->stopdepth_calc && entry->stoptime_calc) {
depthvalue = get_depth_units(entry->stopdepth_calc, NULL, &depth_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nDeco:%umin @ %.0f %s (calc)"), buf2, DIV_UP(entry->stoptime_calc, 60),
+ put_format(b, translate("gettextFromC","Deco:%umin @ %.0f %s (calc)\n"), DIV_UP(entry->stoptime_calc, 60),
depthvalue, depth_unit);
} else if (entry->in_deco_calc) {
/* This means that we have no NDL left,
@@ -1428,40 +1407,29 @@ static void plot_string(struct plot_data *entry, char *buf, int bufsize,
* so if we just accend to the surface slowly
* (ascent_mm_per_step / ascent_s_per_step)
* everything will be ok. */
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nIn deco (calc)"), buf2);
+ put_format(b, translate("gettextFromC","In deco (calc)\n"));
} else if (prefs.calc_ndl_tts && entry->ndl_calc != 0) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nNDL:%umin (calc)"), buf2, DIV_UP(entry->ndl_calc, 60));
- }
- if (entry->tts_calc) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nTTS:%umin (calc)"), buf2, DIV_UP(entry->tts_calc, 60));
+ put_format(b, translate("gettextFromC","NDL:%umin (calc)\n"), DIV_UP(entry->ndl_calc, 60));
}
+ if (entry->tts_calc)
+ put_format(b, translate("gettextFromC","TTS:%umin (calc)\n"), DIV_UP(entry->tts_calc, 60));
if (entry->ceiling) {
depthvalue = get_depth_units(entry->ceiling, NULL, &depth_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nCalculated ceiling %.0f %s"), buf2, depthvalue, depth_unit);
+ put_format(b, translate("gettextFromC","Calculated ceiling %.0f %s\n"), depthvalue, depth_unit);
if (prefs.calc_all_tissues) {
int k;
for (k=0; k<16; k++) {
if (entry->ceilings[k]) {
depthvalue = get_depth_units(entry->ceilings[k], NULL, &depth_unit);
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nTissue %.0fmin: %.0f %s"), buf2, buehlmann_N2_t_halflife[k], depthvalue, depth_unit);
+ put_format(b, translate("gettextFromC","Tissue %.0fmin: %.0f %s\n"), buehlmann_N2_t_halflife[k], depthvalue, depth_unit);
}
}
}
}
- if (entry->heartbeat) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nheartbeat:%d"), buf2, entry->heartbeat);
- }
- if (entry->bearing) {
- memcpy(buf2, buf, bufsize);
- snprintf(buf, bufsize, translate("gettextFromC","%s\nbearing:%d"), buf2, entry->bearing);
- }
- free(buf2);
+ if (entry->heartbeat)
+ put_format(b, translate("gettextFromC","heartbeat:%d\n"), entry->heartbeat);
+ if (entry->bearing)
+ put_format(b, translate("gettextFromC","bearing:%d\n"), entry->bearing);
}
void get_plot_details(struct graphics_context *gc, int time, char *buf, int bufsize)
@@ -1475,8 +1443,18 @@ void get_plot_details(struct graphics_context *gc, int time, char *buf, int bufs
if (entry->sec >= time)
break;
}
- if (entry)
- plot_string(entry, buf, bufsize, pi->has_ndl);
+ if (entry) {
+ struct membuffer mb = {0};
+ plot_string(entry, &mb, pi->has_ndl);
+ bufsize--;
+ if (mb.used < bufsize)
+ bufsize = mb.used;
+ memcpy(buf, mb.buffer, bufsize);
+ buf[bufsize] = 0;
+ while (bufsize > 0 && buf[bufsize-1] == '\n')
+ buf[--bufsize] = 0;
+ free_buffer(&mb);
+ }
}
/* Compare two plot_data entries and writes the results into a string */
More information about the subsurface
mailing list