mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: use std::string in error_callback
No naked free(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
71f3189a31
commit
d05e289507
8 changed files with 40 additions and 74 deletions
|
@ -1,50 +1,44 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifdef __clang__
|
||||
// Clang has a bug on zero-initialization of C structs.
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include "errorhelper.h"
|
||||
#include "membuffer.h"
|
||||
#include "format.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(__ANDROID__)
|
||||
#define LOG_MSG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||
#define LOG_MSG(fmt, s) fprintf(stderr, fmt, s)
|
||||
#else
|
||||
#include <android/log.h>
|
||||
#define LOG_MSG(fmt, ...) __android_log_print(ANDROID_LOG_INFO, "Subsurface", fmt, ##__VA_ARGS__);
|
||||
#define LOG_MSG(fmt, s) __android_log_print(ANDROID_LOG_INFO, "Subsurface", fmt, s);
|
||||
#endif
|
||||
|
||||
#define VA_BUF(b, fmt) do { va_list args; va_start(args, fmt); put_vformat(b, fmt, args); va_end(args); } while (0)
|
||||
|
||||
int verbose;
|
||||
|
||||
void report_info(const char *fmt, ...)
|
||||
{
|
||||
membuffer buf;
|
||||
|
||||
VA_BUF(&buf, fmt);
|
||||
strip_mb(&buf);
|
||||
LOG_MSG("INFO: %s\n", mb_cstring(&buf));
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::string s = vformat_string_std(fmt, args);
|
||||
va_end(args);
|
||||
LOG_MSG("INFO: %s\n", s.c_str());
|
||||
}
|
||||
|
||||
static void (*error_cb)(char *) = NULL;
|
||||
static void (*error_cb)(std::string) = NULL;
|
||||
|
||||
int report_error(const char *fmt, ...)
|
||||
{
|
||||
membuffer buf;
|
||||
|
||||
VA_BUF(&buf, fmt);
|
||||
strip_mb(&buf);
|
||||
LOG_MSG("ERROR: %s\n", mb_cstring(&buf));
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::string s = vformat_string_std(fmt, args);
|
||||
va_end(args);
|
||||
LOG_MSG("ERROR: %s\n", s.c_str());
|
||||
|
||||
/* if there is no error callback registered, don't produce errors */
|
||||
if (!error_cb)
|
||||
return -1;
|
||||
error_cb(detach_cstring(&buf));
|
||||
if (error_cb)
|
||||
error_cb(std::move(s));
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_error_cb(void(*cb)(char *))
|
||||
void set_error_cb(void(*cb)(std::string))
|
||||
{
|
||||
error_cb = cb;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
// error reporting functions
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define __printf(x, y) __attribute__((__format__(__printf__, x, y)))
|
||||
#else
|
||||
|
@ -13,6 +15,6 @@
|
|||
extern int verbose;
|
||||
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
|
||||
extern void set_error_cb(void(*cb)(std::string s)); // Callback takes ownership of passed string
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,35 +18,17 @@ membuffer::membuffer()
|
|||
|
||||
membuffer::~membuffer()
|
||||
{
|
||||
free_buffer(this);
|
||||
}
|
||||
|
||||
/* Only for internal use */
|
||||
static char *detach_buffer(struct membuffer *b)
|
||||
{
|
||||
char *result = b->buffer;
|
||||
b->buffer = NULL;
|
||||
b->len = 0;
|
||||
b->alloc = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *detach_cstring(struct membuffer *b)
|
||||
{
|
||||
mb_cstring(b);
|
||||
return detach_buffer(b);
|
||||
}
|
||||
|
||||
void free_buffer(struct membuffer *b)
|
||||
{
|
||||
free(detach_buffer(b));
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void flush_buffer(struct membuffer *b, FILE *f)
|
||||
{
|
||||
if (b->len) {
|
||||
fwrite(b->buffer, 1, b->len, f);
|
||||
free_buffer(b);
|
||||
free(b->buffer);
|
||||
b->buffer = NULL;
|
||||
b->len = 0;
|
||||
b->alloc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
*
|
||||
* "something, something else"
|
||||
*
|
||||
* Unless ownership to the buffer is given away by using "detach_cstring()":
|
||||
*
|
||||
* ptr = detach_cstring();
|
||||
*
|
||||
* where the caller now has a C string and is supposed to free it.
|
||||
*/
|
||||
#ifndef MEMBUFFER_H
|
||||
|
@ -46,8 +42,6 @@ struct membuffer {
|
|||
#define __printf(x, y)
|
||||
#endif
|
||||
|
||||
extern char *detach_cstring(struct membuffer *b);
|
||||
extern void free_buffer(struct membuffer *);
|
||||
extern void make_room(struct membuffer *b, unsigned int size);
|
||||
extern void flush_buffer(struct membuffer *, FILE *);
|
||||
extern void put_bytes(struct membuffer *, const char *, int);
|
||||
|
|
|
@ -440,12 +440,11 @@ void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked()
|
|||
// this breaks an "else if" across lines... not happy...
|
||||
#endif
|
||||
if (data->vendor() == "Uemis") {
|
||||
char *colon;
|
||||
char *devname = copy_qstring(ui.device->currentText());
|
||||
|
||||
if ((colon = strstr(devname, ":\\ (UEMISSDA)")) != NULL) {
|
||||
*(colon + 2) = '\0';
|
||||
report_info("shortened devname to \"%s\"", devname);
|
||||
QString devname = ui.device->currentText();
|
||||
auto colon = devname.indexOf(":\\ (UEMISSDA)");
|
||||
if (colon >= 0) {
|
||||
devname.resize(colon + 2);
|
||||
report_info("shortened devname to \"%s\"", qPrintable(devname));
|
||||
}
|
||||
data->setDevName(devname);
|
||||
} else {
|
||||
|
|
|
@ -107,11 +107,9 @@ int updateProgress(const char *text)
|
|||
|
||||
MainWindow *MainWindow::m_Instance = nullptr;
|
||||
|
||||
void showErrorFromC(char *buf)
|
||||
static void showError(std::string err)
|
||||
{
|
||||
QString error(buf);
|
||||
free(buf);
|
||||
emit MainWindow::instance()->showError(error);
|
||||
emit MainWindow::instance()->showError(QString::fromStdString(err));
|
||||
}
|
||||
|
||||
MainWindow::MainWindow() :
|
||||
|
@ -242,7 +240,7 @@ MainWindow::MainWindow() :
|
|||
|
||||
setupSocialNetworkMenu();
|
||||
set_git_update_cb(&updateProgress);
|
||||
set_error_cb(&showErrorFromC);
|
||||
set_error_cb(&::showError);
|
||||
|
||||
// full screen support is buggy on Windows and Ubuntu.
|
||||
// require the FULLSCREEN_SUPPORT macro to enable it!
|
||||
|
|
|
@ -66,10 +66,9 @@ bool noCloudToCloud = false;
|
|||
#define RED_FONT QLatin1String("<font color=\"red\">")
|
||||
#define END_FONT QLatin1String("</font>")
|
||||
|
||||
void showErrorFromC(char *buf)
|
||||
static void showError(std::string s)
|
||||
{
|
||||
QString error(buf);
|
||||
free(buf);
|
||||
QString error = QString::fromStdString(s);
|
||||
// By using invokeMethod with Qt:AutoConnection, the error string is safely
|
||||
// transported across thread boundaries, if not called from the UI thread.
|
||||
QMetaObject::invokeMethod(QMLManager::instance(), "registerError", Qt::AutoConnection, Q_ARG(QString, error));
|
||||
|
@ -271,7 +270,7 @@ QMLManager::QMLManager() :
|
|||
appendTextToLog("No writeable location found, in-memory log only and no libdivecomputer log");
|
||||
}
|
||||
#endif
|
||||
set_error_cb(&showErrorFromC);
|
||||
set_error_cb(&showError);
|
||||
uiNotificationCallback = showProgress;
|
||||
appendTextToLog("Starting " + getUserAgent());
|
||||
appendTextToLog(QStringLiteral("built with libdivecomputer v%1").arg(dc_version(NULL)));
|
||||
|
|
|
@ -15,11 +15,9 @@ QStringList inputFiles;
|
|||
QString outputFile;
|
||||
QString error_buf;
|
||||
|
||||
void getErrorFromC(char *buf)
|
||||
void getErrorFromC(std::string buf)
|
||||
{
|
||||
QString error(buf);
|
||||
free(buf);
|
||||
error_buf = error;
|
||||
error_buf = QString::fromStdString(std::move(buf));
|
||||
}
|
||||
|
||||
Smrtk2ssrfcWindow::Smrtk2ssrfcWindow(QWidget *parent) :
|
||||
|
|
Loading…
Add table
Reference in a new issue