1.1.12
by Francois Marier
Import upstream version 1.4.1 |
1 |
/* $Id: log.c 4761 2014-02-24 09:02:44Z nanang $ */
|
2 |
/*
|
|
3 |
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
|
4 |
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
|
5 |
*
|
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; either version 2 of the License, or
|
|
9 |
* (at your option) any later version.
|
|
10 |
*
|
|
11 |
* This program is distributed in the hope that it will be useful,
|
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 |
* GNU General Public License for more details.
|
|
15 |
*
|
|
16 |
* You should have received a copy of the GNU General Public License
|
|
17 |
* along with this program; if not, write to the Free Software
|
|
18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
19 |
*/
|
|
20 |
#include <pj/types.h> |
|
21 |
#include <pj/log.h> |
|
22 |
#include <pj/string.h> |
|
23 |
#include <pj/os.h> |
|
24 |
#include <pj/compat/stdarg.h> |
|
25 |
||
26 |
#if PJ_LOG_MAX_LEVEL >= 1
|
|
27 |
||
28 |
#if 0
|
|
29 |
PJ_DEF_DATA(int) pj_log_max_level = PJ_LOG_MAX_LEVEL;
|
|
30 |
#else
|
|
31 |
static int pj_log_max_level = PJ_LOG_MAX_LEVEL; |
|
32 |
#endif
|
|
33 |
||
34 |
static void *g_last_thread; |
|
35 |
||
36 |
#if PJ_HAS_THREADS
|
|
37 |
static long thread_suspended_tls_id = -1; |
|
38 |
# if PJ_LOG_ENABLE_INDENT
|
|
39 |
static long thread_indent_tls_id = -1; |
|
40 |
# endif
|
|
41 |
#endif
|
|
42 |
||
43 |
#if !PJ_LOG_ENABLE_INDENT || !PJ_HAS_THREADS
|
|
44 |
static int log_indent; |
|
45 |
#endif
|
|
46 |
||
47 |
static pj_log_func *log_writer = &pj_log_write; |
|
48 |
static unsigned log_decor = PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC | |
|
49 |
PJ_LOG_HAS_SENDER | PJ_LOG_HAS_NEWLINE | |
|
50 |
PJ_LOG_HAS_SPACE | PJ_LOG_HAS_THREAD_SWC | |
|
51 |
PJ_LOG_HAS_INDENT
|
|
52 |
#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
|
|
53 |
(defined(PJ_WIN64) && PJ_WIN64!=0)
|
|
54 |
| PJ_LOG_HAS_COLOR |
|
55 |
#endif
|
|
56 |
;
|
|
57 |
||
58 |
static pj_color_t PJ_LOG_COLOR_0 = PJ_TERM_COLOR_BRIGHT | PJ_TERM_COLOR_R; |
|
59 |
static pj_color_t PJ_LOG_COLOR_1 = PJ_TERM_COLOR_BRIGHT | PJ_TERM_COLOR_R; |
|
60 |
static pj_color_t PJ_LOG_COLOR_2 = PJ_TERM_COLOR_BRIGHT | |
|
61 |
PJ_TERM_COLOR_R | |
|
62 |
PJ_TERM_COLOR_G; |
|
63 |
static pj_color_t PJ_LOG_COLOR_3 = PJ_TERM_COLOR_BRIGHT | |
|
64 |
PJ_TERM_COLOR_R | |
|
65 |
PJ_TERM_COLOR_G | |
|
66 |
PJ_TERM_COLOR_B; |
|
67 |
static pj_color_t PJ_LOG_COLOR_4 = PJ_TERM_COLOR_R | |
|
68 |
PJ_TERM_COLOR_G | |
|
69 |
PJ_TERM_COLOR_B; |
|
70 |
static pj_color_t PJ_LOG_COLOR_5 = PJ_TERM_COLOR_R | |
|
71 |
PJ_TERM_COLOR_G | |
|
72 |
PJ_TERM_COLOR_B; |
|
73 |
static pj_color_t PJ_LOG_COLOR_6 = PJ_TERM_COLOR_R | |
|
74 |
PJ_TERM_COLOR_G | |
|
75 |
PJ_TERM_COLOR_B; |
|
76 |
/* Default terminal color */
|
|
77 |
static pj_color_t PJ_LOG_COLOR_77 = PJ_TERM_COLOR_R | |
|
78 |
PJ_TERM_COLOR_G | |
|
79 |
PJ_TERM_COLOR_B; |
|
80 |
||
81 |
#if PJ_LOG_USE_STACK_BUFFER==0
|
|
82 |
static char log_buffer[PJ_LOG_MAX_SIZE]; |
|
83 |
#endif
|
|
84 |
||
85 |
#define LOG_MAX_INDENT 80
|
|
86 |
||
87 |
#if PJ_HAS_THREADS
|
|
88 |
static void logging_shutdown(void) |
|
89 |
{
|
|
90 |
if (thread_suspended_tls_id != -1) { |
|
91 |
pj_thread_local_free(thread_suspended_tls_id); |
|
92 |
thread_suspended_tls_id = -1; |
|
93 |
}
|
|
94 |
# if PJ_LOG_ENABLE_INDENT
|
|
95 |
if (thread_indent_tls_id != -1) { |
|
96 |
pj_thread_local_free(thread_indent_tls_id); |
|
97 |
thread_indent_tls_id = -1; |
|
98 |
}
|
|
99 |
# endif
|
|
100 |
}
|
|
101 |
#endif /* PJ_HAS_THREADS */ |
|
102 |
||
103 |
#if PJ_LOG_ENABLE_INDENT && PJ_HAS_THREADS
|
|
104 |
static void log_set_indent(int indent) |
|
105 |
{
|
|
106 |
if (indent < 0) indent = 0; |
|
107 |
pj_thread_local_set(thread_indent_tls_id, (void*)(pj_ssize_t)indent); |
|
108 |
}
|
|
109 |
||
110 |
static int log_get_raw_indent(void) |
|
111 |
{
|
|
112 |
return (long)(pj_ssize_t)pj_thread_local_get(thread_indent_tls_id); |
|
113 |
}
|
|
114 |
||
115 |
#else
|
|
116 |
static void log_set_indent(int indent) |
|
117 |
{
|
|
118 |
log_indent = indent; |
|
119 |
if (log_indent < 0) log_indent = 0; |
|
120 |
}
|
|
121 |
||
122 |
static int log_get_raw_indent(void) |
|
123 |
{
|
|
124 |
return log_indent; |
|
125 |
}
|
|
126 |
#endif /* PJ_LOG_ENABLE_INDENT && PJ_HAS_THREADS */ |
|
127 |
||
128 |
static int log_get_indent(void) |
|
129 |
{
|
|
130 |
int indent = log_get_raw_indent(); |
|
131 |
return indent > LOG_MAX_INDENT ? LOG_MAX_INDENT : indent; |
|
132 |
}
|
|
133 |
||
134 |
PJ_DEF(void) pj_log_add_indent(int indent) |
|
135 |
{
|
|
136 |
log_set_indent(log_get_raw_indent() + indent); |
|
137 |
}
|
|
138 |
||
139 |
PJ_DEF(void) pj_log_push_indent(void) |
|
140 |
{
|
|
141 |
pj_log_add_indent(PJ_LOG_INDENT_SIZE); |
|
142 |
}
|
|
143 |
||
144 |
PJ_DEF(void) pj_log_pop_indent(void) |
|
145 |
{
|
|
146 |
pj_log_add_indent(-PJ_LOG_INDENT_SIZE); |
|
147 |
}
|
|
148 |
||
149 |
pj_status_t pj_log_init(void) |
|
150 |
{
|
|
151 |
#if PJ_HAS_THREADS
|
|
152 |
if (thread_suspended_tls_id == -1) { |
|
153 |
pj_status_t status; |
|
154 |
status = pj_thread_local_alloc(&thread_suspended_tls_id); |
|
155 |
if (status != PJ_SUCCESS) |
|
156 |
return status; |
|
157 |
||
158 |
# if PJ_LOG_ENABLE_INDENT
|
|
159 |
status = pj_thread_local_alloc(&thread_indent_tls_id); |
|
160 |
if (status != PJ_SUCCESS) { |
|
161 |
pj_thread_local_free(thread_suspended_tls_id); |
|
162 |
thread_suspended_tls_id = -1; |
|
163 |
return status; |
|
164 |
}
|
|
165 |
# endif
|
|
166 |
pj_atexit(&logging_shutdown); |
|
167 |
}
|
|
168 |
#endif
|
|
169 |
g_last_thread = NULL; |
|
170 |
return PJ_SUCCESS; |
|
171 |
}
|
|
172 |
||
173 |
PJ_DEF(void) pj_log_set_decor(unsigned decor) |
|
174 |
{
|
|
175 |
log_decor = decor; |
|
176 |
}
|
|
177 |
||
178 |
PJ_DEF(unsigned) pj_log_get_decor(void) |
|
179 |
{
|
|
180 |
return log_decor; |
|
181 |
}
|
|
182 |
||
183 |
PJ_DEF(void) pj_log_set_color(int level, pj_color_t color) |
|
184 |
{
|
|
185 |
switch (level) |
|
186 |
{
|
|
187 |
case 0: PJ_LOG_COLOR_0 = color; |
|
188 |
break; |
|
189 |
case 1: PJ_LOG_COLOR_1 = color; |
|
190 |
break; |
|
191 |
case 2: PJ_LOG_COLOR_2 = color; |
|
192 |
break; |
|
193 |
case 3: PJ_LOG_COLOR_3 = color; |
|
194 |
break; |
|
195 |
case 4: PJ_LOG_COLOR_4 = color; |
|
196 |
break; |
|
197 |
case 5: PJ_LOG_COLOR_5 = color; |
|
198 |
break; |
|
199 |
case 6: PJ_LOG_COLOR_6 = color; |
|
200 |
break; |
|
201 |
/* Default terminal color */
|
|
202 |
case 77: PJ_LOG_COLOR_77 = color; |
|
203 |
break; |
|
204 |
default: |
|
205 |
/* Do nothing */
|
|
206 |
break; |
|
207 |
}
|
|
208 |
}
|
|
209 |
||
210 |
PJ_DEF(pj_color_t) pj_log_get_color(int level) |
|
211 |
{
|
|
212 |
switch (level) { |
|
213 |
case 0: |
|
214 |
return PJ_LOG_COLOR_0; |
|
215 |
case 1: |
|
216 |
return PJ_LOG_COLOR_1; |
|
217 |
case 2: |
|
218 |
return PJ_LOG_COLOR_2; |
|
219 |
case 3: |
|
220 |
return PJ_LOG_COLOR_3; |
|
221 |
case 4: |
|
222 |
return PJ_LOG_COLOR_4; |
|
223 |
case 5: |
|
224 |
return PJ_LOG_COLOR_5; |
|
225 |
case 6: |
|
226 |
return PJ_LOG_COLOR_6; |
|
227 |
default: |
|
228 |
/* Return default terminal color */
|
|
229 |
return PJ_LOG_COLOR_77; |
|
230 |
}
|
|
231 |
}
|
|
232 |
||
233 |
PJ_DEF(void) pj_log_set_level(int level) |
|
234 |
{
|
|
235 |
pj_log_max_level = level; |
|
236 |
}
|
|
237 |
||
238 |
#if 1
|
|
239 |
PJ_DEF(int) pj_log_get_level(void) |
|
240 |
{
|
|
241 |
return pj_log_max_level; |
|
242 |
}
|
|
243 |
#endif
|
|
244 |
||
245 |
PJ_DEF(void) pj_log_set_log_func( pj_log_func *func ) |
|
246 |
{
|
|
247 |
log_writer = func; |
|
248 |
}
|
|
249 |
||
250 |
PJ_DEF(pj_log_func*) pj_log_get_log_func(void) |
|
251 |
{
|
|
252 |
return log_writer; |
|
253 |
}
|
|
254 |
||
255 |
/* Temporarily suspend logging facility for this thread.
|
|
256 |
* If thread local storage/variable is not used or not initialized, then
|
|
257 |
* we can only suspend the logging globally across all threads. This may
|
|
258 |
* happen e.g. when log function is called before PJLIB is fully initialized
|
|
259 |
* or after PJLIB is shutdown.
|
|
260 |
*/
|
|
261 |
static void suspend_logging(int *saved_level) |
|
262 |
{
|
|
263 |
/* Save the level regardless, just in case PJLIB is shutdown
|
|
264 |
* between suspend and resume.
|
|
265 |
*/
|
|
266 |
*saved_level = pj_log_max_level; |
|
267 |
||
268 |
#if PJ_HAS_THREADS
|
|
269 |
if (thread_suspended_tls_id != -1) |
|
270 |
{
|
|
271 |
pj_thread_local_set(thread_suspended_tls_id, |
|
272 |
(void*)(pj_ssize_t)PJ_TRUE); |
|
273 |
}
|
|
274 |
else
|
|
275 |
#endif
|
|
276 |
{
|
|
277 |
pj_log_max_level = 0; |
|
278 |
}
|
|
279 |
}
|
|
280 |
||
281 |
/* Resume logging facility for this thread */
|
|
282 |
static void resume_logging(int *saved_level) |
|
283 |
{
|
|
284 |
#if PJ_HAS_THREADS
|
|
285 |
if (thread_suspended_tls_id != -1) |
|
286 |
{
|
|
287 |
pj_thread_local_set(thread_suspended_tls_id, |
|
288 |
(void*)(pj_size_t)PJ_FALSE); |
|
289 |
}
|
|
290 |
else
|
|
291 |
#endif
|
|
292 |
{
|
|
293 |
/* Only revert the level if application doesn't change the
|
|
294 |
* logging level between suspend and resume.
|
|
295 |
*/
|
|
296 |
if (pj_log_max_level==0 && *saved_level) |
|
297 |
pj_log_max_level = *saved_level; |
|
298 |
}
|
|
299 |
}
|
|
300 |
||
301 |
/* Is logging facility suspended for this thread? */
|
|
302 |
static pj_bool_t is_logging_suspended(void) |
|
303 |
{
|
|
304 |
#if PJ_HAS_THREADS
|
|
305 |
if (thread_suspended_tls_id != -1) |
|
306 |
{
|
|
307 |
return pj_thread_local_get(thread_suspended_tls_id) != NULL; |
|
308 |
}
|
|
309 |
else
|
|
310 |
#endif
|
|
311 |
{
|
|
312 |
return pj_log_max_level == 0; |
|
313 |
}
|
|
314 |
}
|
|
315 |
||
316 |
PJ_DEF(void) pj_log( const char *sender, int level, |
|
317 |
const char *format, va_list marker) |
|
318 |
{
|
|
319 |
pj_time_val now; |
|
320 |
pj_parsed_time ptime; |
|
321 |
char *pre; |
|
322 |
#if PJ_LOG_USE_STACK_BUFFER
|
|
323 |
char log_buffer[PJ_LOG_MAX_SIZE]; |
|
324 |
#endif
|
|
325 |
int saved_level, len, print_len, indent; |
|
326 |
||
327 |
PJ_CHECK_STACK(); |
|
328 |
||
329 |
if (level > pj_log_max_level) |
|
330 |
return; |
|
331 |
||
332 |
if (is_logging_suspended()) |
|
333 |
return; |
|
334 |
||
335 |
/* Temporarily disable logging for this thread. Some of PJLIB APIs that
|
|
336 |
* this function calls below will recursively call the logging function
|
|
337 |
* back, hence it will cause infinite recursive calls if we allow that.
|
|
338 |
*/
|
|
339 |
suspend_logging(&saved_level); |
|
340 |
||
341 |
/* Get current date/time. */
|
|
342 |
pj_gettimeofday(&now); |
|
343 |
pj_time_decode(&now, &ptime); |
|
344 |
||
345 |
pre = log_buffer; |
|
346 |
if (log_decor & PJ_LOG_HAS_LEVEL_TEXT) { |
|
347 |
static const char *ltexts[] = { "FATAL:", "ERROR:", " WARN:", |
|
348 |
" INFO:", "DEBUG:", "TRACE:", "DETRC:"}; |
|
349 |
pj_ansi_strcpy(pre, ltexts[level]); |
|
350 |
pre += 6; |
|
351 |
}
|
|
352 |
if (log_decor & PJ_LOG_HAS_DAY_NAME) { |
|
353 |
static const char *wdays[] = { "Sun", "Mon", "Tue", "Wed", |
|
354 |
"Thu", "Fri", "Sat"}; |
|
355 |
pj_ansi_strcpy(pre, wdays[ptime.wday]); |
|
356 |
pre += 3; |
|
357 |
}
|
|
358 |
if (log_decor & PJ_LOG_HAS_YEAR) { |
|
359 |
if (pre!=log_buffer) *pre++ = ' '; |
|
360 |
pre += pj_utoa(ptime.year, pre); |
|
361 |
}
|
|
362 |
if (log_decor & PJ_LOG_HAS_MONTH) { |
|
363 |
*pre++ = '-'; |
|
364 |
pre += pj_utoa_pad(ptime.mon+1, pre, 2, '0'); |
|
365 |
}
|
|
366 |
if (log_decor & PJ_LOG_HAS_DAY_OF_MON) { |
|
367 |
*pre++ = '-'; |
|
368 |
pre += pj_utoa_pad(ptime.day, pre, 2, '0'); |
|
369 |
}
|
|
370 |
if (log_decor & PJ_LOG_HAS_TIME) { |
|
371 |
if (pre!=log_buffer) *pre++ = ' '; |
|
372 |
pre += pj_utoa_pad(ptime.hour, pre, 2, '0'); |
|
373 |
*pre++ = ':'; |
|
374 |
pre += pj_utoa_pad(ptime.min, pre, 2, '0'); |
|
375 |
*pre++ = ':'; |
|
376 |
pre += pj_utoa_pad(ptime.sec, pre, 2, '0'); |
|
377 |
}
|
|
378 |
if (log_decor & PJ_LOG_HAS_MICRO_SEC) { |
|
379 |
*pre++ = '.'; |
|
380 |
pre += pj_utoa_pad(ptime.msec, pre, 3, '0'); |
|
381 |
}
|
|
382 |
if (log_decor & PJ_LOG_HAS_SENDER) { |
|
383 |
enum { SENDER_WIDTH = 14 }; |
|
384 |
pj_size_t sender_len = strlen(sender); |
|
385 |
if (pre!=log_buffer) *pre++ = ' '; |
|
386 |
if (sender_len <= SENDER_WIDTH) { |
|
387 |
while (sender_len < SENDER_WIDTH) |
|
388 |
*pre++ = ' ', ++sender_len; |
|
389 |
while (*sender) |
|
390 |
*pre++ = *sender++; |
|
391 |
} else { |
|
392 |
int i; |
|
393 |
for (i=0; i<SENDER_WIDTH; ++i) |
|
394 |
*pre++ = *sender++; |
|
395 |
}
|
|
396 |
}
|
|
397 |
if (log_decor & PJ_LOG_HAS_THREAD_ID) { |
|
398 |
enum { THREAD_WIDTH = 12 }; |
|
399 |
const char *thread_name = pj_thread_get_name(pj_thread_this()); |
|
400 |
pj_size_t thread_len = strlen(thread_name); |
|
401 |
*pre++ = ' '; |
|
402 |
if (thread_len <= THREAD_WIDTH) { |
|
403 |
while (thread_len < THREAD_WIDTH) |
|
404 |
*pre++ = ' ', ++thread_len; |
|
405 |
while (*thread_name) |
|
406 |
*pre++ = *thread_name++; |
|
407 |
} else { |
|
408 |
int i; |
|
409 |
for (i=0; i<THREAD_WIDTH; ++i) |
|
410 |
*pre++ = *thread_name++; |
|
411 |
}
|
|
412 |
}
|
|
413 |
||
414 |
if (log_decor != 0 && log_decor != PJ_LOG_HAS_NEWLINE) |
|
415 |
*pre++ = ' '; |
|
416 |
||
417 |
if (log_decor & PJ_LOG_HAS_THREAD_SWC) { |
|
418 |
void *current_thread = (void*)pj_thread_this(); |
|
419 |
if (current_thread != g_last_thread) { |
|
420 |
*pre++ = '!'; |
|
421 |
g_last_thread = current_thread; |
|
422 |
} else { |
|
423 |
*pre++ = ' '; |
|
424 |
}
|
|
425 |
} else if (log_decor & PJ_LOG_HAS_SPACE) { |
|
426 |
*pre++ = ' '; |
|
427 |
}
|
|
428 |
||
429 |
#if PJ_LOG_ENABLE_INDENT
|
|
430 |
if (log_decor & PJ_LOG_HAS_INDENT) { |
|
431 |
indent = log_get_indent(); |
|
432 |
if (indent > 0) { |
|
433 |
pj_memset(pre, PJ_LOG_INDENT_CHAR, indent); |
|
434 |
pre += indent; |
|
435 |
}
|
|
436 |
}
|
|
437 |
#endif
|
|
438 |
||
439 |
len = (int)(pre - log_buffer); |
|
440 |
||
441 |
/* Print the whole message to the string log_buffer. */
|
|
442 |
print_len = pj_ansi_vsnprintf(pre, sizeof(log_buffer)-len, format, |
|
443 |
marker); |
|
444 |
if (print_len < 0) { |
|
445 |
level = 1; |
|
446 |
print_len = pj_ansi_snprintf(pre, sizeof(log_buffer)-len, |
|
447 |
"<logging error: msg too long>"); |
|
448 |
}
|
|
449 |
if (print_len < 1 || print_len >= (int)(sizeof(log_buffer)-len)) { |
|
450 |
print_len = sizeof(log_buffer) - len - 1; |
|
451 |
}
|
|
452 |
len = len + print_len; |
|
453 |
if (len > 0 && len < (int)sizeof(log_buffer)-2) { |
|
454 |
if (log_decor & PJ_LOG_HAS_CR) { |
|
455 |
log_buffer[len++] = '\r'; |
|
456 |
}
|
|
457 |
if (log_decor & PJ_LOG_HAS_NEWLINE) { |
|
458 |
log_buffer[len++] = '\n'; |
|
459 |
}
|
|
460 |
log_buffer[len] = '\0'; |
|
461 |
} else { |
|
462 |
len = sizeof(log_buffer)-1; |
|
463 |
if (log_decor & PJ_LOG_HAS_CR) { |
|
464 |
log_buffer[sizeof(log_buffer)-3] = '\r'; |
|
465 |
}
|
|
466 |
if (log_decor & PJ_LOG_HAS_NEWLINE) { |
|
467 |
log_buffer[sizeof(log_buffer)-2] = '\n'; |
|
468 |
}
|
|
469 |
log_buffer[sizeof(log_buffer)-1] = '\0'; |
|
470 |
}
|
|
471 |
||
472 |
/* It should be safe to resume logging at this point. Application can
|
|
473 |
* recursively call the logging function inside the callback.
|
|
474 |
*/
|
|
475 |
resume_logging(&saved_level); |
|
476 |
||
477 |
if (log_writer) |
|
478 |
(*log_writer)(level, log_buffer, len); |
|
479 |
}
|
|
480 |
||
481 |
/*
|
|
482 |
PJ_DEF(void) pj_log_0(const char *obj, const char *format, ...)
|
|
483 |
{
|
|
484 |
va_list arg;
|
|
485 |
va_start(arg, format);
|
|
486 |
pj_log(obj, 0, format, arg);
|
|
487 |
va_end(arg);
|
|
488 |
}
|
|
489 |
*/
|
|
490 |
||
491 |
PJ_DEF(void) pj_log_1(const char *obj, const char *format, ...) |
|
492 |
{
|
|
493 |
va_list arg; |
|
494 |
va_start(arg, format); |
|
495 |
pj_log(obj, 1, format, arg); |
|
496 |
va_end(arg); |
|
497 |
}
|
|
498 |
#endif /* PJ_LOG_MAX_LEVEL >= 1 */ |
|
499 |
||
500 |
#if PJ_LOG_MAX_LEVEL >= 2
|
|
501 |
PJ_DEF(void) pj_log_2(const char *obj, const char *format, ...) |
|
502 |
{
|
|
503 |
va_list arg; |
|
504 |
va_start(arg, format); |
|
505 |
pj_log(obj, 2, format, arg); |
|
506 |
va_end(arg); |
|
507 |
}
|
|
508 |
#endif
|
|
509 |
||
510 |
#if PJ_LOG_MAX_LEVEL >= 3
|
|
511 |
PJ_DEF(void) pj_log_3(const char *obj, const char *format, ...) |
|
512 |
{
|
|
513 |
va_list arg; |
|
514 |
va_start(arg, format); |
|
515 |
pj_log(obj, 3, format, arg); |
|
516 |
va_end(arg); |
|
517 |
}
|
|
518 |
#endif
|
|
519 |
||
520 |
#if PJ_LOG_MAX_LEVEL >= 4
|
|
521 |
PJ_DEF(void) pj_log_4(const char *obj, const char *format, ...) |
|
522 |
{
|
|
523 |
va_list arg; |
|
524 |
va_start(arg, format); |
|
525 |
pj_log(obj, 4, format, arg); |
|
526 |
va_end(arg); |
|
527 |
}
|
|
528 |
#endif
|
|
529 |
||
530 |
#if PJ_LOG_MAX_LEVEL >= 5
|
|
531 |
PJ_DEF(void) pj_log_5(const char *obj, const char *format, ...) |
|
532 |
{
|
|
533 |
va_list arg; |
|
534 |
va_start(arg, format); |
|
535 |
pj_log(obj, 5, format, arg); |
|
536 |
va_end(arg); |
|
537 |
}
|
|
538 |
#endif
|
|
539 |
||
540 |
#if PJ_LOG_MAX_LEVEL >= 6
|
|
541 |
PJ_DEF(void) pj_log_6(const char *obj, const char *format, ...) |
|
542 |
{
|
|
543 |
va_list arg; |
|
544 |
va_start(arg, format); |
|
545 |
pj_log(obj, 6, format, arg); |
|
546 |
va_end(arg); |
|
547 |
}
|
|
548 |
#endif
|
|
549 |