rio 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/ChangeLog +225 -0
  2. data/README +12 -0
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/doc/ANNOUNCE +160 -71
  6. data/doc/RELEASE_NOTES +71 -2
  7. data/ex/colx.rb +1 -1
  8. data/ex/passwd_report.rb +4 -8
  9. data/ex/riocat +5 -5
  10. data/ex/riogunzip +1 -1
  11. data/ex/riogzip +6 -6
  12. data/ex/rioprompt.rb +6 -0
  13. data/lib/rio.rb +3 -13
  14. data/lib/rio/arycopy.rb +1 -1
  15. data/lib/rio/base.rb +1 -5
  16. data/lib/rio/construct.rb +75 -0
  17. data/lib/rio/constructor.rb +42 -11
  18. data/lib/rio/context.rb +1 -1
  19. data/lib/rio/context/dir.rb +50 -23
  20. data/lib/rio/context/methods.rb +5 -3
  21. data/lib/rio/{cxdir.rb → context/skip.rb} +24 -36
  22. data/lib/rio/context/stream.rb +38 -16
  23. data/lib/rio/cp.rb +24 -5
  24. data/lib/rio/dir.rb +8 -7
  25. data/lib/rio/doc/HOWTO.rb +33 -33
  26. data/lib/rio/doc/INTRO.rb +416 -256
  27. data/lib/rio/doc/MISC.rb +3 -1
  28. data/lib/rio/doc/SYNOPSIS.rb +28 -33
  29. data/lib/rio/entrysel.rb +76 -9
  30. data/lib/rio/file.rb +2 -1
  31. data/lib/rio/filter.rb +95 -0
  32. data/lib/rio/filter/closeoneof.rb +1 -1
  33. data/lib/rio/grande.rb +0 -74
  34. data/lib/rio/if.rb +2 -1
  35. data/lib/rio/if/basic.rb +1 -1
  36. data/lib/rio/if/csv.rb +1 -1
  37. data/lib/rio/if/dir.rb +1 -220
  38. data/lib/rio/if/fileordir.rb +26 -12
  39. data/lib/rio/if/grande.rb +55 -6
  40. data/lib/rio/if/grande_entry.rb +355 -0
  41. data/lib/rio/if/{methods.rb → grande_stream.rb} +69 -88
  42. data/lib/rio/if/path.rb +25 -3
  43. data/lib/rio/if/stream.rb +62 -37
  44. data/lib/rio/if/temp.rb +2 -2
  45. data/lib/rio/if/test.rb +23 -0
  46. data/lib/rio/impl/path.rb +5 -0
  47. data/lib/rio/match.rb +6 -3
  48. data/lib/rio/matchrecord.rb +50 -46
  49. data/lib/rio/{filter/chomp.rb → ops/construct.rb} +12 -20
  50. data/lib/rio/ops/create.rb +3 -0
  51. data/lib/rio/ops/dir.rb +12 -6
  52. data/lib/rio/ops/either.rb +17 -3
  53. data/lib/rio/ops/path.rb +4 -1
  54. data/lib/rio/ops/stream/input.rb +6 -1
  55. data/lib/rio/ops/stream/read.rb +1 -3
  56. data/lib/rio/{context/chomp.rb → prompt.rb} +17 -13
  57. data/lib/rio/rl/base.rb +1 -1
  58. data/lib/rio/rl/builder.rb +3 -1
  59. data/lib/rio/state.rb +7 -13
  60. data/lib/rio/stream.rb +8 -5
  61. data/lib/rio/stream/open.rb +1 -1
  62. data/lib/rio/version.rb +1 -1
  63. data/test/mswin32.rb +1 -1
  64. data/test/runtests_gem.rb +1 -1
  65. data/test/tc/all.rb +3 -0
  66. data/test/tc/copy-from.rb +13 -13
  67. data/test/tc/copy-to.rb +1 -1
  68. data/test/tc/copy.rb +1 -1
  69. data/test/tc/copydir.rb +0 -24
  70. data/test/tc/copysymlink.rb +39 -0
  71. data/test/tc/csv.rb +2 -2
  72. data/test/tc/csv2.rb +4 -4
  73. data/test/tc/misc.rb +16 -16
  74. data/test/tc/nolines.rb +26 -26
  75. data/test/tc/noqae.rb +74 -74
  76. data/test/tc/overload.rb +28 -28
  77. data/test/tc/riorl.rb +36 -0
  78. data/test/tc/selnosel.rb +36 -0
  79. data/test/tc/skip.rb +58 -0
  80. data/test/tc/skiplines.rb +42 -0
  81. data/test/tc/symlink.rb +1 -1
  82. data/test/tc/symlink0.rb +1 -1
  83. data/test/tc/temp.rb +1 -1
  84. data/test/tc/tempdir.rb +1 -1
  85. data/test/tc/testcase.rb +7 -1
  86. metadata +14 -8
  87. data/lib/rio/matchcolumns.rb +0 -266
  88. data/lib/rio/rangemath.rb +0 -44
