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