Revision: 68968
          http://sourceforge.net/p/brlcad/code/68968
Author:   brlcad
Date:     2016-10-03 07:26:43 +0000 (Mon, 03 Oct 2016)
Log Message:
-----------
after MUCH thrashing, here is a rewrite the add_test() wrapper that fixes a 
problem with the previous version.  previous was not actually handling empty 
strings, which are used by a significant number of our tests.  it was silently 
not passing them to the test program.  turns out that cmake really does not 
like consistently dealing with empty string/list elements and loses it once 
we're in the wrapper. once it's processed into list form (e.g., ARGV/ARGN), it 
gets ignored by _add_test().  this may be due to cmake_parse_arguments() being 
used within _add_test() which also unexpectedly ignores empty list elements.  
reported behavior as bug to upstream.

after much trial and error (more error than trial), a workaround was finally 
found and is implemented here.  basically, we reconstruct an invocation of 
add_test() in the wrapper so empty strings are passed as such, not via a list.  
this is fugly and inane and would be fragile, but there are a couple 
protections included that greatly help future-proof the wrapper.  other 
comments should also help the next dev figure out what's going on.

Modified Paths:
--------------
    brlcad/trunk/CMakeLists.txt

Modified: brlcad/trunk/CMakeLists.txt
===================================================================
--- brlcad/trunk/CMakeLists.txt 2016-10-02 20:15:26 UTC (rev 68967)
+++ brlcad/trunk/CMakeLists.txt 2016-10-03 07:26:43 UTC (rev 68968)
@@ -535,20 +535,106 @@
 
   set_target_properties(unit PROPERTIES FOLDER "BRL-CAD Validation Testing")
 
