libdap  Updated for version 3.20.6
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() : exception(), _error_code(undefined_error), _error_message("")
75 {}
76 
86 Error::Error(ErrorCode ec, string msg, string file /* default: ""*/, int line /* default 0*/)
87  : exception(), _error_code(ec), _error_message(msg), d_file(file), d_line(line)
88 {}
89 
95 Error::Error(string msg, string file /* default: ""*/, int line /* default 0*/)
96  : exception(), _error_code(unknown_error), _error_message(msg), d_file(file), d_line(line)
97 {}
98 
99 Error::Error(const Error &copy_from)
100  : exception(), _error_code(copy_from._error_code), _error_message(copy_from._error_message)
101 {
102 }
103 
104 Error::~Error() throw()
105 {
106 }
107 
108 Error &
109 Error::operator=(const Error &rhs)
110 {
111  assert(OK());
112 
113  if (&rhs == this) // are they identical?
114  return *this;
115  else {
116  _error_code = rhs._error_code;
117  _error_message = rhs._error_message;
118 
119  d_file = rhs.d_file;
120  d_line = rhs.d_line;
121 
122  assert(this->OK());
123 
124  return *this;
125  }
126 }
127 
134 bool
135 Error::OK() const
136 {
137  // The object is empty - users cannot make these, but this class can!
138  bool empty = ((_error_code == undefined_error)
139  && (_error_message.empty()));
140 
141  // Just a message - the program part is null.
142  bool message = ((_error_code != undefined_error)
143  && (!_error_message.empty()));
144 
145  DBG(cerr << "empty: " << empty << ", message: " << message << endl);
146  return empty || message;
147 }
148 
157 bool
158 Error::parse(FILE *fp)
159 {
160  if (!fp)
161  throw InternalErr(__FILE__, __LINE__, "Null input stream");
162 
163  void *buffer = Error_buffer(fp);
164  Error_switch_to_buffer(buffer);
165 
166  parser_arg arg(this);
167 
168  bool status;
169  try {
170  status = Errorparse(&arg) == 0;
171  Error_delete_buffer(buffer);
172  }
173  catch (Error &e) {
174  Error_delete_buffer(buffer);
175  throw InternalErr(__FILE__, __LINE__, e.get_error_message());
176  }
177 
178  // STATUS is the result of the parser function; if a recoverable error
179  // was found it will be true but arg.status() will be false.
180  // I'm throwing an InternalErr here since Error objects are generated by
181  // the core; they should always parse! 9/21/2000 jhrg
182  if (!status || !arg.status())
183  throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
184  else
185  return OK(); // Check object consistency
186 }
187 
188 
199 void
200 Error::print(FILE *out) const
201 {
202  assert(OK());
203 
204  fprintf(out, "Error {\n") ;
205 
206  fprintf(out, " code = %d;\n", static_cast<int>(_error_code)) ;
207 
208  // If the error message is wrapped in double quotes, print it, else, add
209  // wrapping double quotes.
210  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
211  fprintf(out, " message = %s;\n", _error_message.c_str()) ;
212  else
213  fprintf(out, " message = \"%s\";\n", _error_message.c_str()) ;
214 
215  fprintf(out, "};\n") ;
216 }
217 
228 void
229 Error::print(ostream &strm) const
230 {
231  assert(OK());
232 
233  strm << "Error {\n" ;
234 
235  strm << " code = " << static_cast<int>(_error_code) << ";\n" ;
236 
237  // If the error message is wrapped in double quotes, print it, else, add
238  // wrapping double quotes.
239  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
240  strm << " message = " << _error_message.c_str() << ";\n" ;
241  else
242  strm << " message = \"" << _error_message.c_str() << "\";\n" ;
243 
244  strm << "};\n" ;
245 }
246 
248 ErrorCode
250 {
251  assert(OK());
252  return _error_code;
253 }
254 
261 void
263 {
264  _error_code = ec;
265  // Added check to make sure that err_messages is not accessed beyond its
266  // bounds. 02/02/04 jhrg
267  if (_error_message.empty()
268  && ec > undefined_error && ec <= cannot_read_file) {
269  _error_message = err_messages[ec - undefined_error];
270  }
271  else {
272  _error_message = err_messages[0];
273  }
274 }
275 
277 string
279 {
280  assert(OK());
281 
282  return string(_error_message);
283 }
284 
286 void
288 {
289  _error_message = msg;
290 }
291 
292 } // namespace libdap
void set_error_message(std::string msg="")
Definition: Error.cc:287
STL namespace.
bool parse(FILE *fp)
Parse an Error object.
Definition: Error.cc:158
void set_error_code(ErrorCode ec=undefined_error)
Definition: Error.cc:262
top level DAP object to house generic methods
Definition: AISConnect.cc:30
A class for software fault reporting.
Definition: InternalErr.h:64
bool OK() const
Is the Error object valid?
Definition: Error.cc:135
ErrorCode get_error_code() const
Definition: Error.cc:249
std::string get_error_message() const
Definition: Error.cc:278
int ErrorCode
An enumerated type for common errors.
Definition: Error.h:57
void print(FILE *out) const
Definition: Error.cc:200
Pass parameters by reference to a parser.
Definition: parser.h:68
A class for error processing.
Definition: Error.h:92