lgierth-rack-mount 0.6.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +36 -0
  3. data/lib/rack/mount.rb +32 -0
  4. data/lib/rack/mount/analysis/frequency.rb +60 -0
  5. data/lib/rack/mount/analysis/histogram.rb +74 -0
  6. data/lib/rack/mount/analysis/splitting.rb +159 -0
  7. data/lib/rack/mount/code_generation.rb +117 -0
  8. data/lib/rack/mount/generatable_regexp.rb +210 -0
  9. data/lib/rack/mount/multimap.rb +53 -0
  10. data/lib/rack/mount/prefix.rb +36 -0
  11. data/lib/rack/mount/regexp_with_named_groups.rb +69 -0
  12. data/lib/rack/mount/route.rb +130 -0
  13. data/lib/rack/mount/route_set.rb +420 -0
  14. data/lib/rack/mount/strexp.rb +68 -0
  15. data/lib/rack/mount/strexp/parser.rb +160 -0
  16. data/lib/rack/mount/strexp/parser.y +34 -0
  17. data/lib/rack/mount/strexp/tokenizer.rb +83 -0
  18. data/lib/rack/mount/strexp/tokenizer.rex +12 -0
  19. data/lib/rack/mount/utils.rb +162 -0
  20. data/lib/rack/mount/vendor/multimap/multimap.rb +569 -0
  21. data/lib/rack/mount/vendor/multimap/multiset.rb +185 -0
  22. data/lib/rack/mount/vendor/multimap/nested_multimap.rb +158 -0
  23. data/lib/rack/mount/vendor/regin/regin.rb +75 -0
  24. data/lib/rack/mount/vendor/regin/regin/alternation.rb +40 -0
  25. data/lib/rack/mount/vendor/regin/regin/anchor.rb +4 -0
  26. data/lib/rack/mount/vendor/regin/regin/atom.rb +54 -0
  27. data/lib/rack/mount/vendor/regin/regin/character.rb +51 -0
  28. data/lib/rack/mount/vendor/regin/regin/character_class.rb +50 -0
  29. data/lib/rack/mount/vendor/regin/regin/collection.rb +77 -0
  30. data/lib/rack/mount/vendor/regin/regin/expression.rb +126 -0
  31. data/lib/rack/mount/vendor/regin/regin/group.rb +85 -0
  32. data/lib/rack/mount/vendor/regin/regin/options.rb +55 -0
  33. data/lib/rack/mount/vendor/regin/regin/parser.rb +520 -0
  34. data/lib/rack/mount/vendor/regin/regin/tokenizer.rb +246 -0
  35. data/lib/rack/mount/vendor/regin/regin/version.rb +3 -0
  36. data/lib/rack/mount/version.rb +3 -0
  37. metadata +140 -0
