diff --git a/file.c b/file.c index 70eb79ad4..53b03330c 100644 --- a/file.c +++ b/file.c @@ -97,6 +97,36 @@ static int try_to_open_zip(const char *filename, struct memblock *mem, char **er return success; } +static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, char **error) +{ + char *buf; + + if (readfile(filename, mem) < 0) { + if (error) { + int len = strlen(_("Failed to read '%s'")) + strlen(filename); + *error = malloc(len); + snprintf(*error, len, _("Failed to read '%s'"), filename); + } + + return 1; + } + + /* Surround the CSV file content with XML tags to enable XSLT + * parsing + */ + buf = realloc(mem->buffer, mem->size + strlen("")); + if (buf != NULL) { + memmove(buf + 5, mem->buffer, mem->size); + memcpy(buf, "", 5); + memcpy(mem->buffer + mem->size + 5, "", 7); + mem->buffer = buf; + mem->size += strlen(""); + } else + return 1; + + return 0; +} + static int try_to_open_db(const char *filename, struct memblock *mem, char **error) { return parse_dm4_buffer(filename, mem->buffer, mem->size, &dive_table, error); @@ -229,6 +259,10 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo if (!strcasecmp(fmt, "SDE") || !strcasecmp(fmt, "ZIP") || !strcasecmp(fmt, "DLD")) return try_to_open_zip(filename, mem, error); + /* CSV files */ + if (!strcasecmp(fmt, "CSV")) + return try_to_xslt_open_csv(filename, mem, error); + #if ONCE_COCHRAN_IS_SUPPORTED /* Truly nasty intentionally obfuscated Cochran Anal software */ if (!strcasecmp(fmt, "CAN")) @@ -266,8 +300,9 @@ void parse_file(const char *filename, char **error) return; if (error) { - *error = malloc(1024); - snprintf(*error, 1024, _("Failed to read '%s'"), filename); + int len = strlen(_("Failed to read '%s'")) + strlen(filename); + *error = malloc(len); + snprintf(*error, len, _("Failed to read '%s'"), filename); } return; diff --git a/parse-xml.c b/parse-xml.c index 370388f4f..195eafeb9 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -1915,6 +1915,7 @@ static struct xslt_files { { "UDDF", "uddf.xslt" }, { "profile", "udcf.xslt" }, { "Divinglog", "DivingLog.xslt" }, + { "csv", "csv2xml.xslt" }, { NULL, } }; @@ -1925,6 +1926,7 @@ static xmlDoc *test_xslt_transforms(xmlDoc *doc, char **error) xsltStylesheetPtr xslt = NULL; xmlNode *root_element = xmlDocGetRootElement(doc); char *attribute; + char *params[3]; while ((info->root) && (strcasecmp(root_element->name, info->root) != 0)) { info++; @@ -1946,9 +1948,28 @@ static xmlDoc *test_xslt_transforms(xmlDoc *doc, char **error) parser_error(error, _("Can't open stylesheet (%s)/%s"), xslt_path, info->file); return doc; } - transformed = xsltApplyStylesheet(xslt, doc, NULL); + + /* + * params is only used for CSV import, but it does not + * hurt if we supply unused parameters for other + * transforms as well. + * + * We should have a GUI set the parameters but currently + * we just have PoC how parameters would be handled. + * + * (Field 9 is temperature for XP5 import, field 15 + * is temperature for AP Logviewer. + */ + + params[0] = strdup("tempField"); + params[1] = strdup("15"); + params[2] = NULL; + + transformed = xsltApplyStylesheet(xslt, doc, (const char **)params); xmlFreeDoc(doc); xsltFreeStylesheet(xslt); + free(params[0]); + free(params[1]); return transformed; } return doc; diff --git a/xslt/csv2xml.xslt b/xslt/csv2xml.xslt new file mode 100644 index 000000000..faa9e9605 --- /dev/null +++ b/xslt/csv2xml.xslt @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +