pw_assert: Optionally disable CHECK value capture

Adds a config option to pw_assert to allow projects to disable CHECK
value captures for code size savings.

Change-Id: Icd1dc9e59849446e2c7e0fb72e9be2153efdd024
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/70161
Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
diff --git a/pw_assert/docs.rst b/pw_assert/docs.rst
index d528a87..525050c 100644
--- a/pw_assert/docs.rst
+++ b/pw_assert/docs.rst
@@ -719,6 +719,14 @@
   This defaults to being disabled if ``NDEBUG`` is defined, else it is enabled
   by default.
 
+.. c:macro:: PW_ASSERT_CAPTURE_VALUES
+
+  Controls whether the evaluated values of a CHECK statement are captured as
+  arguments to the final string. Disabling this will reduce code size at CHECK
+  callsites, but slightly reduces debugability.
+
+  This defaults to enabled.
+
 -------------
 Compatibility
 -------------
diff --git a/pw_assert/public/pw_assert/config.h b/pw_assert/public/pw_assert/config.h
index d2feebb..8bcb0ee 100644
--- a/pw_assert/public/pw_assert/config.h
+++ b/pw_assert/public/pw_assert/config.h
@@ -26,3 +26,10 @@
 #define PW_ASSERT_ENABLE_DEBUG 1
 #endif  // defined (NDEBUG)
 #endif  // !defined(PW_ASSERT_ENABLE_DEBUG)
+
+// PW_ASSERT_CAPTURE_VALUES controls whether the evaluated values of a CHECK are
+// captured in the final string. Disabling this will reduce codesize at CHECK
+// callsites.
+#if !defined(PW_ASSERT_CAPTURE_VALUES)
+#define PW_ASSERT_CAPTURE_VALUES 1
+#endif  // !defined(PW_ASSERT_CAPTURE_VALUES)
diff --git a/pw_assert/public/pw_assert/internal/check_impl.h b/pw_assert/public/pw_assert/internal/check_impl.h
index 3a9cbe3..bb7c7f3 100644
--- a/pw_assert/public/pw_assert/internal/check_impl.h
+++ b/pw_assert/public/pw_assert/internal/check_impl.h
@@ -132,12 +132,13 @@
 
 // clang-format on
 