@@ -321,7 +321,7 @@ module RIO
321
321
  def /(arg) target / arg end
322
322
 
323
323
 
324
- # Create a Rio referencing Rio#to_s + arg.to_s
324
+ # Create a Rio referencing Rio#to_str + arg.to_str
325
325
  #
326
326
  # rio('afile') + '-0.1' #=> rio('afile-0.1')
327
327
  #
@@ -365,7 +365,9 @@ module RIO
365
365
  # Rio#rootpath
366
366
  #
367
367
  #
368
- def rootpath(*args) target.rootpath(*args) end
368
+ def rootpath(*args) # :nodoc:
369
+ target.rootpath(*args)
370
+ end
369
371
 
370
372
 
371
373
  # Rio#root
@@ -386,7 +388,7 @@ module RIO
386
388
  ##def getwd(*args,&block) target.getwd(*args,&block) end
387
389
 
388
390
 
389
- # Returns the scheme for the Rio's URI like URI#scheme where the Rio is represented
391
+ # Returns the scheme for the Rio's URI-like URI#scheme where the Rio is represented
390
392
  # by a standard URI. For Rios that are not represented by standard URIs one of
391
393
  # Rio's non-standard schemes is returned.
392
394
  #
@@ -434,6 +436,26 @@ module RIO
434
436
  #
435
437
  def route_to(other) target.route_to(other) end
436
438
 
439
+ # Calls Pathname#cleanpath
440
+ #
441
+ # Returns a new Rio whose path is the clean pathname of +self+ with
442
+ # consecutive slashes and useless dots
443
+ # removed. The filesystem is not accessed.
444
+ #
445
+ # If +consider_symlink+ is +true+, then a more conservative algorithm is used
446
+ # to avoid breaking symbolic linkages. This may retain more <tt>..</tt>
447
+ # entries than absolutely necessary, but without accessing the filesystem,
448
+ # this can't be avoided. See #realpath.
449
+ #
450
+ def cleanpath(consider_symlink=false) target.cleanpath(consider_symlink) end
437
451
 
452
+ # Calls Pathname#realpath
453
+ #
454
+ # Returns a new Rio whose path is the real (absolute) pathname
455
+ # of +self+ in the actual filesystem.
456
+ # The real pathname doesn't contain symlinks or useless dots.
457
+ #
458
+ def realpath() target.realpath() end
459
+
438
460
  end
439
461
  end
@@ -51,22 +51,11 @@ module RIO
51
51
 
52
52
  # Slurps the contents of the rio into a string. See also Rio#contents
53
53
  #
54
- # astring = rio('afile.txt').slurp # slurp the entire contents of afile.txt into astring
54
+ # astring = rio('afile.txt').contents # slurp the entire contents of afile.txt into astring
55
55
  #
