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 17002 2007-08-27 19:16:51Z pwest $"
00039     };
00040 
00041 #include <stdio.h>
00042 #include <assert.h>
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 // There are two entries for 'cannot read file' because of an error made 
00060 // when the message was first added to this class. 
00061 static const char *err_messages[] = {
00062     "Undefined error",
00063     "Unknown error",
00064     "Internal error",
00065     "No such file",
00066     "No such variable",
00067     "Malformed expression",
00068     "No authorization",
00069     "Cannot read file",
00070     "Cannot read file"
00071 };
00072 
00075 Error::Error() : _error_code(undefined_error), _error_message("")
00076 {}
00077 
00087 Error::Error(ErrorCode ec, string msg)
00088         : _error_code(ec), _error_message(msg)
00089 {}
00090 
00096 Error::Error(string msg)
00097         : _error_code(unknown_error), _error_message(msg)
00098 {}
00099 
00100 Error::Error(const Error &copy_from)
00101         : _error_code(copy_from._error_code),
00102         _error_message(copy_from._error_message)
00103 {
00104 }
00105 
00106 Error::~Error()
00107 {
00108 }
00109 
00110 Error &
00111 Error::operator=(const Error &rhs)
00112 {
00113     assert(OK());
00114 
00115     if (&rhs == this)  // are they identical?
00116         return *this;
00117     else {
00118         _error_code = rhs._error_code;
00119         _error_message = rhs._error_message;
00120 
00121         assert(this->OK());
00122 
00123         return *this;
00124     }
00125 }
00126 
00133 bool
00134 Error::OK() const
00135 {
00136     // The object is empty - users cannot make these, but this class can!
00137     bool empty = ((_error_code == undefined_error)
00138                   && (_error_message.empty()));
00139 
00140     // Just a message - the program part is null.
00141     bool message = ((_error_code != undefined_error)
00142                     && (!_error_message.empty()));
00143 
00144     DBG(cerr << "empty: " << empty << ", message: " << message << endl);
00145     return empty || message;
00146 }
00147 
00156 bool
00157 Error::parse(FILE *fp)
00158 {
00159     if (!fp)
00160         throw InternalErr(__FILE__, __LINE__, "Null input stream");
00161 
00162     void *buffer = Error_buffer(fp);
00163     Error_switch_to_buffer(buffer);
00164 
00165     parser_arg arg(this);
00166 
00167     bool status;
00168     try {
00169         status = Errorparse((void *) & arg) == 0;
00170         Error_delete_buffer(buffer);
00171     }
00172     catch (Error &e) {
00173         Error_delete_buffer(buffer);
00174         throw InternalErr(__FILE__, __LINE__, e.get_error_message());
00175     }
00176 
00177     // STATUS is the result of the parser function; if a recoverable error
00178     // was found it will be true but arg.status() will be false.
00179     // I'm throwing an InternalErr here since Error objects are generated by
00180     // the core; they should always parse! 9/21/2000 jhrg
00181     if (!status || !arg.status())
00182         throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
00183     else
00184         return OK();  // Check object consistency
00185 }
00186 
00187 
00198 void
00199 Error::print(FILE *out) const
00200 {
00201     assert(OK());
00202 
00203     fprintf(out, "Error {\n") ;
00204 
00205     fprintf(out, "    code = %d;\n", static_cast<int>(_error_code)) ;
00206 
00207     // If the error message is wrapped in double quotes, print it, else, add
00208     // wrapping double quotes.
00209     if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
00210         fprintf(out, "    message = %s;\n", _error_message.c_str()) ;
00211     else
00212         fprintf(out, "    message = \"%s\";\n", _error_message.c_str()) ;
00213 
00214     fprintf(out, "};\n") ;
00215 }
00216 
00227 void
00228 Error::print(ostream &strm) const
00229 {
00230     assert(OK());
00231 
00232     strm << "Error {\n" ;
00233 
00234     strm << "    code = " << static_cast<int>(_error_code) << ";\n" ;
00235 
00236     // If the error message is wrapped in double quotes, print it, else, add
00237     // wrapping double quotes.
00238     if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
00239         strm << "    message = " << _error_message.c_str() << ";\n" ;
00240     else
00241         strm << "    message = \"" << _error_message.c_str() << "\";\n"  ;
00242 
00243     strm << "};\n" ;
00244 }
00245 
00247 ErrorCode
00248 Error::get_error_code() const
00249 {
00250     assert(OK());
00251     return _error_code;
00252 }
00253 
00260 void
00261 Error::set_error_code(ErrorCode ec)
00262 {
00263     _error_code = ec;
00264     // Added check to make sure that err_messages is not accessed beyond its
00265     // bounds. 02/02/04 jhrg
00266     if (_error_message.empty()
00267         && ec > undefined_error && ec <= cannot_read_file) {
00268         _error_message = err_messages[ec - undefined_error];
00269     }
00270     else {
00271         _error_message = err_messages[0];
00272     }
00273 }
00274 
00276 string
00277 Error::get_error_message() const
00278 {
00279     assert(OK());
00280 
00281     return string(_error_message);
00282 }
00283 
00285 void
00286 Error::set_error_message(string msg)
00287 {
00288     _error_message = msg;
00289 }

Generated on Wed Nov 28 16:23:14 2007 for libdap++ by  doxygen 1.4.7