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.
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  */
31 void error_message(const char *msg);
32 
33 /** An error handler that flushes stdout and stderr streams, and sends msg to
34  * the stderr before aborting. When MPI is in use MPI_Abort is invoked. This
35  * implements the behavior after TECA 4.1.0
36  */
37 void error_message_abort(const char *msg);
38 
39 /** Install a custom error haandler. The error handler must have the following
40  * signature.
41  *
42  * void error_handler(const char *msg);
43  *
44  */
46 
47 /// Install the teca_error::error_message error handler
49 
50 /// Install the teca_error::error_message_abort error handler
52 };
53 
54 /// @cond
55 
56 // the operator<< overloads have to be namespace std in order for
57 // boost to find them. they are needed for mutitoken program options
58 namespace std
59 {
60 /// send a vector to a stream
61 template <typename T>
62 std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec)
63 {
64  if (!vec.empty())
65  {
66  os << vec[0];
67  size_t n = vec.size();
68  for (size_t i = 1; i < n; ++i)
69  os << ", " << vec[i];
70  }
71  return os;
72 }
73 
74 /// send a vector of strings to a stream
75 std::ostream &operator<<(std::ostream &os, const std::vector<std::string> &vec);
76 }
77 
78 #ifndef SWIG
79 /// send a fixed length c-array to the stream
80 template <typename num_t, int len,
81  typename = typename std::enable_if<!std::is_same<num_t,char>::value,bool>::type>
82 std::ostream &operator<<(std::ostream &os, const num_t (& data)[len])
83 {
84  os << data[0];
85  for (int i = 1; i < len; ++i)
86  os << ", " << data[i];
87  return os;
88 }
89 #endif
90 
91 /** Return true if we are writing to a TTY. If we are not then we should not
92  * use ansi color codes.
93  */
94 int have_tty();
95 
96 
97 #define ANSI_RED "\033[1;31;40m"
98 #define ANSI_GREEN "\033[1;32;40m"
99 #define ANSI_YELLOW "\033[1;33;40m"
100 #define ANSI_WHITE "\033[1;37;40m"
101 #define ANSI_OFF "\033[0m"
102 
103 #define BEGIN_HL(_color) (have_tty()?_color:"")
104 #define END_HL (have_tty()?ANSI_OFF:"")
105 
106 /// @endcond
107 
108 
109 /** Send a message into the stream with an ANSI color coded message that
110  * include MPI ranks and thread id.
111  */
112 #define TECA_MESSAGE(_strm, _head, _head_color, _msg) \
113 _strm \
114  << BEGIN_HL(_head_color) << _head << END_HL \
115  << " " << teca_parallel_id() << " [" << __FILE__ << ":" << __LINE__ \
116  << " " << TECA_VERSION_DESCR << "]" << std::endl \
117  << BEGIN_HL(_head_color) << _head << END_HL << " " \
118  << BEGIN_HL(ANSI_WHITE) << "" _msg << END_HL << std::endl;
119 
120 /// Send a message into the stream that include MPI ranks and thread id.
121 #define TECA_MESSAGE_RAW(_strm, _head, _msg) \
122 _strm \
123  << _head << " " << teca_parallel_id() << " [" << __FILE__ \
124  << ":" << __LINE__ << " " << TECA_VERSION_DESCR << "]" << std::endl \
125  << _head << " " << "" _msg << std::endl;
126 
127 /** Constructs an the error message using TECA_MESSAGE and invokes the
128  * error handler.
129  */
130 #define TECA_FATAL_ERROR(_msg) \
131 { \
132  std::ostringstream ess; \
133  TECA_MESSAGE(ess, "ERROR:", ANSI_RED, _msg) \
134  teca_error::error_handler(ess.str().c_str()); \
135 }
136 
137 /// Constructs an error message and sends it to the stderr stream
138 #define TECA_ERROR(_msg) TECA_MESSAGE(std::cerr, "ERROR:", ANSI_RED, _msg)
139 
140 /// Constructs a warning message and sends it to the stderr stream
141 #define TECA_WARNING(_msg) TECA_MESSAGE(std::cerr, "WARNING:", ANSI_YELLOW, _msg)
142 
143 /// Constructs a status message and sends it to the stderr stream
144 #define TECA_STATUS(_msg) TECA_MESSAGE(std::cerr, "STATUS:", ANSI_GREEN, _msg)
145 
146 #endif
teca_error
global error handling hooks
Definition: teca_common.h:22
teca_parallel_id.h
teca_error::set_error_message_abort_handler
void set_error_message_abort_handler()
Install the teca_error::error_message_abort error handler.
p_teca_error_handler
void(*)(const char *) p_teca_error_handler
Definition: teca_common.h:19
teca_error::error_message
void error_message(const char *msg)
teca_error::error_message_abort
void error_message_abort(const char *msg)
teca_error::set_error_message_handler
void set_error_message_handler()
Install the teca_error::error_message error handler.
teca_error::error_handler
p_teca_error_handler error_handler
The global error handler instance.
operator<<
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_error::set_error_handler
void set_error_handler(p_teca_error_handler handler)