1 /*
2 Copyright (C) 2003, 2018 Rocky Bernstein <rocky@gnu.org>
3 Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.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
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 /* Public headers */
29 #include <libvcd/logging.h>
30
31 /* Private headers */
32 #include "vcd_assert.h"
33
34 vcd_log_level_t vcd_loglevel_default = VCD_LOG_WARN;
35
36 static void
default_vcd_log_handler(vcd_log_level_t level,const char message[])37 default_vcd_log_handler (vcd_log_level_t level, const char message[])
38 {
39 switch (level)
40 {
41 case VCD_LOG_ERROR:
42 if (level >= vcd_loglevel_default) {
43 fprintf (stderr, "**ERROR: %s\n", message);
44 fflush (stderr);
45 exit (EXIT_FAILURE);
46 }
47 break;
48 case VCD_LOG_DEBUG:
49 if (level >= vcd_loglevel_default) {
50 fprintf (stdout, "--DEBUG: %s\n", message);
51 }
52 break;
53 case VCD_LOG_WARN:
54 if (level >= vcd_loglevel_default) {
55 fprintf (stdout, "++ WARN: %s\n", message);
56 }
57 break;
58 case VCD_LOG_INFO:
59 if (level >= vcd_loglevel_default) {
60 fprintf (stdout, " INFO: %s\n", message);
61 }
62 break;
63 case VCD_LOG_ASSERT:
64 if (level >= vcd_loglevel_default) {
65 fprintf (stderr, "!ASSERT: %s\n", message);
66 fflush (stderr);
67 }
68 abort ();
69 break;
70 default:
71 vcd_assert_not_reached ();
72 break;
73 }
74
75 fflush (stdout);
76 }
77
78 static vcd_log_handler_t _handler = default_vcd_log_handler;
79
80 vcd_log_handler_t
vcd_log_set_handler(vcd_log_handler_t new_handler)81 vcd_log_set_handler (vcd_log_handler_t new_handler)
82 {
83 vcd_log_handler_t old_handler = _handler;
84
85 _handler = new_handler;
86
87 return old_handler;
88 }
89
90 static void
vcd_logv(vcd_log_level_t level,const char format[],va_list args)91 vcd_logv (vcd_log_level_t level, const char format[], va_list args)
92 {
93 char buf[1024] = { 0, };
94 static int in_recursion = 0;
95
96 if (in_recursion)
97 vcd_assert_not_reached ();
98
99 in_recursion = 1;
100
101 vsnprintf(buf, sizeof(buf)-1, format, args);
102
103 _handler(level, buf);
104
105 in_recursion = 0;
106 }
107
108 void
vcd_log(vcd_log_level_t level,const char format[],...)109 vcd_log (vcd_log_level_t level, const char format[], ...)
110 {
111 va_list args;
112 va_start (args, format);
113 vcd_logv (level, format, args);
114 va_end (args);
115 }
116
117 #define VCD_LOG_TEMPLATE(level, LEVEL) \
118 void \
119 vcd_ ## level (const char format[], ...) \
120 { \
121 va_list args; \
122 va_start (args, format); \
123 vcd_logv (VCD_LOG_ ## LEVEL, format, args); \
124 va_end (args); \
125 }
126
127 VCD_LOG_TEMPLATE(debug, DEBUG)
128 VCD_LOG_TEMPLATE(info, INFO)
129 VCD_LOG_TEMPLATE(warn, WARN)
130 VCD_LOG_TEMPLATE(error, ERROR)
131
132 #undef VCD_LOG_TEMPLATE
133
134
135 /*
136 * Local variables:
137 * c-file-style: "gnu"
138 * tab-width: 8
139 * indent-tabs-mode: nil
140 * End:
141 */
142