tb 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +62 -50
- data/bin/tb +22 -18
- data/lib/tb.rb +35 -19
- data/lib/tb/basic.rb +85 -86
- data/lib/tb/catreader.rb +33 -116
- data/lib/tb/cmd_cat.rb +31 -27
- data/lib/tb/cmd_consecutive.rb +45 -35
- data/lib/tb/cmd_crop.rb +86 -52
- data/lib/tb/cmd_cross.rb +113 -71
- data/lib/tb/cmd_cut.rb +49 -44
- data/lib/tb/cmd_git_log.rb +193 -0
- data/lib/tb/cmd_grep.rb +43 -32
- data/lib/tb/cmd_group.rb +63 -39
- data/lib/tb/cmd_gsub.rb +53 -43
- data/lib/tb/cmd_help.rb +51 -24
- data/lib/tb/cmd_join.rb +32 -35
- data/lib/tb/cmd_ls.rb +233 -205
- data/lib/tb/cmd_mheader.rb +47 -37
- data/lib/tb/cmd_nest.rb +94 -0
- data/lib/tb/cmd_newfield.rb +29 -33
- data/lib/tb/cmd_rename.rb +40 -32
- data/lib/tb/cmd_shape.rb +31 -24
- data/lib/tb/cmd_sort.rb +46 -25
- data/lib/tb/cmd_svn_log.rb +47 -28
- data/lib/tb/cmd_tar_tvf.rb +447 -0
- data/lib/tb/cmd_to_csv.rb +60 -0
- data/lib/tb/cmd_to_json.rb +60 -0
- data/lib/tb/cmd_to_pnm.rb +48 -0
- data/lib/tb/cmd_to_pp.rb +71 -0
- data/lib/tb/cmd_to_tsv.rb +48 -0
- data/lib/tb/cmd_to_yaml.rb +52 -0
- data/lib/tb/cmd_unnest.rb +118 -0
- data/lib/tb/cmdmain.rb +24 -20
- data/lib/tb/cmdtop.rb +33 -25
- data/lib/tb/cmdutil.rb +26 -66
- data/lib/tb/csv.rb +46 -34
- data/lib/tb/enum.rb +294 -0
- data/lib/tb/enumerable.rb +198 -7
- data/lib/tb/enumerator.rb +73 -0
- data/lib/tb/fieldset.rb +27 -19
- data/lib/tb/fileenumerator.rb +365 -0
- data/lib/tb/json.rb +50 -0
- data/lib/tb/pager.rb +6 -6
- data/lib/tb/pairs.rb +227 -0
- data/lib/tb/pnm.rb +23 -22
- data/lib/tb/reader.rb +52 -49
- data/lib/tb/record.rb +48 -19
- data/lib/tb/revcmp.rb +38 -0
- data/lib/tb/ropen.rb +74 -57
- data/lib/tb/search.rb +25 -21
- data/lib/tb/tsv.rb +31 -34
- data/sample/excel2csv +24 -20
- data/sample/poi-xls2csv.rb +24 -20
- data/sample/poi-xls2csv.sh +22 -18
- data/sample/tbplot +185 -127
- data/test-all-cov.rb +3 -3
- data/test-all.rb +1 -1
- data/test/test_basic.rb +26 -10
- data/test/test_catreader.rb +7 -6
- data/test/test_cmd_cat.rb +32 -0
- data/test/test_cmd_consecutive.rb +10 -0
- data/test/test_cmd_crop.rb +4 -4
- data/test/test_cmd_cross.rb +16 -4
- data/test/test_cmd_git_log.rb +46 -0
- data/test/test_cmd_help.rb +17 -12
- data/test/test_cmd_join.rb +21 -1
- data/test/test_cmd_ls.rb +3 -4
- data/test/test_cmd_mheader.rb +17 -11
- data/test/test_cmd_nest.rb +49 -0
- data/test/test_cmd_sort.rb +15 -0
- data/test/test_cmd_tar_tvf.rb +281 -0
- data/test/{test_cmd_csv.rb → test_cmd_to_csv.rb} +35 -21
- data/test/{test_cmd_json.rb → test_cmd_to_json.rb} +31 -3
- data/test/{test_cmd_pnm.rb → test_cmd_to_pnm.rb} +2 -2
- data/test/{test_cmd_pp.rb → test_cmd_to_pp.rb} +4 -4
- data/test/{test_cmd_tsv.rb → test_cmd_to_tsv.rb} +4 -4
- data/test/{test_cmd_yaml.rb → test_cmd_to_yaml.rb} +3 -3
- data/test/test_cmd_unnest.rb +89 -0
- data/test/test_cmdtty.rb +19 -13
- data/test/test_enumerable.rb +83 -1
- data/test/test_fileenumerator.rb +265 -0
- data/test/test_json.rb +15 -0
- data/test/test_pager.rb +3 -4
- data/test/test_pairs.rb +122 -0
- data/test/test_pnm.rb +24 -24
- data/test/test_reader.rb +35 -13
- data/test/test_revcmp.rb +10 -0
- data/test/test_tbenum.rb +173 -0
- metadata +51 -23
- data/lib/tb/cmd_csv.rb +0 -42
- data/lib/tb/cmd_json.rb +0 -60
- data/lib/tb/cmd_pnm.rb +0 -43
- data/lib/tb/cmd_pp.rb +0 -70
- data/lib/tb/cmd_tsv.rb +0 -43
- data/lib/tb/cmd_yaml.rb +0 -47
data/lib/tb/cmd_join.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
-
# Copyright (C) 2011 Tanaka Akira <akr@fsij.org>
|
1
|
+
# Copyright (C) 2011-2012 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
|
-
# modification, are permitted provided that the following conditions
|
4
|
+
# modification, are permitted provided that the following conditions
|
5
|
+
# are met:
|
5
6
|
#
|
6
|
-
# 1. Redistributions of source code must retain the above copyright
|
7
|
-
# list of conditions and the following disclaimer.
|
8
|
-
# 2. Redistributions in binary form must reproduce the above
|
9
|
-
# this list of conditions and the following
|
10
|
-
# and/or other materials provided
|
11
|
-
#
|
12
|
-
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above
|
10
|
+
# copyright notice, this list of conditions and the following
|
11
|
+
# disclaimer in the documentation and/or other materials provided
|
12
|
+
# with the distribution.
|
13
|
+
# 3. The name of the author may not be used to endorse or promote
|
14
|
+
# products derived from this software without specific prior
|
15
|
+
# written permission.
|
13
16
|
#
|
14
|
-
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
15
|
-
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
16
|
-
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
-
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# IN
|
23
|
-
# OF
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
18
|
+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
21
|
+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
23
|
+
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
25
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
26
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
27
|
+
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
28
|
|
25
29
|
Tb::Cmd.subcommands << 'join'
|
26
30
|
|
@@ -30,7 +34,8 @@ Tb::Cmd.default_option[:opt_join_retain_right] = nil
|
|
30
34
|
|
31
35
|
def (Tb::Cmd).op_join
|
32
36
|
op = OptionParser.new
|
33
|
-
op.banner =
|
37
|
+
op.banner = "Usage: tb join [OPTS] [TABLE1 TABLE2 ...]\n" +
|
38
|
+
"Concatenate tables horizontally as left/right/full natural join."
|
34
39
|
define_common_option(op, 'hNod', '--no-pager', '--debug')
|
35
40
|
op.def_option('--outer', 'outer join') {
|
36
41
|
Tb::Cmd.opt_join_retain_left = true
|
@@ -60,22 +65,14 @@ def (Tb::Cmd).main_join(argv)
|
|
60
65
|
retain_left = Tb::Cmd.opt_join_retain_left
|
61
66
|
retain_right = Tb::Cmd.opt_join_retain_right
|
62
67
|
err('two tables required at least.') if argv.length < 2
|
63
|
-
result =
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
}
|
70
|
-
else
|
71
|
-
argv.each {|filename|
|
72
|
-
tbl = load_table(filename)
|
73
|
-
STDERR.puts "shared keys: #{(result.list_fields & tbl.list_fields).inspect}" if 1 <= Tb::Cmd.opt_debug
|
74
|
-
result = result.natjoin2(tbl)
|
75
|
-
}
|
76
|
-
end
|
68
|
+
result = tablereader_open(argv.shift)
|
69
|
+
argv.each {|filename|
|
70
|
+
tbl = tablereader_open(filename)
|
71
|
+
$stderr.puts "shared keys: #{(result.list_fields & tbl.list_fields).inspect}" if 1 <= Tb::Cmd.opt_debug
|
72
|
+
result = result.natjoin2_outer(tbl, Tb::Cmd.opt_join_outer_missing, retain_left, retain_right)
|
73
|
+
}
|
77
74
|
with_output {|out|
|
78
|
-
|
75
|
+
result.write_to_csv(out, !Tb::Cmd.opt_N)
|
79
76
|
}
|
80
77
|
end
|
81
78
|
|
data/lib/tb/cmd_ls.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
-
# Copyright (C) 2011 Tanaka Akira <akr@fsij.org>
|
1
|
+
# Copyright (C) 2011-2012 Tanaka Akira <akr@fsij.org>
|
2
2
|
#
|
3
3
|
# Redistribution and use in source and binary forms, with or without
|
4
|
-
# modification, are permitted provided that the following conditions
|
4
|
+
# modification, are permitted provided that the following conditions
|
5
|
+
# are met:
|
5
6
|
#
|
6
|
-
# 1. Redistributions of source code must retain the above copyright
|
7
|
-
# list of conditions and the following disclaimer.
|
8
|
-
# 2. Redistributions in binary form must reproduce the above
|
9
|
-
# this list of conditions and the following
|
10
|
-
# and/or other materials provided
|
11
|
-
#
|
12
|
-
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above
|
10
|
+
# copyright notice, this list of conditions and the following
|
11
|
+
# disclaimer in the documentation and/or other materials provided
|
12
|
+
# with the distribution.
|
13
|
+
# 3. The name of the author may not be used to endorse or promote
|
14
|
+
# products derived from this software without specific prior
|
15
|
+
# written permission.
|
13
16
|
#
|
14
|
-
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
15
|
-
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
16
|
-
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
-
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# IN
|
23
|
-
# OF
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
18
|
+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
21
|
+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
23
|
+
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
25
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
26
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
27
|
+
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
28
|
|
25
29
|
Tb::Cmd.subcommands << 'ls'
|
26
30
|
|
@@ -31,7 +35,8 @@ Tb::Cmd.default_option[:opt_ls_R] = nil
|
|
31
35
|
|
32
36
|
def (Tb::Cmd).op_ls
|
33
37
|
op = OptionParser.new
|
34
|
-
op.banner =
|
38
|
+
op.banner = "Usage: tb ls [OPTS] [FILE ...]\n" +
|
39
|
+
"List directory entries as a table."
|
35
40
|
define_common_option(op, "hNo", "--no-pager")
|
36
41
|
op.def_option('-a', 'don\'t ignore filenames beginning with a period.') {|fs| Tb::Cmd.opt_ls_a = true }
|
37
42
|
op.def_option('-A', 'don\'t ignore filenames beginning with a period, except "." and "..".') {|fs| Tb::Cmd.opt_ls_A = true }
|
@@ -44,230 +49,253 @@ def (Tb::Cmd).main_ls(argv)
|
|
44
49
|
op_ls.parse!(argv)
|
45
50
|
exit_if_help('ls')
|
46
51
|
argv = ['.'] if argv.empty?
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
opts = {
|
53
|
+
:a => Tb::Cmd.opt_ls_a,
|
54
|
+
:A => Tb::Cmd.opt_ls_A,
|
55
|
+
:l => Tb::Cmd.opt_ls_l,
|
56
|
+
:R => Tb::Cmd.opt_ls_R,
|
57
|
+
}
|
58
|
+
ls = nil
|
59
|
+
er = Tb::Enumerator.new {|y|
|
60
|
+
ls = Tb::Cmd::Ls.new(y, opts)
|
61
|
+
ls.set_header
|
54
62
|
argv.each {|arg|
|
55
|
-
ls_run(
|
63
|
+
ls.ls_run(Pathname(ls.real_pathname_string(arg)))
|
56
64
|
}
|
57
65
|
}
|
58
|
-
|
66
|
+
with_output {|out|
|
67
|
+
er.write_to_csv(out, !Tb::Cmd.opt_N)
|
68
|
+
}
|
69
|
+
if ls.fail
|
59
70
|
exit false
|
60
71
|
end
|
61
72
|
end
|
62
73
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
else
|
69
|
-
ls_file(gen, path, st)
|
74
|
+
class Tb::Cmd::Ls
|
75
|
+
def initialize(y, opts)
|
76
|
+
@y = y
|
77
|
+
@opts = opts
|
78
|
+
@fail = false
|
70
79
|
end
|
71
|
-
|
80
|
+
attr_reader :fail
|
72
81
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
return
|
82
|
+
def set_header
|
83
|
+
if @opts[:l] == 0
|
84
|
+
@y.set_header ['filename']
|
85
|
+
else
|
86
|
+
@y.set_header(ls_long_header())
|
87
|
+
end
|
80
88
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
if Tb::Cmd.opt_ls_A
|
88
|
-
entries = entries1 + entries2
|
89
|
+
|
90
|
+
def ls_run(path)
|
91
|
+
st = ls_get_stat(path)
|
92
|
+
return if !st
|
93
|
+
if st.directory?
|
94
|
+
ls_dir(path, st)
|
89
95
|
else
|
90
|
-
|
96
|
+
ls_file(path, st)
|
91
97
|
end
|
92
|
-
else
|
93
|
-
entries.reject! {|filename| /\A\./ =~ filename }
|
94
98
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
99
|
+
|
100
|
+
def ls_dir(dir, st)
|
101
|
+
begin
|
102
|
+
entries = Dir.entries(dir)
|
103
|
+
rescue SystemCallError
|
104
|
+
@fail = true
|
105
|
+
warn "tb: #{$!}: #{dir}"
|
106
|
+
return
|
107
|
+
end
|
108
|
+
entries.map! {|filename| real_pathname_string(filename) }
|
109
|
+
entries = entries.sort_by {|filename| smart_cmp_value(filename) }
|
110
|
+
if @opts[:a] || @opts[:A]
|
111
|
+
entries1, entries2 = entries.partition {|filename| /\A\./ =~ filename }
|
112
|
+
entries0, entries1 = entries1.partition {|filename| filename == '.' || filename == '..' }
|
113
|
+
entries0.sort!
|
114
|
+
if @opts[:A]
|
115
|
+
entries = entries1 + entries2
|
112
116
|
else
|
113
|
-
|
117
|
+
entries = entries0 + entries1 + entries2
|
114
118
|
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
119
|
+
else
|
120
|
+
entries.reject! {|filename| /\A\./ =~ filename }
|
121
|
+
end
|
122
|
+
if !@opts[:R]
|
123
|
+
entries.each {|filename|
|
124
|
+
ls_file(dir + filename, nil)
|
125
|
+
}
|
126
|
+
else
|
127
|
+
dirs = []
|
128
|
+
entries.each {|filename|
|
129
|
+
path = dir + filename
|
130
|
+
st2 = ls_get_stat(path)
|
131
|
+
next if !st2
|
132
|
+
if filename == '.' || filename == '..'
|
133
|
+
if dir.to_s != '.'
|
134
|
+
path = Pathname(dir.to_s + "/" + filename)
|
135
|
+
end
|
136
|
+
ls_file(path, st2)
|
137
|
+
elsif st2.directory?
|
138
|
+
dirs << [path, st2]
|
139
|
+
else
|
140
|
+
ls_file(path, st2)
|
141
|
+
end
|
142
|
+
}
|
143
|
+
dirs.each {|path, st2|
|
144
|
+
ls_file(path, st2)
|
145
|
+
ls_dir(path, st2)
|
146
|
+
}
|
147
|
+
end
|
120
148
|
end
|
121
|
-
end
|
122
149
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
150
|
+
def ls_file(path, st)
|
151
|
+
if 0 < @opts[:l]
|
152
|
+
if !st
|
153
|
+
st = ls_get_stat(path)
|
154
|
+
return if !st
|
155
|
+
end
|
156
|
+
@y.yield ls_long_info(path, st)
|
157
|
+
else
|
158
|
+
@y.yield Tb::Pairs.new([['filename', path.to_s]])
|
128
159
|
end
|
129
|
-
gen << ls_long_info(path, st)
|
130
|
-
else
|
131
|
-
gen << [path.to_s]
|
132
160
|
end
|
133
|
-
end
|
134
161
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
162
|
+
def ls_get_stat(path)
|
163
|
+
begin
|
164
|
+
st = path.lstat
|
165
|
+
rescue SystemCallError
|
166
|
+
@fail = true
|
167
|
+
warn "tb: #{$!}: #{path}"
|
168
|
+
return nil
|
169
|
+
end
|
170
|
+
st
|
142
171
|
end
|
143
|
-
st
|
144
|
-
end
|
145
172
|
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
173
|
+
def ls_long_header
|
174
|
+
if 1 < @opts[:l]
|
175
|
+
%w[dev ino mode filemode nlink uid user gid group rdev size blksize blocks atime mtime ctime filename symlink]
|
176
|
+
else
|
177
|
+
%w[filemode nlink user group size mtime filename symlink]
|
178
|
+
end
|
151
179
|
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def (Tb::Cmd).ls_long_info(path, st)
|
155
|
-
ls_long_header.map {|info_type|
|
156
|
-
self.send("ls_info_#{info_type}", path, st)
|
157
|
-
}
|
158
|
-
end
|
159
180
|
|
160
|
-
def (
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
def (Tb::Cmd).ls_info_gid(path, st) st.gid end
|
166
|
-
def (Tb::Cmd).ls_info_rdev(path, st) sprintf("0x%x", st.rdev) end
|
167
|
-
def (Tb::Cmd).ls_info_size(path, st) st.size end
|
168
|
-
def (Tb::Cmd).ls_info_blksize(path, st) st.blksize end
|
169
|
-
def (Tb::Cmd).ls_info_blocks(path, st) st.blocks end
|
181
|
+
def ls_long_info(path, st)
|
182
|
+
Tb::Pairs.new(ls_long_header.map {|info_type|
|
183
|
+
[info_type, self.send("ls_info_#{info_type}", path, st)]
|
184
|
+
})
|
185
|
+
end
|
170
186
|
|
171
|
-
def (
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
when "unknown" then '?'
|
182
|
-
else '?'
|
183
|
-
end
|
184
|
-
m = st.mode
|
185
|
-
sprintf("%s%c%c%c%c%c%c%c%c%c",
|
186
|
-
entry_type,
|
187
|
-
(m & 0400 == 0 ? ?- : ?r),
|
188
|
-
(m & 0200 == 0 ? ?- : ?w),
|
189
|
-
(m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
|
190
|
-
(m & 04000 == 0 ? ?x : ?s)),
|
191
|
-
(m & 0040 == 0 ? ?- : ?r),
|
192
|
-
(m & 0020 == 0 ? ?- : ?w),
|
193
|
-
(m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
|
194
|
-
(m & 02000 == 0 ? ?x : ?s)),
|
195
|
-
(m & 0004 == 0 ? ?- : ?r),
|
196
|
-
(m & 0002 == 0 ? ?- : ?w),
|
197
|
-
(m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
|
198
|
-
(m & 01000 == 0 ? ?x : ?t)))
|
199
|
-
end
|
187
|
+
def ls_info_dev(path, st) sprintf("0x%x", st.dev) end
|
188
|
+
def ls_info_ino(path, st) st.ino end
|
189
|
+
def ls_info_mode(path, st) sprintf("0%o", st.mode) end
|
190
|
+
def ls_info_nlink(path, st) st.nlink end
|
191
|
+
def ls_info_uid(path, st) st.uid end
|
192
|
+
def ls_info_gid(path, st) st.gid end
|
193
|
+
def ls_info_rdev(path, st) sprintf("0x%x", st.rdev) end
|
194
|
+
def ls_info_size(path, st) st.size end
|
195
|
+
def ls_info_blksize(path, st) st.blksize end
|
196
|
+
def ls_info_blocks(path, st) st.blocks end
|
200
197
|
|
201
|
-
def (
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
198
|
+
def ls_info_filemode(path, st)
|
199
|
+
entry_type =
|
200
|
+
case st.ftype
|
201
|
+
when "file" then '-'
|
202
|
+
when "directory" then 'd'
|
203
|
+
when "characterSpecial" then 'c'
|
204
|
+
when "blockSpecial" then 'b'
|
205
|
+
when "fifo" then 'p'
|
206
|
+
when "link" then 'l'
|
207
|
+
when "socket" then 's'
|
208
|
+
when "unknown" then '?'
|
209
|
+
else '?'
|
210
|
+
end
|
211
|
+
m = st.mode
|
212
|
+
sprintf("%s%c%c%c%c%c%c%c%c%c",
|
213
|
+
entry_type,
|
214
|
+
(m & 0400 == 0 ? ?- : ?r),
|
215
|
+
(m & 0200 == 0 ? ?- : ?w),
|
216
|
+
(m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
|
217
|
+
(m & 04000 == 0 ? ?x : ?s)),
|
218
|
+
(m & 0040 == 0 ? ?- : ?r),
|
219
|
+
(m & 0020 == 0 ? ?- : ?w),
|
220
|
+
(m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
|
221
|
+
(m & 02000 == 0 ? ?x : ?s)),
|
222
|
+
(m & 0004 == 0 ? ?- : ?r),
|
223
|
+
(m & 0002 == 0 ? ?- : ?w),
|
224
|
+
(m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
|
225
|
+
(m & 01000 == 0 ? ?x : ?t)))
|
211
226
|
end
|
212
|
-
end
|
213
227
|
|
214
|
-
def (
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
228
|
+
def ls_info_user(path, st)
|
229
|
+
uid = st.uid
|
230
|
+
begin
|
231
|
+
pw = Etc.getpwuid(uid)
|
232
|
+
rescue ArgumentError
|
233
|
+
end
|
234
|
+
if pw
|
235
|
+
pw.name
|
236
|
+
else
|
237
|
+
uid
|
238
|
+
end
|
219
239
|
end
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
240
|
+
|
241
|
+
def ls_info_group(path, st)
|
242
|
+
gid = st.gid
|
243
|
+
begin
|
244
|
+
gr = Etc.getgrgid(gid)
|
245
|
+
rescue ArgumentError
|
246
|
+
end
|
247
|
+
if gr
|
248
|
+
gr.name
|
249
|
+
else
|
250
|
+
gid
|
251
|
+
end
|
224
252
|
end
|
225
|
-
end
|
226
253
|
|
227
|
-
def
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
254
|
+
def ls_info_atime(path, st)
|
255
|
+
if 1 < @opts[:l]
|
256
|
+
st.atime.iso8601(9)
|
257
|
+
else
|
258
|
+
st.atime.iso8601
|
259
|
+
end
|
232
260
|
end
|
233
|
-
end
|
234
261
|
|
235
|
-
def
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
262
|
+
def ls_info_mtime(path, st)
|
263
|
+
if 1 < @opts[:l]
|
264
|
+
st.mtime.iso8601(9)
|
265
|
+
else
|
266
|
+
st.mtime.iso8601
|
267
|
+
end
|
240
268
|
end
|
241
|
-
end
|
242
269
|
|
243
|
-
def
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
270
|
+
def ls_info_ctime(path, st)
|
271
|
+
if 1 < @opts[:l]
|
272
|
+
st.ctime.iso8601(9)
|
273
|
+
else
|
274
|
+
st.ctime.iso8601
|
275
|
+
end
|
248
276
|
end
|
249
|
-
end
|
250
277
|
|
251
|
-
def
|
252
|
-
|
253
|
-
end
|
278
|
+
def ls_info_filename(path, st)
|
279
|
+
path
|
280
|
+
end
|
254
281
|
|
255
|
-
def
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
282
|
+
def ls_info_symlink(path, st)
|
283
|
+
return nil if !st.symlink?
|
284
|
+
begin
|
285
|
+
File.readlink(path)
|
286
|
+
rescue SystemCallError
|
287
|
+
@fail = true
|
288
|
+
warn "tb: #{$!}: #{path}"
|
289
|
+
return nil
|
290
|
+
end
|
263
291
|
end
|
264
|
-
end
|
265
292
|
|
266
|
-
def
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
293
|
+
def real_pathname_string(str)
|
294
|
+
if str.respond_to? :force_encoding
|
295
|
+
# pathname is a sequence of bytes on Unix.
|
296
|
+
str.dup.force_encoding("ASCII-8BIT")
|
297
|
+
else
|
298
|
+
str
|
299
|
+
end
|
272
300
|
end
|
273
301
|
end
|