tizen 2.3 release
[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 <sys/time.h>
37 #include <unistd.h>
38 #include <time.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <dlog.h>
42 #include "xdbg_log.h"
43
44 #ifndef API
45 #define API __attribute__ ((visibility("default")))
46 #endif
47
48 #ifndef MIN
49 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
50 #endif
51
52 #define MAX_MODULE_NAME 4
53 #define MAX_MODULE_CNT  256
54 #define BUF_LEN         1024
55 #define MAX_MONTH 12
56
57 typedef struct
58 {
59     unsigned int module;
60     char *name;
61     int   loglevel;
62 } ModuleInfo;
63
64 static ModuleInfo modules[MAX_MODULE_CNT];
65 static int module_cnt = 0;
66 static int default_level = XLOG_LEVEL_DEFAULT;
67 static char *st_month[MAX_MONTH] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
68
69 static Bool dlog_enable;
70
71 extern void dLogWrapper (int loglevel, int is_module, const char * file, int line, const char * f, va_list args);
72 extern void kLogWrapper (int loglevel, int is_module, const char * file, int line, const char * f, va_list args);
73 static char* _LogGetName (unsigned int module);
74
75 static void*
76 _LogInitModule (unsigned int module, int loglevel)
77 {
78     if (module_cnt >= MAX_MODULE_CNT)
79         return NULL;
80
81     modules[module_cnt].module = module;
82     modules[module_cnt].name = _LogGetName (module);
83     modules[module_cnt].loglevel = loglevel;
84     module_cnt++;
85
86     return &modules[module_cnt-1];
87 }
88
89 static void
90 _LogModule (void * handle, int logoption, const char * file, int line, const char * f, va_list args)
91 {
92     ModuleInfo *h = (ModuleInfo*)handle;
93     char *ostr[XLOG_LEVEL_MAX] = {"DD", "TT", "II", "WW", "EE"};
94     char tmpBuf[BUF_LEN];
95     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
96     const char *name;
97     struct timeval  tv;
98     struct tm      *tm=NULL;
99
100     if (!h)
101         return;
102
103     name = h->name;
104
105     if (logoption & XLOG_OPTION_KLOG)
106     {
107         snprintf(tmpBuf, BUF_LEN, "[%s]%s", (name)?name:"", f);
108         kLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
109     }
110     else if (loglevel >= XLOG_LEVEL_INFO)
111     {
112         if( !dlog_enable )
113         {
114             /* get local time from tv */
115             gettimeofday(&tv, NULL);
116             tm = localtime(&tv.tv_sec);
117
118             /* write to file */
119             if (logoption & XLOG_OPTION_SECURE)
120                 snprintf(tmpBuf, BUF_LEN, "[%s %d %02d:%02d:%02d:%03ld] (%s) > [SECURE_LOG] [%s]%s", st_month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000, ostr[loglevel], (name)?name:"", f);
121             else
122                 snprintf(tmpBuf, BUF_LEN, "[%s %d %02d:%02d:%02d:%03ld] (%s) [%s]%s", st_month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000, ostr[loglevel], (name)?name:"", f);
123
124             LogVWrite (1, tmpBuf, args);
125         }
126         else
127         {
128             /* dlog already supports localtime stamp. So we just add clock time! */
129             /* write to file */
130             if (logoption & XLOG_OPTION_SECURE)
131                 snprintf(tmpBuf, BUF_LEN, "[%10.3f] (%s) > [SECURE_LOG] [%s]%s", GetTimeInMillis()/1000.0, ostr[loglevel], (name)?name:"", f);
132             else
133                 snprintf(tmpBuf, BUF_LEN, "[%10.3f] (%s) [%s]%s", GetTimeInMillis()/1000.0, ostr[loglevel], (name)?name:"", f);
134
135             dLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
136         }
137     }
138
139     /* write to console */
140     if (loglevel >= h->loglevel)
141     {
142         char *buf = tmpBuf;
143         int   remain = BUF_LEN;
144         int   len = 0;
145         unsigned int tv_ms;
146
147         if( tm == NULL )
148         {
149             gettimeofday(&tv, NULL);
150             tm = localtime(&tv.tv_sec);
151         }
152
153         tv_ms = tv.tv_usec/1000;
154         len = snprintf (buf, remain, "[%10.3f] [%s %d %02d:%02d:%02d:%03d] (%s) [%s]", GetTimeInMillis()/1000.0, st_month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv_ms, ostr[loglevel], name?name:"");
155         buf += len;
156         remain -= len;
157
158         len += vsnprintf (buf, remain, f, args);
159
160         fwrite(tmpBuf, len, 1, stderr);
161     }
162 }
163
164 API int
165 xDbgLogSetLevel (unsigned int module, int level)
166 {
167     int i;
168     ModuleInfo * h;
169
170     if (level < XLOG_LEVEL_0 || level > XLOG_LEVEL_4)
171         return FALSE;
172
173     if (module == XDBG_ALL_MODULE)
174     {
175         default_level = level;
176         for (i = 0; i < module_cnt; i++)
177             modules[i].loglevel = level;
178
179         return TRUE;
180     }
181
182     for (i = 0; i < module_cnt; i++)
183     {
184         if (module == modules[i].module)
185         {
186             modules[i].loglevel = level;
187             return TRUE;
188         }
189     }
190
191     h = _LogInitModule (module, level);
192     if (h == NULL)
193         return FALSE;
194
195     return TRUE;
196 }
197
198 API void
199 xDbgLogEnableDlog (Bool enable)
200 {
201     dlog_enable = (enable > 0) ? TRUE:FALSE;
202 }
203
204 API Bool
205 xDbgGetLogEnableDlog ()
206 {
207     return dlog_enable;
208 }
209
210 API void*
211 xDbgLog (unsigned int module, int logoption, const char * file, int line, const char * f, ...)
212 {
213     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
214     ModuleInfo *h;
215     va_list args;
216     int i;
217
218     if (module == 0)
219         return NULL;
220
221     if (loglevel < XLOG_LEVEL_0 || loglevel > XLOG_LEVEL_4)
222         return NULL;
223
224     for (i = 0; i < module_cnt; i++)
225     {
226         h = &modules[i];
227         if (module == h->module)
228             goto check_level;
229     }
230
231     h= (ModuleInfo *)_LogInitModule (module, default_level);
232     if(h == NULL)
233         return NULL;
234
235 check_level:
236     if (loglevel < XLOG_LEVEL_INFO && loglevel < h->loglevel)
237         return h;
238
239     va_start (args, f);
240     _LogModule (h, logoption, file, line, f, args);
241     va_end (args);
242
243     return h;
244 }
245
246 API int
247 xDbgLogEnumModules (LOG_ENUM_MODE mode, char *buf, int *remain)
248 {
249     int i, len;
250     char *p = buf;
251
252     switch (mode)
253     {
254     case MODE_NAME_ONLY:
255         for (i = 0; i < module_cnt && *remain > 0; i++)
256         {
257             len = snprintf (p, *remain, "%s", modules[i].name);
258             p += len;
259             *remain -= len;
260
261             if (i != module_cnt - 1 && *remain > 0)
262             {
263                 len = snprintf (p, *remain, "/");
264                 p += len;
265                 *remain -= len;
266             }
267         }
268         break;
269     case MODE_WITH_STATUS:
270         for (i = 0; i < module_cnt && *remain > 0; i++)
271         {
272             len = snprintf (p, *remain, "   %12s:%d\n", modules[i].name, modules[i].loglevel);
273             p += len;
274             *remain -= len;
275         }
276         break;
277     default:
278         return 0;
279     }
280
281     return p - buf;
282 }
283
284 static char*
285 _LogGetName (unsigned int module)
286 {
287     char *name = malloc (MAX_MODULE_NAME+1);
288     char *p = name;
289     int i;
290
291     if (!name)
292         return NULL;
293
294     name[0] = '\0';
295
296     for (i = 0; i < MAX_MODULE_NAME; i++)
297     {
298         if (!_C(module, (i<<3)))
299             break;
300
301         *p = _C(module, (i<<3));
302         p++;
303     }
304
305     *p = '\0';
306
307     return name;
308 }
309
310 API unsigned int
311 xDbgLogGetModule (char *name)
312 {
313     unsigned int module = 0;
314     int i, len;
315
316     if (!name)
317         return 0;
318
319     if (!strcasecmp (name, "all"))
320         return XDBG_ALL_MODULE;
321
322     len = strlen (name);
323     for (i = 0; i < len; i++)
324     {
325         module |= _B(*name, (i<<3));
326         name++;
327     }
328
329     return module;
330 }