]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Merge branch 'uemis-integration' of git://github.com/dirkhh/subsurface
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 3 Oct 2011 19:13:54 +0000 (12:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 3 Oct 2011 19:13:54 +0000 (12:13 -0700)
* 'uemis-integration' of git://github.com/dirkhh/subsurface:
  Remove the ability to 'Import' .SDA files
  Integrate loading of uemis SDA files into the regular xml parsing
  First steps towards integrating SDA files into the default XML loading

dive.h
gtk-gui.c
libdivecomputer.c
parse-xml.c
uemis.c
uemis.h

diff --git a/dive.h b/dive.h
index 42d91d630a0776f63b8605d61e6e5f1c429578a0..40fc5ca2c3668b5fada1924fb9ddb0fd41224324 100644 (file)
--- a/dive.h
+++ b/dive.h
@@ -262,8 +262,6 @@ extern void report_error(GError* error);
 extern void dive_list_update_dives(void);
 extern void flush_divelist(struct dive *dive);
 
-extern int open_import_file_dialog(char *filterpattern, char *filtertext, 
-                               void(* parse_function)(char *));
 #define DIVE_ERROR_PARSE 1
 
 const char *weekday(int wday);
index 8ae67ecaa6bcf3ad445b2a52be889a9dfd7716a3..ee3ad2ef11583109f80254007757833970e34fe5 100644 (file)
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -103,6 +103,8 @@ static void file_open(GtkWidget *w, gpointer data)
        filter = gtk_file_filter_new();
        gtk_file_filter_add_pattern(filter, "*.xml");
        gtk_file_filter_add_pattern(filter, "*.XML");
+       gtk_file_filter_add_pattern(filter, "*.sda");
+       gtk_file_filter_add_pattern(filter, "*.SDA");
        gtk_file_filter_add_mime_type(filter, "text/xml");
        gtk_file_filter_set_name(filter, "XML file");
        gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
@@ -668,46 +670,6 @@ void run_ui(void)
        gtk_main();
 }
 
-/* get the filenames the user selects and call the parsing function
- * on them
- * return 0 if the user cancelled the dialog
- */
-int open_import_file_dialog(char *filterpattern, char *filtertext, 
-                       void(* parse_function)(char *))
-{
-       int ret=0;
-
-       GtkWidget *dialog;
-       GtkFileFilter *filter = gtk_file_filter_new ();
-       gtk_file_filter_add_pattern (filter, filterpattern);
-       gtk_file_filter_set_name(filter, filtertext);
-       dialog = gtk_file_chooser_dialog_new("Open File",
-                                       GTK_WINDOW(main_window),
-                                       GTK_FILE_CHOOSER_ACTION_OPEN,
-                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-                                       NULL);
-       gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
-       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
-
-       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
-               GSList *filenames;
-               char *filename;
-               filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
-               while(filenames != NULL) {
-                       filename = (char *)filenames->data;
-                       parse_function(filename);
-                       g_free(filename);
-                       filenames = g_slist_next(filenames);
-               }
-               g_slist_free(filenames);
-               ret = 1;
-       }
-       gtk_widget_destroy(dialog);
-
-       return ret;
-}
-
 static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
        struct dive *dive = current_dive;
index 5fea5c28c848d08659718b08e34cedd2b004bc9e..78be2019a4adba9c03461ba5274271506a730f03 100644 (file)
@@ -497,9 +497,6 @@ void do_import(device_data_t *data)
        pthread_t pthread;
        void *retval;
 
-       if (data->type == DEVICE_TYPE_UEMIS)
-               return uemis_import();
-
        /* I'm sure there is some better interface for waiting on a thread in a UI main loop */
        import_thread_done = 0;
        pthread_create(&pthread, NULL, pthread_wrapper, data);
@@ -542,6 +539,5 @@ struct device_list device_list[] = {
        { "Cressi Edy",         DEVICE_TYPE_CRESSI_EDY },
        { "Zeagle N2iTiON 3",   DEVICE_TYPE_ZEAGLE_N2ITION3 },
        { "Atomics Cobalt",     DEVICE_TYPE_ATOMICS_COBALT },
-       { "Uemis Zurich SDA",   DEVICE_TYPE_UEMIS },
        { NULL }
 };
index efae6b61fd196e893cacc46df8fcffc280f21fd9..6a08a3845c9551c3f35b818ff5c51b468537abda 100644 (file)
@@ -3,11 +3,13 @@
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#define __USE_XOPEN
 #include <time.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 
 #include "dive.h"
+#include "uemis.h"
 
 int verbose;
 
@@ -639,8 +641,10 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu
 /*
  * Crazy suunto xml. Look at how those o2/he things match up.
  */
-static int suunto_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int suunto_dive_match(struct dive **divep, const char *name, int len, char *buf)
 {
+       struct dive *dive = *divep;
+
        return  MATCH(".o2pct", percent, &dive->cylinder[0].gasmix.o2) ||
                MATCH(".hepct_0", percent, &dive->cylinder[0].gasmix.he) ||
                MATCH(".o2pct_2", percent, &dive->cylinder[1].gasmix.o2) ||
@@ -678,8 +682,10 @@ static void divinglog_place(char *place, void *_location)
        country = NULL;
 }
 
