[PATCH] Convert other users of showError() to the new world order

Linus Torvalds torvalds at linux-foundation.org
Fri Mar 14 11:32:54 PDT 2014


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Fri, 14 Mar 2014 11:26:07 -0700
Subject: [PATCH] Convert other users of showError() to the new world order

The "report_error()" interface is a lot simpler, although some of the
C++ code uses QStrings which make them a bit annoying, especially for
the varargs model.  Still, even with the explicit conversion to UTF8 and
"char *", the report_error() model is much nicer.

This also just makes refreshDisplay() do the error reporting in the UI
automatically, so a number of error paths don't even have to worry.  And
the multi-line model of error reporting means that it all automatically
does the right thing, and reports errors for each file rather than just
for the last file that failed to open.

So this removes closer to a hundred lines of cruft, while being a
simpler interface and doing better error reporting.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

On Fri, 14 Mar 2014, Linus Torvalds wrote:
> 
> This concludes the series, and I currently have nothing planned or 
> pending.

I lied. *This* concludes the series.

 dive.h                          |  14 +++---
 file.c                          | 105 ++++++++++++++++------------------------
 parse-xml.c                     |  40 +++------------
 planner.c                       |  31 ++++++------
 qt-ui/divelogimportdialog.cpp   |  18 +------
 qt-ui/diveplanner.cpp           |   6 +--
 qt-ui/mainwindow.cpp            |  26 ++++------
 qt-ui/subsurfacewebservices.cpp |  28 ++++-------
 qt-ui/subsurfacewebservices.h   |   2 +-
 9 files changed, 96 insertions(+), 174 deletions(-)

diff --git a/dive.h b/dive.h
index 1455bb5dfa91..c6867fc5d68c 100644
--- a/dive.h
+++ b/dive.h
@@ -671,16 +671,16 @@ struct dive *find_dive_n_near(timestamp_t when, int n, timestamp_t offset);
 extern int match_one_dc(struct divecomputer *a, struct divecomputer *b);
 
 extern void parse_xml_init(void);
-extern void parse_xml_buffer(const char *url, const char *buf, int size, struct dive_table *table, const char **params, char **error);
+extern void parse_xml_buffer(const char *url, const char *buf, int size, struct dive_table *table, const char **params);
 extern void parse_xml_exit(void);
 extern void set_filename(const char *filename, bool force);
 
-extern int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error);
-extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error);
+extern int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table);
+extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table);
 
-extern void parse_file(const char *filename, char **error);
-extern void parse_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, int units, char **error);
-extern void parse_manual_file(const char *filename, int separator_index, int units, int number, int date, int time, int duration, int location, int gps, int maxdepth, int meandepth, int buddy, int notes, int weight, int tags, char **error);
+extern int parse_file(const char *filename);
+extern int parse_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, int units);
+extern int parse_manual_file(const char *filename, int separator_index, int units, int number, int date, int time, int duration, int location, int gps, int maxdepth, int meandepth, int buddy, int notes, int weight, int tags);
 
 extern int save_dives(const char *filename);
 extern int save_dives_logic(const char *filename, bool select_only);
@@ -820,7 +820,7 @@ struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration,
 void get_gas_string(int o2, int he, char *buf, int len);
 struct divedatapoint *create_dp(int time_incr, int depth, int o2, int he, int po2);
 void dump_plan(struct diveplan *diveplan);
-void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, bool add_deco, const char **error_string_p);
+void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, bool add_deco);
 void delete_single_dive(int idx);
 
 struct event *get_next_event(struct event *event, char *name);
diff --git a/file.c b/file.c
index 8facdf8d5aab..2c0b9f9391cb 100644
--- a/file.c
+++ b/file.c
@@ -62,7 +62,7 @@ out:
 }
 
 
-static void zip_read(struct zip_file *file, char **error, const char *filename)
+static void zip_read(struct zip_file *file, const char *filename)
 {
 	int size = 1024, n, read = 0;
 	char *mem = malloc(size);
@@ -73,11 +73,11 @@ static void zip_read(struct zip_file *file, char **error, const char *filename)
 		mem = realloc(mem, size);
 	}
 	mem[read] = 0;
-	parse_xml_buffer(filename, mem, read, &dive_table, NULL, error);
+	parse_xml_buffer(filename, mem, read, &dive_table, NULL);
 	free(mem);
 }
 
