libdap++  Updated for version 3.12.0
Error.cc
Go to the documentation of this file.
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 static char rcsid[] not_used =
38  {"$Id: Error.cc 27197 2013-10-01 21:29:54Z jimg $"
39  };
40 
41 #include <cstdio>
42 #include <cassert>
43 
44 #include "Error.h"
45 #include "parser.h"
46 #include "InternalErr.h"
47 #include "debug.h"
48 
49 using namespace std;
50 
51 // Glue routines declared in Error.lex
52 extern void Error_switch_to_buffer(void *new_buffer);
53 extern void Error_delete_buffer(void * buffer);
54 extern void *Error_buffer(FILE *fp);
55 
56 //extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
57 extern int Errorparse(libdap::parser_arg *arg);
58 
59 namespace libdap {
60 
61 // There are two entries for 'cannot read file' because of an error made
62 // when the message was first added to this class.
63 static const char *err_messages[] = {
64  "Undefined error",
65  "Unknown error",
66  "Internal error",
67  "No such file",
68  "No such variable",
69  "Malformed expression",
70  "No authorization",
71  "Cannot read file",
72  "Cannot read file"
73 };
74 
77 Error::Error() : _error_code(undefined_error), _error_message("")
78 {}
79 
89 Error::Error(ErrorCode ec, string msg)
90  : _error_code(ec), _error_message(msg)
91 {}
92 
98 Error::Error(string msg)
99  : _error_code(unknown_error), _error_message(msg)
100 {}
101 
102 Error::Error(const Error &copy_from)
103  : _error_code(copy_from._error_code),
104  _error_message(copy_from._error_message)
105 {
106 }
107 
109 {
110 }
111 
112 Error &
114 {
115  assert(OK());
116 
117  if (&rhs == this) // are they identical?
118  return *this;
119  else {
120  _error_code = rhs._error_code;
122 
123  assert(this->OK());
124 
125  return *this;
126  }
127 }
128 
135 bool
136 Error::OK() const
137 {
138  // The object is empty - users cannot make these, but this class can!
139  bool empty = ((_error_code == undefined_error)
140  && (_error_message.empty()));
141 
142  // Just a message - the program part is null.
143  bool message = ((_error_code != undefined_error)
144  && (!_error_message.empty()));
145 
146  DBG(cerr << "empty: " << empty << ", message: " << message << endl);
147  return empty || message;
148 }
149 
158 bool
159 Error::parse(FILE *fp)
160 {
161  if (!fp)
162  throw InternalErr(__FILE__, __LINE__, "Null input stream");
163 
164  void *buffer = Error_buffer(fp);
165  Error_switch_to_buffer(buffer);
166 
167  parser_arg arg(this);
168 
169  bool status;
170  try {
171  status = Errorparse(&arg) == 0;
172  Error_delete_buffer(buffer);
173  }
174  catch (Error &e) {
175  Error_delete_buffer(buffer);
176  throw InternalErr(__FILE__, __LINE__, e.get_error_message());
177  }
178 
179  // STATUS is the result of the parser function; if a recoverable error
180  // was found it will be true but arg.status() will be false.
181  // I'm throwing an InternalErr here since Error objects are generated by
182  // the core; they should always parse! 9/21/2000 jhrg
183  if (!status || !arg.status())
184  throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
185  else
186  return OK(); // Check object consistency
187 }
188 
189 
200 void
201 Error::print(FILE *out) const
202 {
203  assert(OK());
204 
205  fprintf(out, "Error {\n") ;
206 
207  fprintf(out, " code = %d;\n", static_cast<int>(_error_code)) ;
208 
209  // If the error message is wrapped in double quotes, print it, else, add
210  // wrapping double quotes.
211  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
212  fprintf(out, " message = %s;\n", _error_message.c_str()) ;
213  else
214  fprintf(out, " message = \"%s\";\n", _error_message.c_str()) ;
215 
216  fprintf(out, "};\n") ;
217 }
218 
229 void
230 Error::print(ostream &strm) const
231 {
232  assert(OK());
233 
234  strm << "Error {\n" ;
235 
236  strm << " code = " << static_cast<int>(_error_code) << ";\n" ;
237 
238  // If the error message is wrapped in double quotes, print it, else, add
239  // wrapping double quotes.
240  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
241  strm << " message = " << _error_message.c_str() << ";\n" ;
242  else
243  strm << " message = \"" << _error_message.c_str() << "\";\n" ;
244 
245  strm << "};\n" ;
246 }
247 
249 ErrorCode
251 {
252  assert(OK());
253  return _error_code;
254 }
255 
262 void
264 {
265  _error_code = ec;
266  // Added check to make sure that err_messages is not accessed beyond its
267  // bounds. 02/02/04 jhrg
268  if (_error_message.empty()
269  && ec > undefined_error && ec <= cannot_read_file) {
270  _error_message = err_messages[ec - undefined_error];
271  }
272  else {
273  _error_message = err_messages[0];
274  }
275 }
276 
278 string
280 {
281  assert(OK());
282 
283  return string(_error_message);
284 }
285 
287 void
289 {
290  _error_message = msg;
291 }
292 
293 } // namespace libdap