-  function(add_test test_name test_prog)
-    _add_test(${test_name} ${test_prog} ${ARGN})
-    if (NOT "${test_name}" STREQUAL "NAME")
-      if (NOT "${test_name}" MATCHES ^regress- AND NOT "${test_prog}" MATCHES 
^regress- AND NOT "${test_name}" STREQUAL "benchmark")
-       add_dependencies(unit ${test_prog})
-       add_dependencies(check ${test_prog})
-      endif (NOT "${test_name}" MATCHES ^regress- AND NOT "${test_prog}" 
MATCHES ^regress- AND NOT "${test_name}" STREQUAL "benchmark")
-    else (NOT "${test_name}" STREQUAL "NAME")
-      if (NOT "${ARGV1}" MATCHES ^regress- AND NOT "${ARGV3}" MATCHES 
^regress- AND NOT "${ARGV1}" MATCHES "benchmark")
-       add_dependencies(unit ${ARGV3})
-       add_dependencies(check ${ARGV3})
-      endif (NOT "${ARGV1}" MATCHES ^regress- AND NOT "${ARGV3}" MATCHES 
^regress- AND NOT "${ARGV1}" MATCHES "benchmark")
-    endif (NOT "${test_name}" STREQUAL "NAME")
-  endfunction(add_test)
+  # we wrap the CMake add_test() function in order to automatically
+  # set up test dependencies for the 'unit' and 'check' test targets.
+  #
+  # this function extravagantly tries to work around a bug in CMake
+  # where we cannot pass an empty string through this wrapper to
+  # _add_test()/add_test().  passed as a list (e.g., via ARGN, ARGV,
+  # or manually composed), the empty string is skipped(!).  passed as
+  # a string, it is all treated as commnad name with no arguments.
+  #
+  # manual workaround used here involves invoking _add_test() with all
+  # args individually recreated/specified (i.e., not as a list) as
+  # this preserves empty strings.  this approach means we cannot
+  # generalize and only support a limited variety of empty string
+  # arguments, but we do test and halt if someone unknowingly tries.
+  function(add_test NAME test_name COMMAND test_prog)
+
+    # find any occurrences of empty strings
+    set(idx 0)
+    set(matches)
+    foreach (ARG IN LISTS ARGV)
+      if ("${ARG}" STREQUAL "")
+       list(APPEND matches ${idx})
+      endif ("${ARG}" STREQUAL "")
+      math(EXPR idx "${idx} + 1")
+    endforeach()
+
+    # make sure we don't exceed current support
+    list(LENGTH matches cnt)
+    if ("${cnt}" GREATER 1)
+      message(FATAL_ERROR "ERROR: encountered ${cnt} > 1 empty string being 
passed to add_test(${test_name}).  Expand support in the top-level 
CMakeLists.txt file (grep add_test) or pass fewer empty strings.")
+    endif ("${cnt}" GREATER 1)
+
+    # if there are empty strings, we need to manually recreate their calling
+    if ("${cnt}" GREATER 0)
+
+      list(GET matches 0 empty)
+      if ("${empty}" EQUAL 4)
+       foreach (i 1)
+         if (ARGN)
+           list(REMOVE_AT ARGN 0)
+         endif (ARGN)
+       endforeach ()
+       _add_test(NAME ${test_name} COMMAND ${test_prog} "" ${ARGN})
+      elseif ("${empty}" EQUAL 5)
+       foreach (i 1 2)
+         if (ARGN)
+           list(REMOVE_AT ARGN 0)
+         endif (ARGN)
+       endforeach ()
+       _add_test(NAME ${test_name} COMMAND ${test_prog} ${ARGV4} "" ${ARGN})
+      elseif ("${empty}" EQUAL 6)
+       foreach (i 1 2 3)
+         if (ARGN)
+           list(REMOVE_AT ARGN 0)
+         endif (ARGN)
+       endforeach ()
+       _add_test(NAME ${test_name} COMMAND ${test_prog} ${ARGV4} ${ARGV5} "" 
${ARGN})
+      elseif ("${empty}" EQUAL 7)
+       foreach (i 1 2 3 4)
+         if (ARGN)
+           list(REMOVE_AT ARGN 0)
+         endif (ARGN)
+       endforeach ()
+       _add_test(NAME ${test_name} COMMAND ${test_prog} ${ARGV4} ${ARGV5} 
${ARGV6} "" ${ARGN})
+      elseif ("${empty}" EQUAL 8)
+       foreach (i 1 2 3 4 5)
+         if (ARGN)
+           list(REMOVE_AT ARGN 0)
+         endif (ARGN)
+       endforeach ()
+       _add_test(NAME ${test_name} COMMAND ${test_prog} ${ARGV4} ${ARGV5} 
${ARGV6} ${ARGV7} "" ${ARGN})
+      elseif ("${empty}" EQUAL 9)
+       foreach (i 1 2 3 4 5 6)
+         if (ARGN)
+           list(REMOVE_AT ARGN 0)
+         endif (ARGN)
+       endforeach ()
+       _add_test(NAME ${test_name} COMMAND ${test_prog} ${ARGV4} ${ARGV5} 
${ARGV6} ${ARGV7} ${ARGV8} "" ${ARGN})
+
+       # ADD_EMPTY_HERE: insert support for addition argv positions
+       # as extra elseif tests here using the preceding pattern.  be
+       # sure to update the index in the following else clause fatal
+       # error message too.
+
+      else ("${empty}" EQUAL 4)
+       message(FATAL_ERROR "ERROR: encountered an empty string passed to 
add_test(${test_name}) as ARGV${empty} > ARGV9.  Expand support in the 
top-level CMakeLists.txt file (grep ADD_EMPTY_HERE).")
+      endif ("${empty}" EQUAL 4)
+       
+    else ("${cnt}" GREATER 0)
+      # no empty strings, no worries
+      _add_test(NAME ${test_name} COMMAND ${test_prog} ${ARGN})
+    endif ("${cnt}" GREATER 0)
+
+    # add test to unit and check targets
+    if (NOT "${test_name}" MATCHES ^regress- AND NOT "${test_prog}" MATCHES 
^regress- AND NOT "${test_name}" STREQUAL "benchmark" AND NOT "${test_name}" 
MATCHES ^NOTE:)
+      add_dependencies(unit ${test_prog})
+      add_dependencies(check ${test_prog})
+    endif (NOT "${test_name}" MATCHES ^regress- AND NOT "${test_prog}" MATCHES 
^regress- AND NOT "${test_name}" STREQUAL "benchmark" AND NOT "${test_name}" 
MATCHES ^NOTE:)
+
+  endfunction(add_test NAME test_name COMMAND test_prog)
 endif(NOT BRLCAD_IS_SUBBUILD)
 
 
@@ -3157,7 +3243,7 @@
   COMMAND false
   )
 set_target_properties(print-warning-message PROPERTIES FOLDER "Compilation 
Utilities")
-_add_test(NAME "NOTE:\\ some\\ 'test'\\ tests\\ are\\ expected\\ to\\ fail,\\ 
'regress'\\ must\\ pass" COMMAND ${CMAKE_COMMAND} --build . --target 
print-warning-message)
+add_test(NAME "NOTE:\\ some\\ 'test'\\ tests\\ are\\ expected\\ to\\ fail,\\ 
'regress'\\ must\\ pass" COMMAND ${CMAKE_COMMAND} --build . --target 
print-warning-message)
 
 # Local Variables:
 # tab-width: 8

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to