YkLib 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +44 -0
  10. data/Rakefile +6 -0
  11. data/YkLib.gemspec +29 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/YkLib/Yk/__advance__.rb +151 -0
  15. data/lib/YkLib/Yk/__defun__.rb +44 -0
  16. data/lib/YkLib/Yk/__hook__.rb +244 -0
  17. data/lib/YkLib/Yk/__minmax__.rb +123 -0
  18. data/lib/YkLib/Yk/__stdlog.rb +329 -0
  19. data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
  20. data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
  21. data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
  22. data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
  23. data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
  24. data/lib/YkLib/Yk/auto_escseq.rb +5 -0
  25. data/lib/YkLib/Yk/auto_pstore.rb +179 -0
  26. data/lib/YkLib/Yk/bsearch.rb +120 -0
  27. data/lib/YkLib/Yk/clambda.rb +309 -0
  28. data/lib/YkLib/Yk/confLine.rb +423 -0
  29. data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
  30. data/lib/YkLib/Yk/crypt.rb +26 -0
  31. data/lib/YkLib/Yk/debug2 +1 -0
  32. data/lib/YkLib/Yk/debug2.rb +473 -0
  33. data/lib/YkLib/Yk/debugout.rb +139 -0
  34. data/lib/YkLib/Yk/email_tz.rb +533 -0
  35. data/lib/YkLib/Yk/enum_expect.rb +170 -0
  36. data/lib/YkLib/Yk/errlog.rb +5 -0
  37. data/lib/YkLib/Yk/escseq.rb +59 -0
  38. data/lib/YkLib/Yk/eval_alt.rb +281 -0
  39. data/lib/YkLib/Yk/expector.rb +93 -0
  40. data/lib/YkLib/Yk/fetch.rb +556 -0
  41. data/lib/YkLib/Yk/fetch_old.rb +290 -0
  42. data/lib/YkLib/Yk/fib.rb +158 -0
  43. data/lib/YkLib/Yk/file_aux.rb +843 -0
  44. data/lib/YkLib/Yk/file_aux2.rb +919 -0
  45. data/lib/YkLib/Yk/file_aux_old.rb +160 -0
  46. data/lib/YkLib/Yk/filemod.rb +19 -0
  47. data/lib/YkLib/Yk/force_escseq.rb +3 -0
  48. data/lib/YkLib/Yk/generator__.rb +144 -0
  49. data/lib/YkLib/Yk/generator__.rb.org +139 -0
  50. data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
  51. data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
  52. data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
  53. data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
  54. data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
  55. data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
  56. data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
  57. data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
  58. data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
  59. data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
  60. data/lib/YkLib/Yk/indenter/token.rb +1525 -0
  61. data/lib/YkLib/Yk/indenter.rb +1382 -0
  62. data/lib/YkLib/Yk/inot.rb +265 -0
  63. data/lib/YkLib/Yk/intf.rb +815 -0
  64. data/lib/YkLib/Yk/io_aux.rb +1332 -0
  65. data/lib/YkLib/Yk/ioctl.rb +60 -0
  66. data/lib/YkLib/Yk/ipcc.rb +87 -0
  67. data/lib/YkLib/Yk/ipcountry.rb +207 -0
  68. data/lib/YkLib/Yk/ipv4adr.rb +318 -0
  69. data/lib/YkLib/Yk/localmail.rb +276 -0
  70. data/lib/YkLib/Yk/method_chain.rb +359 -0
  71. data/lib/YkLib/Yk/misc_tz.rb +1716 -0
  72. data/lib/YkLib/Yk/missing_method.rb +50 -0
  73. data/lib/YkLib/Yk/mojiConv.rb +257 -0
  74. data/lib/YkLib/Yk/nostdlog.rb +4 -0
  75. data/lib/YkLib/Yk/on_marshal.rb +20 -0
  76. data/lib/YkLib/Yk/overrider.rb +47 -0
  77. data/lib/YkLib/Yk/path.rb +293 -0
  78. data/lib/YkLib/Yk/path_aux.rb +883 -0
  79. data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
  80. data/lib/YkLib/Yk/path_rep.rb +1267 -0
  81. data/lib/YkLib/Yk/pg_setup.rb +917 -0
  82. data/lib/YkLib/Yk/procinfo.rb +314 -0
  83. data/lib/YkLib/Yk/proclist.rb +492 -0
  84. data/lib/YkLib/Yk/property.rb +863 -0
  85. data/lib/YkLib/Yk/ranger.rb +606 -0
  86. data/lib/YkLib/Yk/resolv_tz.rb +88 -0
  87. data/lib/YkLib/Yk/rlprompt.rb +73 -0
  88. data/lib/YkLib/Yk/rootexec.rb +48 -0
  89. data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
  90. data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
  91. data/lib/YkLib/Yk/rwhen.rb +21 -0
  92. data/lib/YkLib/Yk/selector.rb +124 -0
  93. data/lib/YkLib/Yk/set.rb +170 -0
  94. data/lib/YkLib/Yk/shellquote.rb +300 -0
  95. data/lib/YkLib/Yk/sio.rb +1001 -0
  96. data/lib/YkLib/Yk/sio0.rb +835 -0
  97. data/lib/YkLib/Yk/sio_aux.rb +1524 -0
  98. data/lib/YkLib/Yk/sio_inot.rb +86 -0
  99. data/lib/YkLib/Yk/sock_aux.rb +42 -0
  100. data/lib/YkLib/Yk/spipe.rb +843 -0
  101. data/lib/YkLib/Yk/sql_table.rb +565 -0
  102. data/lib/YkLib/Yk/stdlog.rb +4 -0
  103. data/lib/YkLib/Yk/syscommand.rb +173 -0
  104. data/lib/YkLib/Yk/sysinit.rb +75 -0
  105. data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
  106. data/lib/YkLib/Yk/tty_char.dump +0 -0
  107. data/lib/YkLib/Yk/tty_char.rb +47 -0
  108. data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
  109. data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
  110. data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
  111. data/lib/YkLib/Yk/tty_str.rb +461 -0
  112. data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
  113. data/lib/YkLib/Yk/tty_width.rb +180 -0
  114. data/lib/YkLib/Yk/tty_width_available +569 -0
  115. data/lib/YkLib/Yk/tty_width_list +0 -0
  116. data/lib/YkLib/Yk/tty_width_list.linux +280 -0
  117. data/lib/YkLib/Yk/tty_width_list.windows +324 -0
  118. data/lib/YkLib/Yk/tz_tty +0 -0
  119. data/lib/YkLib/Yk/tz_tty.rb +0 -0
  120. data/lib/YkLib/Yk/uprepos.rb +94 -0
  121. data/lib/YkLib/Yk/userinfo.rb +91 -0
  122. data/lib/YkLib/Yk/with.rb +109 -0
  123. data/lib/YkLib/version.rb +3 -0
  124. data/lib/YkLib.rb +6 -0
  125. metadata +170 -0
