help_parser 5.1.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|