shellopts 2.0.0.pre.14 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.ruby-version +1 -1
  4. data/README.md +201 -267
  5. data/TODO +37 -5
  6. data/doc/format.rb +95 -0
  7. data/doc/grammar.txt +27 -0
  8. data/doc/syntax.rb +110 -0
  9. data/doc/syntax.txt +10 -0
  10. data/lib/ext/array.rb +62 -0
  11. data/lib/ext/forward_to.rb +15 -0
  12. data/lib/ext/lcs.rb +34 -0
  13. data/lib/shellopts/analyzer.rb +130 -0
  14. data/lib/shellopts/ansi.rb +8 -0
  15. data/lib/shellopts/args.rb +25 -15
  16. data/lib/shellopts/argument_type.rb +139 -0
  17. data/lib/shellopts/dump.rb +158 -0
  18. data/lib/shellopts/formatter.rb +292 -92
  19. data/lib/shellopts/grammar.rb +375 -0
  20. data/lib/shellopts/interpreter.rb +103 -0
  21. data/lib/shellopts/lexer.rb +175 -0
  22. data/lib/shellopts/parser.rb +293 -0
  23. data/lib/shellopts/program.rb +279 -0
  24. data/lib/shellopts/renderer.rb +227 -0
  25. data/lib/shellopts/stack.rb +7 -0
  26. data/lib/shellopts/token.rb +44 -0
  27. data/lib/shellopts/version.rb +1 -1
  28. data/lib/shellopts.rb +359 -3
  29. data/main +1180 -0
  30. data/shellopts.gemspec +8 -14
  31. metadata +86 -41
  32. data/lib/ext/algorithm.rb +0 -14
  33. data/lib/ext/ruby_env.rb +0 -8
  34. data/lib/shellopts/ast/command.rb +0 -112
  35. data/lib/shellopts/ast/dump.rb +0 -28
  36. data/lib/shellopts/ast/option.rb +0 -15
  37. data/lib/shellopts/ast/parser.rb +0 -106
  38. data/lib/shellopts/constants.rb +0 -88
  39. data/lib/shellopts/exceptions.rb +0 -21
  40. data/lib/shellopts/grammar/analyzer.rb +0 -76
  41. data/lib/shellopts/grammar/command.rb +0 -87
  42. data/lib/shellopts/grammar/dump.rb +0 -56
  43. data/lib/shellopts/grammar/lexer.rb +0 -56
  44. data/lib/shellopts/grammar/option.rb +0 -55
  45. data/lib/shellopts/grammar/parser.rb +0 -78
data/shellopts.gemspec CHANGED
@@ -11,20 +11,10 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{Parse command line options and arguments}
13
13
  spec.description = %q{ShellOpts is a simple command line parsing libray
14
- that covers most modern use cases incl. sub-commands.
15
- Options and commands are specified using a
16
- getopt(1)-like string that is interpreted by the
17
- library to process the command line}
14
+ that supports short and long options and subcommands,
15
+ and has built-in help and error messages}
18
16
  spec.homepage = "http://github.com/clrgit/shellopts"
19
17
 
20
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
21
- # to allow pushing to a single host or delete this section to allow pushing to any host.
22
- if spec.respond_to?(:metadata)
23
- spec.metadata["allowed_push_host"] = "https://rubygems.org"
24
- else
25
- raise "RubyGems 2.0+ is required to protect against public gem pushes"
26
- end
27
-
28
18
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
29
19
  f.match(%r{^(test|spec|features)/})
30
20
  end
@@ -32,9 +22,13 @@ Gem::Specification.new do |spec|
32
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
23
  spec.require_paths = ["lib"]
34
24
 
35
- spec.add_development_dependency "bundler", "~> 1.16"
25
+ spec.add_dependency "forward_to"
26
+ spec.add_dependency "constrain"
27
+ spec.add_dependency "ruby-terminfo"
28
+ spec.add_dependency "indented_io"
29
+
30
+ spec.add_development_dependency "bundler", "~> 2.2.10"
36
31
  spec.add_development_dependency "rake", ">= 12.3.3"
