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 16088 2007-03-28 21:42:19Z jimg $"
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 static const char *err_messages[] =
00060     {"Unknown error", "No such file",
00061      "No such variable", "Malformed expression",
00062      "No authorization", "Cannot read file"
00063     };
00064 
00067 Error::Error()
00068         : _error_code(undefined_error), _error_message(""),
00069         _program_type(undefined_prog_type), _program(0)
00070 {}
00071 
00081 Error::Error(ErrorCode ec, string msg)
00082         : _error_code(ec), _error_message(msg),
00083         _program_type(undefined_prog_type), _program(0)
00084 {}
00085 
00091 Error::Error(string msg)
00092         : _error_code(unknown_error), _error_message(msg),
00093         _program_type(undefined_prog_type), _program(0)
00094 {}
00095 #if 0
00096 
00097 Error::Error(ErrorCode ec, string msg, ProgramType pt, char *pgm)
00098         : _error_code(ec), _error_message(msg),
00099         _program_type(pt), _program(0)
00100 {
00101     _program = new char[strlen(pgm) + 1];
00102     strcpy(_program, pgm);
00103 }
00104 #endif
00105 Error::Error(const Error &copy_from)
00106         : _error_code(copy_from._error_code),
00107         _error_message(copy_from._error_message),
00108         _program_type(copy_from._program_type), _program(0)
00109 {
00110     if (copy_from._program) {
00111         _program = new char[strlen(copy_from._program) + 1];
00112         strcpy(_program, copy_from._program);
00113     }
00114 }
00115 
00116 Error::~Error()
00117 {
00118     delete _program; _program = 0;
00119 }
00120 
00121 Error &
00122 Error::operator=(const Error &rhs)
00123 {
00124     assert(OK());
00125 
00126     if (&rhs == this)  // are they identical?
00127         return *this;
00128     else {
00129         _error_code = rhs._error_code;
00130         _error_message = rhs._error_message;
00131         _program_type = rhs._program_type;
00132 
00133         delete[] _program; _program = 0;
00134         if (rhs._program) {
00135             _program = new char[strlen(rhs._program) + 1];
00136             strcpy(_program, rhs._program);
00137         }
00138 
00139         assert(this->OK());
00140 
00141         return *this;
00142     }
00143 }
00144 
00151 bool
00152 Error::OK() const
00153 {
00154     // The object is empty - users cannot make these, but this class can!
00155     bool empty = ((_error_code == undefined_error)
00156                   && (_error_message.empty()));
00157 
00158     // Just a message - the program part is null.
00159     bool message = ((_error_code != undefined_error)
00160                     && (!_error_message.empty()));
00161 
00162     DBG(cerr << "empty: " << empty << ", message: " << message << endl);
00163     return empty || message;
00164 }
00165 
00174 bool
00175 Error::parse(FILE *fp)
00176 {
00177     if (!fp)
00178         throw InternalErr(__FILE__, __LINE__, "Null input stream");
00179 
00180     void *buffer = Error_buffer(fp);
00181     Error_switch_to_buffer(buffer);
00182 
00183     parser_arg arg(this);
00184 
00185     bool status;
00186     try {
00187         status = Errorparse((void *) & arg) == 0;
00188         Error_delete_buffer(buffer);
00189     }
00190     catch (Error &e) {
00191         throw InternalErr(__FILE__, __LINE__, e.get_error_message());
00192         Error_delete_buffer(buffer);
00193     }
00194 
00195     // STATUS is the result of the parser function; if a recoverable error
00196     // was found it will be true but arg.status() will be false.
00197     // I'm throwing an InternalErr here since Error objects are generated by
00198     // the core; they should always parse! 9/21/2000 jhrg
00199     if (!status || !arg.status())
00200         throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
00201     else
00202         return OK();  // Check object consistency
00203 }
00204 
00205 
00216 void
00217 Error::print(FILE *out) const
00218 {
00219     assert(OK());
00220 
00221     fprintf(out, "Error {\n") ;
00222 
00223     fprintf(out, "    code = %d;\n", static_cast<int>(_error_code)) ;
00224 
00225     // If the error message is wrapped in double quotes, print it, else, add
00226     // wrapping double quotes.
00227     if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
00228         fprintf(out, "    message = %s;\n", _error_message.c_str()) ;
00229     else
00230         fprintf(out, "    message = \"%s\";\n", _error_message.c_str()) ;
00231 
00232     if (_program_type != undefined_prog_type) {
00233         fprintf(out, "    program_type = %d;\n",
00234                 static_cast<int>(_program_type)) ;
00235         fprintf(out, "    program = %s;\n", _program) ;
00236     }
00237 
00238     fprintf(out, "};\n") ;
00239 }
00240 #if 0
00241 
00242 ErrorCode
00243 Error::error_code(ErrorCode ec)
00244 {
00245     assert(OK());
00246     if (ec == undefined_error)
00247         return _error_code;
00248     else {
00249         _error_code = ec;
00250         // Added check to make sure that messages is not accessed beyond its
00251         // bounds. 02/02/04 jhrg
00252         if (_error_message == ""
00253             && ec > undefined_error && ec <= cannot_read_file)
00254             _error_message = err_messages[ec - undefined_error - 1];
00255 
00256         return _error_code;
00257     }
00258 }
00259 #endif
00260 
00261 ErrorCode
00262 Error::get_error_code() const
00263 {
00264     assert(OK());
00265     return _error_code;
00266 }
00267 
00274 void
00275 Error::set_error_code(ErrorCode ec)
00276 {
00277     _error_code = ec;
00278     // Added check to make sure that messages is not accessed beyond its
00279     // bounds. 02/02/04 jhrg
00280     if (_error_message.empty()
00281         && ec > undefined_error && ec <= cannot_read_file)
00282         _error_message = err_messages[ec - undefined_error - 1];
00283 }
00284 #if 0
00285 
00286 string
00287 Error::error_message(string msg)
00288 {
00289     if (msg == "")
00290         return string(_error_message);
00291     else {
00292         _error_message = msg;
00293         return string(_error_message);
00294     }
00295 }
00296 #endif
00297 
00298 string
00299 Error::get_error_message() const
00300 {
00301     assert(OK());
00302 
00303     return string(_error_message);
00304 }
00305 
00307 void
00308 Error::set_error_message(string msg)
00309 {
00310     _error_message = msg;
00311 }
00312 #if 0
00313 
00314 void
00315 Error::display_message(void *) const
00316 {
00317     assert(OK());
00318     cerr << _error_message << endl;
00319 }
00320 
00322 ProgramType
00323 Error::program_type(ProgramType pt)
00324 {
00325     assert(OK());
00326     if (pt == undefined_prog_type)
00327         return _program_type;
00328     else {
00329         _program_type = pt;
00330         return _program_type;
00331     }
00332 }
00333 
00335 ProgramType
00336 Error::get_program_type() const
00337 {
00338     assert(OK());
00339 
00340     return _program_type;
00341 }
00342 
00344 void
00345 Error::set_program_type(ProgramType pt)
00346 {
00347     _program_type = pt;
00348 }
00349 
00351 char *
00352 Error::program(char *pgm)
00353 {
00354     if (pgm == 0)
00355         return _program;
00356     else {
00357         _program = new char[strlen(pgm) + 1];
00358         strcpy(_program, pgm);
00359         return _program;
00360     }
00361 }
00362 
00364 const char *
00365 Error::get_program() const
00366 {
00367     return _program;
00368 }
00369 
00371 void
00372 Error::set_program(char *pgm)
00373 {
00374     _program = new char[strlen(pgm) + 1];
00375     strcpy(_program, pgm);
00376 }
00377 
00379 string
00380 Error::correct_error(void *) const
00381 {
00382     assert(OK());
00383     if (!OK())
00384         return string("");
00385 
00386     display_message(NULL);
00387     return string("");
00388 }
00389 #endif

Generated on Wed Jun 27 12:56:39 2007 for libdap++ by  doxygen 1.4.7