-static int try_to_open_zip(const char *filename, struct memblock *mem, char **error)
+static int try_to_open_zip(const char *filename, struct memblock *mem)
 {
 	int success = 0;
 	/* Grr. libzip needs to re-open the file, it can't take a buffer */
@@ -89,7 +89,7 @@ static int try_to_open_zip(const char *filename, struct memblock *mem, char **er
 			struct zip_file *file = zip_fopen_index(zip, index, 0);
 			if (!file)
 				break;
-			zip_read(file, error, filename);
+			zip_read(file, filename);
 			zip_fclose(file);
 			success++;
 		}
@@ -98,19 +98,12 @@ 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, const char *tag)
+static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, const char *tag)
 {
 	char *buf;
 
-	if (readfile(filename, mem) < 0) {
-		if (error) {
-			int len = strlen(translate("gettextFromC", "Failed to read '%s'")) + strlen(filename);
-			*error = malloc(len);
-			snprintf(*error, len, translate("gettextFromC", "Failed to read '%s'"), filename);
-		}
-
-		return 1;
-	}
+	if (readfile(filename, mem) < 0)
+		return report_error(translate("gettextFromC", "Failed to read '%s'"), filename);
 
 	/* Surround the CSV file content with XML tags to enable XSLT
 	 * parsing
@@ -132,8 +125,7 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, char
 			free(starttag);
 			free(endtag);
 			free(buf);
-			*error = strdup("Memory allocation failed in __func__\n");
-			return 1;
+			return report_error("Memory allocation failed in %s", __func__);
 		}
 
 		sprintf(starttag, "<%s>", tag);
@@ -148,10 +140,8 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, char
 		free(starttag);
 		free(endtag);
 	} else {
-		/* we can atleast try to strdup a error... */
-		*error = strdup("realloc failed in __func__\n");
 		free(mem->buffer);
-		return 1;
+		return report_error("realloc failed in %s", __func__);
 	}
 
 	return 0;
@@ -163,7 +153,7 @@ int db_test_func(void *param, int columns, char **data, char **column)
 }
 
 
-static int try_to_open_db(const char *filename, struct memblock *mem, char **error)
+static int try_to_open_db(const char *filename, struct memblock *mem)
 {
 	sqlite3 *handle;
 	char dm4_test[] = "select count(*) from sqlite_master where type='table' and name='Dive' and sql like '%ProfileBlob%'";
@@ -180,7 +170,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem, char **err
 	/* Testing if DB schema resembles Suunto DM4 database format */
 	retval = sqlite3_exec(handle, dm4_test, &db_test_func, 0, NULL);
 	if (!retval) {
-		retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error);
+		retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table);
 		sqlite3_close(handle);
 		return retval;
 	}
@@ -188,7 +178,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem, char **err
 	/* Testing if DB schema resembles Shearwater database format */
 	retval = sqlite3_exec(handle, shearwater_test, &db_test_func, 0, NULL);
 	if (!retval) {
-		retval = parse_shearwater_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error);
+		retval = parse_shearwater_buffer(handle, filename, mem->buffer, mem->size, &dive_table);
 		sqlite3_close(handle);
 		return retval;
 	}
@@ -321,11 +311,11 @@ static int try_to_open_csv(const char *filename, struct memblock *mem, enum csv_
 	return 1;
 }
 
-static int open_by_filename(const char *filename, const char *fmt, struct memblock *mem, char **error)
+static int open_by_filename(const char *filename, const char *fmt, struct memblock *mem)
 {
 	/* Suunto Dive Manager files: SDE, ZIP; divelogs.de files: DLD */
 	if (!strcasecmp(fmt, "SDE") || !strcasecmp(fmt, "ZIP") || !strcasecmp(fmt, "DLD"))
-		return try_to_open_zip(filename, mem, error);
+		return try_to_open_zip(filename, mem);
 
 	/* CSV files */
 	if (!strcasecmp(fmt, "CSV"))
@@ -334,7 +324,7 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo
 #if ONCE_COCHRAN_IS_SUPPORTED
 	/* Truly nasty intentionally obfuscated Cochran Anal software */
 	if (!strcasecmp(fmt, "CAN"))
-		return try_to_open_cochran(filename, mem, error);
+		return try_to_open_cochran(filename, mem);
 #endif
 
 	/* Cochran export comma-separated-value files */
@@ -348,19 +338,19 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo
 	return 0;
 }
 
