libdap Updated for version 3.18.1
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
45using namespace std;
46
47// Glue routines declared in Error.lex
48extern void Error_switch_to_buffer(void *new_buffer);
49extern void Error_delete_buffer(void * buffer);
50extern void *Error_buffer(FILE *fp);
51
52//extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
53extern int Errorparse(libdap::parser_arg *arg);
54
55namespace 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.
59static 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
74Error::Error() : _error_code(undefined_error), _error_message("")
75{}
76
86Error::Error(ErrorCode ec, string msg)
87 : _error_code(ec), _error_message(msg)
88{}
89
95Error::Error(string msg)
96 : _error_code(unknown_error), _error_message(msg)
97{}
98
99Error::Error(const Error &copy_from)
100 : _error_code(copy_from._error_code),
101 _error_message(copy_from._error_message)
102{
103}
104
105Error::~Error()
106{
107}
108
109Error &
110Error::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
132bool
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
155bool
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
197void
198Error::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
226void
227Error::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
248{
249 assert(OK());
250 return _error_code;
251}
252
259void
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
275string
277{
278 assert(OK());
279
280 return string(_error_message);
281}
282
284void
286{
287 _error_message = msg;
288}
289
290} // namespace libdap
A class for error processing.
Definition: Error.h:91
void set_error_code(ErrorCode ec=undefined_error)
Definition: Error.cc:260
void print(FILE *out) const
Definition: Error.cc:198
ErrorCode get_error_code() const
Definition: Error.cc:247
string get_error_message() const
Definition: Error.cc:276
bool parse(FILE *fp)
Parse an Error object.
Definition: Error.cc:156
bool OK() const
Is the Error object valid?
Definition: Error.cc:133
void set_error_message(string msg="")
Definition: Error.cc:285
A class for software fault reporting.
Definition: InternalErr.h:65
int ErrorCode
An enumerated type for common errors.
Definition: Error.h:55
Pass parameters by reference to a parser.
Definition: parser.h:69