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"))); } }