summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-03-07 11:25:01 -0800
committerKaz Kylheku <kaz@kylheku.com>2020-03-07 11:25:01 -0800
commitbd62b2d0a8bbdf31166f9f39f391f5e2c8e10aa1 (patch)
tree73e6f42db6de7705c8b3cd9b423cbf9cf46c1ff8
parent5241d6f7b1fe64936204d4ba26a92f3f87a2a694 (diff)
downloadtxr-bd62b2d0a8bbdf31166f9f39f391f5e2c8e10aa1.tar.gz
txr-bd62b2d0a8bbdf31166f9f39f391f5e2c8e10aa1.tar.bz2
txr-bd62b2d0a8bbdf31166f9f39f391f5e2c8e10aa1.zip
tags: add --exclude option.
* tags.tl (tags-opts): Cumulative exlude option added. (ftw-actionretval, ftw-continue, ftw-skip-subtree): These variables are missing if we are not on Glibc, so we define them as zero. These definitions help us take advantage of FTW_ACTIONRETVAL to skip recursing into exluded subtrees. (static-when): New macro. (toplevel): Implement exclude option. Skipping directories on platforms whose nftw function doesn't have FTW_ACTIONRETVAL is simulated by keeping a dynamic skip list, which is intelligently purged to keep it short.
-rwxr-xr-xtags.tl42
1 files changed, 33 insertions, 9 deletions
diff --git a/tags.tl b/tags.tl
index 075fc523..de46c5f8 100755
--- a/tags.tl
+++ b/tags.tl
@@ -3,7 +3,9 @@
(define-option-struct tags-opts nil
(nil help :bool "List this help text.")
(a append :bool "Append to existing tags file, without sorting.")
- (m merge :bool "Merge with existing tags file, sorting combined content."))
+ (m merge :bool "Merge with existing tags file, sorting combined content.")
+ (nil exclude (cumul :text) "Skip paths matching glob pattern given \ \
+ in TEXT. Multiple patterns can be specified."))
(defstruct tag ()
ident
@@ -143,6 +145,13 @@
(each ((tag tags))
(put-line tag.(text) stream))))
+(defvarl ftw-actionretval 0)
+(defvarl ftw-continue 0)
+(defvarl ftw-skip-subtree 0)
+
+(defmacro static-when (expr . body)
+ (when expr ^(progn ,*body)))
+
(let ((o (new tags-opts)))
o.(getopts *args*)
(when o.help
@@ -160,12 +169,27 @@
(put-line `@{*load-path*}: --append and --merge are mutually exclusive`)
(exit nil))
- (let ((tags (build
- (ftw o.out-args
- (lambda (path type stat . rest)
- (when (and (eql type ftw-f)
- (or (member path o.out-args)
- (ends-with ".tl" path)))
- (pend (ignerr (collect-tags path)))))
- ftw-phys))))
+ (let* ((have-arv (boundp 'ftw-actionretval))
+ (excf [apply orf (mapcar (do op fnmatch @@1 @1) o.exclude)])
+ (skips ())
+ (tags (build
+ (ftw o.out-args
+ (lambda (path type stat . rest)
+ (caseql* type
+ (ftw-f (when (and (or (member path o.out-args)
+ (ends-with ".tl" path))
+ (not [excf path])
+ (not [excf (base-name path)])
+ (not (some skips (op starts-with @1 path))))
+ (pend (ignerr (collect-tags path)))
+ ftw-continue))
+ (ftw-d (while (and skips (starts-with path (car skips)))
+ (pop skips))
+ (cond
+ ((or [excf path] [excf (base-name path)])
+ (static-when (plusp ftw-actionretval)
+ (push `@path/` skips))
+ ftw-skip-subtree)))
+ (t ftw-continue)))
+ (logior ftw-phys ftw-actionretval)))))
(write-tagfile (sort tags : .ident) o)))