diff --git a/examples/dctool_download.c b/examples/dctool_download.c index 4baa333..2c8f43d 100644 --- a/examples/dctool_download.c +++ b/examples/dctool_download.c @@ -246,6 +246,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto dc_status_t status = DC_STATUS_SUCCESS; dc_buffer_t *fingerprint = NULL; dctool_output_t *output = NULL; + dctool_units_t units = DCTOOL_UNITS_METRIC; // Default option values. unsigned int help = 0; @@ -256,7 +257,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto // Parse the command-line options. int opt = 0; - const char *optstring = "ho:p:c:f:"; + const char *optstring = "ho:p:c:f:u:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, @@ -264,6 +265,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto {"fingerprint", required_argument, 0, 'p'}, {"cache", required_argument, 0, 'c'}, {"format", required_argument, 0, 'f'}, + {"units", required_argument, 0, 'u'}, {0, 0, 0, 0 } }; while ((opt = getopt_long (argc, argv, optstring, options, NULL)) != -1) { @@ -286,6 +288,12 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto case 'f': format = optarg; break; + case 'u': + if (strcmp (optarg, "metric") == 0) + units = DCTOOL_UNITS_METRIC; + if (strcmp (optarg, "imperial") == 0) + units = DCTOOL_UNITS_IMPERIAL; + break; default: return EXIT_FAILURE; } @@ -307,7 +315,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto if (strcasecmp(format, "raw") == 0) { output = dctool_raw_output_new (filename); } else if (strcasecmp(format, "xml") == 0) { - output = dctool_xml_output_new (filename); + output = dctool_xml_output_new (filename, units); } else { message ("Unknown output format: %s\n", format); exitcode = EXIT_FAILURE; @@ -348,12 +356,14 @@ const dctool_command_t dctool_download = { " -p, --fingerprint Fingerprint data (hexadecimal)\n" " -c, --cache Cache directory\n" " -f, --format Output format\n" + " -u, --units Set units (metric or imperial)\n" #else " -h Show help message\n" " -o Output filename\n" " -p Fingerprint data (hexadecimal)\n" " -c Cache directory\n" " -f Output format\n" + " -u Set units (metric or imperial)\n" #endif "\n" "Supported output formats:\n" diff --git a/examples/dctool_parse.c b/examples/dctool_parse.c index ef05aa4..5057566 100644 --- a/examples/dctool_parse.c +++ b/examples/dctool_parse.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_GETOPT_H #include #endif @@ -196,6 +197,7 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t dc_status_t status = DC_STATUS_SUCCESS; dc_buffer_t *buffer = NULL; dctool_output_t *output = NULL; + dctool_units_t units = DCTOOL_UNITS_METRIC; // Default option values. unsigned int help = 0; @@ -205,13 +207,14 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t // Parse the command-line options. int opt = 0; - const char *optstring = "ho:d:s:"; + const char *optstring = "ho:d:s:u:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, {"output", required_argument, 0, 'o'}, {"devtime", required_argument, 0, 'd'}, {"systime", required_argument, 0, 's'}, + {"units", required_argument, 0, 'u'}, {0, 0, 0, 0 } }; while ((opt = getopt_long (argc, argv, optstring, options, NULL)) != -1) { @@ -231,6 +234,12 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t case 's': systime = strtoll (optarg, NULL, 0); break; + case 'u': + if (strcmp (optarg, "metric") == 0) + units = DCTOOL_UNITS_METRIC; + if (strcmp (optarg, "imperial") == 0) + units = DCTOOL_UNITS_IMPERIAL; + break; default: return EXIT_FAILURE; } @@ -246,7 +255,7 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t } // Create the output. - output = dctool_xml_output_new (filename); + output = dctool_xml_output_new (filename, units); if (output == NULL) { message ("Failed to create the output.\n"); exitcode = EXIT_FAILURE; @@ -295,10 +304,12 @@ const dctool_command_t dctool_parse = { " -o, --output Output filename\n" " -d, --devtime Device time\n" " -s, --systime System time\n" + " -u, --units Set units (metric or imperial)\n" #else " -h Show help message\n" " -o Output filename\n" " -d Device time\n" " -s System time\n" + " -u Set units (metric or imperial)\n" #endif }; diff --git a/examples/output.h b/examples/output.h index 0912de2..b22a8f2 100644 --- a/examples/output.h +++ b/examples/output.h @@ -31,8 +31,13 @@ extern "C" { typedef struct dctool_output_t dctool_output_t; +typedef enum dctool_units_t { + DCTOOL_UNITS_METRIC, + DCTOOL_UNITS_IMPERIAL +} dctool_units_t; + dctool_output_t * -dctool_xml_output_new (const char *filename); +dctool_xml_output_new (const char *filename, dctool_units_t units); dctool_output_t * dctool_raw_output_new (const char *template); diff --git a/examples/output_xml.c b/examples/output_xml.c index e4e9b51..2baa329 100644 --- a/examples/output_xml.c +++ b/examples/output_xml.c @@ -23,6 +23,8 @@ #include #include +#include + #include "output-private.h" #include "utils.h" @@ -32,6 +34,7 @@ static dc_status_t dctool_xml_output_free (dctool_output_t *output); typedef struct dctool_xml_output_t { dctool_output_t base; FILE *ostream; + dctool_units_t units; } dctool_xml_output_t; static const dctool_output_vtable_t xml_vtable = { @@ -42,9 +45,50 @@ static const dctool_output_vtable_t xml_vtable = { typedef struct sample_data_t { FILE *ostream; + dctool_units_t units; unsigned int nsamples; } sample_data_t; +static double +convert_depth (double value, dctool_units_t units) +{ + if (units == DCTOOL_UNITS_IMPERIAL) { + return value / FEET; + } else { + return value; + } +} + +static double +convert_temperature (double value, dctool_units_t units) +{ + if (units == DCTOOL_UNITS_IMPERIAL) { + return value * (9.0 / 5.0) + 32.0; + } else { + return value; + } +} + +static double +convert_pressure (double value, dctool_units_t units) +{ + if (units == DCTOOL_UNITS_IMPERIAL) { + return value * BAR / PSI; + } else { + return value; + } +} + +static double +convert_volume (double value, dctool_units_t units) +{ + if (units == DCTOOL_UNITS_IMPERIAL) { + return value / 1000.0 / CUFT; + } else { + return value; + } +} + static void sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) { @@ -68,13 +112,17 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) fprintf (sampledata->ostream, " \n", value.time / 60, value.time % 60); break; case DC_SAMPLE_DEPTH: - fprintf (sampledata->ostream, " %.2f\n", value.depth); + fprintf (sampledata->ostream, " %.2f\n", + convert_depth(value.depth, sampledata->units)); break; case DC_SAMPLE_PRESSURE: - fprintf (sampledata->ostream, " %.2f\n", value.pressure.tank, value.pressure.value); + fprintf (sampledata->ostream, " %.2f\n", + value.pressure.tank, + convert_pressure(value.pressure.value, sampledata->units)); break; case DC_SAMPLE_TEMPERATURE: - fprintf (sampledata->ostream, " %.2f\n", value.temperature); + fprintf (sampledata->ostream, " %.2f\n", + convert_temperature(value.temperature, sampledata->units)); break; case DC_SAMPLE_EVENT: if (value.event.type != SAMPLE_EVENT_GASCHANGE && value.event.type != SAMPLE_EVENT_GASCHANGE2) { @@ -108,7 +156,9 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) break; case DC_SAMPLE_DECO: fprintf (sampledata->ostream, " %s\n", - value.deco.time, value.deco.depth, decostop[value.deco.type]); + value.deco.time, + convert_depth(value.deco.depth, sampledata->units), + decostop[value.deco.type]); break; case DC_SAMPLE_GASMIX: fprintf (sampledata->ostream, " %u\n", value.gasmix); @@ -119,7 +169,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) } dctool_output_t * -dctool_xml_output_new (const char *filename) +dctool_xml_output_new (const char *filename, dctool_units_t units) { dctool_xml_output_t *output = NULL; @@ -138,6 +188,8 @@ dctool_xml_output_new (const char *filename) goto error_free; } + output->units = units; + fprintf (output->ostream, "\n"); return (dctool_output_t *) output; @@ -158,6 +210,7 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u sample_data_t sampledata = {0}; sampledata.nsamples = 0; sampledata.ostream = output->ostream; + sampledata.units = output->units; fprintf (output->ostream, "\n%u\n%u\n", abstract->number, size); @@ -203,7 +256,7 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u } fprintf (output->ostream, "%.2f\n", - maxdepth); + convert_depth(maxdepth, output->units)); // Parse the temperature. message ("Parsing the temperature.\n"); @@ -222,7 +275,8 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u if (status != DC_STATUS_UNSUPPORTED) { fprintf (output->ostream, "%.1f\n", - names[i], temperature); + names[i], + convert_temperature(temperature, output->units)); } } @@ -284,13 +338,16 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u " %s\n" " %.1f\n" " %.2f\n", - names[tank.type], tank.volume, tank.workpressure); + names[tank.type], + convert_volume(tank.volume, output->units), + convert_pressure(tank.workpressure, output->units)); } fprintf (output->ostream, " %.2f\n" " %.2f\n" "\n", - tank.beginpressure, tank.endpressure); + convert_pressure(tank.beginpressure, output->units), + convert_pressure(tank.endpressure, output->units)); } // Parse the dive mode. @@ -333,7 +390,7 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u if (status != DC_STATUS_UNSUPPORTED) { fprintf (output->ostream, "%.5f\n", - atmospheric); + convert_pressure(atmospheric, output->units)); } // Parse the sample data.