18c2ecf20Sopenharmony_ci# This allows us to work with the newline character: 28c2ecf20Sopenharmony_cidefine newline 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciendef 68c2ecf20Sopenharmony_cinewline := $(newline) 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci# nl-escape 98c2ecf20Sopenharmony_ci# 108c2ecf20Sopenharmony_ci# Usage: escape = $(call nl-escape[,escape]) 118c2ecf20Sopenharmony_ci# 128c2ecf20Sopenharmony_ci# This is used as the common way to specify 138c2ecf20Sopenharmony_ci# what should replace a newline when escaping 148c2ecf20Sopenharmony_ci# newlines; the default is a bizarre string. 158c2ecf20Sopenharmony_ci# 168c2ecf20Sopenharmony_cinl-escape = $(if $(1),$(1),m822df3020w6a44id34bt574ctac44eb9f4n) 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci# escape-nl 198c2ecf20Sopenharmony_ci# 208c2ecf20Sopenharmony_ci# Usage: escaped-text = $(call escape-nl,text[,escape]) 218c2ecf20Sopenharmony_ci# 228c2ecf20Sopenharmony_ci# GNU make's $(shell ...) function converts to a 238c2ecf20Sopenharmony_ci# single space each newline character in the output 248c2ecf20Sopenharmony_ci# produced during the expansion; this may not be 258c2ecf20Sopenharmony_ci# desirable. 268c2ecf20Sopenharmony_ci# 278c2ecf20Sopenharmony_ci# The only solution is to change each newline into 288c2ecf20Sopenharmony_ci# something that won't be converted, so that the 298c2ecf20Sopenharmony_ci# information can be recovered later with 308c2ecf20Sopenharmony_ci# $(call unescape-nl...) 318c2ecf20Sopenharmony_ci# 328c2ecf20Sopenharmony_ciescape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1)) 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci# unescape-nl 358c2ecf20Sopenharmony_ci# 368c2ecf20Sopenharmony_ci# Usage: text = $(call unescape-nl,escaped-text[,escape]) 378c2ecf20Sopenharmony_ci# 388c2ecf20Sopenharmony_ci# See escape-nl. 398c2ecf20Sopenharmony_ci# 408c2ecf20Sopenharmony_ciunescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1)) 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci# shell-escape-nl 438c2ecf20Sopenharmony_ci# 448c2ecf20Sopenharmony_ci# Usage: $(shell some-command | $(call shell-escape-nl[,escape])) 458c2ecf20Sopenharmony_ci# 468c2ecf20Sopenharmony_ci# Use this to escape newlines from within a shell call; 478c2ecf20Sopenharmony_ci# the default escape is a bizarre string. 488c2ecf20Sopenharmony_ci# 498c2ecf20Sopenharmony_ci# NOTE: The escape is used directly as a string constant 508c2ecf20Sopenharmony_ci# in an `awk' program that is delimited by shell 518c2ecf20Sopenharmony_ci# single-quotes, so be wary of the characters 528c2ecf20Sopenharmony_ci# that are chosen. 538c2ecf20Sopenharmony_ci# 548c2ecf20Sopenharmony_cidefine shell-escape-nl 558c2ecf20Sopenharmony_ciawk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}' 568c2ecf20Sopenharmony_ciendef 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci# shell-unescape-nl 598c2ecf20Sopenharmony_ci# 608c2ecf20Sopenharmony_ci# Usage: $(shell some-command | $(call shell-unescape-nl[,escape])) 618c2ecf20Sopenharmony_ci# 628c2ecf20Sopenharmony_ci# Use this to unescape newlines from within a shell call; 638c2ecf20Sopenharmony_ci# the default escape is a bizarre string. 648c2ecf20Sopenharmony_ci# 658c2ecf20Sopenharmony_ci# NOTE: The escape is used directly as an extended regular 668c2ecf20Sopenharmony_ci# expression constant in an `awk' program that is 678c2ecf20Sopenharmony_ci# delimited by shell single-quotes, so be wary 688c2ecf20Sopenharmony_ci# of the characters that are chosen. 698c2ecf20Sopenharmony_ci# 708c2ecf20Sopenharmony_ci# (The bash shell has a bug where `{gsub(...),...}' is 718c2ecf20Sopenharmony_ci# misinterpreted as a brace expansion; this can be 728c2ecf20Sopenharmony_ci# overcome by putting a space between `{' and `gsub'). 738c2ecf20Sopenharmony_ci# 748c2ecf20Sopenharmony_cidefine shell-unescape-nl 758c2ecf20Sopenharmony_ciawk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }' 768c2ecf20Sopenharmony_ciendef 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci# escape-for-shell-sq 798c2ecf20Sopenharmony_ci# 808c2ecf20Sopenharmony_ci# Usage: embeddable-text = $(call escape-for-shell-sq,text) 818c2ecf20Sopenharmony_ci# 828c2ecf20Sopenharmony_ci# This function produces text that is suitable for 838c2ecf20Sopenharmony_ci# embedding in a shell string that is delimited by 848c2ecf20Sopenharmony_ci# single-quotes. 858c2ecf20Sopenharmony_ci# 868c2ecf20Sopenharmony_ciescape-for-shell-sq = $(subst ','\'',$(1)) 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci# shell-sq 898c2ecf20Sopenharmony_ci# 908c2ecf20Sopenharmony_ci# Usage: single-quoted-and-escaped-text = $(call shell-sq,text) 918c2ecf20Sopenharmony_ci# 928c2ecf20Sopenharmony_cishell-sq = '$(escape-for-shell-sq)' 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci# shell-wordify 958c2ecf20Sopenharmony_ci# 968c2ecf20Sopenharmony_ci# Usage: wordified-text = $(call shell-wordify,text) 978c2ecf20Sopenharmony_ci# 988c2ecf20Sopenharmony_ci# For instance: 998c2ecf20Sopenharmony_ci# 1008c2ecf20Sopenharmony_ci# |define text 1018c2ecf20Sopenharmony_ci# |hello 1028c2ecf20Sopenharmony_ci# |world 1038c2ecf20Sopenharmony_ci# |endef 1048c2ecf20Sopenharmony_ci# | 1058c2ecf20Sopenharmony_ci# |target: 1068c2ecf20Sopenharmony_ci# | echo $(call shell-wordify,$(text)) 1078c2ecf20Sopenharmony_ci# 1088c2ecf20Sopenharmony_ci# At least GNU make gets confused by expanding a newline 1098c2ecf20Sopenharmony_ci# within the context of a command line of a makefile rule 1108c2ecf20Sopenharmony_ci# (this is in constrast to a `$(shell ...)' function call, 1118c2ecf20Sopenharmony_ci# which can handle it just fine). 1128c2ecf20Sopenharmony_ci# 1138c2ecf20Sopenharmony_ci# This function avoids the problem by producing a string 1148c2ecf20Sopenharmony_ci# that works as a shell word, regardless of whether or 1158c2ecf20Sopenharmony_ci# not it contains a newline. 1168c2ecf20Sopenharmony_ci# 1178c2ecf20Sopenharmony_ci# If the text to be wordified contains a newline, then 1188c2ecf20Sopenharmony_ci# an intrictate shell command substitution is constructed 1198c2ecf20Sopenharmony_ci# to render the text as a single line; when the shell 1208c2ecf20Sopenharmony_ci# processes the resulting escaped text, it transforms 1218c2ecf20Sopenharmony_ci# it into the original unescaped text. 1228c2ecf20Sopenharmony_ci# 1238c2ecf20Sopenharmony_ci# If the text does not contain a newline, then this function 1248c2ecf20Sopenharmony_ci# produces the same results as the `$(shell-sq)' function. 1258c2ecf20Sopenharmony_ci# 1268c2ecf20Sopenharmony_cishell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq)) 1278c2ecf20Sopenharmony_cidefine _sw-esc-nl 1288c2ecf20Sopenharmony_ci"$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))" 1298c2ecf20Sopenharmony_ciendef 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci# is-absolute 1328c2ecf20Sopenharmony_ci# 1338c2ecf20Sopenharmony_ci# Usage: bool-value = $(call is-absolute,path) 1348c2ecf20Sopenharmony_ci# 1358c2ecf20Sopenharmony_ciis-absolute = $(shell echo $(shell-sq) | grep -q ^/ && echo y) 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci# lookup 1388c2ecf20Sopenharmony_ci# 1398c2ecf20Sopenharmony_ci# Usage: absolute-executable-path-or-empty = $(call lookup,path) 1408c2ecf20Sopenharmony_ci# 1418c2ecf20Sopenharmony_ci# (It's necessary to use `sh -c' because GNU make messes up by 1428c2ecf20Sopenharmony_ci# trying too hard and getting things wrong). 1438c2ecf20Sopenharmony_ci# 1448c2ecf20Sopenharmony_cilookup = $(call unescape-nl,$(shell sh -c $(_l-sh))) 1458c2ecf20Sopenharmony_ci_l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,)) 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci# is-executable 1488c2ecf20Sopenharmony_ci# 1498c2ecf20Sopenharmony_ci# Usage: bool-value = $(call is-executable,path) 1508c2ecf20Sopenharmony_ci# 1518c2ecf20Sopenharmony_ci# (It's necessary to use `sh -c' because GNU make messes up by 1528c2ecf20Sopenharmony_ci# trying too hard and getting things wrong). 1538c2ecf20Sopenharmony_ci# 1548c2ecf20Sopenharmony_ciis-executable = $(call _is-executable-helper,$(shell-sq)) 1558c2ecf20Sopenharmony_ci_is-executable-helper = $(shell sh -c $(_is-executable-sh)) 1568c2ecf20Sopenharmony_ci_is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y) 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci# get-executable 1598c2ecf20Sopenharmony_ci# 1608c2ecf20Sopenharmony_ci# Usage: absolute-executable-path-or-empty = $(call get-executable,path) 1618c2ecf20Sopenharmony_ci# 1628c2ecf20Sopenharmony_ci# The goal is to get an absolute path for an executable; 1638c2ecf20Sopenharmony_ci# the `command -v' is defined by POSIX, but it's not 1648c2ecf20Sopenharmony_ci# necessarily very portable, so it's only used if 1658c2ecf20Sopenharmony_ci# relative path resolution is requested, as determined 1668c2ecf20Sopenharmony_ci# by the presence of a leading `/'. 1678c2ecf20Sopenharmony_ci# 1688c2ecf20Sopenharmony_ciget-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup))) 1698c2ecf20Sopenharmony_ci_ge-abspath = $(if $(is-executable),$(1)) 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci# get-supplied-or-default-executable 1728c2ecf20Sopenharmony_ci# 1738c2ecf20Sopenharmony_ci# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default) 1748c2ecf20Sopenharmony_ci# 1758c2ecf20Sopenharmony_cidefine get-executable-or-default 1768c2ecf20Sopenharmony_ci$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2))) 1778c2ecf20Sopenharmony_ciendef 1788c2ecf20Sopenharmony_ci_ge_attempt = $(if $(get-executable),$(get-executable),$(call _gea_err,$(2))) 1798c2ecf20Sopenharmony_ci_gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) 180