@@ -0,0 +1,883 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tempfile'
4
+ require 'pathname'
5
+ require 'Yk/file_aux'
6
+ #require 'Yk/missing_method'
7
+
8
+ # IO.read, IO.readlines, IO.foreach, IO.pipe, IO.write, IO.writeln, IO.rewrite_each_line, IO.ref_each_line, IO.addline, IO.delline
9
+ # String#read_each_line
10
+
11
+ module ExecTimeout
12
+ def exec_timeout t
13
+ pid = nil
14
+ r, w = IO.pipe
15
+ pid = fork do
16
+ r.close
17
+ self.exec
18
+ end
19
+ w.close
20
+ res = nil
21
+ tout = false
22
+ begin
23
+ if nil == IO.select([r], nil, nil, t)
24
+ tout = true
25
+ if block_given?
26
+ res = yield pid
27
+ else
28
+ Process.kill :TERM, pid
29
+ end
30
+ end
31
+ ensure
32
+ Process.waitpid pid
33
+ !tout && (res = ($?.to_i == 0))
34
+ end
35
+ return res
36
+ end
37
+ end
38
+
39
+
40
+ class String
41
+ include ExecTimeout
42
+ end
43
+
44
+
45
+ class Array
46
+ include ExecTimeout
47
+ end
48
+
49
+
50
+ class String
51
+ def chext src, dst = nil
52
+ if !dst
53
+ if self =~ /\.([^\.]+)$/
54
+ $` + src
55
+ else
56
+ self + src
57
+ end
58
+ else
59
+ if self =~ /#{Regexp.escape src}$/
60
+ $` + dst
61
+ else
62
+ self + dst
63
+ end
64
+ end
65
+ end
66
+ def chext! src, dst = nil
67
+ replace(chext(src, dst))
68
+ self
69
+ end
70
+ def chextname a, b = nil
71
+ chext a, b
72
+ end
73
+ def chextname! a, b = nil
74
+ chext! a, b
75
+ end
76
+ def to_file
77
+ if File.file? self
78
+ return self
79
+ else
80
+ return nil
81
+ end
82
+ end
83
+ def to_dir
84
+ if File.directory? self
85
+ return self
86
+ else
87
+ return nil
88
+ end
89
+ end
90
+ FCheckList = {
91
+ ?b => :blockdev?,
92
+ ?c => :chardev?,
93
+ ?d => :directory?,
94
+ ?f => :file?,
95
+ ?L => :symlink?,
96
+ ?p => :pipe?,
97
+ ?S => :socket?,
98
+ ?g => :setgid?,
99
+ ?k => :sticky?,
100
+ ?r => :readable?,
101
+ ?u => :setuid?,
102
+ ?w => :writable?,
103
+ ?x => :executable?,
104
+ ?e => :exist?,
105
+ ?s => :size?,
106
+ }
107
+ FCheckList.each do |flag, checkMethod|
108
+ eval %{
109
+ def _#{flag}? &then_proc
110
+ r = File.#{checkMethod}(self)
111
+ if then_proc
112
+ if r
113
+ then_proc.call self
114
+ else
115
+ nil
116
+ end
117
+ else
118
+ r
119
+ end
120
+ end
121
+ }
122
+ end
123
+ alias_method :__org_method_missing__, :method_missing
124
+ def method_missing (name, *args, **opts, &proc)
125
+ if name.to_s =~ /^(ftest|)_(.+)\?$/
126
+ curList = {}
127
+ mCheckName = $2
128
+ if (mCheckName.each_char do |c|
129
+ if !FCheckList.key?(c) || curList[c]
130
+ break :not_ftest
131
+ else
132
+ curList[c] = true
133
+ end
134
+ end) != :not_ftest then
135
+ self.class.class_eval %{
136
+ def _#{mCheckName}? &then_proc
137
+ r = #{mCheckName.chars.map{FCheckList[_1]}.map{"File." + _1.to_s + "(self)"} * "&&"}
138
+ if then_proc
139
+ if r
140
+ then_proc.call self
141
+ else
142
+ nil
143
+ end
144
+ else
145
+ r
146
+ end
147
+ end
148
+ def ftest_#{mCheckName}? &then_proc
149
+ _#{mCheckName}? &then_proc
150
+ end
151
+ }
152
+ res = true
153
+ curList.each_key do |c|
154
+ res &&= FileTest.method(FCheckList[c]).call(self)
155
+ end
156
+ if res && proc
157
+ proc.call
158
+ else
159
+ res
160
+ end
161
+ end
162
+ else
163
+ if IO.respond_to? name
164
+ IO.__send__(name, self, *args, &proc)
165
+ else
166
+ __org_method_missing__ name, *args, **opts, &proc
167
+ end
168
+ end
169
+ end
170
+ def respond_to_missing? name, include_private
171
+ if name.to_s =~ /^(ftest|)_(.*)\?$/
172
+ curList = {}
173
+ if ($2.each_char do |c|
174
+ if !FCheckList.key?(c) || curList[c]
175
+ break :not_ftest
176
+ else
177
+ curList[c] = true
178
+ end
179
+ end) != :not_ftest then
180
+ true
181
+ else
182
+ IO.respond_to? name, include_private
183
+ end
184
+ end
185
+ end
186
+ #delegated from IO
187
+ %w{
188
+ gets readline readlines write
189
+ readln writeln rewrite_each_line ref_each_line
190
+ writeln_readln print println printf printfln addline delline addlines dellines
191
+ }.each do |e|
192
+ if method_defined? e
193
+ raise ArgumentError.new("'#{e}' already defined")
194
+ end
195
+ class_eval %{
196
+ def #{e} (*args, &bl)
197
+ IO.method(:#{e}).call(self, *args, &bl)
198
+ end
199
+ }
200
+ end
201
+ def __http_fetch (limit = 10)
202
+ raise ArgumentError, 'http redirect too deep' if limit == 0
203
+
204
+ response = Net::HTTP.get_response(URI.parse(self))
205
+ case response
206
+ when Net::HTTPSuccess
207
+ response
208
+ when Net::HTTPRedirection
209
+ res = response['location'].__http_fetch(limit - 1)
210
+ if !res['location']
211
+ res['location'] = response['location']
212
+ end
213
+ res
214
+ else
215
+ response.error!
216
+ end
217
+ end
218
+ attr :timeout, true
219
+ def dump_hex
220
+ self.unpack("H*")[0]
221
+ end
222
+ def undump_hex
223
+ [self].pack("H*")
224
+ end
225
+ def __ftp_fetch_file
226
+ d = (Dir.home / ".tmp/Yk/path_aux/wget_cache").check_dir
227
+ save = d / "ftp.#{$0.basename}.#{rand(100000000)}"
228
+ f = d / dump_hex
229
+ if timeout
230
+ f.lock_sh do
231
+ if Time.now - f.mtime < timeout && f.file_size != 0
232
+ yield f
233
+ return
234
+ end
235
+ end
236
+ end
237
+ if File.executable?("/usr/bin/axel")
238
+ if !%W{axel #{self} -o #{save}}.system
239
+ raise Exception.new("cannot read #{self}")
240
+ end
241
+ else
242
+ save.touch
243
+ if !%W{wget #{self} -O #{save}}.system
244
+ raise Exception.new("cannot read #{self}")
245
+ end
246
+ end
247
+ # if self =~ /^ftp:\/\/([^\/]+)(\/|$)/
248
+ # file = $2 + $'.chomp
249
+ # file = "/" if file == ""
250
+ # STDERR.write "accessing #{$1}\n"
251
+ # ftp = Net::FTP.open $1, "anonymous", "anonymous@anonymous.anonymous"
252
+ # begin
253
+ # ftp.binary = true
254
+ # STDERR.write "reading #{file}\n"
255
+ # ftp.get file, save
256
+ # STDERR.write "finished #{file} \n"
257
+ # ensure
258
+ # ftp.close
259
+ # end
260
+ # end
261
+ begin
262
+ f.open "lw" do |fw|
263
+ fw.write save.read
264
+ end
265
+ f.lock_sh do
266
+ yield f
267
+ end
268
+ ensure
269
+ save.rm_f
270
+ end
271
+ end
272
+ def __wget_file
273
+ save = "/var/tmp/wget.#{$0.basename}.#{rand(100000000)}"
274
+ if File.executable?("/usr/bin/axel")
275
+ if !"axel #{!ENV['DEBUG'] ? '-v' : ''} #{self} -o #{save}".system
276
+ raise Exception.new("cannot read #{self}")
277
+ end
278
+ else
279
+ save.touch
280
+ if !"wget #{!ENV['DEBUG'] ? '-q' : ''} #{self} -O #{save}".system
281
+ raise Exception.new("cannot read #{self}")
282
+ end
283
+ end
284
+ begin
285
+ yield save
286
+ ensure
287
+ save.rm_f
288
+ end
289
+ end
290
+ def read_each_line (rs = $/)
291
+ if self =~ /^http:\/\//
292
+ require 'net/http'
293
+ __http_fetch.body.each_line rs do |ln|
294
+ yield ln
295
+ end
296
+ elsif self =~ /^ftp:\/\//
297
+ require 'net/ftp'
298
+ __ftp_fetch_file do |f|
299
+ f.read_each_line rs do |ln|
300
+ yield ln
301
+ end
302
+ end
303
+ else
304
+ IO.read_each_line self do |ln|
305
+ yield ln
306
+ end
307
+ end
308
+ end
309
+ def read (*args)
310
+ if self =~ /^http:\/\//
311
+ require 'net/http'
312
+ f = __http_fetch.body
313
+ args.push
314
+ case args.size
315
+ when 0
316
+ f
317
+ when 1
318
+ length = args[0]
319
+ f[0 ... length]
320
+ when 2
321
+ offset, length = args
322
+ f[offset ... (offset + length)]
323
+ end
324
+ elsif self =~ /^ftp:\/\//
325
+ res = nil
326
+ __wget_file do |f|
327
+ res = f.read
328
+ end
329
+ res
330
+ elsif !exist? && self =~ /^([a-z][\w\-]+[a-z0-9]):/
331
+ host = $1
332
+ escp = Regexp.escape $'
333
+ prog = "require\\ \\'Yk/path_aux\\'\\;print\\'#{escp}\\'.read"
334
+ ret = ""
335
+ ["ssha", $1, "ruby", "-e", prog].read_each_line_p *args do |ln|
336
+ ret += $1 + ":" + ln
337
+ end
338
+ ret
339
+ elsif directory?
340
+ res = ""
341
+ each_entry do |f|
342
+ res += f + "\n"
343
+ end
344
+ res
345
+ else
346
+ IO.read self, *args
347
+ end
348
+ end
349
+ def open (*args, &bl)
350
+ File.open(self, *args, &bl)
351
+ end
352
+ alias_method :org_delete, :delete
353
+ def delete *args
354
+ if args.size == 0
355
+ if self.directory?
356
+ self.rmdir
357
+ else
358
+ File.delete self
359
+ end
360
+ else
361
+ org_delete *args
362
+ end
363
+ end
364
+ def unlink
365
+ delete
366
+ end
367
+ def exist?
368
+ if self =~ /^(http|ftp):\/\//
369
+ begin
370
+ read
371
+ rescue => e
372
+ STDERR.write e.to_s.ln
373
+ return false
374
+ end
375
+ true
376
+ else
377
+ File.exist? self
378
+ end
379
+ end
380
+ def __http_head_location
381
+ require 'net/http'
382
+ response = nil
383
+ self =~ /^http:\/\/([^\/:]+)(:\d+|)/
384
+ if $2 != ""
385
+ prt = $2.to_i
386
+ else
387
+ prt = 80
388
+ end
389
+ Net::HTTP.start($1, prt) {|http|
390
+ response = http.head($')
391
+ }
392
+ response['location']
393
+ end
394
+ def expand_path (defd = nil)
395
+ if self =~ /^http:\/\//
396
+ s = self
397
+ t = nil
398
+ while true
399
+ t = s.__http_head_location
400
+ break if !t
401
+ s = t
402
+ end
403
+ s
404
+ elsif self =~ /^ftp:\/\//
405
+ if self !~ /\/$/
406
+ begin
407
+ (self + "/").__wget_file do
408
+ end
409
+ if $?.to_i == 0
410
+ return self + "/"
411
+ else
412
+ return self
413
+ end
414
+ rescue Exception
415
+ return self
416
+ end
417
+ end
418
+ elsif self !~ /^[a-z][\w\-]+[a-z0-9]:/
419
+ File.expand_path(self, defd)
420
+ else
421
+ self
422
+ end
423
+ end
424
+ #delegated from Dir
425
+ %w{glob chdir chroot lrecursive recursive}.each do |e|
426
+ class_eval %{
427
+ def #{e} (*args, &bl)
428
+ Dir.method(:#{e}).call(self, *args, &bl)
429
+ end
430
+ }
431
+ end
432
+ #delegated from File
433
+ %w{
434
+ atime ctime mtime dirname extname ftype readlink rename stat lstat
435
+ blockdev? chardev? directory? executable? executable_real? file? grpowned? owned?
436
+ identical? pipe? readable? readable_real? setgid? setuid? socket? sticky? symlink? writable?
437
+ writable_real? zero? setpid try_lock_sh lock_ex lock_sh locked_ex? locked_sh?
438
+ readable_file? writable_file? executable_file?
439
+ lexist? lmtime exist? relative_path normalize_path is_in is_in? sibling resymlink resolv_link
440
+ fifo? mknod mkfifo mksock try_lock_ex which
441
+ partial_path delext
442
+ }.each do |e|
443
+ if method_defined? e
444
+ raise ArgumentError.new("'#{e}' already defined")
445
+ end
446
+ class_eval %{
447
+ def #{e} (*args, &bl)
448
+ File.method(:#{e}).call(self, *args, &bl)
449
+ end
450
+ }
451
+ end
452
+ #delegated from Pathname
453
+ %w{
454
+ cd cmp compare_file copy_entry copy_file cp_r install link ln_s ln_sf
455
+ mkdir mkdir_p mkpath makedirs mv move rm remove rm_f safe_unlink rm_r rm_rf rmtree rmdir
456
+ remove_entry remove_entry_secure remove_file touch uptodate?
457
+ }.each do |e|
458
+ if method_defined? e
459
+ raise ArgumentError.new("'#{e}' already defined")
460
+ end
461
+ class_eval %{
462
+ def #{e} (*args, &bl)
463
+ FileUtils.method(:#{e}).call(self, *args, &bl)
464
+ end
465
+ }
466
+ end
467
+ %w{
468
+ cleanpath realpath parent mountpoint? root? relative_path_from
469
+ }.each do |e|
470
+ if method_defined? e
471
+ raise ArgumentError.new("'#{e}' already defined")
472
+ end
473
+ class_eval %{
474
+ def #{e} (*args, &bl)
475
+ ret = Pathname.new(self).method(:#{e}).call(*args, &bl)
476
+ if ret.is_a? Pathname
477
+ ret.to_s
478
+ else
479
+ ret
480
+ end
481
+ end
482
+ }
483
+ end
484
+ def relative?
485
+ if self =~ /(\w+):\/\//
486
+ false
487
+ else
488
+ Pathname.new(self).relative?
489
+ end
490
+ end
491
+ def absolute?
492
+ !relative?
493
+ end
494
+ def chmod (mode, **options)
495
+ FileUtils.chmod(mode, [self], **options)
496
+ end
497
+ def chmod_R (mode, **options)
498
+ FileUtils.chmod_R(mode, [self], **options)
499
+ end
500
+ def lchmod (mode)
501
+ FileUtils.chmod(mode, self)
502
+ end
503
+ def chown (user, group, **options)
504
+ FileUtils.chown(user, group, [self], **options)
505
+ end
506
+ def chown_R (user, group, **options)
507
+ FileUtils.chown(user, group, [self], **options)
508
+ end
509
+ def lchown (user, group)
510
+ File.lchown(user, group, self)
511
+ end
512
+ def / (arg)
513
+ if arg == ?/
514
+ raise ArgumentError.new("cannot concatenate abosolute path")
515
+ elsif self[-1] != ?/
516
+ self + "/" + arg.to_s
517
+ else
518
+ self + arg.to_s
519
+ end
520
+ end
521
+ def cp f
522
+ sesc = nil
523
+ fesc = nil
524
+ if self =~ /^(http|ftp|https):/
525
+ __wget_file do |tmp|
526
+ tmp.mv f
527
+ end
528
+ elsif (self =~ /^[a-z][\w\-]+[a-z0-9]:/ && !exist? && eval("sesc = true")) || (f =~ /^[a-z][\w\-]+[a-z0-9]:/ && !f.exist? && eval("fesc = true"))
529
+ s = Regexp.escape self if sesc
530
+ f = Regexp.escape f if fesc
531
+ ["scpa", s, f].system
532
+ else
533
+ FileUtils.cp self, f
534
+ end
535
+ end
536
+ def copy f
537
+ cp f
538
+ end
539
+ def each_file
540
+ Dir.each self do |e|
541
+ yield e
542
+ end
543
+ end
544
+ def each_entry
545
+ Dir.each self do |e|
546
+ yield e
547
+ end
548
+ end
549
+ def entries
550
+ ret = []
551
+ Dir.each self do |e|
552
+ ret.push e
553
+ end
554
+ ret
555
+ end
556
+ def symlink (arg)
557
+ if File.exist? arg
558
+ raise Errno::EEXIST
559
+ end
560
+ File.symlink self, arg
561
+ end
562
+ def pread_each_line
563
+ IO.popen self do |fr|
564
+ fr.each_line do |ln|
565
+ yield ln
566
+ end
567
+ end
568
+ end
569
+ def file_size
570
+ if self =~ /^([a-z][\w\-]+[a-z0-9]):/ && !exist?
571
+ host = $1
572
+ escp = Regexp.escape $'
573
+ prog = "require\\ \\'Yk/path_aux\\'\\;print\\'#{escp}\\'.file_size.to_s"
574
+ res = ["ssha", host, "ruby", "-e", prog].read_p
575
+ if res =~ /^\d+$/
576
+ return res.to_i
577
+ else
578
+ raise Exception.new("cannot get file size of #{self}")
579
+ end
580
+ else
581
+ File.size(self)
582
+ end
583
+ end
584
+ def relink target
585
+ if !symlink? && _d?
586
+ s = stat
587
+ if target.symlink? || !target._d?
588
+ target.rm_rf
589
+ target.mkdir
590
+ target.chmod s.mode
591
+ target.mtime = s.mtime
592
+ if Process.euid == 0
593
+ target.chown s.uid, s.gid
594
+ end
595
+ else
596
+ t = target.stat
597
+ if s.mode != t.mode
598
+ target.chmod s.mode
599
+ end
600
+ if s.mtime != t.mtime
601
+ target.mtime = s.mtime
602
+ end
603
+ if Process.euid == 0
604
+ if s.uid != t.uid || s.gid != t.gid
605
+ target.chown s.uid, s.gid
606
+ end
607
+ end
608
+ end
609
+ each_entry do |f|
610
+ f.relink target / f.basename
611
+ end
612
+ else
613
+ st = lstat
614
+ if target.exist?
615
+ tst = target.stat
616
+ if (st.dev != tst.dev) || (st.ino != tst.ino)
617
+ target.rm_rf
618
+ link target
619
+ end
620
+ else
621
+ link target
622
+ end
623
+ end
624
+ end
625
+ def each_path
626
+ pth = self
627
+ if pth == ""
628
+ return
629
+ end
630
+ root = false
631
+ if pth =~ /^\/+/
632
+ root = true
633
+ pth = $'
634
+ end
635
+ if pth =~ /\/$/
636
+ pth = $`
637
+ end
638
+ if pth == ""
639
+ yield "/"
640
+ else
641
+ yield "/" if root
642
+ rt = root ? "/" : ""
643
+ arr = pth.split(/\//)
644
+ arr.each_index do |i|
645
+ yield rt + arr[0..i].join("/"), arr[i + 1 .. -1].join("/")
646
+ end
647
+ end
648
+ end
649
+ def reverse_each_path
650
+ pth = self
651
+ if pth == ""
652
+ return
653
+ end
654
+ root = false
655
+ if pth =~ /^\/+/
656
+ root = true
657
+ pth = $'
658
+ end
659
+ if pth =~ /\/$/
660
+ pth = $`
661
+ end
662
+ if pth == ""
663
+ yield "/", ""
664
+ else
665
+ rt = root ? "/" : ""
666
+ arr = pth.split(/\//)
667
+ arr.each_index do |i|
668
+ j = arr.size - i - 1
669
+ yield rt + arr[0..j].join("/"), arr[j + 1 .. -1].join("/")
670
+ end
671
+ yield "/", pth if root
672
+ end
673
+ end
674
+ def basename= (arg)
675
+ if arg != "" && arg != nil
676
+ self.replace(self.dirname + "/" + arg)
677
+ end
678
+ return arg
679
+ end
680
+ def basename (*args)
681
+ ags = []
682
+ n = 0
683
+ args.each do |e|
684
+ if e.is_a? Integer
685
+ n = e
686
+ else
687
+ ags.push e
688
+ end
689
+ end
690
+ if n == 0
691
+ File.basename self, *ags
692
+ else
693
+ pre = self.split(/\//)[-(1 + n)..-2]
694
+ if pre && pre.size > 0
695
+ pre.push File.basename(self, *ags)
696
+ pre.join("/")
697
+ else
698
+ File.basename(self, *ags)
699
+ end
700
+ end
701
+ end
702
+ class ExtManip
703
+ def initialize (str)
704
+ @str = str
705
+ end
706
+ def [] (ext)
707
+ if @str[-ext.size .. -1] == ext
708
+ ext.clone
709
+ else
710
+ nil
711
+ end
712
+ end
713
+ def []= (ext, arg)
714
+ if @str[-ext.size .. -1] == ext
715
+ @str[-ext.size .. -1] = arg
716
+ arg.clone
717
+ else
718
+ nil
719
+ end
720
+ end
721
+ def == ext
722
+ @str[-ext.size .. -1] == ext && ext.size != @str.basename.size
723
+ end
724
+ end
725
+ def ext
726
+ return ExtManip.new(self)
727
+ end
728
+ def check_dir
729
+ if !File.directory? self
730
+ FileUtils.mkdir_p self
731
+ end
732
+ self
733
+ end
734
+ def check_dirname
735
+ if !File.directory?(tmp = File.dirname(self))
736
+ FileUtils.mkdir_p tmp
737
+ end
738
+ self
739
+ end
740
+ def check_file
741
+ if !File.file? self
742
+ FileUtils.touch self
743
+ end
744
+ self
745
+ end
746
+ def mtime= (arg)
747
+ File.utime(File.atime(self), arg, self)
748
+ arg
749
+ end
750
+ DIRSTACK__ = []
751
+ def pushd
752
+ DIRSTACK__.push Dir.pwd
753
+ self.cd
754
+ if block_given?
755
+ begin
756
+ yield self
757
+ ensure
758
+ DIRSTACK__.pop.cd
759
+ end
760
+ end
761
+ end
762
+ def truncate sz = 0
763
+ File.truncate self, sz
764
+ end
765
+ end
766
+
767
+
768
+
769
+
770
+ class Regexp
771
+ def each_entry
772
+ if to_s !~ /^\(\?\-mix:(.*)\)$/
773
+ raise ArgumentError.new("cannot use regular expression option")
774
+ end
775
+ i = 0
776
+ firstFlag = false
777
+ preExpr = ""
778
+ esc = false
779
+ $1.each_byte do |c|
780
+ if !esc
781
+ if c.chr =~ /^\W$/
782
+ case c
783
+ when ?^
784
+ if i != 0
785
+ break
786
+ else
787
+ firstFlag = true
788
+ next
789
+ end
790
+ when ?\\
791
+ esc = true
792
+ next
793
+ else
794
+ if !"!%&=~@`;:,/<> ".include? c
795
+ break
796
+ end
797
+ end
798
+ end
799
+ preExpr += c.chr
800
+ else
801
+ esc = false
802
+ if c.chr =~ /^\W$/
803
+ preExpr += c.chr
804
+ else
805
+ break
806
+ end
807
+ end
808
+ i += 1
809
+ end
810
+ if firstFlag
811
+ fixedDir = nil
812
+ if preExpr[-1] != ?/
813
+ if preExpr.dirname.directory?
814
+ fixedDir = preExpr.dirname
815
+ end
816
+ elsif preExpr.directory?
817
+ fixedDir = preExpr
818
+ end
819
+ if fixedDir
820
+ absolute = fixedDir.absolute?
821
+ fixedDir.recursive do |f|
822
+ if absolute
823
+ if f =~ self
824
+ yield f
825
+ end
826
+ else
827
+ if f[fixedDir.size .. -1] =~ self
828
+ yield f
829
+ end
830
+ end
831
+ end
832
+ end
833
+ else
834
+ if preExpr.absolute?
835
+ raise ArgumentError.new("cannot process all files from root")
836
+ else
837
+ "./".recursive do |f|
838
+ if f[preExpr.size .. -1] =~ self
839
+ yield f
840
+ end
841
+ end
842
+ end
843
+ end
844
+ end
845
+ end
846
+
847
+
848
+ class Array
849
+ def method_missing (name, *args, **opts, &proc)
850
+ if name == :open
851
+ File.open(self, *args, **opts, &proc)
852
+ else
853
+ IO.method(name).(self, *args, **opts, &proc)
854
+ end
855
+ end
856
+ def respond_to_missing? name, include_private
857
+ name == :open or IO.respond_to_missing?(name, include_private)
858
+ end
859
+ #delegated from IO
860
+ %w{
861
+ gets readline readlines write
862
+ readln writeln read_each_line rewrite_each_line ref_each_line
863
+ writeln_readln print println printf printfln addline delline addlines dellines
864
+ }.each do |e|
865
+ if method_defined? e
866
+ raise ArgumentError.new("'#{e}' already defined")
867
+ end
868
+ class_eval %{
869
+ def #{e} (*args, **opts, &bl)
870
+ IO.method(:#{e}).call(self, *args, **opts, &bl)
871
+ end
872
+ }
873
+ end
874
+ def read_12_each **opts
875
+ IO.read_12_each self, **opts
876
+ end
877
+ def popen (*args, &bl)
878
+ if !args[0].include? "p"
879
+ args[0] += "p"
880
+ end
881
+ File.open(self, *args, &bl)
882
+ end
883
+ end