56
- # Alpha Note: Considering removing Rio#contents and Rio#slurp in favor of +to_string+. Is
57
- # this the Ruby way? Is it too confusing with a +to_s+ and +to_str+ already? Is it a good idea?
58
- def slurp() target.slurp() end
59
-
60
- # Returns the contents of the rio as a string. See also Rio#slurp
61
- #
62
- # astring = rio('afile.txt').contents # copies the entire contents of afile.txt into astring
63
- #
64
- # Alpha Note: Considering removing Rio#contents and Rio#slurp in favor of +to_string+. Is
65
- # this the Ruby way? Is it too confusing with a +to_s+ and +to_str+ already? Is it a good idea?
66
56
  def contents() target.contents() end
67
57
 
68
58
 
69
-
70
59
  # Rio#each_record
71
60
  #
72
61
  #
@@ -98,8 +87,8 @@ module RIO
98
87
  def lineno() target.lineno() end
99
88
 
100
89
  # Calls IO#lineno=
101
- # ario.lineno = integer => integer
102
- # Manually sets the current line number to the given value. +$.+ is
90
+ # ario.lineno = integer => integer
91
+ # Manually sets the current line number to the given value. <tt>$.</tt> is
103
92
  # updated only on the next read.
104
93
  #
105
94
  # f = rio("testfile")
@@ -122,35 +111,25 @@ module RIO
122
111
  #
123
112
  # To illustrate: Given a file containing three lines "L0\n","L1\n","L2\n"
124
113
  # and a Range (0..1)
125
- # Each of the following would fill ay with ["L0\n", "L1\n"]
126
- #
127
- # ay = []
114
+ # Each of the following would fill anarray with ["L0\n", "L1\n"]
115
+ #
116
+ # Given:
117
+ # anarray = []
128
118
  # range = (0..1)
129
- # ain = rio('afile').readlines
130
- # ain.each_with_index do |line,i|
131
- # ay << line if range === i
119
+ #
120
+ # all_lines = rio('afile').readlines
121
+ # all_lines.each_with_index do |line,i|
122
+ # anarray << line if range === i
132
123
  # end
133
- #
134
- # ay = rio('afile').lines[0..1]
135
- #
124
+ # # anarray == ["L0\n", "L1\n"]
125
+ #
126
+ # anarray = rio('afile').lines[0..1] # anarray == ["L0\n", "L1\n"]
127
+ #
136
128
  # +recno+ counts the number of times Rio#getrec or Rio#each is used to get a record.
137
129
  # so +recno+ will only concern parts of the file read with grande methods
138
130
  # Rio#each, Rio#[], Rio#getrec
139
131
  #
140
132
  # See also Rio#lineno
141
- # f = rio("afile")
142
- # r1 = (0..1)
143
- # r2 = (100..101)
144
- #
145
- # aout1 = []
146
- # f.each { |rec|
147
- # aout << rec if r1 === f.recno or r2 === f.recno
148
- # }
149
- #
150
- # aout2 = f[r1,r2]
151
- #
152
- # aout1 == aout2 # true
153
- #
154
133
  def recno() target.recno() end
155
134
 
156
135
 
@@ -281,7 +260,7 @@ module RIO
281
260
 
282
261
  # Calls IO#puts
283
262
  #
284
- # Writes the given objects to the rio as with Rio#print .
263
+ # Writes the given objects to the rio as with Rio#print.
285
264
  # Writes a record separator (typically a newline) after any that do not already end with a newline sequence.
286
265
  # If called with an array argument, writes each element on a new line.
287
266
  # If called without arguments, outputs a single record separator.
@@ -595,5 +574,51 @@ module RIO
595
574
  #
596
575
  def ungetc(*args) target.ungetc(*args); self end
597
576
 
