Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
exit.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file utility/exit.cc
11 /// @brief Program exit functions and macros
12 /// @author David Kim (dekim@u.washington.edu)
13 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
14 
15 #ifdef USEMPI
16 #include <mpi.h>
17 #endif
18 // Unit headers
19 #include <utility/exit.hh>
21 #include <utility/backtrace.hh>
22 // C++ headers
23 #include <cassert>
24 #include <cstdlib>
25 #include <iostream>
26 
27 // Boinc headers
28 #ifdef BOINC
29 #include <utility/io/izstream.hh>
30 #include <boinc_api.h>
31 #endif
32 
33 #include <string>
34 
35 #include <vector>
36 
37 #ifndef _WIN32
38 #include <unistd.h>
39 #endif
40 
41 #include <cstdio>
42 
43 #ifdef _WIN32
44 #include <io.h>
45 //__declspec(dllexport) int isatty(int fd) { return _isatty(fd); }
46 #endif
47 
48 namespace utility {
49 
50 
51 /// Place holder for 'end-action' of utility::exit(…)
52 static void (*main_exit_callback)(void) = 0;
53 
55 {
56  main_exit_callback = my_callback;
57 }
58 
59 /// Array to hold all additional exit-callbacks
60 std::vector< UtilityExitCallBack > & get_all_exit_callbacks()
61 {
62  static std::vector< UtilityExitCallBack > * all_CB = new std::vector< UtilityExitCallBack >;
63  return *all_CB;
64 }
65 
67 {
68  get_all_exit_callbacks().push_back( cb );
69 }
70 
72 {
73  for ( std::vector<UtilityExitCallBack>::iterator it=get_all_exit_callbacks().begin(); it < get_all_exit_callbacks().end(); ++it ) {
74  if ( (*it) == cb ) {
75  get_all_exit_callbacks().erase(it);
76  break;
77  }
78  }
79 }
80 
81 
82 class EXCN_utility_exit : public excn::EXCN_Base { //noboday should be allowed to throw this... that's why its privately hidden in this modul...
83 public:
84  EXCN_utility_exit( std::string const& msg, std::string const& file, int const line );
85  virtual void show( std::ostream& ) const;
86 private:
87  std::string const msg_;
88  std::string const file_;
89  int const line_;
90 };
91 
92 
93 EXCN_utility_exit::EXCN_utility_exit( std::string const& msg, std::string const& file, int const line ) :
94  msg_( msg ),
95  file_( file ),
96  line_( line )
97 {}
98 
99 void EXCN_utility_exit::show( std::ostream& os ) const {
100  os << "\n\n[ERROR] EXCN_utility_exit has been thrown from: "
101  << file_ << " line: " << line_ << "\n";
102  if ( ! msg_.empty() ) os << "ERROR: " << msg_ << "\n\n";
103 }
104 
105 
106 /// @brief Exit with file + line + message + optional status
107 void
109  std::string const & file,
110  int const line,
111  std::string const & message,
112  int const status
113 )
114 {
115  // Calling all preset exit-callback's
116  for ( std::vector<UtilityExitCallBack>::iterator it=get_all_exit_callbacks().begin(); it < get_all_exit_callbacks().end(); ++it ) {
117  (*it)();
118  }
119 
120  if ( isatty(fileno(stdout)) ) std::cerr << "\x1b[0m\x1b[1m\x1b[31m"; // Reseting the terminal state and setting bold-red color
121  if ( ! message.empty() ) std::cerr << std::endl << "ERROR: " << message << std::endl;
122  std::cerr << "ERROR:: Exit from: " << file << " line: " << line << std::endl;
123  if ( isatty(fileno(stdout)) ) std::cerr << "\x1b[0m";
124  print_backtrace();
125  std::cerr.flush();
126 
127 #ifndef BOINC
128  // why did this get placed here basically skipping the logic below?!
129  throw EXCN_utility_exit( message, file, line );
130 #endif
131 
132 #ifdef USEMPI
133  MPI_Abort( MPI_COMM_WORLD, 911 );
134 #endif
135 
136 #ifdef BOINC
137 
138  // check if there are results, if so, return success
139  bool hasresults = false;
140  // Quick hack, since we can't access the options assume
141  // the result file will always be named default.out and thaat
142  // it should be gzipped for now.
143  utility::io::izstream data( "default.out" );
144  if ( !data ){
145  std::cerr << "BOINC:: Error reading and gzipping output datafile: default.out" << std::endl; std::cerr.flush();
146  boinc_finish( status );
147  }
148  std::string tmpline;
149  getline( data, tmpline ); // sequence line
150  getline( data, tmpline ); // score line
151  while( getline(data,tmpline) ) {
152  if ( tmpline.substr(0,7) == "SCORE: " ) {
153  hasresults = true;
154  break;
155  }
156  }
157  data.close();
158  if (hasresults) {
159  utility::file::gzip( "default.out", true );
160  boinc_finish( 0 );
161  } else {
162  boinc_finish( status );
163  }
164 
165 #else // Not BOINC
166  if ( main_exit_callback ) {
168  std::exit( status );
169  } else {
170 #ifndef _WIN32
171  assert( false ); // Force a core dump for post-mortem debugging
172 #endif // Not _WIN32
173  std::exit( status );
174  }
175 #endif // BOINC
176 
177  throw EXCN_utility_exit( message, file, line );
178 
179 }
180 
181 
182 /// @brief Conditional Exit with file + line + message + optional status
183 int
185  bool condition,
186  std::string const & file,
187  int const line,
188  std::string const & message,
189  int const status
190 ){
191  if ( condition ) return 1;
192  exit( file, line, message, status );
193  return 0; // keep compiler happy.
194 }
195 
196 
197 } // namespace utility
ocstream cerr(std::cerr)
Wrapper around std::cerr.
Definition: ocstream.hh:290
int cond_exit(bool condition, std::string const &file, int const line, std::string const &message, int const status)
Conditional Exit with file + line + message + optional status.
Definition: exit.cc:184
virtual std::string const msg() const
Definition: EXCN_Base.hh:70
void exit(std::string const &file, int const line, std::string const &message, int const status)
Exit with file + line + message + optional status.
Definition: exit.cc:108
def status
void print_backtrace()
Definition: backtrace.hh:135
std::istream & getline(std::istream &stream, Fstring &s)
Get Line from Stream.
Definition: Fstring.cc:1610
static void(* main_exit_callback)(void)=0
Place holder for 'end-action' of utility::exit(…)
Definition: exit.cc:52
long gzip(std::string const &uncompressedfile, bool overwrite)
gzip: file compression
Definition: gzip_util.cc:42
Programmatic backtrace whenever you want it.
void close()
Close the ifstream and reset the state.
Definition: izstream.hh:219
Program exit functions and macros.
std::vector< UtilityExitCallBack > & get_all_exit_callbacks()
Array to hold all additional exit-callbacks.
Definition: exit.cc:60
izstream: Input file stream wrapper for uncompressed and compressed files
Definition: izstream.hh:44
Input file stream wrapper for uncompressed and compressed files.
static char * line
Definition: Svm.cc:2683
void set_main_exit_callback(UtilityExitCallBack my_callback)
Set call back funtion that will be called on utility::exit. Use this function to overload default beh...
Definition: exit.cc:54
std::string const file_
Definition: exit.cc:88
void(* UtilityExitCallBack)(void)
Definition: exit.hh:142
EXCN_utility_exit(std::string const &msg, std::string const &file, int const line)
Definition: exit.cc:93
base class for Exception system
void remove_exit_callback(UtilityExitCallBack cb)
Remove additional callback function that was previously added by using add_exit_callback.
Definition: exit.cc:71
utility::keys::lookup::begin< KeyType > const begin
std::string const msg_
Definition: exit.cc:87
ocstream & flush()
Flush the stream.
Definition: ocstream.hh:143
virtual void show(std::ostream &) const
Definition: exit.cc:99
void add_exit_callback(UtilityExitCallBack cb)
Add additional callback function that will be called before standard exit(…) is executed. [Note: do not confuse this function with 'set_main_exit_callback' which is replacing the end behavior of exit(…)].
Definition: exit.cc:66