Class: Shell::CommandProcessor

Inherits:
Object
  • Object
show all
Defined in:
lib/shell/command-processor.rb

Constant Summary

NoDelegateMethods =
m

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (CommandProcessor) initialize(shell)

A new instance of CommandProcessor



64
65
66
67
# File 'lib/shell/command-processor.rb', line 64

def initialize(shell)
  @shell = shell
  @system_commands = {}
end

Class Method Details

+ (Object) add_delegate_command_to_shell(id)


class initializing methods  -



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'lib/shell/command-processor.rb', line 519

def self.add_delegate_command_to_shell(id)
  id = id.intern if id.kind_of?(String)
  name = id.id2name
  if Shell.method_defined?(id)
	Shell.notify "warn: override definition of Shell##{name}."
	Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
	Shell.module_eval "alias #{name}_org #{name}"
  end
  Shell.notify "method added: Shell##{name}.", Shell.debug?
  Shell.module_eval(%Q[def #{name}(*args, &block)
   begin
     @command_processor.__send__(:#{name}, *args, &block)
   rescue Exception
     $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
                   $@.delete_if{|s| /^\\(eval\\):/ =~ s}
   raise
   end
                      end], __FILE__, __LINE__)

  if Shell::Filter.method_defined?(id)
	Shell.notify "warn: override definition of Shell::Filter##{name}."
	Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
	Filter.module_eval "alias #{name}_org #{name}"
  end
  Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
  Filter.module_eval(%Q[def #{name}(*args, &block)
   begin
     self | @shell.__send__(:#{name}, *args, &block)
   rescue Exception
     $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
                   $@.delete_if{|s| /^\\(eval\\):/ =~ s}
   raise
   end
                      end], __FILE__, __LINE__)
end

+ (Object) alias_command(ali, command, *opts, &block)



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/shell/command-processor.rb', line 410

def self.alias_command(ali, command, *opts, &block)
  ali = ali.id2name if ali.kind_of?(Symbol)
  command = command.id2name if command.kind_of?(Symbol)
  begin
	if iterator?
	  @alias_map[ali.intern] = proc

	  eval((d = %Q[def #{ali}(*opts)
                      @shell.__send__(:#{command},
                                      *(CommandProcessor.alias_map[:#{ali}].call *opts))
             end]), nil, __FILE__, __LINE__ - 1)

	else
       args = opts.collect{|opt| '"' + opt + '"'}.join(",")
       eval((d = %Q[def #{ali}(*opts)
                      @shell.__send__(:#{command}, #{args}, *opts)
                    end]), nil, __FILE__, __LINE__ - 1)
	end
  rescue SyntaxError
	Shell.notify "warn: Can't alias #{ali} command: #{command}."
	Shell.notify("Definition of #{ali}: ", d)
	raise
  end
  Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
  Shell.notify("Definition of #{ali}: ", d,
  Shell.debug.kind_of?(Integer) && Shell.debug > 1)
  self
end

+ (Object) alias_map



407
408
409
# File 'lib/shell/command-processor.rb', line 407

def self.alias_map
  @alias_map
end

+ (Object) def_builtin_commands(delegation_class, command_specs)

CommandProcessor.def_builtin_commands(delegation_class, command_specs)

delegation_class: Class or Module
command_specs: [[command_name, [argument,...]],...]
   command_name: String
   arguments:	   String

FILENAME?? -> expand_path(filename??) *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ") define command_name(argument,...) as

delegation_class.command_name(argument,...)


456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
# File 'lib/shell/command-processor.rb', line 456

def self.def_builtin_commands(delegation_class, command_specs)
  for meth, args in command_specs
	arg_str = args.collect{|arg| arg.downcase}.join(", ")
	call_arg_str = args.collect{
	  |arg|
	  case arg
	  when /^(FILENAME.*)$/
 format("expand_path(%s)", $1.downcase)
	  when /^(\*FILENAME.*)$/
 # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
 $1.downcase + '.collect{|fn| expand_path(fn)}'
	  else
 arg
	  end
	}.join(", ")
	d = %Q[def #{meth}(#{arg_str})
  #{delegation_class}.#{meth}(#{call_arg_str})
		 end]
	Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
	Shell.notify("Definition of #{meth}: ", d,
   Shell.debug.kind_of?(Integer) && Shell.debug > 1)
	eval d
  end
end

+ (Object) def_system_command(command, path = command)

CommandProcessor.def_system_command(command, path)

command:  String
path:	    String

define 'command()' method as method.



380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/shell/command-processor.rb', line 380

def self.def_system_command(command, path = command)
  begin
	eval((d = %Q[def #{command}(*opts)
 	          SystemCommand.new(@shell, '#{path}', *opts)
           end]), nil, __FILE__, __LINE__ - 1)
  rescue SyntaxError
	Shell.notify "warn: Can't define #{command} path: #{path}."
  end
  Shell.notify "Define #{command} path: #{path}.", Shell.debug?
  Shell.notify("Definition of #{command}: ", d,
  Shell.debug.kind_of?(Integer) && Shell.debug > 1)
end

+ (Object) initialize



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/shell/command-processor.rb', line 34

def self.initialize

  install_builtin_commands

  # define CommandProcessor#methods to Shell#methods and Filter#methods
  for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
	add_delegate_command_to_shell(m)
  end

  def self.method_added(id)
	add_delegate_command_to_shell(id)
  end
end

+ (Object) install_builtin_commands

define default builtin commands



558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
# File 'lib/shell/command-processor.rb', line 558

def self.install_builtin_commands
  # method related File.
  #	(exclude open/foreach/unlink)
  normal_delegation_file_methods = [
	["atime", ["FILENAME"]],
	["basename", ["fn", "*opts"]],
	["chmod", ["mode", "*FILENAMES"]],
	["chown", ["owner", "group", "*FILENAME"]],
	["ctime", ["FILENAMES"]],
	["delete", ["*FILENAMES"]],
	["dirname", ["FILENAME"]],
	["ftype", ["FILENAME"]],
	["join", ["*items"]],
	["link", ["FILENAME_O", "FILENAME_N"]],
	["lstat", ["FILENAME"]],
	["mtime", ["FILENAME"]],
	["readlink", ["FILENAME"]],
	["rename", ["FILENAME_FROM", "FILENAME_TO"]],
	#      ["size", ["FILENAME"]],
	["split", ["pathname"]],
	["stat", ["FILENAME"]],
	["symlink", ["FILENAME_O", "FILENAME_N"]],
	["truncate", ["FILENAME", "length"]],
	["utime", ["atime", "mtime", "*FILENAMES"]]]

  def_builtin_commands(File, normal_delegation_file_methods)
  alias_method :rm, :delete

  # method related FileTest
  def_builtin_commands(FileTest,
 FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})

end

+ (Object) install_system_commands(pre = "sys_")

CommandProcessor.install_system_commands(pre)

pre: String - command name prefix

defines every command which belongs in default_system_path via CommandProcessor.command(). It doesn't define already defined methods twice. By default, "pre_" is prefixes to each method name. Characters that may not be used in a method name are all converted to '_'. Definition errors are just ignored.



490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/shell/command-processor.rb', line 490

def self.install_system_commands(pre = "sys_")
  defined_meth = {}
  for m in Shell.methods
	defined_meth[m] = true
  end
  sh = Shell.new
  for path in Shell.default_system_path
	next unless sh.directory? path
	sh.cd path
	sh.foreach do
	  |cn|
	  if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
 command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
 begin
   def_system_command(command, sh.expand_path(cn))
 rescue
   Shell.notify "warn: Can't define #{command} path: #{cn}"
 end
 defined_meth[command] = command
	  end
	end
  end
end

+ (Object) method_added(id)



43
44
45
# File 'lib/shell/command-processor.rb', line 43

def self.method_added(id)
	add_delegate_command_to_shell(id)
end

+ (Object) run_config

include run file.



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/shell/command-processor.rb', line 51

def self.run_config
  begin
	load File.expand_path("~/.rb_shell") if ENV.key?("HOME")
  rescue LoadError, Errno::ENOENT
  rescue
	print "load error: #{rc}\n"
	print $!.class, ": ", $!, "\n"
	for err in $@[0, $@.size - 2]
	  print "\t", err, "\n"
	end
  end
end

+ (Object) unalias_command(ali)



439
440
441
442
443
# File 'lib/shell/command-processor.rb', line 439

def self.unalias_command(ali)
  ali = ali.id2name if ali.kind_of?(Symbol)
  @alias_map.delete ali.intern
  undef_system_command(ali)
end

+ (Object) undef_system_command(command)



393
394
395
396
397
398
399
# File 'lib/shell/command-processor.rb', line 393

def self.undef_system_command(command)
  command = command.id2name if command.kind_of?(Symbol)
  remove_method(command)
  Shell.module_eval{remove_method(command)}
  Filter.module_eval{remove_method(command)}
  self
end

Instance Method Details

- (Object) append(to, filter)



318
319
320
321
322
323
324
325
326
327
# File 'lib/shell/command-processor.rb', line 318

def append(to, filter)
  case to
  when String
	AppendFile.new(@shell, to, filter)
  when IO
	AppendIO.new(@shell, to, filter)
  else
	Shell.Fail Error::CantApplyMethod, "append", to.class
  end
end

- (Object) cat(*filenames)



306
307
308
# File 'lib/shell/command-processor.rb', line 306

def cat(*filenames)
  Cat.new(@shell, *filenames)
end

- (Object) check_point Also known as: finish_all_jobs

ProcessCommand#transact



282
283
284
# File 'lib/shell/command-processor.rb', line 282

def check_point
  @shell.process_controller.wait_all_jobs_execution
end

- (Object) concat(*jobs)



333
334
335
# File 'lib/shell/command-processor.rb', line 333

def concat(*jobs)
  Concat.new(@shell, *jobs)
end

- (Object) echo(*strings)



302
303
304
# File 'lib/shell/command-processor.rb', line 302

def echo(*strings)
  Echo.new(@shell, *strings)
end

- (Object) expand_path(path)

CommandProcessor#expand_path(path)

path:	  String
return: String

returns the absolute path for <path>



75
76
77
# File 'lib/shell/command-processor.rb', line 75

def expand_path(path)
  @shell.expand_path(path)
end

- (Object) find_system_command(command)

private functions



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/shell/command-processor.rb', line 350

def find_system_command(command)
  return command if /^\// =~ command
  case path = @system_commands[command]
  when String
	if exists?(path)
	  return path
	else
	  Shell.Fail Error::CommandNotFound, command
	end
  when false
	Shell.Fail Error::CommandNotFound, command
  end

  for p in @shell.system_path
	path = join(p, command)
	if FileTest.exist?(path)
	  @system_commands[command] = path
	  return path
	end
  end
  @system_commands[command] = false
  Shell.Fail Error::CommandNotFound, command
end

- (Object) foreach(path = nil, *rs)

File related commands Shell#foreach Shell#open Shell#unlink Shell#test

-

CommandProcessor#foreach(path, rs)

path: String
rs:	String - record separator
iterator

Same as:

File#foreach (when path is file)
Dir#foreach (when path is directory)

path is relative to pwd



97
98
99
100
101
102
103
104
105
106
# File 'lib/shell/command-processor.rb', line 97

def foreach(path = nil, *rs)
  path = "." unless path
  path = expand_path(path)

  if File.directory?(path)
	Dir.foreach(path){|fn| yield fn}
  else
	IO.foreach(path, *rs){|l| yield l}
  end
end

- (Object) glob(pattern)

def sort(*filenames)

  Sort.new(self, *filenames)
end


314
315
316
# File 'lib/shell/command-processor.rb', line 314

def glob(pattern)
  Glob.new(@shell, pattern)
end

- (Object) mkdir(*path)

Dir related methods

Shell#mkdir Shell#rmdir

--

CommandProcessor#mkdir(*path)

path: String

same as Dir.mkdir()



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/shell/command-processor.rb', line 215

def mkdir(*path)
  @shell.check_point
  notify("mkdir #{path.join(' ')}")

  perm = nil
  if path.last.kind_of?(Integer)
	perm = path.pop
  end
  for dir in path
	d = expand_path(dir)
	if perm
	  Dir.mkdir(d, perm)
	else
	  Dir.mkdir(d)
	end
	File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
  end
  Void.new(@shell)
end

- (Object) notify(*opts, &block)

%pwd, %cwd -> @pwd



338
339
340
341
342
343
344
345
# File 'lib/shell/command-processor.rb', line 338

def notify(*opts, &block)
  Shell.notify(*opts) {|mes|
	yield mes if iterator?

	mes.gsub!("%pwd", "#{@cwd}")
	mes.gsub!("%cwd", "#{@cwd}")
  }
end

- (Object) open(path, mode = nil, perm = 0666, &b)

CommandProcessor#open(path, mode)

path:	  String
mode:	  String
return: File or Dir

Same as:

File#open (when path is file)
Dir#open  (when path is directory)

mode has an effect only when path is a file



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/shell/command-processor.rb', line 118

def open(path, mode = nil, perm = 0666, &b)
  path = expand_path(path)
  if File.directory?(path)
	Dir.open(path, &b)
  else
	if @shell.umask
	  f = File.open(path, mode, perm)
	  File.chmod(perm & ~@shell.umask, path)
	  if block_given?
 f.each(&b)
	  end
	  f
	else
	  f = File.open(path, mode, perm, &b)
	end
  end
end

- (Object) out(dev = STDOUT, &block)

internal commands



298
299
300
# File 'lib/shell/command-processor.rb', line 298

def out(dev = STDOUT, &block)
  dev.print transact(&block)
end

- (Object) rehash

ProcessCommand#rehash clear command hash table.



275
276
277
# File 'lib/shell/command-processor.rb', line 275

def rehash
  @system_commands = {}
end

- (Object) rmdir(*path)

CommandProcessor#rmdir(*path)

path: String

same as Dir.rmdir()



240
241
242
243
244
245
246
247
248
# File 'lib/shell/command-processor.rb', line 240

def rmdir(*path)
  @shell.check_point
  notify("rmdir #{path.join(' ')}")

  for dir in path
	Dir.rmdir(expand_path(dir))
  end
  Void.new(@shell)
end

- (Object) system(command, *opts)

CommandProcessor#system(command, *opts)

command: String
opts:	   String
return:  SystemCommand

Same as system() function example:

print sh.system("ls", "-l")
sh.system("ls", "-l") | sh.head > STDOUT


260
261
262
263
264
265
266
267
268
269
# File 'lib/shell/command-processor.rb', line 260

def system(command, *opts)
  if opts.empty?
	if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
	  return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
	else
	  command, *opts = command.split(/\s+/)
	end
  end
  SystemCommand.new(@shell, find_system_command(command), *opts)
end

- (Object) tee(file)



329
330
331
# File 'lib/shell/command-processor.rb', line 329

def tee(file)
  Tee.new(@shell, file)
end

- (Object) test(command, file1, file2 = nil) Also known as: []



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/shell/command-processor.rb', line 173

def test(command, file1, file2=nil)
  file1 = expand_path(file1)
  file2 = expand_path(file2) if file2
  command = command.id2name if command.kind_of?(Symbol)

  case command
  when Integer
	if file2
	  top_level_test(command, file1, file2)
	else
	  top_level_test(command, file1)
	end
  when String
	if command.size == 1
	  if file2
 top_level_test(command, file1, file2)
	  else
 top_level_test(command, file1)
	  end
	else
	  if file2
 FileTest.send(command, file1, file2)
	  else
 FileTest.send(command, file1)
	  end
	end
  end
end

- (Object) top_level_test

CommandProcessor#test(command, file1, file2) CommandProcessor#[command, file1, file2]

command: char or String or Symbol
file1:   String
file2:   String(optional)
return: Boolean

same as:

test()	   (when command is char or length 1 string or symbol)
FileTest.command (others)

example:

sh[?e, "foo"]
sh[:e, "foo"]
sh["e", "foo"]
sh[:exists?, "foo"]
sh["exists?", "foo"]


172
# File 'lib/shell/command-processor.rb', line 172

alias top_level_test test

- (Object) transact(&block)



287
288
289
290
291
292
293
# File 'lib/shell/command-processor.rb', line 287

def transact(&block)
  begin
	@shell.instance_eval(&block)
  ensure
	check_point
  end
end

CommandProcessor#unlink(path) same as:

Dir#unlink  (when path is directory)
File#unlink (when path is file)


143
144
145
146
147
148
149
150
151
152
153
# File 'lib/shell/command-processor.rb', line 143

def unlink(path)
  @shell.check_point

  path = expand_path(path)
  if File.directory?(path)
	Dir.unlink(path)
  else
	IO.unlink(path)
  end
  Void.new(@shell)
end