37
32
  spec.add_development_dependency "rspec", "~> 3.0"
38
- spec.add_development_dependency "indented_io"
39
33
  spec.add_development_dependency "simplecov"
40
34
  end
metadata CHANGED
@@ -1,71 +1,113 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shellopts
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre.14
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-10 00:00:00.000000000 Z
11
+ date: 2022-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: forward_to
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
20
- type: :development
19
+ version: '0'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: constrain
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 12.3.3
34
- type: :development
33
+ version: '0'
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 12.3.3
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: ruby-terminfo
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: indented_io
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '3.0'
75
+ version: 2.2.10
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '3.0'
82
+ version: 2.2.10
55
83
  - !ruby/object:Gem::Dependency
56
- name: indented_io
84
+ name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - ">="
60
88
  - !ruby/object:Gem::Version
61
- version: '0'
89
+ version: 12.3.3
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - ">="
67
95
  - !ruby/object:Gem::Version
68
- version: '0'
96
+ version: 12.3.3
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: simplecov
71
113
  requirement: !ruby/object:Gem::Requirement
@@ -82,10 +124,8 @@ dependencies:
82
124
  version: '0'
83
125
  description: |-
84
126
  ShellOpts is a simple command line parsing libray
85
- that covers most modern use cases incl. sub-commands.
86
- Options and commands are specified using a
87
- getopt(1)-like string that is interpreted by the
88
- library to process the command line
127
+ that supports short and long options and subcommands,
128
+ and has built-in help and error messages
89
129
  email:
90
130
  - claus.l.rasmussen@gmail.com
91
131
  executables: []
@@ -103,30 +143,35 @@ files:
103
143
  - bin/console
104
144
  - bin/mkdoc
105
145
  - bin/setup
146
+ - doc/format.rb
147
+ - doc/grammar.txt
106
148
  - doc/stylesheet.css
107
- - lib/ext/algorithm.rb
108
- - lib/ext/ruby_env.rb
149
+ - doc/syntax.rb
150
+ - doc/syntax.txt
151
+ - lib/ext/array.rb
152
+ - lib/ext/forward_to.rb
153
+ - lib/ext/lcs.rb
109
154
  - lib/shellopts.rb
155
+ - lib/shellopts/analyzer.rb
156
+ - lib/shellopts/ansi.rb
110
157
  - lib/shellopts/args.rb
111
- - lib/shellopts/ast/command.rb
112
- - lib/shellopts/ast/dump.rb
113
- - lib/shellopts/ast/option.rb
114
- - lib/shellopts/ast/parser.rb
115
- - lib/shellopts/constants.rb
116
- - lib/shellopts/exceptions.rb
158
+ - lib/shellopts/argument_type.rb
159
+ - lib/shellopts/dump.rb
117
160
  - lib/shellopts/formatter.rb
118
- - lib/shellopts/grammar/analyzer.rb
119
- - lib/shellopts/grammar/command.rb
120
- - lib/shellopts/grammar/dump.rb
121
- - lib/shellopts/grammar/lexer.rb
122
- - lib/shellopts/grammar/option.rb
123
- - lib/shellopts/grammar/parser.rb
161
+ - lib/shellopts/grammar.rb
162
+ - lib/shellopts/interpreter.rb
163
+ - lib/shellopts/lexer.rb
164
+ - lib/shellopts/parser.rb
165
+ - lib/shellopts/program.rb
166
+ - lib/shellopts/renderer.rb
167
+ - lib/shellopts/stack.rb
168
+ - lib/shellopts/token.rb
124
169
  - lib/shellopts/version.rb
170
+ - main
125
171
  - shellopts.gemspec
126
172
  homepage: http://github.com/clrgit/shellopts
127
173
  licenses: []
