add 'dlog' option to xdbg
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / lib / xdbg_log.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <string.h>
37 #include <stdarg.h>
38 #include <dlog.h>
39 #include "xdbg_log.h"
40
41 #ifndef API
42 #define API __attribute__ ((visibility("default")))
43 #endif
44
45 #ifndef MIN
46 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
47 #endif
48
49 #define MAX_MODULE_NAME 4
50 #define MAX_MODULE_CNT  256
51 #define BUF_LEN         1024
52
53 typedef struct
54 {
55     unsigned int module;
56     char *name;
57     int   loglevel;
58 } ModuleInfo;
59
60 static ModuleInfo modules[MAX_MODULE_CNT];
61 static int module_cnt = 0;
62 static int default_level = XLOG_LEVEL_DEFAULT;
63
64 static Bool dlog_enable;
65
66 extern void dLogWrapper (int loglevel, int is_module, const char * file, int line, const char * f, va_list args);
67 extern void kLogWrapper (int loglevel, int is_module, const char * file, int line, const char * f, va_list args);
68 static char* _LogGetName (unsigned int module);
69
70 static void*
71 _LogInitModule (unsigned int module, int loglevel)
72 {
73     if (module_cnt >= MAX_MODULE_CNT)
74         return NULL;
75
76     modules[module_cnt].module = module;
77     modules[module_cnt].name = _LogGetName (module);
78     modules[module_cnt].loglevel = loglevel;
79     module_cnt++;
80
81     return &modules[module_cnt-1];
82 }
83
84 static void
85 _LogModule (void * handle, int logoption, const char * file, int line, const char * f, va_list args)
86 {
87     ModuleInfo *h = (ModuleInfo*)handle;
88     char *ostr[XLOG_LEVEL_MAX] = {"DD", "TT", "II", "WW", "EE"};
89     char tmpBuf[BUF_LEN];
90     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
91     const char *name;
92
93     if (!h)
94         return;
95
96     name = h->name;
97
98     if (logoption & XLOG_OPTION_KLOG)
99     {
100         snprintf(tmpBuf, BUF_LEN, "[%s]%s", (name)?name:"", f);
101         kLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
102     }
103
104     /* write to file */
105     if (loglevel >= XLOG_LEVEL_INFO)
106     {
107         if (logoption & XLOG_OPTION_SECURE)
108             snprintf(tmpBuf, BUF_LEN, "(%s) > [SECURE_LOG] [%s]%s", ostr[loglevel], (name)?name:"", f);
109         else
110             snprintf(tmpBuf, BUF_LEN, "(%s) [%s]%s", ostr[loglevel], (name)?name:"", f);
111
112         if (!dlog_enable)
113             LogVWrite (1, tmpBuf, args);
114         else
115         {
116             dLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
117
118             /* write to Xorg.0.log too */
119             if (logoption & XLOG_OPTION_XORG)
120                 LogVWrite (1, tmpBuf, args);
121         }
122     }
123
124     /* write to terminal */
125     if (loglevel >= h->loglevel || logoption & XLOG_OPTION_SLOG)
126     {
127         char *buf = tmpBuf;
128         int   remain = BUF_LEN;
129         int   len = 0;
130
131         len = snprintf (buf, remain, "(%s) [%10.3f][%s]", ostr[loglevel], GetTimeInMillis()/1000.0, name?name:"");
132         buf += len;
133         remain -= len;
134
135         len += vsnprintf (buf, remain, f, args);
136
137         fwrite(tmpBuf, len, 1, stderr);
138     }
139 }
140
141 API int
142 xDbgLogSetLevel (unsigned int module, int level)
143 {
144     int i;
145     ModuleInfo * h;
146
147     if (level < XLOG_LEVEL_0 || level > XLOG_LEVEL_4)
148         return FALSE;
149
150     if (module == XDBG_ALL_MODULE)
151     {
152         default_level = level;
153         for (i = 0; i < module_cnt; i++)
154             modules[i].loglevel = level;
155
156         return TRUE;
157     }
158
159     for (i = 0; i < module_cnt; i++)
160     {
161         if (module == modules[i].module)
162         {
163             modules[i].loglevel = level;
164             return TRUE;
165         }
166     }
167
168     h = _LogInitModule (module, level);
169     if (h == NULL)
170         return FALSE;
171
172     return TRUE;
173 }
174
175 API void
176 xDbgLogEnableDlog (Bool enable)
177 {
178     dlog_enable = (enable > 0) ? TRUE:FALSE;
179 }
180
181 API void*
182 xDbgLog (unsigned int module, int logoption, const char * file, int line, const char * f, ...)
183 {
184     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
185     ModuleInfo *h;
186     va_list args;
187     int i;
188
189     if (module == 0)
190         return NULL;
191
192     if (loglevel < XLOG_LEVEL_0 || loglevel > XLOG_LEVEL_4)
193         return NULL;
194
195     for (i = 0; i < module_cnt; i++)
196     {
197         h = &modules[i];
198         if (module == h->module)
199             goto check_level;
200     }
201
202     h= (ModuleInfo *)_LogInitModule (module, default_level);
203     if(h == NULL)
204         return NULL;
205
206 check_level:
207     if (logoption & (XLOG_OPTION_KLOG | XLOG_OPTION_SLOG))
208         goto write_log;
209
210     if (loglevel < XLOG_LEVEL_INFO && loglevel < h->loglevel)
211         return h;
212
213 write_log:
214     va_start (args, f);
215     _LogModule (h, logoption, file, line, f, args);
216     va_end (args);
217
218     return h;
219 }
220
221 API int
222 xDbgLogEnumModules (LOG_ENUM_MODE mode, char *buf, int *remain)
223 {
224     int i, len;
225     char *p = buf;
226
227     switch (mode)
228     {
229     case MODE_NAME_ONLY:
230         for (i = 0; i < module_cnt && *remain > 0; i++)
231         {
232             len = snprintf (p, *remain, "%s", modules[i].name);
233             p += len;
234             *remain -= len;
235
236             if (i != module_cnt - 1 && *remain > 0)
237             {
238                 len = snprintf (p, *remain, "/");
239                 p += len;
240                 *remain -= len;
241             }
242         }
243         break;
244     case MODE_WITH_STATUS:
245         for (i = 0; i < module_cnt && *remain > 0; i++)
246         {
247             len = snprintf (p, *remain, "   %12s:%d\n", modules[i].name, modules[i].loglevel);
248             p += len;
249             *remain -= len;
250         }
251         break;
252     default:
253         return 0;
254     }
255
256     return p - buf;
257 }
258
259 static char*
260 _LogGetName (unsigned int module)
261 {
262     char *name = malloc (MAX_MODULE_NAME+1);
263     char *p = name;
264     int i;
265
266     if (!name)
267         return NULL;
268
269     name[0] = '\0';
270
271     for (i = 0; i < MAX_MODULE_NAME; i++)
272     {
273         if (!_C(module, (i<<3)))
274             break;
275
276         *p = _C(module, (i<<3));
277         p++;
278     }
279
280     *p = '\0';
281
282     return name;
283 }
284
285 API unsigned int
286 xDbgLogGetModule (char *name)
287 {
288     unsigned int module = 0;
289     int i, len;
290
291     if (!name)
292         return 0;
293
294     if (!strcasecmp (name, "all"))
295         return XDBG_ALL_MODULE;
296
297     len = strlen (name);
298     for (i = 0; i < len; i++)
299     {
300         module |= _B(*name, (i<<3));
301         name++;
302     }
303
304     return module;
305 }