Error.cc
// -*- mode: c++; c-basic-offset:4 -*-
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.
// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
// (c) COPYRIGHT URI/MIT 1994-1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
// Implementation for the Error class.
#include "config.h"
#include <cstdio>
#include <cassert>
#include <utility>
#include "Error.h"
#include "parser.h"
#include "InternalErr.h"
#include "debug.h"
using namespace std;
// Glue routines declared in Error.lex
extern void Error_switch_to_buffer(void *new_buffer);
extern void Error_delete_buffer(void * buffer);
extern void *Error_buffer(FILE *fp);
//extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
extern int Errorparse(libdap::parser_arg *arg);
namespace libdap {
// There are two entries for 'cannot read file' because of an error made
// when the message was first added to this class.
static const char *err_messages[] = {
"Undefined error",
"Unknown error",
"Internal error",
"No such file",
"No such variable",
"Malformed expression",
"No authorization",
"Cannot read file",
"Not Implemented",
""
};
Error &
Error::operator=(const Error &rhs)
{
assert(OK());
if (&rhs == this) // are they identical?
return *this;
else {
_error_code = rhs._error_code;
_error_message = rhs._error_message;
d_file = rhs.d_file;
d_line = rhs.d_line;
assert(this->OK());
return *this;
}
}
bool
Error::OK() const
{
// The object is empty - users cannot make these, but this class can!
bool empty = ((_error_code == undefined_error)
&& (_error_message.empty()));
// Just a message - the program part is null.
bool message = ((_error_code != undefined_error)
&& (!_error_message.empty()));
DBG(cerr << "empty: " << empty << ", message: " << message << endl);
return empty || message;
}
bool
Error::parse(FILE *fp)
{
if (!fp)
throw InternalErr(__FILE__, __LINE__, "Null input stream");
void *buffer = Error_buffer(fp);
Error_switch_to_buffer(buffer);
parser_arg arg(this);
bool status;
try {
status = Errorparse(&arg) == 0;
Error_delete_buffer(buffer);
}
catch (Error &e) {
Error_delete_buffer(buffer);
throw InternalErr(__FILE__, __LINE__, e.get_error_message());
}
// STATUS is the result of the parser function; if a recoverable error
// was found it will be true but arg.status() will be false.
// I'm throwing an InternalErr here since Error objects are generated by
// the core; they should always parse! 9/21/2000 jhrg
if (!status || !arg.status())
throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
else
return OK(); // Check object consistency
}
void
Error::print(FILE *out) const
{
assert(OK());
fprintf(out, "Error {\n") ;
fprintf(out, " code = %d;\n", static_cast<int>(_error_code)) ;
// If the error message is wrapped in double quotes, print it, else, add
// wrapping double quotes.
if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
fprintf(out, " message = %s;\n", _error_message.c_str()) ;
else
fprintf(out, " message = \"%s\";\n", _error_message.c_str()) ;
fprintf(out, "};\n") ;
}
void
Error::print(ostream &strm) const
{
assert(OK());
strm << "Error {\n" ;
strm << " code = " << static_cast<int>(_error_code) << ";\n" ;
// If the error message is wrapped in double quotes, print it, else, add
// wrapping double quotes.
if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
strm << " message = " << _error_message.c_str() << ";\n" ;
else
strm << " message = \"" << _error_message.c_str() << "\";\n" ;
strm << "};\n" ;
}
ErrorCode
Error::get_error_code() const
{
assert(OK());
return _error_code;
}
void
Error::set_error_code(ErrorCode ec)
{
_error_code = ec;
// Added check to make sure that err_messages is not accessed beyond its
// bounds. 02/02/04 jhrg
if (_error_message.empty()
&& ec > undefined_error && ec <= cannot_read_file) {
_error_message = err_messages[ec - undefined_error];
}
else {
_error_message = err_messages[0];
}
}
string
Error::get_error_message() const
{
assert(OK());
return {_error_message};
}
void
Error::set_error_message(string msg)
{
_error_message = std::move(msg);
}
} // namespace libdap
libdap::Error
A class for error processing.
Definition: Error.h:94
libdap::Error::get_error_message
std::string get_error_message() const
Definition: Error.cc:243
libdap::InternalErr
A class for software fault reporting.
Definition: InternalErr.h:65
libdap
top level DAP object to house generic methods
Definition: AlarmHandler.h:36
libdap::ErrorCode
int ErrorCode
An enumerated type for common errors.
Definition: Error.h:58
libdap::parser_arg
Pass parameters by reference to a parser.
Definition: parser.h:69