-static void parse_file_buffer(const char *filename, struct memblock *mem, char **error)
+static void parse_file_buffer(const char *filename, struct memblock *mem)
 {
 	char *fmt = strrchr(filename, '.');
-	if (fmt && open_by_filename(filename, fmt + 1, mem, error))
+	if (fmt && open_by_filename(filename, fmt + 1, mem))
 		return;
 
 	if (!mem->size || !mem->buffer)
 		return;
 
-	parse_xml_buffer(filename, mem->buffer, mem->size, &dive_table, NULL, error);
+	parse_xml_buffer(filename, mem->buffer, mem->size, &dive_table, NULL);
 }
 
-void parse_file(const char *filename, char **error)
+int parse_file(const char *filename)
 {
 	struct git_repository *git;
 	const char *branch;
@@ -369,37 +359,32 @@ void parse_file(const char *filename, char **error)
 
 	git = is_git_repository(filename, &branch);
 	if (git && !git_load_dives(git, branch))
-		return;
+		return 0;
 
 	if (readfile(filename, &mem) < 0) {
 		/* we don't want to display an error if this was the default file */
 		if (prefs.default_filename && !strcmp(filename, prefs.default_filename))
-			return;
-
-		if (error) {
-			int len = strlen(translate("gettextFromC", "Failed to read '%s'")) + strlen(filename);
-			*error = malloc(len);
-			snprintf(*error, len, translate("gettextFromC", "Failed to read '%s'"), filename);
-		}
+			return 0;
 
-		return;
+		return report_error(translate("gettextFromC", "Failed to read '%s'"), filename);
 	}
 
 	fmt = strrchr(filename, '.');
 	if (fmt && (!strcasecmp(fmt + 1, "DB") || !strcasecmp(fmt + 1, "BAK"))) {
-		if (!try_to_open_db(filename, &mem, error)) {
+		if (!try_to_open_db(filename, &mem)) {
 			free(mem.buffer);
-			return;
+			return 0;
 		}
 	}
 
-	parse_file_buffer(filename, &mem, error);
+	parse_file_buffer(filename, &mem);
 	free(mem.buffer);
+	return 0;
 }
 
 #define MAXCOLDIGITS 3
 #define MAXCOLS 100
-void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, int unitidx, char **error)
+int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, int unitidx)
 {
 	struct memblock mem;
 	int pnr = 0;
@@ -417,13 +402,9 @@ void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int
 	char curdate[9];
 	char curtime[6];
 
-	if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS) {
-		int len = strlen(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d")) + MAXCOLDIGITS;
-		*error = malloc(len);
-		snprintf(*error, len, translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
+	if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS)
+		return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
 
-		return;
-	}
 	snprintf(timebuf, MAXCOLDIGITS, "%d", timef);
 	snprintf(depthbuf, MAXCOLDIGITS, "%d", depthf);
 	snprintf(tempbuf, MAXCOLDIGITS, "%d", tempf);
@@ -463,16 +444,17 @@ void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int
 	params[pnr++] = NULL;
 
 	if (filename == NULL)
-		return;
+		return report_error("No CSV filename");
 
-	if (try_to_xslt_open_csv(filename, &mem, error, csvtemplate))
-		return;
+	if (try_to_xslt_open_csv(filename, &mem, csvtemplate))
+		return -1;
 
-	parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params, error);
+	parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params);
 	free(mem.buffer);
+	return 0;
 }
 
