Imported Upstream version 3.0
[debian/gnuradio] / gnuradio-core / src / lib / runtime / gr_error_handler.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2005 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 /*
23  * This code is based on error.cc from the "Click Modular Router".
24  * Original copyright follows:
25  */
26 /* 
27  * error.{cc,hh} -- flexible classes for error reporting
28  * Eddie Kohler
29  *
30  * Copyright (c) 1999-2000 Massachusetts Institute of Technology
31  *
32  * Permission is hereby granted, free of charge, to any person obtaining a
33  * copy of this software and associated documentation files (the "Software"),
34  * to deal in the Software without restriction, subject to the conditions
35  * listed in the Click LICENSE file. These conditions include: you must
36  * preserve this copyright notice, and you cannot mention the copyright
37  * holders in advertising related to the Software without their permission.
38  * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
39  * notice is a summary of the Click LICENSE file; the license in that file is
40  * legally binding.
41  */
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #include <gr_error_handler.h>
48 #include <assert.h>
49 #include <stdexcept>
50 #include <unistd.h>
51
52 #ifdef HAVE_IO_H
53 #include <io.h>
54 #endif
55
56 static gr_error_handler *s_default_handler = 0;
57 static gr_error_handler *s_silent_handler = 0;
58
59 bool
60 gr_error_handler::has_default_handler()
61 {
62   return s_default_handler != 0;
63 }
64
65 void
66 gr_error_handler::set_default_handler(gr_error_handler *errh)
67 {
68   s_default_handler = errh;
69 }
70
71 gr_error_handler *
72 gr_error_handler::default_handler()
73 {
74   assert (s_default_handler != 0);
75   return s_default_handler;
76 }
77
78 gr_error_handler *
79 gr_error_handler::silent_handler()
80 {
81   assert (s_silent_handler != 0);
82   return s_silent_handler;
83 }
84
85 // ----------------------------------------------------------------
86
87 gr_error_handler::~gr_error_handler()
88 {
89   // nop
90 }
91
92 void
93 gr_error_handler::debug(const char *format, ...)
94 {
95   va_list val;
96   va_start(val, format);
97   verror(ERR_DEBUG, format, val);
98   va_end(val);
99 }
100
101 void
102 gr_error_handler::message(const char *format, ...)
103 {
104   va_list val;
105   va_start(val, format);
106   verror(ERR_MESSAGE, format, val);
107   va_end(val);
108 }
109
110 void
111 gr_error_handler::warning(const char *format, ...)
112 {
113   va_list val;
114   va_start(val, format);
115   verror(ERR_WARNING, format, val);
116   va_end(val);
117 }
118
119 void
120 gr_error_handler::error(const char *format, ...)
121 {
122   va_list val;
123   va_start(val, format);
124   verror(ERR_ERROR, format, val);
125   va_end(val);
126 }
127
128 void
129 gr_error_handler::fatal(const char *format, ...)
130 {
131   va_list val;
132   va_start(val, format);
133   verror(ERR_FATAL, format, val);
134   va_end(val);
135 }
136
137 void
138 gr_error_handler::verror(seriousness s, const char *format, va_list val)
139 {
140   std::string text = make_text(s, format, val);
141   handle_text(s, text);
142   count_error(s);
143 }
144
145 void
146 gr_error_handler::verror_text(seriousness s, const std::string &text)
147 {
148   // text is already made
149   handle_text(s, text);
150   count_error(s);
151 }
152
153 std::string
154 gr_error_handler::make_text(seriousness s, const char *format, va_list val)
155 {
156   char text_buf[4096];
157   vsnprintf(text_buf, sizeof(text_buf), format, val);
158   text_buf[sizeof(text_buf)-1] = 0;
159   return text_buf;
160 }
161
162 // ----------------------------------------------------------------
163
164 void
165 gr_base_error_handler::count_error(seriousness s)
166 {
167   if (s < ERR_WARNING)
168     /* do nothing */;
169   else if (s < ERR_ERROR)
170     d_nwarnings++;
171   else
172     d_nerrors++;
173 }
174
175 // ----------------------------------------------------------------
176
177 gr_file_error_handler::gr_file_error_handler(FILE *file)
178   : d_file(file), d_fd(-1)
179 {
180 }
181
182 gr_file_error_handler::gr_file_error_handler(int file_descriptor)
183 {
184   d_fd = dup(file_descriptor);  // so we can fclose it
185   if (d_fd == -1){
186     perror("gr_file_error_handler:dup");
187     throw std::invalid_argument("gr_file_error_handler:dup");
188   }
189   d_file = fdopen(d_fd, "w");
190   if (d_file == 0){
191     perror("gr_file_error_handler:fdopen");
192     throw std::invalid_argument("gr_file_error_handler:fdopen");
193   }
194 }
195
196 gr_file_error_handler::~gr_file_error_handler()
197 {
198   if (d_fd != -1){
199     fclose(d_file);
200   }
201 }
202
203 void
204 gr_file_error_handler::handle_text(seriousness s, const std::string &text)
205 {
206   if (text.length() <= 0)
207     return;
208   
209   fwrite(text.data(), 1, text.length(), d_file);
210   if (text[text.length()-1] != '\n')
211     fwrite("\n", 1, 1, d_file);
212
213   if (d_fd != -1)
214     fflush(d_file);     // keep synced with any other users of fd
215 }
216   
217
218 // ----------------------------------------------------------------
219 // static error handlers
220 //
221
222 class gr_silent_error_handler : public gr_base_error_handler
223 {
224 public:
225   gr_silent_error_handler() {}
226   void handle_text(seriousness s, const std::string &str);
227 };
228
229 void
230 gr_silent_error_handler::handle_text(seriousness s, const std::string &str)
231 {
232   // nop
233 }
234
235 class force_init {
236 public:
237   force_init()
238   {
239     s_default_handler = new gr_file_error_handler(stdout);
240     s_silent_handler = new gr_silent_error_handler();
241   }
242 };
243
244 static force_init       kludge;