• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# -----------------------------------------------------------------------------
27empty :=
28
29# -----------------------------------------------------------------------------
30# Macro    : space
31# Returns  : a single space
32# Usage    : $(space)
33# -----------------------------------------------------------------------------
34space  := $(empty) $(empty)
35
36space4 := $(space)$(space)$(space)$(space)
37
38# -----------------------------------------------------------------------------
39# Macro    : comma
40# Returns  : a single comma
41# Usage    : $(comma)
42# -----------------------------------------------------------------------------
43comma := ,
44
45# -----------------------------------------------------------------------------
46# Macro    : colon
47# Returns  : a single colon
48# Usage    : $(colon)
49# -----------------------------------------------------------------------------
50colon := :
51
52# -----------------------------------------------------------------------------
53# Function : remove-duplicates
54# Arguments: a list
55# Returns  : the list with duplicate items removed, order is preserved.
56# Usage    : $(call remove-duplicates, <LIST>)
57# Note     : This is equivalent to the 'uniq' function provided by GMSL,
58#            however this implementation is non-recursive and *much*
59#            faster. It will also not explode the stack with a lot of
60#            items like 'uniq' does.
61# -----------------------------------------------------------------------------
62remove-duplicates = $(strip \
63  $(eval __uniq_ret :=) \
64  $(foreach __uniq_item,$1,\
65    $(if $(findstring $(__uniq_item),$(__uniq_ret)),,\
66      $(eval __uniq_ret += $(__uniq_item))\
67    )\
68  )\
69  $(__uniq_ret))
70
71-test-remove-duplicates = \
72  $(call test-expect,,$(call remove-duplicates))\
73  $(call test-expect,foo bar,$(call remove-duplicates,foo bar))\
74  $(call test-expect,foo bar,$(call remove-duplicates,foo bar foo bar))\
75  $(call test-expect,foo bar,$(call remove-duplicates,foo foo bar bar bar))
76
77# -----------------------------------------------------------------------------
78# Function : clear-vars
79# Arguments: 1: list of variable names
80#            2: file where the variable should be defined
81# Returns  : None
82# Usage    : $(call clear-vars, VAR1 VAR2 VAR3...)
83# Rationale: Clears/undefines all variables in argument list
84# -----------------------------------------------------------------------------
85clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty)))
86
87# -----------------------------------------------------------------------------
88# Function : filter-by
89# Arguments: 1: list
90#            2: predicate function, will be called as $(call $2,<name>)
91#               and it this returns a non-empty value, then <name>
92#               will be appended to the result.
93# Returns  : elements of $1 that satisfy the predicate function $2
94# -----------------------------------------------------------------------------
95filter-by = $(strip \
96  $(foreach __filter_by_n,$1,\
97    $(if $(call $2,$(__filter_by_n)),$(__filter_by_n))))
98
99-test-filter-by = \
100    $(eval -local-func = $$(call seq,foo,$$1))\
101    $(call test-expect,,$(call filter-by,,-local-func))\
102    $(call test-expect,foo,$(call filter-by,foo,-local-func))\
103    $(call test-expect,foo,$(call filter-by,foo bar,-local-func))\
104    $(call test-expect,foo foo,$(call filter-by,aaa foo bar foo,-local-func))\
105    $(eval -local-func = $$(call sne,foo,$$1))\
106    $(call test-expect,,$(call filter-by,,-local-func))\
107    $(call test-expect,,$(call filter-by,foo,-local-func))\
108    $(call test-expect,bar,$(call filter-by,foo bar,-local-func))\
109    $(call test-expect,aaa bar,$(call filter-by,aaa foo bar,-local-func))
110
111# -----------------------------------------------------------------------------
112# Function : filter-out-by
113# Arguments: 1: list
114#            2: predicate function, will be called as $(call $2,<name>)
115#               and it this returns an empty value, then <name>
116#               will be appended to the result.
117# Returns  : elements of $1 that do not satisfy the predicate function $2
118# -----------------------------------------------------------------------------
119filter-out-by = $(strip \
120  $(foreach __filter_out_by_n,$1,\
121    $(if $(call $2,$(__filter_out_by_n)),,$(__filter_out_by_n))))
122
123-test-filter-out-by = \
124    $(eval -local-func = $$(call seq,foo,$$1))\
125    $(call test-expect,,$(call filter-out-by,,-local-func))\
126    $(call test-expect,,$(call filter-out-by,foo,-local-func))\
127    $(call test-expect,bar,$(call filter-out-by,foo bar,-local-func))\
128    $(call test-expect,aaa bar,$(call filter-out-by,aaa foo bar foo,-local-func))\
129    $(eval -local-func = $$(call sne,foo,$$1))\
130    $(call test-expect,,$(call filter-out-by,,-local-func))\
131    $(call test-expect,foo,$(call filter-out-by,foo,-local-func))\
132    $(call test-expect,foo,$(call filter-out-by,foo bar,-local-func))\
133    $(call test-expect,foo foo,$(call filter-out-by,aaa foo bar foo,-local-func))
134
135# -----------------------------------------------------------------------------
136# Function : find-first
137# Arguments: 1: list
138#            2: predicate function, will be called as $(call $2,<name>).
139# Returns  : the first item of $1 that satisfies the predicate.
140# -----------------------------------------------------------------------------
141find-first = $(firstword $(call filter-by,$1,$2))
142
143-test-find-first.empty = \
144    $(eval -local-pred = $$(call seq,foo,$$1))\
145    $(call test-expect,,$(call find-first,,-local-pred))\
146    $(call test-expect,,$(call find-first,bar,-local-pred))
147
148-test-find-first.simple = \
149    $(eval -local-pred = $$(call seq,foo,$$1))\
150    $(call test-expect,foo,$(call find-first,foo,-local-pred))\
151    $(call test-expect,foo,$(call find-first,aaa foo bar,-local-pred))\
152    $(call test-expect,foo,$(call find-first,aaa foo foo bar,-local-pred))
153
154# -----------------------------------------------------------------------------
155# Function : parent-dir
156# Arguments: 1: path
157# Returns  : Parent dir or path of $1, with final separator removed.
158# -----------------------------------------------------------------------------
159parent-dir = $(patsubst %/,%,$(dir $(1:%/=%)))
160
161-test-parent-dir = \
162  $(call test-expect,,$(call parent-dir))\
163  $(call test-expect,.,$(call parent-dir,foo))\
164  $(call test-expect,foo,$(call parent-dir,foo/bar))\
165  $(call test-expect,foo,$(call parent-dir,foo/bar/))
166
167# -----------------------------------------------------------------------------
168# Strip any 'lib' prefix in front of a given string.
169#
170# Function : strip-lib-prefix
171# Arguments: 1: module name
172# Returns  : module name, without any 'lib' prefix if any
173# Usage    : $(call strip-lib-prefix,$(LOCAL_MODULE))
174# -----------------------------------------------------------------------------
175strip-lib-prefix = $(1:lib%=%)
176
177-test-strip-lib-prefix = \
178  $(call test-expect,,$(call strip-lib-prefix,))\
179  $(call test-expect,foo,$(call strip-lib-prefix,foo))\
180  $(call test-expect,foo,$(call strip-lib-prefix,libfoo))\
181  $(call test-expect,nolibfoo,$(call strip-lib-prefix,nolibfoo))\
182  $(call test-expect,foolib,$(call strip-lib-prefix,foolib))\
183  $(call test-expect,foo bar,$(call strip-lib-prefix,libfoo libbar))
184
185# -----------------------------------------------------------------------------
186# Left-justify input string with spaces to fill a width of 15.
187# Function: left-justify-quoted-15
188# Arguments: 1: Input text
189# Returns: A quoted string that can be used in command scripts to print
190#          the left-justified input with host-echo.
191#
192# Usage:  ---->@$(call host-echo, $(call left-justify-quoted-15,$(_TEXT)): Do stuff)
193#         Where ----> is a TAB character.
194# -----------------------------------------------------------------------------
195left-justify-quoted-15 = $(call -left-justify,$1,xxxxxxxxxxxxxxx)
196
197-test-left-justify-quoted-15 = \
198  $(call test-expect,"               ",$(call left-justify-quoted-15,))\
199  $(call test-expect,"Foo Bar        ",$(call left-justify-quoted-15,Foo Bar))\
200  $(call test-expect,"Very long string over 15 characters wide",$(strip \
201    $(call left-justify-quoted-15,Very long string over 15 characters wide)))
202
203# Used internally to compute a quoted left-justified text string.
204# $1: Input string.
205# $2: A series of contiguous x's, its length determines the full width to justify to.
206# Return: A quoted string with the input text left-justified appropriately.
207-left-justify = $(strip \
208    $(eval __lj_temp := $(subst $(space),x,$1))\
209    $(foreach __lj_a,$(__gmsl_characters),$(eval __lj_temp := $$(subst $$(__lj_a),x,$(__lj_temp))))\
210    $(eval __lj_margin := $$(call -justification-margin,$(__lj_temp),$2)))"$1$(subst x,$(space),$(__lj_margin))"
211
212-test-left-justify = \
213  $(call test-expect,"",$(call -left-justify,,))\
214  $(call test-expect,"foo",$(call -left-justify,foo,xxx))\
215  $(call test-expect,"foo ",$(call -left-justify,foo,xxxx))\
216  $(call test-expect,"foo   ",$(call -left-justify,foo,xxxxxx))\
217  $(call test-expect,"foo         ",$(call -left-justify,foo,xxxxxxxxxxxx))\
218  $(call test-expect,"very long string",$(call -left-justify,very long string,xxx))\
219
220# Used internally to compute a justification margin.
221# Expects $1 to be defined to a string of consecutive x's (e.g. 'xxxx')
222# Expects $2 to be defined to a maximum string of x's (e.g. 'xxxxxxxxx')
223# Returns a string of x's such as $1 + $(result) is equal to $2
224# If $1 is larger than $2, return empty string..
225-justification-margin = $(strip \
226    $(if $2,\
227      $(if $1,\
228        $(call -justification-margin-inner,$1,$2),\
229        $2\
230      ),\
231    $1))
232
233-justification-margin-inner = $(if $(findstring $2,$1),,x$(call -justification-margin-inner,x$1,$2))
234
235-test-justification-margin = \
236  $(call test-expect,,$(call -justification-margin,,))\
237  $(call test-expect,,$(call -justification-margin,xxx,xxx))\
238  $(call test-expect,xxxxxx,$(call -justification-margin,,xxxxxx))\
239  $(call test-expect,xxxxx,$(call -justification-margin,x,xxxxxx))\
240  $(call test-expect,xxxx,$(call -justification-margin,xx,xxxxxx))\
241  $(call test-expect,xxx,$(call -justification-margin,xxx,xxxxxx))\
242  $(call test-expect,xx,$(call -justification-margin,xxxx,xxxxxx))\
243  $(call test-expect,x,$(call -justification-margin,xxxxx,xxxxxx))\
244  $(call test-expect,,$(call -justification-margin,xxxxxx,xxxxxx))\
245  $(call test-expect,,$(call -justification-margin,xxxxxxxxxxx,xxxxxx))\
246
247