wishdev-rio 0.4.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. data/COPYING +341 -0
  2. data/README +81 -0
  3. data/Rakefile +281 -0
  4. data/build_doc.rb +94 -0
  5. data/doc/ANNOUNCE +159 -0
  6. data/doc/RELEASE_NOTES +308 -0
  7. data/doc/RIOIS +215 -0
  8. data/doc/generators/template/html/rio.css +428 -0
  9. data/doc/generators/template/html/rio.rb +523 -0
  10. data/doc/generators/template/html/ugly.rb +132 -0
  11. data/doc/pkg_def.rb +60 -0
  12. data/doc/rfc1738.txt +1403 -0
  13. data/doc/rfc959.txt +3933 -0
  14. data/ex/catcsv.rb +64 -0
  15. data/ex/colx.rb +8 -0
  16. data/ex/findinruby +15 -0
  17. data/ex/findruby +14 -0
  18. data/ex/passwd_report.rb +8 -0
  19. data/ex/prompt.rb +25 -0
  20. data/ex/rgb.txt.gz +0 -0
  21. data/ex/riocat +42 -0
  22. data/ex/riogunzip +31 -0
  23. data/ex/riogzip +24 -0
  24. data/ex/rioprompt.rb +10 -0
  25. data/ex/targz2zip +17 -0
  26. data/ex/tonl +10 -0
  27. data/lib/rio/abstract_method.rb +56 -0
  28. data/lib/rio/argv.rb +56 -0
  29. data/lib/rio/arycopy.rb +43 -0
  30. data/lib/rio/assert.rb +114 -0
  31. data/lib/rio/base.rb +56 -0
  32. data/lib/rio/callstr.rb +46 -0
  33. data/lib/rio/const.rb +51 -0
  34. data/lib/rio/construct.rb +50 -0
  35. data/lib/rio/constructor.rb +258 -0
  36. data/lib/rio/context/autoclose.rb +72 -0
  37. data/lib/rio/context/copying.rb +55 -0
  38. data/lib/rio/context/cxx.rb +66 -0
  39. data/lib/rio/context/dir.rb +120 -0
  40. data/lib/rio/context/gzip.rb +50 -0
  41. data/lib/rio/context/methods.rb +182 -0
  42. data/lib/rio/context/skip.rb +66 -0
  43. data/lib/rio/context/stream.rb +229 -0
  44. data/lib/rio/context.rb +117 -0
  45. data/lib/rio/cp.rb +370 -0
  46. data/lib/rio/def.rb +53 -0
  47. data/lib/rio/dir.rb +144 -0
  48. data/lib/rio/doc/EXAMPLES.rb +299 -0
  49. data/lib/rio/doc/HOWTO.rb +737 -0
  50. data/lib/rio/doc/INDEX.rb +311 -0
  51. data/lib/rio/doc/INTRO.rb +1068 -0
  52. data/lib/rio/doc/OPTIONAL.rb +130 -0
  53. data/lib/rio/doc/SYNOPSIS.rb +183 -0
  54. data/lib/rio/doc.rb +45 -0
  55. data/lib/rio/entrysel.rb +246 -0
  56. data/lib/rio/exception/copy.rb +97 -0
  57. data/lib/rio/exception/notimplemented.rb +57 -0
  58. data/lib/rio/exception/notsupported.rb +46 -0
  59. data/lib/rio/exception/open.rb +61 -0
  60. data/lib/rio/exception/state.rb +73 -0
  61. data/lib/rio/exception.rb +41 -0
  62. data/lib/rio/ext/csv.rb +351 -0
  63. data/lib/rio/ext/if.rb +45 -0
  64. data/lib/rio/ext/mp3info.rb +80 -0
  65. data/lib/rio/ext/splitlines.rb +253 -0
  66. data/lib/rio/ext/yaml/doc.rb +133 -0
  67. data/lib/rio/ext/yaml/tie.rb +149 -0
  68. data/lib/rio/ext/yaml.rb +164 -0
  69. data/lib/rio/ext/zipfile/fs.rb +116 -0
  70. data/lib/rio/ext/zipfile/rl.rb +251 -0
  71. data/lib/rio/ext/zipfile/rootdir.rb +117 -0
  72. data/lib/rio/ext/zipfile/state.rb +161 -0
  73. data/lib/rio/ext/zipfile/wrap.rb +204 -0
  74. data/lib/rio/ext/zipfile.rb +110 -0
  75. data/lib/rio/ext.rb +138 -0
  76. data/lib/rio/factory.rb +436 -0
  77. data/lib/rio/file.rb +118 -0
  78. data/lib/rio/filter/closeoneof.rb +103 -0
  79. data/lib/rio/filter/gzip.rb +70 -0
  80. data/lib/rio/filter.rb +94 -0
  81. data/lib/rio/fs/base.rb +41 -0
  82. data/lib/rio/fs/impl.rb +122 -0
  83. data/lib/rio/fs/native.rb +75 -0
  84. data/lib/rio/fs/stream.rb +61 -0
  85. data/lib/rio/fs/url.rb +63 -0
  86. data/lib/rio/ftp/conncache.rb +101 -0
  87. data/lib/rio/ftp/dir.rb +94 -0
  88. data/lib/rio/ftp/fs.rb +180 -0
  89. data/lib/rio/ftp/ftpfile.rb +20 -0
  90. data/lib/rio/grande.rb +97 -0
  91. data/lib/rio/handle.rb +100 -0
  92. data/lib/rio/if/basic.rb +64 -0
  93. data/lib/rio/if/csv.rb +76 -0
  94. data/lib/rio/if/dir.rb +157 -0
  95. data/lib/rio/if/file.rb +89 -0
  96. data/lib/rio/if/fileordir.rb +268 -0
  97. data/lib/rio/if/grande.rb +729 -0
  98. data/lib/rio/if/grande_entry.rb +379 -0
  99. data/lib/rio/if/grande_stream.rb +693 -0
  100. data/lib/rio/if/internal.rb +125 -0
  101. data/lib/rio/if/path.rb +462 -0
  102. data/lib/rio/if/rubyio.rb +681 -0
  103. data/lib/rio/if/string.rb +83 -0
  104. data/lib/rio/if/temp.rb +45 -0
  105. data/lib/rio/if/test.rb +282 -0
  106. data/lib/rio/if/yaml.rb +206 -0
  107. data/lib/rio/if.rb +64 -0
  108. data/lib/rio/ioh.rb +162 -0
  109. data/lib/rio/iomode.rb +109 -0
  110. data/lib/rio/ios/fail.rb +106 -0
  111. data/lib/rio/ios/generic.rb +119 -0
  112. data/lib/rio/ios/mode.rb +60 -0
  113. data/lib/rio/ios/null.rb +119 -0
  114. data/lib/rio/iowrap.rb +128 -0
  115. data/lib/rio/kernel.rb +54 -0
  116. data/lib/rio/local.rb +62 -0
  117. data/lib/rio/match.rb +53 -0
  118. data/lib/rio/matchrecord.rb +283 -0
  119. data/lib/rio/no_warn.rb +49 -0
  120. data/lib/rio/nullio.rb +159 -0
  121. data/lib/rio/open3.rb +68 -0
  122. data/lib/rio/ops/construct.rb +61 -0
  123. data/lib/rio/ops/create.rb +77 -0
  124. data/lib/rio/ops/dir.rb +346 -0
  125. data/lib/rio/ops/either.rb +134 -0
  126. data/lib/rio/ops/file.rb +102 -0
  127. data/lib/rio/ops/path.rb +296 -0
  128. data/lib/rio/ops/stream/input.rb +267 -0
  129. data/lib/rio/ops/stream/output.rb +100 -0
  130. data/lib/rio/ops/stream/read.rb +86 -0
  131. data/lib/rio/ops/stream/write.rb +57 -0
  132. data/lib/rio/ops/stream.rb +87 -0
  133. data/lib/rio/ops/symlink.rb +80 -0
  134. data/lib/rio/path/reset.rb +69 -0
  135. data/lib/rio/path.rb +129 -0
  136. data/lib/rio/piper/cp.rb +80 -0
  137. data/lib/rio/piper.rb +122 -0
  138. data/lib/rio/prompt.rb +66 -0
  139. data/lib/rio/rectype.rb +88 -0
  140. data/lib/rio/rl/base.rb +118 -0
  141. data/lib/rio/rl/builder.rb +117 -0
  142. data/lib/rio/rl/chmap.rb +66 -0
  143. data/lib/rio/rl/fs2url.rb +82 -0
  144. data/lib/rio/rl/ioi.rb +78 -0
  145. data/lib/rio/rl/path.rb +110 -0
  146. data/lib/rio/rl/pathmethods.rb +116 -0
  147. data/lib/rio/rl/uri.rb +200 -0
  148. data/lib/rio/rl/withpath.rb +296 -0
  149. data/lib/rio/scheme/aryio.rb +88 -0
  150. data/lib/rio/scheme/cmdio.rb +80 -0
  151. data/lib/rio/scheme/cmdpipe.rb +118 -0
  152. data/lib/rio/scheme/fd.rb +65 -0
  153. data/lib/rio/scheme/ftp.rb +141 -0
  154. data/lib/rio/scheme/http.rb +78 -0
  155. data/lib/rio/scheme/null.rb +55 -0
  156. data/lib/rio/scheme/path.rb +98 -0
  157. data/lib/rio/scheme/stderr.rb +55 -0
  158. data/lib/rio/scheme/stdio.rb +71 -0
  159. data/lib/rio/scheme/strio.rb +87 -0
  160. data/lib/rio/scheme/sysio.rb +63 -0
  161. data/lib/rio/scheme/tcp.rb +75 -0
  162. data/lib/rio/scheme/temp.rb +200 -0
  163. data/lib/rio/state/error.rb +72 -0
  164. data/lib/rio/state.rb +242 -0
  165. data/lib/rio/stream/base.rb +54 -0
  166. data/lib/rio/stream/duplex.rb +79 -0
  167. data/lib/rio/stream/open.rb +202 -0
  168. data/lib/rio/stream.rb +181 -0
  169. data/lib/rio/symantics.rb +45 -0
  170. data/lib/rio/tempdir.rb +132 -0
  171. data/lib/rio/to_rio/all.rb +39 -0
  172. data/lib/rio/to_rio/array.rb +39 -0
  173. data/lib/rio/to_rio/io.rb +40 -0
  174. data/lib/rio/to_rio/object.rb +42 -0
  175. data/lib/rio/to_rio/string.rb +40 -0
  176. data/lib/rio/to_rio.rb +67 -0
  177. data/lib/rio/uri/file.rb +198 -0
  178. data/lib/rio/util.rb +48 -0
  179. data/lib/rio/version.rb +51 -0
  180. data/lib/rio.rb +162 -0
  181. data/setup.rb +1360 -0
  182. data/test/bin/count_lines.rb +11 -0
  183. data/test/bin/find_lines.rb +13 -0
  184. data/test/bin/list_dir.rb +14 -0
  185. data/test/ftp/all.rb +9 -0
  186. data/test/ftp/anon_copy_data.rb +36 -0
  187. data/test/ftp/anon_misc.rb +124 -0
  188. data/test/ftp/anon_read.rb +105 -0
  189. data/test/ftp/anon_special.rb +68 -0
  190. data/test/ftp/anon_write.rb +70 -0
  191. data/test/ftp/ftp2ftp.rb +51 -0
  192. data/test/ftp/initftpfiles.rb +14 -0
  193. data/test/ftp/testdef.rb +55 -0
  194. data/test/gem_runtests.rb +15 -0
  195. data/test/http/all.rb +4 -0
  196. data/test/http/copy-from-http.rb +141 -0
  197. data/test/http/uri-meta.rb +72 -0
  198. data/test/lib/temp_server.rb +46 -0
  199. data/test/runalltests.rb +17 -0
  200. data/test/runftptests.rb +14 -0
  201. data/test/runhttp.rb +11 -0
  202. data/test/runhttptests.rb +14 -0
  203. data/test/runtests.rb +52 -0
  204. data/test/tc/abs.rb +355 -0
  205. data/test/tc/all.rb +80 -0
  206. data/test/tc/base.rb +31 -0
  207. data/test/tc/base2.rb +87 -0
  208. data/test/tc/cd1.rb +113 -0
  209. data/test/tc/clearsel.rb +68 -0
  210. data/test/tc/clone.rb +208 -0
  211. data/test/tc/closeoncopy.rb +102 -0
  212. data/test/tc/closeoneof.rb +194 -0
  213. data/test/tc/cmdpipe.rb +149 -0
  214. data/test/tc/copy-dir-samevar.rb +91 -0
  215. data/test/tc/copy-from.rb +129 -0
  216. data/test/tc/copy-to.rb +91 -0
  217. data/test/tc/copy.rb +74 -0
  218. data/test/tc/copyarray.rb +188 -0
  219. data/test/tc/copydest.rb +50 -0
  220. data/test/tc/copydir.rb +166 -0
  221. data/test/tc/copydirlines.rb +121 -0
  222. data/test/tc/copylines.rb +46 -0
  223. data/test/tc/copynonex.rb +118 -0
  224. data/test/tc/copysymlink.rb +39 -0
  225. data/test/tc/create.rb +114 -0
  226. data/test/tc/csv.rb +226 -0
  227. data/test/tc/csv2.rb +138 -0
  228. data/test/tc/csv_columns.rb +37 -0
  229. data/test/tc/csvutil.rb +56 -0
  230. data/test/tc/dir.rb +76 -0
  231. data/test/tc/dir_iter.rb +383 -0
  232. data/test/tc/dirautoclose.rb +67 -0
  233. data/test/tc/dirent.rb +178 -0
  234. data/test/tc/dirss.rb +81 -0
  235. data/test/tc/each.rb +111 -0
  236. data/test/tc/each_break.rb +243 -0
  237. data/test/tc/edf.rb +81 -0
  238. data/test/tc/empty.rb +51 -0
  239. data/test/tc/emptyriodir.rb +129 -0
  240. data/test/tc/entary.rb +227 -0
  241. data/test/tc/entsel.rb +110 -0
  242. data/test/tc/eq.rb +101 -0
  243. data/test/tc/expand_path.rb +69 -0
  244. data/test/tc/ext.rb +136 -0
  245. data/test/tc/fileno.rb +94 -0
  246. data/test/tc/files_select.rb +92 -0
  247. data/test/tc/get.rb +152 -0
  248. data/test/tc/getrec.rb +137 -0
  249. data/test/tc/gzip.rb +109 -0
  250. data/test/tc/io_each_byte.rb +60 -0
  251. data/test/tc/io_read.rb +80 -0
  252. data/test/tc/iometh.rb +149 -0
  253. data/test/tc/likeio.rb +116 -0
  254. data/test/tc/line_record_row.rb +51 -0
  255. data/test/tc/lineno.rb +196 -0
  256. data/test/tc/lines.rb +66 -0
  257. data/test/tc/misc.rb +432 -0
  258. data/test/tc/nolines.rb +204 -0
  259. data/test/tc/noqae.rb +879 -0
  260. data/test/tc/null.rb +45 -0
  261. data/test/tc/once.rb +6 -0
  262. data/test/tc/overload.rb +140 -0
  263. data/test/tc/pa.rb +158 -0
  264. data/test/tc/path_parts.rb +175 -0
  265. data/test/tc/pathop.rb +60 -0
  266. data/test/tc/paths.rb +145 -0
  267. data/test/tc/pid.rb +31 -0
  268. data/test/tc/piper.rb +143 -0
  269. data/test/tc/programs_util.rb +24 -0
  270. data/test/tc/qae.rb +493 -0
  271. data/test/tc/qae_riovar.rb +499 -0
  272. data/test/tc/readline.rb +30 -0
  273. data/test/tc/records.rb +68 -0
  274. data/test/tc/rename.rb +233 -0
  275. data/test/tc/rename_assign.rb +45 -0
  276. data/test/tc/riorl.rb +181 -0
  277. data/test/tc/route.rb +51 -0
  278. data/test/tc/selnosel.rb +33 -0
  279. data/test/tc/skip.rb +89 -0
  280. data/test/tc/skiplines.rb +71 -0
  281. data/test/tc/split.rb +28 -0
  282. data/test/tc/splitlines.rb +65 -0
  283. data/test/tc/splitpath.rb +83 -0
  284. data/test/tc/sub.rb +46 -0
  285. data/test/tc/symlink.rb +176 -0
  286. data/test/tc/symlink0.rb +348 -0
  287. data/test/tc/symlink1.rb +114 -0
  288. data/test/tc/synopsis.rb +75 -0
  289. data/test/tc/temp.rb +152 -0
  290. data/test/tc/tempdir.rb +60 -0
  291. data/test/tc/tempfile.rb +66 -0
  292. data/test/tc/testcase.rb +170 -0
  293. data/test/tc/tonl.rb +37 -0
  294. data/test/tc/truncate.rb +39 -0
  295. data/test/tc/yaml.rb +275 -0
  296. metadata +387 -0
