libdap++ Updated for version 3.8.2
|
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 ©_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