Skip to content

Commit 64d1e6b

Browse files
zxu123wilhuff
authored andcommitted
implement C++ assert (stdio, apple) (#612)
* implement C++ assert (stdio, apple) * Update tests for firebase_firestore_util renames * renaming `assert.h` to `firebase_assert.h` * refactoring to a common `WrapNSStringNoCopy()`
1 parent 9172e6e commit 64d1e6b

File tree

8 files changed

+314
-15
lines changed

8 files changed

+314
-15
lines changed

Firestore/core/src/firebase/firestore/util/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ add_library(
2323
)
2424
target_link_libraries(
2525
firebase_firestore_util_base
26-
PRIVATE
26+
PUBLIC
2727
absl_base
2828
)
2929

3030
# stdio-dependent bits can be built and tested everywhere
3131
add_library(
3232
firebase_firestore_util_stdio
33+
assert_stdio.cc
3334
log_stdio.cc
3435
)
3536
target_link_libraries(
@@ -42,6 +43,7 @@ target_link_libraries(
4243
if(APPLE)
4344
add_library(
4445
firebase_firestore_util_apple
46+
assert_apple.mm
4547
log_apple.mm
4648
)
4749
target_compile_options(
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2018 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+
#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h"
18+
19+
#import <Foundation/Foundation.h>
20+
21+
#include <string.h>
22+
23+
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
24+
25+
namespace firebase {
26+
namespace firestore {
27+
namespace util {
28+
29+
void FailAssert(const char* file, const char* func, const int line, const char* format, ...) {
30+
va_list args;
31+
va_start(args, format);
32+
NSString *description = [[NSString alloc] initWithFormat:WrapNSStringNoCopy(format) arguments:args];
33+
va_end(args);
34+
[[NSAssertionHandler currentHandler]
35+
handleFailureInFunction:WrapNSStringNoCopy(func)
36+
file:WrapNSStringNoCopy(file)
37+
lineNumber:line
38+
description:@"FIRESTORE INTERNAL ASSERTION FAILED: %@", description];
39+
abort();
40+
}
41+
42+
} // namespace util
43+
} // namespace firestore
44+
} // namespace firebase
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2018 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+
#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h"
18+
19+
#include <stdarg.h>
20+
21+
#include <exception>
22+
#include <string>
23+
24+
#include <absl/base/config.h>
25+
26+
#include "Firestore/core/src/firebase/firestore/util/string_printf.h"
27+
28+
namespace firebase {
29+
namespace firestore {
30+
namespace util {
31+
32+
void FailAssert(const char* file, const char* func, const int line,
33+
const char* format, ...) {
34+
std::string message;
35+
StringAppendF(&message, "ASSERT: %s(%d) %s: ", file, line, func);
36+
37+
va_list args;
38+
va_start(args, format);
39+
StringAppendV(&message, format, args);
40+
va_end(args);
41+
42+
#if ABSL_HAVE_EXCEPTIONS
43+
throw std::logic_error(message);
44+
45+
#else
46+
fprintf(stderr, "%s\n", message.c_str());
47+
std::terminate();
48+
#endif
49+
}
50+
51+
} // namespace util
52+
} // namespace firestore
53+
} // namespace firebase
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2018 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+
// To avoid naming-collision, this header is called firebase_assert.h instead
18+
// of assert.h.
19+
20+
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FIREBASE_ASSERT_H_
21+
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FIREBASE_ASSERT_H_
22+
23+
#include <stdlib.h>
24+
25+
#include "Firestore/core/src/firebase/firestore/util/log.h"
26+
27+
#define FIREBASE_EXPAND_STRINGIFY_(X) #X
28+
#define FIREBASE_EXPAND_STRINGIFY(X) FIREBASE_EXPAND_STRINGIFY_(X)
29+
30+
// FIREBASE_ASSERT_* macros are not compiled out of release builds. They should
31+
// be used for assertions that need to be propagated to end-users of SDKs.
32+
// FIREBASE_DEV_ASSERT_* macros are compiled out of release builds, similar to
33+
// the C assert() macro. They should be used for internal assertions that are
34+
// only shown to SDK developers.
35+
36+
// Assert condition is true, if it's false log an assert with the specified
37+
// expression as a string.
38+
#define FIREBASE_ASSERT_WITH_EXPRESSION(condition, expression) \
39+
do { \
40+
if (!(condition)) { \
41+
firebase::firestore::util::FailAssert( \
42+
__FILE__, __PRETTY_FUNCTION__, __LINE__, \
43+
FIREBASE_EXPAND_STRINGIFY(expression)); \
44+
} \
45+
} while(0)
46+
47+
// Assert condition is true, if it's false log an assert with the specified
48+
// expression as a string. Compiled out of release builds.
49+
#if defined(NDEBUG)
50+
#define FIREBASE_DEV_ASSERT_WITH_EXPRESSION(condition, expression) \
51+
{ (void)(condition); }
52+
#else
53+
#define FIREBASE_DEV_ASSERT_WITH_EXPRESSION(condition, expression) \
54+
FIREBASE_ASSERT_WITH_EXPRESSION(condition, expression)
55+
#endif // !defined(NDEBUG)
56+
57+
// Custom assert() implementation that is not compiled out in release builds.
58+
#define FIREBASE_ASSERT(expression) \
59+
FIREBASE_ASSERT_WITH_EXPRESSION(expression, expression)
60+
61+
// Custom assert() implementation that is compiled out in release builds.
62+
// Compiled out of release builds.
63+
#define FIREBASE_DEV_ASSERT(expression) \
64+
FIREBASE_DEV_ASSERT_WITH_EXPRESSION(expression, expression)
65+
66+
// Assert condition is true otherwise display the specified expression,
67+
// message and abort.
68+
#define FIREBASE_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, ...) \
69+
do { \
70+
if (!(condition)) { \
71+
firebase::firestore::util::LogError( \
72+
FIREBASE_EXPAND_STRINGIFY(expression)); \
73+
firebase::firestore::util::FailAssert( \
74+
__FILE__, __PRETTY_FUNCTION__, __LINE__, __VA_ARGS__); \
75+
} \
76+
} while(0)
77+
78+
// Assert condition is true otherwise display the specified expression,
79+
// message and abort. Compiled out of release builds.
80+
#if defined(NDEBUG)
81+
#define FIREBASE_DEV_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, \
82+
...) \
83+
{ (void)(condition); }
84+
#else
85+
#define FIREBASE_DEV_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, \
86+
...) \
87+
FIREBASE_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, __VA_ARGS__)
88+
#endif // !defined(NDEBUG)
89+
90+
namespace firebase {
91+
namespace firestore {
92+
namespace util {
93+
94+
// A no-return helper function. To raise an assertion, use Macro instead.
95+
void FailAssert(const char* file, const char* func, const int line,
96+
const char* format, ...);
97+
98+
} // namespace util
99+
} // namespace firestore
100+
} // namespace firebase
101+
102+
#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FIREBASE_ASSERT_H_

Firestore/core/src/firebase/firestore/util/log_apple.mm

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,14 @@
2121

2222
#include <string>
2323

24+
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
25+
2426
namespace firebase {
2527
namespace firestore {
2628
namespace util {
2729

2830
namespace {
2931

30-
// Translates a C format string to the equivalent NSString without making a
31-
// copy.
32-
NSString* FormatString(const char* format) {
33-
return [[NSString alloc] initWithBytesNoCopy:(void*)format
34-
length:strlen(format)
35-
encoding:NSUTF8StringEncoding
36-
freeWhenDone:NO];
37-
}
38-
3932
// Translates a C++ LogLevel to the equivalent Objective-C FIRLoggerLevel
4033
FIRLoggerLevel ToFIRLoggerLevel(LogLevel level) {
4134
switch (level) {
@@ -85,37 +78,37 @@ void LogDebug(const char* format, ...) {
8578
va_list list;
8679
va_start(list, format);
8780
FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerFirestore, @"I-FST000001",
88-
FormatString(format), list);
81+
WrapNSStringNoCopy(format), list);
8982
va_end(list);
9083
}
9184

9285
void LogInfo(const char* format, ...) {
9386
va_list list;
9487
va_start(list, format);
9588
FIRLogBasic(FIRLoggerLevelInfo, kFIRLoggerFirestore, @"I-FST000001",
96-
FormatString(format), list);
89+
WrapNSStringNoCopy(format), list);
9790
va_end(list);
9891
}
9992

10093
void LogWarning(const char* format, ...) {
10194
va_list list;
10295
va_start(list, format);
10396
FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerFirestore, @"I-FST000001",
104-
FormatString(format), list);
97+
WrapNSStringNoCopy(format), list);
10598
va_end(list);
10699
}
107100

108101
void LogError(const char* format, ...) {
109102
va_list list;
110103
va_start(list, format);
111104
FIRLogBasic(FIRLoggerLevelError, kFIRLoggerFirestore, @"I-FST000001",
112-
FormatString(format), list);
105+
WrapNSStringNoCopy(format), list);
113106
va_end(list);
114107
}
115108

116109
void LogMessageV(LogLevel log_level, const char* format, va_list args) {
117110
FIRLogBasic(ToFIRLoggerLevel(log_level), kFIRLoggerFirestore, @"I-FST000001",
118-
FormatString(format), args);
111+
WrapNSStringNoCopy(format), args);
119112
}
120113

121114
void LogMessage(LogLevel log_level, const char* format, ...) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2018 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+
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_
18+
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_
19+
20+
#import <Foundation/Foundation.h>
21+
22+
namespace firebase {
23+
namespace firestore {
24+
namespace util {
25+
26+
// Translates a C string to the equivalent NSString without making a copy.
27+
inline NSString* WrapNSStringNoCopy(const char* c_str) {
28+
return [[NSString alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(c_str))
29+
length:strlen(c_str)
30+
encoding:NSUTF8StringEncoding
31+
freeWhenDone:NO];
32+
}
33+
34+
35+
} // namespace util
36+
} // namespace firestore
37+
} // namespace firebase
38+
39+
#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_

Firestore/core/test/firebase/firestore/util/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ target_link_libraries(
2626
if(APPLE)
2727
cc_test(
2828
firebase_firestore_util_apple_test
29+
assert_test.cc
2930
log_test.cc
3031
)
3132
target_link_libraries(
@@ -36,6 +37,7 @@ endif(APPLE)
3637

3738
cc_test(
3839
firebase_firestore_util_stdio_test
40+
assert_test.cc
3941
log_test.cc
4042
)
4143
target_link_libraries(

0 commit comments

Comments
 (0)