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