577
+ # Sets the 'sync-mode' of the underlying IO using IO#sync=
578
+ # ario.sync(boolean=true,&block) => ario
579
+ # Sets the Rio so that its 'sync mode' will be set to +true+ or +false+ when opened, or set
580
+ # it immediately if already open. When sync mode is
581
+ # true, all output is immediately flushed to the underlying operating
582
+ # system and is not buffered internally. Returns the rio. See
583
+ # also Rio#fsync, Rio#nosync, Rio#sync?.
584
+ #
585
+ # If a block is given behaves like <tt>ario.sync(arg).each(&block)</tt>
586
+ #
587
+ # f = rio("testfile").sync.puts("Hello World")
588
+ # f.sync? # => true
589
+ #
590
+ def sync(arg=true,&block) target.sync(arg,&block); self end
591
+
592
+ # Similar to IO#sync= false
593
+ # ario.nosync(&block) => ario
594
+ # Sets the Rio so that its 'sync mode' will be set to +false+ when opened, or set
595
+ # it immediately if already open. When sync mode is
596
+ # true, all output is immediately flushed to the underlying operating
597
+ # system and is not buffered internally. Returns the rio. See
598
+ # also Rio#fsync, Rio#sync, Rio#sync?.
599
+ #
600
+ # If a block is given behaves like <tt>ario.nosync.each(&block)</tt>
601
+ #
602
+ # f = rio("testfile").sync.puts("Hello World")
603
+ # f.sync? # => true
604
+ # f.nosync
605
+ # f.sync? # => false
606
+ #
607
+ def nosync(arg=false,&block) target.nosync(arg,&block); self end
608
+
609
+ # Query the current "sync mode" with IO#sync
610
+ # ario.sync? => true or false
611
+ # Returns the current "sync mode" of _ario_. When sync mode is true,
612
+ # all output is immediately flushed to the underlying operating
613
+ # system and is not buffered by Ruby internally. See also Rio#fsync,
614
+ # Rio#sync, Rio#nosync
615
+ #
616
+ # f = rio("testfile")
617
+ # f.sync? #=> false
618
+ #
619
+ def sync?() target.sync?() end
620
+
621
+
622
+
598
623
  end
599
624
  end
@@ -37,8 +37,8 @@
37
37
 
38
38
  module RIO
39
39
  class Rio
40
- def file() target.file; self end
41
- def dir() target.dir; self end
40
+ #def file() target.file; self end
41
+ #def dir() target.dir; self end
42
42
 
43
43
 
44
44
  end
@@ -41,27 +41,35 @@ module RIO
41
41
  # rio('afile').blockdev? => true or false
42
42
  # Returns +true+ if the named file is a block device.
43
43
  def blockdev?() target.blockdev?() end
44
+
44
45
  # Calls FileTest#chardev?
45
46
  # rio('afile').chardev? => true or false
46
47
  # Returns +true+ if the named file is a character device.
47
48
  def chardev?() target.chardev? end
49
+
48
50
  # Calls FileTest#directory?
49
51
  # rio('afile').directory? => true or false
50
52
  # Returns +true+ if the named file is a directory, +false+ otherwise.
51
53
  def directory?() target.directory? end
54
+
55
+ # Alias for #directory?
52
56
  def dir?() target.dir? end
57
+
53
58
  # Calls FileTest#exist?
54
59
  # rio('afile').exist?() => true or false
55
60
  # Returns +true+ if the named file exists.
56
61
  def exist?() target.exist? end
62
+
57
63
  # Calls FileTest#file?
58
64
  # rio('afile').file? => true or false
59
65
  # Returns +true+ if the named file exists and is a regular file.
60
66
  def file?() target.file? end
67
+
61
68
  # Calls FileTest#socket?
62
69
  # rio('afile').socket? => true or false
63
70
  # Returns +true+ if the named file is a socket.
64
71
  def socket?() target.socket? end
72
+
65
73
  # Calls FileTest#symlink?
66
74
  # rio('afile').symlink? => true or false
67
75
  # Returns +true+ if the named file is a symbolic link.
@@ -214,6 +222,21 @@ module RIO
214
222
  #
215
223
  def absolute?() target.absolute?() end
216
224
 
225
+ # Calls Pathname#mountpoint?
226
+ #
227
+ # Returns +true+ if <tt>self</tt> points to a mountpoint.
228
+ def mountpoint?() target.mountpoint?() end
229
+
230
+ # Calls Pathname#root?
231
+ #
232
+ # #root? is a predicate for root directories. I.e. it returns +true+ if the
233
+ # pathname consists of consecutive slashes.
234
+ #
235
+ # It doesn't access the actual filesystem. So it may return +false+ for some
236
+ # pathnames which points to roots such as <tt>/usr/..</tt>.
237
+ #
238
+ def root?() target.root?() end
217
239
 
