rack-mount 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/lib/rack/mount.rb +0 -2
- data/lib/rack/mount/analysis/frequency.rb +10 -3
- data/lib/rack/mount/analysis/splitting.rb +79 -62
- data/lib/rack/mount/generatable_regexp.rb +48 -45
- data/lib/rack/mount/generation/route.rb +10 -5
- data/lib/rack/mount/generation/route_set.rb +23 -31
- data/lib/rack/mount/prefix.rb +14 -15
- data/lib/rack/mount/recognition/code_generation.rb +51 -61
- data/lib/rack/mount/recognition/route.rb +7 -22
- data/lib/rack/mount/recognition/route_set.rb +40 -16
- data/lib/rack/mount/regexp_with_named_groups.rb +33 -7
- data/lib/rack/mount/route_set.rb +7 -5
- data/lib/rack/mount/strexp.rb +11 -40
- data/lib/rack/mount/strexp/parser.rb +158 -0
- data/lib/rack/mount/strexp/tokenizer.rb +84 -0
- data/lib/rack/mount/utils.rb +26 -163
- data/lib/rack/mount/vendor/multimap/multimap.rb +1 -0
- data/lib/rack/mount/vendor/reginald/reginald.rb +55 -0
- data/lib/rack/mount/vendor/reginald/reginald/alternation.rb +50 -0
- data/lib/rack/mount/vendor/reginald/reginald/anchor.rb +20 -0
- data/lib/rack/mount/vendor/reginald/reginald/character.rb +53 -0
- data/lib/rack/mount/vendor/reginald/reginald/character_class.rb +61 -0
- data/lib/rack/mount/vendor/reginald/reginald/expression.rb +75 -0
- data/lib/rack/mount/vendor/reginald/reginald/group.rb +61 -0
- data/lib/rack/mount/vendor/reginald/reginald/parser.rb +306 -0
- data/lib/rack/mount/vendor/reginald/reginald/tokenizer.rb +141 -0
- metadata +14 -15
- data/lib/rack/mount/const.rb +0 -45
- data/lib/rack/mount/meta_method.rb +0 -104
@@ -0,0 +1,158 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by Racc 1.4.6
|
4
|
+
# from Racc grammer file "".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser.rb'
|
8
|
+
|
9
|
+
require 'rack/mount/strexp/tokenizer'
|
10
|
+
|
11
|
+
module Rack
|
12
|
+
module Mount
|
13
|
+
class StrexpParser < Racc::Parser
|
14
|
+
|
15
|
+
|
16
|
+
if RegexpWithNamedGroups.supports_named_captures?
|
17
|
+
REGEXP_NAMED_CAPTURE = '(?<%s>%s)'.freeze
|
18
|
+
else
|
19
|
+
REGEXP_NAMED_CAPTURE = '(?:<%s>%s)'.freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_accessor :requirements
|
23
|
+
##### State transition tables begin ###
|
24
|
+
|
25
|
+
racc_action_table = [
|
26
|
+
4, 5, 6, 11, 7, 4, 5, 6, 12, 7,
|
27
|
+
4, 5, 6, 8, 7, 4, 5, 6, nil, 7 ]
|
28
|
+
|
29
|
+
racc_action_check = [
|
30
|
+
0, 0, 0, 8, 0, 10, 10, 10, 10, 10,
|
31
|
+
2, 2, 2, 1, 2, 6, 6, 6, nil, 6 ]
|
32
|
+
|
33
|
+
racc_action_pointer = [
|
34
|
+
-2, 13, 8, nil, nil, nil, 13, nil, 3, nil,
|
35
|
+
3, nil, nil ]
|
36
|
+
|
37
|
+
racc_action_default = [
|
38
|
+
-8, -8, -1, -3, -4, -5, -8, -7, -8, -2,
|
39
|
+
-8, 13, -6 ]
|
40
|
+
|
41
|
+
racc_goto_table = [
|
42
|
+
9, 2, 1, nil, nil, nil, nil, 10, 9 ]
|
43
|
+
|
44
|
+
racc_goto_check = [
|
45
|
+
3, 2, 1, nil, nil, nil, nil, 2, 3 ]
|
46
|
+
|
47
|
+
racc_goto_pointer = [
|
48
|
+
nil, 2, 1, -2 ]
|
49
|
+
|
50
|
+
racc_goto_default = [
|
51
|
+
nil, nil, nil, 3 ]
|
52
|
+
|
53
|
+
racc_reduce_table = [
|
54
|
+
0, 0, :racc_error,
|
55
|
+
1, 8, :_reduce_1,
|
56
|
+
2, 9, :_reduce_2,
|
57
|
+
1, 9, :_reduce_none,
|
58
|
+
1, 10, :_reduce_4,
|
59
|
+
1, 10, :_reduce_5,
|
60
|
+
3, 10, :_reduce_6,
|
61
|
+
1, 10, :_reduce_7 ]
|
62
|
+
|
63
|
+
racc_reduce_n = 8
|
64
|
+
|
65
|
+
racc_shift_n = 13
|
66
|
+
|
67
|
+
racc_token_table = {
|
68
|
+
false => 0,
|
69
|
+
:error => 1,
|
70
|
+
:PARAM => 2,
|
71
|
+
:GLOB => 3,
|
72
|
+
:LPAREN => 4,
|
73
|
+
:RPAREN => 5,
|
74
|
+
:CHAR => 6 }
|
75
|
+
|
76
|
+
racc_nt_base = 7
|
77
|
+
|
78
|
+
racc_use_result_var = true
|
79
|
+
|
80
|
+
Racc_arg = [
|
81
|
+
racc_action_table,
|
82
|
+
racc_action_check,
|
83
|
+
racc_action_default,
|
84
|
+
racc_action_pointer,
|
85
|
+
racc_goto_table,
|
86
|
+
racc_goto_check,
|
87
|
+
racc_goto_default,
|
88
|
+
racc_goto_pointer,
|
89
|
+
racc_nt_base,
|
90
|
+
racc_reduce_table,
|
91
|
+
racc_token_table,
|
92
|
+
racc_shift_n,
|
93
|
+
racc_reduce_n,
|
94
|
+
racc_use_result_var ]
|
95
|
+
|
96
|
+
Racc_token_to_s_table = [
|
97
|
+
"$end",
|
98
|
+
"error",
|
99
|
+
"PARAM",
|
100
|
+
"GLOB",
|
101
|
+
"LPAREN",
|
102
|
+
"RPAREN",
|
103
|
+
"CHAR",
|
104
|
+
"$start",
|
105
|
+
"target",
|
106
|
+
"expr",
|
107
|
+
"token" ]
|
108
|
+
|
109
|
+
Racc_debug_parser = false
|
110
|
+
|
111
|
+
##### State transition tables end #####
|
112
|
+
|
113
|
+
# reduce 0 omitted
|
114
|
+
|
115
|
+
def _reduce_1(val, _values, result)
|
116
|
+
result = "\\A#{val.join}\\Z"
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
def _reduce_2(val, _values, result)
|
121
|
+
result = val.join
|
122
|
+
result
|
123
|
+
end
|
124
|
+
|
125
|
+
# reduce 3 omitted
|
126
|
+
|
127
|
+
def _reduce_4(val, _values, result)
|
128
|
+
name = val[0].to_sym
|
129
|
+
requirement = requirements[name]
|
130
|
+
result = REGEXP_NAMED_CAPTURE % [name, requirement]
|
131
|
+
|
132
|
+
result
|
133
|
+
end
|
134
|
+
|
135
|
+
def _reduce_5(val, _values, result)
|
136
|
+
name = val[0].to_sym
|
137
|
+
result = REGEXP_NAMED_CAPTURE % [name, '.+']
|
138
|
+
|
139
|
+
result
|
140
|
+
end
|
141
|
+
|
142
|
+
def _reduce_6(val, _values, result)
|
143
|
+
result = "(?:#{val[1]})?"
|
144
|
+
result
|
145
|
+
end
|
146
|
+
|
147
|
+
def _reduce_7(val, _values, result)
|
148
|
+
result = Regexp.escape(val[0])
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
152
|
+
def _reduce_none(val, _values, result)
|
153
|
+
val[0]
|
154
|
+
end
|
155
|
+
|
156
|
+
end # class StrexpParser
|
157
|
+
end # module Mount
|
158
|
+
end # module Rack
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#--
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by rex 1.0.4
|
4
|
+
# from lexical definition file "lib/rack/mount/strexp/tokenizer.rex".
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'racc/parser'
|
8
|
+
module Rack::Mount
|
9
|
+
class StrexpParser < Racc::Parser
|
10
|
+
require 'strscan'
|
11
|
+
|
12
|
+
class ScanError < StandardError ; end
|
13
|
+
|
14
|
+
attr_reader :lineno
|
15
|
+
attr_reader :filename
|
16
|
+
attr_accessor :state
|
17
|
+
|
18
|
+
def scan_setup(str)
|
19
|
+
@ss = StringScanner.new(str)
|
20
|
+
@lineno = 1
|
21
|
+
@state = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def action(&block)
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
|
28
|
+
def scan_str(str)
|
29
|
+
scan_setup(str)
|
30
|
+
do_parse
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_file( filename )
|
34
|
+
@filename = filename
|
35
|
+
open(filename, "r") do |f|
|
36
|
+
scan_setup(f.read)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def scan_file( filename )
|
41
|
+
load_file(filename)
|
42
|
+
do_parse
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def next_token
|
47
|
+
return if @ss.eos?
|
48
|
+
|
49
|
+
text = @ss.peek(1)
|
50
|
+
@lineno += 1 if text == "\n"
|
51
|
+
token = case @state
|
52
|
+
when nil
|
53
|
+
case
|
54
|
+
when (text = @ss.scan(/\\(\(|\)|:|\*)/))
|
55
|
+
action { [:CHAR, @ss[1]] }
|
56
|
+
|
57
|
+
when (text = @ss.scan(/\:([a-zA-Z_]\w*)/))
|
58
|
+
action { [:PARAM, @ss[1]] }
|
59
|
+
|
60
|
+
when (text = @ss.scan(/\*([a-zA-Z_]\w*)/))
|
61
|
+
action { [:GLOB, @ss[1]] }
|
62
|
+
|
63
|
+
when (text = @ss.scan(/\(/))
|
64
|
+
action { [:LPAREN, text] }
|
65
|
+
|
66
|
+
when (text = @ss.scan(/\)/))
|
67
|
+
action { [:RPAREN, text] }
|
68
|
+
|
69
|
+
when (text = @ss.scan(/./))
|
70
|
+
action { [:CHAR, text] }
|
71
|
+
|
72
|
+
else
|
73
|
+
text = @ss.string[@ss.pos .. -1]
|
74
|
+
raise ScanError, "can not match: '" + text + "'"
|
75
|
+
end # if
|
76
|
+
|
77
|
+
else
|
78
|
+
raise ScanError, "undefined state: '" + state.to_s + "'"
|
79
|
+
end # case state
|
80
|
+
token
|
81
|
+
end # def next_token
|
82
|
+
|
83
|
+
end # class
|
84
|
+
end # module
|
data/lib/rack/mount/utils.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
begin
|
2
|
+
require 'reginald'
|
3
|
+
rescue LoadError
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'vendor/reginald'))
|
5
|
+
require 'reginald'
|
6
|
+
end
|
7
|
+
|
3
8
|
require 'uri'
|
4
9
|
|
5
10
|
module Rack::Mount
|
@@ -19,9 +24,9 @@ module Rack::Mount
|
|
19
24
|
# normalize_path("") # => "/"
|
20
25
|
def normalize_path(path)
|
21
26
|
path = "/#{path}"
|
22
|
-
path.squeeze!(
|
23
|
-
path.sub!(%r{/+\Z},
|
24
|
-
path =
|
27
|
+
path.squeeze!('/')
|
28
|
+
path.sub!(%r{/+\Z}, '')
|
29
|
+
path = '/' if path == ''
|
25
30
|
path
|
26
31
|
end
|
27
32
|
module_function :normalize_path
|
@@ -99,173 +104,31 @@ module Rack::Mount
|
|
99
104
|
end
|
100
105
|
module_function :normalize_extended_expression
|
101
106
|
|
102
|
-
|
103
|
-
#
|
104
|
-
# regexp_anchored?(/^foo$/) # => true
|
105
|
-
# regexp_anchored?(/foo/) # => false
|
106
|
-
# regexp_anchored?(/^foo/) # => false
|
107
|
-
# regexp_anchored?(/foo$/) # => false
|
108
|
-
def regexp_anchored?(regexp)
|
109
|
-
regexp.source =~ /\A(\\A|\^).*(\\Z|\$)\Z/ ? true : false
|
110
|
-
end
|
111
|
-
module_function :regexp_anchored?
|
112
|
-
|
113
|
-
# Returns static string source of Regexp if it only includes static
|
114
|
-
# characters and no metacharacters. Otherwise the original Regexp is
|
115
|
-
# returned.
|
116
|
-
#
|
117
|
-
# extract_static_regexp(/^foo$/) # => "foo"
|
118
|
-
# extract_static_regexp(/^foo\.bar$/) # => "foo.bar"
|
119
|
-
# extract_static_regexp(/^foo|bar$/) # => /^foo|bar$/
|
120
|
-
def extract_static_regexp(regexp, options = nil)
|
121
|
-
if regexp.is_a?(String)
|
122
|
-
regexp = Regexp.compile("\\A#{regexp}\\Z", options)
|
123
|
-
end
|
124
|
-
|
125
|
-
# Just return if regexp is case-insensitive
|
126
|
-
return regexp if regexp.casefold?
|
127
|
-
|
128
|
-
source = regexp.source
|
129
|
-
if regexp_anchored?(regexp)
|
130
|
-
source.sub!(/^(\\A|\^)(.*)(\\Z|\$)$/, '\2')
|
131
|
-
unescaped_source = source.gsub(/\\/, Const::EMPTY_STRING)
|
132
|
-
if source == Regexp.escape(unescaped_source) &&
|
133
|
-
Regexp.compile("\\A(#{source})\\Z") =~ unescaped_source
|
134
|
-
return unescaped_source
|
135
|
-
end
|
136
|
-
end
|
137
|
-
regexp
|
138
|
-
end
|
139
|
-
module_function :extract_static_regexp
|
140
|
-
|
141
|
-
if Const::SUPPORTS_NAMED_CAPTURES
|
142
|
-
NAMED_CAPTURE_REGEXP = /\?<([^>]+)>/
|
143
|
-
else
|
144
|
-
NAMED_CAPTURE_REGEXP = /\?:<([^>]+)>/
|
145
|
-
end
|
146
|
-
|
147
|
-
# Strips shim named capture syntax and returns a clean Regexp and
|
148
|
-
# an ordered array of the named captures.
|
149
|
-
#
|
150
|
-
# extract_named_captures(/[a-z]+/) # => /[a-z]+/, []
|
151
|
-
# extract_named_captures(/(?:<foo>[a-z]+)/) # => /([a-z]+)/, ['foo']
|
152
|
-
# extract_named_captures(/([a-z]+)(?:<foo>[a-z]+)/)
|
153
|
-
# # => /([a-z]+)([a-z]+)/, [nil, 'foo']
|
154
|
-
def extract_named_captures(regexp)
|
155
|
-
options = regexp.is_a?(Regexp) ? regexp.options : nil
|
156
|
-
source = Regexp.compile(regexp).source
|
157
|
-
names, scanner = [], StringScanner.new(source)
|
158
|
-
|
159
|
-
while scanner.skip_until(/\(/)
|
160
|
-
if scanner.scan(NAMED_CAPTURE_REGEXP)
|
161
|
-
names << scanner[1]
|
162
|
-
else
|
163
|
-
names << nil
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
names = [] unless names.any?
|
168
|
-
source.gsub!(NAMED_CAPTURE_REGEXP, Const::EMPTY_STRING)
|
169
|
-
return Regexp.compile(source, options), names
|
170
|
-
end
|
171
|
-
module_function :extract_named_captures
|
172
|
-
|
173
|
-
class Capture < Array #:nodoc:
|
174
|
-
attr_reader :name, :optional
|
175
|
-
alias_method :optional?, :optional
|
176
|
-
|
177
|
-
def initialize(*args)
|
178
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
179
|
-
|
180
|
-
@name = options.delete(:name)
|
181
|
-
@name = @name.to_s if @name
|
182
|
-
|
183
|
-
@optional = options.delete(:optional) || false
|
184
|
-
|
185
|
-
super(args)
|
186
|
-
end
|
187
|
-
|
188
|
-
def ==(obj)
|
189
|
-
obj.is_a?(Capture) && @name == obj.name && @optional == obj.optional && super
|
190
|
-
end
|
191
|
-
|
192
|
-
def optionalize!
|
193
|
-
@optional = true
|
194
|
-
self
|
195
|
-
end
|
196
|
-
|
197
|
-
def named?
|
198
|
-
name && name != Const::EMPTY_STRING
|
199
|
-
end
|
200
|
-
|
201
|
-
def to_s
|
202
|
-
source = "(#{join})"
|
203
|
-
source << '?' if optional?
|
204
|
-
source
|
205
|
-
end
|
206
|
-
|
207
|
-
def first_part
|
208
|
-
first.is_a?(Capture) ? first.first_part : first
|
209
|
-
end
|
210
|
-
|
211
|
-
def last_part
|
212
|
-
last.is_a?(Capture) ? last.last_part : last
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
def extract_regexp_parts(regexp) #:nodoc:
|
107
|
+
def parse_regexp(regexp)
|
217
108
|
unless regexp.is_a?(RegexpWithNamedGroups)
|
218
109
|
regexp = RegexpWithNamedGroups.new(regexp)
|
219
110
|
end
|
220
111
|
|
221
|
-
|
222
|
-
regexp, names = extract_named_captures(regexp)
|
223
|
-
else
|
224
|
-
names = regexp.names
|
225
|
-
end
|
226
|
-
source = regexp.source
|
227
|
-
|
228
|
-
source =~ /^(\\A|\^)/ ? source.gsub!(/^(\\A|\^)/, Const::EMPTY_STRING) :
|
229
|
-
raise(ArgumentError, "#{source} needs to match the start of the string")
|
230
|
-
|
231
|
-
scanner = StringScanner.new(source)
|
232
|
-
stack = [[]]
|
112
|
+
expression = Reginald.parse(regexp)
|
233
113
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
cur.push(Const::NULL)
|
244
|
-
elsif escaped
|
245
|
-
cur.push('') unless cur.last.is_a?(String)
|
246
|
-
cur.last << char
|
247
|
-
elsif char == '('
|
248
|
-
name = names[capture_index]
|
249
|
-
capture = Capture.new(:name => name)
|
250
|
-
capture_index += 1
|
251
|
-
cur.push(capture)
|
252
|
-
stack.push(capture)
|
253
|
-
elsif char == ')'
|
254
|
-
capture = stack.pop
|
255
|
-
if scanner.peek(1) == '?'
|
256
|
-
scanner.pos += 1
|
257
|
-
capture.optionalize!
|
114
|
+
unless RegexpWithNamedGroups.supports_named_captures?
|
115
|
+
tag_captures = Proc.new do |group|
|
116
|
+
group.each do |child|
|
117
|
+
if child.is_a?(Reginald::Group)
|
118
|
+
child.name = regexp.names[child.index] if child.index
|
119
|
+
tag_captures.call(child)
|
120
|
+
elsif child.is_a?(Reginald::Expression)
|
121
|
+
tag_captures.call(child)
|
122
|
+
end
|
258
123
|
end
|
259
|
-
elsif char == '$'
|
260
|
-
cur.push(Const::NULL)
|
261
|
-
else
|
262
|
-
cur.push('') unless cur.last.is_a?(String)
|
263
|
-
cur.last << char
|
264
124
|
end
|
125
|
+
tag_captures.call(expression)
|
265
126
|
end
|
266
127
|
|
267
|
-
|
128
|
+
expression
|
129
|
+
rescue Racc::ParseError
|
130
|
+
[]
|
268
131
|
end
|
269
|
-
module_function :
|
132
|
+
module_function :parse_regexp
|
270
133
|
end
|
271
134
|
end
|