ROSE  0.9.9.109
processSupport.h
1 #ifndef ROSE_PROCESSSUPPORT_H
2 #define ROSE_PROCESSSUPPORT_H
3 
4 #include <vector>
5 #include <string>
6 #include <cstdio>
7 #include <exception>
8 #include "rosedll.h"
9 #include <Sawyer/Assert.h>
10 
11 #if 0
12 // I think that this may already be used.
13 // DQ (4/23/2016): Added to inlcude ROSE_ASSERTION_EXIT and related macro definitions.
14 #include "Diagnostics.h"
15 
16 // Check that ROSE_ASSERTION_BEHAVIOR is defined.
17 #ifndef ROSE_ASSERTION_BEHAVIOR
18 
19 #ifndef ROSE_ASSERTION_EXIT
20 // #warning "We want to have ROSE_ASSERTION_EXIT be defined"
21 #endif
22 
23 // This determines how failed assertions should behave, we want it to be defined as:
24 #define ROSE_ASSERTION_BEHAVIOR ROSE_ASSERTION_EXIT
25 
26 // #error "We want to have ROSE_ASSERTION_BEHAVIOR be defined"
27 #endif
28 #endif
29 
30 ROSE_UTIL_API int systemFromVector(const std::vector<std::string>& argv);
31 FILE* popenReadFromVector(const std::vector<std::string>& argv);
32 // Assumes there is only one child process
33 int pcloseFromVector(FILE* f);
34 
35 // Logic assertion checking.
36 //
37 // ROSE_ASSERT can be used to check assertions in program logic; it should not be used to report errors caused by users. This
38 // macro is used in approximately 36,000 places in the library, tutorial, tests, and projects and is sometimes used
39 // (incorrectly) to report user errors. Therefore it is impracticable to inspect all uses, and we must continue to ensure that
40 // all calls to ROSE_ASSERT are checked at runtime regardless of whether NDEBUG is defined.
41 //
42 // New code should use Sawyer's ASSERT_* macros to check logic assertions because:
43 // + It has two-argument versions where the second argument is the string describing what's wrong in more user-friendly
44 // terms. E.g. ASSERT_forbid2(s.empty(), "symbol name cannot be the empty string").
45 // + The name encodes whether the macro is disabled when NDEBUG is defined. The "always" versions are never disabled, nor
46 // are the macros ASSERT_not_implemented, ASSERT_not_reachable, TODO, and FIXME. E.g., ASSERT_always_require(...).
47 // + Failure behavior is configurable via Rose::Diagnostics API, frontend() command-line, or autotools/cmake. E.g.,
48 // a failing assertion can abort, exit with non-zero status, or throw a Rose::Diagnostics::FailedAssertion exception.
49 // + Output from failed assertions is easier to read because it's split across multiple lines. On ANSI terminals it will
50 // show up in bright red.
51 //
52 // Additional documentation can be found here:
53 // + Sawyer ASSERT_* macros (https://hoosierfocus.com/~matzke/Sawyer/namespaceSawyer_1_1Assert.html)
54 // + Rose::Diagnostics (http://rosecompiler.org/ROSE_HTML_Reference/namespacerose_1_1Diagnostics.html)
55 #ifndef ROSE_ASSERT
56  #if _MSC_VER
57  #include <assert.h>
58  #define ROSE_ASSERT assert
59  #elif defined(ROSE_ASSERTION_BEHAVIOR)
60  // Use Sawyer ASSERT_require because it supports different behaviors (abort, exit, or throw) based on ROSE
61  // configuration and overridden at runtime by frontend() command-line switches or the Rose::Diagnostics API. However,
62  // since "ROSE_ASSERT(false)" and equivalents are used so often for "should not get here", we must ensure that
63  // ROSE_ASSERT is checked regardless of whether NDEBUG is defined (thus the "_always_" version). Also, the Sawyer
64  // ASSERT_always_* macros evaluate their arguments exactly once. New code should use ASSERT_not_implemented,
65  // ASSERT_not_reachable, TODO, or FIXME for "should not get here".
66  #define ROSE_ASSERT ASSERT_always_require
67  #elif !defined(NDEBUG)
68  // This is the original pre-Sawyer version when NDEBUG is not defined.
69  #define ROSE_ASSERT assert
70  #else
71  // This is the original pre-Sawyer version when NDEBUG is defined. It came with this comment: We use "assert(false)"
72  // equivalents so often for "should not get here", but we don't want nontrivial side effects in asserts to be run when
73  // assert is disabled.
74  #define ROSE_ASSERT(exp) do {if (__builtin_constant_p(exp)) {if (exp) {} else (std::abort)();}} while (0)
75  #endif
76 #endif
77 
78 
79 
80 // introducing class rose_excepction
81 // this class gets thrown by ROSE_ABORT
82 // it should probably inherit from std::runtime_error
83 // See also Rose::Diagnostics::FailedAssertion
84 class ROSE_UTIL_API rose_exception
85  : public std::exception
86 {
87  public:
88  // call constructor with a reason for that exception
89  explicit rose_exception( const char *what = "" );
90 
91  virtual const char *what() const throw();
92 
93  private:
94  const char *what_;
95 };
96 
97 // DQ (8/22/2009): Added throw since EDG wants to see that the throw options match when ROSE_ABORT is a macro to "abort()" in
98 // "stdlib.h".
99 // throws rose_exception with the reason "abort" void ROSE_ABORT();
100 //
101 #ifdef ROSE_ABORT
102  // If ROSE_ABORT is #defined as abort then avoid redefining ::abort(). If ::abort() is redefined to throw an exception we
103  // run the risk of infinite recursion since the C++ runtime's exception handler might itself call ::abort(). For example,
104  // try adding "ROSE_ABORT()" to the beginning of CxxGrammarMetaProgram and see what happens! [Robb P. Matzke 2015-04-25]
105 #else
106  extern "C" {
107  #ifdef USE_ROSE
108  // DQ (9/3/2009): This is required for EDG to correctly compile
109  // tps (01/22/2010) : gcc43 requires abort(void)
110  inline void ROSE_ABORT() __THROW __attribute__ ((__noreturn__));
111  #elif defined(_MSC_VER)
112  // DQ (11/28/2009): This is a warning in MSVC ("warning C4273: 'abort' : inconsistent dll linkage")
113  inline ROSE_UTIL_API void ROSE_ABORT(void) { throw rose_exception("abort"); }
114  #elif defined(__clang__)
115  inline void ROSE_ABORT(void) { throw rose_exception("abort"); }
116  #else
117  inline void ROSE_ABORT() throw() { throw rose_exception("abort"); }
118  #endif
119  }
120 #endif
121 
122 // throw rose_exception with user defined abort message
123 ROSE_UTIL_API void ROSE_ABORT(const char *message);
124 
126 // Assertion handling
128 namespace Rose {
129 
131 ROSE_UTIL_API void abortOnFailedAssertion(const char*, const char*, const std::string&, const char*, unsigned, const char*);
132 
134 ROSE_UTIL_API void exitOnFailedAssertion(const char*, const char*, const std::string&, const char*, unsigned, const char*);
135 
139 ROSE_UTIL_API void throwOnFailedAssertion(const char*, const char*, const std::string&, const char*, unsigned, const char*);
140 
157 struct FailedAssertion: std::runtime_error {
158  const char *mesg; // a short message, like "assertion failed", "not implemented" etc.
159  const char *expr; // C++ expression that caused the failure (optional)
160  std::string note; // second argument from ASSERT_*() macros, or empty
161  const char *fileName; // name of file where assertion failed
162  unsigned lineNumber; // line number where assertion failed (1-origin)
163  const char *functionName; // function name (perhaps with arg types) where assertion failed
164  FailedAssertion(const char *mesg, const char *expr, const std::string &note,
165  const char *fileName, unsigned lineNumber, const char *functionName)
166  : std::runtime_error(expr?expr:mesg), mesg(mesg), expr(expr), note(note), fileName(fileName),
167  lineNumber(lineNumber), functionName(functionName) {}
168  ~FailedAssertion() throw () {};
169 };
170 
171 } // namespace
172 
173 #endif // ROSE_PROCESSSUPPORT_H
ROSE_UTIL_API void exitOnFailedAssertion(const char *, const char *, const std::string &, const char *, unsigned, const char *)
Exits with non-zero status for a failed assertion.
Main namespace for the ROSE library.
void(* AssertFailureHandler)(const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname)
Type for user-defined assertion failure handler.
Definition: Assert.h:101
Exception that can be thrown for a failed assertion.
ROSE_UTIL_API void abortOnFailedAssertion(const char *, const char *, const std::string &, const char *, unsigned, const char *)
Aborts for a failed assertion.
ROSE_UTIL_API void throwOnFailedAssertion(const char *, const char *, const std::string &, const char *, unsigned, const char *)
Throws an exception for a failed assertion.
ROSE_UTIL_API void failedAssertionBehavior(Sawyer::Assert::AssertFailureHandler handler)
Property: behavior of failed assertions.