Initialize Tizen 2.3
[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 (loglevel >= XLOG_LEVEL_WARNING)
120                 LogVWrite (1, tmpBuf, args);
121         }
122     }
123
124     /* write to console */
125     if (loglevel >= h->loglevel)
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 Bool
182 xDbgGetLogEnableDlog ()
183 {
184     return dlog_enable;
185 }
186
187 API void*
188 xDbgLog (unsigned int module, int logoption, const char * file, int line, const char * f, ...)
189 {
190     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
191     ModuleInfo *h;
192     va_list args;
193     int i;
194
195     if (module == 0)
196         return NULL;
197
198     if (loglevel < XLOG_LEVEL_0 || loglevel > XLOG_LEVEL_4)
199         return NULL;
200
201     for (i = 0; i < module_cnt; i++)
202     {
203         h = &modules[i];
204         if (module == h->module)
205             goto check_level;
206     }
207
208     h= (ModuleInfo *)_LogInitModule (module, default_level);
209     if(h == NULL)
210         return NULL;
211
212 check_level:
213     if (loglevel < XLOG_LEVEL_INFO && loglevel < h->loglevel)
214         return h;
215
216     va_start (args, f);
217     _LogModule (h, logoption, file, line, f, args);
218     va_end (args);
219
220     return h;
221 }
222
223 API int
224 xDbgLogEnumModules (LOG_ENUM_MODE mode, char *buf, int *remain)
225 {
226     int i, len;
227     char *p = buf;
228
229     switch (mode)
230     {
231     case MODE_NAME_ONLY:
232         for (i = 0; i < module_cnt && *remain > 0; i++)
233         {
234             len = snprintf (p, *remain, "%s", modules[i].name);
235             p += len;
236             *remain -= len;
237
238             if (i != module_cnt - 1 && *remain > 0)
239             {
240                 len = snprintf (p, *remain, "/");
241                 p += len;
242                 *remain -= len;
243             }
244         }
245         break;
246     case MODE_WITH_STATUS:
247         for (i = 0; i < module_cnt && *remain > 0; i++)
248         {
249             len = snprintf (p, *remain, "   %12s:%d\n", modules[i].name, modules[i].loglevel);
250             p += len;
251             *remain -= len;
252         }
253         break;
254     default:
255         return 0;
256     }
257
258     return p - buf;
259 }
260
261 static char*
262 _LogGetName (unsigned int module)
263 {
264     char *name = malloc (MAX_MODULE_NAME+1);
265     char *p = name;
266     int i;
267
268     if (!name)
269         return NULL;
270
271     name[0] = '\0';
272
273     for (i = 0; i < MAX_MODULE_NAME; i++)
274     {
275         if (!_C(module, (i<<3)))
276             break;
277
278         *p = _C(module, (i<<3));
279         p++;
280     }
281
282     *p = '\0';
283
284     return name;
285 }
286
287 API unsigned int
288 xDbgLogGetModule (char *name)
289 {
290     unsigned int module = 0;
291     int i, len;
292
293     if (!name)
294         return 0;
295
296     if (!strcasecmp (name, "all"))
297         return XDBG_ALL_MODULE;
298
299     len = strlen (name);
300     for (i = 0; i < len; i++)
301     {
302         module |= _B(*name, (i<<3));
303         name++;
304     }
305
306     return module;
307 }