-// PW_CHECK - If condition evaluates to false, crash. Message optional.
+// PW_CHECK_OK - If condition does not evaluate to PW_STATUS_OK, crash. Message
+// optional.
 #define PW_CHECK_OK(expression, ...)                                     \
   do {                                                                   \
     const _PW_CHECK_OK_STATUS _pw_assert_check_ok_status = (expression); \
     if (_pw_assert_check_ok_status != PW_STATUS_OK) {                    \
-      PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(                           \
+      _PW_CHECK_BINARY_ARG_HANDLER(                                      \
           #expression,                                                   \
           pw_StatusString(_pw_assert_check_ok_status),                   \
           "==",                                                          \
@@ -199,40 +200,73 @@
     _PW_CHECK_CONVERT(type_decl, evaluated_argument_a, arg_a);        \
     _PW_CHECK_CONVERT(type_decl, evaluated_argument_b, arg_b);        \
     if (!(evaluated_argument_a comparison_op evaluated_argument_b)) { \
-      PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(#arg_a,                 \
-                                              evaluated_argument_a,   \
-                                              #comparison_op,         \
-                                              #arg_b,                 \
-                                              evaluated_argument_b,   \
-                                              type_fmt,               \
-                                              "" __VA_ARGS__);        \
+      _PW_CHECK_BINARY_ARG_HANDLER(#arg_a,                            \
+                                   evaluated_argument_a,              \
+                                   #comparison_op,                    \
+                                   #arg_b,                            \
+                                   evaluated_argument_b,              \
+                                   type_fmt,                          \
+                                   "" __VA_ARGS__);                   \
     }                                                                 \
   } while (0)
 
+// All binary comparison CHECK macros are directed to this handler before
+// hitting the CHECK backend. This controls whether evaluated values are
+// captured.
+#if PW_ASSERT_CAPTURE_VALUES
+#define _PW_CHECK_BINARY_ARG_HANDLER(arg_a_str,              \
+                                     arg_a_val,              \
+                                     comparison_op_str,      \
+                                     arg_b_str,              \
+                                     arg_b_val,              \
+                                     type_fmt,               \
+                                     message,                \
+                                     ...)                    \
+  PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(arg_a_str,         \
+                                          arg_a_val,         \
+                                          comparison_op_str, \
+                                          arg_b_str,         \
+                                          arg_b_val,         \
+                                          type_fmt,          \
+                                          message,           \
+                                          __VA_ARGS__)
+#else
+#define _PW_CHECK_BINARY_ARG_HANDLER(arg_a_str,         \
+                                     arg_a_val,         \
+                                     comparison_op_str, \
+                                     arg_b_str,         \
+                                     arg_b_val,         \
+                                     type_fmt,          \
+                                     message,           \
+                                     ...)               \
+  PW_HANDLE_ASSERT_FAILURE(                             \
+      arg_a_str " " comparison_op_str " " arg_b_str, message, __VA_ARGS__)
+#endif  // PW_ASSERT_CAPTURE_VALUES
+
 // Custom implementation for FLOAT_NEAR which is implemented through two
 // underlying checks which are not trivially replaced through the use of
 // FLOAT_EXACT_LE & FLOAT_EXACT_GE.
-#define _PW_CHECK_FLOAT_NEAR(argument_a, argument_b, abs_tolerance, ...)      \
-  do {                                                                        \
-    PW_CHECK_FLOAT_EXACT_GE(abs_tolerance, 0.0f);                             \
-    float evaluated_argument_a = (float)(argument_a);                         \
-    float evaluated_argument_b_min = (float)(argument_b)-abs_tolerance;       \
-    float evaluated_argument_b_max = (float)(argument_b) + abs_tolerance;     \
-    if (!(evaluated_argument_a >= evaluated_argument_b_min)) {                \
-      PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(#argument_a,                    \
-                                              evaluated_argument_a,           \
-                                              ">=",                           \
-                                              #argument_b " - abs_tolerance", \
-                                              evaluated_argument_b_min,       \
-                                              "%f",                           \
-                                              "" __VA_ARGS__);                \
-    } else if (!(evaluated_argument_a <= evaluated_argument_b_max)) {         \
-      PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(#argument_a,                    \
-                                              evaluated_argument_a,           \
-                                              "<=",                           \
-                                              #argument_b " + abs_tolerance", \
-                                              evaluated_argument_b_max,       \
-                                              "%f",                           \
-                                              "" __VA_ARGS__);                \
-    }                                                                         \
+#define _PW_CHECK_FLOAT_NEAR(argument_a, argument_b, abs_tolerance, ...)  \
+  do {                                                                    \
+    PW_CHECK_FLOAT_EXACT_GE(abs_tolerance, 0.0f);                         \
+    float evaluated_argument_a = (float)(argument_a);                     \
+    float evaluated_argument_b_min = (float)(argument_b)-abs_tolerance;   \
+    float evaluated_argument_b_max = (float)(argument_b) + abs_tolerance; \
+    if (!(evaluated_argument_a >= evaluated_argument_b_min)) {            \
+      _PW_CHECK_BINARY_ARG_HANDLER(#argument_a,                           \
+                                   evaluated_argument_a,                  \
+                                   ">=",                                  \
+                                   #argument_b " - abs_tolerance",        \
+                                   evaluated_argument_b_min,              \
+                                   "%f",                                  \
+                                   "" __VA_ARGS__);                       \
+    } else if (!(evaluated_argument_a <= evaluated_argument_b_max)) {     \
+      _PW_CHECK_BINARY_ARG_HANDLER(#argument_a,                           \
+                                   evaluated_argument_a,                  \
+                                   "<=",                                  \
+                                   #argument_b " + abs_tolerance",        \
+                                   evaluated_argument_b_max,              \
+                                   "%f",                                  \
+                                   "" __VA_ARGS__);                       \
+    }                                                                     \
   } while (0)