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:
Berthold Stoeger 2024-06-08 23:32:17 +02:00 committed by bstoeger
parent 71f3189a31
commit d05e289507
8 changed files with 40 additions and 74 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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 {

View file

@ -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!

View file

@ -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)));

View file

@ -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) :