1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2010-2019 Free Software Foundation, Inc. */
5 /* */
6 /* This library is free software, licensed under the terms of the GNU */
7 /* General Public License as published by the Free Software Foundation, */
8 /* either version 3 of the License, or (at your option) any later version. */
9 /* You should have received a copy of the GNU General Public License */
10 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
11 /*****************************************************************************/
12
13 /*
14 * logging.h: logging macros
15 * written by Rodrigo Rodrigues da Silva
16 * modified by Reini Urban
17 */
18
19 // Reduce logging code through macros. In the future, this file can be used as
20 // an interface to use more sophisticated logging libraries such as gnu nana
21
22 #ifndef LOGGING_H
23 #define LOGGING_H
24
25 #include <stdio.h>
26 #include <string.h>
27
28 #ifdef IN_DXF_H
29 # error in_dxf.h must be included after logging.h because of FORMAT_BD
30 #endif
31
32 #include "codepages.h"
33
34 /*
35 * If more logging levels are necessary, put them in the right place and
36 * update the numbering, keeping it a 0,1,...n sequence, where n corresponds
37 * to LOGLEVEL_ALL. If LOGLEVEL is set to k, all messages with LOGLEVEL < k
38 * will be displayed
39 */
40
41 #define DWG_LOGLEVEL_NONE 0 // no log
42 #define DWG_LOGLEVEL_ERROR 1 // only error and warning messages
43 #define DWG_LOGLEVEL_INFO 2 // only general info and object codes/names
44 #define DWG_LOGLEVEL_TRACE 3 // eg for each field value parsed
45 #define DWG_LOGLEVEL_HANDLE 4 // print all referenced objects (handles)
46 #define DWG_LOGLEVEL_INSANE 5 // print all vector data (string content)
47 // #define LOGLEVEL_FOO .. //if more codes are necessary
48 #define DWG_LOGLEVEL_ALL 9
49
50 #ifndef DWG_LOGLEVEL
51 # define DWG_LOGLEVEL DWG_LOGLEVEL_ERROR
52 #endif
53
54 #define HANDLER fprintf
55 #define OUTPUT stderr
56
57 #define LOG(level, ...) \
58 { \
59 if (DWG_LOGLEVEL >= DWG_LOGLEVEL_##level) \
60 { \
61 HANDLER (OUTPUT, __VA_ARGS__); \
62 } \
63 }
64 #define LOG_ERROR(...) \
65 { \
66 if (DWG_LOGLEVEL >= DWG_LOGLEVEL_ERROR) \
67 { \
68 HANDLER (OUTPUT, "ERROR: "); \
69 LOG (ERROR, __VA_ARGS__) \
70 HANDLER (OUTPUT, "\n"); \
71 } \
72 }
73 #define LOG_WARN(...) \
74 { \
75 if (DWG_LOGLEVEL >= DWG_LOGLEVEL_ERROR) \
76 { \
77 HANDLER (OUTPUT, "Warning: "); \
78 LOG (ERROR, __VA_ARGS__) \
79 HANDLER (OUTPUT, "\n"); \
80 } \
81 }
82
83 // speed up fuzzing, avoid unnecessary branches
84 #ifdef __AFL_COMPILER
85 # undef DWG_LOGLEVEL
86 # define DWG_LOGLEVEL DWG_LOGLEVEL_NONE
87 # undef LOG
88 # undef LOG_WARN
89 # undef LOG_ERROR
90 # define LOG(...) \
91 { \
92 }
93 # define LOG_WARN(...) \
94 { \
95 }
96 # define LOG_ERROR(...) \
97 { \
98 }
99 #endif
100
101 #define LOG_INFO(...) LOG (INFO, __VA_ARGS__)
102 #define LOG_TRACE(...) LOG (TRACE, __VA_ARGS__)
103 #define LOG_HANDLE(...) LOG (HANDLE, __VA_ARGS__)
104 #define LOG_INSANE(...) LOG (INSANE, __VA_ARGS__)
105 #define LOG_ALL(...) LOG (ALL, __VA_ARGS__)
106
107 #ifndef LOG_POS
108 # define LOG_POS \
109 LOG_INSANE (" @%" PRIuSIZE ".%u", dat->byte, dat->bit) \
110 LOG_TRACE ("\n")
111 #endif
112 #define LOG_TRACE_TV(fmt, str, dxf) \
113 if (dwg_codepage_isasian ((Dwg_Codepage)dat->codepage)) \
114 { \
115 char *nstr = bit_TV_to_utf8 (str, dat->codepage); \
116 LOG_TRACE (fmt, nstr, dxf) \
117 if (nstr && nstr != str) \
118 free (nstr); \
119 } \
120 else \
121 { \
122 LOG_TRACE (fmt, str, dxf) \
123 } \
124 LOG_POS \
125 if (DWG_LOGLEVEL >= DWG_LOGLEVEL_INSANE && str \
126 && dat->codepage != CP_ANSI_1252 && !(dat->codepage < CP_ISO_8859_1) \
127 && strlen (str) && bit_TF_contains_high (str, strlen (str))) \
128 { \
129 LOG_INSANE_TF (str, strlen (str)); \
130 }
131
132 #ifdef HAVE_NATIVE_WCHAR2
133 # define LOG_TRACE_TU(s, wstr, dxf) \
134 LOG_TRACE ("%s: \"%ls\" [TU %d]", s, (wchar_t *)wstr, dxf) \
135 LOG_POS
136 # define LOG_TRACE_TU_I(s, i, wstr, type, dxf) \
137 LOG_TRACE ("%s[%d]: \"%ls\" [%s %d]", s, (int)i, (wchar_t *)wstr, #type, \
138 dxf) \
139 LOG_POS
140 # define LOG_TEXT_UNICODE(level, args) LOG (level, args)
141 #else
142 # define LOG_TRACE_TU(s, wstr, dxf) \
143 { \
144 LOG_TRACE ("%s: \"", s) \
145 LOG_TEXT_UNICODE (TRACE, (BITCODE_TU)wstr) \
146 LOG_TRACE ("\" [TU %d]", dxf) \
147 LOG_POS; \
148 }
149 # define LOG_TRACE_TU_I(s, i, wstr, type, dxf) \
150 { \
151 LOG_TRACE ("%s[%d]: \"", s, (int)i) \
152 LOG_TEXT_UNICODE (TRACE, (BITCODE_TU)wstr) \
153 LOG_TRACE ("\" [" #type " %d]", dxf) \
154 LOG_POS; \
155 }
156 # define LOG_TEXT_UNICODE(level, wstr) \
157 { \
158 if (DWG_LOGLEVEL >= DWG_LOGLEVEL_##level && wstr) \
159 { \
160 ATTRIBUTE_ALIGNED (2) char *_u8 = bit_convert_TU (wstr); \
161 HANDLER (OUTPUT, "%s", _u8); \
162 free (_u8); \
163 } \
164 }
165 #endif
166 #define LOG_TRACE_TW(s, wstr, dxf) \
167 LOG_TRACE ("%s: \"", s) \
168 LOG_TEXT32 (TRACE, (BITCODE_TW)wstr) \
169 LOG_TRACE ("\" [TW %d]", dxf) \
170 LOG_POS
171 #define LOG_TEXT32(level, wstr) \
172 { \
173 if (DWG_LOGLEVEL >= DWG_LOGLEVEL_##level && wstr) \
174 { \
175 char *_u8 = bit_convert_TU (wstr); \
176 HANDLER (OUTPUT, "%s", _u8); \
177 free (_u8); \
178 } \
179 }
180
181 #endif