Class: ShellOpts::Grammar::Option

Inherits:
IdrNode show all
Defined in:
lib/shellopts/grammar.rb,
lib/shellopts/dump.rb,
lib/shellopts/parser.rb,
lib/shellopts/renderer.rb,
lib/shellopts/formatter.rb

Overview

Note that options are children of Command object but are attached to OptionGroup objects that in turn are attached to the command. This is done to be able to handle multiple options with common brief or descriptions

Constant Summary collapse

SHORT_NAME_RE =
/[a-zA-Z0-9?]/
LONG_NAME_RE =
/[a-zA-Z0-9][a-zA-Z0-9_-]*/
NAME_RE =
/(?:#{SHORT_NAME_RE}|#{LONG_NAME_RE})(?:,#{LONG_NAME_RE})*/

Constants inherited from Node

Node::ALLOWED_PARENTS

Instance Attribute Summary collapse

Attributes inherited from IdrNode

#attr, #ident, #name, #path

Attributes inherited from Node

#children, #parent, #token

Instance Method Summary collapse

Methods inherited from IdrNode

#dump_doc, #set_name, #uid

Methods inherited from Node

#analyzer_error, #ancestors, #dump_ast, #dump_attrs, #initialize, #inspect, #parents, parse, #parser_error, #puts_help, #puts_usage, #remove_arg_descr_nodes, #remove_arg_spec_nodes, #remove_brief_nodes, #traverse

Constructor Details

This class inherits a constructor from ShellOpts::Grammar::Node

Instance Attribute Details

#argument_nameObject (readonly)

Name of argument or nil if not present



134
135
136
# File 'lib/shellopts/grammar.rb', line 134

def argument_name
  @argument_name
end

#argument_typeObject (readonly)

Type of argument (ArgType)



137
138
139
# File 'lib/shellopts/grammar.rb', line 137

def argument_type
  @argument_type
end

#long_identsObject (readonly)

Long option identifiers



119
120
121
# File 'lib/shellopts/grammar.rb', line 119

def long_idents
  @long_idents
end

#long_namesObject (readonly)

Long option names (including initial ‘–’)



125
126
127
# File 'lib/shellopts/grammar.rb', line 125

def long_names
  @long_names
end

#short_identsObject (readonly)

Short option identfiers



116
117
118
# File 'lib/shellopts/grammar.rb', line 116

def short_idents
  @short_idents
end

#short_namesObject (readonly)

Short option names (including initial ‘-’)



122
123
124
# File 'lib/shellopts/grammar.rb', line 122

def short_names
  @short_names
end

Instance Method Details

#argument?Boolean

Returns:

  • (Boolean)


143
# File 'lib/shellopts/grammar.rb', line 143

def argument?() @argument end

#argument_enumObject

Enum values if argument type is an enumerator



140
# File 'lib/shellopts/grammar.rb', line 140

def argument_enum() @argument_type.values end

#commandObject

Redefine command of this object



110
# File 'lib/shellopts/grammar.rb', line 110

def command() parent.parent end

#dump_idr(short = false) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/shellopts/dump.rb', line 79

def dump_idr(short = false)
  if short
    s = [
        name, 
        argument? ? argument_type.name : nil, 
        optional? ? "?" : nil, 
        repeatable? ? "*" : nil
    ].compact.join(" ")
    puts s
  else
    puts "#{name}: #{classname}"
    dump_attrs(
        :uid, :path, :attr, :ident, :name, :idents, :names,
        :repeatable?, 
        :argument?, argument? && :argument_name, argument? && :argument_type, 
        :enum?, enum? && :argument_enum, 
        :optional?)
    indent { puts "brief: #{group.brief}" }
  end
end

#enum?Boolean

Returns:

  • (Boolean)


149
# File 'lib/shellopts/grammar.rb', line 149

def enum?() @argument_type.is_a? EnumArgument end

#file?Boolean

Returns:

  • (Boolean)


148
# File 'lib/shellopts/grammar.rb', line 148

def file?() @argument_type.is_a? FileArgument end

#float?Boolean

Returns:

  • (Boolean)


147
# File 'lib/shellopts/grammar.rb', line 147

def float?() @argument_type.is_a? FloatArgument end

#groupObject

Option group of this object



113
# File 'lib/shellopts/grammar.rb', line 113

def group() parent end

#identsObject

Identifiers of option. Include both short and long identifiers



128
# File 'lib/shellopts/grammar.rb', line 128

def idents() short_idents + long_idents end

#integer?Boolean

Returns:

  • (Boolean)


146
# File 'lib/shellopts/grammar.rb', line 146

def integer?() @argument_type.is_a? IntegerArgument end

#match?(literal) ⇒ Boolean

Returns:

  • (Boolean)


152
# File 'lib/shellopts/grammar.rb', line 152

def match?(literal) argument_type.match?(literal) end

#namesObject

Names of option. Includes both short and long option names



131
# File 'lib/shellopts/grammar.rb', line 131

def names() short_names + long_names end

#optional?Boolean

Returns:

  • (Boolean)


144
# File 'lib/shellopts/grammar.rb', line 144

def optional?() @optional end

#parseObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/shellopts/parser.rb', line 30

def parse
  token.source =~ /^(-|--|\+|\+\+)(#{NAME_RE})(?:=(.+?)(\?)?)?$/ or 
      parser_error token, "Illegal option: #{token.source.inspect}"
  initial = $1
  name_list = $2
  arg = $3
  optional = $4

  @repeatable = %w(+ ++).include?(initial)

  @short_idents = []
  @short_names = []
  names = name_list.split(",")
  if %w(+ -).include?(initial)
    while names.first&.size == 1
      name = names.shift
      @short_names << "-#{name}"
      @short_idents << name.to_sym
    end
  end

  names.each { |name| 
    name.size > 1 or 
        parser_error token, "Long names should be at least two characters long: '#{name}'"
  }

  @long_names = names.map { |name| "--#{name}" }
  @long_idents = names.map { |name| name.tr("-", "_").to_sym }

  set_name(
    @long_names.first || @short_names.first,
    command.path + [@long_idents.first || @short_idents.first])

  @argument = !arg.nil?

  named = true
  if @argument
    if arg =~ /^([^:]+)(?::(.*))/
      @argument_name = $1
      named = true
      arg = $2
    elsif arg =~ /^:(.*)/
      arg = $1
      named = false
    end

    case arg
      when "", nil
        @argument_name ||= "VAL"
        @argument_type = StringType.new
      when "#"
        @argument_name ||= "INT"
        @argument_type = IntegerArgument.new
      when "$"
        @argument_name ||= "NUM"
        @argument_type = FloatArgument.new
      when "FILE", "DIR", "PATH", "EFILE", "EDIR", "EPATH", "NFILE", "NDIR", "NPATH", "IFILE", "OFILE"
        @argument_name ||= arg.sub(/^(?:E|N|I|O)/, "")
        @argument_type = FileArgument.new(arg.downcase.to_sym)
      when /,/
        @argument_name ||= arg
        @argument_type = EnumArgument.new(arg.split(","))
      else
        named && @argument_name.nil? or parser_error token, "Illegal type expression: #{arg.inspect}"
        @argument_name = arg
        @argument_type = StringType.new
    end
    @optional = !optional.nil?
  else
    @argument_type = StringType.new
  end
  super
end

#render(format) ⇒ Object

Formats:

:enum     -a, --all
:long     --all
:short    -a


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/shellopts/renderer.rb', line 39

def render(format)
  constrain format, :enum, :long, :short
  s = 
      case format
        when :enum; names.join(", ")
        when :long; name
        when :short; short_names.first || name
      else
        raise ArgumentError, "Illegal format: #{format.inspect}"
      end 
  if argument?
    s + (optional? ? "[=#{argument_name}]" : "=#{argument_name}")
  else
    s
  end
end

#repeatable?Boolean

Returns:

  • (Boolean)


142
# File 'lib/shellopts/grammar.rb', line 142

def repeatable?() @repeatable end

#string?Boolean

Returns:

  • (Boolean)


150
# File 'lib/shellopts/grammar.rb', line 150

def string?() argument? && !integer? && !float? && !file? && !enum? end