162306a36Sopenharmony_ci# This allows us to work with the newline character:
262306a36Sopenharmony_cidefine newline
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciendef
662306a36Sopenharmony_cinewline := $(newline)
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci# nl-escape
962306a36Sopenharmony_ci#
1062306a36Sopenharmony_ci# Usage: escape = $(call nl-escape[,escape])
1162306a36Sopenharmony_ci#
1262306a36Sopenharmony_ci# This is used as the common way to specify
1362306a36Sopenharmony_ci# what should replace a newline when escaping
1462306a36Sopenharmony_ci# newlines; the default is a bizarre string.
1562306a36Sopenharmony_ci#
1662306a36Sopenharmony_cinl-escape = $(if $(1),$(1),m822df3020w6a44id34bt574ctac44eb9f4n)
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci# escape-nl
1962306a36Sopenharmony_ci#
2062306a36Sopenharmony_ci# Usage: escaped-text = $(call escape-nl,text[,escape])
2162306a36Sopenharmony_ci#
2262306a36Sopenharmony_ci# GNU make's $(shell ...) function converts to a
2362306a36Sopenharmony_ci# single space each newline character in the output
2462306a36Sopenharmony_ci# produced during the expansion; this may not be
2562306a36Sopenharmony_ci# desirable.
2662306a36Sopenharmony_ci#
2762306a36Sopenharmony_ci# The only solution is to change each newline into
2862306a36Sopenharmony_ci# something that won't be converted, so that the
2962306a36Sopenharmony_ci# information can be recovered later with
3062306a36Sopenharmony_ci# $(call unescape-nl...)
3162306a36Sopenharmony_ci#
3262306a36Sopenharmony_ciescape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1))
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci# unescape-nl
3562306a36Sopenharmony_ci#
3662306a36Sopenharmony_ci# Usage: text = $(call unescape-nl,escaped-text[,escape])
3762306a36Sopenharmony_ci#
3862306a36Sopenharmony_ci# See escape-nl.
3962306a36Sopenharmony_ci#
4062306a36Sopenharmony_ciunescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1))
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci# shell-escape-nl
4362306a36Sopenharmony_ci#
4462306a36Sopenharmony_ci# Usage: $(shell some-command | $(call shell-escape-nl[,escape]))
4562306a36Sopenharmony_ci#
4662306a36Sopenharmony_ci# Use this to escape newlines from within a shell call;
4762306a36Sopenharmony_ci# the default escape is a bizarre string.
4862306a36Sopenharmony_ci#
4962306a36Sopenharmony_ci# NOTE: The escape is used directly as a string constant
5062306a36Sopenharmony_ci#       in an `awk' program that is delimited by shell
5162306a36Sopenharmony_ci#       single-quotes, so be wary of the characters
5262306a36Sopenharmony_ci#       that are chosen.
5362306a36Sopenharmony_ci#
5462306a36Sopenharmony_cidefine shell-escape-nl
5562306a36Sopenharmony_ciawk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}'
5662306a36Sopenharmony_ciendef
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci# shell-unescape-nl
5962306a36Sopenharmony_ci#
6062306a36Sopenharmony_ci# Usage: $(shell some-command | $(call shell-unescape-nl[,escape]))
6162306a36Sopenharmony_ci#
6262306a36Sopenharmony_ci# Use this to unescape newlines from within a shell call;
6362306a36Sopenharmony_ci# the default escape is a bizarre string.
6462306a36Sopenharmony_ci#
6562306a36Sopenharmony_ci# NOTE: The escape is used directly as an extended regular
6662306a36Sopenharmony_ci#       expression constant in an `awk' program that is
6762306a36Sopenharmony_ci#       delimited by shell single-quotes, so be wary
6862306a36Sopenharmony_ci#       of the characters that are chosen.
6962306a36Sopenharmony_ci#
7062306a36Sopenharmony_ci# (The bash shell has a bug where `{gsub(...),...}' is
7162306a36Sopenharmony_ci#  misinterpreted as a brace expansion; this can be
7262306a36Sopenharmony_ci#  overcome by putting a space between `{' and `gsub').
7362306a36Sopenharmony_ci#
7462306a36Sopenharmony_cidefine shell-unescape-nl
7562306a36Sopenharmony_ciawk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }'
7662306a36Sopenharmony_ciendef
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci# escape-for-shell-sq
7962306a36Sopenharmony_ci#
8062306a36Sopenharmony_ci# Usage: embeddable-text = $(call escape-for-shell-sq,text)
8162306a36Sopenharmony_ci#
8262306a36Sopenharmony_ci# This function produces text that is suitable for
8362306a36Sopenharmony_ci# embedding in a shell string that is delimited by
8462306a36Sopenharmony_ci# single-quotes.
8562306a36Sopenharmony_ci#
8662306a36Sopenharmony_ciescape-for-shell-sq =  $(subst ','\'',$(1))
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci# shell-sq
8962306a36Sopenharmony_ci#
9062306a36Sopenharmony_ci# Usage: single-quoted-and-escaped-text = $(call shell-sq,text)
9162306a36Sopenharmony_ci#
9262306a36Sopenharmony_cishell-sq = '$(escape-for-shell-sq)'
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci# shell-wordify
9562306a36Sopenharmony_ci#
9662306a36Sopenharmony_ci# Usage: wordified-text = $(call shell-wordify,text)
9762306a36Sopenharmony_ci#
9862306a36Sopenharmony_ci# For instance:
9962306a36Sopenharmony_ci#
10062306a36Sopenharmony_ci#  |define text
10162306a36Sopenharmony_ci#  |hello
10262306a36Sopenharmony_ci#  |world
10362306a36Sopenharmony_ci#  |endef
10462306a36Sopenharmony_ci#  |
10562306a36Sopenharmony_ci#  |target:
10662306a36Sopenharmony_ci#  |	echo $(call shell-wordify,$(text))
10762306a36Sopenharmony_ci#
10862306a36Sopenharmony_ci# At least GNU make gets confused by expanding a newline
10962306a36Sopenharmony_ci# within the context of a command line of a makefile rule
11062306a36Sopenharmony_ci# (this is in constrast to a `$(shell ...)' function call,
11162306a36Sopenharmony_ci# which can handle it just fine).
11262306a36Sopenharmony_ci#
11362306a36Sopenharmony_ci# This function avoids the problem by producing a string
11462306a36Sopenharmony_ci# that works as a shell word, regardless of whether or
11562306a36Sopenharmony_ci# not it contains a newline.
11662306a36Sopenharmony_ci#
11762306a36Sopenharmony_ci# If the text to be wordified contains a newline, then
11862306a36Sopenharmony_ci# an intrictate shell command substitution is constructed
11962306a36Sopenharmony_ci# to render the text as a single line; when the shell
12062306a36Sopenharmony_ci# processes the resulting escaped text, it transforms
12162306a36Sopenharmony_ci# it into the original unescaped text.
12262306a36Sopenharmony_ci#
12362306a36Sopenharmony_ci# If the text does not contain a newline, then this function
12462306a36Sopenharmony_ci# produces the same results as the `$(shell-sq)' function.
12562306a36Sopenharmony_ci#
12662306a36Sopenharmony_cishell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq))
12762306a36Sopenharmony_cidefine _sw-esc-nl
12862306a36Sopenharmony_ci"$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))"
12962306a36Sopenharmony_ciendef
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci# is-absolute
13262306a36Sopenharmony_ci#
13362306a36Sopenharmony_ci# Usage: bool-value = $(call is-absolute,path)
13462306a36Sopenharmony_ci#
13562306a36Sopenharmony_ciis-absolute = $(shell echo $(shell-sq) | grep -q ^/ && echo y)
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci# lookup
13862306a36Sopenharmony_ci#
13962306a36Sopenharmony_ci# Usage: absolute-executable-path-or-empty = $(call lookup,path)
14062306a36Sopenharmony_ci#
14162306a36Sopenharmony_ci# (It's necessary to use `sh -c' because GNU make messes up by
14262306a36Sopenharmony_ci#  trying too hard and getting things wrong).
14362306a36Sopenharmony_ci#
14462306a36Sopenharmony_cilookup = $(call unescape-nl,$(shell sh -c $(_l-sh)))
14562306a36Sopenharmony_ci_l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,))
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci# is-executable
14862306a36Sopenharmony_ci#
14962306a36Sopenharmony_ci# Usage: bool-value = $(call is-executable,path)
15062306a36Sopenharmony_ci#
15162306a36Sopenharmony_ci# (It's necessary to use `sh -c' because GNU make messes up by
15262306a36Sopenharmony_ci#  trying too hard and getting things wrong).
15362306a36Sopenharmony_ci#
15462306a36Sopenharmony_ciis-executable = $(call _is-executable-helper,$(shell-sq))
15562306a36Sopenharmony_ci_is-executable-helper = $(shell sh -c $(_is-executable-sh))
15662306a36Sopenharmony_ci_is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y)
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci# get-executable
15962306a36Sopenharmony_ci#
16062306a36Sopenharmony_ci# Usage: absolute-executable-path-or-empty = $(call get-executable,path)
16162306a36Sopenharmony_ci#
16262306a36Sopenharmony_ci# The goal is to get an absolute path for an executable;
16362306a36Sopenharmony_ci# the `command -v' is defined by POSIX, but it's not
16462306a36Sopenharmony_ci# necessarily very portable, so it's only used if
16562306a36Sopenharmony_ci# relative path resolution is requested, as determined
16662306a36Sopenharmony_ci# by the presence of a leading `/'.
16762306a36Sopenharmony_ci#
16862306a36Sopenharmony_ciget-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup)))
16962306a36Sopenharmony_ci_ge-abspath = $(if $(is-executable),$(1))
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci# get-supplied-or-default-executable
17262306a36Sopenharmony_ci#
17362306a36Sopenharmony_ci# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
17462306a36Sopenharmony_ci#
17562306a36Sopenharmony_cidefine get-executable-or-default
17662306a36Sopenharmony_ci$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
17762306a36Sopenharmony_ciendef
17862306a36Sopenharmony_ci_ge_attempt = $(or $(get-executable),$(call _gea_err,$(2)))
17962306a36Sopenharmony_ci_gea_err  = $(if $(1),$(error Please set '$(1)' appropriately))
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci# version-ge3
18262306a36Sopenharmony_ci#
18362306a36Sopenharmony_ci# Usage $(call version-ge3,2.6.4,$(FLEX_VERSION))
18462306a36Sopenharmony_ci#
18562306a36Sopenharmony_ci# To compare if a 3 component version is greater or equal to another, first use
18662306a36Sopenharmony_ci# was to check the flex version to see if we can use compiler warnings as
18762306a36Sopenharmony_ci# errors for one of the cases flex generates code C compilers complains about.
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_civersion-ge3 = $(shell echo "$(1).$(2)" | awk -F'.' '{ printf("%d\n", (10000000 * $$1 + 10000 * $$2 + $$3) >= (10000000 * $$4 + 10000 * $$5 + $$6)) }')
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci# version-lt3
19262306a36Sopenharmony_ci#
19362306a36Sopenharmony_ci# Usage $(call version-lt3,2.6.2,$(FLEX_VERSION))
19462306a36Sopenharmony_ci#
19562306a36Sopenharmony_ci# To compare if a 3 component version is less thjan another, first use was to
19662306a36Sopenharmony_ci# check the flex version to see if we can use compiler warnings as errors for
19762306a36Sopenharmony_ci# one of the cases flex generates code C compilers complains about.
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_civersion-lt3 = $(shell echo "$(1).$(2)" | awk -F'.' '{ printf("%d\n", (10000000 * $$1 + 10000 * $$2 + $$3) < (10000000 * $$4 + 10000 * $$5 + $$6)) }')
200