/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Event/ers/ers-00-00-03/src/Issue.cxx

Go to the documentation of this file.
00001 /*
00002  *  Issue.cxx
00003  *  ers
00004  *
00005  *  Created by Matthias Wiesmann on 26.11.04.
00006  *  Copyright 2004 CERN. All rights reserved.
00007  *
00008  */
00009 
00010 
00011 #include <iostream>
00012 #include <sstream>
00013 #include <errno.h>
00014 #include <unistd.h>
00015 #include <stdlib.h>
00016 #include <time.h>
00017 #include <math.h>
00018 #include <sysexits.h>
00019 
00020 #include "ers/ers.h"
00021 #include "ers/HumanStream.h"
00022 #include <cstring>
00023 #include <typeinfo> 
00024 #define BUFFER_SIZE 256 
00025 
00026 #define ISSUE_VALUE_SET_SCALAR(table,key,value) { std::ostringstream stream ; stream << value ;  table[key] = stream.str(); }
00027 
00032 namespace {
00033     ers::Issue *create_issue() { return new ers::Issue(); } 
00034     bool registered = ers::IssueFactory::instance()->register_issue(ers::Issue::ISSUE_CLASS_NAME,create_issue) ;
00035 } 
00036 
00037 using namespace ers ; 
00038 
00039 const char* const Issue::CLASS_KEY = "ISSUE_CLASS" ; 
00040 const char* const Issue::COMPILATION_TIME_KEY = "COMPILATION_TIME" ; 
00041 const char* const Issue::COMPILATION_TARGET_KEY = "COMPILATION_TARGET" ; 
00042 const char* const Issue::COMPILATION_DEBUG_LVL_KEY = "COMPILATION_DEBUG_LVL" ; 
00043 const char* const Issue::COMPILER_KEY = "COMPILER" ; 
00044 const char* const Issue::CPP_CLASS_KEY = "ISSUE_CPP_CLASS" ; 
00045 const char* const Issue::ERS_VERSION_KEY = "ERS_VERSION" ;
00046 const char* const Issue::HOST_NAME_KEY = "HOST_NAME" ; 
00047 const char* const Issue::HOST_TYPE_KEY = "HOST_TYPE" ; 
00048 const char* const Issue::HOST_IP_ADDR_KEY = "HOST_IP" ; 
00049 const char* const Issue::MESSAGE_KEY = "MESSAGE" ; 
00050 const char* const Issue::PROCESS_ID_KEY = "PROCESS_ID" ;
00051 const char* const Issue::PROCESS_PWD_KEY = "PROCESS_PWD" ; 
00052 const char* const Issue::PROGRAM_NAME_KEY = "PROGRAM_NAME"; 
00053 const char* const Issue::RESPONSIBILITY_KEY = "RESPONSIBILITY" ; 
00054 const char* const Issue::SEVERITY_KEY = "SEVERITY" ; 
00055 const char* const Issue::SOURCE_POSITION_KEY = "SOURCE_POSITION" ; 
00056 const char* const Issue::SOURCE_PACKAGE_KEY = "SOURCE_PACKAGE" ; 
00057 const char* const Issue::TIME_KEY = "TIME" ; 
00058 const char* const Issue::TRANSIENCE_KEY = "TRANSIENCE" ; 
00059 const char* const Issue::USER_ID_KEY = "USER_ID" ; 
00060 const char* const Issue::USER_NAME_KEY = "USER_NAME" ; 
00061 const char* const Issue::CAUSE_TEXT_KEY = "CAUSE_TEXT"  ;
00062 const char* const Issue::CAUSE_PSEUDO_KEY = "CAUSE" ;
00063 const char* const Issue::QUALIFIER_LIST_KEY = "QUALIFIERS" ; 
00064 const char* const Issue::EXIT_VALUE_KEY = "EXIT_VALUE" ; 
00065 
00066 const char* const Issue::ISSUE_CLASS_NAME = "ers::issue" ; 
00067 
00068 // Constructors
00069 // ====================================================
00070 
00074 Issue::Issue() {
00075     m_human_description.clear() ; 
00076     m_cause = 0 ; 
00077 } // Issue
00078 
00085 Issue::Issue(const Issue &issue) : std::exception() {
00086     m_value_table = issue.m_value_table ;
00087     m_human_description = issue.m_human_description ; 
00088     if (issue.m_cause) {
00089         this->m_cause = issue.m_cause->clone(); 
00090     } else {
00091         this->m_cause = 0 ; 
00092     } 
00093 } // Issue
00094 
00099 Issue::Issue(const string_map_type &values) {
00100     cause(); 
00101     set_values(values); 
00102     m_human_description.clear();
00103 } // Issue
00104 
00105 
00112 Issue::Issue(const Context &context, severity_t s, const std::string &m) {
00113     cause(); 
00114     setup_common(&context);
00115     severity(s);
00116     finish_setup(m); 
00117 } // Issue
00118 
00121 Issue::Issue(const Context &context, severity_t s) {
00122     cause();   
00123     setup_common(&context);
00124     severity(s);
00125 } // Issue
00126 
00133 Issue::Issue(const Context &context, severity_t s, const std::exception *cause_exception) {
00134     ERS_PRE_CHECK_PTR(cause_exception);
00135     cause(cause_exception); 
00136     setup_common(&context);
00137     severity(s);
00138     finish_setup(cause_exception->what()); 
00139 } // Issue
00140 
00145 Issue::~Issue() throw() {
00146     if (m_cause) delete m_cause ; 
00147     m_cause = 0 ; 
00148 } // ~Issue
00149 
00150 
00151 // Operators and factory methods 
00152 // ====================================================
00153 
00154 
00160 Issue *Issue::clone() const { 
00161     return IssueFactory::instance()->build(this) ; 
00162 } // clone
00163 
00164 
00165 Issue::operator std::string() const {
00166     std::string s = human_description();
00167     return s ;
00168 } // std::string()
00169 
00176 Issue Issue::operator=(const Issue &source) {
00177     Issue target(source);
00178     return target ; 
00179 } // operator=
00180 
00186 bool Issue::operator==(const Issue &other) const throw() {
00187     if (m_value_table != other.m_value_table) return false ; 
00188     if (m_cause == other.m_cause) return true ; 
00189     return (*m_cause) == *(other.m_cause) ; 
00190 } // operator==
00191 
00198 const std::string & Issue::operator[](const std::string &key) const throw() {
00199     return get_value(key,"");
00200 } // operator[]
00201 
00202 
00203 
00204 // ====================================================
00205 // Stream Operators
00206 // ====================================================
00207 
00208 
00215 std::ostream& ers::operator<<(std::ostream& s, const Issue& i) {
00216     return s << i.human_description() ; 
00217 } // operator<<
00218 
00226 Stream& ers::operator<<(Stream& s, const Issue& i) {
00227     s.send(&i); 
00228     return s ; 
00229 } // operator<< 
00230 
00231 
00232 // ====================================================
00233 // Manipulation of the m_cause field 
00234 // ====================================================
00235 
00240 const Issue *Issue::cause() const throw() {
00241     return m_cause ; 
00242 } // cause
00243 
00252 void Issue::cause(const std::exception *c) {
00253     if (c==0) {
00254         m_cause = 0 ; 
00255         return ; 
00256     } // No cause easy. 
00257     const Issue *i = dynamic_cast<const Issue *>(c) ; 
00258     if (i) {
00259         m_cause = i->clone(); 
00260     } else {
00261         m_cause = 0 ; 
00262     } // if
00263     set_value(CAUSE_TEXT_KEY,c->what()); 
00264 } // cause
00265 
00266 
00267 // Value Table manipulation Methods 
00268 // ====================================================
00269 
00274 const string_map_type* Issue::get_value_table() const {
00275     return &m_value_table ; 
00276 } // get_value_table
00277 
00283 const std::string &Issue::get_value(const std::string &key, const std::string &def) const throw() {
00284     string_map_type::const_iterator pos = m_value_table.find(key);
00285     if (pos!=m_value_table.end()) {
00286         return pos->second ; 
00287     } // if
00288     return def ; 
00289 } // get_value
00290 
00294 const std::string &Issue::get_value(const std::string &key) const throw() {
00295     return get_value(key,Core::empty_string) ; 
00296 } // get_value
00297 
00298 
00305 int Issue::get_int_value(const std::string &key, int def) const throw() {
00306     std::string v = get_value(key) ;      
00307     if (! v.empty()) { // not empty 
00308         std::istringstream in(v) ;
00309         int n ; 
00310         in >> n ;
00311         return n ; 
00312         // return atoi(v.c_str());
00313     } else { // empty 
00314         return def ; 
00315     } // empty 
00316 } // get_int_value
00317 
00318 
00325 long Issue::get_long_value(const std::string &key, long def) const throw() {
00326     std::string v = get_value(key) ;      
00327     if (! v.empty()) { // not empty 
00328         std::istringstream in(v) ;
00329         long n ; 
00330         in >> n ;
00331         return n ; 
00332         // return atoi(v.c_str());
00333     } else { // empty 
00334         return def ; 
00335     } // empty 
00336 } // get_long_value
00337 
00344 double Issue::get_double_value(const std::string key, double def=nan("")) const throw() {
00345     std::string v = get_value(key) ;      
00346     if (! v.empty()) { // not empty 
00347         std::istringstream in(v) ;
00348         double n ; 
00349         in >> n ;
00350         return n ; 
00351         // return atoi(v.c_str());
00352     } else { // empty 
00353         return def ; 
00354     } // empty     
00355 } // get_double_value
00356 
00357 
00362 void Issue::set_values(const string_map_type &values) throw() {
00363     m_value_table = values ;
00364 } // load_values
00365 
00371 void Issue::set_value(const std::string &key, uint8_t value) throw() {
00372     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00373 } // set_value
00374 
00377 void Issue::set_value(const std::string &key, uint16_t value) throw() {
00378     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00379 } // set_value
00380 
00383 void Issue::set_value(const std::string &key, uint32_t value) throw() {
00384     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00385 } // set_value
00386 
00389 void Issue::set_value(const std::string &key, uint64_t value) throw() {
00390     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00391 } // set_value
00392 
00395 void Issue::set_value(const std::string &key, int8_t value) throw() {
00396     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00397 } // set_value
00398 
00401 void Issue::set_value(const std::string &key, int16_t value) throw() {
00402     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00403 } // set_value
00404 
00407 void Issue::set_value(const std::string &key, int32_t value) throw() {
00408     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00409 } // set_value
00410 
00413 void Issue::set_value(const std::string &key, int64_t value) throw() {
00414     ISSUE_VALUE_SET_SCALAR(m_value_table,key,value); 
00415 } // set_value
00416 
00422 void Issue::set_value(const std::string &key, double value) throw() {
00423     std::ostringstream stream ;
00424     stream << value ; 
00425     m_value_table[key] = stream.str();
00426 } // set_value
00427 
00433 void Issue::set_value(const std::string &key, const std::string &value) throw() {
00434     if (! value.empty()) {
00435         m_value_table[key] = value ;
00436     }
00437 } // set_value
00438 
00444 void Issue::set_value(const std::string &key, const char* value) throw() {
00445     if (value) {
00446         std::string value_str = std::string(value) ; 
00447         set_value(key,value_str); 
00448     } // if 
00449 } // set_value
00450 
00457 void Issue::set_value(const std::string &key, const void* ptr) throw() {
00458     std::ostringstream stream ;
00459     stream.setf(std::ios::hex,std::ios::basefield); 
00460     stream << (unsigned long) ptr ; 
00461     m_value_table[key] = stream.str();
00462 } // set_value
00463 
00464 
00469 int Issue::values_number() const {
00470     return m_value_table.size(); 
00471 } // values_number
00472 
00473 // ====================================================
00474 // Insertions Methods
00475 // ====================================================
00476 
00481 void Issue::insert(const Context *context) throw() {
00482     if (context) {
00483         set_value(SOURCE_POSITION_KEY,context->position()) ; 
00484         set_value(SOURCE_PACKAGE_KEY,context->package_name()); 
00485         set_value(COMPILER_KEY,context->compiler()) ; 
00486         set_value(COMPILATION_TIME_KEY,context->compilation()) ; 
00487         set_value(COMPILATION_TARGET_KEY,context->host_type()) ; 
00488         int lvl = ers::Context::debug_level();
00489         if (lvl>=0) {
00490             set_value(COMPILATION_DEBUG_LVL_KEY,lvl); 
00491         } // if
00492         int frame_number = context->stack_frames();
00493         for(int i=0;i<frame_number;i++) {
00494             char key_buffer[256] ; 
00495             snprintf(key_buffer,sizeof(key_buffer),"SOURCE-STACK-%03x",i);
00496             set_value(key_buffer,context->stack_frame(i)); 
00497         } // for
00498         std::vector<std::string> qualifs = context->qualifiers() ;
00499         std::vector<std::string>::const_iterator pos ; 
00500         for(pos=qualifs.begin();pos!=qualifs.end();pos++) {
00501             add_qualifier(*pos) ; 
00502         } // for
00503     } // if context 
00504 } // insert
00505 
00509 void Issue::insert_time() throw() {
00510     time_t now ;
00511     time(&now); 
00512     char time_buffer[BUFFER_SIZE] ; 
00513     ctime_r(&now,time_buffer) ; 
00514     char *cr = strchr(time_buffer,'\n');
00515     if (cr) {
00516         *cr = '\0' ;
00517     } // carriage return 
00518     set_value(TIME_KEY,time_buffer); 
00519 } // insert_time
00520 
00521 // ====================================================
00522 // Setup Methods
00523 // ====================================================
00524 
00535 void Issue::setup_common(const Context *context) throw() {
00536     const int errno_copy = errno ; // We need to save errno, because it might be changed 
00537     insert(context);
00538     insert_time();
00539     errno = errno_copy ; // we restaure errno 
00540 } // setup_common
00541 
00542 /* Cut out stuff to remove dependency
00543 * \li Hostname 
00544   * \li Process id
00545   * \li OS and processor of the host
00546  Process p ; 
00547     set_value(PROCESS_ID_KEY,p.process_id()); 
00548     System::User user ; 
00549     set_value(USER_ID_KEY,user.identity()) ; 
00550     set_value(USER_NAME_KEY,user.name_safe()) ; 
00551     set_value(PROCESS_PWD_KEY,System::File::working_directory()); 
00552     System::LocalHost *localhost = System::LocalHost::instance(); 
00553     set_value(HOST_NAME_KEY,localhost->full_name()); 
00554     set_value(HOST_IP_ADDR_KEY,localhost->ip_string()); 
00555     set_value(HOST_TYPE_KEY,localhost->description()); 
00556 
00557 */
00558 
00559 
00568 void Issue::finish_setup(const std::string &msg) throw() {
00569     // set_value(CPP_CLASS_KEY,class_name); 
00570     set_value(CLASS_KEY, get_class_name()) ;
00571     set_value(MESSAGE_KEY,msg); 
00572 } // finish_setup
00573 
00574 
00575 
00576 // ====================================================
00577 // Field Access Methods
00578 // ====================================================
00579 
00587 const char*Issue::get_class_name() const throw()  {
00588     if (m_class_name.empty()) {
00589         const Issue *p = this ;
00590         m_class_name = ers::Core::umangle_gcc_class_name((typeid(*p)).name()).c_str(); 
00591         if (m_class_name.empty()) {
00592              m_class_name=ISSUE_CLASS_NAME ; 
00593         } // fall back 
00594     } 
00595     return m_class_name.c_str() ;
00596 } // get_class_name
00597 
00602 severity_t Issue::severity() const throw() {
00603     std::string value = get_value(SEVERITY_KEY); 
00604     return ers::Core::parse_severity(value);
00605 } // severity
00606 
00611 void Issue::severity(severity_t s) {
00612     set_value(SEVERITY_KEY,ers::Core::to_string(s)); 
00613 } // severity
00614 
00619 bool Issue::is_error() {
00620     severity_t s = severity(); 
00621     return (s==ers::error || s== ers::fatal) ;
00622 } // is_error
00623 
00628 std::string Issue::severity_message() const {
00629     return get_value(SEVERITY_KEY);  
00630 } // severity_message
00631 
00632 
00637 responsibility_t  Issue::responsibility() const throw() {
00638     std::string value = this->get_value(RESPONSIBILITY_KEY); 
00639     return ers::Core::parse_responsibility(value);
00640 } // responsability
00641 
00646 void Issue::responsibility(responsibility_t  r) {
00647     set_value(RESPONSIBILITY_KEY,ers::Core::to_string(r)) ; 
00648 } // responsability
00649 
00650 
00655 void Issue::transience(bool tr) {
00656     set_value(TRANSIENCE_KEY,ers::Core::to_string(tr)) ; 
00657 } // transience
00658 
00662 int Issue::transience() const throw () {
00663     std::string value = this->get_value(TRANSIENCE_KEY); 
00664     return ers::Core::parse_boolean(value.c_str());
00665 } // transience
00666 
00667 
00672 const std::string &Issue::human_description() const throw()  {
00673     if (m_human_description.empty()) {
00674          m_human_description = HumanStream::to_string(this) ; 
00675     } 
00676     return m_human_description ; 
00677 }  // human_description
00678 
00684 const char *Issue::what() const throw() {
00685     std::string desr = human_description() ; 
00686     return desr.c_str(); 
00687 } // what();  
00688 
00689 const std::string &Issue::message() const throw() {
00690     return get_value(MESSAGE_KEY) ; 
00691 } // message
00692 
00693 int Issue::exit_value() const throw() {
00694     int v = 1 ; 
00695     if (transience()==1) v = EX_TEMPFAIL ; 
00696     return get_int_value(EXIT_VALUE_KEY,v); 
00697 } // exit_value
00698 
00703 void Issue::add_qualifier(const std::string &qualif) {
00704     const std::string &qualif_s = get_value(QUALIFIER_LIST_KEY) ; 
00705     std::string::size_type pos = qualif_s.find(qualif);
00706     if (pos!=std::string::npos) return ; // already present
00707     std::string n_qualif = qualif_s+qualif + " " ; 
00708     set_value(QUALIFIER_LIST_KEY,n_qualif); 
00709 } // add_qualifier
00710 
00715 std::vector<std::string> Issue::qualifiers() const {
00716     const std::string &qualif_s = get_value(QUALIFIER_LIST_KEY) ; 
00717     return ers::Core::tokenize(qualif_s,", \t"); 
00718 } // qualifiers
00719 
00720 
00721 
00722 
00723 
00724 
00725 

Generated on Tue Nov 29 22:58:25 2016 for BOSS_7.0.2 by  doxygen 1.4.7