1 # Copyright (C) 2009 The Android Open Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # 15 16 # Common utility functions. 17 # 18 # NOTE: All the functions here should be purely functional, i.e. avoid 19 # using global variables or depend on the file system / environment 20 # variables. This makes testing easier. 21 22 # ----------------------------------------------------------------------------- 23 # Macro : empty 24 # Returns : an empty macro 25 # Usage : $(empty) 26 # ----------------------------------------------------------------------------- 27 empty := 28 29 # ----------------------------------------------------------------------------- 30 # Macro : space 31 # Returns : a single space 32 # Usage : $(space) 33 # ----------------------------------------------------------------------------- 34 space := $(empty) $(empty) 35 36 space4 := $(space)$(space)$(space)$(space) 37 38 # ----------------------------------------------------------------------------- 39 # Function : remove-duplicates 40 # Arguments: a list 41 # Returns : the list with duplicate items removed, order is preserved. 42 # Usage : $(call remove-duplicates, <LIST>) 43 # Note : This is equivalent to the 'uniq' function provided by GMSL, 44 # however this implementation is non-recursive and *much* 45 # faster. It will also not explode the stack with a lot of 46 # items like 'uniq' does. 47 # ----------------------------------------------------------------------------- 48 remove-duplicates = $(strip \ 49 $(eval __uniq_ret :=) \ 50 $(foreach __uniq_item,$1,\ 51 $(if $(findstring $(__uniq_item),$(__uniq_ret)),,\ 52 $(eval __uniq_ret += $(__uniq_item))\ 53 )\ 54 )\ 55 $(__uniq_ret)) 56 57 -test-remove-duplicates = \ 58 $(call test-expect,,$(call remove-duplicates))\ 59 $(call test-expect,foo bar,$(call remove-duplicates,foo bar))\ 60 $(call test-expect,foo bar,$(call remove-duplicates,foo bar foo bar))\ 61 $(call test-expect,foo bar,$(call remove-duplicates,foo foo bar bar bar)) 62 63 # ----------------------------------------------------------------------------- 64 # Function : clear-vars 65 # Arguments: 1: list of variable names 66 # 2: file where the variable should be defined 67 # Returns : None 68 # Usage : $(call clear-vars, VAR1 VAR2 VAR3...) 69 # Rationale: Clears/undefines all variables in argument list 70 # ----------------------------------------------------------------------------- 71 clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty))) 72 73 # ----------------------------------------------------------------------------- 74 # Function : filter-by 75 # Arguments: 1: list 76 # 2: predicate function, will be called as $(call $2,<name>) 77 # and it this returns a non-empty value, then <name> 78 # will be appended to the result. 79 # Returns : elements of $1 that satisfy the predicate function $2 80 # ----------------------------------------------------------------------------- 81 filter-by = $(strip \ 82 $(foreach __filter_by_n,$1,\ 83 $(if $(call $2,$(__filter_by_n)),$(__filter_by_n)))) 84 85 -test-filter-by = \ 86 $(eval -local-func = $$(call seq,foo,$$1))\ 87 $(call test-expect,,$(call filter-by,,-local-func))\ 88 $(call test-expect,foo,$(call filter-by,foo,-local-func))\ 89 $(call test-expect,foo,$(call filter-by,foo bar,-local-func))\ 90 $(call test-expect,foo foo,$(call filter-by,aaa foo bar foo,-local-func))\ 91 $(eval -local-func = $$(call sne,foo,$$1))\ 92 $(call test-expect,,$(call filter-by,,-local-func))\ 93 $(call test-expect,,$(call filter-by,foo,-local-func))\ 94 $(call test-expect,bar,$(call filter-by,foo bar,-local-func))\ 95 $(call test-expect,aaa bar,$(call filter-by,aaa foo bar,-local-func)) 96 97 # ----------------------------------------------------------------------------- 98 # Function : filter-out-by 99 # Arguments: 1: list 100 # 2: predicate function, will be called as $(call $2,<name>) 101 # and it this returns an empty value, then <name> 102 # will be appended to the result. 103 # Returns : elements of $1 that do not satisfy the predicate function $2 104 # ----------------------------------------------------------------------------- 105 filter-out-by = $(strip \ 106 $(foreach __filter_out_by_n,$1,\ 107 $(if $(call $2,$(__filter_out_by_n)),,$(__filter_out_by_n)))) 108 109 -test-filter-out-by = \ 110 $(eval -local-func = $$(call seq,foo,$$1))\ 111 $(call test-expect,,$(call filter-out-by,,-local-func))\ 112 $(call test-expect,,$(call filter-out-by,foo,-local-func))\ 113 $(call test-expect,bar,$(call filter-out-by,foo bar,-local-func))\ 114 $(call test-expect,aaa bar,$(call filter-out-by,aaa foo bar foo,-local-func))\ 115 $(eval -local-func = $$(call sne,foo,$$1))\ 116 $(call test-expect,,$(call filter-out-by,,-local-func))\ 117 $(call test-expect,foo,$(call filter-out-by,foo,-local-func))\ 118 $(call test-expect,foo,$(call filter-out-by,foo bar,-local-func))\ 119 $(call test-expect,foo foo,$(call filter-out-by,aaa foo bar foo,-local-func)) 120 121 # ----------------------------------------------------------------------------- 122 # Function : find-first 123 # Arguments: 1: list 124 # 2: predicate function, will be called as $(call $2,<name>). 125 # Returns : the first item of $1 that satisfies the predicate. 126 # ----------------------------------------------------------------------------- 127 find-first = $(firstword $(call filter-by,$1,$2)) 128 129 -test-find-first.empty = \ 130 $(eval -local-pred = $$(call seq,foo,$$1))\ 131 $(call test-expect,,$(call find-first,,-local-pred))\ 132 $(call test-expect,,$(call find-first,bar,-local-pred)) 133 134 -test-find-first.simple = \ 135 $(eval -local-pred = $$(call seq,foo,$$1))\ 136 $(call test-expect,foo,$(call find-first,foo,-local-pred))\ 137 $(call test-expect,foo,$(call find-first,aaa foo bar,-local-pred))\ 138 $(call test-expect,foo,$(call find-first,aaa foo foo bar,-local-pred)) 139 140 # ----------------------------------------------------------------------------- 141 # Function : parent-dir 142 # Arguments: 1: path 143 # Returns : Parent dir or path of $1, with final separator removed. 144 # ----------------------------------------------------------------------------- 145 parent-dir = $(patsubst %/,%,$(dir $(1:%/=%))) 146 147 -test-parent-dir = \ 148 $(call test-expect,,$(call parent-dir))\ 149 $(call test-expect,.,$(call parent-dir,foo))\ 150 $(call test-expect,foo,$(call parent-dir,foo/bar))\ 151 $(call test-expect,foo,$(call parent-dir,foo/bar/)) 152 153 # ----------------------------------------------------------------------------- 154 # Strip any 'lib' prefix in front of a given string. 155 # 156 # Function : strip-lib-prefix 157 # Arguments: 1: module name 158 # Returns : module name, without any 'lib' prefix if any 159 # Usage : $(call strip-lib-prefix,$(LOCAL_MODULE)) 160 # ----------------------------------------------------------------------------- 161 strip-lib-prefix = $(1:lib%=%) 162 163 -test-strip-lib-prefix = \ 164 $(call test-expect,,$(call strip-lib-prefix,))\ 165 $(call test-expect,foo,$(call strip-lib-prefix,foo))\ 166 $(call test-expect,foo,$(call strip-lib-prefix,libfoo))\ 167 $(call test-expect,nolibfoo,$(call strip-lib-prefix,nolibfoo))\ 168 $(call test-expect,foolib,$(call strip-lib-prefix,foolib))\ 169 $(call test-expect,foo bar,$(call strip-lib-prefix,libfoo libbar)) 170 171