From: Linus Torvalds <torva...@linux-foundation.org>
Date: Tue, 25 Jul 2017 19:10:03 -0700
Subject: [PATCH 2/2] Add support for loading and saving multiple pressure 
samples

This does both the XML and the git save format, because the changes
really are the same, even if the actual format differs in some details. 
See how the two "save_samples()" routines both do the same basic setup, 
for example.

This is fairly straightforward, with the possible exception of the odd

     sensor = sample->sensor[0];

default in the git pressure loading code.

That line just means that if we do *not* have an explicit cylinder index 
for the pressure reading, we will always end up filling in the new 
pressure as the first pressure (because the cylinder index will match the 
first sensor slot).

So that makes the "add_sample_pressure()" case always do the same thing it 
used to do for the legacy case: fill in the first slot. The actual sensor 
index may later change, since the legacy format has a "sensor=X" key value 
pair that sets the sensor, but it will also use the first sensor slot, 
making it all do exactly what it used to do.

And on the other hand, if we're loading new-style data with cylinder 
pressure and sensor index together, we just end up using the new semantics 
for add_sample_pressure(), which tries to keep the same slot for the same 
sensor, but does the right thing if we already have other pressure values.

The XML code has no such issues at all, since it can't share the cases 
anyway, and we need to have different node names for the different sensor 
values and cannot just have multiple "pressure" entries. Have I mentioned 
how much I despise XML lately?

Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
---

 core/load-git.c  |  7 ++++++-
 core/parse-xml.c | 22 +++++++++++++++++++++
 core/save-git.c  | 60 +++++++++++++++++++++++++++++++++++++++-----------------
 core/save-xml.c  | 45 ++++++++++++++++++++++++++++++------------
 4 files changed, 103 insertions(+), 31 deletions(-)

