CMake: Fix config condition evaluator
Use recursive descent to handle parentheses in config condition expressions. This fixes cases like 'NOT (A AND B)'. Fixes: QTBUG-117053 Change-Id: Iab1b6173abe00d763808bb972a9a5443ffa0938d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: Amir Masoud Abdol <amir.abdol@qt.io>
This commit is contained in:
parent
49ff83fcef
commit
814de4c2ce
@ -81,35 +81,23 @@ function(qt_evaluate_to_boolean expressionVar)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt_evaluate_config_expression resultVar)
|
||||
function(qt_internal_evaluate_config_expression resultVar outIdx startIdx)
|
||||
set(result "")
|
||||
set(nestingLevel 0)
|
||||
set(expression "${ARGN}")
|
||||
list(LENGTH expression length)
|
||||
|
||||
set(memberIdx -1)
|
||||
math(EXPR memberIdx "${startIdx} - 1")
|
||||
math(EXPR length "${length}-1")
|
||||
while(memberIdx LESS ${length})
|
||||
math(EXPR memberIdx "${memberIdx} + 1")
|
||||
list(GET expression ${memberIdx} member)
|
||||
|
||||
if("${member}" STREQUAL "(")
|
||||
if(${nestingLevel} GREATER 0)
|
||||
list(APPEND result ${member})
|
||||
endif()
|
||||
math(EXPR nestingLevel "${nestingLevel} + 1")
|
||||
math(EXPR memberIdx "${memberIdx} + 1")
|
||||
qt_internal_evaluate_config_expression(sub_result memberIdx ${memberIdx} ${expression})
|
||||
list(APPEND result ${sub_result})
|
||||
elseif("${member}" STREQUAL ")")
|
||||
math(EXPR nestingLevel "${nestingLevel} - 1")
|
||||
if(nestingLevel LESS 0)
|
||||
break()
|
||||
endif()
|
||||
if(${nestingLevel} EQUAL 0)
|
||||
qt_evaluate_config_expression(result ${result})
|
||||
else()
|
||||
list(APPEND result ${member})
|
||||
endif()
|
||||
elseif(${nestingLevel} GREATER 0)
|
||||
list(APPEND result ${member})
|
||||
break()
|
||||
elseif("${member}" STREQUAL "NOT")
|
||||
list(APPEND result ${member})
|
||||
elseif("${member}" STREQUAL "AND")
|
||||
@ -166,9 +154,34 @@ function(qt_evaluate_config_expression resultVar)
|
||||
qt_evaluate_to_boolean(result)
|
||||
endif()
|
||||
|
||||
# When in recursion, we must skip to the next closing parenthesis on nesting level 0. The outIdx
|
||||
# must point to the matching closing parenthesis, and that's not the case if we're early exiting
|
||||
# in AND/OR.
|
||||
if(startIdx GREATER 0)
|
||||
set(nestingLevel 1)
|
||||
while(TRUE)
|
||||
list(GET expression ${memberIdx} member)
|
||||
if("${member}" STREQUAL ")")
|
||||
math(EXPR nestingLevel "${nestingLevel} - 1")
|
||||
if(nestingLevel EQUAL 0)
|
||||
break()
|
||||
endif()
|
||||
elseif("${member}" STREQUAL "(")
|
||||
math(EXPR nestingLevel "${nestingLevel} + 1")
|
||||
endif()
|
||||
math(EXPR memberIdx "${memberIdx} + 1")
|
||||
endwhile()
|
||||
endif()
|
||||
|
||||
set(${outIdx} ${memberIdx} PARENT_SCOPE)
|
||||
set(${resultVar} ${result} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_evaluate_config_expression resultVar)
|
||||
qt_internal_evaluate_config_expression(result unused 0 ${ARGN})
|
||||
set("${resultVar}" "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_get_feature_condition_keywords out_var)
|
||||
set(keywords "EQUAL" "LESS" "LESS_EQUAL" "GREATER" "GREATER_EQUAL" "STREQUAL" "STRLESS"
|
||||
"STRLESS_EQUAL" "STRGREATER" "STRGREATER_EQUAL" "VERSION_EQUAL" "VERSION_LESS"
|
||||
|
@ -88,9 +88,9 @@ assert_F(A AND B)
|
||||
assert_T(A AND (B OR C))
|
||||
assert_T((A AND B) OR C)
|
||||
assert_T((A AND B) OR (NOT B AND C))
|
||||
expect_failure_F(NOT (B OR C)) # QTBUG-117053
|
||||
expect_failure_T(NOT (A AND B)) # QTBUG-117053
|
||||
expect_failure_F(NOT (B OR C)) # QTBUG-117053
|
||||
assert_F(NOT (B OR C))
|
||||
assert_T(NOT (A AND B))
|
||||
assert_F(NOT (B OR C))
|
||||
|
||||
# target check
|
||||
set(lib1_cpp "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp")
|
||||
|
Loading…
Reference in New Issue
Block a user