3 # ref_match - TopGit awk utility script used by tg--awksome
4 # Copyright (C) 2017 Kyle J. McKay <mackyle@gmail.com>
10 # pckdrefs input refs are in packed-refs format
11 # patterns whitespace-separated for-each-ref style patterns to match
12 # matchfmt a for-each-ref format string (limited, see below)
13 # sortkey optional "[-]<key>" or "[-]<key>,[-]<key>" (see below)
14 # maxout stop after no more matches than this
16 # input is a list of "<ref> <hash>" per line (or packed-refs style if
17 # pckdrefs is true) if there are multiple entries for the same ref name
18 # only one wins (which exactly is indeterminate since the sort is unstable)
20 # hash values are always converted to lowercase
22 # output is each matching ref shown using the output matchfmt format whcih
23 # is a limited form of the for-each-ref format in that the default is similar
24 # to for-each-ref and only fields "%(refname)" and "%(objectname)" are
25 # supported along with "%%" and "%xx" EXCEPT "%00" (it will try don't expect
26 # it to work though) any other % sequence will pass through unchanged
28 # here is the actual format string (as a --format argument) used by default:
30 # --format="%(objectname) object%09%(refname)"
32 # while this is similar the for-each-ref default it uses "object" for the object
33 # type since one is not available and, in fact, %(objecttype) will indeed also
34 # be replaced with "object"
36 # output will be sorted by "refname" by default (it's always sorted somehow)
37 # and for the two-key form, the LAST key is the primary key; if the leading
38 # "-" is present it's a descending sort instead of ascending; only "objectname"
39 # and "refname" keys are supported (obviously)
41 # This one was supposed to be jast a simple quick little thing *sigh*
44 function arrayswp
(anarray
, i1
, i2
, _swapper
) {
45 _swapper = anarray
[i1
]
46 anarray
[i1
] = anarray
[i2
]
47 anarray
[i2
] = _swapper
48 if (!multisort
) return # ** cough **
50 hashes
[i1
] = hashes
[i2
]
54 function kasort_order3
(anarray
, i1
, i2
, i3
, _c12
, _c13
, _c23
) {
55 _c12 = cmpkeys
(anarray
, i1
, i2
)
56 _c23 = cmpkeys
(anarray
, i2
, i3
)
60 arrayswp
(anarray
, i1
, i3
)
63 } else if (_c23
>=
0) {
64 arrayswp
(anarray
, i1
, i3
)
67 _c13 = cmpkeys
(anarray
, i1
, i3
)
68 if (_c13
> 0) arrayswp
(anarray
, i1
, i3
)
69 if (_c12
<=
0) arrayswp
(anarray
, i2
, i3
)
70 else arrayswp
(anarray
, i1
, i2
)
73 # Could "ka" mean, oh I don't know, perhaps one of these? ;)
74 # Kyle's Awesome alternativve to the low iQ sort
78 function kasort_partition
(anarray
, si
, ei
, _mi
, _le
, _ge
) {
81 if (cmpkeys
(anarray
, si
, ei
) > 0)
82 arrayswp
(anarray
, si
, ei
)
85 _mi = int
((si
+ ei
) / 2)
86 kasort_order3
(anarray
, si
, _mi
, ei
)
87 if (si
+ 2 == ei
) return
92 while (++_le
< _ge
&& _le
!= _mi
&& cmpkeys
(anarray
, _le
, _mi
) <=
0) ;
94 while (_le
< --_ge
&& cmpkeys
(anarray
, _mi
, _ge
) <=
0) ;
95 if (_mi
<= _le
&& _le
< _ge
)
96 while (++_le
< _ge
&& cmpkeys
(anarray
, _le
, _mi
) <=
0) ;
98 arrayswp
(anarray
, _le
, _ge
)
102 arrayswp
(anarray
, _le
, _mi
)
105 arrayswp
(anarray
, _mi
, _ge
)
108 kasort_partition
(anarray
, si
, _mi
- 1)
109 kasort_partition
(anarray
, _mi
+ 1, ei
)
114 function getpatarr
(patstr
,
115 _p
, _pi
, _pc
, _sa1
, _c2
, _sa2
, _lpat
, _llen
, _i
) {
117 split(patstr
, _sa1
, " ")
121 if (_p !~
/^refs\
/.
/) continue
122 if (_p !~
/\
/$
/) _p = _p
"/"
127 kasort_partition
(_sa2
, 1, _c2
)
129 _llen =
length(_lpat
)
130 patarr
[++_pc
] = _lpat
131 for (_i =
2; _i
<= _c2
; ++_i
) {
133 if (length(_p
) >= _llen
&& _lpat ==
substr(_p
, 1, _llen
))
137 _llen =
length(_lpat
)
140 patarr
[++_pc
] =
"refs/"
142 patarr
[++_pc
] = _sa2
[1]
144 patarr
[_pc
+ 1] =
"zend"
154 patcnt = getpatarr
(patterns
)
155 for (i =
split(tolower(sortkey
), keys
, /[, \t\r\n]+/); i
>=
1; --i
) {
156 if (keys
[i
] ==
"refname") {
159 } else if (keys
[i
] ==
"-refname") {
163 if (sortobj ==
0 && keys
[i
] ==
"objectname") sortobj =
1
164 if (sortobj ==
0 && keys
[i
] ==
"-objectname") sortobj =
-1
166 if (!sortref
) sortref =
1
167 if (matchfmt ==
"") matchfmt =
"%(objectname) %(objecttype)%09%(refname)"
168 fc =
split(matchfmt
, fmts
, /%
(%
|[0-9a
-fA
-F
]{2})/)
171 fpos =
length(theformat
) + 1
172 while (fpos
<=
length(matchfmt
)) {
173 pct =
tolower(substr(matchfmt
, fpos
, 3))
174 if (substr(pct
, 1, 2) ==
"%%") {
175 theformat = theformat
"%"
178 hexval = (index("0123456789abcdef
", substr(pct, 2, 1)) - 1) * 16
179 hexval += index("0123456789abcdef
", substr(pct, 3, 1)) - 1
180 theformat = theformat sprintf("%c
", hexval)
184 theformat = theformat fmts[++fi]
185 fpos += length(fmts[fi])
190 pckdrefs && $2 ~ /^refs\/./ && $1 ~ /^[0-9A-Fa-f]{4,}$/ {
194 hashes[cnt] = tolower($1)
197 !pckdrefs && $1 ~ /^refs\/./ && $2 ~ /^[0-9A-Fa-f]{4,}$/ {
201 hashes[cnt] = tolower($2)
204 function cmpkeys(anarray, i1, i2, _k1, _k2, _ans) {
206 if (dosortobj) { # ** cough **
209 if (_k1 < _k2) _ans = -1
210 else if (_k1 > _k2) _ans = 1
211 if (sortobj < 0) _ans = 0 - _ans
216 if (_k1 < _k2) _ans = -1
217 else if (_k1 > _k2) _ans = 1
218 if (sortref < 0) _ans = 0 - _ans
223 function formatline(rname, oname, _out) {
225 gsub(/%\(objectname\)/, oname, _out)
226 gsub(/%\(objecttype\)/, "object
", _out)
227 gsub(/%\(refname\)/, rname, _out)
233 presortedbyrefonly = 0
234 if (patcnt > 1 || patarr[1] != "refs
/") {
235 savesortref = sortref
237 if (cnt > 1) kasort_partition(refs, 1, cnt)
238 presortedbyrefonly = 1
242 for (i = 1; i <= cnt; ++i) {
243 if (refs[i] == ref) {
252 if (substr(ref, 1, length(curpat)) == curpat) continue
253 while (patarr[++ji] < ref) ;
258 sortref = savesortref
261 if (cnt > 1 && (!presortedbyrefonly || sortobj || sortref < 0))
262 kasort_partition(refs, 1, cnt)
264 for (i = 1; i <= cnt; ++i) {
266 sub(/\/+$/, "", refname)
267 if (refname == "") continue
268 if (maxout > 0 && ++outcnt > maxout) exit 0
270 print formatline(refname, objname)