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