128
- metadata:
129
- allowed_push_host: https://rubygems.org
174
+ metadata: {}
130
175
  post_install_message:
131
176
  rdoc_options: []
132
177
  require_paths:
@@ -138,11 +183,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
183
  version: '0'
139
184
  required_rubygems_version: !ruby/object:Gem::Requirement
140
185
  requirements:
141
- - - ">"
186
+ - - ">="
142
187
  - !ruby/object:Gem::Version
143
- version: 1.3.1
188
+ version: '0'
144
189
  requirements: []
145
- rubygems_version: 3.0.8
190
+ rubygems_version: 3.2.26
146
191
  signing_key:
147
192
  specification_version: 4
148
193
  summary: Parse command line options and arguments
data/lib/ext/algorithm.rb DELETED
@@ -1,14 +0,0 @@
1
-
2
- module Algorithm
3
- def follow(object, sym = nil, &block)
4
- sym.nil? == block_given? or raise "Can't use both symbol and block"
5
- a = []
6
- while object
7
- a << object
8
- object = block_given? ? yield(object) : object.send(sym)
9
- end
10
- a
11
- end
12
-
13
- module_function :follow
14
- end
data/lib/ext/ruby_env.rb DELETED
@@ -1,8 +0,0 @@
1
-
2
- if File.directory?(File.join(File.dirname(File.dirname(File.dirname(__FILE__))), "spec"))
3
- RUBY_ENV = "development"
4
- else
5
- RUBY_ENV = "production"
6
- end
7
-
8
-
@@ -1,112 +0,0 @@
1
- module ShellOpts
2
- module Ast
3
- # Note that Command is derived from BasicObject to minimize the number of
4
- # reserved names
5
- class Command < BasicObject
6
- def initialize(grammar)
7
- @grammar = grammar
8
- @options_list = []
9
- @options_hash = {}
10
- @subcommand = nil
11
- @subcommands_hash = {} # have at most one element
12
-
13
- @grammar.opts.each { |opt|
14
- if opt.argument?
15
- self.instance_eval("def #{opt.ident}() @options_hash[:#{opt.ident}] end")
16
- end
17
- self.instance_eval("def #{opt.ident}?() @options_hash.key?(:#{opt.ident}) end")
18
- }
19
-
20
- @grammar.cmds.each { |cmd|
21
- self.instance_eval("def #{cmd.ident}!() @subcommands_hash[:#{cmd.ident}] end")
22
- }
23
- end
24
-
25
- # Return true if the option was used. Defined in #initialize for each option
26
- # def <option>?() end
27
-
28
- # Return the value of the option. Note that repeated options have their
29
- # values aggregated into an array. Defined in #initialize for each option
30
- # def <option>() end
31
-
32
- # List of Ast::Option objects in the same order as on the command line
33
- def options() @options_list end
34
-
35
- # Hash from option identifier to option value. Note that repeated options
36
- # have their values aggregated into an array
37
- def [](ident) @options_hash[ident].argument end
38
-
39
- # Return the sub-command Command object or nil if not present. Defined in
40
- # #initialize for each sub-command
41
- # def <command>!() end
42
-
43
- # The sub-command identifier or nil if not present
44
- def subcommand() @subcommand && Command.grammar(@subcommand).ident end
45
-
46
- # The sub-command Command object or nil if not present
47
- def subcommand!() @subcommand end
48
-
49
- # Class-level accessor methods
50
- def self.program?(command) command.__send__(:__is_program__) end
51
- def self.grammar(command) command.__send__(:__get_grammar__) end
52
-
53
- # Class-level mutating methods
54
- def self.add_option(command, option) command.__send__(:__add_option__, option) end
55
- def self.add_command(command, subcommand) command.__send__(:__add_command__, subcommand) end
56
-
57
- private
58
- # True if this is a Program object
59
- def __is_program__() false end
60
-
61
- # Get grammar
62
- def __get_grammar__()
63
- @grammar
64
- end
65
-
66
- # Add an option. Only used from the parser
67
- def __add_option__(option)
68
- @options_list << option
69
- if option.grammar.repeatable?
70
- (@options_hash[option.grammar.ident] ||= []) << option.argument
71
- else
72
- @options_hash[option.grammar.ident] = option.argument
73
- end
74
- end
75
-
76
- # Set sub-command. Only used from the parser
77
- def __add_command__(command)
78
- ident = Command.grammar(command).ident
79
- @subcommand = command
80
- @subcommands_hash[ident] = command
81
- end
82
- end
83
-
84
- class Program < Command
85
- def __is_program__() true end
86
- end
87
- end
88
- end
89
-
90
- # # TODO: Create class-level methods for access
91
- # private
92
- # # Return class of object. #class is not defined for BasicObjects so this
93
- # # method provides an alternative way of getting the class
94
- # def self.class_of(object)
95
- # # https://stackoverflow.com/a/18621313/2130986
96
- # ::Kernel.instance_method(:class).bind(object).call
97
- # end
98
- #
99
- # # Class method implementation of ObjectStruct#instance_variable_set that is
100
- # # not defined in a BasicObject
101
- # def self.set_variable(this, var, value)
102
- # # https://stackoverflow.com/a/18621313/2130986
103
- # ::Kernel.instance_method(:instance_variable_set).bind(this).call(var, value)
104
- # end
105
- #
106
- # # Class method implementation of ObjectStruct#instance_variable_get that is
107
- # # not defined in a BasicObject
108
- # def self.get_variable(this, var)
109
- # # https://stackoverflow.com/a/18621313/2130986
110
- # ::Kernel.instance_method(:instance_variable_get).bind(this).call(var)
111
- # end
112
-
@@ -1,28 +0,0 @@
1
- module ShellOpts
2
- module Ast
3
- class Command < BasicObject
4
- def dump
5
- klass = __is_program__ ? "Program" : "Command"
6
- ::Kernel.puts "#{@grammar.ident.inspect} (#{klass})"
7
- ::Kernel.indent {
8
- if !options.empty?
9
- options.map(&:dump)
10
- end
11
- if subcommand
12
- subcommand!.dump
13
- end
14
- }
15
- end
16
- end
17
-
18
- class Option
19
- def dump
20
- puts "#{grammar.ident.inspect} (Option)"
21
- indent {
22
- puts "name: #{name.inspect}"
23
- puts "argument: #{argument.inspect}"
24
- }
25
- end
26
- end
27
- end
28
- end
@@ -1,15 +0,0 @@
1
- module ShellOpts
2
- module Ast
3
- class Option
4
- attr_reader :grammar
5
- attr_reader :name # The actual name used on the command line
6
- attr_reader :argument
7
-
8
- def initialize(grammar, name, argument)
9
- @grammar = grammar
10
- @name = name
11
- @argument = argument
12
- end
13
- end
14
- end
15
- end
@@ -1,106 +0,0 @@
1
- module ShellOpts
2
- module Ast
3
- # Parse a subcommand
4
- class Parser
5
- def initialize(grammar, argv)
6
- @grammar, @argv = grammar, argv.dup
7
- @seen_options = {} # Used to keep track of repeated options
8
- @current = nil # Current command
9
- end
10
-
11
- def call
12
- @current = program = Program.new(@grammar)
13
- parse_command(program)
14
- cmd = Command.grammar(@current)
15
- !cmd.virtual? or error("'%s' command requires a sub-command")
16
- [program, Args.new(cmd, @argv)]
17
- end
18
-
19
- def self.parse(grammar, argv)
20
- self.new(grammar, argv).call
21
- end
22
-
23
- private
24
- def error(message)
25
- grammar = Command.grammar(@current)
26
- raise Error.new(grammar), message % grammar.name
27
- end
28
-
29
- def parse_command(command)
30
- @seen_options = {} # Every new command resets the seen options
31
- while arg = @argv.first
32
- if arg == "--"
33
- @argv.shift
34
- break
35
- elsif arg.start_with?("-")
36
- parse_option(command)
37
- elsif cmd = Command.grammar(command).commands[arg]
38
- @argv.shift
39
- @current = subcommand = Ast::Command.new(cmd)
40
- Command.add_command(command, subcommand)
41
- parse_command(subcommand)
42
- break
43
- else
44
- break
45
- end
46
- end
47
- end
48
-
49
- def parse_option(command)
50
- # Split into name and argument
51
- case @argv.first
52
- when /^--(.+?)(?:=(.*))?$/
53
- name, arg, short = $1, $2, false
54
- opt_name = "--#{name}"
55
- when /^-(.)(.+)?$/
56
- name, arg, short = $1, $2, true
57
- opt_name = "-#{name}"
58
- end
59
- @argv.shift
60
-
61
- option = Command.grammar(command).options[name] or error "Unknown option '#{opt_name}'"
62
- !@seen_options.key?(option.ident) || option.repeatable? or error "Duplicate option '#{opt_name}'"
63
- @seen_options[option.ident] = true
64
-
65
- # Parse (optional) argument
66
- if option.argument?
67
- if arg.nil? && !option.optional?
68
- if !@argv.empty?
69
- arg = @argv.shift
70
- else
71
- error "Missing argument for option '#{opt_name}'"
72
- end
73
- end
74
- arg &&= parse_option_arg(option, name, arg)
75
- elsif arg && short
76
- @argv.unshift("-#{arg}")
77
- arg = nil
78
- elsif !arg.nil?
79
- error "No argument allowed for option '#{opt_name}'"
80
- end
81
-
82
- Command.add_option(command, Option.new(option, name, arg))
83
- end
84
-
85
- def parse_option_arg(option, name, arg)
86
- if option.string?
87
- arg
88
- elsif arg == ""
89
- nil
90
- elsif option.integer?
91
- arg =~ /^-?\d+$/ or error "Illegal integer in '#{name}' argument: '#{arg}'"
92
- arg.to_i
93
- else # option.float?
94
- # https://stackoverflow.com/a/21891705/2130986
95
- arg =~ /^[+-]?(?:0|[1-9]\d*)(?:\.(?:\d*[1-9]|0))?$/ or
96
- error "Illegal float in '#{name}' argument: '#{arg}'"
97
- arg.to_f
98
- end
99
- end
100
- end
101
- end
102
- end
103
-
104
-
105
-
106
-
@@ -1,88 +0,0 @@
1
-
2
- module ShellOpts
3
- # FIXME: An option group is -abcd, an option list is a,b,c,d
4
- module Constants
5
- # Short and long option names
6
- SHORT_OPTION_NAME_SUB_RE = /[a-zA-Z0-9]/
7
- LONG_OPTION_NAME_SUB_RE = /[a-z](?:[\w-]*\w)/
8
- OPTION_NAME_SUB_RE = /#{SHORT_OPTION_NAME_SUB_RE}|#{LONG_OPTION_NAME_SUB_RE}/
9
-
10
- # Initial option in a group
11
- INITIAL_SHORT_OPTION_SUB_RE = /[-+]#{SHORT_OPTION_NAME_SUB_RE}/
12
- INITIAL_LONG_OPTION_SUB_RE = /(?:--|\+\+)#{LONG_OPTION_NAME_SUB_RE}/
13
- INITIAL_OPTION_SUB_RE = /#{INITIAL_SHORT_OPTION_SUB_RE}|#{INITIAL_LONG_OPTION_SUB_RE}/
14
-
15
- # A list of short and long options
16
- OPTION_GROUP_SUB_RE = /#{INITIAL_OPTION_SUB_RE}(?:,#{OPTION_NAME_SUB_RE})*/
17
-
18
- # Option argument
19
- OPTION_ARG_SUB_RE = /[A-Z](?:[A-Z0-9_-]*[A-Z0-9])?/
20
-
21
- # Matches option flags and argument. It defines the following captures
22
- #
23
- # $1 - Argument flag ('=')
24
- # $2 - Type flag ('#' or '$')
25
- # $3 - Argument name
26
- # $4 - Optional flag ('?')
27
- #
28
- OPTION_FLAGS_SUB_RE = /(=)(#|\$)?(#{OPTION_ARG_SUB_RE})?(\?)?/
29
-
30
- # Matches a declaration of an option. The RE defines the following captures:
31
- #
32
- # $1 - Option group
33
- # $2 - Argument flag ('=')
34
- # $3 - Type flag ('#' or '$')
35
- # $4 - Argument name
36
- # $5 - Optional flag ('?')
37
- #
38
- OPTION_SUB_RE = /(#{OPTION_GROUP_SUB_RE})#{OPTION_FLAGS_SUB_RE}?/
39
-
40
- # Command and command paths
41
- COMMAND_IDENT_SUB_RE = /[a-z](?:[a-z0-9_-]*[a-z0-9])?/
42
- COMMAND_SUB_RE = /#{COMMAND_IDENT_SUB_RE}!/
43
- COMMAND_PATH_SUB_RE = /#{COMMAND_IDENT_SUB_RE}(?:\.#{COMMAND_IDENT_SUB_RE})*!/
44
-
45
- # Command argument
46
- ARGUMENT_SUB_RE = /[A-Z][A-Z0-9_-]*[A-Z0-9](?:\.\.\.)?/
47
- ARGUMENT_EXPR_SUB_RE = /\[?#{ARGUMENT_SUB_RE}(?:#{ARGUMENT_SUB_RE}|[\[\]\|\s])*/
48
-
49
- # Matches a line starting with a command or an option
50
- SCAN_RE = /^(?:#{COMMAND_PATH_SUB_RE}|#{OPTION_SUB_RE})(?:\s+.*)?$/
51
-
52
-
53
- # Create anchored REs for all SUB_REs
54
- self.constants.each { |c|
55
- next if c.to_s !~ /_SUB_RE$/
56
- sub_re = self.const_get(c)
57
- next if !sub_re.is_a?(Regexp)
58
- re = /^#{sub_re}$/
59
- name = c.to_s.sub(/_SUB_RE$/, "_RE")
60
- self.const_set(name, re)
61
- }
62
-
63
- # Method names reserved by the BasicObject class
64
- BASIC_OBJECT_RESERVED_WORDS = %w(
65
- ! != == __id__ __send__ equal? instance_eval instance_exec method_missing
66
- singleton_method_added singleton_method_removed singleton_method_undefined)
67
-
68
- # Method names reserved by the Ast::Command class
69
- AST_COMMAND_RESERVED_WORDS = %w(
70
- initialize options subcommand __is_program__ __get_grammar__
71
- __add_option__ __add_command__)
72
-
73
- # Reserved option names
74
- OPTION_RESERVED_WORDS =
75
- (BASIC_OBJECT_RESERVED_WORDS + AST_COMMAND_RESERVED_WORDS).grep(OPTION_NAME_RE)
76
-
77
- # Reserved command names
78
- COMMAND_RESERVED_WORDS = %w(subcommand)
79
- end
80
-
81
- include Constants
82
- end
83
-
84
-
85
-
86
-
87
-
88
-
@@ -1,21 +0,0 @@
1
-
2
- module ShellOpts
3
- class CompileError < StandardError; end
4
-
5
- class ShellOptsError < RuntimeError; end
6
-
7
- class Error < ShellOptsError
8
- attr_reader :subject
9
-
10
- def initialize(subject = nil)
11
- super()
12
- @subject = subject
13
- end
14
- end
15
-
16
- class Fail < ShellOptsError; end
17
- end
18
-
19
- class NotYet < NotImplementedError; end
20
- class NotThis < ScriptError; end
21
- class NotHere < ScriptError; end