TECA
The Toolkit for Extreme Climate Analysis
teca_common.h
Go to the documentation of this file.
1 #ifndef teca_common_h
2 #define teca_common_h
3 
4 /// @file
5 
6 #include "teca_config.h"
7 #include "teca_parallel_id.h"
8 
9 #include <iostream>
10 #include <sstream>
11 #include <unistd.h>
12 #include <cstdio>
13 #include <string>
14 #include <vector>
15 
16 /** The call signature for the error handler. The error handler will be passed
17  * a string describing the error.
18  */
19 using p_teca_error_handler = void (*) (const char*);
20 
21 /// global error handling hooks
22 namespace teca_error
23 {
24 /// The global error handler instance.
25 extern p_teca_error_handler error_handler TECA_EXPORT;
26 
27 /** An error handler that flushes stdout and stderr streams, and sends msg to
28  * the stderr before returing. This implements the behavior up to and including
29  * TECA 4.1.0
30  */
32 void error_message(const char *msg);
33 
34 /** An error handler that flushes stdout and stderr streams, and sends msg to
35  * the stderr before aborting. When MPI is in use MPI_Abort is invoked. This
36  * implements the behavior after TECA 4.1.0
37  */
39 void error_message_abort(const char *msg);
40 
41 /** Install a custom error haandler. The error handler must have the following
42  * signature.
43  *
44  * void error_handler(const char *msg);
45  *
46  */
49 
50 /// Install the teca_error::error_message error handler
53 
54 /// Install the teca_error::error_message_abort error handler
57 };
58 
59 /// @cond
60 
61 // the operator<< overloads have to be namespace std in order for
62 // boost to find them. they are needed for mutitoken program options
63 namespace std
64 {
65 /// send a vector to a stream
66 template <typename T>
68 std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec)
69 {
70  if (!vec.empty())
71  {
72  os << vec[0];
73  size_t n = vec.size();
74  for (size_t i = 1; i < n; ++i)
75  os << ", " << vec[i];
76  }
77  return os;
78 }
79 
80 /// send a vector of strings to a stream
82 std::ostream &operator<<(std::ostream &os, const std::vector<std::string> &vec);
83 }
84 
85 #ifndef SWIG
86 /// send a fixed length c-array to the stream
87 template <typename num_t, int len,
88  typename = typename std::enable_if<!std::is_same<num_t,char>::value,bool>::type>
90 std::ostream &operator<<(std::ostream &os, const num_t (& data)[len])
91 {
92  os << data[0];
93  for (int i = 1; i < len; ++i)
94  os << ", " << data[i];
95  return os;
96 }
97 #endif
98 
99 /** Return true if we are writing to a TTY. If we are not then we should not
100  * use ansi color codes.
101  */
102 TECA_EXPORT int have_tty();
103 
104 
105 #define ANSI_RED "\033[1;31;40m"
106 #define ANSI_GREEN "\033[1;32;40m"
107 #define ANSI_YELLOW "\033[1;33;40m"
108 #define ANSI_WHITE "\033[1;37;40m"
109 #define ANSI_OFF "\033[0m"
110 
111 #define BEGIN_HL(_color) (have_tty()?_color:"")
112 #define END_HL (have_tty()?ANSI_OFF:"")
113 
114 /// @endcond
115 
116 
117 /** Send a message into the stream with an ANSI color coded message that
118  * include MPI ranks and thread id.
119  */
120 #define TECA_MESSAGE(_strm, _head, _head_color, _msg) \
121 _strm \
122  << BEGIN_HL(_head_color) << _head << END_HL \
123  << " " << teca_parallel_id() << " [" << __FILE__ << ":" << __LINE__ \
124  << " " << TECA_VERSION_DESCR << "]" << std::endl \
125  << BEGIN_HL(_head_color) << _head << END_HL << " " \
126  << BEGIN_HL(ANSI_WHITE) << "" _msg << END_HL << std::endl;
127 
128 /// Send a message into the stream that include MPI ranks and thread id.
129 #define TECA_MESSAGE_RAW(_strm, _head, _msg) \
130 _strm \
131  << _head << " " << teca_parallel_id() << " [" << __FILE__ \
132  << ":" << __LINE__ << " " << TECA_VERSION_DESCR << "]" << std::endl \
133  << _head << " " << "" _msg << std::endl;
134 
135 /** Constructs an the error message using TECA_MESSAGE and invokes the
136  * error handler.
137  */
138 #define TECA_FATAL_ERROR(_msg) \
139 { \
140  std::ostringstream ess; \
141  TECA_MESSAGE(ess, "ERROR:", ANSI_RED, _msg) \
142  teca_error::error_handler(ess.str().c_str()); \
143 }
144 
145 /// Constructs an error message and sends it to the stderr stream
146 #define TECA_ERROR(_msg) TECA_MESSAGE(std::cerr, "ERROR:", ANSI_RED, _msg)
147 
148 /// Constructs a warning message and sends it to the stderr stream
149 #define TECA_WARNING(_msg) TECA_MESSAGE(std::cerr, "WARNING:", ANSI_YELLOW, _msg)
150 
151 /// Constructs a status message and sends it to the stderr stream
152 #define TECA_STATUS(_msg) TECA_MESSAGE(std::cerr, "STATUS:", ANSI_GREEN, _msg)
153 
154 #endif
teca_error
global error handling hooks
Definition: teca_common.h:22
operator<<
TECA_EXPORT std::ostream & operator<<(std::ostream &os, const teca_calendar_util::time_point &tpt)
send the time_point to a stream in humnan readable form
teca_parallel_id.h
teca_error::set_error_handler
TECA_EXPORT void set_error_handler(p_teca_error_handler handler)
p_teca_error_handler
void(*)(const char *) p_teca_error_handler
Definition: teca_common.h:19
teca_error::error_message_abort
TECA_EXPORT void error_message_abort(const char *msg)
teca_error::error_message
TECA_EXPORT void error_message(const char *msg)
teca_error::set_error_message_abort_handler
TECA_EXPORT void set_error_message_abort_handler()
Install the teca_error::error_message_abort error handler.
teca_error::set_error_message_handler
TECA_EXPORT void set_error_message_handler()
Install the teca_error::error_message error handler.
teca_error::TECA_EXPORT
p_teca_error_handler error_handler TECA_EXPORT
The global error handler instance.