tg-info.sh: show a message when the remote base is missing
[topgit/pro.git] / gnomake.sh
blob26a0399ee575d273ef3581a3a785bd7738d31440
1 # gnomake.sh - POSIX Makefile.sh utility functions
2 # Copyright (C) 2017 Kyle J. McKay
3 # All rights reserved
4 # License GPL2
6 ##
7 ## Utility functions for Makefile.sh scripts
8 ##
10 # prevent crazy "sh" implementations from exporting functions into environment
11 set +a
13 # always run in errexit mode
14 set -e
16 # configsh sources config.sh if it exists and then sets
17 # CONFIGMAK to either Makefile.mt (if there is no config.mak)
18 # or "config.mak" if there is.
20 # If MKTOP is set, they are looked for there instead of in
21 # the current directory.
23 # wrap it up for safety
24 configsh() {
25 ! [ -f "${MKTOP:+$MKTOP/}config.sh" ] ||
26 . ./"${MKTOP:+$MKTOP/}config.sh"
27 # now set CONFIGMAK and make it an absolute path
28 [ -n "$CONFIGMAK" ] || CONFIGMAK="${MKTOP:+$MKTOP/}config.mak"
29 [ -f "$CONFIGMAK" ] || CONFIGMAK="${MKTOP:+$MKTOP/}Makefile.mt"
30 case "$CONFIGMAK" in */?*);;*) CONFIGMAK="./$CONFIGMAK"; esac
31 CONFIGMAK="$(cd "${CONFIGMAK%/*}" && pwd)/${CONFIGMAK##*/}"
34 # "which" but using only POSIX shell built-ins
35 cmd_path() (
36 { "unset" -f command unset unalias "$1"; } >/dev/null 2>&1 || :
37 { "unalias" -a || unalias -m "*"; } >/dev/null 2>&1 || :
38 command -v "$1"
41 # stores the single-quoted value of the variable name passed as
42 # the first argument into the variable name passed as the second
43 # (use quotevar 3 varname "$value" to quote a value directly)
44 quotevar() {
45 eval "set -- \"\${$1}\" \"$2\""
46 case "$1" in *"'"*)
47 set -- "$(printf '%s\nZ\n' "$1" | sed "s/'/'\\\''/g")" "$2"
48 set -- "${1%??}" "$2"
49 esac
50 eval "$2=\"'$1'\""
53 # The result(s) of stripping the second argument from the end of the
54 # third and following argument(s) is joined using a space and stored
55 # in the variable named by the first argument
56 v_strip_sfx() {
57 _var="$1"
58 _sfx="$2"
59 shift 2
60 _result=
61 for _item in "$@"; do
62 _result="$_result ${_item%$_sfx}"
63 done
64 eval "$_var="'"${_result# }"'
65 unset _var _sfx _result _item
68 # The result(s) of appending the second argument to the end of the
69 # third and following argument(s) is joined using a space and stored
70 # in the variable named by the first argument
71 v_add_sfx() {
72 _var="$1"
73 _sfx="$2"
74 shift 2
75 _result=
76 for _item in "$@"; do
77 _result="$_result $_item$_sfx"
78 done
79 eval "$_var="'"${_result# }"'
80 unset _var _sfx _result _item
83 # The result(s) of stripping the second argument from the end of the
84 # fourth and following argument(s) and then appending the third argument is
85 # joined using a space and stored in the variable named by the first argument
86 v_stripadd_sfx() {
87 _var2="$1"
88 _stripsfx="$2"
89 _addsfx="$3"
90 shift 3
91 v_strip_sfx _result2 "$_stripsfx" "$@"
92 v_add_sfx "$_var2" "$_addsfx" $_result2
93 unset _var2 _stripsfx _addsfx _result2
96 # The second and following argument(s) are joined with a space and
97 # stored in the variable named by the first argument
98 v_strip_() {
99 _var="$1"
100 shift
101 eval "$_var="'"$*"'
102 unset _var
105 # The second and following argument(s) are joined with a space and then
106 # the result has leading and trailing whitespace removed and internal
107 # whitespace sequences replaced with a single space and is then stored
108 # in the variable named by the first argument and pathname expansion is
109 # disabled during the stripping process
110 v_strip() {
111 _var="$1"
112 shift
113 set -f
114 v_strip_ "$_var" $*
115 set +f
118 # Expand the second and following argument(s) using pathname expansion but
119 # skipping any that have no match and join all the results using a space and
120 # store that in the variable named by the first argument
121 v_wildcard() {
122 _var="$1"
123 shift
124 _result=
125 for _item in "$@"; do
126 eval "_exp=\"\$(printf ' %s' $_item)\""
127 [ " $_item" = "$_exp" ] && ! [ -e "$_item" ] || _result="$_result$_exp"
128 done
129 eval "$_var="'"${_result# }"'
130 unset _var _result _item _exp
133 # Sort the second and following argument(s) removing duplicates and join all the
134 # results using a space and store that in the variable named by the first argument
135 v_sort() {
136 _var="$1"
137 _saveifs="$IFS"
138 shift
139 IFS='
141 set -- $(printf '%s\n' "$@" | LC_ALL=C sort -u)
142 IFS="$_saveifs"
143 eval "$_var="'"$*"'
144 unset _var _saveifs
147 # Filter the fourth and following argument(s) according to the space-separated
148 # list of '%' pattern(s) in the third argument doing a "filter-out" instead of
149 # a "filter" if the second argument is true and join all the results using a
150 # space and store that in the variable named by the first argument
151 v_filter_() {
152 _var="$1"
153 _fo="$2"
154 _pat="$3"
155 _saveifs="$IFS"
156 shift 3
157 IFS='
159 set -- $(awk -v "fo=$_fo" -f - "$_pat" "$*"<<'EOT'
160 function qr(p) {
161 gsub(/[][*?+.|{}()^$\\]/, "\\\\&", p)
162 return p
164 function qp(p) {
165 if (match(p, /\\*%/)) {
166 return qr(substr(p, 1, RSTART - 1)) \
167 substr(p, RSTART, RLENGTH - (2 - RLENGTH % 2)) \
168 (RLENGTH % 2 ? ".*" : "%") \
169 qr(substr(p, RSTART + RLENGTH))
171 else
172 return qr(p)
174 function qm(s, _l, _c, _a, _i, _g) {
175 if (!(_c = split(s, _l, " "))) return "^$"
176 if (_c == 1) return "^" qp(_l[1]) "$"
177 _a = ""
178 _g = "^("
179 for (_i = 1; _i <= _c; ++_i) {
180 _a = _a _g qp(_l[_i])
181 _g = "|"
183 return _a ")$"
185 BEGIN {exit}
186 END {
187 pat = ARGV[1]
188 vals = ARGV[2]
189 qpat = qm(pat)
190 cnt = split(vals, va, " ")
191 for (i=1; i<=cnt; ++i)
192 if ((va[i] ~ qpat) == !fo) print va[i]
196 IFS="$_saveifs"
197 eval "$_var="'"$*"'
198 unset _var _fo _pat _saveifs
201 # Filter the third and following argument(s) according to the space-separated
202 # list of '%' pattern(s) in the second argument and join all the results using
203 # a space and store that in the variable named by the first argument
204 v_filter() {
205 _var="$1"
206 shift
207 v_filter_ "$_var" "" "$@"
210 # Filter out the third and following argument(s) according to the space-separated
211 # list of '%' pattern(s) in the second argument and join all the results using
212 # a space and store that in the variable named by the first argument
213 v_filter_out() {
214 _var="$1"
215 shift
216 v_filter_ "$_var" "1" "$@"
219 # Write the third and following target arguments out as target with a dependency
220 # line(s) to standard output where each line is created by stripping the target
221 # argument suffix specified by the first argument ('' to strip nothing) and
222 # adding the suffix specified by the second argument ('' to add nothing).
223 # Does nothing if "$1" = "$2". (Set $1 = " " and $2 = "" to write out
224 # dependency lines with no prerequisites.)
225 write_auto_deps() {
226 [ "$1" != "$2" ] || return 0
227 _strip="$1"
228 _add="$2"
229 shift 2
230 for _targ in "$@"; do
231 printf '%s: %s\n' "$_targ" "${_targ%$_strip}$_add"
232 done
233 unset _strip _add _targ
236 # always turn on allexport now
237 set -a