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, #uid

Attributes inherited from Node

#children, #parent, #token

Instance Method Summary collapse

Methods inherited from IdrNode

#dump_doc

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



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

def argument_name
  @argument_name
end

#argument_typeObject (readonly)

Type of argument (ArgType)



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

def argument_type
  @argument_type
end

#long_identsObject (readonly)

Long option identifiers



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

def long_idents
  @long_idents
end

#long_namesObject (readonly)

Long option names (including initial ‘–’)



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

def long_names
  @long_names
end

#short_identsObject (readonly)

Short option identfiers



107
108
109
# File 'lib/shellopts/grammar.rb', line 107

def short_idents
  @short_idents
end

#short_namesObject (readonly)

Short option names (including initial ‘-’)



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

def short_names
  @short_names
end

Instance Method Details

#argument?Boolean

Returns:



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

def argument?() @argument end

#argument_enumObject

Enum values if argument type is an enumerator



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

def argument_enum() @argument_type.values end

#commandObject

Redefine command of this object



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

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:



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

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

#file?Boolean

Returns:



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

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

#float?Boolean

Returns:



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

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

#groupObject

Option group of this object



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

def group() parent end

#identsObject

Identifiers of option. Include both short and long identifiers



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

def idents() short_idents + long_idents end

#integer?Boolean

Returns:



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

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

#match?(literal) ⇒ Boolean

Returns:



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

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

#namesObject

Names of option. Includes both short and long option names



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

def names() short_names + long_names end

#optional?Boolean

Returns:



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

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
# 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 }

  @name = @long_names.first || @short_names.first
  @path = 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"
        @argument_name ||= arg.sub(/^(?:E|N)/, "")
        @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
# File 'lib/shellopts/renderer.rb', line 39

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

#repeatable?Boolean

Returns:



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

def repeatable?() @repeatable end

#string?Boolean

Returns:



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

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