help_parser 5.1.0 → 6.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.
- checksums.yaml +5 -5
- data/README.md +16 -11
- data/lib/help_parser.rb +12 -12
- data/lib/help_parser/aliases.rb +2 -6
- data/lib/help_parser/completion.rb +6 -6
- data/lib/help_parser/constants.rb +48 -2
- data/lib/help_parser/exceptions.rb +5 -5
- data/lib/help_parser/k2t2r.rb +4 -4
- data/lib/help_parser/macros.rb +24 -24
- data/lib/help_parser/options.rb +5 -2
- data/lib/help_parser/parsea.rb +2 -2
- data/lib/help_parser/parseh.rb +19 -10
- data/lib/help_parser/parseu.rb +4 -4
- data/lib/help_parser/validations.rb +26 -36
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 32640b3a82d8e685727ed7ff3e3aedbe8e9ca33c6f0593614605eac9d2d9f7e4
|
4
|
+
data.tar.gz: e30652f83532f4640d4e3759bea0fb3528b80a16dcf69029b2ac387442adb41b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 346ae0d84f82e9c274088f0855aedf234ead157bf4a52351702e3f6a3d5267bf80eda759df59e8abb01cb873168e3c3f3d3e898c2a9790fa8e4cb095a3077b0f
|
7
|
+
data.tar.gz: c19868f202f8247664b2e5006b915752609f22f7e98771edc108996dc456b858a353fbfa67079aa158704764feab96eb6902515e2b09fb0d6d7048950e0bfa86
|
data/README.md
CHANGED
@@ -1,16 +1,14 @@
|
|
1
|
-
# Help Parser
|
2
|
-
## V: Infamous
|
1
|
+
# Help Parser VI: Tweeker
|
3
2
|
|
4
3
|
* [github](https://www.github.com/carlosjhr64/Ruby-HelpParser)
|
5
4
|
* [rubygems](https://rubygems.org/gems/help_parser)
|
6
5
|
|
7
6
|
## DESCRIPTION:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
has as familiar text.
|
7
|
+
Welcome to the best Help Parser of all!
|
8
|
+
Tweeker!
|
9
|
+
Which do you find most helpful?
|
10
|
+
Hard?
|
11
|
+
I prefer easy.
|
14
12
|
|
15
13
|
## SYNOPSIS:
|
16
14
|
|
@@ -18,7 +16,8 @@ has as familiar text.
|
|
18
16
|
require "help_parser"
|
19
17
|
|
20
18
|
HELP = <<-HELP
|
21
|
-
|
19
|
+
# <= Hash here, parser skips
|
20
|
+
# The Awesome Command.
|
22
21
|
Usage:
|
23
22
|
awesome [:options+] <args>+
|
24
23
|
awesome :alternate <arg=NAME>
|
@@ -36,9 +35,14 @@ has as familiar text.
|
|
36
35
|
NAME /^[A-Z][a-z]+$/
|
37
36
|
FLOAT /^\\d+\\.\\d+$/
|
38
37
|
YN /^[YNyn]$/
|
38
|
+
Exclusive:
|
39
|
+
version help \t Tells parser these are exclusive keys
|
40
|
+
# <= Hash here, parser breaks out
|
41
|
+
# Notes #
|
42
|
+
Blah blah blah
|
39
43
|
HELP
|
40
44
|
|
41
|
-
VERSION = "
|
45
|
+
VERSION = "6.0.0"
|
42
46
|
|
43
47
|
# Macros:
|
44
48
|
HelpParser.string(name) # for options.name : String
|
@@ -56,7 +60,8 @@ has as familiar text.
|
|
56
60
|
pp options.number?
|
57
61
|
end
|
58
62
|
|
59
|
-
|
63
|
+
Well, what do you think?
|
64
|
+
PERFECT!
|
60
65
|
|
61
66
|
## INSTALL:
|
62
67
|
|
data/lib/help_parser.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
1
|
+
require_relative './help_parser/constants'
|
2
|
+
require_relative './help_parser/exceptions'
|
3
|
+
require_relative './help_parser/aliases'
|
4
|
+
require_relative './help_parser/parsea'
|
5
|
+
require_relative './help_parser/validations'
|
6
|
+
require_relative './help_parser/parseu'
|
7
|
+
require_relative './help_parser/parseh'
|
8
|
+
require_relative './help_parser/k2t2r'
|
9
|
+
require_relative './help_parser/completion'
|
10
|
+
require_relative './help_parser/options'
|
11
|
+
require_relative './help_parser/macros'
|
12
12
|
|
13
13
|
module HelpParser
|
14
|
-
VERSION =
|
14
|
+
VERSION = '6.0.0'
|
15
15
|
|
16
16
|
def self.[](
|
17
17
|
version = nil,
|
data/lib/help_parser/aliases.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
module HelpParser
|
2
2
|
class NoDupHash < Hash
|
3
3
|
def []=(k,v)
|
4
|
-
raise HelpError,
|
4
|
+
raise HelpError, MSG[DUP_KEY,k] if self.has_key?(k)
|
5
5
|
super
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
class ArgvHash < Hash
|
10
10
|
def []=(k,v)
|
11
|
-
raise UsageError,
|
11
|
+
raise UsageError, MSG[DUP_KEY,k] if self.has_key?(k)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
16
|
-
def self.f2k(f)
|
17
|
-
f[1]=='-' ? f[2..((f.index('=')||0)-1)] : f[1]
|
18
|
-
end
|
19
15
|
end
|
@@ -20,7 +20,7 @@ module HelpParser
|
|
20
20
|
@cache.clear
|
21
21
|
end
|
22
22
|
end
|
23
|
-
raise UsageError,
|
23
|
+
raise UsageError, MATCH_USAGE
|
24
24
|
end
|
25
25
|
|
26
26
|
def types
|
@@ -39,7 +39,7 @@ module HelpParser
|
|
39
39
|
raise UsageError, "--#{key}=#{string} !~ #{type}=#{regex.inspect}" unless string=~regex
|
40
40
|
end
|
41
41
|
else
|
42
|
-
raise UsageError, "
|
42
|
+
raise UsageError, "--#{key} !~ #{type}=#{regex.inspect}"
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -59,7 +59,7 @@ module HelpParser
|
|
59
59
|
short,long = first[1],second[2..(i-1)]
|
60
60
|
if @hash.has_key?(short)
|
61
61
|
if @hash.has_key?(long)
|
62
|
-
raise UsageError,
|
62
|
+
raise UsageError, MSG[REDUNDANT, short, long]
|
63
63
|
end
|
64
64
|
@hash[long] = (default.nil?) ? true : default
|
65
65
|
elsif value = @hash[long]
|
@@ -94,10 +94,10 @@ module HelpParser
|
|
94
94
|
end
|
95
95
|
next
|
96
96
|
elsif m=FLAG_GROUP.match(token)
|
97
|
-
group,plus = m[
|
97
|
+
group,plus = m['k'],m['p']
|
98
98
|
key = keys[i]
|
99
99
|
raise NoMatch if key.nil? || key.is_a?(Integer)
|
100
|
-
list = @specs[group].flatten.select{|f|f[0]=='-'}.map{|f|
|
100
|
+
list = @specs[group].flatten.select{|f|f[0]=='-'}.map{|f| F2K[f]}
|
101
101
|
raise NoMatch unless list.include?(key)
|
102
102
|
unless plus.nil?
|
103
103
|
loop do
|
@@ -109,7 +109,7 @@ module HelpParser
|
|
109
109
|
elsif m=VARIABLE.match(token)
|
110
110
|
key = keys[i]
|
111
111
|
raise NoMatch unless key.is_a?(Integer)
|
112
|
-
variable,plus = m[
|
112
|
+
variable,plus = m['k'],m['p']
|
113
113
|
if plus.nil?
|
114
114
|
@cache[variable] = @hash[key]
|
115
115
|
else
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module HelpParser
|
2
|
-
USAGE =
|
3
|
-
TYPES =
|
2
|
+
USAGE = 'usage'
|
3
|
+
TYPES = 'types'
|
4
|
+
EXCLUSIVE = 'exclusive'
|
4
5
|
|
5
6
|
# usage
|
6
7
|
FLAG = /^[-][-]?(?<k>\w+)$/
|
@@ -19,5 +20,50 @@ module HelpParser
|
|
19
20
|
# spec W+ /~/
|
20
21
|
TYPE_DEF = /^(?<t>[A-Z]+),?\s+\/(?<r>\S+)\/$/
|
21
22
|
|
23
|
+
# spec w+( w+)*
|
24
|
+
X_DEF = /^\w+( +\w+)+$/
|
25
|
+
|
22
26
|
CSV = /,?\s+/
|
27
|
+
|
28
|
+
# exit codes
|
29
|
+
EX_USAGE = 64
|
30
|
+
EX_SOFTWARE = 70
|
31
|
+
EX_CONFIG = 78
|
32
|
+
|
33
|
+
# error messages, partials:
|
34
|
+
NO_MATCH = 'Software Error: NoMatch was not caught by HelpParser.'
|
35
|
+
DUP_KEY = 'Duplicate key'
|
36
|
+
DUP_WORD = 'Duplicate word'
|
37
|
+
DUP_FLAG = 'Duplicate flag'
|
38
|
+
DUP_X = 'Duplicate exclusive spec'
|
39
|
+
UNSEEN_FLAG = 'Undefined flag'
|
40
|
+
INCONSISTENT = 'Inconsistent use of variable'
|
41
|
+
UNEXPECTED = 'Unexpected string in help text'
|
42
|
+
BAD_REGEX = 'Bad regex'
|
43
|
+
REDUNDANT = 'Redundant'
|
44
|
+
EXCLUSIVE_KEYS = 'Exclusive keys'
|
45
|
+
UNBALANCED = 'Unbalanced brackets'
|
46
|
+
UNRECOGNIZED_TOKEN = 'Unrecognized usage token'
|
47
|
+
UNRECOGNIZED_TYPE = 'Unrecognized type spec'
|
48
|
+
UNRECOGNIZED_X = 'Unrecognized exclusive spec'
|
49
|
+
UNRECOGNIZED_OPTION = 'Unrecognized option spec'
|
50
|
+
UNDEFINED_SECTION = 'Section not defined'
|
51
|
+
MISSING_CASES = 'Missing cases'
|
52
|
+
MISSING_USAGE = 'Missing usage'
|
53
|
+
UNCOMPLETED_TYPES = 'Uncompleted types definition'
|
54
|
+
BAD_DEFAULT = 'Default does not match type'
|
55
|
+
NOT_STRING = 'Not a String'
|
56
|
+
NOT_STRINGS = 'Not all Strings'
|
57
|
+
NOT_FLOAT = 'Not a Float'
|
58
|
+
NOT_FLOATS = 'Not all Floats'
|
59
|
+
NOT_INTEGER = 'Not an Integer'
|
60
|
+
NOT_INTEGERS = 'Not all Integers'
|
61
|
+
# error messages, full:
|
62
|
+
MATCH_USAGE = 'Please match usage.'
|
63
|
+
EXTRANEOUS_SPACES = 'Extraneous spaces in help.'
|
64
|
+
|
65
|
+
# lambda utilities
|
66
|
+
MSG = lambda{|msg,*keys| "#{msg}: #{keys.join(' ')}"}
|
67
|
+
F2K = lambda{|f| f[1]=='-' ? f[2..((f.index('=')||0)-1)] : f[1]}
|
68
|
+
RESERVED = lambda{|k| [USAGE,TYPES,EXCLUSIVE].include?(k)} # reserved
|
23
69
|
end
|
@@ -27,25 +27,25 @@ module HelpParser
|
|
27
27
|
end
|
28
28
|
|
29
29
|
class UsageError < HelpParserException
|
30
|
-
def _init; @code =
|
30
|
+
def _init; @code = EX_USAGE; end
|
31
31
|
end
|
32
32
|
|
33
33
|
class SoftwareError < HelpParserException
|
34
34
|
# Stuff that should not happen
|
35
|
-
def _init; @code =
|
35
|
+
def _init; @code = EX_SOFTWARE; end
|
36
36
|
end
|
37
37
|
|
38
38
|
class NoMatch < HelpParserException
|
39
39
|
# used to shortcircuit out
|
40
|
-
def _init; @code =
|
40
|
+
def _init; @code = EX_SOFTWARE; end
|
41
41
|
|
42
42
|
# Forces it's owm message
|
43
43
|
def initialize
|
44
|
-
super(
|
44
|
+
super(NO_MATCH)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
class HelpError < HelpParserException
|
49
|
-
def _init; @code =
|
49
|
+
def _init; @code = EX_CONFIG; end
|
50
50
|
end
|
51
51
|
end
|
data/lib/help_parser/k2t2r.rb
CHANGED
@@ -4,12 +4,12 @@ module HelpParser
|
|
4
4
|
tokens = specs.select{|k,v| !(k==TYPES)}.values.flatten.select{|v|v.include?('=')}
|
5
5
|
tokens.each do |token|
|
6
6
|
if match = VARIABLE.match(token) || LONG.match(token)
|
7
|
-
name, type = match[
|
7
|
+
name, type = match['k'], match['t']
|
8
8
|
k2t[name] = type if !k2t.has_key?(name)
|
9
|
-
raise HelpError,
|
9
|
+
raise HelpError, MSG[INCONSISTENT,name,type,k2t[name]] unless type==k2t[name]
|
10
10
|
else
|
11
11
|
# Expected these to be caught earlier...
|
12
|
-
raise SoftwareError,
|
12
|
+
raise SoftwareError, MSG[UNEXPECTED,token]
|
13
13
|
end
|
14
14
|
end
|
15
15
|
return k2t
|
@@ -23,7 +23,7 @@ module HelpParser
|
|
23
23
|
begin
|
24
24
|
t2r[type] = Regexp.new(pattern[1..-2])
|
25
25
|
rescue
|
26
|
-
raise HelpError,
|
26
|
+
raise HelpError, MSG[BAD_REGEX,type,pattern]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
return t2r
|
data/lib/help_parser/macros.rb
CHANGED
@@ -4,8 +4,8 @@ module HelpParser
|
|
4
4
|
code = <<-CODE
|
5
5
|
class Options
|
6
6
|
def #{name}
|
7
|
-
s = @hash[
|
8
|
-
raise UsageError,
|
7
|
+
s = @hash['#{name}']
|
8
|
+
raise UsageError, MSG[NOT_STRING,'#{name}'] unless s.is_a?(String)
|
9
9
|
return s
|
10
10
|
end
|
11
11
|
end
|
@@ -19,8 +19,8 @@ module HelpParser
|
|
19
19
|
code = <<-CODE
|
20
20
|
class Options
|
21
21
|
def #{name}?
|
22
|
-
s = @hash[
|
23
|
-
raise UsageError,
|
22
|
+
s = @hash['#{name}']
|
23
|
+
raise UsageError, MSG[NOT_STRING,'#{name}'] unless s.nil? || s.is_a?(String)
|
24
24
|
return s
|
25
25
|
end
|
26
26
|
end
|
@@ -34,8 +34,8 @@ module HelpParser
|
|
34
34
|
code = <<-CODE
|
35
35
|
class Options
|
36
36
|
def #{name}
|
37
|
-
a = @hash[
|
38
|
-
raise UsageError,
|
37
|
+
a = @hash['#{name}']
|
38
|
+
raise UsageError, MSG[NOT_STRINGS,'#{name}'] unless a.is_a?(Array)
|
39
39
|
return a
|
40
40
|
end
|
41
41
|
end
|
@@ -49,8 +49,8 @@ module HelpParser
|
|
49
49
|
code = <<-CODE
|
50
50
|
class Options
|
51
51
|
def #{name}?
|
52
|
-
a = @hash[
|
53
|
-
raise UsageError,
|
52
|
+
a = @hash['#{name}']
|
53
|
+
raise UsageError, MSG[NOT_STRINGS,'#{name}'] unless a.nil? || a.is_a?(Array)
|
54
54
|
return a
|
55
55
|
end
|
56
56
|
end
|
@@ -64,11 +64,11 @@ module HelpParser
|
|
64
64
|
code = <<-CODE
|
65
65
|
class Options
|
66
66
|
def #{name}
|
67
|
-
f = @hash[
|
67
|
+
f = @hash['#{name}']
|
68
68
|
raise if f.nil?
|
69
69
|
f.to_f
|
70
70
|
rescue
|
71
|
-
raise UsageError,
|
71
|
+
raise UsageError, MSG[NOT_FLOAT,'#{name}']
|
72
72
|
end
|
73
73
|
end
|
74
74
|
CODE
|
@@ -81,11 +81,11 @@ module HelpParser
|
|
81
81
|
code = <<-CODE
|
82
82
|
class Options
|
83
83
|
def #{name}?
|
84
|
-
f = @hash[
|
84
|
+
f = @hash['#{name}']
|
85
85
|
f = f.to_f if f
|
86
86
|
return f
|
87
87
|
rescue
|
88
|
-
raise UsageError,
|
88
|
+
raise UsageError, MSG[NOT_FLOAT,'#{name}']
|
89
89
|
end
|
90
90
|
end
|
91
91
|
CODE
|
@@ -98,11 +98,11 @@ module HelpParser
|
|
98
98
|
code = <<-CODE
|
99
99
|
class Options
|
100
100
|
def #{name}
|
101
|
-
f = @hash[
|
101
|
+
f = @hash['#{name}']
|
102
102
|
raise unless f.is_a?(Array)
|
103
103
|
f.map{|_|_.to_f}
|
104
104
|
rescue
|
105
|
-
raise UsageError,
|
105
|
+
raise UsageError, MSG[#{NOT_FLOATS},'#{name}']
|
106
106
|
end
|
107
107
|
end
|
108
108
|
CODE
|
@@ -115,12 +115,12 @@ module HelpParser
|
|
115
115
|
code = <<-CODE
|
116
116
|
class Options
|
117
117
|
def #{name}?
|
118
|
-
f = @hash[
|
118
|
+
f = @hash['#{name}']
|
119
119
|
return nil unless f
|
120
120
|
raise unless f.is_a?(Array)
|
121
121
|
f.map{|_|_.to_f}
|
122
122
|
rescue
|
123
|
-
raise UsageError,
|
123
|
+
raise UsageError, MSG[NOT_FLOATS,'#{name}']
|
124
124
|
end
|
125
125
|
end
|
126
126
|
CODE
|
@@ -133,11 +133,11 @@ module HelpParser
|
|
133
133
|
code = <<-CODE
|
134
134
|
class Options
|
135
135
|
def #{name}
|
136
|
-
f = @hash[
|
136
|
+
f = @hash['#{name}']
|
137
137
|
raise if f.nil?
|
138
138
|
f.to_i
|
139
139
|
rescue
|
140
|
-
raise UsageError,
|
140
|
+
raise UsageError, MSG[NOT_INTEGER,'#{name}']
|
141
141
|
end
|
142
142
|
end
|
143
143
|
CODE
|
@@ -150,11 +150,11 @@ module HelpParser
|
|
150
150
|
code = <<-CODE
|
151
151
|
class Options
|
152
152
|
def #{name}?
|
153
|
-
f = @hash[
|
153
|
+
f = @hash['#{name}']
|
154
154
|
f = f.to_i if f
|
155
155
|
return f
|
156
156
|
rescue
|
157
|
-
raise UsageError,
|
157
|
+
raise UsageError, MSG[NOT_INTEGER,'#{name}']
|
158
158
|
end
|
159
159
|
end
|
160
160
|
CODE
|
@@ -167,11 +167,11 @@ module HelpParser
|
|
167
167
|
code = <<-CODE
|
168
168
|
class Options
|
169
169
|
def #{name}
|
170
|
-
f = @hash[
|
170
|
+
f = @hash['#{name}']
|
171
171
|
raise unless f.is_a?(Array)
|
172
172
|
f.map{|_|_.to_i}
|
173
173
|
rescue
|
174
|
-
raise UsageError,
|
174
|
+
raise UsageError, MSG[NOT_INTEGERS,'#{name}']
|
175
175
|
end
|
176
176
|
end
|
177
177
|
CODE
|
@@ -184,12 +184,12 @@ module HelpParser
|
|
184
184
|
code = <<-CODE
|
185
185
|
class Options
|
186
186
|
def #{name}?
|
187
|
-
f = @hash[
|
187
|
+
f = @hash['#{name}']
|
188
188
|
return nil unless f
|
189
189
|
raise unless f.is_a?(Array)
|
190
190
|
f.map{|_|_.to_i}
|
191
191
|
rescue
|
192
|
-
raise UsageError,
|
192
|
+
raise UsageError, MSG[NOT_INTEGERS,'#{name}']
|
193
193
|
end
|
194
194
|
end
|
195
195
|
CODE
|
data/lib/help_parser/options.rb
CHANGED
@@ -2,17 +2,20 @@ module HelpParser
|
|
2
2
|
class Options
|
3
3
|
def initialize( version, help, argv)
|
4
4
|
@hash = HelpParser.parsea(argv)
|
5
|
-
if version && (@hash.has_key?('v') || @hash.has_key?(
|
5
|
+
if version && (@hash.has_key?('v') || @hash.has_key?('version'))
|
6
6
|
# -v or --version
|
7
7
|
raise VersionException, version
|
8
8
|
end
|
9
9
|
if help
|
10
|
-
if @hash.has_key?('h') || @hash.has_key?(
|
10
|
+
if @hash.has_key?('h') || @hash.has_key?('help')
|
11
11
|
# -h or --help
|
12
12
|
raise HelpException, help
|
13
13
|
end
|
14
14
|
specs = HelpParser.parseh(help)
|
15
15
|
Completion.new(@hash, specs)
|
16
|
+
if xs=specs[EXCLUSIVE]
|
17
|
+
xs.each{|x| raise HelpParser::UsageError, MSG[EXCLUSIVE_KEYS,*x] if @hash.keys.count{|k|x.include?(k)}>1}
|
18
|
+
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
data/lib/help_parser/parsea.rb
CHANGED
@@ -4,9 +4,9 @@ module HelpParser
|
|
4
4
|
n = 0
|
5
5
|
argv.each do |a|
|
6
6
|
if a[0]=='-'
|
7
|
-
break if a.size==1 #
|
7
|
+
break if a.size==1 # '-' quits argv processing
|
8
8
|
if a[1]=='-'
|
9
|
-
break if a.size==2 #
|
9
|
+
break if a.size==2 # '--' also quits argv processing
|
10
10
|
s = a[2..-1]
|
11
11
|
if s.include?('=')
|
12
12
|
k,v = s.split('=',2)
|
data/lib/help_parser/parseh.rb
CHANGED
@@ -1,25 +1,34 @@
|
|
1
1
|
module HelpParser
|
2
2
|
def self.parseh(help)
|
3
|
-
specs,name = NoDupHash.new,
|
3
|
+
specs,name = NoDupHash.new,''
|
4
4
|
help.each_line do |line|
|
5
5
|
line.chomp!
|
6
|
-
next if line==
|
6
|
+
next if line==''
|
7
7
|
if line=~/^[A-Z]\w+:$/
|
8
8
|
name = line[0..-2].downcase
|
9
9
|
specs[name] = []
|
10
10
|
else
|
11
|
-
next if name==
|
11
|
+
next if name==''
|
12
|
+
break if line[0]=='#'
|
13
|
+
next if line[0]!=' '
|
12
14
|
spec = (index=line.rindex("\t"))? line[0,index].strip : line.strip
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
raise HelpError, EXTRANEOUS_SPACES if spec == ''
|
16
|
+
case name
|
17
|
+
when USAGE
|
16
18
|
specs[name].push HelpParser.parseu spec
|
17
|
-
|
18
|
-
|
19
|
+
when TYPES
|
20
|
+
raise HelpError, MSG[UNRECOGNIZED_TYPE,spec] unless spec=~TYPE_DEF
|
19
21
|
specs[name].push spec.split(CSV)
|
20
|
-
|
21
|
-
|
22
|
+
when EXCLUSIVE
|
23
|
+
raise HelpError, MSG[UNRECOGNIZED_X,spec] unless spec=~X_DEF
|
22
24
|
specs[name].push spec.split(CSV)
|
25
|
+
else
|
26
|
+
case spec
|
27
|
+
when SHORT, LONG, SHORT_LONG, SHORT_LONG_DEFAULT
|
28
|
+
specs[name].push spec.split(CSV)
|
29
|
+
else
|
30
|
+
raise HelpError, MSG[UNRECOGNIZED_OPTION,spec]
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
25
34
|
end
|
data/lib/help_parser/parseu.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module HelpParser
|
2
2
|
def self._parseu(chars)
|
3
|
-
tokens,token = [],
|
3
|
+
tokens,token = [],''
|
4
4
|
while c = chars.shift
|
5
5
|
case c
|
6
6
|
when ' ','[',']'
|
7
|
-
unless token==
|
7
|
+
unless token==''
|
8
8
|
tokens.push(token)
|
9
|
-
token =
|
9
|
+
token = ''
|
10
10
|
end
|
11
11
|
tokens.push HelpParser._parseu(chars) if c=='['
|
12
12
|
return tokens if c==']'
|
@@ -14,7 +14,7 @@ module HelpParser
|
|
14
14
|
token += c
|
15
15
|
end
|
16
16
|
end
|
17
|
-
tokens.push(token) unless token==
|
17
|
+
tokens.push(token) unless token==''
|
18
18
|
return tokens
|
19
19
|
end
|
20
20
|
|
@@ -9,7 +9,7 @@ module HelpParser
|
|
9
9
|
end
|
10
10
|
break if count<0
|
11
11
|
end
|
12
|
-
raise HelpError,
|
12
|
+
raise HelpError, MSG[UNBALANCED,chars.join] unless count==0
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.validate_usage_tokens(tokens)
|
@@ -19,53 +19,47 @@ module HelpParser
|
|
19
19
|
token.match(LITERAL) ||
|
20
20
|
token.match(VARIABLE) ||
|
21
21
|
token.match(FLAG_GROUP)
|
22
|
-
raise HelpError,
|
23
|
-
words.push match[
|
22
|
+
raise HelpError, MSG[UNRECOGNIZED_TOKEN,token] unless match
|
23
|
+
words.push match['k'] # key
|
24
24
|
end
|
25
25
|
words.each_with_index do |word,i|
|
26
|
-
raise HelpError,
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.validate_usage_spec(spec)
|
31
|
-
# TODO: Symmetry demands this,
|
32
|
-
# but I can't think of any help text errors I'm not already catching.
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.validate_type_spec(spec)
|
36
|
-
raise HelpError, "Unrecognized type spec: "+spec unless spec=~TYPE_DEF
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.validate_option_spec(spec)
|
40
|
-
case spec
|
41
|
-
when SHORT, LONG, SHORT_LONG, SHORT_LONG_DEFAULT
|
42
|
-
# OK
|
43
|
-
else
|
44
|
-
raise HelpError, "Unrecognized option spec: #{spec}"
|
26
|
+
raise HelpError, MSG[DUP_WORD,word] unless i==words.rindex(word)
|
45
27
|
end
|
46
28
|
end
|
47
29
|
|
48
30
|
def self.validate_usage_specs(specs)
|
49
|
-
option_specs = specs.select{|a,b| !
|
50
|
-
flags = option_specs.values.flatten.select{|f|f[0]=='-'}.map{|f|
|
31
|
+
option_specs = specs.select{|a,b| !RESERVED[a]}
|
32
|
+
flags = option_specs.values.flatten.select{|f|f[0]=='-'}.map{|f| F2K[f]}
|
33
|
+
unless specs[EXCLUSIVE].nil?
|
34
|
+
seen = {}
|
35
|
+
specs[EXCLUSIVE].each do |xs|
|
36
|
+
k = xs.sort.join
|
37
|
+
raise HelpError, MSG[DUP_X,*xs] if seen[k]
|
38
|
+
seen[k] = true
|
39
|
+
xs.each do |x|
|
40
|
+
raise HelpError, MSG[UNSEEN_FLAG, x] unless flags.include?(x)
|
41
|
+
k<<x
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
51
45
|
flags.each_with_index do |flag,i|
|
52
|
-
raise HelpError,
|
46
|
+
raise HelpError, MSG[DUP_FLAG,flag] unless i==flags.rindex(flag)
|
53
47
|
end
|
54
48
|
group = []
|
55
49
|
specs_usage = specs[USAGE]
|
56
50
|
unless specs_usage.nil?
|
57
51
|
specs_usage.flatten.each do |token|
|
58
52
|
if match = token.match(FLAG_GROUP)
|
59
|
-
key = match[
|
60
|
-
raise HelpError,
|
53
|
+
key = match['k']
|
54
|
+
raise HelpError, MSG[UNDEFINED_SECTION,key] unless specs[key]
|
61
55
|
group.push(key)
|
62
56
|
end
|
63
57
|
end
|
64
58
|
end
|
65
59
|
specs.each do |key,tokens|
|
66
|
-
raise HelpError,
|
67
|
-
next if specs_usage.nil?
|
68
|
-
raise HelpError,
|
60
|
+
raise HelpError, MSG[MISSING_CASES,key] unless tokens.size>0
|
61
|
+
next if specs_usage.nil? or RESERVED[key]
|
62
|
+
raise HelpError, MSG[MISSING_USAGE,key] unless group.include?(key)
|
69
63
|
end
|
70
64
|
end
|
71
65
|
|
@@ -73,7 +67,7 @@ module HelpParser
|
|
73
67
|
a,b = k2t.values.uniq.sort,t2r.keys.sort
|
74
68
|
unless a==b
|
75
69
|
c = (a+b).uniq.select{|x|!(a.include?(x) && b.include?(x))}
|
76
|
-
raise HelpError,
|
70
|
+
raise HelpError, MSG[UNCOMPLETED_TYPES,c.join(',')]
|
77
71
|
end
|
78
72
|
specs.each do |section,tokens|
|
79
73
|
next if section==USAGE || section==TYPES
|
@@ -87,12 +81,8 @@ module HelpParser
|
|
87
81
|
long = long_type[2..(i-1)]
|
88
82
|
type = long_type[(i+1)..-1]
|
89
83
|
regex = t2r[type]
|
90
|
-
raise HelpError,
|
84
|
+
raise HelpError, MSG[BAD_DEFAULT,long,default,type,regex.inspect] unless regex=~default
|
91
85
|
end
|
92
86
|
end
|
93
87
|
end
|
94
|
-
|
95
|
-
def self.validate_no_extraneous_spaces(spec)
|
96
|
-
raise HelpError, "Extraneous spaces in help." if spec == ""
|
97
|
-
end
|
98
88
|
end
|
metadata
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: help_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- carlosjhr64
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
has as familiar text.
|
14
|
+
Welcome to the best Help Parser of all!
|
15
|
+
Tweeker!
|
16
|
+
Which do you find most helpful?
|
17
|
+
Hard?
|
18
|
+
I prefer easy.
|
20
19
|
email: carlosjhr64@gmail.com
|
21
20
|
executables: []
|
22
21
|
extensions: []
|
@@ -55,10 +54,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
54
|
- !ruby/object:Gem::Version
|
56
55
|
version: '0'
|
57
56
|
requirements:
|
58
|
-
- 'ruby: ruby 2.
|
57
|
+
- 'ruby: ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]'
|
59
58
|
rubyforge_project:
|
60
|
-
rubygems_version: 2.
|
59
|
+
rubygems_version: 2.7.3
|
61
60
|
signing_key:
|
62
61
|
specification_version: 4
|
63
|
-
summary:
|
62
|
+
summary: Welcome to the best Help Parser of all! Tweeker! Which do you find most helpful?
|
63
|
+
Hard? I prefer easy.
|
64
64
|
test_files: []
|