Browse Source

FindDoxygen: Add DOXYGEN_VERBATIM_VARS for quote prevention

Each CMake variable listed in DOXYGEN_VERBATIM_VARS will not have any
automatic quoting applied to it when written to the Doxyfile.
Craig Scott 8 years ago
parent
commit
1e6d1dd358

+ 8 - 0
Help/release/dev/doxygen-verbatim-vars.rst

@@ -0,0 +1,8 @@
+FindDoxygen
+-----------
+
+* The :command:`doxygen_add_docs` function of the :module:`FindDoxygen` module
+  now supports a new ``DOXYGEN_VERBATIM_VARS`` list variable. Any
+  ``DOXYGEN_...`` variable contained in that list will bypass the automatic
+  quoting logic, leaving its contents untouched when transferring them to the
+  output Doxyfile.

+ 51 - 8
Modules/FindDoxygen.cmake

@@ -244,7 +244,7 @@ required form if set.
   TAGFILES
   TCL_SUBST
 
-The following single value Doxygen options would be quoted automatically
+The following single value Doxygen options will be quoted automatically
 if they contain at least one space:
 
 ::
@@ -292,6 +292,36 @@ if they contain at least one space:
   WARN_LOGFILE
   XML_OUTPUT
 
+There are situations where it may be undesirable for a particular config option
+to be automatically quoted by ``doxygen_add_docs()``, such as ``ALIASES`` which
+may need to include its own embedded quoting.  The ``DOXYGEN_VERBATIM_VARS``
+variable can be used to specify a list of Doxygen variables (including the
+leading ``DOXYGEN_`` prefix) which should not be quoted.  The project is then
+responsible for ensuring that those variables' values make sense when placed
+directly in the Doxygen input file.  In the case of list variables, list items
+are still separated by spaces, it is only the automatic quoting that is
+skipped.  For example, the following allows ``doxygen_add_docs()`` to apply
+quoting to ``DOXYGEN_PROJECT_BRIEF``, but not each item in the
+``DOXYGEN_ALIASES`` list (:ref:`bracket syntax <Bracket Argument>` can also
+be used to make working with embedded quotes easier):
+
+.. code-block:: cmake
+
+  set(DOXYGEN_PROJECT_BRIEF "String with spaces")
+  set(DOXYGEN_ALIASES
+      [[somealias="@some_command param"]]
+      "anotherAlias=@foobar"
+  )
+  set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES)
+
+The resultant ``Doxyfile`` will contain the following lines:
+
+.. code-block:: text
+
+  PROJECT_BRIEF = "String with spaces"
+  ALIASES       = somealias="@some_command param" anotherAlias=@foobar
+
+
 Deprecated Result Variables
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -331,7 +361,7 @@ Deprecated Hint Variables
 
 .. variable:: DOXYGEN_SKIP_DOT
 
-  This variable has no any effect for component form of ``find_package``.
+  This variable has no effect for the component form of ``find_package``.
   In backward compatibility mode (i.e. without components list) it prevents
   the finder module from searching for Graphviz's ``dot`` utility.
 
@@ -716,12 +746,15 @@ endif()
 
 function(doxygen_quote_value VARIABLE)
     # Quote a value of the given variable if:
-    # - variable parameter was really given
-    # - a variable it points is defined
-    # - a value doesn't quoted already
-    # - and it has spaces
+    # - VARIABLE parameter was really given
+    # - the variable it names is defined and is not present in the list
+    #   specified by DOXYGEN_VERBATIM_VARS (if set)
+    # - the value of the named variable isn't already quoted
+    # - the value has spaces
     if(VARIABLE AND DEFINED ${VARIABLE} AND
-       NOT ${VARIABLE} MATCHES "^\".* .*\"$" AND ${VARIABLE} MATCHES " ")
+       NOT ${VARIABLE} MATCHES "^\".* .*\"$" AND ${VARIABLE} MATCHES " " AND
+       NOT (DEFINED DOXYGEN_VERBATIM_VARS AND
+            "${VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS))
         set(${VARIABLE} "\"${${VARIABLE}}\"" PARENT_SCOPE)
     endif()
 endfunction()
@@ -730,8 +763,18 @@ function(doxygen_list_to_quoted_strings LIST_VARIABLE)
     if(LIST_VARIABLE AND DEFINED ${LIST_VARIABLE})
         unset(_inputs)
         unset(_sep)
+        unset(_verbatim)
+        # Have to test if list items should be treated as verbatim here
+        # because we lose the variable name when we pass just one list item
+        # to doxygen_quote_value() below
+        if(DEFINED DOXYGEN_VERBATIM_VARS AND
+           "${LIST_VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS)
+            set(_verbatim True)
+        endif()
         foreach(_in IN LISTS ${LIST_VARIABLE})
-            doxygen_quote_value(_in)
+            if(NOT _verbatim)
+                doxygen_quote_value(_in)
+            endif()
             string(APPEND _inputs "${_sep}${_in}")
             set(_sep " ")
         endforeach()

+ 10 - 0
Tests/FindDoxygen/CMakeLists.txt

@@ -8,6 +8,16 @@ add_test(NAME FindDoxygen.SimpleTest COMMAND
   --build-options ${build_options}
 )
 
+add_test(NAME FindDoxygen.QuotingTest COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindDoxygen/QuotingTest"
+  "${CMake_BINARY_DIR}/Tests/FindDoxygen/QuotingTest"
+  --build-target allDocTargets
+  ${build_generator_args}
+  --build-options ${build_options}
+)
+
 if(CMake_TEST_FindDoxygen_Dot)
   add_test(NAME FindDoxygen.DotComponentTest COMMAND
     ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>

+ 34 - 0
Tests/FindDoxygen/QuotingTest/CMakeLists.txt

@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.10)
+project(TestFindDoxygen VERSION 1.0 LANGUAGES NONE)
+
+find_package(Doxygen REQUIRED)
+
+set(DOXYGEN_PROJECT_BRIEF "String with spaces")
+set(DOXYGEN_ALIASES
+  [[somealias="@some_command param"]]
+  "anotherAlias=@foobar"
+)
+
+set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES)
+
+doxygen_add_docs(docsQuoting)
+if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsQuoting")
+  message(FATAL_ERROR "Missing generated file: Doxyfile.docsQuoting")
+endif()
+
+file(STRINGS "${PROJECT_BINARY_DIR}/Doxyfile.docsQuoting" matches
+  REGEX [[^PROJECT_BRIEF *= *"String with spaces"]]
+)
+if(NOT matches)
+  message(FATAL_ERROR "PROJECT_BRIEF does not match expected contents")
+endif()
+
+file(STRINGS "${PROJECT_BINARY_DIR}/Doxyfile.docsQuoting" matches
+  REGEX [[^ALIASES *= *somealias="@some_command param" anotherAlias=@foobar]]
+)
+if(NOT matches)
+  message(FATAL_ERROR "ALIASES does not match expected contents")
+endif()
+
+add_custom_target(allDocTargets)
+add_dependencies(allDocTargets docsQuoting)