3 # ref_prefixes - TopGit awk utility script used by tg--awksome
4 # Copyright (C) 2017,2019,2021 Kyle J. McKay <mackyle@gmail.com>
10 # pckdrefs input refs are in packed-refs format (instead of just full ref name)
11 # prefix1 first ref prefix to look for and the default
12 # prefix2 second ref prefix to look for
13 # prefixh ignore prefix1/prefix2 matches without corresponding prefixh
14 # noerr instead of error 65 (EX_DATAERR) output default (prefix1) when both
15 # nodef instead of defaulting to prefix1, exit with error 66 (EX_NOINPUT)
17 # input is a list of full ref names one per line; if pckdrefs is true then the
18 # second field of the line will be used otherwise the first
20 # prefix1 may not be a prefix of prefix2 or vice versa
21 # if prefix1, prefix2 and/or prefixh are invalid exit status will be 2
23 # if prefixh is non-empty then matches for prefix1 or prefix2 must also match
24 # another line from the input after replacing the prefix1/prefix2 part with
25 # prefixh or they are discarded and do not participate in choosing the output
27 # note that the input need not be sorted in any particular order or be
28 # duplicate free even when prefixh is non-empty
30 # a prefix will only match at a "/" boundary
32 # ontput according to this table:
34 # any refs match any refs match noerr nodef exit output
35 # prefix1 prefix prefix2 prefix value value status value
36 # -------------- -------------- ----- ------ ------ -------
37 # no no any false 0 prefix1
39 # yes no any any 0 prefix1
40 # no yes any any 0 prefix2
41 # yes yes false any 65
42 # yes yes true any 0 prefix1
44 # there is no output when exit status is not 0
45 # the output value, if any, will have any trailing slash(es) removed from it
48 BEGIN { exitcode =
"" }
49 function exitnow
(e
) { exitcode=e
; exit e
}
50 END { if (exitcode
!= "") exit exitcode
}
53 sub(/\
/+$
/, "", prefix1
)
54 sub(/\
/+$
/, "", prefix2
)
55 sub(/\
/+$
/, "", prefixh
)
56 if (prefix1 ==
"" || prefix2 ==
"" ||
58 prefix1 == prefixh
|| prefix2 == prefixh
)
60 if (substr(prefix1
, 1, 5) != "refs/" ||
61 substr(prefix2
, 1, 5) != "refs/" ||
62 (prefixh
!= "" && substr(prefixh
, 1, 5) != "refs/"))
64 plen1 =
length(prefix1
)
65 plen2 =
length(prefix2
)
66 plenh =
length(prefixh
)
67 if (plen1
< 6 || plen2
< 6) exitnow
(2)
76 if (plen1
< plen2
&& plen1 ==
substr(plen2
, 1, plen1
)) exitnow
(2)
77 if (plen1
> plen2
&& substr(plen1
, 1, plen2
) == plen2
) exitnow
(2)
84 if (length(r
) > plen1
&& prefix1 ==
substr(r
, 1, plen1
)) {
85 if (prefixh
&& !
(substr(r
, plen1
) in heads
)) return 0
87 } else if (length(r
) > plen2
&& prefix2 ==
substr(r
, 1, plen2
)) {
88 if (prefixh
&& !
(substr(r
, plen2
) in heads
)) return 0
91 if (sawp1
&& sawp2
) return 1
96 if (pckdrefs
) ref = $
2
99 if (length(ref
) < 6 || substr(ref
, 1, 5) != "refs/") next
102 if (length(ref
) > plenh
&& prefixh ==
substr(ref
, 1, plenh
))
103 heads
[substr(ref
, plenh
)] =
1
110 for (i =
1; i
<= cnt
&& !check
(refs
[i
]); ++i
) ;
111 if (!noerr
&& sawp1
&& sawp2
) exit 65
112 if (!sawp1
&& !sawp2
&& nodef
) exit 66
114 print substr(prefix1
, 1, plen1
- 1)
116 print substr(prefix2
, 1, plen2
- 1)