diff --git a/core/load-git.c b/core/load-git.c
index 6a3cc75c..e7732a69 100644
--- a/core/load-git.c
+++ b/core/load-git.c
@@ -560,6 +560,7 @@ static void parse_sample_keyvalue(void *_sample, const char 
*key, const char *va
 
 static char *parse_sample_unit(struct sample *sample, double val, char *unit)
 {
+       unsigned int sensor;
        char *end = unit, c;
 
        /* Skip over the unit */
@@ -572,12 +573,16 @@ static char *parse_sample_unit(struct sample *sample, 
double val, char *unit)
        }
 
        /* The units are "°C", "m" or "bar", so let's just look at the first 
character */
+       /* The cylinder pressure may also be of the form '123.0bar:4' to 
indicate sensor */
        switch (*unit) {
        case 'm':
                sample->depth.mm = lrint(1000*val);
                break;
        case 'b':
-               sample->pressure[0].mbar = lrint(1000*val);
+               sensor = sample->sensor[0];
+               if (end > unit+4 && unit[3] == ':')
+                       sensor = atoi(unit+4);
+               add_sample_pressure(sample, sensor, lrint(1000*val));
                break;
        default:
                sample->temperature.mkelvin = C_to_mkelvin(val);
diff --git a/core/parse-xml.c b/core/parse-xml.c
index e261d127..ef6f0bdf 100644
--- a/core/parse-xml.c
+++ b/core/parse-xml.c
@@ -928,6 +928,7 @@ static void try_to_fill_dc(struct divecomputer *dc, const 
char *name, char *buf)
 static void try_to_fill_sample(struct sample *sample, const char *name, char 
*buf)
 {
        int in_deco;
+       pressure_t p;
 
        start_match("sample", name, buf);
        if (MATCH("pressure.sample", pressure, &sample->pressure[0]))
@@ -938,6 +939,27 @@ static void try_to_fill_sample(struct sample *sample, 
const char *name, char *bu
                return;
        if (MATCH("o2pressure.sample", pressure, &sample->pressure[1]))
                return;
+       /* Christ, this is ugly */
+       if (MATCH("pressure0.sample", pressure, &p)) {
+               add_sample_pressure(sample, 0, p.mbar);
+               return;
+       }
+       if (MATCH("pressure1.sample", pressure, &p)) {
+               add_sample_pressure(sample, 1, p.mbar);
+               return;
+       }
+       if (MATCH("pressure2.sample", pressure, &p)) {
+               add_sample_pressure(sample, 2, p.mbar);
+               return;
+       }
+       if (MATCH("pressure3.sample", pressure, &p)) {
+               add_sample_pressure(sample, 3, p.mbar);
+               return;
+       }
+       if (MATCH("pressure4.sample", pressure, &p)) {
+               add_sample_pressure(sample, 4, p.mbar);
+               return;
+       }
        if (MATCH("cylinderindex.sample", get_cylinderindex, 
&sample->sensor[0]))
                return;
        if (MATCH("sensor.sample", get_sensor, &sample->sensor[0]))
diff --git a/core/save-git.c b/core/save-git.c
index b734f59f..1fe2642f 100644
--- a/core/save-git.c
+++ b/core/save-git.c
@@ -241,21 +241,45 @@ static void show_index(struct membuffer *b, int value, 
const char *pre, const ch
  *
  * For parsing, look at the units to figure out what the numbers are.
  */
-static void save_sample(struct membuffer *b, struct sample *sample, struct 
sample *old)
+static void save_sample(struct membuffer *b, struct sample *sample, struct 
sample *old, int o2sensor)
 {
+       int idx;
+
        put_format(b, "%3u:%02u", FRACTION(sample->time.seconds, 60));
        put_milli(b, " ", sample->depth.mm, "m");
        put_temperature(b, sample->temperature, " ", "°C");
-       put_pressure(b, sample->pressure[0], " ", "bar");
-       put_pressure(b, sample->pressure[1]," o2pressure=","bar");
 
-       /*
-        * We only show sensor information for samples with pressure, and only 
if it
-        * changed from the previous sensor we showed.
-        */
-       if (sample->pressure[0].mbar && sample->sensor[0] != old->sensor[0]) {
-               put_format(b, " sensor=%d", sample->sensor[0]);
-               old->sensor[0] = sample->sensor[0];
+       for (idx = 0; idx < MAX_SENSORS; idx++) {
+               pressure_t p = sample->pressure[idx];
+               int sensor = sample->sensor[idx];
+
+               if (!p.mbar)
+                       continue;
+
+               /* Old-style "o2sensor" syntax for CCR dives? */
+               if (o2sensor >= 0) {
+                       if (sensor == o2sensor) {
+                               put_pressure(b, sample->pressure[1]," 
o2pressure=","bar");
+                               continue;
+                       }
+
+                       put_pressure(b, p, " ", "bar");
+
+                       /*
+                        * Note: regardless of which index we used for the 
non-O2
+                        * sensor, we know there is only one non-O2 sensor in 
legacy
+                        * mode, and "old->sensor[0]" contains that index.
+                        */
+                       if (sensor != old->sensor[0]) {
+                               put_format(b, " sensor=%d", sensor);
+                               old->sensor[0] = sensor;
+                       }
+                       continue;
+               }
+
+               /* The new-style format is much simpler: the sensor is always 
encoded */
+               put_pressure(b, p, " ", "bar");
+               put_format(b, ":%d", sensor);
        }
 
        /* the deco/ndl values are stored whenever they change */
@@ -324,21 +348,21 @@ static void save_sample(struct membuffer *b, struct 
sample *sample, struct sampl
 static void save_samples(struct membuffer *b, struct dive *dive, struct 
divecomputer *dc)
 {
        int nr;
-       int o2sensor;
+       int o2sensor, legacy;
        struct sample *s;
        struct sample dummy = {};
 
-       /* Set up default pressure sensor indexes */
-       o2sensor = get_cylinder_idx_by_use(dive, OXYGEN);
-       if (o2sensor < 0)
-               o2sensor = 1;
-       dummy.sensor[0] = !o2sensor;
-       dummy.sensor[1] = o2sensor;
+       /* Is this a CCR dive with the old-style "o2pressure" sensor? */
+       o2sensor = legacy_format_o2pressures(dive, dc);
+       if (o2sensor >= 0) {
+               dummy.sensor[0] = !o2sensor;
+               dummy.sensor[1] = o2sensor;
+       }
 
        s = dc->sample;
        nr = dc->samples;
        while (--nr >= 0) {
-               save_sample(b, s, &dummy);
+               save_sample(b, s, &dummy, o2sensor);
                s++;
        }
 }
diff --git a/core/save-xml.c b/core/save-xml.c
index 73a00f54..19b4e79b 100644
--- a/core/save-xml.c
+++ b/core/save-xml.c
@@ -192,24 +192,45 @@ static void show_index(struct membuffer *b, int value, 
const char *pre, const ch
                show_integer(b, value, pre, post);
 }
 
-static void save_sample(struct membuffer *b, struct sample *sample, struct 
sample *old)
+static void save_sample(struct membuffer *b, struct sample *sample, struct 
sample *old, int o2sensor)
 {
+       int idx;
+
        put_format(b, "  <sample time='%u:%02u min'", 
FRACTION(sample->time.seconds, 60));
        put_milli(b, " depth='", sample->depth.mm, " m'");
        if (sample->temperature.mkelvin && sample->temperature.mkelvin != 
old->temperature.mkelvin) {
                put_temperature(b, sample->temperature, " temp='", " C'");
                old->temperature = sample->temperature;
        }
-       put_pressure(b, sample->pressure[0], " pressure='", " bar'");
-       put_pressure(b, sample->pressure[1], " o2pressure='", " bar'");
 
        /*
         * We only show sensor information for samples with pressure, and only 
if it
         * changed from the previous sensor we showed.
         */
-       if (sample->pressure[0].mbar && sample->sensor[0] != old->sensor[0]) {
-               put_format(b, " sensor='%d'", sample->sensor[0]);
-               old->sensor[0] = sample->sensor[0];
+       for (idx = 0; idx < MAX_SENSORS; idx++) {
+               pressure_t p = sample->pressure[idx];
+               int sensor = sample->sensor[idx];
+
+               if (!p.mbar)
+                       continue;
+
+               /* Legacy o2pressure format? */
+               if (o2sensor >= 0) {
+                       if (sensor == o2sensor) {
+                               put_pressure(b, p, " o2pressure='", " bar'");
+                               continue;
+                       }
+                       put_pressure(b, sample->pressure[0], " pressure='", " 
bar'");
+                       if (sensor != old->sensor[0]) {
+                               put_format(b, " sensor='%d'", sensor);
+                               old->sensor[0] = sensor;
+                       }
+                       continue;
+               }
+
+               /* The new-style format is much simpler: the sensor is always 
encoded */
+               put_format(b, " pressure%d=", sensor);
+               put_pressure(b, p, "'", " bar'");
        }
 
        /* the deco/ndl values are stored whenever they change */
@@ -339,16 +360,16 @@ static void save_samples(struct membuffer *b, struct dive 
*dive, struct divecomp
        struct sample dummy = {};
 
        /* Set up default pressure sensor indexes */
-       o2sensor = get_cylinder_idx_by_use(dive, OXYGEN);
-       if (o2sensor < 0)
-               o2sensor = 1;
-       dummy.sensor[0] = !o2sensor;
-       dummy.sensor[1] = o2sensor;
+       o2sensor = legacy_format_o2pressures(dive, dc);
+       if (o2sensor >= 0) {
+               dummy.sensor[0] = !o2sensor;
+               dummy.sensor[1] = o2sensor;
+       }
 
        s = dc->sample;
        nr = dc->samples;
        while (--nr >= 0) {
-               save_sample(b, s, &dummy);
+               save_sample(b, s, &dummy, o2sensor);
                s++;
        }
 }
-- 
2.13.1.518.g0d864c4df

_______________________________________________
subsurface mailing list
subsurface@subsurface-divelog.org
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to