1 /*
2  *  Debugging macro calls.
3  */
4 
5 #include "duk_internal.h"
6 
7 #ifdef DUK_USE_DEBUG
8 
9 /*
10  *  Debugging enabled
11  */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 
17 #define DUK__DEBUG_BUFSIZE  DUK_USE_DEBUG_BUFSIZE
18 DUK_LOCAL char duk__debug_buf[DUK__DEBUG_BUFSIZE];
19 
duk__get_level_string(duk_small_int_t level)20 DUK_LOCAL const char *duk__get_level_string(duk_small_int_t level) {
21 	switch ((int) level) {
22 	case DUK_LEVEL_DEBUG:
23 		return "D";
24 	case DUK_LEVEL_DDEBUG:
25 		return "DD";
26 	case DUK_LEVEL_DDDEBUG:
27 		return "DDD";
28 	}
29 	return "???";
30 }
31 
32 #ifdef DUK_USE_DPRINT_COLORS
33 
34 /* http://en.wikipedia.org/wiki/ANSI_escape_code */
35 #define DUK__TERM_REVERSE  "\x1b[7m"
36 #define DUK__TERM_BRIGHT   "\x1b[1m"
37 #define DUK__TERM_RESET    "\x1b[0m"
38 #define DUK__TERM_BLUE     "\x1b[34m"
39 #define DUK__TERM_RED      "\x1b[31m"
40 
duk__get_term_1(duk_small_int_t level)41 DUK_LOCAL const char *duk__get_term_1(duk_small_int_t level) {
42 	DUK_UNREF(level);
43 	return (const char *) DUK__TERM_RED;
44 }
45 
duk__get_term_2(duk_small_int_t level)46 DUK_LOCAL const char *duk__get_term_2(duk_small_int_t level) {
47 	switch ((int) level) {
48 	case DUK_LEVEL_DEBUG:
49 		return (const char *) (DUK__TERM_RESET DUK__TERM_BRIGHT);
50 	case DUK_LEVEL_DDEBUG:
51 		return (const char *) (DUK__TERM_RESET);
52 	case DUK_LEVEL_DDDEBUG:
53 		return (const char *) (DUK__TERM_RESET DUK__TERM_BLUE);
54 	}
55 	return (const char *) DUK__TERM_RESET;
56 }
57 
duk__get_term_3(duk_small_int_t level)58 DUK_LOCAL const char *duk__get_term_3(duk_small_int_t level) {
59 	DUK_UNREF(level);
60 	return (const char *) DUK__TERM_RESET;
61 }
62 
63 #else
64 
duk__get_term_1(duk_small_int_t level)65 DUK_LOCAL const char *duk__get_term_1(duk_small_int_t level) {
66 	DUK_UNREF(level);
67 	return (const char *) "";
68 }
69 
duk__get_term_2(duk_small_int_t level)70 DUK_LOCAL const char *duk__get_term_2(duk_small_int_t level) {
71 	DUK_UNREF(level);
72 	return (const char *) "";
73 }
74 
duk__get_term_3(duk_small_int_t level)75 DUK_LOCAL const char *duk__get_term_3(duk_small_int_t level) {
76 	DUK_UNREF(level);
77 	return (const char *) "";
78 }
79 
80 #endif  /* DUK_USE_DPRINT_COLORS */
81 
82 #ifdef DUK_USE_VARIADIC_MACROS
83 
duk_debug_log(duk_small_int_t level,const char * file,duk_int_t line,const char * func,const char * fmt,...)84 DUK_INTERNAL void duk_debug_log(duk_small_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) {
85 	va_list ap;
86 
87 	va_start(ap, fmt);
88 
89 	DUK_MEMZERO((void *) duk__debug_buf, (size_t) DUK__DEBUG_BUFSIZE);
90 	duk_debug_vsnprintf(duk__debug_buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);
91 
92 	DUK_FPRINTF(DUK_STDERR, "%s[%s] %s:%ld (%s):%s %s%s\n",
93 	            (const char *) duk__get_term_1(level),
94 	            (const char *) duk__get_level_string(level),
95 	            (const char *) file,
96 	            (long) line,
97 	            (const char *) func,
98 	            (const char *) duk__get_term_2(level),
99 	            (const char *) duk__debug_buf,
100 	            (const char *) duk__get_term_3(level));
101 	DUK_FFLUSH(DUK_STDERR);
102 
103 	va_end(ap);
104 }
105 
106 #else  /* DUK_USE_VARIADIC_MACROS */
107 
108 DUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];
109 DUK_INTERNAL char duk_debug_line_stash[DUK_DEBUG_STASH_SIZE];
110 DUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];
111 DUK_INTERNAL duk_small_int_t duk_debug_level_stash;
112 
duk_debug_log(const char * fmt,...)113 DUK_INTERNAL void duk_debug_log(const char *fmt, ...) {
114 	va_list ap;
115 	duk_small_int_t level = duk_debug_level_stash;
116 
117 	va_start(ap, fmt);
118 
119 	DUK_MEMZERO((void *) duk__debug_buf, (size_t) DUK__DEBUG_BUFSIZE);
120 	duk_debug_vsnprintf(duk__debug_buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);
121 
122 	DUK_FPRINTF(DUK_STDERR, "%s[%s] %s:%s (%s):%s %s%s\n",
123 	            (const char *) duk__get_term_1(level),
124 	            (const char *) duk__get_level_string(duk_debug_level_stash),
125 	            (const char *) duk_debug_file_stash,
126 	            (const char *) duk_debug_line_stash,
127 	            (const char *) duk_debug_func_stash,
128 	            (const char *) duk__get_term_2(level),
129 	            (const char *) duk__debug_buf,
130 	            (const char *) duk__get_term_3(level));
131 	DUK_FFLUSH(DUK_STDERR);
132 
133 	va_end(ap);
134 }
135 
136 #endif  /* DUK_USE_VARIADIC_MACROS */
137 
138 #else  /* DUK_USE_DEBUG */
139 
140 /*
141  *  Debugging disabled
142  */
143 
144 #endif  /* DUK_USE_DEBUG */
145