line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package File::Namaste; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
59780
|
use 5.006; |
|
2
|
|
|
|
|
9
|
|
|
2
|
|
|
|
|
153
|
|
4
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
62
|
|
5
|
2
|
|
|
2
|
|
18
|
use warnings; |
|
2
|
|
|
|
|
10
|
|
|
2
|
|
|
|
|
336
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
require Exporter; |
8
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION; |
11
|
|
|
|
|
|
|
$VERSION = sprintf "%d.%02d", q$Name: Release-1-04 $ =~ /Release-(\d+)-(\d+)/; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @EXPORT = qw(); |
14
|
|
|
|
|
|
|
#our @EXPORT_OK = qw(); |
15
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
16
|
|
|
|
|
|
|
nam_get nam_add nam_elide |
17
|
|
|
|
|
|
|
); |
18
|
|
|
|
|
|
|
our %EXPORT_TAGS = (all => [ @EXPORT_OK ]); |
19
|
|
|
|
|
|
|
#our @EXPORT_OK = qw(); |
20
|
|
|
|
|
|
|
|
21
|
2
|
|
|
2
|
|
2051
|
use File::Spec::Functions; # we want catfile() |
|
2
|
|
|
|
|
1922
|
|
|
2
|
|
|
|
|
930
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Default setting for tranformations is non-portable for Unix. |
24
|
|
|
|
|
|
|
our $portable_default = grep(/Win32|OS2/i, @File::Spec::ISA); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# Instead of "use File::Value;" for a small dependency, use this |
27
|
|
|
|
|
|
|
# abbreviated version of "raw" File::Value::file_value() (that we |
28
|
|
|
|
|
|
|
# also use commonly in test scripts). |
29
|
|
|
|
|
|
|
# |
30
|
11
|
|
|
11
|
0
|
17
|
sub filval { my( $file, $value )=@_; # $file must begin with >, <, or >> |
31
|
11
|
100
|
|
|
|
45
|
if ($file =~ /^\s*>>?/) { |
32
|
3
|
50
|
|
|
|
242
|
open(OUT, $file) or return "$file: $!"; |
33
|
3
|
|
|
|
|
25
|
my $r = print OUT $value; |
34
|
3
|
50
|
|
|
|
143
|
close(OUT); return ($r ? '' : "write failed: $!"); |
|
3
|
|
|
|
|
28
|
|
35
|
|
|
|
|
|
|
} # If we get here, we're doing file-to-value case. |
36
|
8
|
50
|
|
|
|
241
|
open(IN, $file) or return "$file: $!"; |
37
|
8
|
|
|
|
|
29
|
local $/; $_[1] = ; # slurp mode (entire file) |
|
8
|
|
|
|
|
139
|
|
38
|
8
|
|
|
|
|
77
|
close(IN); return ''; |
|
8
|
|
|
|
|
29
|
|
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# xxx not yet doing unicode or i18n |
42
|
|
|
|
|
|
|
# only first arg required |
43
|
|
|
|
|
|
|
# return tvalue given fvalue |
44
|
3
|
|
|
3
|
0
|
7
|
sub nam_tvalue { my( $fvalue, $portable, $max, $ellipsis )=@_; |
45
|
|
|
|
|
|
|
|
46
|
3
|
50
|
|
|
|
10
|
defined($portable) or $portable = $portable_default; |
47
|
3
|
|
|
|
|
6
|
my $tvalue = $fvalue; |
48
|
3
|
|
|
|
|
10
|
$tvalue =~ s,/,=,g; |
49
|
3
|
|
|
|
|
12
|
$tvalue =~ s,\s+, ,g; |
50
|
2
|
|
|
2
|
|
8860
|
$tvalue =~ s,\p{IsC},?,g; # control characters |
|
2
|
|
|
|
|
27
|
|
|
2
|
|
|
|
|
34
|
|
|
3
|
|
|
|
|
7
|
|
51
|
|
|
|
|
|
|
|
52
|
3
|
50
|
|
|
|
9
|
$portable and # more portable (Win32) mapping |
53
|
|
|
|
|
|
|
$tvalue =~ tr {"*/:<>?|\\}{.}; |
54
|
|
|
|
|
|
|
|
55
|
3
|
|
|
|
|
10
|
return nam_elide($tvalue, $max, $ellipsis); |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# Ordered list of labels, mostly kernel element names |
59
|
|
|
|
|
|
|
# yyy should this be coming from ERC module, or is that creating |
60
|
|
|
|
|
|
|
# a big dependency hurdle for a sliver of functionality? |
61
|
|
|
|
|
|
|
our @namaste_labels = qw( |
62
|
|
|
|
|
|
|
dir_type |
63
|
|
|
|
|
|
|
who |
64
|
|
|
|
|
|
|
what |
65
|
|
|
|
|
|
|
when |
66
|
|
|
|
|
|
|
where |
67
|
|
|
|
|
|
|
how |
68
|
|
|
|
|
|
|
why |
69
|
|
|
|
|
|
|
huh |
70
|
|
|
|
|
|
|
); |
71
|
|
|
|
|
|
|
|
72
|
0
|
|
|
0
|
0
|
0
|
sub num2label { my $num = shift; |
73
|
|
|
|
|
|
|
|
74
|
0
|
|
|
|
|
0
|
my $last = $#namaste_labels; |
75
|
0
|
|
|
|
|
0
|
$num =~ s/^(\d+).*/$1/; # forgive, eg, 3=foo |
76
|
0
|
0
|
0
|
|
|
0
|
$num =~ /\D/ || $num < 0 || $num > $last and |
|
|
|
0
|
|
|
|
|
77
|
|
|
|
|
|
|
return $namaste_labels[$last]; # last label |
78
|
|
|
|
|
|
|
# last label doubles as unknown (huh?) if number is bad |
79
|
0
|
|
|
|
|
0
|
return $namaste_labels[$num]; # normal return |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# xxx should create shadow tag files with highly deterministic names? |
84
|
|
|
|
|
|
|
# easier for a machine to fine a specific element |
85
|
|
|
|
|
|
|
my $dtname = ".dir_type"; # canonical name of directory type file |
86
|
|
|
|
|
|
|
# xxx .=dir_type |
87
|
|
|
|
|
|
|
# xxx .=how |
88
|
|
|
|
|
|
|
# xxx .=huh |
89
|
|
|
|
|
|
|
# xxx .=what |
90
|
|
|
|
|
|
|
# xxx .=when |
91
|
|
|
|
|
|
|
# xxx .=where |
92
|
|
|
|
|
|
|
# xxx .=who |
93
|
|
|
|
|
|
|
# xxx .=why |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# xxx to do |
96
|
|
|
|
|
|
|
# N means create N=... |
97
|
|
|
|
|
|
|
# .N means create or add to .=wh{o,at,en,ere} |
98
|
|
|
|
|
|
|
# N. means do both N and .N |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# $num and $fvalue required |
101
|
|
|
|
|
|
|
# returns empty string on success, otherwise a diagnostic |
102
|
3
|
|
|
3
|
0
|
4936
|
sub nam_add { my( $dir, $portable, $num, $fvalue, $max, $ellipsis )=@_; |
103
|
|
|
|
|
|
|
|
104
|
3
|
50
|
33
|
|
|
18
|
return 0 |
105
|
|
|
|
|
|
|
if (! defined($num) || ! defined($fvalue)); |
106
|
|
|
|
|
|
|
|
107
|
3
|
|
50
|
|
|
14
|
$dir ||= ""; |
108
|
|
|
|
|
|
|
#$dir = catfile($dir, "") # add portable separator |
109
|
|
|
|
|
|
|
# if $dir; # (eg, slash) if there's a dir name |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
#my $fname = $dir . $dtname; # path to .dir_type, if needed |
112
|
3
|
|
|
|
|
85
|
my $fname = catfile($dir, $dtname); # path to .dir_type, if needed |
113
|
3
|
|
|
|
|
12
|
my $tvalue = nam_tvalue($fvalue, $portable, $max, $ellipsis); |
114
|
|
|
|
|
|
|
# ".0" means set .dir_type also; "." means only set .dir_type |
115
|
3
|
50
|
33
|
|
|
21
|
if ($num =~ s/^\.0/0/ || $num eq ".") { |
116
|
|
|
|
|
|
|
# "append only" supports multi-typing in .dir_type, so |
117
|
|
|
|
|
|
|
# caller must remove .dir_type to re-set (see "nam" script) |
118
|
|
|
|
|
|
|
# right now $fname contains catfile($dir, $dtname) |
119
|
0
|
|
|
|
|
0
|
my $ret = filval(">>$fname", $fvalue); |
120
|
0
|
0
|
0
|
|
|
0
|
return $ret # return if error or only .dir_type |
121
|
|
|
|
|
|
|
if $ret || $num eq "."; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
#$fname = "$dir$num=$tvalue"; |
125
|
3
|
|
|
|
|
19
|
$fname = catfile($dir, "$num=$tvalue"); |
126
|
|
|
|
|
|
|
#nam_tvalue($fvalue, $portable, $max, $ellipsis); |
127
|
|
|
|
|
|
|
# why is this sometimes null? |
128
|
|
|
|
|
|
|
|
129
|
3
|
|
|
|
|
15
|
return filval(">$fname", $fvalue); |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
2
|
|
|
2
|
|
53858
|
use File::Glob ':glob'; # standard use of module, which we need |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
8439
|
|
133
|
|
|
|
|
|
|
# as vanilla glob won't match whitespace |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# first arg is directory, remaining args give numbers to fetch; |
136
|
|
|
|
|
|
|
# no args means return all |
137
|
|
|
|
|
|
|
# args can be file globs |
138
|
|
|
|
|
|
|
# returns array of number/fname/value triples (every third elem is number) |
139
|
|
|
|
|
|
|
sub nam_get { |
140
|
|
|
|
|
|
|
|
141
|
5
|
|
|
5
|
0
|
2468
|
my $dir = shift @_; |
142
|
|
|
|
|
|
|
|
143
|
5
|
|
50
|
|
|
16
|
$dir ||= ""; |
144
|
|
|
|
|
|
|
#$dir = catfile($dir, "") # add portable separator |
145
|
|
|
|
|
|
|
# if $dir; # (eg, slash) if there's a dir name |
146
|
|
|
|
|
|
|
#my $dir_type = $dir . $dtname; # path to .dir_type, if needed |
147
|
5
|
|
|
|
|
28
|
my $dir_type = catfile($dir, $dtname); # path to .dir_type, if needed |
148
|
|
|
|
|
|
|
|
149
|
5
|
|
|
|
|
9
|
my (@in, @out); |
150
|
5
|
100
|
|
|
|
13
|
if ($#_ < 0) { # if no args, get all files starting |
151
|
|
|
|
|
|
|
# Surprisingly, with bsd_glob a / separator works in Win32 |
152
|
3
|
|
|
|
|
288
|
@in = bsd_glob("$dir/[0-9]=*"); # so no need for catfile() |
153
|
|
|
|
|
|
|
# @in = bsd_glob(catfile($dir, '[0-9]=*')); # "=..." |
154
|
3
|
50
|
|
|
|
41
|
-e $dir_type and # since we're getting all, |
155
|
|
|
|
|
|
|
unshift @in, $dir_type; # if it exists, add .dir_type |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
else { # else do globs for each arg |
158
|
2
|
|
|
|
|
9
|
while (defined(my $n = shift @_)) { # next number |
159
|
2
|
50
|
33
|
|
|
19
|
if (($n =~ s/^\.0/0/ || $n eq ".") && -e $dir_type) { |
|
|
|
33
|
|
|
|
|
160
|
|
|
|
|
|
|
# if requested and it exists, add .dir_type |
161
|
0
|
|
|
|
|
0
|
push @in, $dir_type; |
162
|
|
|
|
|
|
|
next # next if only .dir_type |
163
|
0
|
0
|
|
|
|
0
|
if $n eq "."; |
164
|
|
|
|
|
|
|
} |
165
|
2
|
|
|
|
|
131
|
push @in, bsd_glob("$dir/$n=*"); |
166
|
|
|
|
|
|
|
#push @in, bsd_glob(catfile($dir, $n . '=*')); |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
# Now create the output array. |
170
|
5
|
|
|
|
|
8
|
my ($number, $fname, $fvalue, $status, $regex); |
171
|
5
|
|
|
|
|
17
|
while (defined($fname = shift(@in))) { |
172
|
|
|
|
|
|
|
|
173
|
8
|
|
|
|
|
25
|
$status = filval("<$fname", $fvalue); |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
#($number) = ($fname =~ m{^$dir(\d*)=}); |
176
|
|
|
|
|
|
|
#$regex = catfile($dir, '(\d*)='); |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# # ask for a dummy file 'x' in order to get a dir separator |
179
|
|
|
|
|
|
|
# # |
180
|
|
|
|
|
|
|
# $regex = catfile($dir, 'x'); # separator might be \ or / |
181
|
|
|
|
|
|
|
# temporary crap to flush out bug in Windows version |
182
|
|
|
|
|
|
|
#$regex =~ s,/,\\,g; |
183
|
|
|
|
|
|
|
#$fname =~ s,/,\\,g; |
184
|
|
|
|
|
|
|
# $regex =~ s/\\/\\\\/g; # preserve any \ separators for regex |
185
|
|
|
|
|
|
|
# |
186
|
|
|
|
|
|
|
# # replace dummy file with pattern we want, leaving separator |
187
|
|
|
|
|
|
|
# # |
188
|
|
|
|
|
|
|
# $regex =~ s/x$/(\\d*)=/; # replace with literal pattern |
189
|
|
|
|
|
|
|
#print "xxx regex=$regex\n"; |
190
|
|
|
|
|
|
|
# ($number) = ($fname =~ m{^$regex}); |
191
|
|
|
|
|
|
|
#print "xxx number=$number, fname=$fname\n"; |
192
|
8
|
|
|
|
|
70
|
($number) = ($fname =~ m{^$dir/(\d*)=}); |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# if there's no number matched, it may be for .dir_type, |
195
|
|
|
|
|
|
|
# in which case use "." for number, else give up with "" |
196
|
|
|
|
|
|
|
# |
197
|
|
|
|
|
|
|
# $regex = catfile($dir, $dtname); |
198
|
|
|
|
|
|
|
#$regex =~ s,/,\\,g; |
199
|
|
|
|
|
|
|
# $regex =~ s/\\/\\\\/g; # preserve any \ separators for regex |
200
|
|
|
|
|
|
|
#print "xxx dtname=$dtname, regex=$regex\n"; |
201
|
|
|
|
|
|
|
#$number = ($fname =~ m{^$dir$dtname} ? "." : "") |
202
|
|
|
|
|
|
|
# yyy matching on $dtname is imperfect if it contains |
203
|
|
|
|
|
|
|
# a '.' -- eg, ".dir_type" matches "adir_type" |
204
|
|
|
|
|
|
|
# contains a |
205
|
|
|
|
|
|
|
#$number = ($fname =~ m{^$regex} ? "." : "") |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# \Q prevents chars in $dtname (eg, '.') being used in regex |
208
|
8
|
0
|
|
|
|
21
|
$number = ($fname =~ m{^$dir/\Q$dtname\E} ? "." : "") |
|
|
50
|
|
|
|
|
|
209
|
|
|
|
|
|
|
if (! defined($number)); |
210
|
|
|
|
|
|
|
|
211
|
8
|
50
|
|
|
|
48
|
push @out, $number, $fname, ($status ? $status : $fvalue); |
212
|
|
|
|
|
|
|
} |
213
|
5
|
|
|
|
|
35
|
return @out; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# xxx unicode friendly?? |
217
|
|
|
|
|
|
|
our $max_default = 16; # is there some sense to this? xxx use |
218
|
|
|
|
|
|
|
# fraction of display width maybe? |
219
|
|
|
|
|
|
|
|
220
|
13
|
|
|
13
|
1
|
4760
|
sub nam_elide { my( $s, $max, $ellipsis )=@_; |
221
|
|
|
|
|
|
|
|
222
|
13
|
50
|
|
|
|
33
|
$s or return undef; |
223
|
|
|
|
|
|
|
# $max can be zero (0) so that nam_add() can ask for no elision. |
224
|
13
|
100
|
|
|
|
32
|
defined($max) or $max = $max_default; |
225
|
13
|
50
|
|
|
|
80
|
$max !~ /^(\d+)([esmESM]*)([+-]\d+%?)?$/ and |
226
|
|
|
|
|
|
|
return undef; |
227
|
13
|
|
|
|
|
41
|
my ($maxlen, $where, $tweak) = ($1, $2, $3); |
228
|
|
|
|
|
|
|
|
229
|
13
|
|
100
|
|
|
45
|
$where ||= "e"; |
230
|
13
|
|
|
|
|
24
|
$where = lc($where); |
231
|
|
|
|
|
|
|
|
232
|
13
|
100
|
66
|
|
|
54
|
$ellipsis ||= ($where eq "m" ? "..." : ".."); |
233
|
13
|
|
|
|
|
19
|
my $elen = length($ellipsis); |
234
|
|
|
|
|
|
|
|
235
|
13
|
|
|
|
|
16
|
my ($side, $offset, $percent); # xxx only used for "m"? |
236
|
13
|
100
|
|
|
|
33
|
if (defined($tweak)) { |
237
|
1
|
|
|
|
|
7
|
($side, $offset, $percent) = ($tweak =~ /^([+-])(\d+)(%?)$/); |
238
|
|
|
|
|
|
|
} |
239
|
13
|
|
100
|
|
|
44
|
$side ||= ""; $offset ||= 0; $percent ||= ""; |
|
13
|
|
100
|
|
|
44
|
|
|
13
|
|
100
|
|
|
42
|
|
240
|
|
|
|
|
|
|
# XXXXX finish this! print "side=$side, n=$offset, p=$percent\n"; |
241
|
|
|
|
|
|
|
|
242
|
13
|
|
|
|
|
23
|
my $slen = length($s); |
243
|
13
|
100
|
66
|
|
|
97
|
return $s |
244
|
|
|
|
|
|
|
if ($slen <= $maxlen || $maxlen == 0); # doesn't need elision |
245
|
|
|
|
|
|
|
|
246
|
10
|
|
|
|
|
14
|
my $re; # we will create a regex to edit the string |
247
|
|
|
|
|
|
|
# length of orig string after that will be left after edit |
248
|
10
|
|
|
|
|
12
|
my $left = $maxlen - $elen; |
249
|
|
|
|
|
|
|
|
250
|
10
|
|
|
|
|
15
|
my $retval = $s; |
251
|
|
|
|
|
|
|
# Example: if $left is 5, then |
252
|
|
|
|
|
|
|
# if "e" then s/^(.....).*$/$1$ellipsis/ |
253
|
|
|
|
|
|
|
# if "s" then s/^.*(.....)$/$ellipsis$1/ |
254
|
|
|
|
|
|
|
# if "m" then s/^.*(...).*(..)$/$1$ellipsis$2/ |
255
|
|
|
|
|
|
|
# In order to make '.' match \n, we use s///s ('s' modifier). |
256
|
10
|
100
|
|
|
|
21
|
if ($where eq "m") { |
257
|
|
|
|
|
|
|
# if middle, we split the string |
258
|
4
|
|
|
|
|
10
|
my $half = int($left / 2); |
259
|
4
|
50
|
|
|
|
11
|
$half += 1 # bias larger half to front if $left is odd |
260
|
|
|
|
|
|
|
if ($half > $left - $half); # xxx test |
261
|
4
|
|
|
|
|
16
|
$re = "^(" . ("." x $half) . ").*(" |
262
|
|
|
|
|
|
|
. ("." x ($left - $half)) . ")\$"; |
263
|
|
|
|
|
|
|
# $left - $half might be zero, but this still works |
264
|
4
|
|
|
|
|
84
|
$retval =~ s/$re/$1$ellipsis$2/s; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
else { |
267
|
6
|
|
|
|
|
14
|
my $dots = "." x $left; |
268
|
6
|
100
|
|
|
|
21
|
$re = ($where eq "e" ? "^($dots).*\$" : "^.*($dots)\$"); |
269
|
6
|
100
|
|
|
|
12
|
if ($where eq "e") { |
270
|
4
|
|
|
|
|
76
|
$retval =~ s/$re/$1$ellipsis/s; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
else { # else "s" |
273
|
2
|
|
|
|
|
39
|
$retval =~ s/$re/$ellipsis$1/s; |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
} |
276
|
10
|
|
|
|
|
58
|
return $retval; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
1; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
__END__ |