YkLib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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