diff --git a/core/cloudstorage.cpp b/core/cloudstorage.cpp
index d68b530d6..38c7cab0d 100644
--- a/core/cloudstorage.cpp
+++ b/core/cloudstorage.cpp
@@ -97,7 +97,7 @@ void CloudStorageAuthenticate::uploadFinished()
} else if (cloudAuthReply == QLatin1String("[VERIFY]") ||
cloudAuthReply == QLatin1String("Invalid PIN")) {
qPrefCloudStorage::set_cloud_verification_status(qPrefCloudStorage::CS_NEED_TO_VERIFY);
- report_error(qPrintable(tr("Cloud account verification required, enter PIN in preferences")));
+ report_error("%s", qPrintable(tr("Cloud account verification required, enter PIN in preferences")));
} else if (cloudAuthReply == QLatin1String("[PASSWDCHANGED]")) {
qPrefCloudStorage::set_cloud_storage_password(cloudNewPassword);
cloudNewPassword.clear();
diff --git a/core/configuredivecomputer.cpp b/core/configuredivecomputer.cpp
index e6dc31e6b..be5507768 100644
--- a/core/configuredivecomputer.cpp
+++ b/core/configuredivecomputer.cpp
@@ -594,7 +594,7 @@ QString ConfigureDiveComputer::dc_open(device_data_t *data)
rc = divecomputer_device_open(data);
if (rc != DC_STATUS_SUCCESS) {
- report_error(errmsg(rc));
+ report_error("%s", errmsg(rc));
} else {
rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream);
}
diff --git a/core/datatrak.cpp b/core/datatrak.cpp
index 8bc214168..72d49cb89 100644
--- a/core/datatrak.cpp
+++ b/core/datatrak.cpp
@@ -688,7 +688,7 @@ int datatrak_import(std::string &mem, std::string &wl_mem, struct divelog *log)
// Verify fileheader, get number of dives in datatrak divelog, zero on error
numdives = read_file_header((unsigned char *)mem.data());
if (!numdives) {
- report_error(translate("gettextFromC", "[Error] File is not a DataTrak file. Aborted"));
+ report_error("%s", translate("gettextFromC", "[Error] File is not a DataTrak file. Aborted"));
goto bail;
}
// Verify WLog .add file, Beginning sequence and NÂș dives
@@ -711,7 +711,7 @@ int datatrak_import(std::string &mem, std::string &wl_mem, struct divelog *log)
if (!wl_mem.empty())
wlog_compl_parser(wl_mem, ptdive, i);
if (runner == NULL) {
- report_error(translate("gettextFromC", "Error: no dive"));
+ report_error("%s", translate("gettextFromC", "Error: no dive"));
free(ptdive);
rc = 1;
goto out;
diff --git a/core/divelogexportlogic.cpp b/core/divelogexportlogic.cpp
index c487a3446..06690e4d2 100644
--- a/core/divelogexportlogic.cpp
+++ b/core/divelogexportlogic.cpp
@@ -149,7 +149,7 @@ void exportHtmlInitLogic(const QString &filename, struct htmlExportSetting &hes)
QString searchPath = getSubsurfaceDataPath("theme");
if (searchPath.isEmpty()) {
- report_error(qPrintable(gettextFromC::tr("Cannot find a folder called 'theme' in the standard locations")));
+ report_error("%s", qPrintable(gettextFromC::tr("Cannot find a folder called 'theme' in the standard locations")));
return;
}
diff --git a/core/errorhelper.h b/core/errorhelper.h
index 179afdd23..7db677ab4 100644
--- a/core/errorhelper.h
+++ b/core/errorhelper.h
@@ -8,9 +8,15 @@
extern "C" {
#endif
+#ifdef __GNUC__
+#define __printf(x, y) __attribute__((__format__(__printf__, x, y)))
+#else
+#define __printf(x, y)
+#endif
+
extern int verbose;
-extern int report_error(const char *fmt, ...);
-extern void report_info(const char *fmt, ...);
+extern int __printf(1, 2) report_error(const char *fmt, ...);
+extern void __printf(1, 2) report_info(const char *fmt, ...);
extern void set_error_cb(void(*cb)(char *)); // Callback takes ownership of passed string
#define SSRF_INFO(fmt, ...) report_info(fmt, ##__VA_ARGS__)
diff --git a/core/git-access.cpp b/core/git-access.cpp
index 2c957610d..c45be6e41 100644
--- a/core/git-access.cpp
+++ b/core/git-access.cpp
@@ -191,7 +191,7 @@ static int reset_to_remote(struct git_info *info, git_reference *local, const gi
if (git_reference_set_target(&out, local, new_id, "Update to remote")) {
SSRF_INFO("git storage: could not update local cache to newer remote data");
- return report_error(translate("gettextFromC", "Could not update local cache to newer remote data"));
+ return report_error("%s", translate("gettextFromC", "Could not update local cache to newer remote data"));
}
git_reference_free(out);
@@ -205,7 +205,7 @@ static int reset_to_remote(struct git_info *info, git_reference *local, const gi
if (git_object_lookup(&target, info->repo, new_id, GIT_OBJ_COMMIT)) {
SSRF_INFO("git storage: could not look up remote commit");
if (info->is_subsurface_cloud)
- return report_error(translate("gettextFromC", "Subsurface cloud storage corrupted"));
+ return report_error("%s", translate("gettextFromC", "Subsurface cloud storage corrupted"));
else
return report_error("Could not look up remote commit");
}
@@ -213,7 +213,7 @@ static int reset_to_remote(struct git_info *info, git_reference *local, const gi
if (git_reset(info->repo, target, GIT_RESET_HARD, &opts)) {
SSRF_INFO("git storage: local head checkout failed after update");
if (info->is_subsurface_cloud)
- return report_error(translate("gettextFromC", "Could not update local cache to newer remote data"));
+ return report_error("%s", translate("gettextFromC", "Could not update local cache to newer remote data"));
else
return report_error("Local head checkout failed after update");
}
@@ -331,7 +331,7 @@ static int update_remote(struct git_info *info, git_remote *origin, git_referenc
const char *msg = giterr_last()->message;
SSRF_INFO("git storage: unable to update remote with current local cache state, error: %s", msg);
if (info->is_subsurface_cloud)
- return report_error(translate("gettextFromC", "Could not update Subsurface cloud storage, try again later"));
+ return report_error("%s", translate("gettextFromC", "Could not update Subsurface cloud storage, try again later"));
else
return report_error("Unable to update remote with current local cache state (%s)", msg);
}
@@ -417,7 +417,7 @@ static int try_to_git_merge(struct git_info *info, git_reference **local_p, git_
}
git_index_conflict_cleanup(merged_index);
git_index_conflict_iterator_free(iter);
- report_error(translate("gettextFromC", "Remote storage and local data diverged. Cannot combine local and remote changes"));
+ report_error("%s", translate("gettextFromC", "Remote storage and local data diverged. Cannot combine local and remote changes"));
}
{
git_oid merge_oid, commit_oid;
@@ -455,7 +455,7 @@ static int try_to_git_merge(struct git_info *info, git_reference **local_p, git_
}
diverged_error:
- return report_error(translate("gettextFromC", "Remote storage and local data diverged"));
+ return report_error("%s", translate("gettextFromC", "Remote storage and local data diverged"));
write_error:
free_buffer(&msg);
@@ -469,7 +469,7 @@ static int cleanup_local_cache(struct git_info *info)
{
char *backup_path = move_local_cache(info);
SSRF_INFO("git storage: problems with local cache, moved to %s", backup_path);
- report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
+ report_error("%s", translate("gettextFromC", "Problems with local cache of Subsurface cloud data"));
report_error(translate("gettextFromC", "Moved cache data to %s. Please try the operation again."), backup_path);
free(backup_path);
return -1;
@@ -884,7 +884,7 @@ static bool create_local_repo(struct git_info *info)
error = 0;
#if !defined(DEBUG) && !defined(SUBSURFACE_MOBILE)
} else if (info->is_subsurface_cloud) {
- report_error(translate("gettextFromC", "Error connecting to Subsurface cloud storage"));
+ report_error("%s", translate("gettextFromC", "Error connecting to Subsurface cloud storage"));
#endif
} else {
report_error(translate("gettextFromC", "git clone of %s failed (%s)"), info->url, msg);
diff --git a/core/libdivecomputer.cpp b/core/libdivecomputer.cpp
index 2ad891aec..9bff5b51e 100644
--- a/core/libdivecomputer.cpp
+++ b/core/libdivecomputer.cpp
@@ -1500,7 +1500,7 @@ const char *do_libdivecomputer_import(device_data_t *data)
rc = divecomputer_device_open(data);
if (rc != DC_STATUS_SUCCESS) {
- report_error(errmsg(rc));
+ report_error("%s", errmsg(rc));
} else {
dev_info(data, "Connecting ...");
rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream);
diff --git a/core/uploadDiveLogsDE.cpp b/core/uploadDiveLogsDE.cpp
index 1ace74da2..2f103223f 100644
--- a/core/uploadDiveLogsDE.cpp
+++ b/core/uploadDiveLogsDE.cpp
@@ -73,7 +73,7 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
xslt = get_stylesheet("divelogs-export.xslt");
if (!xslt) {
qDebug() << errPrefix << "missing stylesheet";
- report_error(tr("Stylesheet to export to divelogs.de is not found").toUtf8());
+ report_error("%s", qPrintable(tr("Stylesheet to export to divelogs.de is not found")));
return false;
}
@@ -83,7 +83,7 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
if (!zip) {
char buffer[1024];
zip_error_to_str(buffer, sizeof buffer, error_code, errno);
- report_error(tr("Failed to create zip file for upload: %s").toUtf8(), buffer);
+ report_error(qPrintable(tr("Failed to create zip file for upload: %s")), buffer);
return false;
}
@@ -144,7 +144,7 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
xmlDoc *doc = xmlReadMemory(mb.buffer, mb.len, "divelog", NULL, XML_PARSE_HUGE | XML_PARSE_RECOVER);
if (!doc) {
qWarning() << errPrefix << "could not parse back into memory the XML file we've just created!";
- report_error(tr("internal error").toUtf8());
+ report_error("%s", qPrintable(tr("internal error")));
zip_close(zip);
QFile::remove(tempfile);
xsltFreeStylesheet(xslt);
@@ -157,7 +157,7 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
free_xml_params(params);
if (!transformed) {
qWarning() << errPrefix << "XSLT transform failed for dive: " << i;
- report_error(tr("Conversion of dive %1 to divelogs.de format failed").arg(i).toUtf8());
+ report_error("%s", qPrintable(tr("Conversion of dive %1 to divelogs.de format failed").arg(i)));
continue;
}
xmlDocDumpMemory(transformed, (xmlChar **)&membuf, &streamsize);
@@ -310,7 +310,7 @@ void uploadDiveLogsDE::uploadFinishedSlot()
if (parsed) {
if (strstr(resp, "succeeded")) {
if (strstr(resp, "failed")) {
- report_error(tr("Upload failed").toUtf8());
+ report_error("%s", qPrintable(tr("Upload failed")));
return;
}
timeout.stop();
@@ -320,13 +320,13 @@ void uploadDiveLogsDE::uploadFinishedSlot()
}
timeout.stop();
err = tr("Login failed");
- report_error(err.toUtf8());
+ report_error("%s", qPrintable(err));
emit uploadFinish(false, err);
return;
}
timeout.stop();
err = tr("Cannot parse response");
- report_error(tr("Cannot parse response").toUtf8());
+ report_error("%s", qPrintable(tr("Cannot parse response")));
emit uploadFinish(false, err);
}
}
@@ -341,7 +341,7 @@ void uploadDiveLogsDE::uploadTimeoutSlot()
}
cleanupTempFile();
QString err(tr("divelogs.de not responding"));
- report_error(err.toUtf8());
+ report_error("%s", qPrintable(err));
emit uploadFinish(false, err);
}
@@ -355,6 +355,6 @@ void uploadDiveLogsDE::uploadErrorSlot(QNetworkReply::NetworkError error)
}
cleanupTempFile();
QString err(tr("network error %1").arg(error));
- report_error(err.toUtf8());
+ report_error("%s", qPrintable(err));
emit uploadFinish(false, err);
}
diff --git a/core/uploadDiveShare.cpp b/core/uploadDiveShare.cpp
index f1b94b097..329cce9a1 100644
--- a/core/uploadDiveShare.cpp
+++ b/core/uploadDiveShare.cpp
@@ -100,7 +100,7 @@ void uploadDiveShare::uploadTimeoutSlot()
reply = NULL;
}
QString err(tr("dive-share.com not responding"));
- report_error(err.toUtf8());
+ report_error("%s", qPrintable(err));
emit uploadFinish(false, err, QByteArray());
}
@@ -113,6 +113,6 @@ void uploadDiveShare::uploadErrorSlot(QNetworkReply::NetworkError error)
reply = NULL;
}
QString err(tr("network error %1").arg(error));
- report_error(err.toUtf8());
+ report_error("%s", qPrintable(err));
emit uploadFinish(false, err, QByteArray());
}
diff --git a/core/videoframeextractor.cpp b/core/videoframeextractor.cpp
index 9cf564afd..d377a7fc9 100644
--- a/core/videoframeextractor.cpp
+++ b/core/videoframeextractor.cpp
@@ -90,11 +90,11 @@ void VideoFrameExtractor::processItem(QString originalFilename, QString filename
// Since we couldn't sart ffmpeg, turn off thumbnailing
// TODO: call the proper preferences-functions
prefs.extract_video_thumbnails = false;
- report_error(qPrintable(tr("ffmpeg failed to start - video thumbnail creation suspended. To enable video thumbnailing, set working executable in preferences.")));
+ report_error("%s", qPrintable(tr("ffmpeg failed to start - video thumbnail creation suspended. To enable video thumbnailing, set working executable in preferences.")));
return fail(originalFilename, duration, false);
}
if (!ffmpeg.waitForFinished()) {
- report_error(qPrintable(tr("Failed waiting for ffmpeg - video thumbnail creation suspended. To enable video thumbnailing, set working executable in preferences.")));
+ report_error("%s", qPrintable(tr("Failed waiting for ffmpeg - video thumbnail creation suspended. To enable video thumbnailing, set working executable in preferences.")));
return fail(originalFilename, duration, false);
}
diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp
index 328df5c88..5d71df8b0 100644
--- a/desktop-widgets/divelistview.cpp
+++ b/desktop-widgets/divelistview.cpp
@@ -884,7 +884,7 @@ void DiveListView::loadImagesFromURLs(const QString &urls)
if (image.isNull()) {
// If this is not an image, maybe it's an html file and Miika can provide some xslr magic to extract images.
// In this case we would call the function recursively on the list of image source urls;
- report_error(qPrintable(tr("%1 does not appear to be an image").arg(url.toString())));
+ report_error("%s", qPrintable(tr("%1 does not appear to be an image").arg(url.toString())));
return;
}
diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp
index 5a57000d4..8a0b422d4 100644
--- a/desktop-widgets/mainwindow.cpp
+++ b/desktop-widgets/mainwindow.cpp
@@ -427,7 +427,7 @@ void MainWindow::on_actionCloudstorageopen_triggered()
static bool saveToCloudOK()
{
if (!divelog.dives->nr) {
- report_error(qPrintable(gettextFromC::tr("Don't save an empty log to the cloud")));
+ report_error("%s", qPrintable(gettextFromC::tr("Don't save an empty log to the cloud")));
return false;
}
return true;
@@ -486,7 +486,7 @@ void MainWindow::on_actionCloudOnline_triggered()
on_actionCloudstorageopen_triggered();
}
if (git_local_only)
- report_error(qPrintable(tr("Failure taking cloud storage online")));
+ report_error("%s", qPrintable(tr("Failure taking cloud storage online")));
}
setTitle();
diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp
index f051f06d7..b3a9e30ac 100644
--- a/profile-widget/profilewidget2.cpp
+++ b/profile-widget/profilewidget2.cpp
@@ -242,7 +242,7 @@ void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, int flags)
qDebug() << "Profile calculation for dive " << d->number << "took" << elapsedTime << "ms" << " -- calculated ceiling preference is" << prefs.calcceiling;
if (elapsedTime > 1000 && prefs.calcndltts) {
qPrefTechnicalDetails::set_calcndltts(false);
- report_error(qPrintable(tr("Show NDL / TTS was disabled because of excessive processing time")));
+ report_error("%s", qPrintable(tr("Show NDL / TTS was disabled because of excessive processing time")));
}
}