Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
debug.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011 Bruce Guenter.
4 Copyright (C) 2011 Henrik Andersson.
5 Copyright (C) 2011 johannes hanika.
6 Copyright (C) 2011, 2014, 2016-2017 Tobias Ellinghaus.
7 Copyright (C) 2012 Richard Wonka.
8 Copyright (C) 2016 Roman Lebedev.
9 Copyright (C) 2018 Mario Lueder.
10 Copyright (C) 2020 Pascal Obry.
11 Copyright (C) 2022, 2026 Aurélien PIERRE.
12 Copyright (C) 2022 Martin Bařinka.
13 Copyright (C) 2023, 2025 Alynx Zhou.
14
15 darktable is free software: you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 darktable is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with darktable. If not, see <http://www.gnu.org/licenses/>.
27*/
28
29#pragma once
30
31#include <sqlite3.h>
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37// define this to see all sql queries passed to prepare and exec at compile time, or a variable name
38// warning:
39// there are some direct calls to sqlite3_exec and sqlite3_prepare_v2 which are missing here. grep manually.
40// #define DEBUG_SQL_QUERIES
41
42#ifdef DEBUG_SQL_QUERIES
43 #define __STRINGIFY(TEXT) #TEXT
44 #define MESSAGE(VALUE) __STRINGIFY(message __STRINGIFY(SQLDEBUG: VALUE))
45 #define __DT_DEBUG_SQL_QUERY__(value) _Pragma(MESSAGE(value))
46#else
47 #define __DT_DEBUG_SQL_QUERY__(value)
48#endif
49
50
51#ifdef _DEBUG
52#include <assert.h>
53#define __DT_DEBUG_ASSERT__(xin) \
54 { \
55 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
56 if(x != SQLITE_OK) \
57 { \
58 fprintf(stderr, "sqlite3 error: %s:%d, function %s(): %s\n", __FILE__, __LINE__, __FUNCTION__, \
59 sqlite3_errmsg(dt_database_get(darktable.db))); \
60 } \
61 assert(x == SQLITE_OK); \
62 _Pragma("GCC diagnostic pop") \
63 }
64#define __DT_DEBUG_ASSERT_WITH_QUERY__(xin, query) \
65 { \
66 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
67 if(x != SQLITE_OK) \
68 { \
69 fprintf(stderr, "sqlite3 error: %s:%d, function %s(), query \"%s\": %s\n", __FILE__, __LINE__, __FUNCTION__,\
70 (query), sqlite3_errmsg(dt_database_get(darktable.db))); \
71 } \
72 assert(x == SQLITE_OK); \
73 _Pragma("GCC diagnostic pop") \
74 }
75#else
76#define __DT_DEBUG_ASSERT__(xin) \
77 { \
78 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
79 if(x != SQLITE_OK) \
80 { \
81 fprintf(stderr, "sqlite3 error: %s:%d, function %s(): %s\n", __FILE__, __LINE__, __FUNCTION__, \
82 sqlite3_errmsg(dt_database_get(darktable.db))); \
83 } \
84 _Pragma("GCC diagnostic pop") \
85 }
86#define __DT_DEBUG_ASSERT_WITH_QUERY__(xin, query) \
87 { \
88 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
89 if(x != SQLITE_OK) \
90 { \
91 fprintf(stderr, "sqlite3 error: %s:%d, function %s(), query \"%s\": %s\n", __FILE__, __LINE__, __FUNCTION__,\
92 (query), sqlite3_errmsg(dt_database_get(darktable.db))); \
93 } \
94 _Pragma("GCC diagnostic pop") \
95 }
96
97#endif
98
99#define DT_DEBUG_SQLITE3_EXEC(a, b, c, d, e) \
100 do \
101 { \
102 dt_print(DT_DEBUG_SQL, "[sql] %s:%d, function %s(): exec \"%s\"\n", __FILE__, __LINE__, __FUNCTION__, (b)); \
103 __DT_DEBUG_ASSERT_WITH_QUERY__(sqlite3_exec(a, b, c, d, e), (b)); \
104 __DT_DEBUG_SQL_QUERY__(b) \
105 } while(0)
106
107#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e) \
108 do \
109 { \
110 dt_print(DT_DEBUG_SQL, "[sql] %s:%d, function %s(): prepare \"%s\"\n", __FILE__, __LINE__, __FUNCTION__, (b));\
111 __DT_DEBUG_ASSERT_WITH_QUERY__(sqlite3_prepare_v2(a, b, c, d, e), (b)); \
112 __DT_DEBUG_SQL_QUERY__(b) \
113 } while(0)
114
115#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_int(a, b, c))
116#define DT_DEBUG_SQLITE3_BIND_INT64(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_int64(a, b, c))
117#define DT_DEBUG_SQLITE3_BIND_DOUBLE(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_double(a, b, c))
118#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e) __DT_DEBUG_ASSERT__(sqlite3_bind_text(a, b, c, d, e))
119#define DT_DEBUG_SQLITE3_BIND_BLOB(a, b, c, d, e) __DT_DEBUG_ASSERT__(sqlite3_bind_blob(a, b, c, d, e))
120#define DT_DEBUG_SQLITE3_CLEAR_BINDINGS(a) __DT_DEBUG_ASSERT__(sqlite3_clear_bindings(a))
121#define DT_DEBUG_SQLITE3_RESET(a) __DT_DEBUG_ASSERT__(sqlite3_reset(a))
122
123// Use this to re-define a function to trace it, so you don't need to modify all
124// callers. `thread` should be `dt_debug_thread_t`. This requires verbose mode.
125//
126// Example:
127// void dt_dev_pixelpipe_update_history_main_real(dt_develop_t *dev);
128// #define dt_dev_pixelpipe_update_history_main(dev) DT_DEBUG_TRACE_WRAPPER(DT_DEBUG_DEV, dt_dev_pixelpipe_update_history_main_real, (dev))
129#define DT_DEBUG_TRACE_WRAPPER(thread, function, ...) \
130 do { \
131 dt_vprint((thread), "[debug_trace] %s is called from %s at %s:%d\n", \
132 #function, __FUNCTION__, __FILE__, __LINE__); \
133 function(__VA_ARGS__); \
134 } while (0)
135
136#ifdef __cplusplus
137}
138#endif
139
140// clang-format off
141// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
142// vim: shiftwidth=2 expandtab tabstop=2 cindent
143// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
144// clang-format on