Module: SOPT

Defined in:
lib/rbbt/util/simpleopt.rb,
lib/rbbt/util/simpleopt/doc.rb,
lib/rbbt/util/simpleopt/get.rb,
lib/rbbt/util/simpleopt/parse.rb,
lib/rbbt/util/simpleopt/setup.rb,
lib/rbbt/util/simpleopt/accessor.rb

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.commandObject

Returns the value of attribute command.



4
5
6
# File 'lib/rbbt/util/simpleopt/doc.rb', line 4

def command
  @command
end

.descriptionObject

Returns the value of attribute description.



4
5
6
# File 'lib/rbbt/util/simpleopt/doc.rb', line 4

def description
  @description
end

.input_defaultsObject

Returns the value of attribute input_defaults.



4
5
6
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 4

def input_defaults
  @input_defaults
end

.input_descriptionsObject

Returns the value of attribute input_descriptions.



4
5
6
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 4

def input_descriptions
  @input_descriptions
end

.input_shortcutsObject

Returns the value of attribute input_shortcuts.



4
5
6
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 4

def input_shortcuts
  @input_shortcuts
end

.input_typesObject

Returns the value of attribute input_types.



4
5
6
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 4

def input_types
  @input_types
end

.inputsObject

Returns the value of attribute inputs.



4
5
6
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 4

def inputs
  @inputs
end

.summaryObject

Returns the value of attribute summary.



4
5
6
# File 'lib/rbbt/util/simpleopt/doc.rb', line 4

def summary
  @summary
end

.synopsysObject

Returns the value of attribute synopsys.



4
5
6
# File 'lib/rbbt/util/simpleopt/doc.rb', line 4

def synopsys
  @synopsys
end

Class Method Details

.allObject



7
8
9
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 7

def self.all
  @all ||= {}
end

.consume(args = ARGV) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rbbt/util/simpleopt/get.rb', line 2

def self.consume(args = ARGV)
  i = 0
  values = {}
  while i < args.length do
    current = args[i]
    if m = current.match(/--?(.+?)(?:=(.+))?$/)
      key = $1
      value = $2

      input = inputs.include?(key)? key : shortcuts[key]

      if input.nil?
        i += 1
        next
      else
        args.delete_at i
      end
    else
      i += 1
      next
    end

    if input_types[input] == :string
      value = args.delete_at(i) if value.nil?
      values[input] = value
    else
      if value.nil? and %w(F false FALSE no).include?(args[i])
        Log.warn "Boolean values must are best specified as #{current}=[true|false], not #{ current } [true|false]. Token '#{args[i]}' following '#{current}' automatically assigned as value" 
        value = args.delete_at(i)
      end
      values[input] = %w(F false FALSE no).include?(value)? false : true
    end
  end

  IndiferentHash.setup values

  values
end

.delete_inputs(inputs) ⇒ Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 40

def self.delete_inputs(inputs)
  inputs.each do |input|
    input = input.to_s
    self.shortcuts.delete self.input_shortcuts.delete(input)
    self.inputs.delete input
    self.input_types.delete input
    self.input_defaults.delete input
    self.input_descriptions.delete input
  end
end

.docObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rbbt/util/simpleopt/doc.rb', line 76

def self.doc
  doc = <<-EOF
#{Log.color :magenta}#{command}(1) -- #{summary}
#{"=" * (command.length + summary.length + 7)}#{Log.color :reset}

#{ Log.color :magenta, "## SYNOPSYS"}

#{Log.color :blue, synopsys}

#{ Log.color :magenta, "## DESCRIPTION"}

#{Misc.format_paragraph description}

#{ Log.color :magenta, "## OPTIONS"}

#{input_doc(inputs, input_types, input_descriptions, input_defaults, input_shortcuts)}
  EOF
end

.fix_shortcut(short, long) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rbbt/util/simpleopt/parse.rb', line 4

def self.fix_shortcut(short, long)
  return short unless short and shortcuts.include?(short)

  chars = long.chars.to_a
  current = [chars.shift]
  short = current * ""

  if (shortcuts.include?(short) and not shortcuts[short] == long) and long.index "-" or long.index "_"
    parts = long.split(/[_-]/)
    acc = parts.collect{|s| s[0] } * ""
    return acc unless shortcuts.include? acc
  end

  while shortcuts.include?(short) and not shortcuts[short] == long
    while shortcuts[short].index current * ""
      next_letter = chars.shift
      return nil if next_letter.nil?
      current << next_letter
    end
    short = current * ""
  end

  return nil if shortcuts.include? short

  short
