1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #if _DEBUGGING
28 
29 #include <klib/extern.h>
30 #include <klib/debug.h>
31 #include "writer-priv.h"
32 #include <sysalloc.h>
33 
34 /* PUT THIS IN A CORRECT PLACE */
35 #define _module(mod) \
36     KDbgFlag DBG_PASTE_3(DBG_,mod,_ANY) = ( DBG_PASTE_2(mod,_CONDITIONS()) 0);
37 #define _condition(mod,flag) \
38     (((KDbgFlag)1)<<DBG_PASTE_4(DBG_,mod,_,flag)) |
39 
40 MODULE_NAMES()
41 
42 #undef _module
43 #undef _condition
44 
45 #define _module(mod)                            \
46     dbg_s_flag DBG_PASTE_2(dbg_s_flag_,mod) [] = \
47     {                                            \
48         DBG_PASTE_2(mod,_CONDITIONS())           \
49         { NULL, DBG_FLAG_NONE }                      \
50     };
51 
52 #define _condition(mod,flag)                                           \
53     { DBG_STRING(flag), ((KDbgFlag)1)<<DBG_PASTE_4(DBG_,mod,_,flag) },
54 
55 MODULE_NAMES()
56 
57 #undef _module
58 #undef _condition
59 
60 #define _module(mod)                           \
61     {                                           \
62         DBG_STRING(mod),                         \
63         DBG_PASTE_2(dbg_s_flag_,mod),        \
64         0                                       \
65     },
66 
67 dbg_s_mod dbg_flag_mod [] =
68 {
69     MODULE_NAMES()
70     { NULL, NULL }
71 };
72 #undef _module
73 
74 #define _module(mod)
75 
76 #include <klib/rc.h>
77 #include <klib/text.h>
78 #include <stdio.h>
79 #include <string.h>
80 
81 KWrtHandler G_dbg_handler;
82 
83 
84 /*  ********************************************************
85 
86     setters and getters to find out what causes file-acces
87 
88     ******************************************************** */
89 
90 uint64_t dbg_row_id;
91 char dbg_col_name[ 128 ];
92 
93 
KDbgSetRowId(uint64_t row_id)94 LIB_EXPORT void CC KDbgSetRowId( uint64_t row_id )
95 {
96     dbg_row_id = row_id;
97 }
98 
99 
KDbgGetRowId(void)100 LIB_EXPORT uint64_t CC KDbgGetRowId( void )
101 {
102     return dbg_row_id;
103 }
104 
KDbgSetColName(const char * col_name)105 LIB_EXPORT void CC KDbgSetColName( const char * col_name )
106 {
107     if ( col_name != NULL )
108         string_copy ( dbg_col_name, sizeof dbg_col_name, col_name, string_size( col_name ) );
109     else
110         dbg_col_name[ 0 ] = 0;
111 }
112 
KDbgGetColName(void)113 LIB_EXPORT const char * CC KDbgGetColName( void )
114 {
115     return dbg_col_name;
116 }
117 
118 
119 /*  ********************************************************  */
120 
121 /*
122  * Init()
123  * Initialize the debug messages module to a known state
124  */
KDbgInit(void)125 LIB_EXPORT rc_t CC KDbgInit( void )
126 {
127     KDbgHandlerSetStdErr();
128     dbg_row_id = 0;
129     dbg_col_name[ 0 ] = 0;
130     return 0;
131 }
132 
KDbgMsg(const char * fmt,...)133 LIB_EXPORT rc_t CC KDbgMsg ( const char * fmt, ... )
134 {
135     rc_t rc;
136 
137     va_list args;
138     va_start ( args, fmt );
139 
140     if( (rc = vkfprintf(KDbgHandlerGet (), NULL, fmt, args)) != 0 ) {
141         kfprintf(KDbgHandlerGet(), NULL, "dbgmsg failure: %R in '%s'\n", rc, fmt);
142     }
143     va_end ( args );
144 
145     return rc;
146 }
147 
KDbgCondToFlag(KDbgCond cond)148 LIB_EXPORT KDbgFlag CC KDbgCondToFlag( KDbgCond cond )
149 {
150     return (((KDbgFlag)1)<<cond);
151 }
152 
153 /*
154  * For module 'mod' turn on or off the specific flags in
155  * mask flags
156  *
157  * bits in mask are effected.
158  * return previous
159  */
KDbgSetModConds(KDbgMod mod,KDbgMask mask,KDbgMask flags)160 LIB_EXPORT KDbgMask CC KDbgSetModConds( KDbgMod mod, KDbgMask mask, KDbgMask flags )
161 {
162     KDbgMask previous;
163 
164     if ((mod < 0) || (mod >= DBG_MOD_COUNT))
165     {
166         /* unmaskable debug message */
167         KDbgMsg ("%s: Undefined module: (%u)\n", __func__, mod);
168         return DBG_FLAG_NONE;
169     }
170     previous = dbg_flag_mod[mod].flags;
171 
172     dbg_flag_mod[mod].flags = (flags & mask) | (previous & ~mask);
173 
174     return previous;
175 }
176 
177 
KDbgTestModConds(KDbgMod mod,KDbgMask flags)178 LIB_EXPORT bool CC KDbgTestModConds( KDbgMod mod, KDbgMask flags )
179 {
180     if (mod >= DBG_MOD_COUNT)
181     {
182         /* unmaskable debug message */
183         KDbgMsg ("%s: Undefined module: (%u)\n", __func__, mod);
184         return false;
185     }
186     return DBG_FLAG_NONE != (KDbgGetModFlags (mod) & flags);
187 }
188 
189 
190 /*
191  * Get the KDbgMod associated with a name.
192  */
KDbgGetModId(KDbgMod * mod,const char * mod_name,size_t mod_size)193 LIB_EXPORT rc_t CC KDbgGetModId( KDbgMod * mod,
194                    const char * mod_name, size_t mod_size )
195 {
196     KDbgMod idx;
197 
198     for (idx = 0; idx < DBG_MOD_COUNT; ++idx)
199     {
200         if (strncmp (dbg_flag_mod[idx].name, mod_name, mod_size) == 0)
201         {
202             *mod = idx;
203             return 0;
204         }
205     }
206     *mod = DBG_MOD_NOT_FOUND;
207     return RC (rcRuntime, rcLog, rcAccessing, rcParam, rcNotFound);
208 }
209 
210 
211 /*
212  * Get the KDbgCond associated with a name.
213  */
KDbgGetCndFlag(KDbgMod mod,KDbgFlag * flag,const char * cnd_name,size_t cnd_size)214 LIB_EXPORT rc_t CC KDbgGetCndFlag( KDbgMod mod, KDbgFlag * flag,
215                       const char * cnd_name, size_t cnd_size )
216 {
217     const dbg_s_flag * cnd;
218 
219     for (cnd = dbg_flag_mod[mod].conds; cnd->name != NULL; ++cnd)
220     {
221         if (strncmp (cnd_name, cnd->name, cnd_size) == 0)
222             break;
223     }
224     if (cnd->name == NULL)
225         return RC (rcRuntime, rcArgv, rcAccessing, rcParam, rcUndefined);
226 
227     *flag = cnd->flag;
228     return 0;
229 }
230 
KDbgGetModFlags(KDbgMod mod)231 LIB_EXPORT KDbgMask CC KDbgGetModFlags( KDbgMod mod )
232 {
233     if ((mod < 0) || (mod >= DBG_MOD_COUNT))
234     {
235         /* unmaskable debug message */
236         KDbgMsg ("%s: Undefined module: (%u)\n", __func__, mod);
237         return DBG_FLAG_NONE;
238     }
239     return dbg_flag_mod[mod].flags;
240 }
241 
242 /*
243  * param is coming in as utf-8/ASCII with NUL terminator or we fail
244  * we also assume no more than 127 significant characters
245  *
246  * These strings can be utf-8 or ASCII even if we are using
247  * clib strXXX functions.
248  */
KDbgSetString(const char * string)249 LIB_EXPORT rc_t CC KDbgSetString( const char * string )
250 {
251     const char * mod_s;
252     const char * flag_s;
253     size_t mod_z;
254 
255     KDbgMod mod;
256 
257     rc_t rc;
258 
259     mod_s = string;
260 
261     if (mod_s == NULL)
262         return RC (rcRuntime, rcArgv, rcAccessing, rcParam, rcNull);
263     if (*mod_s == '\0')
264         return 0;
265 
266     flag_s = strchr (mod_s, '-');
267     if (flag_s)
268     {
269         mod_z = (size_t)(flag_s - mod_s);
270 
271         if (*(++flag_s) == '\0')
272             flag_s = NULL;
273     }
274     else
275         mod_z = strlen (mod_s);
276 
277     rc = KDbgGetModId (&mod, mod_s, mod_z);
278     if (rc)
279         return rc;
280 
281     /* now we have a id for the module so we need to figure out the flag */
282 
283     if (flag_s == NULL)
284     {
285         dbg_flag_mod[mod].flags = ~(KDbgMask)0;
286         rc = 0;
287     }
288     else
289     {
290         const dbg_s_flag * cnd;
291 
292         for (cnd = dbg_flag_mod[mod].conds; cnd->name != NULL; ++cnd)
293         {
294             if (strcmp (flag_s, cnd->name) == 0)
295                 break;
296         }
297         if (cnd->name == NULL)
298             return RC (rcRuntime, rcArgv, rcAccessing, rcParam, rcUndefined);
299 
300         dbg_flag_mod[mod].flags |= cnd->flag;
301 
302     }
303     return 0;
304 }
305 
306 /* -----
307  * Handlers for application and library writers.
308  */
309 
310 #undef KDbgHandlerSetStdOut
KDbgHandlerSetStdOut(void)311 LIB_EXPORT rc_t CC KDbgHandlerSetStdOut( void )
312 {
313     return KDbgHandlerSet( KWrt_DefaultWriter,KWrt_DefaultWriterDataStdOut );
314 }
315 
316 
317 #undef KDbgHandlerSetStdErr
KDbgHandlerSetStdErr(void)318 LIB_EXPORT rc_t CC KDbgHandlerSetStdErr( void )
319 {
320     return KDbgHandlerSet( KWrt_DefaultWriter,KWrt_DefaultWriterDataStdErr );
321 }
322 
323 
324 #undef KDbgHandlerSet
KDbgHandlerSet(KWrtWriter writer,void * writer_data)325 LIB_EXPORT rc_t CC KDbgHandlerSet( KWrtWriter writer, void * writer_data )
326 {
327     G_dbg_handler.writer = writer;
328     G_dbg_handler.data = writer_data;
329     return 0;
330 }
331 
332 #undef KDbgWriterDataGet
KDbgWriterDataGet(void)333 LIB_EXPORT void * CC KDbgWriterDataGet( void )
334 {
335     return ( KDbgHandlerGet()->data );
336 }
337 
338 
339 #undef KDbgWriterGet
KDbgWriterGet(void)340 LIB_EXPORT KWrtWriter CC KDbgWriterGet( void )
341 {
342     return ( KDbgHandlerGet()->writer );
343 }
344 
345 
346 #undef KDbgHandlerGet
KDbgHandlerGet(void)347 LIB_EXPORT KWrtHandler * CC KDbgHandlerGet( void )
348 {
349     return ( &G_dbg_handler );
350 }
351 
352 #endif /* _DEBUGGING */
353