libdap++ Updated for version 3.8.2

Error.cc

Go to the documentation of this file.
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 // (c) COPYRIGHT URI/MIT 1994-1999
00027 // Please read the full copyright statement in the file COPYRIGHT_URI.
00028 //
00029 // Authors:
00030 //      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
00031 
00032 // Implementation for the Error class.
00033 
00034 
00035 #include "config.h"
00036 
00037 static char rcsid[] not_used =
00038     {"$Id: Error.cc 18940 2008-06-25 19:22:37Z jimg $"
00039     };
00040 
00041 #include <cstdio>
00042 #include <cassert>
00043 
00044 #include "Error.h"
00045 #include "parser.h"
00046 #include "InternalErr.h"
00047 #include "debug.h"
00048 
00049 using namespace std;
00050 
00051 // Glue routines declared in Error.lex
00052 extern void Error_switch_to_buffer(void *new_buffer);
00053 extern void Error_delete_buffer(void * buffer);
00054 extern void *Error_buffer(FILE *fp);
00055 
00056 extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
00057 extern int Errorparse(void *arg);
00058 
00059 namespace libdap {
00060 
00061 // There are two entries for 'cannot read file' because of an error made 
00062 // when the message was first added to this class. 
00063 static const char *err_messages[] = {
00064     "Undefined error",
00065     "Unknown error",
00066     "Internal error",
00067     "No such file",
00068     "No such variable",
00069     "Malformed expression",
00070     "No authorization",
00071     "Cannot read file",
00072     "Cannot read file"
00073 };
00074 
00077 Error::Error() : _error_code(undefined_error), _error_message("")
00078 {}
00079 
00089 Error::Error(ErrorCode ec, string msg)
00090         : _error_code(ec), _error_message(msg)
00091 {}
00092 
00098 Error::Error(string msg)
00099         : _error_code(unknown_error), _error_message(msg)
00100 {}
00101 
00102 Error::Error(const Error &copy_from)
00103         : _error_code(copy_from._error_code),
00104         _error_message(copy_from._error_message)
00105 {
00106 }
00107 
00108 Error::~Error()
00109 {
00110 }
00111 
00112 Error &
00113 Error::operator=(const Error &rhs)
00114 {
00115     assert(OK());
00116 
00117     if (&rhs == this)  // are they identical?
00118         return *this;
00119     else {
00120         _error_code = rhs._error_code;
00121         _error_message = rhs._error_message;
00122 
00123         assert(this->OK());
00124 
00125         return *this;
00126     }
00127 }
00128 
00135 bool
00136 Error::OK() const
00137 {
00138     // The object is empty - users cannot make these, but this class can!
00139     bool empty = ((_error_code == undefined_error)
00140                   && (_error_message.empty()));
00141 
00142     // Just a message - the program part is null.
00143     bool message = ((_error_code != undefined_error)
00144                     && (!_error_message.empty()));
00145 
00146     DBG(cerr << "empty: " << empty << ", message: " << message << endl);
00147     return empty || message;
00148 }
00149 
00158 bool
00159 Error::parse(FILE *fp)
00160 {
00161     if (!fp)
00162         throw InternalErr(__FILE__, __LINE__, "Null input stream");
00163 
00164     void *buffer = Error_buffer(fp);
00165     Error_switch_to_buffer(buffer);
00166 
00167     parser_arg arg(this);
00168 
00169     bool status;
00170     try {
00171         status = Errorparse((void *) & arg) == 0;
00172         Error_delete_buffer(buffer);
00173     }
00174     catch (Error &e) {
00175         Error_delete_buffer(buffer);
00176         throw InternalErr(__FILE__, __LINE__, e.get_error_message());
00177     }
00178 
00179     // STATUS is the result of the parser function; if a recoverable error
00180     // was found it will be true but arg.status() will be false.
00181     // I'm throwing an InternalErr here since Error objects are generated by
00182     // the core; they should always parse! 9/21/2000 jhrg
00183     if (!status || !arg.status())
00184         throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
00185     else
00186         return OK();  // Check object consistency
00187 }
00188 
00189 
00200 void
00201 Error::print(FILE *out) const
00202 {
00203     assert(OK());
00204 
00205     fprintf(out, "Error {\n") ;
00206 
00207     fprintf(out, "    code = %d;\n", static_cast<int>(_error_code)) ;
00208 
00209     // If the error message is wrapped in double quotes, print it, else, add
00210     // wrapping double quotes.
00211     if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
00212         fprintf(out, "    message = %s;\n", _error_message.c_str()) ;
00213     else
00214         fprintf(out, "    message = \"%s\";\n", _error_message.c_str()) ;
00215 
00216     fprintf(out, "};\n") ;
00217 }
00218 
00229 void
00230 Error::print(ostream &strm) const
00231 {
00232     assert(OK());
00233 
00234     strm << "Error {\n" ;
00235 
00236     strm << "    code = " << static_cast<int>(_error_code) << ";\n" ;
00237 
00238     // If the error message is wrapped in double quotes, print it, else, add
00239     // wrapping double quotes.
00240     if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
00241         strm << "    message = " << _error_message.c_str() << ";\n" ;
00242     else
00243         strm << "    message = \"" << _error_message.c_str() << "\";\n"  ;
00244 
00245     strm << "};\n" ;
00246 }
00247 
00249 ErrorCode
00250 Error::get_error_code() const
00251 {
00252     assert(OK());
00253     return _error_code;
00254 }
00255 
00262 void
00263 Error::set_error_code(ErrorCode ec)
00264 {
00265     _error_code = ec;
00266     // Added check to make sure that err_messages is not accessed beyond its
00267     // bounds. 02/02/04 jhrg
00268     if (_error_message.empty()
00269         && ec > undefined_error && ec <= cannot_read_file) {
00270         _error_message = err_messages[ec - undefined_error];
00271     }
00272     else {
00273         _error_message = err_messages[0];
00274     }
00275 }
00276 
00278 string
00279 Error::get_error_message() const
00280 {
00281     assert(OK());
00282 
00283     return string(_error_message);
00284 }
00285 
00287 void
00288 Error::set_error_message(string msg)
00289 {
00290     _error_message = msg;
00291 }
00292 
00293 } // namespace libdap