# Copyright (C) 2013-2016 Daniel Scharrer # # This software is provided 'as-is', without any express or implied # warranty. In no event will the author(s) be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. # Filter a list with conditional ites # # Supported syntax: # # item # # item if CONDITION_VARIABLE # # CONDITION_VARIABLE { # item1 # item2 # } # # Conditions cannot be nested. # # The list specified by LIST_NAM Ewill be modifed in place. # An optional second parameter can be given to specify the name of a list that # should receive all items, even those whose conditions evaluated to false, # but not syntactic elements such as 'if', '{', '}' and condition variables. # function(filter_list LIST_NAME) set(TOKEN_IF "if") set(TOKEN_GROUP_BEGIN "{") set(TOKEN_GROUP_END "}") set(filtered) set(all) # the item from the previous iteration set(last_item "") # current syntax state: # 0 - start # 1 - after 'if', expected condition variable # 2 - inside block (true) # 3 - inside block (false) set(mode 0) foreach(item IN LISTS ${LIST_NAME}) if(mode EQUAL 1) # Handle condition variables set(condition ${${item}}) if(condition) list(APPEND filtered ${last_item}) endif() set(mode 0) set(last_item "") elseif(item STREQUAL TOKEN_IF) if(NOT mode EQUAL 0) message(FATAL_ERROR "bad filter_list syntax: IF inside { } block is forbidden") endif() # Handle condition start if(last_item STREQUAL "") message(FATAL_ERROR "bad filter_list syntax: IF without preceding item") endif() set(mode 1) elseif(item STREQUAL TOKEN_GROUP_BEGIN) if(NOT mode EQUAL 0) message(FATAL_ERROR "bad filter_list syntax: cannot nest { } blocks") endif() if(last_item STREQUAL "") message(FATAL_ERROR "bad filter_list syntax: { without preceding item") endif() set(condition ${${last_item}}) if(condition) set(mode 2) else() set(mode 3) endif() set(last_item "") else() # Handle unconditional items if(NOT last_item STREQUAL "" AND NOT mode EQUAL 3) list(APPEND filtered ${last_item}) endif() if(item STREQUAL TOKEN_GROUP_END) if(mode EQUAL 0) message(FATAL_ERROR "bad filter_list syntax: } without open block") endif() set(mode 0) set(last_item) else() list(APPEND all ${item}) set(last_item ${item}) endif() endif() endforeach() if(mode EQUAL 1) message(FATAL_ERROR "bad filter_list syntax: unexpected end, expected condition") elseif(mode EQUAL 2 OR mode EQUAL 3) message(FATAL_ERROR "bad filter_list syntax: unexpected end, expected }") endif() if(last_item) list(APPEND filtered ${last_item}) endif() list(SORT filtered) list(REMOVE_DUPLICATES filtered) set(${LIST_NAME} ${filtered} PARENT_SCOPE) if(ARGC GREATER 1) list(SORT all) list(REMOVE_DUPLICATES all) set(${ARGV1} ${all} PARENT_SCOPE) endif() endfunction()