lpw
2020-09-01 a6c01451f65c7fc139844333f37345283d5f4354
commit | author | age
a6c014 1 /*
L 2  * Copyright 2019 Google
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #import <Foundation/Foundation.h>
18
19 #import "GDTCORConsoleLogger.h"
20
21 NS_ASSUME_NONNULL_BEGIN
22
23 /** A block type that could be run instead of normal assertion logging. No return type, no params.
24  */
25 typedef void (^GDTCORAssertionBlock)(void);
26
27 /** Returns the result of executing a soft-linked method present in unit tests that allows a block
28  * to be run instead of normal assertion logging. This helps ameliorate issues with catching
29  * exceptions that occur on a dispatch_queue.
30  *
31  * @return A block that can be run instead of normal assert printing.
32  */
33 FOUNDATION_EXPORT GDTCORAssertionBlock _Nullable GDTCORAssertionBlockToRunInstead(void);
34
35 #if defined(NS_BLOCK_ASSERTIONS)
36
37 #define GDTCORAssert(condition, ...) \
38   do {                               \
39   } while (0);
40
41 #define GDTCORFatalAssert(condition, ...) \
42   do {                                    \
43   } while (0);
44
45 #else  // defined(NS_BLOCK_ASSERTIONS)
46
47 /** Asserts using a console log, unless a block was specified to be run instead.
48  *
49  * @param condition The condition you'd expect to be YES.
50  */
51 #define GDTCORAssert(condition, format, ...)                                     \
52   do {                                                                           \
53     __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS                                          \
54     if (__builtin_expect(!(condition), 0)) {                                     \
55       GDTCORAssertionBlock assertionBlock = GDTCORAssertionBlockToRunInstead();  \
56       if (assertionBlock) {                                                      \
57         assertionBlock();                                                        \
58       } else {                                                                   \
59         NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__];    \
60         __assert_file__ = __assert_file__ ? __assert_file__ : @"<Unknown File>"; \
61         GDTCORLogAssert(NO, __assert_file__, __LINE__, format, ##__VA_ARGS__);   \
62         __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS                                       \
63       }                                                                          \
64     }                                                                            \
65   } while (0);
66
67 /** Asserts by logging to the console and throwing an exception if NS_BLOCK_ASSERTIONS is not
68  * defined.
69  *
70  * @param condition The condition you'd expect to be YES.
71  */
72 #define GDTCORFatalAssert(condition, format, ...)                                          \
73   do {                                                                                     \
74     __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS                                                    \
75     if (__builtin_expect(!(condition), 0)) {                                               \
76       GDTCORAssertionBlock assertionBlock = GDTCORAssertionBlockToRunInstead();            \
77       if (assertionBlock) {                                                                \
78         assertionBlock();                                                                  \
79       } else {                                                                             \
80         NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__];              \
81         __assert_file__ = __assert_file__ ? __assert_file__ : @"<Unknown File>";           \
82         GDTCORLogAssert(YES, __assert_file__, __LINE__, format, ##__VA_ARGS__);            \
83         [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd                    \
84                                                             object:self                    \
85                                                               file:__assert_file__         \
86                                                         lineNumber:__LINE__                \
87                                                        description:format, ##__VA_ARGS__]; \
88         __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS                                                 \
89       }                                                                                    \
90     }                                                                                      \
91   } while (0);
92
93 #endif  // defined(NS_BLOCK_ASSERTIONS)
94
95 NS_ASSUME_NONNULL_END