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