@@ -0,0 +1,160 @@
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/utils'
10
+ require 'rack/mount/strexp/tokenizer'
11
+
12
+ module Rack
13
+ module Mount
14
+ class StrexpParser < Racc::Parser
15
+
16
+
17
+ if Regin.regexp_supports_named_captures?
18
+ REGEXP_NAMED_CAPTURE = '(?<%s>%s)'.freeze
19
+ else
20
+ REGEXP_NAMED_CAPTURE = '(?:<%s>%s)'.freeze
21
+ end
22
+
23
+ attr_accessor :anchor, :requirements
24
+ ##### State transition tables begin ###
25
+
26
+ racc_action_table = [
27
+ 1, 2, 3, 9, 4, 1, 2, 3, 12, 4,
28
+ 1, 2, 3, 11, 4, 1, 2, 3, nil, 4 ]
29
+
30
+ racc_action_check = [
31
+ 0, 0, 0, 5, 0, 3, 3, 3, 9, 3,
32
+ 8, 8, 8, 8, 8, 6, 6, 6, nil, 6 ]
33
+
34
+ racc_action_pointer = [
35
+ -2, nil, nil, 3, nil, 3, 13, nil, 8, 8,
36
+ nil, nil, nil ]
37
+
38
+ racc_action_default = [
39
+ -8, -4, -5, -8, -7, -8, -1, -3, -8, -8,
40
+ -2, -6, 13 ]
41
+
42
+ racc_goto_table = [
43
+ 6, 5, 10, 8, 10 ]
44
+
45
+ racc_goto_check = [
46
+ 2, 1, 3, 2, 3 ]
47
+
48
+ racc_goto_pointer = [
49
+ nil, 1, 0, -4 ]
50
+
51
+ racc_goto_default = [
52
+ nil, nil, nil, 7 ]
53
+
54
+ racc_reduce_table = [
55
+ 0, 0, :racc_error,
56
+ 1, 8, :_reduce_1,
57
+ 2, 9, :_reduce_2,
58
+ 1, 9, :_reduce_none,
59
+ 1, 10, :_reduce_4,
60
+ 1, 10, :_reduce_5,
61
+ 3, 10, :_reduce_6,
62
+ 1, 10, :_reduce_7 ]
63
+
64
+ racc_reduce_n = 8
65
+
66
+ racc_shift_n = 13
67
+
68
+ racc_token_table = {
69
+ false => 0,
70
+ :error => 1,
71
+ :PARAM => 2,
72
+ :GLOB => 3,
73
+ :LPAREN => 4,
74
+ :RPAREN => 5,
75
+ :CHAR => 6 }
76
+
77
+ racc_nt_base = 7
78
+
79
+ racc_use_result_var = true
80
+
81
+ Racc_arg = [
82
+ racc_action_table,
83
+ racc_action_check,
84
+ racc_action_default,
85
+ racc_action_pointer,
86
+ racc_goto_table,
87
+ racc_goto_check,
88
+ racc_goto_default,
89
+ racc_goto_pointer,
90
+ racc_nt_base,
91
+ racc_reduce_table,
92
+ racc_token_table,
93
+ racc_shift_n,
94
+ racc_reduce_n,
95
+ racc_use_result_var ]
96
+
97
+ Racc_token_to_s_table = [
98
+ "$end",
99
+ "error",
100
+ "PARAM",
101
+ "GLOB",
102
+ "LPAREN",
103
+ "RPAREN",
104
+ "CHAR",
105
+ "$start",
106
+ "target",
107
+ "expr",
108
+ "token" ]
109
+
110
+ Racc_debug_parser = false
111
+
112
+ ##### State transition tables end #####
113
+
114
+ # reduce 0 omitted
115
+
116
+ def _reduce_1(val, _values, result)
117
+ result = anchor ? "\\A#{val.join}\\Z" : "\\A#{val.join}"
118
+ result
119
+ end
120
+
121
+ def _reduce_2(val, _values, result)
122
+ result = val.join
123
+ result
124
+ end
125
+
126
+ # reduce 3 omitted
127
+
128
+ def _reduce_4(val, _values, result)
129
+ name = val[0].to_sym
130
+ requirement = requirements[name]
131
+ result = REGEXP_NAMED_CAPTURE % [name, requirement]
132
+
133
+ result
134
+ end
135
+
136
+ def _reduce_5(val, _values, result)
137
+ name = val[0].to_sym
138
+ requirement = requirements[name]
139
+ result = REGEXP_NAMED_CAPTURE % [name, '.+' || requirement]
140
+
141
+ result
142
+ end
143
+
144
+ def _reduce_6(val, _values, result)
145
+ result = "(?:#{val[1]})?"
146
+ result
147
+ end
148
+
149
+ def _reduce_7(val, _values, result)
150
+ result = Regexp.escape(val[0])
151
+ result
152
+ end
153
+
154
+ def _reduce_none(val, _values, result)
155
+ val[0]
156
+ end
157
+
158
+ end # class StrexpParser
159
+ end # module Mount
160
+ end # module Rack
@@ -0,0 +1,34 @@
1
+ class Rack::Mount::StrexpParser
2
+ rule
3
+ target: expr { result = anchor ? "\\A#{val.join}\\Z" : "\\A#{val.join}" }
4
+
5
+ expr: expr token { result = val.join }
6
+ | token
7
+
8
+ token: PARAM {
9
+ name = val[0].to_sym
10
+ requirement = requirements[name]
11
+ result = REGEXP_NAMED_CAPTURE % [name, requirement]
12
+ }
13
+ | GLOB {
14
+ name = val[0].to_sym
15
+ requirement = requirements[name]
16
+ result = REGEXP_NAMED_CAPTURE % [name, '.+' || requirement]
17
+ }
18
+ | LPAREN expr RPAREN { result = "(?:#{val[1]})?" }
19
+ | CHAR { result = Regexp.escape(val[0]) }
20
+ end
21
+
22
+ ---- header ----
23
+ require 'rack/mount/utils'
24
+ require 'rack/mount/strexp/tokenizer'
25
+
26
+ ---- inner
27
+
28
+ if Regin.regexp_supports_named_captures?
29
+ REGEXP_NAMED_CAPTURE = '(?<%s>%s)'.freeze
30
+ else
31
+ REGEXP_NAMED_CAPTURE = '(?:<%s>%s)'.freeze
32
+ end
33
+
34
+ attr_accessor :anchor, :requirements
@@ -0,0 +1,83 @@
1
+ #--
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by rex 1.0.5.beta1
4
+ # from lexical definition file "lib/rack/mount/strexp/tokenizer.rex".
5
+ #++
6
+
7
+ require 'racc/parser'
8
+ class Rack::Mount::StrexpParser < Racc::Parser
9
+ require 'strscan'
10
+
11
+ class ScanError < StandardError ; end
12
+
13
+ attr_reader :lineno
14
+ attr_reader :filename
15
+ attr_accessor :state
16
+
17
+ def scan_setup(str)
18
+ @ss = StringScanner.new(str)
19
+ @lineno = 1
20
+ @state = nil
21
+ end
22
+
23
+ def action
24
+ yield
25
+ end
26
+
27
+ def scan_str(str)
28
+ scan_setup(str)
29
+ do_parse
30
+ end
31
+ alias :scan :scan_str
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
@@ -0,0 +1,12 @@
1
+ class Rack::Mount::StrexpParser
2
+ macro
3
+ RESERVED \(|\)|:|\*
4
+ ALPHA_U [a-zA-Z_]
5
+ rule
6
+ \\({RESERVED}) { [:CHAR, @ss[1]] }
7
+ \:({ALPHA_U}\w*) { [:PARAM, @ss[1]] }
8
+ \*({ALPHA_U}\w*) { [:GLOB, @ss[1]] }
9
+ \( { [:LPAREN, text] }
10
+ \) { [:RPAREN, text] }
11
+ . { [:CHAR, text] }
12
+ end
@@ -0,0 +1,162 @@
1
+ begin
2
+ require 'regin'
3
+ rescue LoadError
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__), 'vendor/regin'))
5
+ require 'regin'
6
+ end
7
+
8
+ require 'uri'
9
+
10
+ module Rack::Mount
11
+ # Private utility methods used throughout Rack::Mount.
12
+ #--
13
+ # This module is a trash can. Try to move these functions into
14
+ # more appropriate contexts.
15
+ #++
16
+ module Utils
17
+ def silence_debug
18
+ old_debug, $DEBUG = $DEBUG, nil
19
+ yield
20
+ ensure
21
+ $DEBUG = old_debug
22
+ end
23
+ module_function :silence_debug
24
+
25
+ def debug(msg)
26
+ warn "Rack::Mount #{msg}" if $DEBUG
27
+ end
28
+ module_function :debug
29
+
30
+ # Normalizes URI path.
31
+ #
32
+ # Strips off trailing slash and ensures there is a leading slash.
33
+ #
34
+ # normalize_path("/foo") # => "/foo"
35
+ # normalize_path("/foo/") # => "/foo"
36
+ # normalize_path("foo") # => "/foo"
37
+ # normalize_path("") # => "/"
38
+ def normalize_path(path)
39
+ path = "/#{path}"
40
+ path.squeeze!('/')
41
+ path.sub!(%r{/+\Z}, '')
42
+ path = '/' if path == ''
43
+ path
44
+ end
45
+ module_function :normalize_path
46
+
47
+ # Removes trailing nils from array.
48
+ #
49
+ # pop_trailing_blanks!([1, 2, 3]) # => [1, 2, 3]
50
+ # pop_trailing_blanks!([1, 2, 3, nil, ""]) # => [1, 2, 3]
51
+ # pop_trailing_blanks!([nil]) # => []
52
+ # pop_trailing_blanks!([""]) # => []
53
+ def pop_trailing_blanks!(ary)
54
+ while ary.length > 0 && (ary.last.nil? || ary.last == '')
55
+ ary.pop
56
+ end
57
+ ary
58
+ end
59
+ module_function :pop_trailing_blanks!
60
+
61
+ RESERVED_PCHAR = ':@&=+$,;%'
62
+ SAFE_PCHAR = "#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}"
63
+ if RUBY_VERSION >= '1.9'
64
+ UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false).freeze
65
+ else
66
+ UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false, 'N').freeze
67
+ end
68
+
69
+ Parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
70
+
71
+ def escape_uri(uri)
72
+ Parser.escape(uri.to_s, UNSAFE_PCHAR)
73
+ end
74
+ module_function :escape_uri
75
+
76
+ if ''.respond_to?(:force_encoding)
77
+ def unescape_uri(uri)
78
+ Parser.unescape(uri).force_encoding('utf-8')
79
+ end
80
+ else
81
+ def unescape_uri(uri)
82
+ URI.unescape(uri)
83
+ end
84
+ end
85
+ module_function :unescape_uri
86
+
87
+ # Taken from Rack 1.1.x to build nested query strings
88
+ def build_nested_query(value, prefix = nil) #:nodoc:
89
+ case value
90
+ when Array
91
+ value.map { |v|
92
+ build_nested_query(v, "#{prefix}[]")
93
+ }.join("&")
94
+ when Hash
95
+ value.map { |k, v|
96
+ build_nested_query(v, prefix ? "#{prefix}[#{Rack::Utils.escape(k)}]" : Rack::Utils.escape(k))
97
+ }.join("&")
98
+ when String
99
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
100
+ "#{prefix}=#{Rack::Utils.escape(value)}"
101
+ else
102
+ prefix
103
+ end
104
+ end
105
+ module_function :build_nested_query
106
+
107
+ # Determines whether the regexp must match the entire string.
108
+ #
109
+ # regexp_anchored?(/^foo$/) # => true
110
+ # regexp_anchored?(/foo/) # => false
111
+ # regexp_anchored?(/^foo/) # => false
112
+ # regexp_anchored?(/foo$/) # => false
113
+ def regexp_anchored?(regexp)
114
+ regexp.source =~ /\A(\\A|\^).*(\\Z|\$)\Z/m ? true : false
115
+ end
116
+ module_function :regexp_anchored?
117
+
118
+ def normalize_extended_expression(regexp)
119
+ return regexp unless regexp.options & Regexp::EXTENDED != 0
120
+ source = regexp.source
121
+ source.gsub!(/#.+$/, '')
122
+ source.gsub!(/\s+/, '')
123
+ source.gsub!(/\\\//, '/')
124
+ Regexp.compile(source)
125
+ end
126
+ module_function :normalize_extended_expression
127
+
128
+ def parse_regexp(regexp)
129
+ cache = @@_parse_regexp_cache ||= {}
130
+
131
+ if expression = cache[regexp]
132
+ return expression
133
+ end
134
+
135
+ unless regexp.is_a?(RegexpWithNamedGroups)
136
+ regexp = RegexpWithNamedGroups.new(regexp)
137
+ end
138
+
139
+ expression = Regin.parse(regexp)
140
+
141
+ unless Regin.regexp_supports_named_captures?
142
+ tag_captures = Proc.new do |group|
143
+ case group
144
+ when Regin::Group
145
+ # TODO: dup instead of mutating
146
+ group.instance_variable_set('@name', regexp.names[group.index]) if group.index
147
+ tag_captures.call(group.expression)
148
+ when Regin::Expression
149
+ group.each { |child| tag_captures.call(child) }
150
+ end
151
+ end
152
+ tag_captures.call(expression)
153
+ end
154
+
155
+ cache[regexp] = expression.freeze
156
+ expression
157
+ rescue Racc::ParseError, Regin::Parser::ScanError
158
+ []
159
+ end
160
+ module_function :parse_regexp
161
+ end
162
+ end