-void parse_manual_file(const char *filename, int sepidx, int units, int numberf, int datef, int timef, int durationf, int locationf, int gpsf, int maxdepthf, int meandepthf, int buddyf, int notesf, int weightf, int tagsf, char **error)
+int parse_manual_file(const char *filename, int sepidx, int units, int numberf, int datef, int timef, int durationf, int locationf, int gpsf, int maxdepthf, int meandepthf, int buddyf, int notesf, int weightf, int tagsf)
 {
 	struct memblock mem;
 	int pnr = 0;
@@ -496,13 +478,9 @@ void parse_manual_file(const char *filename, int sepidx, int units, int numberf,
 	char curdate[9];
 	char curtime[6];
 
-	if (numberf >= MAXCOLS || datef >= MAXCOLS || timef >= MAXCOLS || durationf >= MAXCOLS || locationf >= MAXCOLS || gpsf >= MAXCOLS || maxdepthf >= MAXCOLS || meandepthf >= MAXCOLS || buddyf >= MAXCOLS || notesf >= MAXCOLS || weightf >= MAXCOLS || tagsf >= MAXCOLS) {
-		int len = strlen(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d")) + MAXCOLDIGITS;
-		*error = malloc(len);
-		snprintf(*error, len, translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
+	if (numberf >= MAXCOLS || datef >= MAXCOLS || timef >= MAXCOLS || durationf >= MAXCOLS || locationf >= MAXCOLS || gpsf >= MAXCOLS || maxdepthf >= MAXCOLS || meandepthf >= MAXCOLS || buddyf >= MAXCOLS || notesf >= MAXCOLS || weightf >= MAXCOLS || tagsf >= MAXCOLS)
+		return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
 
-		return;
-	}
 	snprintf(numberbuf, MAXCOLDIGITS, "%d", numberf);
 	snprintf(datebuf, MAXCOLDIGITS, "%d", datef);
 	snprintf(timebuf, MAXCOLDIGITS, "%d", timef);
@@ -560,11 +538,12 @@ void parse_manual_file(const char *filename, int sepidx, int units, int numberf,
 	params[pnr++] = NULL;
 
 	if (filename == NULL)
-		return;
+		return report_error("No manual CSV filename");
 
-	if (try_to_xslt_open_csv(filename, &mem, error, "manualCSV"))
-		return;
+	if (try_to_xslt_open_csv(filename, &mem, "manualCSV"))
+		return -1;
 
-	parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params, error);
+	parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params);
 	free(mem.buffer);
+	return 0;
 }
diff --git a/parse-xml.c b/parse-xml.c
index d3ff03d2c297..483187a51787 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -20,36 +20,13 @@
 int verbose, quit;
 int metric = 1;
 
-static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params, char **error);
+static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params);
 
 /* the dive table holds the overall dive list; target table points at
  * the table we are currently filling */
 struct dive_table dive_table;
 struct dive_table *target_table = NULL;
 
-static void parser_error(char **error, const char *fmt, ...)
-{
-	va_list args;
-	char *tmp;
-
-	if (!error)
-		return;
-
-	tmp = malloc(1024);
-	va_start(args, fmt);
-	vsnprintf(tmp, 1024, fmt, args);
-	va_end(args);
-
-	if (*error) {
-		int len = strlen(*error) + strlen(tmp) + 1;
-		*error = realloc(*error, len);
-		strncat(*error, tmp, strlen(tmp));
-		free(tmp);
-	} else {
-		*error = tmp;
-	}
-}
-
 /*
  * Add a dive into the dive_table array
  */
@@ -1611,7 +1588,7 @@ const char *preprocess_divelog_de(const char *buffer)
 }
 
 void parse_xml_buffer(const char *url, const char *buffer, int size,
-		      struct dive_table *table, const char **params, char **error)
+		      struct dive_table *table, const char **params)
 {
 	xmlDoc *doc;
 	const char *res = preprocess_divelog_de(buffer);
@@ -1622,13 +1599,12 @@ void parse_xml_buffer(const char *url, const char *buffer, int size,
 		free((char *)res);
 
 	if (!doc) {
-		fprintf(stderr, translate("gettextFromC", "Failed to parse '%s'.\n"), url);
-		parser_error(error, translate("gettextFromC", "Failed to parse '%s'"), url);
+		report_error(translate("gettextFromC", "Failed to parse '%s'"), url);
 		return;
 	}
 	reset_all();
 	dive_start();
-	doc = test_xslt_transforms(doc, params, error);
+	doc = test_xslt_transforms(doc, params);
 	traverse(xmlDocGetRootElement(doc));
 	dive_end();
 	xmlFreeDoc(doc);
@@ -1870,7 +1846,7 @@ extern int dm4_dive(void *param, int columns, char **data, char **column)
 }
 
 int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buffer, int size,
-		     struct dive_table *table, char **error)
+		     struct dive_table *table)
 {
 	int retval;
 	char *err = NULL;
@@ -2019,7 +1995,7 @@ extern int shearwater_dive(void *param, int columns, char **data, char **column)
 
 
 int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buffer, int size,
-			    struct dive_table *table, char **error)
+			    struct dive_table *table)
 {
 	int retval;
 	char *err = NULL;
@@ -2068,7 +2044,7 @@ static struct xslt_files {
 	  { NULL, }
   };
 
-static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params, char **error)
+static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params)
 {
 	struct xslt_files *info = xslt_files;
 	xmlDoc *transformed;
@@ -2099,7 +2075,7 @@ static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params, char **err
 		xmlSubstituteEntitiesDefault(1);
 		xslt = get_stylesheet(info->file);
 		if (xslt == NULL) {
-			parser_error(error, translate("gettextFromC", "Can't open stylesheet %s"), info->file);
+			report_error(translate("gettextFromC", "Can't open stylesheet %s"), info->file);
 			return doc;
 		}
 		transformed = xsltApplyStylesheet(xslt, doc, params);
diff --git a/planner.c b/planner.c
index 5142b0e50f28..96f3bc7e0bee 100644
--- a/planner.c
+++ b/planner.c
@@ -100,14 +100,13 @@ void get_gas_string(int o2, int he, char *text, int len)
 }
 
 /* returns the tissue tolerance at the end of this (partial) dive */