end

.get(opt_str) ⇒ Object



41
42
43
44
# File 'lib/rbbt/util/simpleopt/get.rb', line 41

def self.get(opt_str)
  SOPT.parse(opt_str)
  SOPT.consume(ARGV)
end

.input_doc(inputs, input_types = nil, input_descriptions = nil, input_defaults = nil, input_shortcuts = nil) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rbbt/util/simpleopt/doc.rb', line 47

def self.input_doc(inputs, input_types = nil, input_descriptions = nil, input_defaults = nil, input_shortcuts = nil)
  type = description = default = nil
  shortcut = ""
  inputs.collect do |name|

    type = input_types[name] unless input_types.nil?
    description = input_descriptions[name] unless input_descriptions.nil?
    default = input_defaults[name] unless input_defaults.nil?

    name = name.to_s

    case input_shortcuts
    when nil, FalseClass
      shortcut = nil
    when Hash
      shortcut = input_shortcuts[name] 
    when TrueClass
      shortcut = fix_shortcut(name[0], name)
    end

    type = :string if type.nil?
    register(shortcut, name, type, description) unless self.inputs.include? name

    name  = SOPT.input_format(name, type.to_sym, default, shortcut) 
    description 
    Misc.format_definition_list_item(name, description, 80, 31, nil)
  end * "\n"
end

.input_format(name, type = nil, default = nil, short = nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rbbt/util/simpleopt/doc.rb', line 28

def self.input_format(name, type = nil, default = nil, short = nil)
  input_str = (short.nil? or short.empty?) ? "--#{name}" : "-#{short},--#{name}"
  input_str = Log.color(:blue, input_str)
  extra = case type
  when nil
    ""
  when :boolean
    "[=false]" 
  when :tsv, :text
    "=<file|->"
  when :array
    "=<list|file|->"
  else
    "=<#{ type }>"
  end
  extra << " (default '#{default}')" if default != nil
  input_str << Log.color(:green, extra)
end

.parse(opt_str) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rbbt/util/simpleopt/parse.rb', line 40

def self.parse(opt_str)
  info = {}

  inputs = []
  opt_str.split(/[:\n]+/).each do |entry|
    entry.strip!
    next if entry.empty?
    names, _sep, description = entry.partition /\s+/
    short, long, asterisk = names.match(/\s*(?:-(.+))?(?:--(.+?))([*])?$/).values_at 1,2,3 

    inputs << long
    register short, long, asterisk, description
  end
  inputs
end

.register(short, long, asterisk, description) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/rbbt/util/simpleopt/parse.rb', line 31

def self.register(short, long, asterisk, description)
  short = fix_shortcut(short, long)
  shortcuts[short] = long if short
  inputs << long
  input_shortcuts[long] = short
  input_descriptions[long] = description
  input_types[long] = asterisk ? :string : :boolean
end

.require(options, *parameters) ⇒ Object



46
47
48
49
50
# File 'lib/rbbt/util/simpleopt/get.rb', line 46

def self.require(options, *parameters)
  parameters.flatten.each do |parameter|
    raise ParameterException, "Parameter '#{ Log.color :blue, parameter }' not given" if options[parameter].nil?
  end
end

.resetObject



35
36
37
38
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 35

def self.reset
  @shortcuts = {}
  @all = {}
end

.setup(str) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/rbbt/util/simpleopt/setup.rb', line 6

def self.setup(str)
  parts = str.split(/\n\n+/)

  summary = parts.shift unless parts.first =~ /^\s*\$-/
  synopsys = parts.shift if parts.first =~ /^\s*\$/

  description = []
  while parts.first and parts.first !~ /^\s*-/
    description << parts.shift
  end
  description = description * "\n\n"

  options = parts.collect{|part| part.split("\n").select{|l| l=~ /^\s*-/ }  }.flatten.compact * "\n"

  synopsys.sub!(/^\$\s+/,'') if synopsys

  SOPT.summary = summary.strip if summary
  SOPT.synopsys = synopsys.strip if synopsys
  SOPT.description = description.strip if description
  SOPT.parse options  if options

  SOPT.consume
end

.shortcutsObject



11
12
13
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 11

def self.shortcuts
  @shortcuts ||= {}
end

.usageObject



51
52
53
54
# File 'lib/rbbt/util/simpleopt/accessor.rb', line 51

def self.usage
  puts SOPT.doc
  exit 0
end