summaryrefslogtreecommitdiffstats
path: root/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'file.c')
-rw-r--r--file.c218
1 files changed, 121 insertions, 97 deletions
diff --git a/file.c b/file.c
index 8fca750ac..f7f98333f 100644
--- a/file.c
+++ b/file.c
@@ -824,98 +824,101 @@ int parse_txt_file(const char *filename, const char *csv)
return 0;
}
-#define MAXCOLDIGITS 3
+#define MAXCOLDIGITS 10
#define MAXCOLS 100
#define DATESTR 9
#define TIMESTR 6
-void init_csv_file_parsing(char **params, char *timebuf, char *depthbuf, char *tempbuf, char *po2buf, char *o2sensor1buf, char *o2sensor2buf, char *o2sensor3buf, char *cnsbuf, char *ndlbuf, char *ttsbuf, char *stopdepthbuf, char *pressurebuf, char *setpointbuf, char *unitbuf, char *separator_index, time_t *now, struct tm *timep, char *curdate, char *curtime, int timef, int depthf, int tempf, int po2f, int o2sensor1f, int o2sensor2f, int o2sensor3f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int setpointf, int sepidx, const char *csvtemplate, int unitidx)
+
+int init_csv_file_parsing(char **params, time_t *now, struct tm *timep, int timef, int depthf, int tempf, int po2f, int o2sensor1f, int o2sensor2f, int o2sensor3f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int setpointf, int sepidx, const char *csvtemplate, int unitidx)
{
int pnr = 0;
+ char tmpbuf[MAXCOLDIGITS];
- snprintf(timebuf, MAXCOLDIGITS, "%d", timef);
- snprintf(depthbuf, MAXCOLDIGITS, "%d", depthf);
- snprintf(tempbuf, MAXCOLDIGITS, "%d", tempf);
- snprintf(po2buf, MAXCOLDIGITS, "%d", po2f);
- snprintf(o2sensor1buf, MAXCOLDIGITS, "%d", o2sensor1f);
- snprintf(o2sensor2buf, MAXCOLDIGITS, "%d", o2sensor2f);
- snprintf(o2sensor3buf, MAXCOLDIGITS, "%d", o2sensor3f);
- snprintf(cnsbuf, MAXCOLDIGITS, "%d", cnsf);
- snprintf(ndlbuf, MAXCOLDIGITS, "%d", ndlf);
- snprintf(ttsbuf, MAXCOLDIGITS, "%d", ttsf);
- snprintf(stopdepthbuf, MAXCOLDIGITS, "%d", stopdepthf);
- snprintf(pressurebuf, MAXCOLDIGITS, "%d", pressuref);
- snprintf(setpointbuf, MAXCOLDIGITS, "%d", setpointf);
- snprintf(separator_index, MAXCOLDIGITS, "%d", sepidx);
- snprintf(unitbuf, MAXCOLDIGITS, "%d", unitidx);
- time(now);
- timep = localtime(now);
- strftime(curdate, DATESTR, "%Y%m%d", timep);
-
- /* As the parameter is numeric, we need to ensure that the leading zero
- * is not discarded during the transform, thus prepend time with 1 */
- strftime(curtime, TIMESTR, "1%H%M", timep);
-
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", timef);
params[pnr++] = "timeField";
- params[pnr++] = timebuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", depthf);
params[pnr++] = "depthField";
- params[pnr++] = depthbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", tempf);
params[pnr++] = "tempField";
- params[pnr++] = tempbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", po2f);
params[pnr++] = "po2Field";
- params[pnr++] = po2buf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", o2sensor1f);
params[pnr++] = "o2sensor1Field";
- params[pnr++] = o2sensor1buf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", o2sensor2f);
params[pnr++] = "o2sensor2Field";
- params[pnr++] = o2sensor2buf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", o2sensor3f);
params[pnr++] = "o2sensor3Field";
- params[pnr++] = o2sensor3buf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", cnsf);
params[pnr++] = "cnsField";
- params[pnr++] = cnsbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", ndlf);
params[pnr++] = "ndlField";
- params[pnr++] = ndlbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", ttsf);
params[pnr++] = "ttsField";
- params[pnr++] = ttsbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", stopdepthf);
params[pnr++] = "stopdepthField";
- params[pnr++] = stopdepthbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", pressuref);
params[pnr++] = "pressureField";
- params[pnr++] = pressurebuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", setpointf);
params[pnr++] = "setpointField";
- params[pnr++] = setpointbuf;
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", sepidx);
+ params[pnr++] = "separatorIndex";
+ params[pnr++] = strdup(tmpbuf);
+
+ snprintf(tmpbuf, MAXCOLDIGITS, "%d", unitidx);
+ params[pnr++] = "units";
+ params[pnr++] = strdup(tmpbuf);
+
+ time(now);
+ timep = localtime(now);
+
+ strftime(tmpbuf, MAXCOLDIGITS, "%Y%m%d", timep);
params[pnr++] = "date";
- params[pnr++] = curdate;
+ params[pnr++] = strdup(tmpbuf);
+
+ /* As the parameter is numeric, we need to ensure that the leading zero
+ * is not discarded during the transform, thus prepend time with 1 */
+ strftime(tmpbuf, MAXCOLDIGITS, "1%H%M", timep);
params[pnr++] = "time";
- params[pnr++] = curtime;
- params[pnr++] = "units";
- params[pnr++] = unitbuf;
- params[pnr++] = "separatorIndex";
- params[pnr++] = separator_index;
+ params[pnr++] = strdup(tmpbuf);
+
params[pnr++] = NULL;
+
+ return pnr - 1;
}
int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int o2sensor1f, int o2sensor2f, int o2sensor3f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int setpointf, int sepidx, const char *csvtemplate, int unitidx)
{
- int ret;
+ int ret, i;
struct memblock mem;
char *params[35];
- char timebuf[MAXCOLDIGITS];
- char depthbuf[MAXCOLDIGITS];
- char tempbuf[MAXCOLDIGITS];
- char po2buf[MAXCOLDIGITS];
- char o2sensor1buf[MAXCOLDIGITS];
- char o2sensor2buf[MAXCOLDIGITS];
- char o2sensor3buf[MAXCOLDIGITS];
- char cnsbuf[MAXCOLDIGITS];
- char ndlbuf[MAXCOLDIGITS];
- char ttsbuf[MAXCOLDIGITS];
- char stopdepthbuf[MAXCOLDIGITS];
- char pressurebuf[MAXCOLDIGITS];
- char setpointbuf[MAXCOLDIGITS];
- char unitbuf[MAXCOLDIGITS];
- char separator_index[MAXCOLDIGITS];
time_t now;
struct tm *timep = NULL;
- char curdate[DATESTR];
- char curtime[TIMESTR];
int previous;
/* Increase the limits for recursion and variables on XSLT
@@ -928,7 +931,7 @@ int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int p
if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || o2sensor1f >= MAXCOLS || o2sensor2f >= MAXCOLS || o2sensor3f >= MAXCOLS || cnsf >= MAXCOLS || ndlf >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS || pressuref >= MAXCOLS || setpointf >= MAXCOLS)
return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
- init_csv_file_parsing(params, timebuf, depthbuf, tempbuf, po2buf, o2sensor1buf, o2sensor2buf, o2sensor3buf, cnsbuf, ndlbuf, ttsbuf, stopdepthbuf, pressurebuf, setpointbuf, unitbuf, separator_index, &now, timep, curdate, curtime, timef, depthf, tempf, po2f, o2sensor1f, o2sensor2f, o2sensor3f, cnsf, ndlf, ttsf, stopdepthf, pressuref, setpointf, sepidx, csvtemplate, unitidx);
+ init_csv_file_parsing(params, &now, timep, timef, depthf, tempf, po2f, o2sensor1f, o2sensor2f, o2sensor3f, cnsf, ndlf, ttsf, stopdepthf, pressuref, setpointf, sepidx, csvtemplate, unitidx);
if (filename == NULL)
return report_error("No CSV filename");
@@ -941,42 +944,35 @@ int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int p
ret = parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params);
free(mem.buffer);
+ for (i = 0; params[i]; i += 2)
+ free(params[i + 1]);
+
return ret;
}
-#define SBPARAMS 35
+#define SBPARAMS 38
int parse_seabear_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int o2sensor1f, int o2sensor2f, int o2sensor3f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int unitidx, const char *delta)
{
- int ret;
+ int ret, i, pnr;
struct memblock mem;
char *params[SBPARAMS];
- char timebuf[MAXCOLDIGITS];
- char depthbuf[MAXCOLDIGITS];
- char tempbuf[MAXCOLDIGITS];
- char po2buf[MAXCOLDIGITS];
- char o2sensor1buf[MAXCOLDIGITS];
- char o2sensor2buf[MAXCOLDIGITS];
- char o2sensor3buf[MAXCOLDIGITS];
- char cnsbuf[MAXCOLDIGITS];
- char ndlbuf[MAXCOLDIGITS];
- char ttsbuf[MAXCOLDIGITS];
- char stopdepthbuf[MAXCOLDIGITS];
- char pressurebuf[MAXCOLDIGITS];
- char setpointbuf[MAXCOLDIGITS];
- char unitbuf[MAXCOLDIGITS];
- char separator_index[MAXCOLDIGITS];
char deltabuf[MAXCOLDIGITS];
time_t now;
struct tm *timep = NULL;
- char curdate[DATESTR];
- char curtime[TIMESTR];
char *ptr, *ptr_old = NULL;
char *NL = NULL;
+ /* Increase the limits for recursion and variables on XSLT
+ * parsing */
+ xsltMaxDepth = 30000;
+#if LIBXSLT_VERSION > 10126
+ xsltMaxVars = 150000;
+#endif
+
if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || o2sensor1f >= MAXCOLS || o2sensor2f >= MAXCOLS || o2sensor3f >= MAXCOLS || cnsf >= MAXCOLS || ndlf >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS || pressuref >= MAXCOLS)
return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
- init_csv_file_parsing(params, timebuf, depthbuf, tempbuf, po2buf, o2sensor1buf, o2sensor2buf, o2sensor3buf, cnsbuf, ndlbuf, ttsbuf, stopdepthbuf, pressurebuf, setpointbuf, unitbuf, separator_index, &now, timep, curdate, curtime, timef, depthf, tempf, po2f, o2sensor1f, o2sensor2f, o2sensor3f, cnsf, ndlf, ttsf, stopdepthf, pressuref, -1, sepidx, csvtemplate, unitidx);
+ pnr = init_csv_file_parsing(params, &now, timep, timef, depthf, tempf, po2f, o2sensor1f, o2sensor2f, o2sensor3f, cnsf, ndlf, ttsf, stopdepthf, pressuref, -1, sepidx, csvtemplate, unitidx);
if (filename == NULL)
return report_error("No CSV filename");
@@ -993,6 +989,7 @@ int parse_seabear_csv_file(const char *filename, int timef, int depthf, int temp
}
if (!ptr_old) {
+ ptr = mem.buffer;
while ((ptr = strstr(ptr, "\n\n")) != NULL) {
ptr_old = ptr;
ptr += 1;
@@ -1012,30 +1009,41 @@ int parse_seabear_csv_file(const char *filename, int timef, int depthf, int temp
/*
* On my current sample of Seabear DC log file, the date is
* without any identifier. Thus we must search for the previous
- * line and step through from there.
+ * line and step through from there. That is the line after
+ * Serial number.
*/
ptr = strstr(mem.buffer, "Serial number:");
if (ptr)
ptr = strstr(ptr, NL);
- /* Write date and time values to params array */
+ /*
+ * Write date and time values to params array, if available in
+ * the CSV header
+ */
+
if (ptr) {
ptr += strlen(NL) + 2;
- memcpy(params[19], ptr, 4);
- memcpy(params[19] + 4, ptr + 5, 2);
- memcpy(params[19] + 6, ptr + 8, 2);
- params[19][8] = 0;
-
- params[21][0] = '1';
- memcpy(params[21] + 1, ptr + 11, 2);
- memcpy(params[21] + 3, ptr + 14, 2);
- params[21][5] = 0;
+ /*
+ * pnr is the index of NULL on the params as filled by
+ * the init function. The two last entries should be
+ * date and time. Here we overwrite them with the data
+ * from the CSV header.
+ */
+
+ memcpy(params[pnr - 3], ptr, 4);
+ memcpy(params[pnr - 3] + 4, ptr + 5, 2);
+ memcpy(params[pnr - 3] + 6, ptr + 8, 2);
+ params[pnr - 3][8] = 0;
+
+ memcpy(params[pnr - 1] + 1, ptr + 11, 2);
+ memcpy(params[pnr - 1] + 3, ptr + 14, 2);
+ params[pnr - 1][5] = 0;
}
snprintf(deltabuf, MAXCOLDIGITS, "%s", delta);
- params[SBPARAMS - 3] = "delta";
- params[SBPARAMS - 2] = deltabuf;
- params[SBPARAMS - 1] = NULL;
+ params[pnr++] = "delta";
+ params[pnr++] = strdup(deltabuf);
+ params[pnr++] = NULL;
/* Move the CSV data to the start of mem buffer */
memmove(mem.buffer, ptr_old, mem.size - (ptr_old - (char*)mem.buffer));
@@ -1044,8 +1052,24 @@ int parse_seabear_csv_file(const char *filename, int timef, int depthf, int temp
if (try_to_xslt_open_csv(filename, &mem, csvtemplate))
return -1;
+ /*
+ * Lets print command line for manual testing with xsltproc if
+ * verbosity level is high enough. The printed line needs the
+ * input file added as last parameter.
+ */
+
+ if (verbose >= 2) {
+ fprintf(stderr, "xsltproc ");
+ for (i=0; params[i]; i+=2)
+ fprintf(stderr, "--stringparam %s %s ", params[i], params[i+1]);
+ fprintf(stderr, "xslt/csv2xml.xslt\n");
+ }
+
ret = parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params);
free(mem.buffer);
+ for (i = 0; params[i]; i += 2)
+ free(params[i + 1]);
+
return ret;
}