switch source package format to 3.0 quilt
[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 3, 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 #include <stdio.h>
52
53 #ifdef HAVE_IO_H
54 #include <io.h>
55 #endif
56
57 static gr_error_handler *s_default_handler = 0;
58 static gr_error_handler *s_silent_handler = 0;
59
60 bool
61 gr_error_handler::has_default_handler()
62 {
63   return s_default_handler != 0;
64 }
65
66 void
67 gr_error_handler::set_default_handler(gr_error_handler *errh)
68 {
69   s_default_handler = errh;
70 }
71
72 gr_error_handler *
73 gr_error_handler::default_handler()
74 {
75   assert (s_default_handler != 0);
76   return s_default_handler;
77 }
78
79 gr_error_handler *
80 gr_error_handler::silent_handler()
81 {
82   assert (s_silent_handler != 0);
83   return s_silent_handler;
84 }
85
86 // ----------------------------------------------------------------
87
88 gr_error_handler::~gr_error_handler()
89 {
90   // nop
91 }
92
93 void
94 gr_error_handler::debug(const char *format, ...)
95 {
96   va_list val;
97   va_start(val, format);
98   verror(ERR_DEBUG, format, val);
99   va_end(val);
100 }
101
102 void
103 gr_error_handler::message(const char *format, ...)
104 {
105   va_list val;
106   va_start(val, format);
107   verror(ERR_MESSAGE, format, val);
108   va_end(val);
109 }
110
111 void
112 gr_error_handler::warning(const char *format, ...)
113 {
114   va_list val;
115   va_start(val, format);
116   verror(ERR_WARNING, format, val);
117   va_end(val);
118 }
119
120 void
121 gr_error_handler::error(const char *format, ...)
122 {
123   va_list val;
124   va_start(val, format);
125   verror(ERR_ERROR, format, val);
126   va_end(val);
127 }
128
129 void
130 gr_error_handler::fatal(const char *format, ...)
131 {
132   va_list val;
133   va_start(val, format);
134   verror(ERR_FATAL, format, val);
135   va_end(val);
136 }
137
138 void
139 gr_error_handler::verror(seriousness s, const char *format, va_list val)
140 {
141   std::string text = make_text(s, format, val);
142   handle_text(s, text);
143   count_error(s);
144 }
145
146 void
147 gr_error_handler::verror_text(seriousness s, const std::string &text)
148 {
149   // text is already made
150   handle_text(s, text);
151   count_error(s);
152 }
153
154 std::string
155 gr_error_handler::make_text(seriousness s, const char *format, va_list val)
156 {
157   char text_buf[4096];
158   vsnprintf(text_buf, sizeof(text_buf), format, val);
159   text_buf[sizeof(text_buf)-1] = 0;
160   return text_buf;
161 }
162
163 // ----------------------------------------------------------------
164
165 void
166 gr_base_error_handler::count_error(seriousness s)
167 {
168   if (s < ERR_WARNING)
169     /* do nothing */;
170   else if (s < ERR_ERROR)
171     d_nwarnings++;
172   else
173     d_nerrors++;
174 }
175
176 // ----------------------------------------------------------------
177
178 gr_file_error_handler::gr_file_error_handler(FILE *file)
179   : d_file(file), d_fd(-1)
180 {
181 }
182
183 gr_file_error_handler::gr_file_error_handler(int file_descriptor)
184 {
185   d_fd = dup(file_descriptor);  // so we can fclose it
186   if (d_fd == -1){
187     perror("gr_file_error_handler:dup");
188     throw std::invalid_argument("gr_file_error_handler:dup");
189   }
190   d_file = fdopen(d_fd, "w");
191   if (d_file == 0){
192     perror("gr_file_error_handler:fdopen");
193     throw std::invalid_argument("gr_file_error_handler:fdopen");
194   }
195 }
196
197 gr_file_error_handler::~gr_file_error_handler()
198 {
199   if (d_fd != -1){
200     fclose(d_file);
201   }
202 }
203
204 void
205 gr_file_error_handler::handle_text(seriousness s, const std::string &text)
206 {
207   if (text.length() <= 0)
208     return;
209   
210   fwrite(text.data(), 1, text.length(), d_file);
211   if (text[text.length()-1] != '\n')
212     fwrite("\n", 1, 1, d_file);
213
214   if (d_fd != -1)
215     fflush(d_file);     // keep synced with any other users of fd
216 }
217   
218
219 // ----------------------------------------------------------------
220 // static error handlers
221 //
222
223 class gr_silent_error_handler : public gr_base_error_handler
224 {
225 public:
226   gr_silent_error_handler() {}
227   void handle_text(seriousness s, const std::string &str);
228 };
229
230 void
231 gr_silent_error_handler::handle_text(seriousness s, const std::string &str)
232 {
233   // nop
234 }
235
236 class force_init {
237 public:
238   force_init()
239   {
240     s_default_handler = new gr_file_error_handler(stdout);
241     s_silent_handler = new gr_silent_error_handler();
242   }
243 };
244
245 static force_init       kludge;