Skip to content

Commit e8059fd

Browse files
committed
Sort in directory order
1 parent f52b357 commit e8059fd

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

Diff for: sort-directory-order

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env perl
2+
3+
## Sorts the input lines by directory order:
4+
## first, every file in a given directory, in sorted order
5+
## then, process subdirectories recursively, in sorted order
6+
## Example output order:
7+
## annotatenullable.txt
8+
## chicory.txt
9+
## varinfoaux.txt
10+
## varinfoname.txt
11+
## asm/asmfile.txt
12+
## asm/dsforest.txt
13+
## asm/pptfile.txt
14+
## asm/testredundantvars.txt
15+
## asm/x86instruction.txt
16+
## chicory/arrayinfo.txt
17+
## chicory/chicorypremain.txt
18+
## derive/derivation.txt
19+
## derive/derivationfactory.txt
20+
## derive/valueandmodified.txt
21+
## derive/binary/binaryderivation.txt
22+
## derive/binary/binaryderivationfactory.txt
23+
## derive/binary/sequencespredicatefactoryfloat.txt
24+
## derive/binary/sequencespredicatefloat.txt
25+
## derive/ternary/sequencefloatarbitrarysubsequence.txt
26+
## derive/ternary/sequencefloatarbitrarysubsequencefactory.txt
27+
## derive/ternary/ternaryderivation.txt
28+
## derive/ternary/ternaryderivationfactory.txt
29+
## derive/unary/sequenceinitial.txt
30+
## derive/unary/sequenceinitialfactory.txt
31+
## derive/unary/unaryderivation.txt
32+
## derive/unary/unaryderivationfactory.txt
33+
34+
## This can be used with "find" to put the results in sorted order.
35+
## (find's default order has to do with where files happen to be stored on
36+
## disk.) Sorted order may be more sensible to a user, or may make other
37+
## commands more deterministic. (But for determinism alone, you might as
38+
## well just use "sort", which is faster than this script.)
39+
##
40+
## For example, when making a TAGS file, instead of
41+
## etags `find . -iname '*.java' -print`
42+
## do
43+
## etags `find . -iname '*.java' -print | sort-directory-order`
44+
45+
## Note a directory name will appear immediately before its contents if it
46+
## ends with a slash (/), but a directory name that lacks a slash will
47+
## appear with the contents of the parent directory. If this is
48+
## undesirable, then you want to use `sort` instead of this program.
49+
50+
## Mac OS X has a "-s" option to "find" that is similar (but not
51+
## necessarily identical) to "find | sort".
52+
53+
my $debug = 0;
54+
# $debug = 1;
55+
56+
57+
my @lines = <>;
58+
my @sorted_lines = sort cmp_parents_first @lines;
59+
print @sorted_lines;
60+
exit;
61+
62+
63+
64+
65+
sub num_slashes ( $ ) {
66+
my ($tmp) = @_;
67+
return ($tmp =~ tr/\///);
68+
}
69+
70+
sub longest_common_prefix {
71+
my $prefix = shift;
72+
for (@_) {
73+
chop $prefix while (! /^\Q$prefix\E/);
74+
}
75+
return $prefix;
76+
}
77+
78+
79+
# Crazily, if the first two lines of this routine are
80+
# sub cmp_parents_first ( $$ ) {
81+
# my ($a, $b) = @_;
82+
# then it does not behave properly with sort even though it does
83+
# behave properly when called directly.
84+
# Perl's sort routine is messed up.
85+
86+
# Comparator that places entries in parent directories first.
87+
sub cmp_parents_first {
88+
if ($debug) { print "cmp_parents_first($a, $b)\n"; }
89+
90+
my $num_slashes_a = num_slashes($a);
91+
my $num_slashes_b = num_slashes($b);
92+
if ($debug) { print "slashes: $num_slashes_a $num_slashes_b\n"; }
93+
if ($num_slashes_a == $num_slashes_b) {
94+
return ($a cmp $b);
95+
}
96+
97+
my $prefix = longest_common_prefix($a, $b);
98+
my $num_slashes_prefix = num_slashes($prefix);
99+
my $num_extra_slashes_a = $num_slashes_a - $num_slashes_prefix;
100+
my $num_extra_slashes_b = $num_slashes_b - $num_slashes_prefix;
101+
if ($debug) { print "prefix ($num_slashes_prefix slashes): $prefix\n"; }
102+
if ($debug) { print "num_extra_slashes $num_extra_slashes_a $num_extra_slashes_b\n"; }
103+
104+
# If one of the directories contains all the slashes that the other does,
105+
# plus more, then the one with less slashes is a file in a parent
106+
# directory and should appear earlier in the sort order.
107+
if (($num_extra_slashes_a == 0) && ($num_extra_slashes_b != 0)) {
108+
return -1;
109+
} elsif (($num_extra_slashes_b == 0) && ($num_extra_slashes_a != 0)) {
110+
return 1;
111+
} else {
112+
return ($a cmp $b);
113+
}
114+
115+
}

0 commit comments

Comments
 (0)