-double tissue_at_end(struct dive *dive, char **cached_datap, const char **error_string_p)
+double tissue_at_end(struct dive *dive, char **cached_datap)
 {
 	struct divecomputer *dc;
 	struct sample *sample, *psample;
 	int i, j, t0, t1, gasidx, lastdepth;
 	int o2, he;
 	double tissue_tolerance;
-	static char buf[200];
 
 	if (!dive)
 		return 0.0;
@@ -129,8 +128,7 @@ double tissue_at_end(struct dive *dive, char **cached_datap, const char **error_
 		t1 = sample->time.seconds;
 		get_gas_from_events(&dive->dc, t0, &o2, &he);
 		if ((gasidx = get_gasidx(dive, o2, he)) == -1) {
-			snprintf(buf, sizeof(buf), translate("gettextFromC", "Can't find gas %d/%d"), (o2 + 5) / 10, (he + 5) / 10);
-			*error_string_p = buf;
+			report_error(translate("gettextFromC", "Can't find gas %d/%d"), (o2 + 5) / 10, (he + 5) / 10);
 			gasidx = 0;
 		}
 		if (i > 0)
@@ -147,7 +145,7 @@ double tissue_at_end(struct dive *dive, char **cached_datap, const char **error_
 }
 
 /* how many seconds until we can ascend to the next stop? */
-static int time_at_last_depth(struct dive *dive, int o2, int he, unsigned int next_stop, char **cached_data_p, const char **error_string_p)
+static int time_at_last_depth(struct dive *dive, int o2, int he, unsigned int next_stop, char **cached_data_p)
 {
 	int depth, gasidx;
 	double surface_pressure, tissue_tolerance;
@@ -157,7 +155,7 @@ static int time_at_last_depth(struct dive *dive, int o2, int he, unsigned int ne
 	if (!dive)
 		return 0;
 	surface_pressure = dive->dc.surface_pressure.mbar / 1000.0;
-	tissue_tolerance = tissue_at_end(dive, cached_data_p, error_string_p);
+	tissue_tolerance = tissue_at_end(dive, cached_data_p);
 	sample = &dive->dc.sample[dive->dc.samples - 1];
 	depth = sample->depth.mm;
 	gasidx = get_gasidx(dive, o2, he);
@@ -223,7 +221,7 @@ static int add_gas(struct dive *dive, int o2, int he)
 	return i;
 }
 
-struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error_string)
+struct dive *create_dive_from_plan(struct diveplan *diveplan)
 {
 	struct dive *dive;
 	struct divedatapoint *dp;
@@ -233,7 +231,6 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
 	int oldpo2 = 0;
 	int lasttime = 0;
 
-	*error_string = NULL;
 	if (!diveplan || !diveplan->dp)
 		return NULL;
 #if DEBUG_PLAN & 4
@@ -321,7 +318,7 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
 
 gas_error_exit:
 	free(dive);
-	*error_string = translate("gettextFromC", "Too many gas mixes");
+	report_error(translate("gettextFromC", "Too many gas mixes"));
 	return NULL;
 }
 
@@ -587,7 +584,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive)
 }
 #endif
 
-void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, bool add_deco, const char **error_string_p)
+void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, bool add_deco)
 {
 	struct dive *dive;
 	struct sample *sample;
@@ -604,7 +601,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
 		diveplan->surface_pressure = SURFACE_PRESSURE;
 	if (*divep)
 		delete_single_dive(dive_table.nr - 1);
-	*divep = dive = create_dive_from_plan(diveplan, error_string_p);
+	*divep = dive = create_dive_from_plan(diveplan);
 	if (!dive)
 		return;
 	record_dive(dive);
@@ -623,13 +620,13 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
 		plan_add_segment(diveplan, transitiontime, 0, o2, he, po2);
 		/* re-create the dive */
 		delete_single_dive(dive_table.nr - 1);
-		*divep = dive = create_dive_from_plan(diveplan, error_string_p);
+		*divep = dive = create_dive_from_plan(diveplan);
 		if (dive)
 			record_dive(dive);
 		return;
 	}
 