240
+
218
241
  end
219
242
  end
@@ -77,6 +77,11 @@ module RIO
77
77
  def self.writable?(s,*args) ::FileTest.writable?(s,*args) end
78
78
  def self.writable_real?(s,*args) ::FileTest.writable_real?(s,*args) end
79
79
  def self.zero?(s,*args) ::FileTest.zero?(s,*args) end
80
+ require 'pathname'
81
+ def self.root?(s) ::Pathname.new(s).root? end
82
+ def self.mountpoint?(s) ::Pathname.new(s).mountpoint? end
83
+ def self.realpath(s) ::Pathname.new(s).realpath end
84
+ def self.cleanpath(s,*args) ::Pathname.new(s).cleanpath(*args) end
80
85
  end
81
86
  end
82
87
  end
@@ -40,9 +40,12 @@ module RIO
40
40
  module Common
41
41
 
42
42
  def ss_type?(keys)
43
- case
44
- when cx['ss_type'].nil? then keys[0]
45
- when cx['ss_type'].in?(keys) then cx['ss_type']
43
+ #p cx,keys
44
+ case cx['ss_type']
45
+ when nil
46
+ keys[0]
47
+ else
48
+ cx['ss_type']
46
49
  end
47
50
  end
48
51
 
@@ -41,7 +41,7 @@ module RIO
41
41
 
42
42
  class Base
43
43
  def initialize(arg)
44
- @select_arg = arg
44
+ @select_arg = arg
45
45
  end
46
46
  def inspect
47
47
  @select_arg.inspect
@@ -55,40 +55,27 @@ module RIO
55
55
  class All < Base
56
56
  def match?(val,recno) true end
57
57
  def match_all?() true end
58
- def =~(record) true end
59
58
  end
60
59
  class None < Base
61
60
  def match?(val,recno) false end
62
61
  def match_none?() true end
63
- def =~(record) false end
64
62
  end
65
63
  class RegExp < Base
66
64
  def match?(val,recno)
67
65
  @select_arg.match(val)
68
66
  end
69
- def =~(record)
70
- @select_arg =~ record
71
- end
72
67
  end
73
68
  class Range < Base
74
69
  def match?(val,recno)
75
70
  #p "match?(#{val},#{recno}) select_arg=#{@select_arg}"
76
71
  @select_arg === recno
77
72
  end
78
- def =~(record)
79
- #p "=~(#{record},#{record.recno}) select_arg=#{@select_arg}"
80
- @select_arg === record.recno
81
- end
82
73
  end
83
74
  class Fixnum < Base
84
75
  def match?(val,recno)
85
76
  #p "match?(#{val},#{recno}) select_arg=#{@select_arg}"
86
77
  @select_arg === recno
87
78
  end
88
- def =~(record)
89
- #p "=~(#{record},#{record.recno}) select_arg=#{@select_arg}"
90
- @select_arg === record.recno
91
- end
92
79
  end
93
80
  class Proc < Base
94
81
  def initialize(arg,therio)
@@ -99,19 +86,46 @@ module RIO
99
86
  #p "match?(#{val},#{recno}) select_arg=#{@select_arg}"
100
87
  @select_arg.call(val,recno,@therio)
101
88
  end
102
- def =~(record)
103
- @select_arg.call(record,record.recno,@therio)
104
- end
105
89
  end
106
90
  class Symbol < Base
107
91
  def match?(val,recno)
108
92
  #p "match?(#{val},#{recno}) select_arg=#{@select_arg}"
109
93
  val.__send__(@select_arg)
110
94
  end
