From 05857e0a05bc15672ddd5e835714d2cd20405b97 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 6 Sep 2011 19:07:17 -0700 Subject: [PATCH] Start "output unit management" support This doesn't actually *do* anything yet, but it introduces the notion of output units, and allows you to pick metric or imperial. Of course, since the output doesn't currently care, the units you pick are irrelevant. But just wait.. Signed-off-by: Linus Torvalds --- dive.h | 16 ++++++++++++ main.c | 18 ++++++++++++++ parse-xml.c | 70 ++++++++++++++++++++++++++--------------------------- 3 files changed, 68 insertions(+), 36 deletions(-) diff --git a/dive.h b/dive.h index 82b336e..ea8fcee 100644 --- a/dive.h +++ b/dive.h @@ -126,6 +126,22 @@ struct dive { struct sample sample[]; }; +/* + * We keep our internal data in well-specified units, but + * the input and output may come in some random format. This + * keeps track of those units. + */ +struct units { + enum { METERS, FEET } length; + enum { LITER, CUFT } volume; + enum { BAR, PSI, PASCAL } pressure; + enum { CELSIUS, FAHRENHEIT, KELVIN } temperature; + enum { KG, LBS } weight; +}; + +extern const struct units SI_units, IMPERIAL_units; +extern struct units input_units, output_units; + extern int verbose; struct dive_table { diff --git a/main.c b/main.c index 14c4f26..9ef4fa0 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,8 @@ GtkWidget *error_label; int error_count; struct DiveList dive_list; +struct units output_units; + static int sortfn(const void *_a, const void *_b) { const struct dive *a = *(void **)_a; @@ -200,11 +202,23 @@ static void quit(GtkWidget *w, gpointer data) gtk_main_quit(); } +static void imperial(GtkWidget *w, gpointer data) +{ + output_units = IMPERIAL_units; +} + +static void metric(GtkWidget *w, gpointer data) +{ + output_units = SI_units; +} + static GtkActionEntry menu_items[] = { { "FileMenuAction", GTK_STOCK_FILE, "Log", NULL, NULL, NULL}, { "OpenFile", GTK_STOCK_OPEN, NULL, "O", NULL, G_CALLBACK(file_open) }, { "SaveFile", GTK_STOCK_SAVE, NULL, "S", NULL, G_CALLBACK(file_save) }, { "Quit", GTK_STOCK_QUIT, NULL, "Q", NULL, G_CALLBACK(quit) }, + { "Metric", NULL, "Metric", NULL, NULL, G_CALLBACK(metric) }, + { "Imperial", NULL, "Imperial", NULL, NULL, G_CALLBACK(imperial) }, }; static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]); @@ -215,6 +229,9 @@ static const gchar* ui_string = " \ \ \ \ + \ + \ + \ \ \ \ @@ -249,6 +266,7 @@ int main(int argc, char **argv) GtkWidget *menubar; GtkWidget *vbox; + output_units = SI_units; parse_xml_init(); gtk_init(&argc, &argv); diff --git a/parse-xml.c b/parse-xml.c index 50f85fb..92da468 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -62,18 +62,8 @@ static int match(const char *pattern, int plen, return 1; } -/* - * We keep our internal data in well-specified units, but - * the input may come in some random format. This keeps track - * of the incoming units. - */ -static struct units { - enum { METERS, FEET } length; - enum { LITER, CUFT } volume; - enum { BAR, PSI, PASCAL } pressure; - enum { CELSIUS, FAHRENHEIT, KELVIN } temperature; - enum { KG, LBS } weight; -} units; + +struct units input_units; /* * We're going to default to SI units for input. Yes, @@ -81,7 +71,7 @@ static struct units { * we default to bar (10^5 pascal), which people * actually use. Similarly, C instead of Kelvin. */ -static const struct units SI_units = { +const struct units SI_units = { .length = METERS, .volume = LITER, .pressure = BAR, @@ -89,6 +79,14 @@ static const struct units SI_units = { .weight = KG }; +const struct units IMPERIAL_units = { + .length = FEET, + .volume = CUFT, + .pressure = PSI, + .temperature = FAHRENHEIT, + .weight = LBS +}; + /* * Dive info as it is being built up.. */ @@ -243,7 +241,7 @@ static void pressure(char *buffer, void *_press) /* Just ignore zero values */ if (!val.fp) break; - switch (units.pressure) { + switch (input_units.pressure) { case PASCAL: mbar = val.fp / 100; break; @@ -275,7 +273,7 @@ static void depth(char *buffer, void *_depth) switch (integer_or_float(buffer, &val)) { case FLOAT: - switch (units.length) { + switch (input_units.length) { case METERS: depth->mm = val.fp * 1000 + 0.5; break; @@ -301,7 +299,7 @@ static void temperature(char *buffer, void *_temperature) if (!val.fp) break; /* Celsius */ - switch (units.temperature) { + switch (input_units.temperature) { case KELVIN: temperature->mkelvin = val.fp * 1000; break; @@ -632,29 +630,29 @@ static int buffer_value(char *buffer) static void uemis_length_unit(char *buffer, void *_unused) { - units.length = buffer_value(buffer) ? FEET : METERS; + input_units.length = buffer_value(buffer) ? FEET : METERS; } static void uemis_volume_unit(char *buffer, void *_unused) { - units.volume = buffer_value(buffer) ? CUFT : LITER; + input_units.volume = buffer_value(buffer) ? CUFT : LITER; } static void uemis_pressure_unit(char *buffer, void *_unused) { #if 0 - units.pressure = buffer_value(buffer) ? PSI : BAR; + input_units.pressure = buffer_value(buffer) ? PSI : BAR; #endif } static void uemis_temperature_unit(char *buffer, void *_unused) { - units.temperature = buffer_value(buffer) ? FAHRENHEIT : CELSIUS; + input_units.temperature = buffer_value(buffer) ? FAHRENHEIT : CELSIUS; } static void uemis_weight_unit(char *buffer, void *_unused) { - units.weight = buffer_value(buffer) ? LBS : KG; + input_units.weight = buffer_value(buffer) ? LBS : KG; } static void uemis_time_unit(char *buffer, void *_unused) @@ -766,13 +764,13 @@ static void uemis_percent(char *buffer, void *_cylinder) static int uemis_dive_match(struct dive *dive, const char *name, int len, char *buf) { - return MATCH(".units.length", uemis_length_unit, &units) || - MATCH(".units.volume", uemis_volume_unit, &units) || - MATCH(".units.pressure", uemis_pressure_unit, &units) || - MATCH(".units.temperature", uemis_temperature_unit, &units) || - MATCH(".units.weight", uemis_weight_unit, &units) || - MATCH(".units.time", uemis_time_unit, &units) || - MATCH(".units.date", uemis_date_unit, &units) || + return MATCH(".units.length", uemis_length_unit, &input_units) || + MATCH(".units.volume", uemis_volume_unit, &input_units) || + MATCH(".units.pressure", uemis_pressure_unit, &input_units) || + MATCH(".units.temperature", uemis_temperature_unit, &input_units) || + MATCH(".units.weight", uemis_weight_unit, &input_units) || + MATCH(".units.time", uemis_time_unit, &input_units) || + MATCH(".units.date", uemis_date_unit, &input_units) || MATCH(".date_time", uemis_date_time, &dive->when) || MATCH(".time_zone", uemis_time_zone, &dive->when) || MATCH(".ambient.temperature", decicelsius, &dive->airtemp) || @@ -1229,13 +1227,13 @@ static void visit(xmlNode *n) static void suunto_importer(void) { import_source = SUUNTO; - units = SI_units; + input_units = SI_units; } static void uemis_importer(void) { import_source = UEMIS; - units = SI_units; + input_units = SI_units; } static void DivingLog_importer(void) @@ -1249,16 +1247,16 @@ static void DivingLog_importer(void) * when they are in Fahrenheit. Depths are in * meters, but pressure is in PSI. */ - units = SI_units; - units.pressure = PSI; + input_units = SI_units; + input_units.pressure = PSI; } static void uddf_importer(void) { import_source = UDDF; - units = SI_units; - units.pressure = PASCAL; - units.temperature = KELVIN; + input_units = SI_units; + input_units.pressure = PASCAL; + input_units.temperature = KELVIN; } /* @@ -1320,7 +1318,7 @@ static void reset_all(void) * data within one file, we might have to reset it per * dive for that format. */ - units = SI_units; + input_units = SI_units; import_source = UNKNOWN; } -- 2.45.2