Flutter Engine
The Flutter Engine
assert.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_PLATFORM_ASSERT_H_
6#define RUNTIME_PLATFORM_ASSERT_H_
7
8#include "platform/globals.h"
10
11#if !defined(DEBUG) && !defined(NDEBUG)
12#error neither DEBUG nor NDEBUG defined
13#elif defined(DEBUG) && defined(NDEBUG)
14#error both DEBUG and NDEBUG defined
15#endif
16
17// TODO(5411406): include sstream for now, once we have a Utils::toString()
18// implemented for all the primitive types we can replace the usage of
19// sstream by Utils::toString()
20#if defined(DEBUG) || defined(TESTING)
21#include <sstream>
22#include <string>
23#endif
24
25namespace dart {
26
28 public:
30 : file_(file), line_(line) {}
31
32 protected:
33 void Print(const char* format,
34 va_list arguments,
35 bool will_abort = false) const;
36
37 const char* const file_;
38 const int line_;
39
41};
42
44 public:
46
47 DART_NORETURN void Fail(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
48
49 template <typename T>
50 T NotNull(const T p);
51};
52
54 public:
56
57 void Fail(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
58
59#if defined(TESTING)
60 template <typename E, typename A>
61 void Equals(const E& expected, const A& actual);
62
63 template <typename E, typename A>
64 void NotEquals(const E& not_expected, const A& actual);
65
66 template <typename E, typename A, typename T>
67 void FloatEquals(const E& expected, const A& actual, const T& tol);
68
69 void StringEquals(const char* expected, const char* actual);
70
71 void IsSubstring(const char* needle, const char* haystack);
72
73 void IsNotSubstring(const char* needle, const char* haystack);
74
75 template <typename E, typename A>
76 void LessThan(const E& left, const A& right);
77
78 template <typename E, typename A>
79 void LessEqual(const E& left, const A& right);
80
81 template <typename E, typename A>
82 void GreaterThan(const E& left, const A& right);
83
84 template <typename E, typename A>
85 void GreaterEqual(const E& left, const A& right);
86
87 template <typename T>
88 void NotNull(const T p);
89
90 template <typename T>
91 void Null(const T p);
92#endif
93
94 static bool failed() { return failed_; }
95
96 private:
97 static bool failed_;
98};
99
100template <typename T>
102 if (p != nullptr) return p;
103 Fail("expected: not nullptr, found nullptr");
104 return nullptr;
105}
106
107#if defined(TESTING)
108// Only allow the expensive (with respect to code size) assertions
109// in testing code.
110template <typename E, typename A>
111void Expect::Equals(const E& expected, const A& actual) {
112 if (actual == expected) return;
113 std::ostringstream ess, ass;
114 ess << expected;
115 ass << actual;
116 std::string es = ess.str(), as = ass.str();
117 Fail("expected: <%s> but was: <%s>", es.c_str(), as.c_str());
118}
119
120template <typename E, typename A>
121void Expect::NotEquals(const E& not_expected, const A& actual) {
122 if (actual != not_expected) return;
123 std::ostringstream ness;
124 ness << not_expected;
125 std::string nes = ness.str();
126 Fail("did not expect: <%s>", nes.c_str());
127}
128
129template <typename E, typename A, typename T>
130void Expect::FloatEquals(const E& expected, const A& actual, const T& tol) {
131 if (((expected - tol) <= actual) && (actual <= (expected + tol))) {
132 return;
133 }
134 std::ostringstream ess, ass, tolss;
135 ess << expected;
136 ass << actual;
137 tolss << tol;
138 std::string es = ess.str(), as = ass.str(), tols = tolss.str();
139 Fail("expected: <%s> but was: <%s> (tolerance: <%s>)", es.c_str(), as.c_str(),
140 tols.c_str());
141}
142
143static void Escape(std::string& dst, const char* src) {
144 char c;
145 while ((c = *src++) != '\0') {
146 if (c == '\n') {
147 dst += "\\n\"\n\"";
148 } else if (c == '\'') {
149 dst += "\\\'";
150 } else if (c == '\"') {
151 dst += "\\\"";
152 } else if (c == '\\') {
153 dst += "\\\\";
154 } else {
155 dst += c;
156 }
157 }
158}
159
160inline void Expect::StringEquals(const char* expected, const char* actual) {
161 if (strcmp(expected, actual) == 0) return;
162 if (actual == nullptr) {
163 Fail("expected:\n<\"%s\">\nbut was nullptr", expected);
164 } else {
165 if (strcmp(expected, actual) == 0) return;
166 std::string es, as;
167 Escape(es, expected);
168 Escape(as, actual);
169 Fail("expected:\n<\"%s\">\nbut was:\n<\"%s\">", es.c_str(), as.c_str());
170 }
171}
172
173inline void Expect::IsSubstring(const char* needle, const char* haystack) {
174 if (strstr(haystack, needle) != nullptr) return;
175 Fail("expected <\"%s\"> to be a substring of <\"%s\">", needle, haystack);
176}
177
178inline void Expect::IsNotSubstring(const char* needle, const char* haystack) {
179 if (strstr(haystack, needle) == nullptr) return;
180 Fail("expected <\"%s\"> to not be a substring of <\"%s\">", needle, haystack);
181}
182
183template <typename E, typename A>
184void Expect::LessThan(const E& left, const A& right) {
185 if (left < right) return;
186 std::ostringstream ess, ass;
187 ess << left;
188 ass << right;
189 std::string es = ess.str(), as = ass.str();
190 Fail("expected: %s < %s", es.c_str(), as.c_str());
191}
192
193template <typename E, typename A>
194void Expect::LessEqual(const E& left, const A& right) {
195 if (left <= right) return;
196 std::ostringstream ess, ass;
197 ess << left;
198 ass << right;
199 std::string es = ess.str(), as = ass.str();
200 Fail("expected: %s <= %s", es.c_str(), as.c_str());
201}
202
203template <typename E, typename A>
204void Expect::GreaterThan(const E& left, const A& right) {
205 if (left > right) return;
206 std::ostringstream ess, ass;
207 ess << left;
208 ass << right;
209 std::string es = ess.str(), as = ass.str();
210 Fail("expected: %s > %s", es.c_str(), as.c_str());
211}
212
213template <typename E, typename A>
214void Expect::GreaterEqual(const E& left, const A& right) {
215 if (left >= right) return;
216 std::ostringstream ess, ass;
217 ess << left;
218 ass << right;
219 std::string es = ess.str(), as = ass.str();
220 Fail("expected: %s >= %s", es.c_str(), as.c_str());
221}
222
223template <typename T>
224void Expect::NotNull(const T p) {
225 if (p != nullptr) return;
226 Fail("expected: not nullptr, found nullptr");
227}
228
229template <typename T>
230void Expect::Null(const T p) {
231 if (p == nullptr) return;
232 Fail("expected: nullptr, found not null pointer");
233}
234#endif
235
236} // namespace dart
237
238#if defined(_MSC_VER)
239#define FATAL(format, ...) \
240 dart::Assert(__FILE__, __LINE__).Fail(format, __VA_ARGS__);
241#else
242#define FATAL(format, ...) \
243 dart::Assert(__FILE__, __LINE__).Fail(format, ##__VA_ARGS__);
244#endif
245
246#define UNIMPLEMENTED() FATAL("unimplemented code")
247
248#define UNREACHABLE() FATAL("unreachable code")
249
250#define OUT_OF_MEMORY() FATAL("Out of memory.")
251
252#if defined(DEBUG)
253// DEBUG binaries use assertions in the code.
254// Note: We wrap the if statement in a do-while so that we get a compile
255// error if there is no semicolon after ASSERT(condition). This
256// ensures that we get the same behavior on DEBUG and RELEASE builds.
257
258#define ASSERT(cond) \
259 do { \
260 if (!(cond)) dart::Assert(__FILE__, __LINE__).Fail("expected: %s", #cond); \
261 } while (false)
262
263#define ASSERT_EQUAL(actual, expected) \
264 do { \
265 if ((expected) != (actual)) { \
266 const std::string actual_str = std::to_string(actual); \
267 const std::string expected_str = std::to_string(expected); \
268 dart::Assert(__FILE__, __LINE__) \
269 .Fail("expected \"%s\" = %s, actual \"%s\" = %s", #expected, \
270 expected_str.c_str(), #actual, actual_str.c_str()); \
271 } \
272 } while (false)
273
274#define ASSERT_LESS_OR_EQUAL(actual, expected) \
275 do { \
276 if ((actual) > (expected)) { \
277 const std::string actual_str = std::to_string(actual); \
278 const std::string expected_str = std::to_string(expected); \
279 dart::Assert(__FILE__, __LINE__) \
280 .Fail("expected \"%s\" = %s >= actual \"%s\" = %s", #expected, \
281 expected_str.c_str(), #actual, actual_str.c_str()); \
282 } \
283 } while (false)
284
285#define ASSERT_IMPLIES(antecedent, consequent) \
286 do { \
287 if (antecedent) { \
288 ASSERT(consequent); \
289 } \
290 } while (false)
291
292// DEBUG_ASSERT allows identifiers in condition to be undeclared in release
293// mode.
294#define DEBUG_ASSERT(cond) ASSERT(cond)
295
296// Returns 'ptr'; useful for initializer lists:
297// class Foo { Foo(int* ptr) : ptr_(ASSERT_NOTNULL(ptr)) ...
298#define ASSERT_NOTNULL(ptr) dart::Assert(__FILE__, __LINE__).NotNull((ptr))
299
300#else // if defined(DEBUG)
301
302// In order to avoid variable unused warnings for code that only uses
303// a variable in an ASSERT or EXPECT, we make sure to use the macro
304// argument.
305#define ASSERT(condition) \
306 do { \
307 } while (false && (condition))
308
309#define ASSERT_EQUAL(expected, actual) \
310 do { \
311 } while (false && ((expected) != (actual)))
312
313#define ASSERT_LESS_OR_EQUAL(expected, actual) \
314 do { \
315 } while (false && ((actual) > (expected)))
316
317#define ASSERT_IMPLIES(antecedent, consequent) \
318 do { \
319 } while (false && (!(antecedent) || (consequent)))
320
321#define DEBUG_ASSERT(cond)
322
323#define ASSERT_NOTNULL(ptr) (ptr)
324
325#endif // if defined(DEBUG)
326
327#define RELEASE_ASSERT(cond) \
328 do { \
329 if (!(cond)) dart::Assert(__FILE__, __LINE__).Fail("expected: %s", #cond); \
330 } while (false)
331
332#define RELEASE_ASSERT_WITH_MSG(cond, msg) \
333 do { \
334 if (!(cond)) { \
335 dart::Assert(__FILE__, __LINE__).Fail("%s: expected: %s", msg, #cond); \
336 } \
337 } while (false)
338
339#define COMPILE_ASSERT(expr) static_assert(expr, "")
340
341#if defined(TESTING)
342
343// EXPECT and FAIL are equivalent to ASSERT and FATAL except that they do not
344// cause early termination of the unit test. This allows testing to proceed
345// further to be able to report other failures before reporting the overall
346// unit tests as failing.
347
348#define EXPECT(condition) \
349 if (!(condition)) { \
350 dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition); \
351 }
352
353#define EXPECT_EQ(expected, actual) \
354 dart::Expect(__FILE__, __LINE__).Equals((expected), (actual))
355
356#define EXPECT_NE(not_expected, actual) \
357 dart::Expect(__FILE__, __LINE__).NotEquals((not_expected), (actual))
358
359#define EXPECT_FLOAT_EQ(expected, actual, tol) \
360 dart::Expect(__FILE__, __LINE__).FloatEquals((expected), (actual), (tol))
361
362#define EXPECT_STREQ(expected, actual) \
363 dart::Expect(__FILE__, __LINE__).StringEquals((expected), (actual))
364
365#define EXPECT_SUBSTRING(needle, haystack) \
366 dart::Expect(__FILE__, __LINE__).IsSubstring((needle), (haystack))
367
368#define EXPECT_NOTSUBSTRING(needle, haystack) \
369 dart::Expect(__FILE__, __LINE__).IsNotSubstring((needle), (haystack))
370
371#define EXPECT_LT(left, right) \
372 dart::Expect(__FILE__, __LINE__).LessThan((left), (right))
373
374#define EXPECT_LE(left, right) \
375 dart::Expect(__FILE__, __LINE__).LessEqual((left), (right))
376
377#define EXPECT_GT(left, right) \
378 dart::Expect(__FILE__, __LINE__).GreaterThan((left), (right))
379
380#define EXPECT_GE(left, right) \
381 dart::Expect(__FILE__, __LINE__).GreaterEqual((left), (right))
382
383#define EXPECT_NOTNULL(ptr) dart::Expect(__FILE__, __LINE__).NotNull((ptr))
384
385#define EXPECT_NULLPTR(ptr) dart::Expect(__FILE__, __LINE__).Null((ptr))
386
387#if defined(_MSC_VER)
388#define FAIL(format, ...) \
389 dart::Expect(__FILE__, __LINE__).Fail(format, __VA_ARGS__);
390#else
391#define FAIL(format, ...) \
392 dart::Expect(__FILE__, __LINE__).Fail(format, ##__VA_ARGS__);
393#endif
394
395#endif // defined(TESTING)
396
397#endif // RUNTIME_PLATFORM_ASSERT_H_
Assert(const char *file, int line)
Definition: assert.h:45
DART_NORETURN void Fail(const char *format,...) const PRINTF_ATTRIBUTE(2
Definition: assert.cc:45
DART_NORETURN void T NotNull(const T p)
DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicAssertionHelper)
const char *const file_
Definition: assert.h:37
void Print(const char *format, va_list arguments, bool will_abort=false) const
Definition: assert.cc:19
DynamicAssertionHelper(const char *file, int line)
Definition: assert.h:29
Expect(const char *file, int line)
Definition: assert.h:55
void Fail(const char *format,...) const PRINTF_ATTRIBUTE(2
void static bool failed()
Definition: assert.h:94
uint32_t uint32_t * format
SK_API sk_sp< SkSurface > Null(int width, int height)
Definition: dart_vm.cc:33
static bool Equals(const Object &expected, const Object &actual)
bool Equals(const T *a, const T *b)
Definition: dl_comparable.h:19
bool NotEquals(const T *a, const T *b)
Definition: dl_comparable.h:70
dst
Definition: cp.py:12
#define PRINTF_ATTRIBUTE(string_index, first_to_check)
Definition: globals.h:697
#define T
Definition: precompiler.cc:65