111
- def =~(record)
112
- record.__send__(@select_arg)
95
+ end
96
+ class And < Base
97
+ def initialize(matches,therio)
98
+ list = []
99
+ matches.each do |arg|
100
+ list << Match::Record.create(therio,arg)
101
+ end
102
+ super(list)
103
+ @therio = therio
104
+ end
105
+ def match?(val,recno)
106
+ #p "match?(#{val},#{recno}) select_arg=#{@select_arg}"
107
+ @select_arg.all? { |sel| sel.match?(val,recno) }
108
+ end
109
+ end
110
+ def create(therio,arg)
111
+ case arg
112
+ when ::Regexp
113
+ Match::Record::RegExp.new(arg)
114
+ when ::Range
115
+ Match::Record::Range.new(arg)
116
+ when ::Proc
117
+ Match::Record::Proc.new(arg,therio)
118
+ when ::Symbol
119
+ Match::Record::Symbol.new(arg)
120
+ when ::Fixnum
121
+ Match::Record::Fixnum.new(arg)
122
+ when ::Array
123
+ Match::Record::And.new(arg,therio)
124
+ else
125
+ raise ArgumentError,"Argument must be a Regexp,Range,Fixnum,Proc, or Symbol"
113
126
  end
114
127
  end
128
+ module_function :create
115
129
  end
116
130
  end
117
131
 
@@ -162,20 +176,23 @@ module RIO
162
176
  @list.nil? ? nil : self
163
177
  end
164
178
  def create_sel(therio,arg)
165
- case arg
166
- when ::Regexp
167
- Match::Record::RegExp.new(arg)
168
- when ::Range
169
- Match::Record::Range.new(arg)
170
- when ::Proc
171
- Match::Record::Proc.new(arg,therio)
172
- when ::Symbol
173
- Match::Record::Symbol.new(arg)
174
- when ::Fixnum
175
- Match::Record::Fixnum.new(arg)
176
- else
177
- raise ArgumentError,"Argument must be a Regexp,Range,Fixnum,Proc, or Symbol"
178
- end
179
+ Match::Record.create(therio,arg)
180
+ # case arg
181
+ # when ::Regexp
182
+ # Match::Record::RegExp.new(arg)
183
+ # when ::Range
184
+ # Match::Record::Range.new(arg)
185
+ # when ::Proc
186
+ # Match::Record::Proc.new(arg,therio)
187
+ # when ::Symbol
188
+ # Match::Record::Symbol.new(arg)
189
+ # when ::Fixnum
190
+ # Match::Record::Fixnum.new(arg)
191
+ # when ::Array
192
+ # Match::Record::And.new(arg)
193
+ # else
194
+ # raise ArgumentError,"Argument must be a Regexp,Range,Fixnum,Proc, or Symbol"
195
+ # end
179
196
  end
180
197
  def match?(val,recno)
181
198
  # !@list.nil? && (@list.empty? || @list.detect { |sel| sel.match?(val,recno) } || false) && true
@@ -190,9 +207,6 @@ module RIO
190
207
  return as if al
191
208
  return false
192
209
  end
193
- def =~(el)
194
- !@list.nil? && (@list.empty? || @list.detect { |sel| sel =~ el } || false) && true
195
- end
196
210
  def always?() !@list.nil? && @list.empty? end
197
211
  def never?() @list.nil? end
198
212
  end
@@ -253,16 +267,6 @@ module RIO
253
267
  ok = ((!@sel.nil? && (as = @sel.match?(val,recno))) && !(!@rej.nil? && @rej.match?(val,recno)))
254
268
  return (ok ? as : ok)
255
269
  end
256
- def =~(el)
257
- return @always unless @always.nil?
258
- (!@sel.nil? && (@sel =~ el)) && !(!@rej.nil? && (@rej =~ el))
259
-
260
- #yes = (!@sel.nil? && (@sel =~ el))
261
- #no = (!@rej.nil? && (@rej =~ el))
262
- #p "yes=#{yes} no=#{no} el=#{el}"
263
- #return yes && !no
264
- #(@sel =~ el) && !(@rej =~ el)
265
- end
266
270
  end
267
271
  end
268
272
  end