-static int divinglog_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int divinglog_dive_match(struct dive **divep, const char *name, int len, char *buf)
 {
+       struct dive *dive = *divep;
+
        return  MATCH(".divedate", divedate, &dive->when) ||
                MATCH(".entrytime", divetime, &dive->when) ||
                MATCH(".depth", depth, &dive->maxdepth) ||
@@ -770,6 +776,21 @@ static void uemis_time_zone(char *buffer, void *_when)
 #endif
 }
 
+static void uemis_ts(char *buffer, void *_when)
+{
+       struct tm tm;
+       time_t *when = _when;
+
+       strptime(buffer, "%Y-%m-%dT%H:%M:%S", &tm);
+       *when = utc_mktime(&tm);
+}
+
+static void uemis_duration(char *buffer, void *_duration)
+{
+       duration_t *duration = _duration;
+       duration->seconds = atof(buffer) * 60 + 0.5;
+}
+
 /* 0 - air ; 1 - nitrox1 ; 2 - nitrox2 ; 3 = nitrox3 */
 static int uemis_gas_template;
 
@@ -834,8 +855,10 @@ static void uemis_percent(char *buffer, void *_cylinder)
                percent(buffer, &dive->cylinder[index].gasmix.o2);
 }
 
-static int uemis_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int uemis_dive_match(struct dive **divep, const char *name, int len, char *buf)
 {
+       struct dive *dive = *divep;
+
        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) ||
@@ -861,6 +884,9 @@ static int uemis_dive_match(struct dive *dive, const char *name, int len, char *
                MATCH(".nitrox_3.deco_tank.oxygen", uemis_percent, dive->cylinder + 5) ||
                MATCH(".nitrox_3.travel_tank.size", uemis_cylindersize, dive->cylinder + 6) ||
                MATCH(".nitrox_3.travel_tank.oxygen", uemis_percent, dive->cylinder + 6) ||
+               MATCH(".dive.val.float", uemis_duration, &dive->duration) ||
+               MATCH(".dive.val.ts", uemis_ts, &dive->when) ||
+               MATCH(".dive.val.bin", uemis_parse_divelog_binary, divep) ||
                0;
 }
 
@@ -908,8 +934,10 @@ success:
        free(buffer);
 }
 
-static int uddf_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int uddf_dive_match(struct dive **divep, const char *name, int len, char *buf)
 {
+       struct dive *dive = *divep;
+
        return  MATCH(".datetime", uddf_datetime, &dive->when) ||
                MATCH(".diveduration", duration, &dive->duration) ||
                MATCH(".greatestdepth", depth, &dive->maxdepth) ||
@@ -931,7 +959,7 @@ static void gps_location(char *buffer, void *_dive)
 }
 
 /* We're in the top-level dive xml. Try to convert whatever value to a dive value */
-static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
+static void try_to_fill_dive(struct dive **divep, const char *name, char *buf)
 {
        int len = strlen(name);
 
@@ -939,22 +967,22 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
 
        switch (import_source) {
        case SUUNTO:
-               if (suunto_dive_match(dive, name, len, buf))
+               if (suunto_dive_match(divep, name, len, buf))
                        return;
                break;
 
        case UEMIS:
-               if (uemis_dive_match(dive, name, len, buf))
+               if (uemis_dive_match(divep, name, len, buf))
                        return;
                break;
 
        case DIVINGLOG:
-               if (divinglog_dive_match(dive, name, len, buf))
+               if (divinglog_dive_match(divep, name, len, buf))
                        return;
                break;
 
        case UDDF:
-               if (uddf_dive_match(dive, name, len, buf))
+               if (uddf_dive_match(divep, name, len, buf))
                        return;
                break;
 
@@ -962,6 +990,8 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
                break;
        }
 
+       struct dive *dive = *divep;
+
        if (MATCH(".number", get_index, &dive->number))
                return;
        if (MATCH(".date", divedate, &dive->when))
@@ -1222,7 +1252,7 @@ static void entry(const char *name, int size, const char *raw)
                return;
        }
        if (dive) {
-               try_to_fill_dive(dive, name, buf);
+               try_to_fill_dive(&dive, name, buf);
                return;
        }
 }
