# Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Common utility functions. # # NOTE: All the functions here should be purely functional, i.e. avoid # using global variables or depend on the file system / environment # variables. This makes testing easier. # ----------------------------------------------------------------------------- # Macro : empty # Returns : an empty macro # Usage : $(empty) # ----------------------------------------------------------------------------- empty := # ----------------------------------------------------------------------------- # Macro : space # Returns : a single space # Usage : $(space) # ----------------------------------------------------------------------------- space := $(empty) $(empty) space4 := $(space)$(space)$(space)$(space) # ----------------------------------------------------------------------------- # Function : remove-duplicates # Arguments: a list # Returns : the list with duplicate items removed, order is preserved. # Usage : $(call remove-duplicates, <LIST>) # Note : This is equivalent to the 'uniq' function provided by GMSL, # however this implementation is non-recursive and *much* # faster. It will also not explode the stack with a lot of # items like 'uniq' does. # ----------------------------------------------------------------------------- remove-duplicates = $(strip \ $(eval __uniq_ret :=) \ $(foreach __uniq_item,$1,\ $(if $(findstring $(__uniq_item),$(__uniq_ret)),,\ $(eval __uniq_ret += $(__uniq_item))\ )\ )\ $(__uniq_ret)) -test-remove-duplicates = \ $(call test-expect,,$(call remove-duplicates))\ $(call test-expect,foo bar,$(call remove-duplicates,foo bar))\ $(call test-expect,foo bar,$(call remove-duplicates,foo bar foo bar))\ $(call test-expect,foo bar,$(call remove-duplicates,foo foo bar bar bar)) # ----------------------------------------------------------------------------- # Function : clear-vars # Arguments: 1: list of variable names # 2: file where the variable should be defined # Returns : None # Usage : $(call clear-vars, VAR1 VAR2 VAR3...) # Rationale: Clears/undefines all variables in argument list # ----------------------------------------------------------------------------- clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty))) # ----------------------------------------------------------------------------- # Function : filter-by # Arguments: 1: list # 2: predicate function, will be called as $(call $2,<name>) # and it this returns a non-empty value, then <name> # will be appended to the result. # Returns : elements of $1 that satisfy the predicate function $2 # ----------------------------------------------------------------------------- filter-by = $(strip \ $(foreach __filter_by_n,$1,\ $(if $(call $2,$(__filter_by_n)),$(__filter_by_n)))) -test-filter-by = \ $(eval -local-func = $$(call seq,foo,$$1))\ $(call test-expect,,$(call filter-by,,-local-func))\ $(call test-expect,foo,$(call filter-by,foo,-local-func))\ $(call test-expect,foo,$(call filter-by,foo bar,-local-func))\ $(call test-expect,foo foo,$(call filter-by,aaa foo bar foo,-local-func))\ $(eval -local-func = $$(call sne,foo,$$1))\ $(call test-expect,,$(call filter-by,,-local-func))\ $(call test-expect,,$(call filter-by,foo,-local-func))\ $(call test-expect,bar,$(call filter-by,foo bar,-local-func))\ $(call test-expect,aaa bar,$(call filter-by,aaa foo bar,-local-func)) # ----------------------------------------------------------------------------- # Function : filter-out-by # Arguments: 1: list # 2: predicate function, will be called as $(call $2,<name>) # and it this returns an empty value, then <name> # will be appended to the result. # Returns : elements of $1 that do not satisfy the predicate function $2 # ----------------------------------------------------------------------------- filter-out-by = $(strip \ $(foreach __filter_out_by_n,$1,\ $(if $(call $2,$(__filter_out_by_n)),,$(__filter_out_by_n)))) -test-filter-out-by = \ $(eval -local-func = $$(call seq,foo,$$1))\ $(call test-expect,,$(call filter-out-by,,-local-func))\ $(call test-expect,,$(call filter-out-by,foo,-local-func))\ $(call test-expect,bar,$(call filter-out-by,foo bar,-local-func))\ $(call test-expect,aaa bar,$(call filter-out-by,aaa foo bar foo,-local-func))\ $(eval -local-func = $$(call sne,foo,$$1))\ $(call test-expect,,$(call filter-out-by,,-local-func))\ $(call test-expect,foo,$(call filter-out-by,foo,-local-func))\ $(call test-expect,foo,$(call filter-out-by,foo bar,-local-func))\ $(call test-expect,foo foo,$(call filter-out-by,aaa foo bar foo,-local-func)) # ----------------------------------------------------------------------------- # Function : find-first # Arguments: 1: list # 2: predicate function, will be called as $(call $2,<name>). # Returns : the first item of $1 that satisfies the predicate. # ----------------------------------------------------------------------------- find-first = $(firstword $(call filter-by,$1,$2)) -testfind-first.empty = \ $(eval -local-pred = $$(call seq,foo,$$1))\ $(call test-expect,,$(call find-first,,-local-pred))\ $(call test-expect,,$(call find-first,bar,-local-pred)) -testfind-first.simple = \ $(eval -local-pred = $$(call seq,foo,$$1))\ $(call test-expect,foo,$(call find-first,foo,-local-pred))\ $(call test-expect,foo,$(call find-first,aaa foo bar,-local-pred))\ $(call test-expect,foo,$(call find-first,aaa foo foo bar,-local-pred)) # ----------------------------------------------------------------------------- # Function : parent-dir # Arguments: 1: path # Returns : Parent dir or path of $1, with final separator removed. # ----------------------------------------------------------------------------- parent-dir = $(patsubst %/,%,$(dir $(1:%/=%))) -test-parent-dir = \ $(call test-expect,,$(call parent-dir))\ $(call test-expect,.,$(call parent-dir,foo))\ $(call test-expect,foo,$(call parent-dir,foo/bar))\ $(call test-expect,foo,$(call parent-dir,foo/bar/)) # ----------------------------------------------------------------------------- # Strip any 'lib' prefix in front of a given string. # # Function : strip-lib-prefix # Arguments: 1: module name # Returns : module name, without any 'lib' prefix if any # Usage : $(call strip-lib-prefix,$(LOCAL_MODULE)) # ----------------------------------------------------------------------------- strip-lib-prefix = $(1:lib%=%) -test-strip-lib-prefix = \ $(call test-expect,,$(call strip-lib-prefix,))\ $(call test-expect,foo,$(call strip-lib-prefix,foo))\ $(call test-expect,foo,$(call strip-lib-prefix,libfoo))\ $(call test-expect,nolibfoo,$(call strip-lib-prefix,nolibfoo))\ $(call test-expect,foolib,$(call strip-lib-prefix,foolib))\ $(call test-expect,foo bar,$(call strip-lib-prefix,libfoo libbar))