2 nobug.h - a small debugging library
4 Copyright (C) 2006, 2007, Christian Thaeter <ct@pipapo.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
22 #ifndef NOBUG_LIBNOBUG_C /* not when building libnobug */
25 #error NDEBUG incompatible with -DEBUG_ALPHA
28 #error NDEBUG incompatible with -DEBUG_BETA
32 #if defined(EBUG_ALPHA)
33 # define NOBUG_MODE_ALPHA 1
34 # define NOBUG_MODE_BETA 0
35 # define NOBUG_MODE_RELEASE 0
36 #elif defined(EBUG_BETA)
37 # define NOBUG_MODE_ALPHA 0
38 # define NOBUG_MODE_BETA 1
39 # define NOBUG_MODE_RELEASE 0
41 # define NOBUG_MODE_ALPHA 0
42 # define NOBUG_MODE_BETA 0
43 # define NOBUG_MODE_RELEASE 1
45 #error no debug level and no NDEBUG defined
47 #endif /* NOBUG_LIBNOBUG_C */
58 #ifdef HAVE_EXECINFO_H
59 # ifndef NOBUG_USE_EXECINFO
60 # define NOBUG_USE_EXECINFO 1
63 # undef NOBUG_USE_EXECINFO
64 # define NOBUG_USE_EXECINFO 0
67 #if NOBUG_USE_EXECINFO
71 #if defined(HAVE_VALGRIND_VALGRIND_H) && !defined(NVALGRIND)
72 # ifndef NOBUG_USE_VALGRIND
73 # define NOBUG_USE_VALGRIND 1
76 # undef NOBUG_USE_VALGRIND
77 # define NOBUG_USE_VALGRIND 0
80 #if NOBUG_USE_VALGRIND
81 #include <valgrind/valgrind.h>
85 # ifndef NOBUG_USE_PTHREAD
86 # define NOBUG_USE_PTHREAD 1
89 # undef NOBUG_USE_PTHREAD
90 # define NOBUG_USE_PTHREAD 0
98 #ifndef NOBUG_LIBNOBUG_C /* not when building libnobug */
102 #if NOBUG_MODE_RELEASE==0
104 #define assert(expr) NOBUG_ASSERT(expr)
108 check preconditions (incoming parameters)
111 #define NOBUG_REQUIRE(expr, ...) \
112 NOBUG_IF_NOT_RELEASE(NOBUG_ASSERT_(expr, "PRECONDITION", \
113 NOBUG_LOCATION_INFO, ## __VA_ARGS__))
116 #define NOBUG_REQUIRE_DBG(expr, ...) \
117 NOBUG_IF_NOT_RELEASE(NOBUG_ASSERT_DBG_(expr, "PRECONDITION", \
118 NOBUG_LOCATION_INFO, ## __VA_ARGS__))
121 #define NOBUG_REQUIRE_IF(when, expr, ...) \
122 NOBUG_WHEN(when, NOBUG_REQUIRE(expr, ## __VA_ARGS__))
124 #define NOBUG_REQUIRE_IF_DBG(when, expr, ...) \
125 NOBUG_WHEN(when, NOBUG_REQUIRE_DBG(expr, ## __VA_ARGS__))
128 check postcondistions (computation outcomes)
130 #define NOBUG_ENSURE(expr, ...) \
132 NOBUG_ASSERT_(expr, "POSTCONDITION", \
133 NOBUG_LOCATION_INFO, ## __VA_ARGS__), \
135 if (NOBUG_SCOPE_UNCHECKED) \
137 NOBUG_ASSERT_(expr, "POSTCONDITION", \
138 NOBUG_LOCATION_INFO, ## __VA_ARGS__); \
144 #define NOBUG_ENSURE_DBG(expr, ...) \
146 NOBUG_ASSERT_DBG_(expr, "POSTCONDITION", \
147 NOBUG_LOCATION_INFO, ## __VA_ARGS__), \
149 if (NOBUG_SCOPE_UNCHECKED) \
151 NOBUG_ASSERT_DBG_(expr, "POSTCONDITION", \
152 NOBUG_LOCATION_INFO, ## __VA_ARGS__); \
158 #define NOBUG_ENSURE_IF(when, expr, ...) \
159 NOBUG_WHEN(when, NOBUG_ENSURE(expr, ## __VA_ARGS__))
161 #define NOBUG_ENSURE_IF_DBG(when, expr, ...) \
162 NOBUG_WHEN(when, NOBUG_ENSURE_DBG(expr, ## __VA_ARGS__))
169 #define NOBUG_ASSERT(expr, ...) \
170 NOBUG_IF_NOT_RELEASE( \
172 NOBUG_ASSERT_(expr, "ASSERTION", NOBUG_LOCATION_INFO, ## __VA_ARGS__) \
175 #define NOBUG_ASSERT_DBG(expr, ...) \
176 NOBUG_IF_NOT_RELEASE( \
178 NOBUG_ASSERT_DBG_(expr, "ASSERTION", \
179 NOBUG_LOCATION_INFO, ## __VA_ARGS__); \
183 #define NOBUG_ASSERT_IF(when, expr, ...) \
184 NOBUG_WHEN(when, NOBUG_ASSERT(expr, ## __VA_ARGS__))
186 #define NOBUG_ASSERT_IF_DBG(when, expr, ...) \
187 NOBUG_WHEN(when, NOBUG_ASSERT_DBG(expr, ## __VA_ARGS__))
192 #define NOBUG_ASSERT_(expr, what, location, ...) \
193 if (NOBUG_EXPECT_FALSE(!(expr))) \
195 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, \
196 location, what, "(%s) " \
197 NOBUG_HEAD(__VA_ARGS__), \
198 #expr NOBUG_TAIL(__VA_ARGS__)); \
203 #define NOBUG_ASSERT_DBG_(expr, what, location, ...) \
204 NOBUG_IF_DBG_ACTIVE( \
205 if (NOBUG_EXPECT_FALSE(!(expr))) \
207 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, \
208 location, what, "(%s) " \
209 NOBUG_HEAD(__VA_ARGS__), \
210 #expr NOBUG_TAIL(__VA_ARGS__)); \
215 #define NOBUG_ASSERTN_(expr, what, location, ...) \
216 if (NOBUG_EXPECT_FALSE(!(expr))) \
218 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, \
230 #define NOBUG_INVARIANT(type, pointer, depth) \
233 if (NOBUG_SCOPE_UNCHECKED) \
235 NOBUG_CAT(type,_invariant)(pointer, depth, \
236 NOBUG_LOCATION_ARGS); \
239 NOBUG_PASS, NOBUG_PASS \
242 #define NOBUG_INVARIANT_DBG(type, pointer, ...) \
244 NOBUG_IF_DBG_ACTIVE ( \
245 if (NOBUG_SCOPE_UNCHECKED) \
247 NOBUG_CAT(type,_invariant)(pointer, depth, NOBUG_LOCATION_ARGS); \
250 NOBUG_PASS, NOBUG_PASS \
253 #define NOBUG_INVARIANT_IF(when, type, pointer, ...) \
254 NOBUG_WHEN(when, NOBUG_INVARIANT(type, pointer, ## __VA_ARGS__))
256 #define NOBUG_INVARIANT_IF_DBG(when, type, pointer, ...) \
257 NOBUG_WHEN(when, NOBUG_INVARIANT_DBG(type, pointer, ## __VA_ARGS__))
259 #define NOBUG_INVARIANT_ASSERT(expr, ...) \
260 NOBUG_ASSERT_(expr, "INVARIANT", (file, line, func), ## __VA_ARGS__)
264 dumping datastructures
266 /*TODO dump-level for flags instead limits[0]*/
267 #define NOBUG_DUMP(flag, type, pointer, depth) \
268 NOBUG_IF_NOT_RELEASE( \
270 if (NOBUG_EXPECT_FALSE (NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
273 NOBUG_CAT3(nobug_, type, _dump)(pointer, depth, \
274 NOBUG_LOCATION_ARGS); \
278 #define NOBUG_DUMP_DBG(flag, type, pointer, depth) \
279 NOBUG_IF_NOT_RELEASE( \
281 NOBUG_IF_DBG_ACTIVE ( \
282 if (NOBUG_EXPECT_FALSE(NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
284 NOBUG_CAT3(nobug_, type, _dump)(pointer, depth, \
285 NOBUG_LOCATION_ARGS); \
289 #define NOBUG_DUMP_IF(expr, flag, type, pointer, depth) \
291 if (NOBUG_EXPECT_FALSE(NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
293 if (NOBUG_EXPECT_FALSE(expr)) \
295 NOBUG_CAT3(nobug_, type,_dump)(pointer, depth, \
296 NOBUG_LOCATION_ARGS); \
300 #define NOBUG_DUMP_IF_DBG(expr, flag, type, pointer, depth) \
301 NOBUG_IF_NOT_RELEASE( \
302 NOBUG_IF_DBG_ACTIVE ( \
303 if (NOBUG_EXPECT_FALSE(NOBUG_DUMP_LEVEL <= nobug_flag_##flag.limits[0])) \
305 if (NOBUG_EXPECT_FALSE(expr)) \
307 NOBUG_CAT(nobug_, type,_dump)(pointer, depth, \
308 NOBUG_LOCATION_ARGS); \
312 #ifndef NOBUG_DUMP_LEVEL
313 #define NOBUG_DUMP_LEVEL LOG_DEBUG
316 #define NOBUG_DUMP_LOG(fmt, ...) \
317 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
318 (file, line, func), "DUMP", \
322 #define NOBUG_DUMP_LOG_DBG(fmt, ...) \
323 NOBUG_IF_DBG_ACTIVE ( \
324 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
325 (file, line, func), "DUMP", \
326 fmt, ## __VA_ARGS__) \
329 #define NOBUG_DUMP_LOG_IF(expr, fmt, ...) \
331 if (NOBUG_EXPECT_FALSE(expr)) { \
332 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
333 (file, line, func), "DUMP", \
334 fmt, ## __VA_ARGS__) \
338 #define NOBUG_DUMP_LOG_IF_DBG(expr, fmt, ...) \
339 NOBUG_IF_DBG_ACTIVE ( \
340 if (NOBUG_EXPECT_FALSE(expr)) { \
341 NOBUG_LOG_( NOBUG_ON, NOBUG_DUMP_LEVEL, \
342 (file), line, func), "DUMP", \
343 fmt, ## __VA_ARGS__) \
351 #define NOBUG_LOG(flag, lvl, ...) \
353 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
354 NOBUG_LVL(lvl), ## __VA_ARGS__); \
357 #define NOBUG_LOG_DBG(flag, lvl, ...) \
358 NOBUG_IF_DBG_ACTIVE ( \
359 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
360 NOBUG_LVL(lvl), ## __VA_ARGS__); \
363 #define NOBUG_LOG_IF(expr, flag, lvl, ...) \
365 if (NOBUG_EXPECT_FALSE(expr)) { \
366 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
367 NOBUG_LVL(lvl), ## __VA_ARGS__); \
371 #define NOBUG_LOG_IF_DBG(expr, flag, lvl, ...) \
372 NOBUG_IF_DBG_ACTIVE ( \
373 if (NOBUG_EXPECT_FALSE(expr)) { \
374 NOBUG_LOG_(flag, lvl, NOBUG_LOCATION_INFO, \
375 NOBUG_LVL(lvl), ## __VA_ARGS__); \
379 #define NOBUG_LVL(lvl) NOBUG_LVL_##lvl
380 #define NOBUG_LVL_0 "EMERG"
381 #define NOBUG_LVL_1 "ALERT"
382 #define NOBUG_LVL_2 "CRIT"
383 #define NOBUG_LVL_3 "ERR"
384 #define NOBUG_LVL_4 "WARNING"
385 #define NOBUG_LVL_5 "NOTICE"
386 #define NOBUG_LVL_6 "INFO"
387 #define NOBUG_LVL_7 "TRACE"
391 low level logging handler
393 #define NOBUG_LOG_(flag, lvl, location, what, ...) \
394 if (NOBUG_EXPECT_FALSE(lvl <= NOBUG_FLAG(flag).limits[NOBUG_TARGET_RINGBUFFER])) \
397 char * log = nobug_ringbuffer_pos (NOBUG_FLAG(flag).ringbuffer_target); \
398 nobug_ringbuffer_printf(NOBUG_FLAG(flag).ringbuffer_target, \
399 "%s:%d: %s:"NOBUG_THREAD_ID_FMT(" ",":")" %s: "NOBUG_HEAD(__VA_ARGS__), \
400 NOBUG_LOCATION_FILE location, NOBUG_LOCATION_LINE location, \
401 what NOBUG_THREAD_ID_COMMA, NOBUG_LOCATION_FUNC location NOBUG_TAIL(__VA_ARGS__)); \
402 if (NOBUG_EXPECT_FALSE(lvl <= NOBUG_FLAG(flag).limits[NOBUG_TARGET_CONSOLE])){ \
403 NOBUG_MODE_SWITCH ( \
404 NOBUG_IF(NOBUG_USE_VALGRIND, \
405 if (NOBUG_EXPECT_FALSE (NOBUG_DBG_ACTIVE)) { \
406 VALGRIND_PRINTF ("%s\n", log); \
408 fprintf(NOBUG_FLAG(flag).console_target?NOBUG_FLAG(flag).console_target:stderr, \
411 fprintf(NOBUG_FLAG(flag).console_target?NOBUG_FLAG(flag).console_target:stderr, \
414 fprintf(NOBUG_FLAG(flag).console_target?NOBUG_FLAG(flag).console_target:stderr, \
417 if (NOBUG_EXPECT_FALSE(lvl <= NOBUG_FLAG(flag).limits[NOBUG_TARGET_FILE] \
418 && NOBUG_FLAG(flag).file_target)){ \
419 fprintf(NOBUG_FLAG(flag).file_target, "%s\n", log); \
421 if (NOBUG_EXPECT_FALSE(lvl <= NOBUG_FLAG(flag).limits[NOBUG_TARGET_SYSLOG])){ \
422 syslog(lvl, "%s\n", log); \
428 NOBUG_IF(NOBUG_USE_XXXX_TARGET ...
430 NOBUG_TARGET_APPLICATION
433 #define NOBUG_LOCATION_ARGS NOBUG_BASENAME(__FILE__), __LINE__, __func__
434 #define NOBUG_LOCATION_INFO (NOBUG_LOCATION_ARGS)
436 #define NOBUG_LOCATION_FILE(file, _1, _2) file
437 #define NOBUG_LOCATION_LINE(_1, line, _2) line
438 #define NOBUG_LOCATION_FUNC(_1, _2, func) func
441 /*TODO better location handling, no text? empty on RELEASE*/
442 #define NOBUG_LOCATION(text) \
444 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__) text), \
445 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__) text), \
449 #define NOBUG_ERROR(flag, ...) \
450 NOBUG_LOG(flag, LOG_ERR, ## __VA_ARGS__)
451 #define NOBUG_ERROR_IF(expr, flag, ...) \
452 NOBUG_LOG_IF(expr, flag, LOG_ERR, ## __VA_ARGS__)
453 #define NOBUG_ERROR_DBG(flag, ...) \
454 NOBUG_LOG_DBG(flag, LOG_ERR, ## __VA_ARGS__)
455 #define NOBUG_ERROR_IF_DBG(expr, flag, ...) \
456 NOBUG_LOG_IF_DBG(expr, flag, LOG_ERR, ## __VA_ARGS__)
458 #define NOBUG_WARN(flag, ...) \
459 NOBUG_LOG(flag, LOG_WARNING, ## __VA_ARGS__)
460 #define NOBUG_WARN_IF(expr, flag, ...) \
461 NOBUG_LOG_IF(expr, flag, LOG_WARNING, ## __VA_ARGS__)
462 #define NOBUG_WARN_DBG(flag, ...) \
463 NOBUG_LOG_DBG(flag, LOG_WARNING, ## __VA_ARGS__)
464 #define NOBUG_WARN_IF_DBG(expr, flag, ...) \
465 NOBUG_LOG_IF_DBG(expr, flag, LOG_WARNING, ## __VA_ARGS__)
467 #define NOBUG_INFO(flag, ...) \
468 NOBUG_LOG(flag, LOG_INFO, ## __VA_ARGS__)
469 #define NOBUG_INFO_IF(expr, flag, ...) \
470 NOBUG_LOG_IF(expr, flag, LOG_INFO, ## __VA_ARGS__)
471 #define NOBUG_INFO_DBG(flag, ...) \
472 NOBUG_LOG_DBG(flag, LOG_INFO, ## __VA_ARGS__)
473 #define NOBUG_INFO_IF_DBG(expr, flag, ...) \
474 NOBUG_LOG_IF_DBG(expr, flag, LOG_INFO, ## __VA_ARGS__)
476 #define NOBUG_NOTICE(flag, ...) \
477 NOBUG_LOG(flag, LOG_NOTICE, ## __VA_ARGS__)
478 #define NOBUG_NOTICE_IF(expr, flag, ...) \
479 NOBUG_LOG_IF(expr, flag, LOG_NOTICE, ## __VA_ARGS__)
480 #define NOBUG_NOTICE_DBG(flag, ...) \
481 NOBUG_LOG_DBG(flag, LOG_NOTICE, ## __VA_ARGS__)
482 #define NOBUG_NOTICE_IF_DBG(expr, flag, ...) \
483 NOBUG_LOG_IF_DBG(expr, flag, LOG_NOTICE, ## __VA_ARGS__)
485 #define NOBUG_TRACE(flag, ...) \
486 NOBUG_LOG(flag, LOG_DEBUG, ## __VA_ARGS__)
487 #define NOBUG_TRACE_IF(expr, flag, ...) \
488 NOBUG_LOG_IF(expr, flag, LOG_DEBUG, ## __VA_ARGS__)
489 #define NOBUG_TRACE_DBG(flag, ...) \
490 NOBUG_LOG_DBG(flag, LOG_DEBUG, ## __VA_ARGS__)
491 #define NOBUG_TRACE_IF_DBG(expr, flag, ...) \
492 NOBUG_LOG_IF_DBG(expr, flag, LOG_DEBUG, ## __VA_ARGS__)
494 #define NOBUG_BASENAME(name) (strrchr((name), '/')?strrchr((name), '/') + 1 : (name))
496 #define NOBUG_SCOPE_UNCHECKED NOBUG_CHECKED_VALUE == 0
498 #define NOBUG_DBG_ACTIVE \
499 NOBUG_IF(NOBUG_USE_VALGRIND, (RUNNING_ON_VALGRIND?2:0)) \
500 NOBUG_IFNOT(NOBUG_USE_VALGRIND, (0))
504 unchecked Preconditions, Postconditions, Invariants Preconditions, Postconditions compiling will abort
505 checked Preconditions, Postconditions Preconditions
508 #define NOBUG_CHECKED NOBUG_IF_NOT_RELEASE(enum {NOBUG_CHECKED_VALUE=1})
510 #define NOBUG_UNCHECKED \
511 NOBUG_IF_NOT_RELEASE(enum {NOBUG_CHECKED_VALUE=0}) \
512 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_UNCHECKED_NOT_ALLOWED_IN_RELEASE_BUILD)
514 #define NOBUG_ABORT abort()
516 #define NOBUG_DBG_GDB 1
517 #define NOBUG_DBG_VALGRIND 2
519 #define NOBUG_BACKTRACE \
521 switch (NOBUG_DBG_ACTIVE) { \
522 case NOBUG_DBG_VALGRIND: \
523 NOBUG_BACKTRACE_VALGRIND; \
526 NOBUG_BACKTRACE_GLIBC; \
528 NOBUG_BACKTRACE_GLIBC, \
529 NOBUG_BACKTRACE_GLIBC \
532 #define NOBUG_BACKTRACE_DBG \
533 NOBUG_IF_NOT_RELEASE( \
534 switch (NOBUG_DBG_ACTIVE) { \
535 case NOBUG_DBG_VALGRIND: \
536 NOBUG_BACKTRACE_VALGRIND; \
540 #define NOBUG_BACKTRACE_GDB fprintf(stderr, "UNIMPLEMENTED : GDB Backtraces\n")
542 #define NOBUG_BACKTRACE_VALGRIND \
543 NOBUG_IF(NOBUG_USE_VALGRIND, \
544 VALGRIND_PRINTF_BACKTRACE("BACKTRACE : %s@%d %s", \
545 NOBUG_LOCATION_INFO))
548 #ifndef NOBUG_BACKTRACE_DEPTH
549 #define NOBUG_BACKTRACE_DEPTH 256
552 #define NOBUG_BACKTRACE_GLIBC \
553 NOBUG_IF_NOT_RELEASE( \
555 NOBUG_IF(NOBUG_USE_EXECINFO, \
556 void* nobug_backtrace_buffer[NOBUG_BACKTRACE_DEPTH]; \
557 backtrace_symbols_fd (nobug_backtrace_buffer, \
558 backtrace (nobug_backtrace_buffer, NOBUG_BACKTRACE_DEPTH), 2))))
563 DEPRECATED log nothing wont compile
565 #define NOBUG_DEPRECATED(msg) \
568 NOBUG_LOG_ (NOBUG_ON, LOG_ALERT, NOBUG_LOCATION_INFO, \
569 "DEPRECATED", msg); \
572 NOBUG_DEPRECATED_NOT_ALLOWED_IN_RELEASE_BUILD(msg) \
577 UNIMPLEMENTED abort abort wont compile
579 #define NOBUG_UNIMPLEMENTED(msg) \
580 NOBUG_IF_NOT_RELEASE ( \
582 NOBUG_LOG_ (NOBUG_ON, LOG_EMERG, NOBUG_LOCATION_INFO, \
583 "UNIMPLEMENTED", msg); \
586 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_UNIMPLEMENTED_NOT_ALLOWED_IN_RELEASE_BUILD(msg);)
590 FIXME log wont compile wont compile
592 #define NOBUG_FIXME(msg) \
595 NOBUG_LOG_ (NOBUG_ON, LOG_ALERT, NOBUG_LOCATION_INFO, \
598 NOBUG_FIXME_NOT_ALLOWED_IN_BETA_BUILD(msg), \
599 NOBUG_FIXME_NOT_ALLOWED_IN_RELEASE_BUILD(msg) \
604 TODO log log wont compile
606 #define NOBUG_TODO(msg) \
607 NOBUG_IF_NOT_RELEASE ( \
609 NOBUG_LOG_( NOBUG_ON, LOG_CRIT, NOBUG_LOCATION_INFO, \
612 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_TODO_NOT_ALLOWED_IN_RELEASE_BUILD(msg);)
616 PLANNED log nothing nothing
618 #define NOBUG_PLANNED(msg) \
619 NOBUG_MODE_SWITCH ( \
621 NOBUG_LOG_ (NOBUG_ON, LOG_INFO, NOBUG_LOCATION_INFO, \
624 NOBUG_PASS,NOBUG_PASS \
629 NOTREACHED abort abort nothing
631 #define NOBUG_NOTREACHED \
632 NOBUG_IF_NOT_RELEASE ( \
634 NOBUG_LOG_( NOBUG_ON, LOG_EMERG, NOBUG_LOCATION_INFO, \
639 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_PASS)
643 Resource registry macros
645 #ifndef NOBUG_RESOURCE_LOGGING
646 #define NOBUG_RESOURCE_LOGGING 1
649 #ifndef NOBUG_RESOURCE_LOG_LEVEL
650 #define NOBUG_RESOURCE_LOG_LEVEL LOG_DEBUG
653 #define NOBUG_RESOURCE_HANDLE(handle) \
654 NOBUG_IF(NOBUG_MODE_ALPHA, \
655 struct nobug_resource_record* handle)
657 #define NOBUG_RESOURCE_ANNOUNCE(flag, type, name, ptr, handle) \
658 NOBUG_IF(NOBUG_MODE_ALPHA, \
659 NOBUG_ASSERTN_(handle = nobug_resource_announce (type, name, ptr, \
660 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__))), \
661 "RESOURCE_ANNOUNCE", NOBUG_LOCATION_INFO, "%s: %s@%p %s", \
662 type, name, ptr, nobug_resource_error) \
663 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
664 ; NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
665 "RESOURCE_ANNOUNCE", "%s: %s@%p", type, name, ptr) \
668 #define NOBUG_RESOURCE_FORGET(flag, handle) \
669 NOBUG_IF(NOBUG_MODE_ALPHA, \
670 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
671 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
672 "RESOURCE_FORGET", "%s: %s@%p", handle?handle->type:"", \
673 handle?handle->name:"", handle?handle->object_id:NULL); \
675 NOBUG_ASSERTN_(nobug_resource_forget (handle), \
676 "RESOURCE_FORGET", NOBUG_LOCATION_INFO, "%s: %s@%p: %s", \
677 handle?handle->type:"", handle?handle->name:"", \
678 handle?handle->object_id:NULL, nobug_resource_error); \
682 #define NOBUG_RESOURCE_ENTER(flag, resource, user, ptr, state, handle) \
683 NOBUG_IF(NOBUG_MODE_ALPHA, \
684 NOBUG_ASSERTN_(handle = nobug_resource_enter (resource, user, ptr, state, \
685 NOBUG_BASENAME(__FILE__ ":" NOBUG_STRINGIZE(__LINE__))), \
686 "RESOURCE_ENTER", NOBUG_LOCATION_INFO, "%s: %s@%p: %s@%p: %s: %s", \
687 resource?resource->type:"", resource?resource->name:"", \
688 resource?resource->object_id:NULL, \
689 user, ptr, nobug_resource_states[state], nobug_resource_error) \
690 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
691 ; NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
692 "RESOURCE_ENTER", "%s: %s@%p: %s@%p: %s", \
693 resource->type, resource->name, resource->object_id, \
694 user, ptr, nobug_resource_states[state]) \
697 #define NOBUG_RESOURCE_STATE(flag, resource, state) \
698 NOBUG_IF(NOBUG_MODE_ALPHA, \
699 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
700 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
701 "RESOURCE_STATE", "%s: %s@%p: %s@%p: %s->%s", \
702 resource?((struct nobug_resource_record*)resource->data)->type:"", \
703 resource?((struct nobug_resource_record*)resource->data)->name:"", \
704 resource?((struct nobug_resource_record*)resource->data)->object_id:"", \
705 resource?resource->name:NULL, \
706 resource?resource->object_id:NULL, \
707 resource?resource->type:"", nobug_resource_states[state]); \
709 NOBUG_ASSERTN_(nobug_resource_state (resource, state), \
710 "RESOURCE_ENTER", NOBUG_LOCATION_INFO, "%s: %s@%p: %s@%p: %s->%s: %s", \
711 resource?((struct nobug_resource_record*)resource->data)->type:"", \
712 resource?((struct nobug_resource_record*)resource->data)->name:"", \
713 resource?((struct nobug_resource_record*)resource->data)->object_id:"", \
714 resource?resource->name:NULL, \
715 resource?resource->object_id:NULL, \
716 resource?resource->type:"", nobug_resource_states[state], \
717 nobug_resource_error) \
720 #define NOBUG_RESOURCE_LEAVE(flag, handle) \
721 NOBUG_IF(NOBUG_MODE_ALPHA, \
722 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
723 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
724 "RESOURCE_LEAVE", "%s: %s@%p: %s@%p: %s", \
725 handle?((struct nobug_resource_record*)handle->data)->type:"", \
726 handle?((struct nobug_resource_record*)handle->data)->name:"", \
727 handle?((struct nobug_resource_record*)handle->data)->object_id:"", \
728 handle?handle->name:NULL, \
729 handle?handle->object_id:NULL, \
730 handle?handle->type:""); \
732 NOBUG_ASSERTN_(nobug_resource_leave (handle), \
733 "RESOURCE_LEAVE", NOBUG_LOCATION_INFO, "%s: %s@%p: %s@%p: %s: %s", \
734 handle?((struct nobug_resource_record*)handle->data)->type:"", \
735 handle?((struct nobug_resource_record*)handle->data)->name:"", \
736 handle?((struct nobug_resource_record*)handle->data)->object_id:"", \
737 handle?handle->name:NULL, \
738 handle?handle->object_id:NULL, \
739 handle?handle->type:"", \
740 nobug_resource_error); \
743 #define NOBUG_RESOURCE_LEAVE_LOOKUP(flag, handle, ptr) \
744 NOBUG_IF(NOBUG_MODE_ALPHA, \
745 NOBUG_IF(NOBUG_RESOURCE_LOGGING, \
746 NOBUG_LOG_(flag, NOBUG_RESOURCE_LOG_LEVEL, NOBUG_LOCATION_INFO, \
747 "RESOURCE_LEAVE", "%s: %s@%p: @%p", \
748 handle?handle->type:"", \
749 handle?handle->name:"", \
750 handle?handle->object_id:"", \
753 NOBUG_ASSERTN_(nobug_resource_leave (nobug_resource_find(handle, ptr)), \
754 "RESOURCE_LEAVE", NOBUG_LOCATION_INFO, "%s: %s@%p: @%p: %s", \
755 handle?handle->type:"", \
756 handle?handle->name:"", \
757 handle?handle->object_id:"", \
758 ptr, nobug_resource_error) \
764 #if NOBUG_USE_PTHREAD
765 #define NOBUG_LOCK pthread_mutex_lock (&nobug_global_mutex)
766 #define NOBUG_UNLOCK pthread_mutex_unlock (&nobug_global_mutex)
768 #define NOBUG_LOCKED(code) \
774 #define NOBUG_THREAD_ID_SET(name) nobug_thread_id_set(name)
775 #define NOBUG_THREAD_ID_FMT(pre,post) pre "%s" post
776 #define NOBUG_THREAD_ID_COMMA , NOBUG_THREAD_ID_GET
777 #define NOBUG_THREAD_ID_GET nobug_thread_id_get()
780 #define NOBUG_LOCKED(code) code
781 #define NOBUG_THREAD_ID_SET(name)
782 #define NOBUG_THREAD_ID_FMT(pre,post) ""
783 #define NOBUG_THREAD_ID_COMMA
784 #define NOBUG_THREAD_ID_GET ""
790 #define NOBUG_INIT nobug_init()
797 #define NOBUG_CLEANUP(fn) __attribute__((cleanup(fn)))
799 #define NOBUG_CLEANUP(fn)
802 #define NOBUG_ONCE(code) \
804 static int NOBUG_CAT(nobug_once_,__LINE__) = 0; \
805 if (NOBUG_EXPECT_FALSE(!NOBUG_CAT(nobug_once_,__LINE__))) \
807 NOBUG_CAT(nobug_once_,__LINE__) = 1; \
814 #define NOBUG_BLOCK(code) do { code; } while (0)
816 // branch prediction on bools
818 #define NOBUG_EXPECT_FALSE(x) __builtin_expect(!!(x),0)
820 #define NOBUG_EXPECT_FALSE(x) x
823 #define NOBUG_IF_DBG_ACTIVE(code) \
824 NOBUG_IF(NOBUG_MODE_ALPHA, \
826 if (NOBUG_EXPECT_FALSE(NOBUG_DBG_ACTIVE)) \
832 NOBUG_IF(NOBUG_NOT(NOBUG_MODE_ALPHA), NOBUG_PASS)
834 #define NOBUG_WHEN(when, code) \
835 NOBUG_IF_NOT_RELEASE(do{ if (when){code;}}while(0))
837 #define NOBUG_IF_NOT_RELEASE(code) \
838 NOBUG_IF(NOBUG_NOT(NOBUG_MODE_RELEASE), code) \
839 NOBUG_IF(NOBUG_MODE_RELEASE, NOBUG_PASS)
841 #define NOBUG_MODE_SWITCH(alpha_code, beta_code, release_code) \
842 NOBUG_IF(NOBUG_MODE_ALPHA, alpha_code) \
843 NOBUG_IF(NOBUG_MODE_BETA, beta_code) \
844 NOBUG_IF(NOBUG_MODE_RELEASE, release_code)
849 #define NOBUG_FLAG(name) NOBUG_CAT(nobug_flag_,name)
851 #define NOBUG_DEFINE_FLAG(name) struct nobug_flag NOBUG_FLAG(name) = \
852 NOBUG_IF(NOBUG_MODE_ALPHA, {#name, {LOG_DEBUG, LOG_INFO, LOG_DEBUG, -1, LOG_INFO}, \
853 &nobug_default_ringbuffer, NULL,NULL}) \
854 NOBUG_IF(NOBUG_MODE_BETA, {#name, {LOG_INFO, LOG_NOTICE, LOG_NOTICE, LOG_NOTICE, LOG_WARNING}, \
855 &nobug_default_ringbuffer, NULL,NULL}) \
856 NOBUG_IF(NOBUG_MODE_RELEASE, {#name, {LOG_NOTICE, -1, LOG_WARNING, LOG_WARNING, LOG_ERROR}, \
857 &nobug_default_ringbuffer, NULL,NULL})
859 #define NOBUG_DEFINE_FLAG_LIMIT(name, limit) struct nobug_flag NOBUG_FLAG(name) = \
860 NOBUG_IF(NOBUG_MODE_ALPHA, {#name, {LOG_DEBUG, limit, LOG_DEBUG, -1, LOG_INFO}, \
861 &nobug_default_ringbuffer, NULL,NULL}) \
862 NOBUG_IF(NOBUG_MODE_BETA, {#name, {LOG_INFO, LOG_NOTICE, limit, LOG_NOTICE, LOG_WARNING}, \
863 &nobug_default_ringbuffer, NULL,NULL}) \
864 NOBUG_IF(NOBUG_MODE_RELEASE, {#name, {LOG_NOTICE, -1, LOG_WARNING, limit, LOG_ERROR}, \
865 &nobug_default_ringbuffer, NULL,NULL})
868 /*TODO better FLAG_LIMIT handling, should respect LOG_TARGET */
871 #define NOBUG_DECLARE_FLAG(name) extern struct nobug_flag NOBUG_FLAG(name)
873 #define NOBUG_INIT_FLAG(name) \
874 nobug_env_init_flag (&NOBUG_FLAG(name), NOBUG_LOG_TARGET, NOBUG_LOG_LIMIT)
876 #define NOBUG_INIT_FLAG_LIMIT(name, default) \
877 nobug_env_init_flag (&NOBUG_FLAG(name), NOBUG_LOG_TARGET, default)
880 #define NOBUG_CPP_DEFINE_FLAG(name) \
881 NOBUG_DEFINE_FLAG(name); \
882 static int nobug_##name##_cppinit##__LINE__ = NOBUG_INIT_FLAG(name)
884 #define NOBUG_CPP_DEFINE_FLAG_LIMIT(name, default) \
885 NOBUG_DEFINE_FLAG_LIMIT(name, default); \
886 static int nobug_##name##_cppinit##__LINE__ = NOBUG_INIT_FLAG_LIMIT(name, default)
889 #ifndef NOBUG_LOG_LIMIT_ALPHA
890 # define NOBUG_LOG_LIMIT_ALPHA LOG_INFO
892 #ifndef NOBUG_LOG_LIMIT_BETA
893 # define NOBUG_LOG_LIMIT_BETA LOG_WARNING
895 #ifndef NOBUG_LOG_LIMIT_RELEASE
896 # define NOBUG_LOG_LIMIT_RELEASE LOG_CRIT
899 #ifndef NOBUG_LOG_LIMIT
900 # define NOBUG_LOG_LIMIT \
902 NOBUG_LOG_LIMIT_ALPHA, \
903 NOBUG_LOG_LIMIT_BETA, \
904 NOBUG_LOG_LIMIT_RELEASE)
907 #ifndef NOBUG_LOG_TARGET_ALPHA
908 # define NOBUG_LOG_TARGET_ALPHA NOBUG_TARGET_CONSOLE
910 #ifndef NOBUG_LOG_TARGET_BETA
911 # define NOBUG_LOG_TARGET_BETA NOBUG_TARGET_FILE
913 #ifndef NOBUG_LOG_TARGET_RELEASE
914 # define NOBUG_LOG_TARGET_RELEASE NOBUG_TARGET_SYSLOG
917 #ifndef NOBUG_LOG_TARGET
918 # define NOBUG_LOG_TARGET \
920 NOBUG_LOG_TARGET_ALPHA, \
921 NOBUG_LOG_TARGET_BETA, \
922 NOBUG_LOG_TARGET_RELEASE)
925 #define NOBUG_SET_LIMIT(flag, min) \
927 NOBUG_FLAG(flag) = (min), \
928 NOBUG_FLAG(flag) = (min), \
933 short macros without NOBUG_
935 #ifndef NOBUG_DISABLE_SHORTNAMES
937 #define REQUIRE NOBUG_REQUIRE
940 #define REQUIRE_DBG NOBUG_REQUIRE_DBG
943 #define REQUIRE_IF NOBUG_REQUIRE_IF
945 #ifndef REQUIRE_IF_DBG
946 #define REQUIRE_IF_DBG NOBUG_REQUIRE_IF_DBG
949 #define ENSURE NOBUG_ENSURE
952 #define ENSURE_DBG NOBUG_ENSURE_DBG
955 #define ENSURE_IF NOBUG_ENSURE_IF
957 #ifndef ENSURE_IF_DBG
958 #define ENSURE_IF_DBG NOBUG_ENSURE_IF_DBG
961 #define ASSERT NOBUG_ASSERT
964 #define ASSERT_DBG NOBUG_ASSERT_DBG
967 #define ASSERT_IF NOBUG_ASSERT_IF
969 #ifndef ASSERT_IF_DBG
970 #define ASSERT_IF_DBG NOBUG_ASSERT_IF_DBG
973 #define INVARIANT NOBUG_INVARIANT
975 #ifndef INVARIANT_DBG
976 #define INVARIANT_DBG NOBUG_INVARIANT_DBG
979 #define INVARIANT_IF NOBUG_INVARIANT_IF
981 #ifndef INVARIANT_IF_DBG
982 #define INVARIANT_IF_DBG NOBUG_INVARIANT_IF_DBG
984 #ifndef INVARIANT_ASSERT
985 #define INVARIANT_ASSERT NOBUG_INVARIANT_ASSERT
988 #define DUMP NOBUG_DUMP
991 #define DUMP_DBG NOBUG_DUMP_DBG
994 #define DUMP_IF NOBUG_DUMP_IF
997 #define DUMP_IF_DBG NOBUG_DUMP_IF_DBG
1000 #define DUMP_LOG NOBUG_DUMP_LOG
1002 #ifndef DUMP_LOG_DBG
1003 #define DUMP_LOG_DBG NOBUG_DUMP_LOG_DBG
1006 #define DUMP_LOG_IF NOBUG_DUMP_LOG_IF
1008 #ifndef DUMP_LOG_IF_DBG
1009 #define DUMP_LOG_IF_DBG NOBUG_DUMP_LOG_IF_DBG
1012 #define LOG NOBUG_LOG
1015 #define LOG_DBG NOBUG_LOG_DBG
1018 #define LOG_IF NOBUG_LOG_IF
1021 #define LOG_IF_DBG NOBUG_LOG_IF_DBG
1024 #define ERROR NOBUG_ERROR
1027 #define ERROR_DBG NOBUG_ERROR_DBG
1030 #define ERROR_IF NOBUG_ERROR_IF
1032 #ifndef ERROR_IF_DBG
1033 #define ERROR_IF_DBG NOBUG_ERROR_IF_DBG
1036 #define WARN NOBUG_WARN
1039 #define WARN_DBG NOBUG_WARN_DBG
1042 #define WARN_IF NOBUG_WARN_IF
1045 #define WARN_IF_DBG NOBUG_WARN_IF_DBG
1048 #define INFO NOBUG_INFO
1051 #define INFO_DBG NOBUG_INFO_DBG
1054 #define INFO_IF NOBUG_INFO_IF
1057 #define INFO_IF_DBG NOBUG_INFO_IF_DBG
1060 #define NOTICE NOBUG_NOTICE
1063 #define NOTICE_DBG NOBUG_NOTICE_DBG
1066 #define NOTICE_IF NOBUG_NOTICE_IF
1068 #ifndef NOTICE_IF_DBG
1069 #define NOTICE_IF_DBG NOBUG_NOTICE_IF_DBG
1072 #define TRACE NOBUG_TRACE
1075 #define TRACE_DBG NOBUG_TRACE_DBG
1078 #define TRACE_IF NOBUG_TRACE_IF
1080 #ifndef TRACE_IF_DBG
1081 #define TRACE_IF_DBG NOBUG_TRACE_IF_DBG
1084 #define BACKTRACE NOBUG_BACKTRACE
1086 #ifndef BACKTRACE_DBG
1087 #define BACKTRACE_DBG NOBUG_BACKTRACE_DBG
1090 #define DEPRECATED NOBUG_DEPRECATED
1092 #ifndef UNIMPLEMENTED
1093 #define UNIMPLEMENTED NOBUG_UNIMPLEMENTED
1096 #define FIXME NOBUG_FIXME
1099 #define TODO NOBUG_TODO
1102 #define PLANNED NOBUG_PLANNED
1105 #define NOTREACHED NOBUG_NOTREACHED
1108 #define CLEANUP NOBUG_CLEANUP
1111 #define CHECKED NOBUG_CHECKED
1114 #define UNCHECKED NOBUG_UNCHECKED
1116 #ifndef RESOURCE_ANNOUNCE
1117 #define RESOURCE_ANNOUNCE NOBUG_RESOURCE_ANNOUNCE
1119 #ifndef RESOURCE_FORGET
1120 #define RESOURCE_FORGET NOBUG_RESOURCE_FORGET
1122 #ifndef RESOURCE_ENTER
1123 #define RESOURCE_ENTER NOBUG_RESOURCE_ENTER
1125 #ifndef RESOURCE_STATE
1126 #define RESOURCE_STATE NOBUG_RESOURCE_STATE
1128 #ifndef RESOURCE_LEAVE
1129 #define RESOURCE_LEAVE NOBUG_RESOURCE_LEAVE
1131 #ifndef RESOURCE_LEAVE_LOOKUP
1132 #define RESOURCE_LEAVE_LOOKUP NOBUG_RESOURCE_LEAVE_LOOKUP
1134 #ifndef RESOURCE_HANDLE
1135 #define RESOURCE_HANDLE NOBUG_RESOURCE_HANDLE
1137 #endif /* NOBUG_DISABLE_SHORTNAMES */
1138 #endif /* NOBUG_LIBNOBUG_C */
1144 #define NOBUG_IF(bool, ...) NOBUG_CAT(NOBUG_IF_,bool)(__VA_ARGS__)
1145 #define NOBUG_IF_1(...) __VA_ARGS__
1146 #define NOBUG_IF_0(...)
1148 #define NOBUG_IFNOT(bool, ...) NOBUG_CAT(NOBUG_IF_, NOBUG_NOT(bool))(__VA_ARGS__)
1150 #define NOBUG_NOT(bool) NOBUG_CAT(NOBUG_NOT_, bool)
1151 #define NOBUG_NOT_1 0
1152 #define NOBUG_NOT_0 1
1154 #define NOBUG_AND(a,b) NOBUG_CAT3(NOBUG_AND_, a, b)
1155 #define NOBUG_AND_00 0
1156 #define NOBUG_AND_01 0
1157 #define NOBUG_AND_10 0
1158 #define NOBUG_AND_11 1
1160 #define NOBUG_OR(a,b) NOBUG_CAT3(NOBUG_OR_, a, b)
1161 #define NOBUG_OR_00 0
1162 #define NOBUG_OR_01 1
1163 #define NOBUG_OR_10 1
1164 #define NOBUG_OR_11 1
1166 #define NOBUG_XOR(a,b) NOBUG_CAT( NOBUG_XOR_, NOBUG_CAT(a,b))
1167 #define NOBUG_XOR_00 0
1168 #define NOBUG_XOR_01 1
1169 #define NOBUG_XOR_10 1
1170 #define NOBUG_XOR_11 0
1172 #define NOBUG_CAT(a,b) NOBUG_CAT_(a,b)
1173 #define NOBUG_CAT_(a,b) a##b
1175 #define NOBUG_CAT3(a,b,c) NOBUG_CAT3_(a,b,c)
1176 #define NOBUG_CAT3_(a,b,c) a##b##c
1178 #define NOBUG_HEAD(head, ...) head
1179 #define NOBUG_TAIL(_, ...) , ## __VA_ARGS__
1181 #define NOBUG_STRINGIZE(s) NOBUG_STRINGIZE_(s)
1182 #define NOBUG_STRINGIZE_(s) #s
1186 LIBNOBUG DECLARATIONS
1195 enum nobug_log_targets
1197 NOBUG_TARGET_RINGBUFFER
,
1198 NOBUG_TARGET_CONSOLE
,
1200 NOBUG_TARGET_SYSLOG
,
1201 NOBUG_TARGET_APPLICATION
1208 struct nobug_ringbuffer
* ringbuffer_target
;
1209 FILE* console_target
;
1214 nobug_env_parse_flag (const char* env
, struct nobug_flag
* flag
, int default_target
, int default_limit
);
1217 nobug_env_init_flag (struct nobug_flag
* flag
, int default_target
, int default_limit
);
1224 struct nobug_ringbuffer
1233 extern struct nobug_ringbuffer nobug_default_ringbuffer
;
1234 extern FILE* nobug_default_file
;
1235 extern struct nobug_flag nobug_flag_NOBUG_ON
;
1237 enum nobug_ringbuffer_flags
1239 NOBUG_RINGBUFFER_DEFAULT
, /* Default is to overwrite file and delete it on nobug_ringbuffer_destroy */
1240 NOBUG_RINGBUFFER_APPEND
= 1, /* use existing backing file, append if possible */
1241 NOBUG_RINGBUFFER_TEMP
= 2, /* unlink file instantly */
1242 NOBUG_RINGBUFFER_KEEP
= 4 /* dont unlink the file at destroy */
1246 Note: some flags conflict (TEMP with KEEP) nobug_ringbuffer will not error on these but continue gracefully
1247 with sane (but undefined) semantics.
1250 nobug_ringbuffer_init (struct nobug_ringbuffer
* self
, size_t size
,
1251 const char * name
, enum nobug_ringbuffer_flags flags
);
1254 nobug_ringbuffer_destroy (struct nobug_ringbuffer
* self
);
1257 nobug_ringbuffer_printf (struct nobug_ringbuffer
* self
, const char* fmt
, ...);
1260 nobug_ringbuffer_prev (struct nobug_ringbuffer
* self
, char* pos
);
1263 nobug_ringbuffer_next (struct nobug_ringbuffer
* self
, char* pos
);
1266 nobug_ringbuffer_save (struct nobug_ringbuffer
* self
, FILE* out
);
1269 nobug_ringbuffer_load (struct nobug_ringbuffer
* self
, FILE* in
);
1272 nobug_ringbuffer_pos (struct nobug_ringbuffer
* self
);
1275 nobug_ringbuffer_pop (struct nobug_ringbuffer
* self
);
1280 struct nobug_resource_record
1282 char* type
; /* type or state */
1283 char* name
; /* name */
1284 void* object_id
; /* unique identifer, usually a this pointer or similar */
1285 #if NOBUG_USE_PTHREAD == 1
1288 void* data
; /* tree of holders in resouces, backpointer to resource in holders */
1289 char* extra
; /* extra information, file/line usually */
1290 unsigned long counter
; /* users or recursive enters */
1293 enum nobug_resource_state
1295 NOBUG_RESOURCE_WAITING
,
1296 NOBUG_RESOURCE_EXCLUSIVE
,
1297 NOBUG_RESOURCE_RECURSIVE
1300 extern void* nobug_resource_registry
;
1301 extern const char* nobug_resource_error
;
1302 extern FILE* nobug_resource_dump_target
;
1304 extern const char* nobug_resource_states
[];
1308 struct nobug_resource_record
*
1309 nobug_resource_announce (const char* type
, const char* name
, const void* object_id
, const char* extra
);
1312 nobug_resource_forget (struct nobug_resource_record
* node
);
1314 struct nobug_resource_record
*
1315 nobug_resource_find (const struct nobug_resource_record
* resource
, const void* object_id
);
1317 struct nobug_resource_record
*
1318 nobug_resource_enter (struct nobug_resource_record
* resource
,
1320 const void* object_id
,
1321 enum nobug_resource_state state
,
1325 nobug_resource_state (struct nobug_resource_record
* resource
,
1326 enum nobug_resource_state state
);
1329 nobug_resource_leave (struct nobug_resource_record
* handle
);
1332 nobug_resource_dump (struct nobug_resource_record
* resource
, FILE* target
);
1335 nobug_resource_dump_all (FILE* target
);
1338 nobug_resource_dump_resources (FILE* target
);
1343 #ifdef NOBUG_USE_PTHREAD
1344 extern pthread_key_t nobug_thread_id_key
;
1347 nobug_thread_id_set (const char* name
);
1350 nobug_thread_id_get (void);
1352 extern pthread_mutex_t nobug_global_mutex
;
1353 #define NOBUG_LOCK pthread_mutex_lock (&nobug_global_mutex)
1354 #define NOBUG_UNLOCK pthread_mutex_unlock (&nobug_global_mutex)
1357 #define NOBUG_UNLOCK
1362 global config and data
1364 extern const char* nobug_resource_acquired
;
1372 #ifndef NOBUG_LIBNOBUG_C
1375 tag this translation unit as unchecked in ALPHA and BETA builds
1377 NOBUG_IF_NOT_RELEASE(NOBUG_UNCHECKED
);
1379 #endif /* NOBUG_LIBNOBUG_C */