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 /*
33  * If more logging levels are necessary, put them in the right place and
34  * update the numbering, keeping it a 0,1,...n sequence, where n corresponds
35  * to LOGLEVEL_ALL. If LOGLEVEL is set to k, all messages with LOGLEVEL < k
36  * will be displayed
37  */
38 
39 #define DWG_LOGLEVEL_NONE 0   // no log
40 #define DWG_LOGLEVEL_ERROR 1  // only error messages
41 #define DWG_LOGLEVEL_INFO 2   // only general info and object codes/names
42 #define DWG_LOGLEVEL_TRACE 3  // eg for each field value parsed
43 #define DWG_LOGLEVEL_HANDLE 4 // print all referenced objects (handles)
44 #define DWG_LOGLEVEL_INSANE 5 // print all vector data (string content)
45 // #define LOGLEVEL_FOO ..     //if more codes are necessary
46 #define DWG_LOGLEVEL_ALL 9
47 
48 #ifndef DWG_LOGLEVEL
49 #  define DWG_LOGLEVEL DWG_LOGLEVEL_ERROR
50 #endif
51 
52 #define HANDLER fprintf
53 #define OUTPUT stderr
54 
55 #define LOG(level, args...)                                                   \
56   {                                                                           \
57     if (DWG_LOGLEVEL >= DWG_LOGLEVEL_##level)                                 \
58       {                                                                       \
59         HANDLER (OUTPUT, args);                                               \
60       }                                                                       \
61   }
62 #define LOG_ERROR(args...)                                                    \
63   {                                                                           \
64     if (DWG_LOGLEVEL >= DWG_LOGLEVEL_ERROR)                                   \
65       {                                                                       \
66         HANDLER (OUTPUT, "ERROR: ");                                          \
67         LOG (ERROR, args)                                                     \
68         HANDLER (OUTPUT, "\n");                                               \
69       }                                                                       \
70   }
71 #define LOG_WARN(args...)                                                     \
72   {                                                                           \
73     if (DWG_LOGLEVEL >= DWG_LOGLEVEL_ERROR)                                   \
74       {                                                                       \
75         HANDLER (OUTPUT, "Warning: ");                                        \
76         LOG (ERROR, args)                                                     \
77         HANDLER (OUTPUT, "\n");                                               \
78       }                                                                       \
79   }
80 
81 // speed up fuzzing, avoid unnecessary branches
82 #ifdef __AFL_COMPILER
83 #  undef DWG_LOGLEVEL
84 #  define DWG_LOGLEVEL DWG_LOGLEVEL_NONE
85 #  undef LOG
86 #  undef LOG_WARN
87 #  undef LOG_ERROR
88 #  define LOG(args...) {}
89 #  define LOG_WARN(args...) {}
90 #  define LOG_ERROR(args...) {}
91 #endif
92 
93 #define LOG_INFO(args...) LOG (INFO, args)
94 #define LOG_TRACE(args...) LOG (TRACE, args)
95 #define LOG_HANDLE(args...) LOG (HANDLE, args)
96 #define LOG_INSANE(args...) LOG (INSANE, args)
97 #define LOG_ALL(args...) LOG (ALL, args)
98 
99 #ifndef LOG_POS
100 #  define LOG_POS                                                             \
101     LOG_INSANE (" @%lu.%u", dat->byte, dat->bit)                              \
102     LOG_TRACE ("\n")
103 #endif
104 #ifdef HAVE_NATIVE_WCHAR2
105 #  define LOG_TRACE_TU(s, wstr, dxf)                                          \
106     LOG_TRACE ("%s: \"%ls\" [TU %d]", s, (wchar_t *)wstr, dxf)                \
107     LOG_POS
108 #  define LOG_TRACE_TU_I(s, i, wstr, type, dxf)                               \
109     LOG_TRACE ("%s[%d]: \"%ls\" [%s %d]", s, (int)i, (wchar_t *)wstr, #type,  \
110                dxf)                                                           \
111     LOG_POS
112 #  define LOG_TEXT_UNICODE(level, args) LOG (level, args)
113 #else
114 #  define LOG_TRACE_TU(s, wstr, dxf)                                          \
115     {                                                                         \
116       LOG_TRACE ("%s: \"", s)                                                 \
117       LOG_TEXT_UNICODE (TRACE, (BITCODE_TU)wstr)                              \
118       LOG_TRACE ("\" [TU %d]", dxf)                                           \
119       LOG_POS;                                                                \
120     }
121 #  define LOG_TRACE_TU_I(s, i, wstr, type, dxf)                               \
122     {                                                                         \
123       LOG_TRACE ("%s[%d]: \"", s, (int)i)                                     \
124       LOG_TEXT_UNICODE (TRACE, (BITCODE_TU)wstr)                              \
125       LOG_TRACE ("\" [" #type " %d]", dxf)                                    \
126       LOG_POS;                                                                \
127     }
128 #  define LOG_TEXT_UNICODE(level, wstr)                                       \
129     {                                                                         \
130       if (DWG_LOGLEVEL >= DWG_LOGLEVEL_##level && wstr)                       \
131         {                                                                     \
132           char *_u8 = bit_convert_TU (wstr);                                  \
133           HANDLER (OUTPUT, "%s", _u8);                                        \
134           free (_u8);                                                         \
135         }                                                                     \
136     }
137 #endif
138 #define LOG_TRACE_TW(s, wstr, dxf)                                            \
139   LOG_TRACE ("%s: \"", s)                                                     \
140   LOG_TEXT32 (TRACE, (BITCODE_TW)wstr)                                        \
141   LOG_TRACE ("\" [TW %d]", dxf)                                               \
142   LOG_POS
143 #define LOG_TEXT32(level, wstr)                                               \
144     {                                                                         \
145       if (DWG_LOGLEVEL >= DWG_LOGLEVEL_##level && wstr)                       \
146         {                                                                     \
147           char *_u8 = bit_convert_TU (wstr);                                  \
148           HANDLER (OUTPUT, "%s", _u8);                                        \
149           free (_u8);                                                         \
150         }                                                                     \
151     }
152 
153 #endif
154