pw_log_null: pw_log backend that does nothing
pw_log_null implements pw_log backend using an empty inline function.
This ensures that arguments are checked and evaluated consistently with
a functional pw_log backend.
Change-Id: I65761933c50bba228e2154d2bc4f9636bb069b90
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/17280
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index dae1f18..2f52926 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -188,6 +188,7 @@
"$dir_pw_hdlc_lite:tests",
"$dir_pw_hex_dump:tests",
"$dir_pw_log:tests",
+ "$dir_pw_log_null:tests",
"$dir_pw_log_tokenized:tests",
"$dir_pw_malloc_freelist:tests",
"$dir_pw_metric:tests",
diff --git a/docs/BUILD.gn b/docs/BUILD.gn
index 1296b3f..0d5bdbb 100644
--- a/docs/BUILD.gn
+++ b/docs/BUILD.gn
@@ -85,6 +85,7 @@
"$dir_pw_kvs:docs",
"$dir_pw_log:docs",
"$dir_pw_log_basic:docs",
+ "$dir_pw_log_null:docs",
"$dir_pw_log_tokenized:docs",
"$dir_pw_metric:docs",
"$dir_pw_minimal_cpp_stdlib:docs",
diff --git a/modules.gni b/modules.gni
index 7894054..0ca3cce 100644
--- a/modules.gni
+++ b/modules.gni
@@ -41,6 +41,7 @@
dir_pw_kvs = get_path_info("pw_kvs", "abspath")
dir_pw_log = get_path_info("pw_log", "abspath")
dir_pw_log_basic = get_path_info("pw_log_basic", "abspath")
+ dir_pw_log_null = get_path_info("pw_log_null", "abspath")
dir_pw_log_tokenized = get_path_info("pw_log_tokenized", "abspath")
dir_pw_malloc = get_path_info("pw_malloc", "abspath")
dir_pw_malloc_freelist = get_path_info("pw_malloc_freelist", "abspath")
diff --git a/pw_log_null/BUILD b/pw_log_null/BUILD
new file mode 100644
index 0000000..f87a328
--- /dev/null
+++ b/pw_log_null/BUILD
@@ -0,0 +1,59 @@
+# Copyright 2020 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+load(
+ "//pw_build:pigweed.bzl",
+ "pw_cc_library",
+ "pw_cc_test",
+)
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"]) # Apache License 2.0
+
+pw_cc_library(
+ name = "headers",
+ hdrs = [
+ "public/pw_log_null/log_null.h",
+ "public_overrides/pw_log_backend/log_backend.h",
+ ],
+ includes = [
+ "public",
+ "public_overrides",
+ ],
+ deps = [
+ "//pw_preprocessor",
+ ],
+)
+
+pw_cc_library(
+ name = "pw_log_null",
+ srcs = [
+ "log_null.cc",
+ ],
+ deps = [
+ "//pw_log:facade",
+ "//pw_log_null:headers",
+ "//pw_string",
+ "//pw_sys_io",
+ ],
+)
+
+pw_cc_library(
+ name = "test",
+ srcs = [
+ "test.cc",
+ "test_c.c",
+ ],
+)
diff --git a/pw_log_null/BUILD.gn b/pw_log_null/BUILD.gn
new file mode 100644
index 0000000..e480d0e
--- /dev/null
+++ b/pw_log_null/BUILD.gn
@@ -0,0 +1,49 @@
+# Copyright 2020 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+# gn-format disable
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_docgen/docs.gni")
+import("$dir_pw_unit_test/test.gni")
+config("config") {
+ include_dirs = [
+ "public",
+ "public_overrides",
+ ]
+ visibility = [ ":*" ]
+}
+
+source_set("pw_log_null") {
+ public_configs = [ ":config" ]
+ public = [ "public_overrides/pw_log_backend/log_backend.h" ]
+ sources = [ "public/pw_log_null/log_null.h" ]
+ friend = [ ":test" ]
+}
+
+pw_doc_group("docs") {
+ sources = [ "docs.rst" ]
+}
+
+pw_test_group("tests") {
+ tests = [ ":test" ]
+}
+
+pw_test("test") {
+ sources = [
+ "test.cc",
+ "test_c.c",
+ ]
+ deps = [ ":pw_log_null" ]
+}
diff --git a/pw_log_null/CMakeLists.txt b/pw_log_null/CMakeLists.txt
new file mode 100644
index 0000000..0d86701
--- /dev/null
+++ b/pw_log_null/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright 2020 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+pw_auto_add_simple_module(pw_log_null
+ IMPLEMENTS_FACADE
+ pw_log
+ PUBLIC_DEPS
+ pw_preprocessor
+)
+
+target_include_directories(pw_log_null PUBLIC public_overrides)
diff --git a/pw_log_null/docs.rst b/pw_log_null/docs.rst
new file mode 100644
index 0000000..6b80809
--- /dev/null
+++ b/pw_log_null/docs.rst
@@ -0,0 +1,23 @@
+.. _chapter-pw-log-null:
+
+.. default-domain:: cpp
+
+.. highlight:: sh
+
+-----------
+pw_log_null
+-----------
+``pw_log_null`` is a ``pw_log backend`` that ignores all ``pw_log`` statements.
+The backend implements ``PW_LOG`` with an empty inline function. Using an empty
+function ensures that the arguments are evaluated and their types are correct.
+Since the function is inline in the header, the compiler will optimize out the
+function call.
+
+This backend can be used to completely disable ``pw_log``, which may be helpful
+in certain development situations (e.g. to avoid circular dependencies).
+
+.. tip::
+ If you are concerned about the resource demands of logging, try tokenizing
+ logs with :ref:`chapter-pw-tokenizer` and :ref:`chapter-pw-log-tokenized`
+ instead of disabling logs completely. Tokenized logs provide exactly same
+ information as plain text logs but use dramatically less resources.
diff --git a/pw_log_null/public/pw_log_null/log_null.h b/pw_log_null/public/pw_log_null/log_null.h
new file mode 100644
index 0000000..0496f1b
--- /dev/null
+++ b/pw_log_null/public/pw_log_null/log_null.h
@@ -0,0 +1,56 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+#include "pw_preprocessor/compiler.h"
+#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/util.h"
+
+PW_EXTERN_C_START
+
+// Empty function for compiling out log statements. Since the function is empty
+// and inline, it should be completely compiled out. This function accomplishes
+// following:
+//
+// - Uses the arguments to PW_LOG, which avoids "unused variable" warnings.
+// - Executes expressions passed to PW_LOG, so that the behavior is consistent
+// between this null backend and a backend that actually logs.
+// - Checks the printf-style format string arguments to PW_LOG.
+//
+// For compatibility with C and the printf compiler attribute, the declaration
+// and definition must be separate and both marked inline.
+static inline void pw_log_Ignored(int level,
+ unsigned int flags,
+ const char* module_name,
+ const char* message,
+ ...) PW_PRINTF_FORMAT(4, 5);
+
+static inline void pw_log_Ignored(int level,
+ unsigned int flags,
+ const char* module_name,
+ const char* message,
+ ...) {
+ PW_UNUSED(level);
+ PW_UNUSED(flags);
+ PW_UNUSED(module_name);
+ PW_UNUSED(message);
+}
+
+PW_EXTERN_C_END
+
+#define PW_LOG(level, flags, message, ...) \
+ pw_log_Ignored((level), \
+ (flags), \
+ PW_LOG_MODULE_NAME, \
+ message PW_COMMA_ARGS(__VA_ARGS__))
diff --git a/pw_log_null/public_overrides/pw_log_backend/log_backend.h b/pw_log_null/public_overrides/pw_log_backend/log_backend.h
new file mode 100644
index 0000000..3822a51
--- /dev/null
+++ b/pw_log_null/public_overrides/pw_log_backend/log_backend.h
@@ -0,0 +1,16 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+#include "pw_log_null/log_null.h"
diff --git a/pw_log_null/test.cc b/pw_log_null/test.cc
new file mode 100644
index 0000000..6c656be
--- /dev/null
+++ b/pw_log_null/test.cc
@@ -0,0 +1,49 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include "gtest/gtest.h"
+#include "pw_log_null/log_null.h"
+
+#define PW_LOG_MODULE_NAME "this test!"
+
+extern "C" bool CTest();
+
+namespace {
+
+TEST(LogNull, NoArguments) {
+ PW_LOG(1, 2, "3");
+ PW_LOG(1, 2, "whoa");
+}
+
+TEST(LogNull, WithArguments) {
+ PW_LOG(1, 2, "%s", "hello");
+ PW_LOG(1, 2, "%d + %s == %p", 1, "two", nullptr);
+}
+
+TEST(LogNull, ExpressionsAreEvaluated) {
+ static int global;
+
+ global = 0;
+ bool local = true;
+
+ PW_LOG(1, 2, "You are number%s %d!", (local = false) ? "" : " not", []() {
+ global = 1;
+ return global;
+ }());
+
+ EXPECT_EQ(1, global);
+ EXPECT_FALSE(local);
+}
+
+} // namespace
diff --git a/pw_log_null/test_c.c b/pw_log_null/test_c.c
new file mode 100644
index 0000000..d68e9fd
--- /dev/null
+++ b/pw_log_null/test_c.c
@@ -0,0 +1,44 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "pw_log_null/log_null.h"
+
+#define PW_LOG_MODULE_NAME "c test!"
+
+static int global;
+
+static int IncrementGlobal(void) { return ++global; }
+
+bool CTest() {
+ PW_LOG(1, 2, "3");
+ PW_LOG(1, 2, "whoa");
+ PW_LOG(1, 2, "%s", "hello");
+ PW_LOG(1, 2, "%d + %s == %p", 1, "two", NULL);
+
+ static int global;
+
+ global = 0;
+ bool local = true;
+
+ PW_LOG(1,
+ 2,
+ "You are number%s %d!",
+ (local = false) ? "" : " not",
+ IncrementGlobal());
+
+ return global == 1 && !local;
+}