libdap  Updated for version 3.19.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
Error.cc
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2002,2003 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 // (c) COPYRIGHT URI/MIT 1994-1999
27 // Please read the full copyright statement in the file COPYRIGHT_URI.
28 //
29 // Authors:
30 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
31 
32 // Implementation for the Error class.
33 
34 
35 #include "config.h"
36 
37 #include <cstdio>
38 #include <cassert>
39 
40 #include "Error.h"
41 #include "parser.h"
42 #include "InternalErr.h"
43 #include "debug.h"
44 
45 using namespace std;
46 
47 // Glue routines declared in Error.lex
48 extern void Error_switch_to_buffer(void *new_buffer);
49 extern void Error_delete_buffer(void * buffer);
50 extern void *Error_buffer(FILE *fp);
51 
52 //extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
53 extern int Errorparse(libdap::parser_arg *arg);
54 
55 namespace libdap {
56 
57 // There are two entries for 'cannot read file' because of an error made
58 // when the message was first added to this class.
59 static const char *err_messages[] = {
60  "Undefined error",
61  "Unknown error",
62  "Internal error",
63  "No such file",
64  "No such variable",
65  "Malformed expression",
66  "No authorization",
67  "Cannot read file",
68  "Not Implemented",
69  ""
70 };
71 
74 Error::Error() : _error_code(undefined_error), _error_message("")
75 {}
76 
86 Error::Error(ErrorCode ec, string msg)
87  : _error_code(ec), _error_message(msg)
88 {}
89 
95 Error::Error(string msg)
96  : _error_code(unknown_error), _error_message(msg)
97 {}
98 
99 Error::Error(const Error &copy_from)
100  : _error_code(copy_from._error_code),
101  _error_message(copy_from._error_message)
102 {
103 }
104 
105 Error::~Error()
106 {
107 }
108 
109 Error &
110 Error::operator=(const Error &rhs)
111 {
112  assert(OK());
113 
114  if (&rhs == this) // are they identical?
115  return *this;
116  else {
117  _error_code = rhs._error_code;
118  _error_message = rhs._error_message;
119 
120  assert(this->OK());
121 
122  return *this;
123  }
124 }
125 
132 bool
133 Error::OK() const
134 {
135  // The object is empty - users cannot make these, but this class can!
136  bool empty = ((_error_code == undefined_error)
137  && (_error_message.empty()));
138 
139  // Just a message - the program part is null.
140  bool message = ((_error_code != undefined_error)
141  && (!_error_message.empty()));
142 
143  DBG(cerr << "empty: " << empty << ", message: " << message << endl);
144  return empty || message;
145 }
146 
155 bool
156 Error::parse(FILE *fp)
157 {
158  if (!fp)
159  throw InternalErr(__FILE__, __LINE__, "Null input stream");
160 
161  void *buffer = Error_buffer(fp);
162  Error_switch_to_buffer(buffer);
163 
164  parser_arg arg(this);
165 
166  bool status;
167  try {
168  status = Errorparse(&arg) == 0;
169  Error_delete_buffer(buffer);
170  }
171  catch (Error &e) {
172  Error_delete_buffer(buffer);
173  throw InternalErr(__FILE__, __LINE__, e.get_error_message());
174  }
175 
176  // STATUS is the result of the parser function; if a recoverable error
177  // was found it will be true but arg.status() will be false.
178  // I'm throwing an InternalErr here since Error objects are generated by
179  // the core; they should always parse! 9/21/2000 jhrg
180  if (!status || !arg.status())
181  throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
182  else
183  return OK(); // Check object consistency
184 }
185 
186 
197 void
198 Error::print(FILE *out) const
199 {
200  assert(OK());
201 
202  fprintf(out, "Error {\n") ;
203 
204  fprintf(out, " code = %d;\n", static_cast<int>(_error_code)) ;
205 
206  // If the error message is wrapped in double quotes, print it, else, add
207  // wrapping double quotes.
208  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
209  fprintf(out, " message = %s;\n", _error_message.c_str()) ;
210  else
211  fprintf(out, " message = \"%s\";\n", _error_message.c_str()) ;
212 
213  fprintf(out, "};\n") ;
214 }
215 
226 void
227 Error::print(ostream &strm) const
228 {
229  assert(OK());
230 
231  strm << "Error {\n" ;
232 
233  strm << " code = " << static_cast<int>(_error_code) << ";\n" ;
234 
235  // If the error message is wrapped in double quotes, print it, else, add
236  // wrapping double quotes.
237  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
238  strm << " message = " << _error_message.c_str() << ";\n" ;
239  else
240  strm << " message = \"" << _error_message.c_str() << "\";\n" ;
241 
242  strm << "};\n" ;
243 }
244 
246 ErrorCode
248 {
249  assert(OK());
250  return _error_code;
251 }
252 
259 void
261 {
262  _error_code = ec;
263  // Added check to make sure that err_messages is not accessed beyond its
264  // bounds. 02/02/04 jhrg
265  if (_error_message.empty()
266  && ec > undefined_error && ec <= cannot_read_file) {
267  _error_message = err_messages[ec - undefined_error];
268  }
269  else {
270  _error_message = err_messages[0];
271  }
272 }
273 
275 string
277 {
278  assert(OK());
279 
280  return string(_error_message);
281 }
282 
284 void
286 {
287  _error_message = msg;
288 }
289 
290 } // namespace libdap
STL namespace.
bool parse(FILE *fp)
Parse an Error object.
Definition: Error.cc:156
void set_error_code(ErrorCode ec=undefined_error)
Definition: Error.cc:260
A class for software fault reporting.
Definition: InternalErr.h:64
bool OK() const
Is the Error object valid?
Definition: Error.cc:133
ErrorCode get_error_code() const
Definition: Error.cc:247
string get_error_message() const
Definition: Error.cc:276
int ErrorCode
An enumerated type for common errors.
Definition: Error.h:55
void print(FILE *out) const
Definition: Error.cc:198
Pass parameters by reference to a parser.
Definition: parser.h:68
A class for error processing.
Definition: Error.h:90
void set_error_message(string msg="")
Definition: Error.cc:285