@@ -1365,6 +1395,7 @@ static struct nesting {
        { "SUUNTO", suunto_importer },
        { "Divinglog", DivingLog_importer },
        { "pre_dive", uemis_importer },
+       { "dives", uemis_importer },
        { "uddf", uddf_importer },
 
        { NULL, }
diff --git a/uemis.c b/uemis.c
index 76bd1669b4217a8f05306874a9a0c1b6dcfae71e..46878e22a89c0632ad0be203f41ea3bbbcc8bfda 100644 (file)
--- a/uemis.c
+++ b/uemis.c
@@ -73,64 +73,6 @@ static void decode( uint8_t *inbuf, uint8_t *outbuf, int inbuf_len ) {
 }
 /* end code from Bob Trower */
 
-/* small helper functions */
-/* simpleregex allocates (and reallocates) the found buffer
- * don't forget to free it when you are done
- */
-static int simpleregex(char *buffer, char *regex, char **found) {
-       int status;
-       regex_t re;
-       regmatch_t match[5];
-
-       if (regcomp(&re, regex, 0) !=0) {
-               fprintf(stderr,"internal error, regex failed!\n");
-               exit(1);
-       }
-       status = regexec(&re,buffer,5,match,0);
-       if(status == 0) {
-               *found = realloc(*found,match[1].rm_eo-match[1].rm_so + 1);
-               strncpy(*found,buffer+match[1].rm_so,match[1].rm_eo-match[1].rm_so);
-               (*found)[match[1].rm_eo-match[1].rm_so] = '\0';
-       }
-       return(status == 0);
-}
-
-/* read in line of arbitrary length (important for SDA files that can
- * have lines that are tens of kB long
- * don't forget to free it when you are done
- */
-#define MYGETL_INCR 1024
-static char * mygetline(FILE * f) {
-       size_t size = 0;
-       size_t len  = 0;
-       char * buf  = NULL;
-
-       do {
-               size += MYGETL_INCR;
-               if ((buf = realloc(buf,size)) == NULL)
-                       break;
-               fgets(buf+len,MYGETL_INCR,f);
-               len = strlen(buf);
-       } while (!feof(f) && buf[len-1]!='\n');
-       return buf;
-}
-
-/* text matching, used to build very poor man's XML parser */
-int matchit(FILE *infd, char *regex, char *typeregex, char **found) {
-       char *buffer;
-
-       while (!feof(infd)) {
-               buffer = mygetline(infd);
-               if (buffer && simpleregex(buffer,regex,found)) {
-                       buffer = mygetline(infd);
-                       if (buffer && simpleregex(buffer,typeregex,found)) {
-                               return 1;
-                       }
-               }
-       }
-       return 0;
-}
-
 /*
  * pressure_to_depth: In centibar. And when converting to
  * depth, I'm just going to always use saltwater, because I
@@ -180,11 +122,12 @@ bail:
 /*
  * parse uemis base64 data blob into struct dive
  */
-static void parse_divelog_binary(char *base64, struct dive **divep) {
+void uemis_parse_divelog_binary(char *base64, void *datap) {
        int datalen;
        int i;
        uint8_t *data;
        struct sample *sample;
+       struct dive **divep = datap;
        struct dive *dive = *divep;
        int template, gasoffset;
 
@@ -237,58 +180,3 @@ static void parse_divelog_binary(char *base64, struct dive **divep) {
        dive->duration.seconds = sample->time.seconds - 1;
        return;
 }
-
-/* parse a single file
- * TODO: we don't report any errors when the parse fails - we simply don't add them to the list
- */
-void
-parse_uemis_file(char *divelogfilename) {
-       char *found=NULL;
-       struct tm tm;
-       struct dive *dive;
-
-       FILE *divelogfile = fopen(divelogfilename,"r");
-
-       dive = alloc_dive();
-
-       if (! matchit(divelogfile,"val key=\"date\"","<ts>\\([^<]*\\)</ts>",&found)) {
-               /* some error handling */
-               goto bail;
-       }
-       strptime(found, "%Y-%m-%dT%H:%M:%S", &tm);
-       dive->when = utc_mktime(&tm);
-       if (! matchit(divelogfile,"<val key=\"duration\">",
-                       "<float>\\([0-9.]*\\)</float>", &found)) {
-               /* some error handling */
-               goto bail;
-       }
-       dive->duration.seconds = 60.0 * atof(found);
-
-       if (! matchit(divelogfile,"<val key=\"depth\">",
-                       "<int>\\([0-9.]*\\)</int>", &found)) {
-               /* some error handling */
-               goto bail;
-       }
-       dive->maxdepth.mm = pressure_to_depth(atoi(found));
-
-       if (! matchit(divelogfile,"<val key=\"file_content\">",
-                       ">\\([a-zA-Z0-9+/=]*\\)<", &found)) {
-               /* some error handling */
-               goto bail;
-       }
-       parse_divelog_binary(found,&dive);
-       record_dive(dive);
-bail:
-       if (found)
-               free(found);
-}
-
-/*
- * parse the two files extracted from the SDA
- */
-void
-uemis_import() {
-       if (open_import_file_dialog("*.SDA","uemis Zurich SDA files",
-                                       &parse_uemis_file))
-               report_dives();
-}      
diff --git a/uemis.h b/uemis.h
index d694007d031e2eb919136c2ce46d8dc9e9165be1..e4e8532c21c429680a059041cfac0a3eadd2f822 100644 (file)
--- a/uemis.h
+++ b/uemis.h
@@ -3,11 +3,8 @@
 
 /*
  * defines and prototypes for the uemis Zurich SDA file parser
- * we add this to the list of dive computers that is supported
- * in libdivecomputer by using a negative value for the type enum
  */
-#define DEVICE_TYPE_UEMIS (-1)
 
-void uemis_import();
+void uemis_parse_divelog_binary(char *base64, void *divep);
 
 #endif /* DIVE_H */