summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2011-10-03 12:13:54 -0700
committerGravatar Linus Torvalds <torvalds@linux-foundation.org>2011-10-03 12:13:54 -0700
commit1531a37dd0b74fcb06ca06fd2f225d4a2d228a87 (patch)
tree87edc576053e177afb4a3bcddee4876cea0ece47
parenta32d28d5e388ab3e31eadcd329814488fa5e8b1b (diff)
parentc15f798a85db53dae404a9113266a4d2bc72fbc6 (diff)
downloadsubsurface-1531a37dd0b74fcb06ca06fd2f225d4a2d228a87.tar.gz
Merge branch 'uemis-integration' of git://github.com/dirkhh/subsurface
* '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
-rw-r--r--dive.h2
-rw-r--r--gtk-gui.c42
-rw-r--r--libdivecomputer.c4
-rw-r--r--parse-xml.c51
-rw-r--r--uemis.c116
-rw-r--r--uemis.h5
6 files changed, 46 insertions, 174 deletions
diff --git a/dive.h b/dive.h
index 42d91d630..40fc5ca2c 100644
--- 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);
diff --git a/gtk-gui.c b/gtk-gui.c
index 8ae67ecaa..ee3ad2ef1 100644
--- 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;
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 5fea5c28c..78be2019a 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -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 }
};
diff --git a/parse-xml.c b/parse-xml.c
index efae6b61f..6a08a3845 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -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 76bd1669b..46878e22a 100644
--- 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 d694007d0..e4e8532c2 100644
--- 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 */