@@ -0,0 +1,89 @@
1
+ #--
2
+ # ===============================================================================
3
+ # Copyright (c) 2005,2006,2007 Christopher Kleckner
4
+ # All rights reserved
5
+ #
6
+ # This file is part of the Rio library for ruby.
7
+ #
8
+ # Rio is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Rio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Rio; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # ===============================================================================
22
+ #++
23
+ #
24
+ # To create the documentation for Rio run the command
25
+ # ruby build_doc.rb
26
+ # from the distribution directory.
27
+ #
28
+ # Suggested Reading
29
+ # * RIO::Doc::SYNOPSIS
30
+ # * RIO::Doc::INTRO
31
+ # * RIO::Doc::HOWTO
32
+ # * RIO::Doc::EXAMPLES
33
+ # * RIO::Rio
34
+ #
35
+
36
+
37
+ module RIO
38
+ module IF
39
+ module File
40
+
41
+ # Calls FileUtils#rm
42
+ #
43
+ # Deletes the referenced file, returning the Rio. Raises an exception on any error.
44
+ #
45
+ # See also IF::Grande#delete, IF::Grande#delete!, IF::Dir#rmdir.
46
+ def rm() target.rm(); self end
47
+
48
+
49
+ # Calls FileUtils#touch
50
+ #
51
+ # Updates modification time (mtime) and access time (atime) of a Rio.
52
+ # A file is created if it doesn't exist.
53
+ #
54
+ def touch() target.touch(); self end
55
+
56
+ # Calls File#truncate
57
+ #
58
+ # Truncates a file referenced by a Rio to be at most +sz+ bytes long.
59
+ # Not available on all platforms.
60
+ #
61
+ # f = rio("out")
62
+ # f.print!("1234567890")
63
+ # f.size #=> 10
64
+ # f.truncate(5)
65
+ # f.size() #=> 5
66
+ #
67
+ # If called with no arguments, truncates the Rio at the
68
+ # value returned by IF::FileOrDir#pos().
69
+ # f.read(2)
70
+ # f.truncate.size #=> 2
71
+ # f.contents #=> "12"
72
+ #
73
+ # Returns the Rio
74
+ #
75
+ def truncate(sz=pos()) target.truncate(sz); self end
76
+
77
+ # Calls IF::File#truncate(0)
78
+ #
79
+ def clear() target.clear(); self end
80
+
81
+ end
82
+ end
83
+ end
84
+
85
+ module RIO
86
+ class Rio
87
+ include RIO::IF::File
88
+ end
89
+ end
@@ -0,0 +1,268 @@
1
+ #--
2
+ # ===============================================================================
3
+ # Copyright (c) 2005,2006,2007 Christopher Kleckner
4
+ # All rights reserved
5
+ #
6
+ # This file is part of the Rio library for ruby.
7
+ #
8
+ # Rio is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Rio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Rio; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # ===============================================================================
22
+ #++
23
+ #
24
+ # To create the documentation for Rio run the command
25
+ # ruby build_doc.rb
26
+ # from the distribution directory.
27
+ #
28
+ # Suggested Reading
29
+ # * RIO::Doc::SYNOPSIS
30
+ # * RIO::Doc::INTRO
31
+ # * RIO::Doc::HOWTO
32
+ # * RIO::Doc::EXAMPLES
33
+ # * RIO::Rio
34
+ #
35
+
36
+
37
+ module RIO
38
+ module IF
39
+ module FileOrDir
40
+
41
+ # undocumented
42
+ def open(m,*args,&block) target.open(m,*args,&block); self end
43
+
44
+ # Creates a symbolic link _dest_ which points to the Rio's IF::Path#fspath.
45
+ # Raises a NotImplementedError exception on platforms that do not support symbolic links.
46
+ # _dest_ may be a Rio, a String, or anything that will create an appropriate Rio
47
+ # when passed to Rio#new .
48
+ # If _dest_ already exists and is a directory, creates a symbolic link in the _dest_ directory,
49
+ # named with the name returned by IF::Path#filename.
50
+ # If _dest_ already exists and it is not a directory, raises Errno::EEXIST.
51
+ #
52
+ # Returns the Rio (not the symlink).
53
+ #
54
+ # IF::FileOrDir#symlink differs from File#symlink when the Rio or the _dest_ path has directory information.
55
+ # In this case IF::FileOrDir#symlink creates a symlink that actually refers to the Rio's location
56
+ # from the perspective of the link's location.
57
+ #
58
+ # For example: Given an existing file 'adir/afile' and a _dest_ of 'adir/alink'
59
+ # ::File.symlink('adir/afile','adir/alink1') # creates 'adir/alink1 -> adir/afile'
60
+ # ::File.exist?('adir/alink1') # false
61
+ # rio('adir/afile').symlink('adir/alink2') # creates 'adir/alink2 -> afile'
62
+ # ::File.exist?('adir/alink2') # true
63
+ #
64
+ # To replace an existing symlink use the following Rio idiom
65
+ # rio('afile').symlink( rio('link_name').delete ) # delete 'link_name' and recreate linked to 'afile'
66
+ #
67
+ # Examples
68
+ # rio('afile').symlink('alink') # create the symbolic link 'alink' which references 'afile'
69
+ # rio('afile').symlink('adir/alink') # create a symlink 'adir/alink' -> '../afile'
70
+ # rio('adir/afile').symlink('alink') # create a symlink 'alink' -> 'adir/afile'
71
+ # rio('adir/afile').symlink('adir/alink') # create a symlink 'adir/alink' -> 'afile'
72
+ # rio('adir/afile').symlink('adir/alink') # create a symlink 'adir/alink' -> 'afile'
73
+ # rio('adir1/afile').symlink('adir2/alink') # create a symlink 'adir2/alink' -> '../adir1/afile'
74
+ # rio('/tmp/afile').symlink('alink') # create a symlink 'adir/alink' -> '/tmp/afile'
75
+ def symlink(dest) target.symlink(dest); self end
76
+
77
+
78
+ # Calls File#readlink
79
+ #
80
+ # Returns a Rio referencing the file referenced by the given link. Not available on all platforms.
81
+ #
82
+ def readlink(*args) target.readlink(*args) end
83
+
84
+ # If called with an argument calls FileUtils#rename.
85
+ # If called without an argument puts the Rio in "rename mode".
86
+ #
87
+ # Proxy for FileUtils#rename
88
+ # ario = rio('afile.cpp')
89
+ # ario.rename('afile.cxx') # renamed the file, but ario still references
90
+ # # the old path
91
+ # ===== Rename Mode
92
+ #
93
+ # In rename mode, changes to a Rio's path using IF::Path#dirname=, IF::Path#filename=,
94
+ # IF::Path#basename=, and IF::Path#extname= also cause the object on the filesystem
95
+ # to be renamed.
96
+ #
97
+ # Change the extension of all'.cpp' files in 'adir' to '.cxx'
98
+ # rio('adir').rename.files('*.cpp') do |file|
99
+ # file.ext = '.cxx' # 'file' references the new path and the actual file is renamed
100
+ # end
101
+ #
102
+ # Recursively change all '.tar.gz' files to '.tgz' files
103
+ # rio('adir').rename.all.files('*.tar.gz') do |gzfile|
104
+ # gzfile.ext('.tar.gz').ext = '.tgz'
105
+ # end
106
+ #
107
+ # See IF::Path#dirname=, IF::Path#filename=, IF::Path#basename=, and IF::Path#extname=
108
+ #
109
+ def rename(*args,&block) target.rename(*args,&block); self end
110
+
111
+
112
+ # Behaves like IF::FileOrDir#rename, but also changes the calling Rio to
113
+ # refer to the renamed path
114
+ def rename!(*args,&block) target.rename!(*args,&block); self end
115
+
116
+
117
+ # For directories calls Dir#read, otherwise calls IO#read
118
+ #
119
+ # For streams calls IO#read
120
+ # ario.read([integer [, buffer]]) => string, buffer, or nil
121
+ # Reads at most _integer_ bytes from the I/O stream, or to the end of
122
+ # file if _integer_ is omitted or is +nil+. If the optional _buffer_
123
+ # argument is present, it must reference a String, which will receive
124
+ # the data. Returns +nil+ if called at end of file.
125
+ #
126
+ # f = rio("testfile")
127
+ # f.read(16) #=> "This is line one"
128
+ #
129
+ # rio("testfile").read(16) #=> "This is line one"
130
+ #
131
+ # For directories calls Dir#read
132
+ # dir.read => ario or nil
133
+ #------------------------------------------------------------------------
134
+ # Reads the next entry from _dir_ and returns it as a Rio. Returns
135
+ # +nil+ at the end of the stream.
136
+ # d = rio("testdir")
137
+ # d.read #=> rio(".")
138
+ # d.read #=> rio("..")
139
+ # d.read #=> rio("config.h")
140
+ #
141
+ def read(*args) target.read(*args)end
142
+
143
+ # For directories proxies Dir#rewind, otherwise proxies IO#rewind
144
+ #
145
+ # Proxy for IO#rewind
146
+ # ario.rewind => ario
147
+ # Positions _ario_ to the beginning of input, resetting lineno to zero.
148
+ #
149
+ # Returns the Rio
150
+ #
151
+ # f = rio("testfile")
152
+ # f.readline #=> "This is line one\n"
153
+ # f.rewind #=> f
154
+ # f.lineno #=> 0
155
+ # f.readline #=> "This is line one\n"
156
+ #
157
+ # f.rewind.readline #=> "This is line one\n"
158
+ #
159
+ # Proxy for Dir#rewind
160
+ # ario.rewind => ario
161
+ #------------------------------------------------------------------------
162
+ # Repositions _ario_ to the first entry.
163
+ #
164
+ # d = rio("testdir")
165
+ # d.read #=> rio(".")
166
+ # d.rewind.read #=> rio(".")
167
+ def rewind(&block) target.rewind(&block); self end
168
+
169
+ # For directories calls Dir#seek, otherwise calls IO#seek
170
+ #
171
+ # For streams calls IO#seek
172
+ # ario.seek(amount, whence=SEEK_SET) -> ario
173
+ # Seeks to a given offset _amount_ in the stream according to the
174
+ # value of _whence_:
175
+ #
176
+ # IO::SEEK_CUR | Seeks to 'amount' plus current position
177
+ # --------------+----------------------------------------------------
178
+ # IO::SEEK_END | Seeks to 'amount' plus end of stream (you probably
179
+ # | want a negative value for 'amount')
180
+ # --------------+----------------------------------------------------
181
+ # IO::SEEK_SET | Seeks to the absolute location given by 'amount'
182
+ #
183
+ # Example:
184
+ #
185
+ # f = rio("testfile")
186
+ # f.seek(-28, IO::SEEK_END).readline #=> "happily ever after. The End\n"
187
+ #
188
+ # For directories calls Dir#seek
189
+ # ario.seek( integer ) => ario
190
+ # Seeks to a particular location in _ario_. _integer_ must be a value
191
+ # returned by IF::FileOrDir#tell.
192
+ #
193
+ # d = rio("testdir") #=> #<RIO::Rio:0x401b3c40>
194
+ # d.read #=> rio(".")
195
+ # i = d.tell #=> 12
196
+ # d.read #=> rio("..")
197
+ # d.seek(i) #=> #<RIO::Rio:0x401b3c40>
198
+ # d.read #=> rio("..")
199
+ def seek(*args) target.seek(*args); self end
200
+ #def seek(amount,whence=IO::SEEK_SET) target.seek(amount,whence) end
201
+
202
+
203
+
204
+ # For directories calls Dir#pos, otherwise calls IO#pos
205
+ #
206
+ # For streams calls IO#pos
207
+ # ario.pos => integer
208
+ # ario.tell => integer
209
+ # Returns the current offset (in bytes) of _ario_.
210
+ #
211
+ # f = rio("testfile")
212
+ # f.pos #=> 0
213
+ # f.gets #=> "This is line one\n"
214
+ # f.pos #=> 17
215
+ #
216
+ #
217
+ # For directories calls Dir#pos
218
+ # ario.pos => integer
219
+ # ario.tell => integer
220
+ # Returns the current position in _dir_. See also IF::FileOrDir#seek.
221
+ #
222
+ # d = rio("testdir")
223
+ # d.pos #=> 0
224
+ # d.read #=> rio(".")
225
+ # d.pos #=> 12
226
+ #
227
+ def pos() target.pos end
228
+
229
+ # See IF::FileOrDir#pos
230
+ def tell() target.tell end
231
+
232
+ # For directories calls Dir#pos=, otherwise calls IO#pos=
233
+ #
234
+ # For streams calls IO#pos=
235
+ # ario.pos = integer => 0
236
+ # Seeks to the given position (in bytes) in _ario_.
237
+ #
238
+ # f = rio("testfile")
239
+ # f.pos = 17
240
+ # f.gets #=> "This is line two\n"
241
+ #
242
+ # For directories calls Dir#pos=
243
+ # ario.pos = integer => integer
244
+ #------------------------------------------------------------------------
245
+ # Synonym for +IF::FileOrDir#seek+, but returns the position parameter.
246
+ #
247
+ # d = rio("testdir") #=> d
248
+ # d.read #=> rio(".")
249
+ # i = d.pos #=> 12
250
+ # d.read #=> rio("..")
251
+ # d.pos = i #=> 12
252
+ # d.read #=> rio("..")
253
+ #
254
+ def pos=(integer) target.pos = integer end
255
+
256
+ # For Streams calls IO#reopen, otherwise closes and re-opens
257
+ # the Rio.
258
+ #
259
+ def reopen(mode=nil) target.reopen(mode); self end
260
+ end
261
+ end
262
+ end
263
+
264
+ module RIO
265
+ class Rio
266
+ include RIO::IF::FileOrDir
267
+ end
268
+ end
@@ -0,0 +1,729 @@
1
+ #--
2
+ # ===============================================================================
3
+ # Copyright (c) 2005,2006,2007 Christopher Kleckner
4
+ # All rights reserved
5
+ #
6
+ # This file is part of the Rio library for ruby.
7
+ #
8
+ # Rio is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Rio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Rio; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # ===============================================================================
22
+ #++
23
+ #
24
+ # To create the documentation for Rio run the command
25
+ # ruby build_doc.rb
26
+ # from the distribution directory.
27
+ #
28
+ # Suggested Reading
29
+ # * RIO::Doc::SYNOPSIS
30
+ # * RIO::Doc::INTRO
31
+ # * RIO::Doc::HOWTO
32
+ # * RIO::Doc::EXAMPLES
33
+ # * RIO::Rio
34
+ #
35
+
36
+ require 'rio/no_warn'
37
+ module RIO
38
+ module IF
39
+ module Grande
40
+
41
+ # Returns the contents of the rio as an array. (See ::Enumerable#to_a)
42
+ #
43
+ # IF::Grande#to_a is implemented in terms of #each so the the following are roughly equivelent
44
+ #
45
+ # ary = ario.to_a
46
+ #
47
+ # ary = []
48
+ # ario.each do |rec|
49
+ # ary << ary
50
+ # end
51
+ #
52
+ # What constitutes an array element is determined by IF::GrandeStream#lines,
53
+ # IF::GrandeStream#bytes, IF::GrandeStream#records, IF::GrandeStream#rows or
54
+ # by an extension such as IF::CSV#csv. IF::GrandeStream#lines is the default.
55
+ #
56
+ # rio('afile.txt').to_a # returns an array of the lines in afile.txt
57
+ #
58
+ # rio('afile.txt').lines(1...3).to_a # an array containing lines 1 and 2 of afile.txt
59
+ #
60
+ # rio('afile.dat').bytes(50).to_a # an array containing the contents of afile.dat broken
61
+ # # up into 50 byte chunks
62
+ #
63
+ # See also IF::Grande#[] (subscript operator)
64
+ #
65
+ def to_a() target.to_a() end
66
+
67
+ # Grande subscript operator.
68
+ #
69
+ # For files this returns all or part of a file as an array.
70
+ #
71
+ # For directories this returns all or some of the entries in a directory
72
+ #
73
+ # === Files
74
+ #
75
+ # This combines the record selection offered by IF::GrandeStream#records with
76
+ # the conversion to an array provided by IF::Grande#to_a. The following two are equivelant:
77
+ # ario[*args]
78
+ # ario.records(*args).to_a
79
+ #
80
+ # What constitutes an array element is determined by IF::GrandeStream#lines, IF::GrandeStream#bytes,
81
+ # or by an extension such as IF::CSV#csv. IF::GrandeStream#lines is the default.
82
+ #
83
+ # Arguments may consist of zero or more integers, ranges, regular expressions, symbols,
84
+ # procs, and arrays
85
+ # An empty argument list selects all records
86
+ #
87
+ # Records are selected as follows.
88
+ # range:: specifies a range of records to be selected (zero based)
89
+ # regexp:: matching records will be selected.
90
+ # integer:: treated like a one element range
91
+ # symbol:: the symbol is sent to each record. Record is selected
92
+ # unless false is returned
93
+ # proc:: the proc is called with the record as an argument.
94
+ # Record is selected unless false is returned
95
+ # array:: the array may contain any of the other selector types. Record is selected
96
+ # unless any of the selectors returns false. (a logical and)
97
+ #
98
+ # A record matching *any* of the selectors will be included in the array. (acts like an _or_)
99
+ #
100
+ # Because this is implemented in terms of the IF::Grande#each,
101
+ # When only record ranges are used to select records,
102
+ # iteration will stop when the recno exceeds the maximum of any range. That is to say
103
+ #
104
+ # This reads one record from a file and returns it
105
+ # rio('bigfile.mp3').bytes(1024)[0]
106
+ # While this reads *all* records from a file and returns the first one
107
+ # rio('bigfile.mp3').bytes(1024).to_a[0]
108
+ #
109
+ # === Directories
110
+ #
111
+ # This combines the entry selection offered by IF::GrandeEntry#entries with
112
+ # the conversion to an array provided by IF::Grande#to_a. The following two are equivelant:
113
+ # ario[*args]
114
+ # ario.entries(*args).to_a
115
+ #
116
+ # Arguments may consist of strings (treated as globs) or regular expressions.
117
+ # An empty argument list selects all entries
118
+ # See ::Dir#glob and ::File::fnmatch? for more in information on _globs_.
119
+ # Be warned that using the '**' glob
120
+ # recurses into directories independently of IF::GrandeEntry#all and using both is unsupported.
121
+ #
122
+ # ario = rio('adir')
123
+ # ario[] # returns an array containg all entries in _adir_
124
+ # ario[/^zippy/] # all entries starting with 'zippy'
125
+ # ario['zippy*'] # same thing
126
+ #
127
+ # As with IF::Grande#each:
128
+ # * Files and directories are returned as Rios
129
+ # * The types of entries is also affected by IF::GrandeEntry#files and IF::GrandeEntry#dirs.
130
+ # rio('adir').files['*.txt'] # array of all .txt files
131
+ # rio('adir').dirs[/^\./] # array of all dot directories
132
+ # * Recursion is enabled using IF::GrandeEntry#all
133
+ # rio('adir').all.files['*.[ch]'] # array of c source files in adir and its subdirecories
134
+ # rio('adir').all.dirs[/^\.svn/] # array of subversion directories in adir and subdirectories
135
+ # * IF::GrandeEntry#files and IF::GrandeEntry#dirs act independently of each other.
136
+ # Specifying both will cause both to be returned.
137
+ # The argument list to IF::Grande#[] will be applied to the closest.
138
+ # rio('adir').files('*.rb').dirs['ruby*'] # array of .rb files and
139
+ # # directories starting with 'ruby'
140
+ # rio('adir').dirs('ruby*').files['*.rb'] # same thing
141
+ #
142
+ # === Lines
143
+ # This section applies similarly to IF::GrandeStream#lines, IF::GrandeStream#bytes,
144
+ # IF::GrandeStream#records, and IF::GrandeStream#rows
145
+ #
146
+ # Using IF::GrandeStream#lines and related methods with a Rio referencing a directory
147
+ # imples IF::GrandeEntry#files and will cause an array of the lines or bytes in the
148
+ # files to be returned. As above,
149
+ # the arguments to the subscript operator will be applied to the closest.
150
+ # rio('adir').lines[] # array of all lines in the files in 'adir'
151
+ # rio('adir').files.lines[] # same thing
152
+ # rio('adir').lines(0..9).files['*.txt'] # array of the first ten lines of all .txt files
153
+ # rio('adir').files('*.txt').lines[0..9] # same thing
154
+ # rio('adir').all.files('*.rb').lines[/^\s*require/] # array of 'require' lines in .rb files in
155
+ # # 'adir and its subdirectories
156
+ #
157
+ # Note the difference between the following similar usages
158
+ # it1 = rio('adir').files('*.rb') # returns a Rio, prepared for selecting ruby files
159
+ # it2 = rio('adir').files['*.rb'] # returns an array of the ruby files
160
+ #
161
+ # The second example above could have been written
162
+ # it2 = it1.to_a
163
+ #
164
+ # Examples:
165
+ #
166
+ # rio('afile.txt').lines[1..2] # array containing the 2nd and 3rd line
167
+ #
168
+ # rio('afile.txt')[1,3..5] # array containing lines 1,3,4 and 5
169
+ #
170
+ # rio('afile.txt')[/Zippy/] # array of all lines containing 'Zippy'
171
+ #
172
+ # rio('afile.txt')[1,3..5,/Zippy/] # array with lines 1,3,4 and 5 and all lines containing 'Zippy'
173
+ #
174
+ # rio('afile.dat').bytes(50)[] # array containing the contents of afile.dat broken up into 50 byte chunks
175
+ #
176
+ # rio('afile.dat').bytes(50)[0,2] # array containing the first and third such chunk
177
+ #
178
+ # rio('afile.dat').bytes(50).records[0,2] # same thing
179
+ #
180
+ # rio('afile.dat').bytes(50).records(0,2).to_a # once again
181
+ #
182
+ # rio('afile.csv').csv[0..9] # array of the first 10 records of afile.csv parsed by the ::CSV module
183
+ #
184
+ # rio('afile.csv').csv.records[0..9] # same thing
185
+ #
186
+ # rio('afile.csv').csv(';').records[0..9] # same thing using semi-colon as the value separator
187
+ #
188
+ # rio('afile.csv').csv.records[0,/Zippy/] # record 0 and all records containing 'Zippy'
189
+ # # the regexp is matched against the line before parsing by ::CSV
190
+ #
191
+ # rio('adir')[] # array of entries in 'adir'
192
+ #
193
+ # rio('adir')['*.txt'] # array of all .txt entries
194
+ #
195
+ # rio('adir').all['*.txt'] # array of all .txt entries in 'adir and its subdirectories
196
+ #
197
+ # rio('adir').files['*.txt'] # array of all .txt files
198
+ #
199
+ # rio('adir').dirs['CSV'] # array of all CSV directories
200
+ # rio('adir').skipdirs['CSV'] # array of all non-CSV directories
201
+ #
202
+ def [](*selectors) target[*selectors] end
203
+
204
+
205
+
206
+ # Iterate through a rio. Executes the block for each item selected for the Rio.
207
+ # See IF::GrandeStream#lines, IF::GrandeStream#records, IF::GrandeStream#bytes,
208
+ # IF::GrandeEntry#files, IF::GrandeEntry#dirs, IF::Grande#[]
209
+ # and IF::Grande#to_a for more information
210
+ # on how records are selected and what kind of record is passed to the block.
211
+ #
212
+ # IF::Grande#each is the fundemental method for all the Rio grande operators.
213
+ # IF::Grande#to_a and the Rio copy operators
214
+ # IF::Grande#<, IF::Grande#<<, IF::Grande#>>, and IF::Grande#>
215
+ # are all implemented in terms of IF::Grande#each.
216
+ #
217
+ # While IF::Grande#each is fundamental to a Rio, it rarely needs
218
+ # actually be called because all the grande configuration methods will also take a block
219
+ # and call IF::Grande#each if one is given.
220
+ # So the existance of a block after many methods is taken as an implied
221
+ # IF::Grande#each
222
+ #
223
+ # For Rios that refer to files, the item passed to the block is a String containing
224
+ # the line or block as selected by IF::GrandeStream#lines, or IF::GrandeStream#bytes.
225
+ # +lines+ is the default.
226
+ # rio('afile').lines.each { |line| ...}
227
+ #
228
+ # The block passed to +each+ will also accept an optional second parameter which will contain
229
+ # the result of the matching function. What this variable contains depends on the argument
230
+ # to +lines+ that resulted in the match as follows:
231
+ #
232
+ # Regexp:: The MatchData that resulted from the match.
233
+ # Range:: The record number of the matching record.
234
+ # Fixnum:: The record number of the matching record.
235
+ # Proc:: The value returned by the proc.
236
+ # Symbol:: The value resulting from sending the symbol to the String.
237
+ #
238
+ # If no selection arguments were used, this variable will simply contain +true+.
239
+ #
240
+ # rio(??).puts(%w[0:zero 1:one]).rewind.lines(/(\d+):([a-z]+)/) do |line,match|
241
+ # puts("#{match[1]} is spelled '#{match[2]}'")
242
+ # end
243
+ #
244
+ # Produces:
245
+ # 0 is spelled 'zero'
246
+ # 1 is spelled 'one'
247
+ #
248
+ #
249
+ # For Rios that refer to directories, the item passed to the block is a Rio refering to
250
+ # the directory entry.
251
+ #
252
+ # rio('adir').files.each do |file|
253
+ # file.kind_of?(RIO::Rio) # true
254
+ # end
255
+ #
256
+ # In addition, the Rio passed to the block inherits certain attributes from the directory Rio.
257
+ #
258
+ # rio('adir').files.chomp.each do |file| # chomp is ignored for directories,
259
+ # file.each do |line| # chomp attribute is inherited by the file rio
260
+ # # .. line is chomped
261
+ # end
262
+ # end
263
+ #
264
+ # IF::Grande#each returns the Rio which called it.
265
+ #
266
+ # Here are a few illustrative examples
267
+ #
268
+ # * Processing lines in a file
269
+ #
270
+ # rio('f.txt').each { |line| ... } # execute block for every line in the file
271
+ # rio('f.txt').lines.each { |line| ... } # same thing
272
+ # rio('f.txt').lines { |line| ... } # same thing
273
+ #
274
+ # rio('f.txt').chomp.each { |line| ... } # same as above with lines chomped
275
+ # rio('f.txt').chomp { |line| ... } # ditto
276
+ # rio('f.txt').lines.chomp { |line| ... } # ditto
277
+ # rio('f.txt').chomp.lines { |line| ... } # ditto
278
+ #
279
+ # rio('f.txt.gz').gzip.each { |line| ... } # execute block for every line in a gzipped file
280
+ # rio('f.txt.gz').gzip { |line| ... } # same thing
281
+ # rio('f.txt.gz').lines.gzip { |line| ... } # same thing
282
+ #
283
+ # rio('f.txt.gz').gzip.chomp { |line| ... } # chomp lines from a gzipped file
284
+ # rio('f.txt.gz').gzip.chomp.each { |line| ... } # ditto
285
+ # rio('f.txt.gz').chomp.lines.gzip { |line| ... } # ditto
286
+ #
287
+ # rio('f.txt').lines(0..9) { |line| ... } # execute block for the first 10 lines in the file
288
+ # rio('f.txt').lines(0..9).each { |line| ... } # same thing
289
+ #
290
+ # rio('f.txt').lines(/^\s*#/) { |line| ... } # execute block for comment-only lines
291
+ # rio('f.txt').lines(/^\s*#/).each { |line| ... } # same thing
292
+ #
293
+ # rio('f.txt').lines(0,/Rio/) { |line| ... } # execute block for the first line and
294
+ # # all lines containing 'Rio'
295
+ #
296
+ # rio('f.txt.gz').gzip.chomp.lines(0..1) { |line| ... } # first 2 lines chomped from a gzip file
297
+ #
298
+ # * Processing a file a block at a time
299
+ #
300
+ # rio('f.dat').bytes(10).each { |data| ... } # process the file 10 bytes at a time
301
+ # rio('f.dat').bytes(10) { |data| ... } # same thing
302
+ # rio('f.dat').bytes(10).records(2,4) { |data| ... } # only 3rd and 5th ten-byte data-block
303
+ # rio('f.dat.gz').gzip.records(2,4).bytes(10) { |data| ... } # same from a gzipped file
304
+ #
305
+ # * Iterating over directories
306
+ # rio('adir').each { |ent| ... } # execute the block for each entry in the directory 'adir'
307
+ # rio('adir').files.each { |file| ...} # only files
308
+ # rio('adir').files { |file| ...} # ditto
309
+ # rio('adir').all.files { |file| ...} # files, recurse into subdirectories
310
+ # rio('adir').dirs { |dir| ...} # only directories
311
+ # rio('adir').files('*.rb') { |file| ...} # only .rb files using a glob
312
+ # rio('adir').files(/\.rb$/) { |file| ...} # only .rb files using a regular expression
313
+ # rio('adir').all.files('*.rb') { |file| ...} # .rb files, recursing into subdirectories
314
+ # rio('adir').dirs(/^\./) { |dir| ... } # only dot directories
315
+ # rio('adir').dirs('/home/*') { |dir| ... } # home directories
316
+ #
317
+ # See RIO::Doc::HOWTO and RIO::Doc::SYNOPSIS for more examples, and RIO::Doc::INTRO for further explanation.
318
+ #
319
+ def each(*args,&block) target.each(*args,&block); self end
320
+
321
+
322
+ # For a file Rio +delete+ calls FileUtils#rm.
323
+ # For a directory Rio +delete+ calls FileUtils#rmdir
324
+ # Returns the Rio. If the Rio does not exist, simply return the Rio.
325
+ #
326
+ # rio('afile,txt').delete # delete 'afile.txt'
327
+ # rio('adir').delete # delete adir
328
+ # rio('something').delete # delete something
329
+ #
330
+ def delete() target.delete(); self end
331
+
332
+ # See IF::Grande#delete
333
+ def unlink() target.unlink(); self end
334
+
335
+ # For a file IF::Grande#delete! calls FileUtils#rm.
336
+ # For a directory IF::Grande#delete! calls FileUtils#rmtree.
337
+ # Returns the Rio. If the rio does not exist, simply returns itself.
338
+ #
339
+ # rio('afile,txt').delete! # delete f.txt
340
+ # rio('adir').delete! # delete adir
341
+ #
342
+ # # create a directory, after deleting anything that previously had its name
343
+ # rio('adir/asubdir').delete!.mkpath
344
+ #
345
+ # ==== Deleting Summary
346
+ # * To delete something only if it is not a directory use IF::File#rm
347
+ # * To delete an empty directory use IF::Dir#rmdir
348
+ # * To delete an entire directory tree use IF::Dir#rmtree
349
+ # * To delete anything except a populated directory use IF::Grande#delete
350
+ # * To delete anything use IF::Grande#delete!
351
+ #
352
+ # In all cases, deleting something that does not exist is considered successful.
353
+ #
354
+ def delete!() target.delete!(); self end
355
+
356
+ # Grande Copy-To Operator
357
+ #
358
+ # The copy grande-operator copies a Rio to a another Rio or another ruby object. The behaviour
359
+ # and the library used depend on the types of the of the source and destination. For
360
+ # simple file or directory copying ::FileUtils#cp or ::FileUtils#cp_r will be used. If
361
+ # any of the Rio grande methods are specified for the source or destination, the
362
+ # source Rio will be iterated through copying records to the destintion as specified. Roughly
363
+ # equivelant to
364
+ # dst = rio('dst_file')
365
+ # rio('src_file').each do |line|
366
+ # dst.print(line)
367
+ # end
368
+ # dst.close
369
+ #
370
+ # The destination of the copy operators may be a:
371
+ # IO:: Each record of the Rio is written to the IO using IO#print. The IO must be opened for writing.
372
+ # Array:: Each record or entry of the Rio becomes an element of the array
373
+ # String:: Puts the entire contents of the Rio into the string
374
+ # Rio:: Depends on the destination. See below.
375
+ #
376
+ # Copy a file to a file
377
+ # rio('src_file') > rio('dst_file')
378
+ #
379
+ # Copy a file to a directory
380
+ # rio('src_file') > rio('dst_dir')
381
+ #
382
+ # Copy a directory to another directory
383
+ # rio('src_dir') > rio('dst_dir')
384
+ #
385
+ # Make an ungizipped copy of a gzipped file
386
+ # rio('src.txt.gz').gzip > rio('dst.txt')
387
+ #
388
+ # Copying to an array
389
+ # rio('afile') > ary # each line of the file becomes an element of the ary
390
+ # rio('afile').chomp > ary # same thing with lines chomped
391
+ # rio('afile.gz').gzip.chomp > ary # same thing from a gzipped file
392
+ #
393
+ # rio('afile').lines(0..9) > ary # ary will contain only the first ten lines of the file
394
+ # rio('afile').chomp.lines(0..9) > ary # same thing with lines chomped
395
+ # rio('afile').gzip.chomp.lines(0..9) > ary # same thing from a gzipped file
396
+ #
397
+ # rio('afile').skiplines(0..9) > ary # ary will contain all but the first ten lines of the file
398
+ #
399
+ # rio('adir') > ary # ary will contain a Rio for each entry in the directory
400
+ # rio('adir').files > ary # same, but only files
401
+ # rio('adir').files('*.rb') >ary # same, but only .rb files
402
+ #
403
+ # Copying to a string
404
+ # rio('afile') > astring # slurp the entire contents of the file into astring
405
+ # astring = rio('afile').contents # same effect
406
+ #
407
+ # Copy the first line *and* every line containing the word Rio into a gzipped file
408
+ # rio('src').lines(1,/Rio/) > rio('dst.gz').gzip
409
+ #
410
+ # Copy lines of a web page into an array with each line chomped
411
+ # rio('http://ruby-doc.org/index.html').chomp > an_array
412
+ #
413
+ # Copy the first and 8th through 10th columns of the first ten rows of a gzipped csv
414
+ # file on a web site into a local gzipped csv file that uses semi-colons as separators
415
+ # rio('http://host/file.csv.gz').columns(0,7..9).gzip.csv[0..9] > rio('localfile.csv.gz').csv(';').gzip
416
+ #
417
+ # See also IF::Grande#>>, IF::Grande#|
418
+ #
419
+ def >(destination)
420
+ RIO::no_warn {
421
+ target > destination;
422
+ }
423
+ self
424
+ end
425
+
426
+ # Alias for IF::Grande#> (copy-to grande operator)
427
+ def copy_to(destination) target.copy_to(destination); self end
428
+
429
+
430
+ # Grande Pipe Operator
431
+ #
432
+ # The Rio pipe operator is actually an alternative syntax for calling the IF::Grande#> (copy-to)
433
+ # operator, designed to
434
+ # allow several copy operation to be performed in one line of code, with behavior that mimics
435
+ # the pipe operator commonly available in shells.
436
+ #
437
+ # If +destination+ is a +cmdio+, a <tt>cmdpipe</tt> Rio is returned, and none of the commands are run.
438
+ #
439
+ # Otherwise the +cmdpipe+ Rio is run with the output of the pipe being copied to the destination.
440
+ # In this case a Rio representing the +destination+ is returned.
441
+ #
442
+ # If destination is not a Rio it is passed to the Rio constructor as is done with the copy-to operator
443
+ # except that if +destination+ is a String it is assumed to be a command instead of a path.
444
+ #
445
+ # rio('afile') | rio(?-,'grep i') | rio(?-) # returns rio(?-)
446
+ # # equivelent to rio(?-, 'grep i') < rio('afile') > rio(?-)
447
+ #
448
+ # rio('infile') | rio(?-, 'acmd') | rio(?-, 'acmd2') | rio('outfile')
449
+ # # same as
450
+ # # acmd = rio(?-,'acmd')
451
+ # # acmd2 = rio(?-,'acmd2')
452
+ # # out = rio('outfile')
453
+ # # acmd < rio('infile')
454
+ # # acmd2 < acmd
455
+ # # out < acmd2
456
+ #
457
+ # rio('afile') | 'acmd' | 'acmd2' | rio('outfile') # same thing
458
+ #
459
+ # acmdpipe = rio(?-,'acmd') | 'acmd2'
460
+ # rio('afile') | acmdpipe | rio('outfile') # same thing
461
+ #
462
+ # acmdpipe1 = rio(?|,'acmd','acmd2')
463
+ # rio('afile') | acmdpipe1 | rio('outfile') # same thing
464
+ #
465
+ # acmdpipe2 = rio('afile') | 'acmd' | 'acmd2'
466
+ # acmdpipe2 | rio('outfile') # same thing
467
+ #
468
+ # The grande pipe operator can not be used to create a +cmdpipe+ Rio that includes a destination.
469
+ # This must be done using a Rio constructor
470
+ # cmd_with_output = rio(?|,'acmd',rio('outfile'))
471
+ # rio('afile') | cmd_with_output # same as above
472
+ #
473
+ def |(destination) target | destination end
474
+
475
+ # Grande Append-To Operator
476
+ #
477
+ # The append-to grande-operator is the same as IF::Grande#> (copy-to) except that it opens the destination
478
+ # for append.
479
+ # The destination can be a kind of:
480
+ # IO:: Each record of the Rio is written to the IO using IO#print. The IO must be opened for writing.
481
+ # Array:: Each record or entry of the Rio is appended to the destination array
482
+ # String:: Appends the entire contents of the Rio to destination
483
+ # Rio:: Just like IF::Grande#> (copy-to) except the unopened object are
484
+ # opened for append. If the destination is already opened for writing or is a
485
+ # directory, this is identical to IF::Grande#> (copy-to)
486
+ #
487
+ # See IF::Grande#> (copy-to)
488
+ #
489
+ # rio('afile') >> rio('anotherfile') # append the contents of 'afile' to 'anotherfile'
490
+ # rio('afile') >> rio('adir') # copies 'afile' to the directory 'adir'
491
+ # rio('adir') >> rio('anotherdir') # copy directory 'adir' recursively to 'anotherdir'
492
+ # rio('adir') >> array # a Rio for each entry in the directory will be appended to ary
493
+ def >>(destination) target >> destination; self end
494
+
495
+
496
+ # Alias for IF::Grande#>> (append-to grande operator)
497
+ def append_to(destination) target.append_to(destination); self end
498
+
499
+
500
+ # Grande Append-From Operator
501
+ #
502
+ # The append-from grande-operator copies a Rio from another Rio or another ruby object. This
503
+ # behaves like IF::Grande#< (copy-from) except unopened Rios are opened for append.
504
+ #
505
+ # The following summarizes how objects are copied:
506
+ # IO:: IO#each is used to iterate through the source with each record appended to the Rio
507
+ # Array:: Each element of the Array is appended individually to the Rio.
508
+ # String:: The string is appended to the Rio using IF::RubyIO#print
509
+ # Rio:: The source Rio is appended using its IF::Grande#>> (append-to) operator
510
+ #
511
+ # See IF::Grande#< (copy-from)
512
+ def <<(source) target << source; self end
513
+
514
+
515
+ # Alias for IF::Grande#<< (append-from grande operator)
516
+ def append_from(source) target.append_from(source); self end
517
+
518
+
519
+ # Grande Copy-From Operator
520
+ #
521
+ # The copy-from grande-operator copies a Rio from another Rio or another ruby object.
522
+ # Its operation is dependent on the the file system objects referenced, the rio
523
+ # options set, and the state of its source and destination. In the broadest of terms
524
+ # it could be described as doing the following:
525
+ # source.each do |entry|
526
+ # destination << entry
527
+ # end
528
+ # That is to say, it iterates through its argument, calling the copy-from operator
529
+ # again for each element. While it is not implemented like this, and the above code would
530
+ # not give the same results, This generalized description is convenient.
531
+ #
532
+ # For example the code:
533
+ #
534
+ # destination < source
535
+ # is like
536
+ # source.each { |element| destination << element }
537
+ #
538
+ # for any of the following definitions of src and dst
539
+ # * copying files
540
+ # src = rio('afile')
541
+ # dst = rio('acopy')
542
+ # * copying parts of files
543
+ # src = rio('afile').lines(0..9)
544
+ # dst = rio('acopy')
545
+ # * copying directories
546
+ # src = rio('srcdir')
547
+ # dst = rio('dstdir')
548
+ # * copy directories selectively
549
+ # src = rio('srcdir').dirs(/^\./).files('*.tmp')
550
+ # dst = rio('dstdir')
551
+ # * copying to a file from an array
552
+ # src = ["line0\n","line1\n"]
553
+ # dst = rio('afile')
554
+ # * copying to a directory from an array
555
+ # array = [rio("file1"),rio("file2")]
556
+ # dst = rio('adir')
557
+ #
558
+ # Arrays are handled differently depending on whether the rio references a file or a directory.
559
+ # * If the destination is a file.
560
+ # dest = rio('afile')
561
+ # dest < array
562
+ # # is roughly equivelent to
563
+ # array.each do |el|
564
+ # case el
565
+ # when ::String then dest.print(el)
566
+ # when ::Rio then dest << el
567
+ # else dest << rio(el)
568
+ # end
569
+ # * If the destination is a directory
570
+ # dest = rio('adir')
571
+ # dest < array
572
+ # # is roughly equivelent to
573
+ # array.each do |el|
574
+ # case el
575
+ # when ::String then rio(el)
576
+ # when ::Rio then dest << el
577
+ # else dest << rio(el)
578
+ # end
579
+ #
580
+ # To improve run-time efficiency, Rio will choose from among several strategies when
581
+ # copying. For instance when no file or directory filtering is specified, FileUtils#cp_r is
582
+ # used to copy directories; and when no line filtering is specified, FileUtils#cp is used to copy
583
+ # files.
584
+ #
585
+ # rio('adir') < rio('anotherdir') # 'anotherdir' is copied to 'adir' using FileUtils#cp_r
586
+ # rio('adir') < rio('anotherdir').files('*.rb') # copy only .rb files
587
+ # rio('afile') < rio('anotherfile') # 'anotherfile' is copied to 'afile' using FileUtils#cp
588
+ # rio('afile') < ios # ios must be an IO object opened for reading
589
+ # rio('afile') < astring # basically the same as rio('afile').print(astring)
590
+ #
591
+ # anarray = [ astring, rio('anotherfile') ]
592
+ # rio('afile') < anarray # copies each element to 'afile' as if one had written
593
+ # ario = rio('afile')
594
+ # anarray.each do |el|
595
+ # ario << el
596
+ # end
597
+ # ario.close
598
+ # rio('skeldir') < rio('adir').dirs # copy only the directory structure
599
+ # rio('destdir') < rio('adir').dirs.files(/^\./) # copy the directory structure and all dot files
600
+ #
601
+ # See also IF::Grande#> (copy-to), IF::Grande#each, IF::Grande#[]
602
+ #
603
+ def <(source)
604
+ RIO::no_warn {
605
+ target < source
606
+ }
607
+ self
608
+ end
609
+
610
+ # Alias for IF::Grande#< (copy-from grande operator)
611
+ def copy_from(source) target.copy_from(source); self end
612
+
613
+
614
+ # Reads and returns the next record or entry from a Rio,
615
+ # honoring the grande selection methods.
616
+ #
617
+ # Returns nil on end of file.
618
+ #
619
+ # See also IF::GrandeStream#records, IF::GrandeStream#lines, IF::Grande#each, IF::Grande#[]
620
+ #
621
+ # ario = rio('afile').lines(10..12)
622
+ # line10 = ario.get
623
+ # line11 = ario.get
624
+ # line12 = ario.get
625
+ # a_nil = ario.get
626
+ #
627
+ # ario = rio('adir').entries('*.txt')
628
+ # ent1 = ario.get
629
+ # ent2 = ario.get
630
+ #
631
+ def get() target.get() end
632
+
633
+ # Grande Exclude method
634
+ #
635
+ # +skip+ can be used in two ways.
636
+ #
637
+ #
638
+ # ==== skip with no arguments
639
+ #
640
+ # If called with no arguments it reverses the polarity of the
641
+ # next non-skip grande selection method that is called. That is,
642
+ # it turns +lines+, +records+, +rows+, +files+, +dirs+ and +entries+
643
+ # into +skiplines+, +skiprecords+, +skiprows+, +skipfiles+,
644
+ # +skipdirs+, and +skipentries+, respectively.
645
+ #
646
+ # rio('afile').skip.lines(0..5) # same as rio('afile').skiplines(0..5)
647
+ # rio('adir').skip.files('*~') # same as rio('adir').skipfiles('*~')
648
+ #
649
+ # Note that it only affects the next selection method seen -- and may be
650
+ # used more than once. If no grande selection method is seen, +skip+ is
651
+ # ignored.
652
+ #
653
+ # ==== skip with arguments
654
+ #
655
+ # When called with arguments it acts like IF::GrandeEntry#skipentries for directory
656
+ # Rios and like IF::GrandeStream#skiprecords for stream Rios.
657
+ #
658
+ # rio('afile').lines(/Rio/).skip[0..4] # lines containg 'Rio' excluding the
659
+ # # first five lines
660
+ #
661
+ # rio('adir').files('*.rb').skip[:symlink?] # .rb files, but not symlinks to
662
+ # # .rb files
663
+ #
664
+ # If a block is given, behaves as if <tt>skip(*args).each(&block)</tt> had been called.
665
+ #
666
+ # Returns the Rio.
667
+ #
668
+ # See IF::GrandeStream#skiplines, IF::GrandeStream#skiprecords, IF::GrandeStream#skiprows,
669
+ # IF::GrandeEntry#skipfiles, IF::GrandeEntry#skipdirs, and IF::GrandeEntry#skipentries.
670
+ #
671
+ def skip(*args,&block) target.skip(*args,&block); self end
672
+
673
+
674
+ # Returns true if the referenced file or directory is empty after honoring the grande
675
+ # selection methods.
676
+ #
677
+ # rio('f0').delete!.touch.empty? #=> true
678
+ # rio('f1').puts!("Not Empty\n").empty? #=> false
679
+ # rio('d0').delete!.mkdir.empty? #=> true
680
+ #
681
+ def empty?() target.empty? end
682
+
683
+ # IF::Grande#split has two distinct behaviors depending on
684
+ # whether or not it is called with an argument.
685
+ #
686
+ # ==== split with no aruments:
687
+ #
688
+ # Returns an array of Rios, one for each path element.
689
+ # (Note that this behavior differs from File#split.)
690
+ #
691
+ # rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
692
+ #
693
+ # The array returned is extended with a +to_rio+ method,
694
+ # which will put the parts back together again.
695
+ #
696
+ # ary = rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
697
+ # ary.to_rio #=> rio('a/b/c')
698
+ #
699
+ # ary = rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
700
+ # ary[1] = rio('d')
701
+ # ary.to_rio #=> rio('a/d/c')
702
+ #
703
+ # See also IF::Path#join, IF::Path#/, IF::Path#splitpath
704
+ #
705
+ # ==== split with an argument:
706
+ #
707
+ # This causes String#split(arg) to be called on every line
708
+ # before it is returned. An array of the split lines is
709
+ # returned when iterating
710
+ #
711
+ # rio('/etc/passwd').split(':').columns(0,2) { |ary|
712
+ # username,uid = ary
713
+ # }
714
+ #
715
+ # rio('/etc/passwd').split(':').columns(0,2).to_a #=> [[user1,uid1],[user2,uid2]]
716
+ #
717
+ #
718
+ def split(*args,&block) target.split(*args,&block) end
719
+
720
+
721
+ end
722
+ end
723
+ end
724
+
725
+ module RIO
726
+ class Rio
727
+ #include RIO::IF::Grande
728
+ end
729
+ end