-	tissue_tolerance = tissue_at_end(dive, cached_datap, error_string_p);
+	tissue_tolerance = tissue_at_end(dive, cached_datap);
 	ceiling = deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1);
 #if DEBUG_PLAN & 4
 	printf("gas %d/%d\n", o2, he);
@@ -665,7 +662,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
 		plan_add_segment(diveplan, transitiontime, stoplevels[stopidx], o2, he, po2);
 		/* re-create the dive */
 		delete_single_dive(dive_table.nr - 1);
-		*divep = dive = create_dive_from_plan(diveplan, error_string_p);
+		*divep = dive = create_dive_from_plan(diveplan);
 		if (!dive)
 			goto error_exit;
 		record_dive(dive);
@@ -686,12 +683,12 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
 #endif
 			gi--;
 		}
-		wait_time = time_at_last_depth(dive, o2, he, stoplevels[stopidx - 1], cached_datap, error_string_p);
+		wait_time = time_at_last_depth(dive, o2, he, stoplevels[stopidx - 1], cached_datap);
 		/* typically deco plans are done in one minute increments; we may want to
 		 * make this configurable at some point */
 		wait_time = ((wait_time + 59) / 60) * 60;
 #if DEBUG_PLAN & 2
-		tissue_tolerance = tissue_at_end(dive, cached_datap, error_string_p);
+		tissue_tolerance = tissue_at_end(dive, cached_datap);
 		ceiling = deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1);
 		printf("waittime %d:%02d at depth %5.2lfm; ceiling %5.2lfm\n", FRACTION(wait_time, 60),
 		       stoplevels[stopidx] / 1000.0, ceiling / 1000.0);
@@ -706,7 +703,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
 		plan_add_segment(diveplan, transitiontime, stoplevels[stopidx - 1], o2, he, po2);
 		/* re-create the dive */
 		delete_single_dive(dive_table.nr - 1);
-		*divep = dive = create_dive_from_plan(diveplan, error_string_p);
+		*divep = dive = create_dive_from_plan(diveplan);
 		if (!dive)
 			goto error_exit;
 		record_dive(dive);
diff --git a/qt-ui/divelogimportdialog.cpp b/qt-ui/divelogimportdialog.cpp
index bff49156fad1..3de08b00323d 100644
--- a/qt-ui/divelogimportdialog.cpp
+++ b/qt-ui/divelogimportdialog.cpp
@@ -54,8 +54,6 @@ DiveLogImportDialog::~DiveLogImportDialog()
 #define VALUE_IF_CHECKED(x) (ui->x->isEnabled() ? ui->x->value() - 1 : -1)
 void DiveLogImportDialog::on_buttonBox_accepted()
 {
-	char *error = NULL;
-
 	if (ui->tabWidget->currentIndex() == 0) {
 		for (int i = 0; i < fileNames.size(); ++i) {
 			parse_csv_file(fileNames[i].toUtf8().data(), ui->CSVTime->value() - 1,
@@ -65,13 +63,7 @@ void DiveLogImportDialog::on_buttonBox_accepted()
 				       VALUE_IF_CHECKED(CSVstopdepth),
 				       ui->CSVSeparator->currentIndex(),
 				       specialCSV.contains(ui->knownImports->currentIndex()) ? CSVApps[ui->knownImports->currentIndex()].name.toUtf8().data() : "csv",
-				       ui->CSVUnits->currentIndex(),
-				       &error);
-			if (error != NULL) {
-				MainWindow::instance()->showError(error);
-				free(error);
-				error = NULL;
-			}
+				       ui->CSVUnits->currentIndex());
 		}
 	} else {
 		for (int i = 0; i < fileNames.size(); ++i) {
@@ -84,13 +76,7 @@ void DiveLogImportDialog::on_buttonBox_accepted()
 					  VALUE_IF_CHECKED(Gps), VALUE_IF_CHECKED(MaxDepth),
 					  VALUE_IF_CHECKED(MeanDepth), VALUE_IF_CHECKED(Buddy),
 					  VALUE_IF_CHECKED(Notes), VALUE_IF_CHECKED(Weight),
-					  VALUE_IF_CHECKED(Tags),
-					  &error);
-			if (error != NULL) {
-				MainWindow::instance()->showError(error);
-				free(error);
-				error = NULL;
-			}
+					  VALUE_IF_CHECKED(Tags));
 		}
 	}
 	process_dives(true, false);
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp
index c5715f9df4b5..27eedb58652e 100644
--- a/qt-ui/diveplanner.cpp
+++ b/qt-ui/diveplanner.cpp
@@ -1414,7 +1414,6 @@ void DivePlannerPointsModel::createTemporaryPlan()
 	}
 	char *cache = NULL;
 	tempDive = NULL;
