Browse Source

cmDebugTools: add header

This provides a utility macro which prints out:

- location of the call;
- the expression being evaluated; and
- the value of the expression.

Evaluates to the value of the expression.

Inspired by Rust's `dbg!` macro.

See: https://doc.rust-lang.org/stable/std/macro.dbg.html
Ben Boeckel 2 years ago
parent
commit
b0612796b1
3 changed files with 57 additions and 0 deletions
  1. 23 0
      Source/cmDebugTools.h
  2. 1 0
      Tests/CMakeLib/CMakeLists.txt
  3. 33 0
      Tests/CMakeLib/testDebug.cxx

+ 23 - 0
Source/cmDebugTools.h

@@ -0,0 +1,23 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <iostream>
+
+#define CM_DBG(expr) cm::dbg_impl(__FILE__, __LINE__, #expr, expr)
+
+namespace cm {
+
+namespace {
+
+template <typename T>
+T dbg_impl(const char* fname, int line, const char* expr, T value)
+{
+  std::cerr << fname << ':' << line << ": " << expr << " = " << value
+            << std::endl;
+  return value;
+}
+
+} // namespace
+
+} // namespace cm

+ 1 - 0
Tests/CMakeLib/CMakeLists.txt

@@ -11,6 +11,7 @@ set(CMakeLib_TESTS
   testCTestResourceAllocator.cxx
   testCTestResourceSpec.cxx
   testCTestResourceGroups.cxx
+  testDebug.cxx
   testGccDepfileReader.cxx
   testGeneratedFileStream.cxx
   testJSONHelpers.cxx

+ 33 - 0
Tests/CMakeLib/testDebug.cxx

@@ -0,0 +1,33 @@
+#include <iostream>
+#include <string>
+
+#include "cmDebugTools.h"
+
+#define check(expr, value)                                                    \
+  do {                                                                        \
+    if (expr != value) {                                                      \
+      std::cerr << "Failed to return " #value " for " #expr << std::endl;     \
+      retval = 1;                                                             \
+    }                                                                         \
+  } while (false)
+
+int testDebug(int argc, char** const /*argv*/)
+{
+  if (argc != 1) {
+    std::cout << "Invalid arguments.\n";
+    return -1;
+  }
+
+  int retval = 0;
+  check(CM_DBG(true), true);
+  check(CM_DBG(4), 4);
+  check(CM_DBG(1.), 1.);
+  check(CM_DBG('c'), 'c');
+  check(CM_DBG("literal string"), std::string("literal string"));
+
+  std::string str = "std string";
+  check(CM_DBG(str), "std string");
+  check(CM_DBG(str.empty()), false);
+
+  return retval;
+}