-	const char *errorString = NULL;
 	struct divedatapoint *dp = NULL;
 	for (int i = 0; i < MAX_CYLINDERS; i++) {
 		cylinder_t *cyl = &stagingDive->cylinder[i];
@@ -1432,7 +1431,7 @@ void DivePlannerPointsModel::createTemporaryPlan()
 #if DEBUG_PLAN
 	dump_plan(&diveplan);
 #endif
-	plan(&diveplan, &cache, &tempDive, isPlanner(), &errorString);
+	plan(&diveplan, &cache, &tempDive, isPlanner());
 	if (mode == ADD) {
 		// copy the samples and events, but don't overwrite the cylinders
 		copy_samples(tempDive, current_dive);
@@ -1468,10 +1467,9 @@ void DivePlannerPointsModel::createPlan()
 	// to not delete it later. mumble. ;p
 	char *cache = NULL;
 	tempDive = NULL;
-	const char *errorString = NULL;
 
 	createTemporaryPlan();
-	plan(&diveplan, &cache, &tempDive, isPlanner(), &errorString);
+	plan(&diveplan, &cache, &tempDive, isPlanner());
 	copy_cylinders(stagingDive, tempDive);
 	int mean[MAX_CYLINDERS], duration[MAX_CYLINDERS];
 	per_cylinder_mean_depth(tempDive, select_dc(&tempDive->dc), mean, duration);
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 44b02b1253a9..069d2f2f831a 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -105,6 +105,7 @@ MainWindow *MainWindow::instance()
 // this gets called after we download dives from a divecomputer
 void MainWindow::refreshDisplay(bool recreateDiveList)
 {
+	showError(get_error_string());
 	ui.InfoWidget->reload();
 	TankInfoModel::instance()->update();
 	ui.globe->reload();
@@ -973,15 +974,10 @@ void MainWindow::importFiles(const QStringList fileNames)
 		return;
 
 	QByteArray fileNamePtr;
-	char *error = NULL;
+
 	for (int i = 0; i < fileNames.size(); ++i) {
 		fileNamePtr = QFile::encodeName(fileNames.at(i));
-		parse_file(fileNamePtr.data(), &error);
-		if (error != NULL) {
-			showError(error);
-			free(error);
-			error = NULL;
-		}
+		parse_file(fileNamePtr.data());
 	}
 	process_dives(true, false);
 	refreshDisplay();
@@ -992,21 +988,19 @@ void MainWindow::loadFiles(const QStringList fileNames)
 	if (fileNames.isEmpty())
 		return;
 
-	char *error = NULL;
 	QByteArray fileNamePtr;
 	QStringList failedParses;
 
 	for (int i = 0; i < fileNames.size(); ++i) {
-		fileNamePtr = QFile::encodeName(fileNames.at(i));
-		parse_file(fileNamePtr.data(), &error);
-		set_filename(fileNamePtr.data(), true);
-		setTitle(MWTF_FILENAME);
+		int error;
 
-		if (error != NULL) {
+		fileNamePtr = QFile::encodeName(fileNames.at(i));
+		error = parse_file(fileNamePtr.data());
+		if (!error) {
+			set_filename(fileNamePtr.data(), true);
+			setTitle(MWTF_FILENAME);
+		} else {
 			failedParses.append(fileNames.at(i));
-			showError(error);
-			free(error);
-			error = NULL;
 		}
 	}
 
diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp
index 93b452475e47..707746573bcf 100644
--- a/qt-ui/subsurfacewebservices.cpp
+++ b/qt-ui/subsurfacewebservices.cpp
@@ -103,11 +103,11 @@ static void clear_table(struct dive_table *table)
 	table->nr = 0;
 }
 
-bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile, const bool selected, QString *errorMsg)
+bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile, const bool selected)
 {
 	static const char errPrefix[] = "divelog.de-upload:";
 	if (!amount_selected) {
-		*errorMsg = tr("no dives were selected");
+		report_error(tr("no dives were selected").toUtf8());
 		return false;
 	}
 
@@ -126,8 +126,7 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
 	if (!zip) {
 		char buffer[1024];
 		zip_error_to_str(buffer, sizeof buffer, error_code, errno);
-		*errorMsg = tr("failed to create zip file for upload: %1")
-				.arg(QString::fromLocal8Bit(buffer));
+		report_error(tr("failed to create zip file for upload: %s").toUtf8(), buffer);
 		return false;
 	}
 
@@ -151,7 +150,7 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
 			continue;
 		f = tmpfile();
 		if (!f) {
-			*errorMsg = tr("cannot create temporary file: %1").arg(qt_error_string());
+			report_error(tr("cannot create temporary file: %s").toUtf8(), qt_error_string().toUtf8().data());
 			goto error_close_zip;
 		}
 		save_dive(f, dive);
@@ -161,7 +160,7 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
 
 		membuf = (char *)malloc(streamsize + 1);
 		if (!membuf || (streamsize = fread(membuf, streamsize, 1, f)) == 0) {
-			*errorMsg = tr("internal error: %1").arg(qt_error_string());
+			report_error(tr("internal error: %s").toUtf8(), qt_error_string().toUtf8().data());
 			fclose(f);
 			free((void *)membuf);
 			goto error_close_zip;
@@ -177,7 +176,7 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
 		xmlDoc *doc = xmlReadMemory(membuf, streamsize, "divelog", NULL, 0);
 		if (!doc) {
 			qWarning() << errPrefix << "could not parse back into memory the XML file we've just created!";
-			*errorMsg = tr("internal error");
+			report_error(tr("internal error").toUtf8());
 			free((void *)membuf);
 			goto error_close_zip;
 		}
@@ -328,7 +327,7 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton *button)
 	case QDialogButtonBox::ApplyRole: {
 		clear_table(&gps_location_table);
 		QByteArray url = tr("Webservice").toLocal8Bit();
-		parse_xml_buffer(url.data(), downloadedData.data(), downloadedData.length(), &gps_location_table, NULL, NULL);
+		parse_xml_buffer(url.data(), downloadedData.data(), downloadedData.length(), &gps_location_table, NULL);
 
 		/* now merge the data in the gps_location table into the dive_table */
 		if (merge_locations_into_dives()) {
@@ -580,11 +579,9 @@ void DivelogsDeWebServices::downloadDives()
 
 void DivelogsDeWebServices::prepareDivesForUpload()
 {
-	QString errorText;
-
 	/* generate a random filename and create/open that file with zip_open */
 	QString filename = QDir::tempPath() + "/import-" + QString::number(qrand() % 99999999) + ".dld";
-	if (prepare_dives_for_divelogs(filename, true, &errorText)) {
+	if (prepare_dives_for_divelogs(filename, true)) {
 		QFile f(filename);
 		if (f.open(QIODevice::ReadOnly)) {
 			uploadDives((QIODevice *)&f);
@@ -593,7 +590,7 @@ void DivelogsDeWebServices::prepareDivesForUpload()
 			return;
 		}
 	}
-	MainWindow::instance()->showError(errorText);
+	MainWindow::instance()->showError(get_error_string());
 }
 
 void DivelogsDeWebServices::uploadDives(QIODevice *dldContent)
@@ -861,12 +858,7 @@ void DivelogsDeWebServices::buttonClicked(QAbstractButton *button)
 			break;
 		}
 		/* parse file and import dives */
-		char *error = NULL;
-		parse_file(QFile::encodeName(zipFile.fileName()), &error);
-		if (error != NULL) {
-			MainWindow::instance()->showError(error);
-			free(error);
-		}
+		parse_file(QFile::encodeName(zipFile.fileName()));
 		process_dives(true, false);
 		MainWindow::instance()->refreshDisplay();
 
diff --git a/qt-ui/subsurfacewebservices.h b/qt-ui/subsurfacewebservices.h
index 872cf377d4ff..175c991090ef 100644
--- a/qt-ui/subsurfacewebservices.h
+++ b/qt-ui/subsurfacewebservices.h
@@ -89,7 +89,7 @@ private:
 	void uploadDives(QIODevice *dldContent);
 	explicit DivelogsDeWebServices(QWidget *parent = 0, Qt::WindowFlags f = 0);
 	void setStatusText(int status);
-	bool prepare_dives_for_divelogs(const QString &filename, bool selected, QString *errorMsg);
+	bool prepare_dives_for_divelogs(const QString &filename, bool selected);
 	void download_dialog_traverse_xml(xmlNodePtr node, unsigned int *download_status);
 	unsigned int download_dialog_parse_response(const QByteArray &length);
 
-- 
1.9.0



More information about the subsurface mailing list