diff --git a/vendor/plugins/radius/CHANGELOG b/vendor/plugins/radius/CHANGELOG new file mode 100644 index 00000000..4efb14f7 --- /dev/null +++ b/vendor/plugins/radius/CHANGELOG @@ -0,0 +1,42 @@ += Change Log + +== edge +* Support for Rubinius [jlong] +* Support for Ruby 1.9 [aemadrid] +* More tests [aemadrid] +* Fixed issue #5 - problem with other namespace tags [jemmyw] +* Switched to Jeweler for better gem management [jlong] +* Allow operation in a threaded environment (parser per-thread, shared context) +* Allow switching scanners that tokenize templates. +* Include SquiggleScanner to parse tags that look like "{ hello /}" + +== 0.6.1 +* Fixed a problem with non-tags that have no prefix or tag name (see test_parse_chirpy_bird) + +== 0.6.0 (private release) +* Split radius.rb into multiple files. +* Ported the really hairy regexes from Radius::Parser to a single Ragel machine. +* Added and refactored tests. +* Refactored Rakefile and other administrativia. + +== 0.5.1 +* Fixed a problem with parsing quotes where a single tag preceding a double tag would consume the start tag of the double tag if both contained attributes. + +== 0.5.0 +* Created a DSL for tag definitions (introducing a DSL makes this version of Radiant incompatible with the last). The DSL has the following features: + - full support for nested tags + - global and local tag variables + - Contexts can now be defined dynamically (instead of being subclassed) + - see the QUICKSTART for more info +* Many refactorings of the library and unit tests. +* Changed the license to the MIT-LICENSE. +* Updated documentation to reflect the changes. +* Updated the version number to reflect the maturity of the code base. + +== 0.0.2 +* Refactored Parser to use Context#render_tag instead of #send when rendering tags defined on a Context. +* UndefinedTagError is now thrown when Parser tries to render a tag which doesn't exist on a Context. +* Added Context#tag_missing which works like method_method missing on Object, but is tag specific. + +== 0.0.1 +* First release. diff --git a/vendor/plugins/radius/LICENSE b/vendor/plugins/radius/LICENSE new file mode 100644 index 00000000..f6f3aa75 --- /dev/null +++ b/vendor/plugins/radius/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006-2010, John W. Long + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/plugins/radius/QUICKSTART.rdoc b/vendor/plugins/radius/QUICKSTART.rdoc new file mode 100644 index 00000000..d4972e95 --- /dev/null +++ b/vendor/plugins/radius/QUICKSTART.rdoc @@ -0,0 +1,322 @@ += Radius Quick Start + + +== Defining Tags + +Before you can parse a template with Radius you need to create a Context object which defines +the tags that will be used in the template. This is actually quite simple: + + require 'radius' + + context = Radius::Context.new + context.define_tag "hello" do |tag| + "Hello #{tag.attr['name'] || 'World'}!" + end + +Once you have defined a context you can easily create a Parser: + + parser = Radius::Parser.new(context) + puts parser.parse('

') + puts parser.parse('

') + +This code will output: + +

Hello World!

+

Hello John!

+ +Note how you can pass attributes from the template to the context using the attributes hash. +Above, the first tag that was parsed didn't have a name attribute so the code in the +hello+ +tag definition uses "World" instead. The second time the tag is parsed the name attribute is +set to "John" which is used to create the string "Hello John!". Tags that do not follow this +rule will be treated as if they were undefined (like normal methods). + + +== Container Tags + +Radius also allows you to define "container" tags. That is, tags that contain content and +that may optionally manipulate it in some way. For example, if you have RedCloth installed +you could define another tag to parse and create Textile output: + + require 'redcloth' + + context.define_tag "textile" do |tag| + contents = tag.expand + RedCloth.new(contents).to_html + end + +(The code tag.expand above returns the contents of the template between the start and end +tags.) + +With the code above your parser can easily handle Textile: + + parser.parse('h1. Hello **World**!') + +This code will output: + +

Hello World!

+ + +== Nested Tags + +But wait!--it gets better. Because container tags can manipulate the content they contain +you can use them to iterate over collections: + + context = Radius::Context.new + + context.define_tag "stooge" do |tag| + content = '' + ["Larry", "Moe", "Curly"].each do |name| + tag.locals.name = name + content << tag.expand + end + content + end + + context.define_tag "stooge:name" do |tag| + tag.locals.name + end + + parser = Radius::Parser.new(context) + + template = <<-TEMPLATE + + TEMPLATE + + puts parser.parse(template) + +This code will output: + + + +Note how the definition for the +name+ tag is defined. Because "name" is prefixed +with "stooge:" the +name+ tag cannot appear outside the +stooge+ tag. Had it been defined +simply as "name" it would be valid anywhere, even outside the +stooge+ tag (which was +not what we wanted). Using the colon operator you can define tags with any amount of +nesting. + + +== Exposing Objects to Templates + +During normal operation, you will often want to expose certain objects to your templates. +Writing the tags to do this all by hand would be cumbersome of Radius did not provide +several mechanisms to make this easier. The first is a way of exposing objects as tags +on the context object. To expose an object simply call the +define_tag+ +method with the +for+ option: + + context.define_tag "count", :for => 1 + +This would expose the object 1 to the template as the +count+ tag. It's basically the +equivalent of writing: + + context.define_tag("count") { 1 } + +So far this doesn't save you a whole lot of typing, but suppose you want to expose certain +methods that are on that object? You could do this: + + context.define_tag "user", :for => user, :expose => [ :name, :age, :email ] + +This will add a total of four tags to the context. One for the user variable, and +one for each of the three methods listed in the +expose+ clause. You could now get the user's +name inside your template like this: + + + +If "John" was the value stored in user.name the template would render as "John". + + +== Tag Shorthand + +In the example above we made reference to user.name in our template by using the +following code: + + + +There is a much easer way to refer to the user.name variable. Use the colon operator +to "scope" the reference to name: + + + +Radius allows you to use this shortcut for all tags. + + +== Changing the Tag Prefix + +By default, all Radius tags must begin with "radius". You can change this by altering the +tag_prefix attribute on a Parser. For example: + + parser = Radius::Parser.new(context, :tag_prefix => 'r') + +Now, when parsing templates with +parser+, Radius will require that every tag begin with "r" +instead of "radius". + + +== Custom Behavior for Undefined Tags + +Context#tag_missing behaves much like Object#method_missing only it allows you to define +specific behavior for when a tag is not defined on a Context. For example: + + class LazyContext < Radius::Context + def tag_missing(tag, attr, &block) + "ERROR: Undefined tag `#{tag}' with attributes #{attr.inspect}" + end + end + + parser = Radius::Parser.new(LazyContext.new, :tag_prefix => 'lazy') + puts parser.parse('') + +This will output: + + ERROR: Undefined tag `weird' with attributes {"value"=>"true"} + +Normally, when the Radius Parser encounters an undefined tag for a Context it raises an +UndefinedTagError, but since we have defined #tag_missing on LazyContext the Parser now +outputs a nicely formated error message when we parse a string that does not contain a +valid tag. + + +== Tag Bindings + +Radius passes a TagBinding into the block of the Context#define_tag method. The tag +binding is useful for a number of tasks. A tag binding has an #expand instance method +which processes a tag's contents and returns the result. It also has a #attr method +which returns a hash of the attributes that were passed into the tag. TagBinding also +contains the TagBinding#single? and TagBinding#double? methods which return true or false +based on wether the tag is a container tag or not. More about the methods which are +available on tag bindings can be found on the Radius::TagBinding documentation page. + + +== Tag Binding Locals, Globals, and Context Sensitive Tags + +A TagBinding also contains two OpenStruct-like objects which are useful when developing +tags. TagBinding#globals is useful for storing variables which you would like to be +accessible to all tags: + + context.define_tag "inc" do |tag| + tag.globals.count ||= 0 + tag.globals.count += 1 + "" + end + + context.define_tag "count" do |tag| + tag.globals.count || 0 + end + +TagBinding#locals mirrors the variables that are in TagBinding#globals, but allows child +tags to redefine variables. This is valuable when defining context sensitive tags: + + class Person + attr_accessor :name, :friend + def initialize(name) + @name = name + end + end + + jack = Person.new('Jack') + jill = Person.new('Jill') + jack.friend = jill + jill.friend = jack + + context = Radius::Context.new do |c| + c.define_tag "jack" do |tag| + tag.locals.person = jack + tag.expand + end + c.define_tag "jill" do |tag| + tag.locals.person = jill + tag.expand + end + c.define_tag "name" do |tag| + tag.locals.person.name rescue tag.missing! + end + c.define_tag "friend" do |tag| + tag.locals.person = tag.locals.person.friend rescue tag.missing! + tag.expand + end + end + + parser = Radius::Parser.new(context, :tag_prefix => 'r') + + parser.parse('') #=> "Jack" + parser.parse('') #=> "Jill" + parser.parse('') #=> "Jack" + parser.parse('') #=> "Jack" + parser.parse(' and ') #=> "Jack and Jill" + parser.parse('') # raises a Radius::UndefinedTagError exception + +Notice how TagBinding#locals enables intelligent nesting. "" evaluates to +"Jill", but "" evaluates to "Jack". Locals lose scope as soon as +the tag they were defined in closes. Globals on the other hand, never lose scope. + +The final line in the example above demonstrates that calling "" raises a +TagMissing error. This is because of the way the name tag was defined: + + tag.locals.person.name rescue tag.missing! + +If person is not defined on locals it will return nil. Calling #name on nil would normally +raise a NoMethodError exception, but because of the 'rescue' clause the TagBinding#missing! +method is called which fires off Context#tag_missing. By default Context#tag_missing raises +a UndefinedTagError exception. The 'rescue tag.missing!' idiom is extremly useful for adding +simple error checking to context sensitive tags. + + +== Tag Specificity + +When Radius is presented with two tags that have the same name, but different nesting +Radius uses an algorithm similar to the way winning rules are calculated in Cascading Style +Sheets (CSS) to determine which definition should be used. Each time a tag is encountered +in a template potential tags are assigned specificity values and the tag with the highest +specificity wins. + +For example, given the following tag definitions: + + nesting + extra:nesting + parent:child:nesting + +And template: + + + +Radius will calculate specificity values like this: + + nesting => 1.0.0.0 + extra:nesting => 1.0.1.0 + parent:child:nesting => 1.1.0.1 + +Meaning that parent:child:nesting will win. If a template contained: + + + +The following specificity values would be assigned to each of the tag definitions: + + nesting => 1.0.0.0 + extra:nesting => 1.1.0.0 + parent:child:nesting => 1.0.1.1 + +Meaning that extra:nesting would win because it is more "specific". + +Values are assigned by assigning points to each of the tags from right to left. +Given a tag found in a template with nesting four levels deep, the maximum +specificity a tag could be assigned would be: + + 1.1.1.1 + +One point for each of the levels. + +In practice, you don't need to understand this topic to be effective with Radius. +For the most part you will find that Radius resolves tags precisely the way that +you would expect. If you find this section confusing forget about it and refer +back to it if you find that tags are resolving differently from the way that you +expected. diff --git a/vendor/plugins/radius/README.rdoc b/vendor/plugins/radius/README.rdoc new file mode 100644 index 00000000..1c16bcd0 --- /dev/null +++ b/vendor/plugins/radius/README.rdoc @@ -0,0 +1,100 @@ += Radius -- Powerful Tag-Based Templates + +Radius is a powerful tag-based template language for Ruby inspired by the +template languages used in MovableType[http://www.movabletype.org] and +TextPattern[http://www.textpattern.com]. It uses tags similar to XML, but can +be used to generate any form of plain text (HTML, e-mail, etc...). + + +== Usage + +With Radius, it is extremely easy to create custom tags and parse them. Here's a small +example: + + require 'radius' + + # Define tags on a context that will be available to a template: + context = Radius::Context.new do |c| + c.define_tag 'hello' do + 'Hello world' + end + c.define_tag 'repeat' do |tag| + number = (tag.attr['times'] || '1').to_i + result = '' + number.times { result << tag.expand } + result + end + end + + # Create a parser to parse tags that begin with 'r:' + parser = Radius::Parser.new(context, :tag_prefix => 'r') + + # Parse tags and output the result + puts parser.parse(%{A small example:\n* !\n}) + +Output: + + A small example: + * Hello world! + * Hello world! + * Hello world! + + +== Quick Start + +Read the QUICKSTART file to get up and running with Radius. + + +== Requirements + +Radius does not have any external requirements for using the library in your +own programs. + +Ragel is required to create the ruby parser from the Ragel specification, +and both Ragel and Graphviz are required to draw the state graph for the +parser. + + +== Installation + +It is recommended that you install Radius using the RubyGems packaging system: + + % gem install --remote radius + + +== License + +Radius is released under the MIT license and is copyright (c) 2006-2010 +John W. Long. A copy of the MIT license can be found in the LICENSE file. + + +== Roadmap + +This is a prioritized roadmap for future releases: + +1. Clean up the current code base. [Done] + +2. Add support for multi-level contexts: tags should be able to be + defined to only be valid within other sets of tags. [Done] + +3. Create a simple DSL for defining contexts. [Done] + +4. Optimize for speed, modify scan.rl to emit C. + + +== Development + +The latest version of Radius can be found on RubyForge: + +http://rubyforge.org/projects/radius + +Experimental and development versions of Radius can be found on Github: + +http://github.com/jlong/radius + +If you are interested in helping with the development of Radius, feel free to +fork the project on GitHub and send me a pull request. + + +John Long :: +http://wiseheartdesign.com diff --git a/vendor/plugins/radius/Rakefile b/vendor/plugins/radius/Rakefile new file mode 100644 index 00000000..13823529 --- /dev/null +++ b/vendor/plugins/radius/Rakefile @@ -0,0 +1,8 @@ +require 'rubygems' +require 'rake' + +require File.dirname(__FILE__) + '/lib/radius/version' + +Dir['tasks/**/*.rake'].each { |t| load t } + +task :default => :test diff --git a/vendor/plugins/radius/VERSION b/vendor/plugins/radius/VERSION new file mode 100644 index 00000000..8e3db852 --- /dev/null +++ b/vendor/plugins/radius/VERSION @@ -0,0 +1 @@ +0.7.0.prerelease \ No newline at end of file diff --git a/vendor/plugins/radius/lib/radius.rb b/vendor/plugins/radius/lib/radius.rb new file mode 100644 index 00000000..c0468ff8 --- /dev/null +++ b/vendor/plugins/radius/lib/radius.rb @@ -0,0 +1,11 @@ +require 'radius/version' +require 'radius/error' +require 'radius/tag_definitions' +require 'radius/delegating_open_struct' +require 'radius/tag_binding' +require 'radius/context' +require 'radius/parse_tag' +require 'radius/ord_string' +require 'radius/parser/scanner' +require 'radius/parser' +require 'radius/utility' diff --git a/vendor/plugins/radius/lib/radius/context.rb b/vendor/plugins/radius/lib/radius/context.rb new file mode 100644 index 00000000..e1ebc688 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/context.rb @@ -0,0 +1,147 @@ +module Radius + # + # A context contains the tag definitions which are available for use in a template. + # See the QUICKSTART for a detailed explaination its + # usage. + # + class Context + # A hash of tag definition blocks that define tags accessible on a Context. + attr_accessor :definitions # :nodoc: + attr_accessor :globals # :nodoc: + + # Creates a new Context object. + def initialize(&block) + @definitions = {} + @tag_binding_stack = [] + @globals = DelegatingOpenStruct.new + with(&block) if block_given? + end + + # Yield an instance of self for tag definitions: + # + # context.with do |c| + # c.define_tag 'test' do + # 'test' + # end + # end + # + def with + yield self + self + end + + # Creates a tag definition on a context. Several options are available to you + # when creating a tag: + # + # +for+:: Specifies an object that the tag is in reference to. This is + # applicable when a block is not passed to the tag, or when the + # +expose+ option is also used. + # + # +expose+:: Specifies that child tags should be set for each of the methods + # contained in this option. May be either a single symbol/string or + # an array of symbols/strings. + # + # +attributes+:: Specifies whether or not attributes should be exposed + # automatically. Useful for ActiveRecord objects. Boolean. Defaults + # to +true+. + # + def define_tag(name, options = {}, &block) + type = Utility.impartial_hash_delete(options, :type).to_s + klass = Utility.constantize('Radius::TagDefinitions::' + Utility.camelize(type) + 'TagFactory') rescue raise(ArgumentError.new("Undefined type `#{type}' in options hash")) + klass.new(self).define_tag(name, options, &block) + end + + # Returns the value of a rendered tag. Used internally by Parser#parse. + def render_tag(name, attributes = {}, &block) + if name =~ /^(.+?):(.+)$/ + render_tag($1) { render_tag($2, attributes, &block) } + else + tag_definition_block = @definitions[qualified_tag_name(name.to_s)] + if tag_definition_block + stack(name, attributes, block) do |tag| + tag_definition_block.call(tag).to_s + end + else + tag_missing(name, attributes, &block) + end + end + end + + # Like method_missing for objects, but fired when a tag is undefined. + # Override in your own Context to change what happens when a tag is + # undefined. By default this method raises an UndefinedTagError. + def tag_missing(name, attributes, &block) + raise UndefinedTagError.new(name) + end + + # Returns the state of the current render stack. Useful from inside + # a tag definition. Normally just use TagBinding#nesting. + def current_nesting + @tag_binding_stack.collect { |tag| tag.name }.join(':') + end + + # make a usable copy of this context + def dup # :nodoc: + rv = self.class.new + rv.globals = globals.dup + rv.definitions = definitions.dup + rv + end + + private + + # A convienence method for managing the various parts of the + # tag binding stack. + def stack(name, attributes, block) + previous = @tag_binding_stack.last + previous_locals = previous.nil? ? globals : previous.locals + locals = DelegatingOpenStruct.new(previous_locals) + binding = TagBinding.new(self, locals, name, attributes, block) + @tag_binding_stack.push(binding) + result = yield(binding) + @tag_binding_stack.pop + result + end + + # Returns a fully qualified tag name based on state of the + # tag binding stack. + def qualified_tag_name(name) + nesting_parts = @tag_binding_stack.collect { |tag| tag.name } + nesting_parts << name unless nesting_parts.last == name + specific_name = nesting_parts.join(':') # specific_name always has the highest specificity + unless @definitions.has_key? specific_name + possible_matches = @definitions.keys.grep(/(^|:)#{name}$/) + specificity = possible_matches.inject({}) { |hash, tag| hash[numeric_specificity(tag, nesting_parts)] = tag; hash } + max = specificity.keys.max + if max != 0 + specificity[max] + else + name + end + else + specific_name + end + end + + # Returns the specificity for +tag_name+ at nesting defined + # by +nesting_parts+ as a number. + def numeric_specificity(tag_name, nesting_parts) + nesting_parts = nesting_parts.dup + name_parts = tag_name.split(':') + specificity = 0 + value = 1 + if nesting_parts.last == name_parts.last + while nesting_parts.size > 0 + if nesting_parts.last == name_parts.last + specificity += value + name_parts.pop + end + nesting_parts.pop + value *= 0.1 + end + specificity = 0 if (name_parts.size > 0) + end + specificity + end + end +end diff --git a/vendor/plugins/radius/lib/radius/delegating_open_struct.rb b/vendor/plugins/radius/lib/radius/delegating_open_struct.rb new file mode 100644 index 00000000..1a95bee8 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/delegating_open_struct.rb @@ -0,0 +1,37 @@ +module Radius + class DelegatingOpenStruct # :nodoc: + attr_accessor :object + + def initialize(object = nil) + @object = object + @hash = {} + end + + def dup + rv = self.class.new + rv.instance_variable_set(:@hash, @hash.dup) + rv + end + + def method_missing(method, *args, &block) + symbol = (method.to_s =~ /^(.*?)=$/) ? $1.intern : method + if (0..1).include?(args.size) + if args.size == 1 + @hash[symbol] = args.first + else + if @hash.has_key?(symbol) + @hash[symbol] + else + unless object.nil? + @object.send(method, *args, &block) + else + nil + end + end + end + else + super + end + end + end +end diff --git a/vendor/plugins/radius/lib/radius/error.rb b/vendor/plugins/radius/lib/radius/error.rb new file mode 100644 index 00000000..a7725f1d --- /dev/null +++ b/vendor/plugins/radius/lib/radius/error.rb @@ -0,0 +1,43 @@ +module Radius + # Abstract base class for all parsing errors. + class ParseError < StandardError + end + + # Occurs when the Parser expects an end tag for one tag and finds the end tag for another. + class WrongEndTagError < ParseError + def initialize(expected_tag, got_tag, stack) + stack_message = " with stack #{stack.inspect}" if stack + super("wrong end tag `#{got_tag}' found for start tag `#{expected_tag}'#{stack_message}") + end + end + + # Occurs when Parser cannot find an end tag for a given tag in a template or when + # tags are miss-matched in a template. + class MissingEndTagError < ParseError + # Create a new MissingEndTagError object for +tag_name+. + def initialize(tag_name, stack) + stack_message = " with stack #{stack.inspect}" if stack + super("end tag not found for start tag `#{tag_name}'#{stack_message}") + end + end + + # Occurs when Context#render_tag cannot find the specified tag on a Context. + class UndefinedTagError < ParseError + # Create a new UndefinedTagError object for +tag_name+. + def initialize(tag_name) + super("undefined tag `#{tag_name}'") + end + end + + class TastelessTagError < ParseError #:nodoc: + def initialize(tag, stack) + super("internal error with tasteless tag #{tag.inspect} and stack #{stack.inspect}") + end + end + + class UndefinedFlavorError < ParseError #:nodoc: + def initialize(tag, stack) + super("internal error with unknown flavored tag #{tag.inspect} and stack #{stack.inspect}") + end + end +end \ No newline at end of file diff --git a/vendor/plugins/radius/lib/radius/ord_string.rb b/vendor/plugins/radius/lib/radius/ord_string.rb new file mode 100644 index 00000000..f97093a5 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/ord_string.rb @@ -0,0 +1,13 @@ +module Radius + class OrdString < String + if RUBY_VERSION[0,3] == '1.9' + def [](*args) + if args.size == 1 && args.first.is_a?(Integer) + slice(args.first).ord + else + super + end + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/radius/lib/radius/parse_tag.rb b/vendor/plugins/radius/lib/radius/parse_tag.rb new file mode 100644 index 00000000..f21103a6 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parse_tag.rb @@ -0,0 +1,24 @@ +module Radius + class ParseTag # :nodoc: + def initialize(&b) + @block = b + end + + def on_parse(&b) + @block = b + end + + def to_s + @block.call(self) + end + end + + class ParseContainerTag < ParseTag # :nodoc: + attr_accessor :name, :attributes, :contents + + def initialize(name = "", attributes = {}, contents = [], &b) + @name, @attributes, @contents = name, attributes, contents + super(&b) + end + end +end \ No newline at end of file diff --git a/vendor/plugins/radius/lib/radius/parser.rb b/vendor/plugins/radius/lib/radius/parser.rb new file mode 100644 index 00000000..42609434 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser.rb @@ -0,0 +1,79 @@ +module Radius + # + # The Radius parser. Initialize a parser with a Context object that + # defines how tags should be expanded. See the QUICKSTART[link:files/QUICKSTART.html] + # for a detailed explaination of its usage. + # + class Parser + # The Context object used to expand template tags. + attr_accessor :context + + # The string that prefixes all tags that are expanded by a parser + # (the part in the tag name before the first colon). + attr_accessor :tag_prefix + + # The class that performs tokenization of the input string + attr_accessor :scanner + + # Creates a new parser object initialized with a Context. + def initialize(context = Context.new, options = {}) + if context.kind_of?(Hash) and options.empty? + options, context = context, (context[:context] || context['context']) + end + options = Utility.symbolize_keys(options) + self.context = context ? context.dup : Context.new + self.tag_prefix = options[:tag_prefix] || 'radius' + self.scanner = options[:scanner] || default_scanner + end + + # Parses string for tags, expands them, and returns the result. + def parse(string) + @stack = [ ParseContainerTag.new { |t| Utility.array_to_s(t.contents) } ] + tokenize(string) + stack_up + @stack.last.to_s + end + + protected + # Convert the string into a list of text blocks and scanners (tokens) + def tokenize(string) + @tokens = scanner.operate(tag_prefix, string) + end + + def stack_up + @tokens.each do |t| + if t.is_a? String + @stack.last.contents << t + next + end + case t[:flavor] + when :open + @stack.push(ParseContainerTag.new(t[:name], t[:attrs])) + when :self + @stack.last.contents << ParseTag.new {@context.render_tag(t[:name], t[:attrs])} + when :close + popped = @stack.pop + raise WrongEndTagError.new(popped.name, t[:name], @stack) if popped.name != t[:name] + popped.on_parse { |b| @context.render_tag(popped.name, popped.attributes) { Utility.array_to_s(b.contents) } } + @stack.last.contents << popped + when :tasteless + raise TastelessTagError.new(t, @stack) + else + raise UndefinedFlavorError.new(t, @stack) + end + end + raise MissingEndTagError.new(@stack.last.name, @stack) if @stack.length != 1 + end + + def default_scanner + if RUBY_PLATFORM == 'java' + require 'java' + require 'radius/parser/java_scanner.jar' + ::Radius.send(:include_package, 'radius.parser') + Radius::JavaScanner.new(JRuby.runtime) + else + Radius::Scanner.new + end + end + end +end diff --git a/vendor/plugins/radius/lib/radius/parser/JavaScanner$Flavor.class b/vendor/plugins/radius/lib/radius/parser/JavaScanner$Flavor.class new file mode 100644 index 00000000..12e0a78f Binary files /dev/null and b/vendor/plugins/radius/lib/radius/parser/JavaScanner$Flavor.class differ diff --git a/vendor/plugins/radius/lib/radius/parser/JavaScanner$Tag.class b/vendor/plugins/radius/lib/radius/parser/JavaScanner$Tag.class new file mode 100644 index 00000000..2059ee60 Binary files /dev/null and b/vendor/plugins/radius/lib/radius/parser/JavaScanner$Tag.class differ diff --git a/vendor/plugins/radius/lib/radius/parser/JavaScanner.class b/vendor/plugins/radius/lib/radius/parser/JavaScanner.class new file mode 100644 index 00000000..e16e7b7c Binary files /dev/null and b/vendor/plugins/radius/lib/radius/parser/JavaScanner.class differ diff --git a/vendor/plugins/radius/lib/radius/parser/JavaScanner.java b/vendor/plugins/radius/lib/radius/parser/JavaScanner.java new file mode 100644 index 00000000..b45cb731 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser/JavaScanner.java @@ -0,0 +1,634 @@ + +// line 1 "JavaScanner.rl" + +// line 84 "JavaScanner.rl" + + +package radius.parser; + +import java.util.HashMap; +import java.util.LinkedList; +import org.jruby.Ruby; // runtime +import org.jruby.RubyObject; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.RubyArray; +import org.jruby.RubyString; +import org.jruby.RubyHash; +import org.jruby.RubySymbol; + +public class JavaScanner { + + Ruby runtime = null; + RubyArray rv = null; + + void pass_through(String str) { + RubyObject last = ((RubyObject)rv.last()); + if ( rv.size() > 0 && last != null && (last instanceof RubyString) ){ + // XXX concat changes for ruby 1.9 + ((RubyString) last).concat(RubyString.newString(runtime, str)); + } else { + rv.append(RubyString.newString(runtime, str)); + } + } + + void tag(String prefix, String name, RubyHash attr, RubySymbol flavor) { + RubyHash tag = RubyHash.newHash(runtime); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "prefix"), + RubyString.newString(runtime, prefix) + ); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "name"), + RubyString.newString(runtime, name) + ); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "attrs"), + attr + ); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "flavor"), + flavor + ); + rv.append(tag); + } + + public JavaScanner(Ruby runtime) { + this.runtime = runtime; + } + + +// line 65 "JavaScanner.java" +private static byte[] init__parser_actions_0() +{ + return new byte [] { + 0, 1, 0, 1, 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8, 1, 9, 1, 10, 1, 14, 1, 15, 1, + 19, 1, 21, 1, 22, 1, 23, 2, 1, 2, 2, 5, + 6, 2, 6, 7, 2, 9, 5, 2, 9, 10, 2, 10, + 9, 2, 11, 20, 2, 12, 20, 2, 13, 20, 2, 16, + 17, 2, 16, 18, 3, 5, 6, 7, 3, 9, 5, 6, + 3, 16, 6, 17, 4, 9, 5, 6, 7, 4, 16, 5, + 6, 17, 5, 16, 9, 5, 6, 17 + }; +} + +private static final byte _parser_actions[] = init__parser_actions_0(); + + +private static short[] init__parser_key_offsets_0() +{ + return new short [] { + 0, 0, 11, 21, 34, 47, 61, 65, 70, 72, 74, 87, + 100, 101, 103, 118, 133, 149, 155, 161, 176, 179, 182, 185, + 200, 202, 204, 219, 235, 241, 247, 250, 253, 269, 285, 302, + 309, 315, 331, 335, 351, 366, 369, 371, 381, 392, 402, 416, + 420, 420, 421, 430, 430, 430, 432, 434, 437, 440, 442, 444 + }; +} + +private static final short _parser_key_offsets[] = init__parser_key_offsets_0(); + + +private static char[] init__parser_trans_keys_0() +{ + return new char [] { + 58, 63, 95, 45, 46, 48, 57, 65, 90, 97, 122, 63, + 95, 45, 46, 48, 58, 65, 90, 97, 122, 32, 47, 62, + 63, 95, 9, 13, 45, 58, 65, 90, 97, 122, 32, 47, + 62, 63, 95, 9, 13, 45, 58, 65, 90, 97, 122, 32, + 61, 63, 95, 9, 13, 45, 46, 48, 58, 65, 90, 97, + 122, 32, 61, 9, 13, 32, 34, 39, 9, 13, 34, 92, + 34, 92, 32, 47, 62, 63, 95, 9, 13, 45, 58, 65, + 90, 97, 122, 32, 47, 62, 63, 95, 9, 13, 45, 58, + 65, 90, 97, 122, 62, 34, 92, 32, 34, 47, 62, 63, + 92, 95, 9, 13, 45, 58, 65, 90, 97, 122, 32, 34, + 47, 62, 63, 92, 95, 9, 13, 45, 58, 65, 90, 97, + 122, 32, 34, 61, 63, 92, 95, 9, 13, 45, 46, 48, + 58, 65, 90, 97, 122, 32, 34, 61, 92, 9, 13, 32, + 34, 39, 92, 9, 13, 32, 34, 47, 62, 63, 92, 95, + 9, 13, 45, 58, 65, 90, 97, 122, 34, 62, 92, 34, + 39, 92, 34, 39, 92, 32, 39, 47, 62, 63, 92, 95, + 9, 13, 45, 58, 65, 90, 97, 122, 39, 92, 39, 92, + 32, 39, 47, 62, 63, 92, 95, 9, 13, 45, 58, 65, + 90, 97, 122, 32, 39, 61, 63, 92, 95, 9, 13, 45, + 46, 48, 58, 65, 90, 97, 122, 32, 39, 61, 92, 9, + 13, 32, 34, 39, 92, 9, 13, 34, 39, 92, 34, 39, + 92, 32, 34, 39, 47, 62, 63, 92, 95, 9, 13, 45, + 58, 65, 90, 97, 122, 32, 34, 39, 47, 62, 63, 92, + 95, 9, 13, 45, 58, 65, 90, 97, 122, 32, 34, 39, + 61, 63, 92, 95, 9, 13, 45, 46, 48, 58, 65, 90, + 97, 122, 32, 34, 39, 61, 92, 9, 13, 32, 34, 39, + 92, 9, 13, 32, 34, 39, 47, 62, 63, 92, 95, 9, + 13, 45, 58, 65, 90, 97, 122, 34, 39, 62, 92, 32, + 34, 39, 47, 62, 63, 92, 95, 9, 13, 45, 58, 65, + 90, 97, 122, 32, 39, 47, 62, 63, 92, 95, 9, 13, + 45, 58, 65, 90, 97, 122, 39, 62, 92, 39, 92, 63, + 95, 45, 46, 48, 57, 65, 90, 97, 122, 58, 63, 95, + 45, 46, 48, 57, 65, 90, 97, 122, 63, 95, 45, 46, + 48, 58, 65, 90, 97, 122, 32, 62, 63, 95, 9, 13, + 45, 46, 48, 58, 65, 90, 97, 122, 32, 62, 9, 13, + 60, 47, 63, 95, 45, 57, 65, 90, 97, 122, 34, 92, + 34, 92, 34, 39, 92, 34, 39, 92, 39, 92, 39, 92, + 0 + }; +} + +private static final char _parser_trans_keys[] = init__parser_trans_keys_0(); + + +private static byte[] init__parser_single_lengths_0() +{ + return new byte [] { + 0, 3, 2, 5, 5, 4, 2, 3, 2, 2, 5, 5, + 1, 2, 7, 7, 6, 4, 4, 7, 3, 3, 3, 7, + 2, 2, 7, 6, 4, 4, 3, 3, 8, 8, 7, 5, + 4, 8, 4, 8, 7, 3, 2, 2, 3, 2, 4, 2, + 0, 1, 3, 0, 0, 2, 2, 3, 3, 2, 2, 0 + }; +} + +private static final byte _parser_single_lengths[] = init__parser_single_lengths_0(); + + +private static byte[] init__parser_range_lengths_0() +{ + return new byte [] { + 0, 4, 4, 4, 4, 5, 1, 1, 0, 0, 4, 4, + 0, 0, 4, 4, 5, 1, 1, 4, 0, 0, 0, 4, + 0, 0, 4, 5, 1, 1, 0, 0, 4, 4, 5, 1, + 1, 4, 0, 4, 4, 0, 0, 4, 4, 4, 5, 1, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +} + +private static final byte _parser_range_lengths[] = init__parser_range_lengths_0(); + + +private static short[] init__parser_index_offsets_0() +{ + return new short [] { + 0, 0, 8, 15, 25, 35, 45, 49, 54, 57, 60, 70, + 80, 82, 85, 97, 109, 121, 127, 133, 145, 149, 153, 157, + 169, 172, 175, 187, 199, 205, 211, 215, 219, 232, 245, 258, + 265, 271, 284, 289, 302, 314, 318, 321, 328, 336, 343, 353, + 357, 358, 360, 367, 368, 369, 372, 375, 379, 383, 386, 389 + }; +} + +private static final short _parser_index_offsets[] = init__parser_index_offsets_0(); + + +private static byte[] init__parser_indicies_0() +{ + return new byte [] { + 2, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, + 3, 3, 0, 4, 6, 7, 5, 5, 4, 5, 5, 5, + 0, 8, 10, 11, 9, 9, 8, 9, 9, 9, 0, 13, + 15, 14, 14, 13, 14, 14, 14, 14, 12, 16, 17, 16, + 12, 17, 18, 19, 17, 12, 21, 22, 20, 24, 25, 23, + 26, 28, 29, 27, 27, 26, 27, 27, 27, 12, 30, 32, + 33, 31, 31, 30, 31, 31, 31, 12, 34, 12, 35, 25, + 23, 36, 24, 38, 39, 37, 25, 37, 36, 37, 37, 37, + 23, 40, 24, 42, 43, 41, 25, 41, 40, 41, 41, 41, + 23, 44, 24, 46, 45, 25, 45, 44, 45, 45, 45, 45, + 23, 47, 24, 48, 25, 47, 23, 48, 49, 50, 25, 48, + 23, 51, 21, 53, 54, 52, 22, 52, 51, 52, 52, 52, + 20, 24, 55, 25, 23, 57, 58, 59, 56, 61, 35, 62, + 60, 64, 24, 66, 67, 65, 68, 65, 64, 65, 65, 65, + 63, 24, 68, 63, 61, 68, 63, 69, 24, 71, 72, 70, + 68, 70, 69, 70, 70, 70, 63, 73, 24, 75, 74, 68, + 74, 73, 74, 74, 74, 74, 63, 76, 24, 77, 68, 76, + 63, 77, 78, 79, 68, 77, 63, 80, 58, 59, 56, 81, + 81, 62, 60, 82, 61, 35, 84, 85, 83, 62, 83, 82, + 83, 83, 83, 60, 86, 61, 35, 88, 89, 87, 62, 87, + 86, 87, 87, 87, 60, 90, 61, 35, 92, 91, 62, 91, + 90, 91, 91, 91, 91, 60, 93, 61, 35, 94, 62, 93, + 60, 94, 95, 96, 62, 94, 60, 97, 80, 58, 99, 100, + 98, 59, 98, 97, 98, 98, 98, 56, 61, 35, 101, 62, + 60, 97, 57, 58, 99, 100, 98, 59, 98, 97, 98, 98, + 98, 56, 103, 21, 105, 106, 104, 107, 104, 103, 104, 104, + 104, 102, 24, 108, 68, 63, 21, 107, 102, 109, 109, 109, + 109, 109, 109, 0, 111, 110, 110, 110, 110, 110, 110, 0, + 112, 112, 112, 112, 112, 112, 0, 113, 115, 114, 114, 113, + 114, 114, 114, 114, 0, 116, 117, 116, 0, 118, 120, 119, + 123, 122, 122, 122, 122, 122, 121, 124, 125, 24, 25, 23, + 24, 25, 23, 61, 35, 62, 60, 61, 35, 62, 60, 24, + 68, 63, 24, 68, 63, 126, 0 + }; +} + +private static final byte _parser_indicies[] = init__parser_indicies_0(); + + +private static byte[] init__parser_trans_targs_0() +{ + return new byte [] { + 49, 1, 2, 3, 4, 3, 12, 52, 4, 5, 12, 52, + 49, 6, 5, 7, 6, 7, 8, 42, 9, 10, 13, 9, + 10, 13, 11, 5, 12, 52, 11, 5, 12, 52, 51, 14, + 15, 16, 20, 54, 15, 16, 20, 54, 17, 16, 18, 17, + 18, 19, 21, 15, 16, 20, 54, 53, 22, 23, 14, 31, + 22, 23, 31, 24, 26, 27, 41, 58, 25, 26, 27, 41, + 58, 28, 27, 29, 28, 29, 30, 40, 23, 32, 33, 34, + 38, 56, 33, 34, 38, 56, 35, 34, 36, 35, 36, 37, + 39, 33, 34, 38, 56, 55, 24, 26, 27, 41, 58, 25, + 57, 44, 44, 45, 46, 47, 46, 59, 47, 59, 0, 49, + 50, 49, 1, 43, 49, 49, 49 + }; +} + +private static final byte _parser_trans_targs[] = init__parser_trans_targs_0(); + + +private static byte[] init__parser_trans_actions_0() +{ + return new byte [] { + 27, 0, 31, 3, 5, 0, 5, 5, 0, 11, 0, 0, + 29, 13, 0, 13, 0, 0, 0, 0, 15, 43, 15, 0, + 17, 0, 7, 64, 34, 34, 0, 37, 9, 9, 0, 17, + 7, 64, 34, 81, 0, 37, 9, 72, 13, 0, 13, 0, + 0, 17, 0, 40, 76, 68, 86, 58, 15, 46, 43, 15, + 0, 17, 0, 0, 7, 64, 34, 81, 0, 0, 37, 9, + 72, 13, 0, 13, 0, 0, 0, 17, 43, 17, 7, 64, + 34, 81, 0, 37, 9, 72, 13, 0, 13, 0, 0, 17, + 17, 40, 76, 68, 86, 58, 15, 40, 76, 68, 86, 15, + 58, 1, 0, 31, 3, 5, 0, 5, 0, 0, 0, 23, + 61, 25, 1, 0, 52, 49, 55 + }; +} + +private static final byte _parser_trans_actions[] = init__parser_trans_actions_0(); + + +private static byte[] init__parser_to_state_actions_0() +{ + return new byte [] { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +} + +private static final byte _parser_to_state_actions[] = init__parser_to_state_actions_0(); + + +private static byte[] init__parser_from_state_actions_0() +{ + return new byte [] { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; +} + +private static final byte _parser_from_state_actions[] = init__parser_from_state_actions_0(); + + +private static short[] init__parser_eof_trans_0() +{ + return new short [] { + 0, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, + 0, 0, 122, 125, 126, 125, 126, 125, 126, 125, 126, 127 + }; +} + +private static final short _parser_eof_trans[] = init__parser_eof_trans_0(); + + +static final int parser_start = 49; +static final int parser_first_final = 49; +static final int parser_error = 0; + +static final int parser_en_Closeout = 48; +static final int parser_en_main = 49; + + +// line 143 "JavaScanner.rl" + + public RubyArray operate(String tag_prefix, String input) { + char[] data = input.toCharArray(); + String disposable_string; + + String name = ""; + String prefix = ""; + RubySymbol flavor = RubySymbol.newSymbol(runtime, "tasteless".intern()); + RubyHash attributes = RubyHash.newHash(runtime); + + int tagstart = 0; + int mark_pfx = 0; + int mark_stg = 0; + int mark_attr = 0; + int mark_nat = 0; + int mark_vat = 0; + + String nat = ""; + String vat = ""; + + int cs; + int p = 0; + int pe = data.length; + int eof = pe; + int act; + int ts; + int te; + + rv = RubyArray.newArray(runtime); + char[] remainder = data; + + +// line 351 "JavaScanner.java" + { + cs = parser_start; + ts = -1; + te = -1; + act = 0; + } + +// line 175 "JavaScanner.rl" + +// line 361 "JavaScanner.java" + { + int _klen; + int _trans = 0; + int _acts; + int _nacts; + int _keys; + int _goto_targ = 0; + + _goto: while (true) { + switch ( _goto_targ ) { + case 0: + if ( p == pe ) { + _goto_targ = 4; + continue _goto; + } + if ( cs == 0 ) { + _goto_targ = 5; + continue _goto; + } +case 1: + _acts = _parser_from_state_actions[cs]; + _nacts = (int) _parser_actions[_acts++]; + while ( _nacts-- > 0 ) { + switch ( _parser_actions[_acts++] ) { + case 15: +// line 1 "NONE" + {ts = p;} + break; +// line 390 "JavaScanner.java" + } + } + + _match: do { + _keys = _parser_key_offsets[cs]; + _trans = _parser_index_offsets[cs]; + _klen = _parser_single_lengths[cs]; + if ( _klen > 0 ) { + int _lower = _keys; + int _mid; + int _upper = _keys + _klen - 1; + while (true) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( data[p] < _parser_trans_keys[_mid] ) + _upper = _mid - 1; + else if ( data[p] > _parser_trans_keys[_mid] ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + break _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _parser_range_lengths[cs]; + if ( _klen > 0 ) { + int _lower = _keys; + int _mid; + int _upper = _keys + (_klen<<1) - 2; + while (true) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( data[p] < _parser_trans_keys[_mid] ) + _upper = _mid - 2; + else if ( data[p] > _parser_trans_keys[_mid+1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + break _match; + } + } + _trans += _klen; + } + } while (false); + + _trans = _parser_indicies[_trans]; +case 3: + cs = _parser_trans_targs[_trans]; + + if ( _parser_trans_actions[_trans] != 0 ) { + _acts = _parser_trans_actions[_trans]; + _nacts = (int) _parser_actions[_acts++]; + while ( _nacts-- > 0 ) + { + switch ( _parser_actions[_acts++] ) + { + case 0: +// line 4 "JavaScanner.rl" + { mark_pfx = p; } + break; + case 1: +// line 5 "JavaScanner.rl" + { + prefix = input.substring(mark_pfx, p); + } + break; + case 2: +// line 8 "JavaScanner.rl" + { + if ( !prefix.equals(tag_prefix) ) { + // have to manually add ':' / Sep + // pass the text through & reset state + pass_through(input.substring(tagstart, p) + ":"); + prefix = ""; + {cs = 49; _goto_targ = 2; if (true) continue _goto;} + } + } + break; + case 3: +// line 18 "JavaScanner.rl" + { mark_stg = p; } + break; + case 4: +// line 19 "JavaScanner.rl" + { name = input.substring(mark_stg, p); } + break; + case 5: +// line 20 "JavaScanner.rl" + { mark_attr = p; } + break; + case 6: +// line 21 "JavaScanner.rl" + { + attributes.op_aset( + runtime.getCurrentContext(), + RubyString.newString(runtime, nat), + RubyString.newString(runtime, vat) + ); + } + break; + case 7: +// line 29 "JavaScanner.rl" + { mark_nat = p; } + break; + case 8: +// line 30 "JavaScanner.rl" + { nat = input.substring(mark_nat, p); } + break; + case 9: +// line 31 "JavaScanner.rl" + { mark_vat = p; } + break; + case 10: +// line 32 "JavaScanner.rl" + { vat = input.substring(mark_vat, p); } + break; + case 11: +// line 34 "JavaScanner.rl" + { flavor = RubySymbol.newSymbol(runtime, "open".intern()); } + break; + case 12: +// line 35 "JavaScanner.rl" + { flavor = RubySymbol.newSymbol(runtime, "self".intern()); } + break; + case 13: +// line 36 "JavaScanner.rl" + { flavor = RubySymbol.newSymbol(runtime, "close".intern()); } + break; + case 16: +// line 1 "NONE" + {te = p+1;} + break; + case 17: +// line 72 "JavaScanner.rl" + {act = 1;} + break; + case 18: +// line 79 "JavaScanner.rl" + {act = 2;} + break; + case 19: +// line 79 "JavaScanner.rl" + {te = p+1;{ + pass_through(input.substring(p, p + 1)); + tagstart = p + 1; + }} + break; + case 20: +// line 72 "JavaScanner.rl" + {te = p;p--;{ + tag(prefix, name, attributes, flavor); + prefix = ""; + name = ""; + attributes = RubyHash.newHash(runtime); + flavor = RubySymbol.newSymbol(runtime, "tasteless".intern()); + }} + break; + case 21: +// line 79 "JavaScanner.rl" + {te = p;p--;{ + pass_through(input.substring(p, p + 1)); + tagstart = p + 1; + }} + break; + case 22: +// line 79 "JavaScanner.rl" + {{p = ((te))-1;}{ + pass_through(input.substring(p, p + 1)); + tagstart = p + 1; + }} + break; + case 23: +// line 1 "NONE" + { switch( act ) { + case 1: + {{p = ((te))-1;} + tag(prefix, name, attributes, flavor); + prefix = ""; + name = ""; + attributes = RubyHash.newHash(runtime); + flavor = RubySymbol.newSymbol(runtime, "tasteless".intern()); + } + break; + case 2: + {{p = ((te))-1;} + pass_through(input.substring(p, p + 1)); + tagstart = p + 1; + } + break; + } + } + break; +// line 590 "JavaScanner.java" + } + } + } + +case 2: + _acts = _parser_to_state_actions[cs]; + _nacts = (int) _parser_actions[_acts++]; + while ( _nacts-- > 0 ) { + switch ( _parser_actions[_acts++] ) { + case 14: +// line 1 "NONE" + {ts = -1;} + break; +// line 604 "JavaScanner.java" + } + } + + if ( cs == 0 ) { + _goto_targ = 5; + continue _goto; + } + if ( ++p != pe ) { + _goto_targ = 1; + continue _goto; + } +case 4: + if ( p == eof ) + { + if ( _parser_eof_trans[cs] > 0 ) { + _trans = _parser_eof_trans[cs] - 1; + _goto_targ = 3; + continue _goto; + } + } + +case 5: + } + break; } + } + +// line 176 "JavaScanner.rl" + + return rv; + } +} diff --git a/vendor/plugins/radius/lib/radius/parser/JavaScanner.rl b/vendor/plugins/radius/lib/radius/parser/JavaScanner.rl new file mode 100644 index 00000000..b53601a1 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser/JavaScanner.rl @@ -0,0 +1,179 @@ +%%{ + machine parser; + + action _prefix { mark_pfx = p; } + action prefix { + prefix = input.substring(mark_pfx, p); + } + action _check_prefix { + if ( !prefix.equals(tag_prefix) ) { + // have to manually add ':' / Sep + // pass the text through & reset state + pass_through(input.substring(tagstart, p) + ":"); + prefix = ""; + fgoto main; + } + } + + action _starttag { mark_stg = p; } + action starttag { name = input.substring(mark_stg, p); } + action _attr { mark_attr = p; } + action attr { + attributes.op_aset( + runtime.getCurrentContext(), + RubyString.newString(runtime, nat), + RubyString.newString(runtime, vat) + ); + } + + action _nameattr { mark_nat = p; } + action nameattr { nat = input.substring(mark_nat, p); } + action _valattr { mark_vat = p; } + action valattr { vat = input.substring(mark_vat, p); } + + action opentag { flavor = RubySymbol.newSymbol(runtime, "open".intern()); } + action selftag { flavor = RubySymbol.newSymbol(runtime, "self".intern()); } + action closetag { flavor = RubySymbol.newSymbol(runtime, "close".intern()); } + + Closeout := empty; + + # words + PrefixChar = [\-A-Za-z0-9._?] ; + NameChar = [\-A-Za-z0-9._:?] ; + TagName = NameChar+ >_starttag %starttag; + Prefix = PrefixChar+ >_prefix %prefix; + Open = "<"; + Sep = ":" >_check_prefix; + End = "/"; + Close = ">"; + + Name = Prefix Sep TagName; + + NameAttr = NameChar+ >_nameattr %nameattr; + Q1Char = ( "\\\'" | [^'] ) ; + Q1Attr = Q1Char* >_valattr %valattr; + Q2Char = ( "\\\"" | [^"] ) ; + Q2Attr = Q2Char* >_valattr %valattr; + + Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr; + Attrs = (space+ Attr* | empty); + + CloseTrailer = End Close %selftag; + OpenTrailer = Close %opentag; + + Trailer = (OpenTrailer | CloseTrailer); + + OpenOrSelfTag = Name Attrs? Trailer; + CloseTag = End Name space* Close %closetag; + + SomeTag = Open (OpenOrSelfTag | CloseTag); + + main := |* + SomeTag => { + tag(prefix, name, attributes, flavor); + prefix = ""; + name = ""; + attributes = RubyHash.newHash(runtime); + flavor = RubySymbol.newSymbol(runtime, "tasteless".intern()); + }; + any => { + pass_through(input.substring(p, p + 1)); + tagstart = p + 1; + }; + *|; +}%% + +package radius.parser; + +import java.util.HashMap; +import java.util.LinkedList; +import org.jruby.Ruby; // runtime +import org.jruby.RubyObject; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.RubyArray; +import org.jruby.RubyString; +import org.jruby.RubyHash; +import org.jruby.RubySymbol; + +public class JavaScanner { + + Ruby runtime = null; + RubyArray rv = null; + + void pass_through(String str) { + RubyObject last = ((RubyObject)rv.last()); + if ( rv.size() > 0 && last != null && (last instanceof RubyString) ){ + // XXX concat changes for ruby 1.9 + ((RubyString) last).concat(RubyString.newString(runtime, str)); + } else { + rv.append(RubyString.newString(runtime, str)); + } + } + + void tag(String prefix, String name, RubyHash attr, RubySymbol flavor) { + RubyHash tag = RubyHash.newHash(runtime); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "prefix"), + RubyString.newString(runtime, prefix) + ); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "name"), + RubyString.newString(runtime, name) + ); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "attrs"), + attr + ); + tag.op_aset( + runtime.getCurrentContext(), + RubySymbol.newSymbol(runtime, "flavor"), + flavor + ); + rv.append(tag); + } + + public JavaScanner(Ruby runtime) { + this.runtime = runtime; + } + + %% write data; + + public RubyArray operate(String tag_prefix, String input) { + char[] data = input.toCharArray(); + String disposable_string; + + String name = ""; + String prefix = ""; + RubySymbol flavor = RubySymbol.newSymbol(runtime, "tasteless".intern()); + RubyHash attributes = RubyHash.newHash(runtime); + + int tagstart = 0; + int mark_pfx = 0; + int mark_stg = 0; + int mark_attr = 0; + int mark_nat = 0; + int mark_vat = 0; + + String nat = ""; + String vat = ""; + + int cs; + int p = 0; + int pe = data.length; + int eof = pe; + int act; + int ts; + int te; + + rv = RubyArray.newArray(runtime); + char[] remainder = data; + + %% write init; + %% write exec; + + return rv; + } +} diff --git a/vendor/plugins/radius/lib/radius/parser/java_scanner.jar b/vendor/plugins/radius/lib/radius/parser/java_scanner.jar new file mode 100644 index 00000000..f652a9ff Binary files /dev/null and b/vendor/plugins/radius/lib/radius/parser/java_scanner.jar differ diff --git a/vendor/plugins/radius/lib/radius/parser/scanner.rb b/vendor/plugins/radius/lib/radius/parser/scanner.rb new file mode 100644 index 00000000..47bfc2df --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser/scanner.rb @@ -0,0 +1,1254 @@ + +# line 1 "scanner.rl" + +# line 84 "scanner.rl" + + +module Radius + class Scanner + def operate(prefix, data) + data = Radius::OrdString.new data + buf = "" + csel = "" + @prematch = '' + @starttag = nil + @attrs = {} + @flavor = :tasteless + @cursor = 0 + @tagstart = 0 + @nodes = [''] + remainder = data.dup + + until remainder.length == 0 + p = perform_parse(prefix, remainder) + remainder = remainder[p..-1] + end + + return @nodes + end + + private + def perform_parse(prefix, data) + stack = [] + p = 0 + ts = 0 + te = 0 + act = 0 + eof = data.length + + @prefix = prefix + +# line 42 "scanner.rb" +class << self + attr_accessor :_parser_trans_keys + private :_parser_trans_keys, :_parser_trans_keys= +end +self._parser_trans_keys = [ + 0, 0, 45, 122, 45, 122, + 9, 122, 9, 122, 9, + 122, 9, 61, 9, 39, + 34, 92, 34, 92, 9, 122, + 9, 122, 62, 62, 34, + 92, 9, 122, 9, 122, + 9, 122, 9, 92, 9, 92, + 9, 122, 34, 92, 34, + 92, 34, 92, 9, 122, + 39, 92, 39, 92, 9, 122, + 9, 122, 9, 92, 9, + 92, 34, 92, 34, 92, + 9, 122, 9, 122, 9, 122, + 9, 92, 9, 92, 9, + 122, 34, 92, 9, 122, + 9, 122, 39, 92, 39, 92, + 45, 122, 45, 122, 45, + 122, 9, 122, 9, 62, + 0, 0, 60, 60, 45, 122, + 0, 0, 0, 0, 34, + 92, 34, 92, 34, 92, + 34, 92, 39, 92, 39, 92, + 0, 0, 0 +] + +class << self + attr_accessor :_parser_key_spans + private :_parser_key_spans, :_parser_key_spans= +end +self._parser_key_spans = [ + 0, 78, 78, 114, 114, 114, 53, 31, + 59, 59, 114, 114, 1, 59, 114, 114, + 114, 84, 84, 114, 59, 59, 59, 114, + 54, 54, 114, 114, 84, 84, 59, 59, + 114, 114, 114, 84, 84, 114, 59, 114, + 114, 54, 54, 78, 78, 78, 114, 54, + 0, 1, 78, 0, 0, 59, 59, 59, + 59, 54, 54, 0 +] + +class << self + attr_accessor :_parser_index_offsets + private :_parser_index_offsets, :_parser_index_offsets= +end +self._parser_index_offsets = [ + 0, 0, 79, 158, 273, 388, 503, 557, + 589, 649, 709, 824, 939, 941, 1001, 1116, + 1231, 1346, 1431, 1516, 1631, 1691, 1751, 1811, + 1926, 1981, 2036, 2151, 2266, 2351, 2436, 2496, + 2556, 2671, 2786, 2901, 2986, 3071, 3186, 3246, + 3361, 3476, 3531, 3586, 3665, 3744, 3823, 3938, + 3993, 3994, 3996, 4075, 4076, 4077, 4137, 4197, + 4257, 4317, 4372, 4427 +] + +class << self + attr_accessor :_parser_indicies + private :_parser_indicies, :_parser_indicies= +end +self._parser_indicies = [ + 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 0, 0, + 0, 0, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 3, + 3, 0, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 0, 0, 0, + 0, 3, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 0, 0, 0, + 0, 3, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 0, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 6, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 7, 5, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 5, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 0, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 10, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 11, 9, + 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 9, + 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 13, 13, 13, 13, + 13, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 13, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 14, 14, 12, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 12, 12, + 15, 12, 14, 12, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 12, 12, + 12, 12, 14, 12, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 12, 16, + 16, 16, 16, 16, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 16, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 17, 12, 17, 17, 17, + 17, 17, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 17, 12, 18, 12, + 12, 12, 12, 19, 12, 21, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 22, + 20, 24, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 25, 23, 26, 26, 26, + 26, 26, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 26, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 27, 27, 28, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 12, + 12, 12, 29, 27, 12, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 12, + 12, 12, 12, 27, 12, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 12, + 30, 30, 30, 30, 30, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 30, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 31, 31, 32, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 12, 12, 12, 33, 31, 12, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 12, 12, 12, 12, 31, 12, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 12, 34, 12, 35, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 25, + 23, 36, 36, 36, 36, 36, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 36, 23, 24, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 37, 37, 38, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 23, 23, 23, 39, 37, + 23, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 23, 25, 23, 23, 37, + 23, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 23, 40, 40, 40, 40, + 40, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 40, 23, 24, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 41, 41, 42, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 23, 23, + 23, 43, 41, 23, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 23, 25, + 23, 23, 41, 23, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 23, 44, + 44, 44, 44, 44, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 44, 23, + 24, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 45, 45, 23, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 23, 23, 46, 23, 45, 23, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 23, 25, 23, 23, 45, 23, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 23, 47, 47, 47, 47, 47, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 47, 23, 24, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 48, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 25, 23, 48, + 48, 48, 48, 48, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 48, 23, + 49, 23, 23, 23, 23, 50, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 25, 23, 51, 51, 51, 51, + 51, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 51, 20, 21, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 52, 52, 53, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 20, 20, + 20, 54, 52, 20, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 20, 22, + 20, 20, 52, 20, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 20, 24, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 55, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 25, 23, 57, 56, 56, 56, 56, + 58, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 59, 56, 61, + 60, 60, 60, 60, 35, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 62, 60, 64, 64, 64, 64, 64, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 64, 63, 63, 63, 63, 63, + 63, 24, 63, 63, 63, 63, 63, 65, + 65, 66, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 63, 63, 63, + 67, 65, 63, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 63, 68, 63, + 63, 65, 63, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 63, 24, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 68, 63, 61, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 68, 63, 69, 69, 69, 69, + 69, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 69, 63, 63, 63, 63, + 63, 63, 24, 63, 63, 63, 63, 63, + 70, 70, 71, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 63, 63, + 63, 72, 70, 63, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 63, 68, + 63, 63, 70, 63, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 63, 73, + 73, 73, 73, 73, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 73, 63, + 63, 63, 63, 63, 63, 24, 63, 63, + 63, 63, 63, 74, 74, 63, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 63, 63, 75, 63, 74, 63, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 63, 68, 63, 63, 74, 63, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 63, 76, 76, 76, 76, 76, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 76, 63, 63, 63, 63, 63, 63, + 24, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 77, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 68, 63, 77, + 77, 77, 77, 77, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 77, 63, + 78, 63, 63, 63, 63, 79, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 68, 63, 80, 56, 56, 56, + 56, 58, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 59, 56, + 81, 60, 60, 60, 60, 81, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 62, 60, 82, 82, 82, 82, + 82, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 82, 60, 61, 60, 60, + 60, 60, 35, 60, 60, 60, 60, 60, + 83, 83, 84, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 60, 60, + 60, 85, 83, 60, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 60, 62, + 60, 60, 83, 60, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 60, 86, + 86, 86, 86, 86, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 86, 60, + 61, 60, 60, 60, 60, 35, 60, 60, + 60, 60, 60, 87, 87, 88, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 60, 60, 60, 89, 87, 60, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 60, 62, 60, 60, 87, 60, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 60, 90, 90, 90, 90, 90, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 90, 60, 61, 60, 60, 60, 60, + 35, 60, 60, 60, 60, 60, 91, 91, + 60, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 60, 60, 92, 60, + 91, 60, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 60, 62, 60, 60, + 91, 60, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 60, 93, 93, 93, + 93, 93, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 93, 60, 61, 60, + 60, 60, 60, 35, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 94, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 62, 60, 94, 94, 94, 94, 94, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 94, 60, 95, 60, 60, 60, 60, + 96, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 62, 60, 97, + 97, 97, 97, 97, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 97, 56, + 80, 56, 56, 56, 56, 58, 56, 56, + 56, 56, 56, 98, 98, 99, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 56, 56, 56, 100, 98, 56, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 56, 59, 56, 56, 98, 56, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 56, 61, 60, 60, 60, 60, 35, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 101, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 62, 60, 97, 97, + 97, 97, 97, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 97, 56, 57, + 56, 56, 56, 56, 58, 56, 56, 56, + 56, 56, 98, 98, 99, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 56, 56, 56, 100, 98, 56, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 56, 59, 56, 56, 98, 56, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 56, 103, 103, 103, 103, 103, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 103, 102, 102, 102, 102, 102, 102, 21, + 102, 102, 102, 102, 102, 104, 104, 105, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 102, 102, 102, 106, 104, + 102, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 102, 107, 102, 102, 104, + 102, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 102, 24, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 108, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 68, 63, 21, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 107, 102, 109, 109, 0, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 0, + 0, 0, 0, 0, 109, 0, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 0, 0, 0, 0, 109, 0, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 0, 110, 110, 0, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 111, 0, + 0, 0, 0, 110, 0, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 0, + 0, 0, 0, 110, 0, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 0, + 112, 112, 0, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 0, 0, + 0, 0, 112, 0, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 0, 0, + 0, 0, 112, 0, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 0, 113, + 113, 113, 113, 113, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 113, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 114, 114, 0, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 0, 0, 0, 115, 114, 0, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 0, 0, 0, 0, 114, 0, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 0, 116, 116, 116, 116, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 116, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 117, + 0, 118, 120, 119, 122, 122, 123, 122, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 121, 121, 121, 121, 121, 122, 121, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 121, 121, 121, 121, 122, 121, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 121, 124, 125, 24, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 25, + 23, 24, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 25, 23, 61, 60, 60, + 60, 60, 35, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 62, + 60, 61, 60, 60, 60, 60, 35, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 62, 60, 24, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 68, 63, 24, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 68, 63, 126, 0 +] + +class << self + attr_accessor :_parser_trans_targs + private :_parser_trans_targs, :_parser_trans_targs= +end +self._parser_trans_targs = [ + 49, 1, 2, 3, 4, 3, 12, 52, + 4, 5, 12, 52, 49, 6, 5, 7, + 6, 7, 8, 42, 9, 10, 13, 9, + 10, 13, 11, 5, 12, 52, 11, 5, + 12, 52, 51, 14, 15, 16, 20, 54, + 15, 16, 20, 54, 17, 16, 18, 17, + 18, 19, 21, 15, 16, 20, 54, 53, + 22, 23, 14, 31, 22, 23, 31, 24, + 26, 27, 41, 58, 25, 26, 27, 41, + 58, 28, 27, 29, 28, 29, 30, 40, + 23, 32, 33, 34, 38, 56, 33, 34, + 38, 56, 35, 34, 36, 35, 36, 37, + 39, 33, 34, 38, 56, 55, 24, 26, + 27, 41, 58, 25, 57, 44, 44, 45, + 46, 47, 46, 59, 47, 59, 0, 49, + 50, 49, 1, 43, 49, 49, 49 +] + +class << self + attr_accessor :_parser_trans_actions + private :_parser_trans_actions, :_parser_trans_actions= +end +self._parser_trans_actions = [ + 1, 0, 2, 3, 4, 0, 4, 4, + 0, 5, 0, 0, 6, 7, 0, 7, + 0, 0, 0, 0, 8, 9, 8, 0, + 10, 0, 11, 12, 13, 13, 0, 14, + 15, 15, 0, 10, 11, 12, 13, 16, + 0, 14, 15, 17, 7, 0, 7, 0, + 0, 10, 0, 18, 19, 20, 21, 22, + 8, 23, 9, 8, 0, 10, 0, 0, + 11, 12, 13, 16, 0, 0, 14, 15, + 17, 7, 0, 7, 0, 0, 0, 10, + 9, 10, 11, 12, 13, 16, 0, 14, + 15, 17, 7, 0, 7, 0, 0, 10, + 10, 18, 19, 20, 21, 22, 8, 18, + 19, 20, 21, 8, 22, 24, 0, 2, + 3, 4, 0, 4, 0, 0, 0, 27, + 28, 29, 24, 0, 30, 31, 32 +] + +class << self + attr_accessor :_parser_to_state_actions + private :_parser_to_state_actions, :_parser_to_state_actions= +end +self._parser_to_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 25, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +] + +class << self + attr_accessor :_parser_from_state_actions + private :_parser_from_state_actions, :_parser_from_state_actions= +end +self._parser_from_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +] + +class << self + attr_accessor :_parser_eof_trans + private :_parser_eof_trans, :_parser_eof_trans= +end +self._parser_eof_trans = [ + 0, 1, 1, 1, 1, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 1, 1, 1, 1, 1, + 0, 0, 122, 125, 126, 125, 126, 125, + 126, 125, 126, 127 +] + +class << self + attr_accessor :parser_start +end +self.parser_start = 49; +class << self + attr_accessor :parser_first_final +end +self.parser_first_final = 49; +class << self + attr_accessor :parser_error +end +self.parser_error = 0; + +class << self + attr_accessor :parser_en_Closeout +end +self.parser_en_Closeout = 48; +class << self + attr_accessor :parser_en_main +end +self.parser_en_main = 49; + + +# line 120 "scanner.rl" + +# line 780 "scanner.rb" +begin + p ||= 0 + pe ||= data.length + cs = parser_start + ts = nil + te = nil + act = 0 +end + +# line 121 "scanner.rl" + +# line 792 "scanner.rb" +begin + testEof = false + _slen, _trans, _keys, _inds, _acts, _nacts = nil + _goto_level = 0 + _resume = 10 + _eof_trans = 15 + _again = 20 + _test_eof = 30 + _out = 40 + while true + if _goto_level <= 0 + if p == pe + _goto_level = _test_eof + next + end + if cs == 0 + _goto_level = _out + next + end + end + if _goto_level <= _resume + case _parser_from_state_actions[cs] + when 26 then +# line 1 "scanner.rl" + begin +ts = p + end +# line 1 "scanner.rl" +# line 821 "scanner.rb" + end + _keys = cs << 1 + _inds = _parser_index_offsets[cs] + _slen = _parser_key_spans[cs] + _trans = if ( _slen > 0 && + _parser_trans_keys[_keys] <= data[p] && + data[p] <= _parser_trans_keys[_keys + 1] + ) then + _parser_indicies[ _inds + data[p] - _parser_trans_keys[_keys] ] + else + _parser_indicies[ _inds + _slen ] + end + end + if _goto_level <= _eof_trans + cs = _parser_trans_targs[_trans] + if _parser_trans_actions[_trans] != 0 + case _parser_trans_actions[_trans] + when 24 then +# line 5 "scanner.rl" + begin + mark_pfx = p end +# line 5 "scanner.rl" + when 2 then +# line 6 "scanner.rl" + begin + + if data[mark_pfx..p-1] != @prefix + closing = data[mark_pfx-1,1] == '/' + @nodes.last << data[mark_pfx-(closing ? 2 : 1)..p] + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 6 "scanner.rl" + when 3 then +# line 13 "scanner.rl" + begin + mark_stg = p end +# line 13 "scanner.rl" + when 4 then +# line 14 "scanner.rl" + begin + @starttag = data[mark_stg..p-1] end +# line 14 "scanner.rl" + when 11 then +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" + when 15 then +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" + when 5 then +# line 25 "scanner.rl" + begin + mark_nat = p end +# line 25 "scanner.rl" + when 7 then +# line 26 "scanner.rl" + begin + @nat = data[mark_nat..p-1] end +# line 26 "scanner.rl" + when 8 then +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" + when 10 then +# line 28 "scanner.rl" + begin + @vat = data[mark_vat..p-1] end +# line 28 "scanner.rl" + when 27 then +# line 79 "scanner.rl" + begin +te = p+1 + begin + @nodes.last << data[p].chr + @tagstart = p + end + end +# line 79 "scanner.rl" + when 29 then +# line 79 "scanner.rl" + begin +te = p +p = p - 1; begin + @nodes.last << data[p].chr + @tagstart = p + end + end +# line 79 "scanner.rl" + when 1 then +# line 79 "scanner.rl" + begin + begin p = ((te))-1; end + begin + @nodes.last << data[p].chr + @tagstart = p + end + end +# line 79 "scanner.rl" + when 6 then +# line 1 "scanner.rl" + begin + case act + when 1 then + begin begin p = ((te))-1; end + + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + when 2 then + begin begin p = ((te))-1; end + + @nodes.last << data[p].chr + @tagstart = p + end +end + end +# line 1 "scanner.rl" + when 13 then +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" + when 14 then +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" +# line 25 "scanner.rl" + begin + mark_nat = p end +# line 25 "scanner.rl" + when 18 then +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" + when 9 then +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" +# line 28 "scanner.rl" + begin + @vat = data[mark_vat..p-1] end +# line 28 "scanner.rl" + when 23 then +# line 28 "scanner.rl" + begin + @vat = data[mark_vat..p-1] end +# line 28 "scanner.rl" +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" + when 31 then +# line 30 "scanner.rl" + begin + @flavor = :open end +# line 30 "scanner.rl" +# line 70 "scanner.rl" + begin +te = p +p = p - 1; begin + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 70 "scanner.rl" + when 30 then +# line 31 "scanner.rl" + begin + @flavor = :self end +# line 31 "scanner.rl" +# line 70 "scanner.rl" + begin +te = p +p = p - 1; begin + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 70 "scanner.rl" + when 32 then +# line 32 "scanner.rl" + begin + @flavor = :close end +# line 32 "scanner.rl" +# line 70 "scanner.rl" + begin +te = p +p = p - 1; begin + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 70 "scanner.rl" + when 22 then +# line 1 "scanner.rl" + begin +te = p+1 + end +# line 1 "scanner.rl" +# line 70 "scanner.rl" + begin +act = 1; end +# line 70 "scanner.rl" + when 28 then +# line 1 "scanner.rl" + begin +te = p+1 + end +# line 1 "scanner.rl" +# line 79 "scanner.rl" + begin +act = 2; end +# line 79 "scanner.rl" + when 12 then +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" +# line 25 "scanner.rl" + begin + mark_nat = p end +# line 25 "scanner.rl" + when 20 then +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" + when 17 then +# line 1 "scanner.rl" + begin +te = p+1 + end +# line 1 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" +# line 70 "scanner.rl" + begin +act = 1; end +# line 70 "scanner.rl" + when 19 then +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" +# line 25 "scanner.rl" + begin + mark_nat = p end +# line 25 "scanner.rl" + when 16 then +# line 1 "scanner.rl" + begin +te = p+1 + end +# line 1 "scanner.rl" +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" +# line 70 "scanner.rl" + begin +act = 1; end +# line 70 "scanner.rl" + when 21 then +# line 1 "scanner.rl" + begin +te = p+1 + end +# line 1 "scanner.rl" +# line 27 "scanner.rl" + begin + mark_vat = p end +# line 27 "scanner.rl" +# line 15 "scanner.rl" + begin + mark_attr = p end +# line 15 "scanner.rl" +# line 16 "scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 16 "scanner.rl" +# line 70 "scanner.rl" + begin +act = 1; end +# line 70 "scanner.rl" +# line 1211 "scanner.rb" + end + end + end + if _goto_level <= _again + case _parser_to_state_actions[cs] + when 25 then +# line 1 "scanner.rl" + begin +ts = nil; end +# line 1 "scanner.rl" +# line 1222 "scanner.rb" + end + + if cs == 0 + _goto_level = _out + next + end + p += 1 + if p != pe + _goto_level = _resume + next + end + end + if _goto_level <= _test_eof + if p == eof + if _parser_eof_trans[cs] > 0 + _trans = _parser_eof_trans[cs] - 1; + _goto_level = _eof_trans + next; + end + end + + end + if _goto_level <= _out + break + end +end + end + +# line 122 "scanner.rl" + return p + end + end +end diff --git a/vendor/plugins/radius/lib/radius/parser/scanner.rl b/vendor/plugins/radius/lib/radius/parser/scanner.rl new file mode 100644 index 00000000..6c38f5b8 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser/scanner.rl @@ -0,0 +1,125 @@ +%%{ + machine parser; + + + action _prefix { mark_pfx = p } + action prefix { + if data[mark_pfx..p-1] != @prefix + closing = data[mark_pfx-1,1] == '/' + @nodes.last << data[mark_pfx-(closing ? 2 : 1)..p] + fbreak; + end + } + action _starttag { mark_stg = p } + action starttag { @starttag = data[mark_stg..p-1] } + action _attr { mark_attr = p } + action attr { + @attrs[@nat] = @vat + } + + action prematch { + @prematch_end = p + @prematch = data[0..p] if p > 0 + } + + action _nameattr { mark_nat = p } + action nameattr { @nat = data[mark_nat..p-1] } + action _valattr { mark_vat = p } + action valattr { @vat = data[mark_vat..p-1] } + + action opentag { @flavor = :open } + action selftag { @flavor = :self } + action closetag { @flavor = :close } + + action stopparse { + @cursor = p; + fbreak; + } + + + Closeout := empty; + + # words + PrefixChar = [\-A-Za-z0-9._?] ; + NameChar = [\-A-Za-z0-9._:?] ; + TagName = NameChar+ >_starttag %starttag; + Prefix = PrefixChar+ >_prefix %prefix; + + Name = Prefix ":" TagName; + + NameAttr = NameChar+ >_nameattr %nameattr; + Q1Char = ( "\\\'" | [^'] ) ; + Q1Attr = Q1Char* >_valattr %valattr; + Q2Char = ( "\\\"" | [^"] ) ; + Q2Attr = Q2Char* >_valattr %valattr; + + Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr; + Attrs = (space+ Attr* | empty); + + CloseTrailer = "/>" %selftag; + OpenTrailer = ">" %opentag; + + Trailer = (OpenTrailer | CloseTrailer); + + OpenOrSelfTag = Name Attrs? Trailer; + CloseTag = "/" Name space* ">" %closetag; + + SomeTag = '<' (OpenOrSelfTag | CloseTag); + + main := |* + SomeTag => { + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + fbreak; + }; + any => { + @nodes.last << data[p] + @tagstart = p + }; + *|; +}%% + +module Radius + class Scanner + def operate(prefix, data) + data = Radius::OrdString.new data + buf = "" + csel = "" + @prematch = '' + @starttag = nil + @attrs = {} + @flavor = :tasteless + @cursor = 0 + @tagstart = 0 + @nodes = [''] + remainder = data.dup + + until remainder.length == 0 + p = perform_parse(prefix, remainder) + remainder = remainder[p..-1] + end + + return @nodes + end + + private + def perform_parse(prefix, data) + stack = [] + p = 0 + ts = 0 + te = 0 + act = 0 + eof = data.length + + @prefix = prefix + %% write data; + %% write init; + %% write exec; + return p + end + end +end diff --git a/vendor/plugins/radius/lib/radius/parser/squiggle_scanner.rb b/vendor/plugins/radius/lib/radius/parser/squiggle_scanner.rb new file mode 100644 index 00000000..d37394d4 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser/squiggle_scanner.rb @@ -0,0 +1,1237 @@ + +# line 1 "squiggle_scanner.rl" + +# line 85 "squiggle_scanner.rl" + + +module Radius + class SquiggleScanner + def operate(prefix, data) + data = Radius::OrdString.new data + buf = "" + csel = "" + @prematch = '' + @starttag = nil + @attrs = {} + @flavor = :tasteless + @cursor = 0 + @tagstart = 0 + @nodes = [''] + remainder = data.dup + + until remainder.length == 0 + p = perform_parse(prefix, remainder) + remainder = remainder[p..-1] + end + + return @nodes + end + + private + def perform_parse(prefix, data) + stack = [] + p = 0 + ts = 0 + te = 0 + act = 0 + eof = data.length + + @prefix = prefix + +# line 42 "squiggle_scanner.rb" +class << self + attr_accessor :_parser_trans_keys + private :_parser_trans_keys, :_parser_trans_keys= +end +self._parser_trans_keys = [ + 0, 0, 9, 122, 9, 125, + 9, 125, 9, 122, 9, + 61, 9, 39, 34, 92, + 34, 92, 9, 125, 9, 125, + 125, 125, 34, 92, 9, + 125, 9, 125, 9, 122, + 9, 92, 9, 92, 9, 125, + 34, 125, 34, 92, 34, + 92, 9, 125, 39, 92, + 39, 92, 9, 125, 9, 122, + 9, 92, 9, 92, 34, + 92, 34, 92, 9, 125, + 9, 125, 9, 122, 9, 92, + 9, 92, 9, 125, 34, + 125, 9, 125, 9, 125, + 39, 125, 39, 92, 45, 122, + 9, 125, 9, 125, 0, + 0, 123, 123, 9, 122, + 0, 0, 0, 0, 34, 92, + 34, 92, 34, 92, 34, + 92, 39, 92, 39, 92, + 0, 0, 0 +] + +class << self + attr_accessor :_parser_key_spans + private :_parser_key_spans, :_parser_key_spans= +end +self._parser_key_spans = [ + 0, 114, 117, 117, 114, 53, 31, 59, + 59, 117, 117, 1, 59, 117, 117, 114, + 84, 84, 117, 92, 59, 59, 117, 54, + 54, 117, 114, 84, 84, 59, 59, 117, + 117, 114, 84, 84, 117, 92, 117, 117, + 87, 54, 78, 117, 117, 0, 1, 114, + 0, 0, 59, 59, 59, 59, 54, 54, + 0 +] + +class << self + attr_accessor :_parser_index_offsets + private :_parser_index_offsets, :_parser_index_offsets= +end +self._parser_index_offsets = [ + 0, 0, 115, 233, 351, 466, 520, 552, + 612, 672, 790, 908, 910, 970, 1088, 1206, + 1321, 1406, 1491, 1609, 1702, 1762, 1822, 1940, + 1995, 2050, 2168, 2283, 2368, 2453, 2513, 2573, + 2691, 2809, 2924, 3009, 3094, 3212, 3305, 3423, + 3541, 3629, 3684, 3763, 3881, 3999, 4000, 4002, + 4117, 4118, 4119, 4179, 4239, 4299, 4359, 4414, + 4469 +] + +class << self + attr_accessor :_parser_indicies + private :_parser_indicies, :_parser_indicies= +end +self._parser_indicies = [ + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 3, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0, 0, 0, 0, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0, 0, 0, 0, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5, + 5, 6, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, + 0, 5, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, + 0, 5, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 7, + 0, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 10, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 9, + 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 9, + 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 11, 0, 13, + 13, 13, 13, 13, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 13, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 14, 14, 12, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 12, 12, 15, 12, 14, 12, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 12, 12, 12, 12, 14, 12, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 12, 16, 16, 16, 16, 16, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 16, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 17, 12, + 17, 17, 17, 17, 17, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 17, + 12, 18, 12, 12, 12, 12, 19, 12, + 21, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 22, 20, 24, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 25, 23, + 26, 26, 26, 26, 26, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 26, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 27, 27, 28, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 12, 12, 12, 12, 27, 12, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 12, 12, 12, 12, 27, 12, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 12, 12, 29, 12, 30, 30, + 30, 30, 30, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 30, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 31, 31, 32, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 12, 12, 12, 12, 31, 12, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 12, 12, 12, 12, 31, 12, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 12, 12, 33, 12, 34, 12, 35, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 25, 23, 36, 36, 36, 36, 36, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 36, 23, 24, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 37, 37, + 38, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 23, 23, 23, 23, + 37, 23, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 23, 25, 23, 23, + 37, 23, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 23, 23, 39, 23, + 40, 40, 40, 40, 40, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 40, + 23, 24, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 41, 41, 42, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 23, 23, 23, 23, 41, 23, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 23, 25, 23, 23, 41, 23, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 23, 23, 43, 23, 44, 44, + 44, 44, 44, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 44, 23, 24, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 45, 45, 23, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 23, 23, 46, 23, 45, 23, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 23, 25, 23, 23, 45, 23, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 23, 47, 47, 47, 47, 47, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 47, 23, 24, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 48, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 25, 23, 48, 48, + 48, 48, 48, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 48, 23, 49, + 23, 23, 23, 23, 50, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 25, 23, 51, 51, 51, 51, 51, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 51, 20, 21, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 52, + 52, 53, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 20, 20, 20, + 20, 52, 20, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 20, 22, 20, + 20, 52, 20, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 20, 20, 54, + 20, 24, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 25, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 55, 23, 57, 56, + 56, 56, 56, 58, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 59, 56, 61, 60, 60, 60, 60, 35, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 62, 60, 64, 64, + 64, 64, 64, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 64, 63, 63, + 63, 63, 63, 63, 24, 63, 63, 63, + 63, 63, 65, 65, 66, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 63, 63, 63, 63, 65, 63, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 63, 67, 63, 63, 65, 63, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 63, 63, 68, 63, 24, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 67, 63, 61, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 67, 63, 69, 69, 69, 69, 69, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 69, 63, 63, 63, 63, 63, 63, + 24, 63, 63, 63, 63, 63, 70, 70, + 71, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 63, 63, 63, 63, + 70, 63, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 63, 67, 63, 63, + 70, 63, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 63, 63, 72, 63, + 73, 73, 73, 73, 73, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 73, + 63, 63, 63, 63, 63, 63, 24, 63, + 63, 63, 63, 63, 74, 74, 63, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 63, 63, 75, 63, 74, 63, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 63, 67, 63, 63, 74, 63, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 63, 76, 76, 76, 76, 76, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 76, 63, 63, 63, 63, 63, + 63, 24, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 77, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 67, 63, + 77, 77, 77, 77, 77, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 77, + 63, 78, 63, 63, 63, 63, 79, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 67, 63, 80, 56, 56, + 56, 56, 58, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 59, + 56, 81, 60, 60, 60, 60, 81, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 62, 60, 82, 82, 82, + 82, 82, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 82, 60, 61, 60, + 60, 60, 60, 35, 60, 60, 60, 60, + 60, 83, 83, 84, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 60, + 60, 60, 60, 83, 60, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 60, + 62, 60, 60, 83, 60, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 60, + 60, 85, 60, 86, 86, 86, 86, 86, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 86, 60, 61, 60, 60, 60, + 60, 35, 60, 60, 60, 60, 60, 87, + 87, 88, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 60, 60, 60, + 60, 87, 60, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 60, 62, 60, + 60, 87, 60, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 60, 60, 89, + 60, 90, 90, 90, 90, 90, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 90, 60, 61, 60, 60, 60, 60, 35, + 60, 60, 60, 60, 60, 91, 91, 60, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 60, 60, 92, 60, 91, + 60, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 60, 62, 60, 60, 91, + 60, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 60, 93, 93, 93, 93, + 93, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 93, 60, 61, 60, 60, + 60, 60, 35, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 94, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 62, + 60, 94, 94, 94, 94, 94, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 94, 60, 95, 60, 60, 60, 60, 96, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 62, 60, 97, 97, + 97, 97, 97, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 97, 56, 80, + 56, 56, 56, 56, 58, 56, 56, 56, + 56, 56, 98, 98, 99, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 56, 56, 56, 56, 98, 56, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 56, 59, 56, 56, 98, 56, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 56, 56, 100, 56, 61, 60, 60, 60, + 60, 35, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 62, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 101, + 60, 97, 97, 97, 97, 97, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 97, 56, 57, 56, 56, 56, 56, 58, + 56, 56, 56, 56, 56, 98, 98, 99, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 56, 56, 56, 56, 98, + 56, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 56, 59, 56, 56, 98, + 56, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 56, 56, 100, 56, 103, + 103, 103, 103, 103, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 103, 102, + 102, 102, 102, 102, 102, 21, 102, 102, + 102, 102, 102, 104, 104, 105, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 102, 102, 102, 102, 104, 102, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 102, 106, 102, 102, 104, 102, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 102, 102, 107, 102, 24, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 67, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 108, 63, 21, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 106, 102, 109, 109, 0, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 0, 0, 0, 0, 109, 0, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 0, 0, 0, 0, 109, 0, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 0, 110, 110, 110, 110, 110, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 110, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 111, + 111, 0, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 0, 0, 0, + 0, 111, 0, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 0, 0, 0, + 0, 111, 0, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 0, 0, 112, + 0, 113, 113, 113, 113, 113, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 113, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 114, 0, 115, + 117, 116, 1, 1, 1, 1, 1, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 1, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 2, 2, + 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 118, 118, 118, 118, + 2, 118, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 118, 118, 118, 118, + 2, 118, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 118, 119, 120, 24, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 25, 23, 24, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 25, 23, 61, + 60, 60, 60, 60, 35, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 62, 60, 61, 60, 60, 60, 60, + 35, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 62, 60, 24, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 67, 63, 24, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 67, 63, 121, 0 +] + +class << self + attr_accessor :_parser_trans_targs + private :_parser_trans_targs, :_parser_trans_targs= +end +self._parser_trans_targs = [ + 46, 1, 2, 42, 3, 2, 11, 49, + 3, 4, 11, 49, 46, 5, 4, 6, + 5, 6, 7, 41, 8, 9, 12, 8, + 9, 12, 10, 4, 11, 49, 10, 4, + 11, 49, 48, 13, 14, 15, 19, 51, + 14, 15, 19, 51, 16, 15, 17, 16, + 17, 18, 20, 14, 15, 19, 51, 50, + 21, 22, 13, 30, 21, 22, 30, 23, + 25, 26, 40, 24, 55, 25, 26, 40, + 55, 27, 26, 28, 27, 28, 29, 39, + 22, 31, 32, 33, 37, 53, 32, 33, + 37, 53, 34, 33, 35, 34, 35, 36, + 38, 32, 33, 37, 53, 52, 23, 25, + 26, 40, 24, 55, 54, 43, 44, 43, + 56, 44, 56, 0, 46, 47, 46, 46, + 46, 46 +] + +class << self + attr_accessor :_parser_trans_actions + private :_parser_trans_actions, :_parser_trans_actions= +end +self._parser_trans_actions = [ + 1, 0, 2, 0, 3, 0, 3, 3, + 0, 4, 0, 0, 5, 6, 0, 6, + 0, 0, 0, 0, 7, 8, 7, 0, + 9, 0, 10, 11, 12, 12, 0, 13, + 14, 14, 0, 9, 10, 11, 12, 15, + 0, 13, 14, 16, 6, 0, 6, 0, + 0, 9, 0, 17, 18, 19, 20, 21, + 7, 22, 8, 7, 0, 9, 0, 0, + 10, 11, 12, 0, 15, 0, 13, 14, + 16, 6, 0, 6, 0, 0, 0, 9, + 8, 9, 10, 11, 12, 15, 0, 13, + 14, 16, 6, 0, 6, 0, 0, 9, + 9, 17, 18, 19, 20, 21, 7, 17, + 18, 19, 7, 20, 21, 2, 3, 0, + 3, 0, 0, 0, 25, 26, 27, 28, + 29, 30 +] + +class << self + attr_accessor :_parser_to_state_actions + private :_parser_to_state_actions, :_parser_to_state_actions= +end +self._parser_to_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 23, 23, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +] + +class << self + attr_accessor :_parser_from_state_actions + private :_parser_from_state_actions, :_parser_from_state_actions= +end +self._parser_from_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +] + +class << self + attr_accessor :_parser_eof_trans + private :_parser_eof_trans, :_parser_eof_trans= +end +self._parser_eof_trans = [ + 0, 1, 1, 1, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 1, 1, 1, 0, 0, 119, + 120, 121, 120, 121, 120, 121, 120, 121, + 122 +] + +class << self + attr_accessor :parser_start +end +self.parser_start = 46; +class << self + attr_accessor :parser_first_final +end +self.parser_first_final = 46; +class << self + attr_accessor :parser_error +end +self.parser_error = 0; + +class << self + attr_accessor :parser_en_Closeout +end +self.parser_en_Closeout = 45; +class << self + attr_accessor :parser_en_main +end +self.parser_en_main = 46; + + +# line 121 "squiggle_scanner.rl" + +# line 784 "squiggle_scanner.rb" +begin + p ||= 0 + pe ||= data.length + cs = parser_start + ts = nil + te = nil + act = 0 +end + +# line 122 "squiggle_scanner.rl" + +# line 796 "squiggle_scanner.rb" +begin + testEof = false + _slen, _trans, _keys, _inds, _acts, _nacts = nil + _goto_level = 0 + _resume = 10 + _eof_trans = 15 + _again = 20 + _test_eof = 30 + _out = 40 + while true + if _goto_level <= 0 + if p == pe + _goto_level = _test_eof + next + end + if cs == 0 + _goto_level = _out + next + end + end + if _goto_level <= _resume + case _parser_from_state_actions[cs] + when 24 then +# line 1 "squiggle_scanner.rl" + begin +ts = p + end +# line 1 "squiggle_scanner.rl" +# line 825 "squiggle_scanner.rb" + end + _keys = cs << 1 + _inds = _parser_index_offsets[cs] + _slen = _parser_key_spans[cs] + _trans = if ( _slen > 0 && + _parser_trans_keys[_keys] <= data[p] && + data[p] <= _parser_trans_keys[_keys + 1] + ) then + _parser_indicies[ _inds + data[p] - _parser_trans_keys[_keys] ] + else + _parser_indicies[ _inds + _slen ] + end + end + if _goto_level <= _eof_trans + cs = _parser_trans_targs[_trans] + if _parser_trans_actions[_trans] != 0 + case _parser_trans_actions[_trans] + when 2 then +# line 12 "squiggle_scanner.rl" + begin + mark_stg = p end +# line 12 "squiggle_scanner.rl" + when 3 then +# line 13 "squiggle_scanner.rl" + begin + @starttag = data[mark_stg..p-1] end +# line 13 "squiggle_scanner.rl" + when 10 then +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" + when 14 then +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" + when 4 then +# line 24 "squiggle_scanner.rl" + begin + mark_nat = p end +# line 24 "squiggle_scanner.rl" + when 6 then +# line 25 "squiggle_scanner.rl" + begin + @nat = data[mark_nat..p-1] end +# line 25 "squiggle_scanner.rl" + when 7 then +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" + when 9 then +# line 27 "squiggle_scanner.rl" + begin + @vat = data[mark_vat..p-1] end +# line 27 "squiggle_scanner.rl" + when 25 then +# line 80 "squiggle_scanner.rl" + begin +te = p+1 + begin + @nodes.last << data[p] + @tagstart = p + end + end +# line 80 "squiggle_scanner.rl" + when 27 then +# line 80 "squiggle_scanner.rl" + begin +te = p +p = p - 1; begin + @nodes.last << data[p] + @tagstart = p + end + end +# line 80 "squiggle_scanner.rl" + when 1 then +# line 80 "squiggle_scanner.rl" + begin + begin p = ((te))-1; end + begin + @nodes.last << data[p] + @tagstart = p + end + end +# line 80 "squiggle_scanner.rl" + when 5 then +# line 1 "squiggle_scanner.rl" + begin + case act + when 1 then + begin begin p = ((te))-1; end + + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + when 2 then + begin begin p = ((te))-1; end + + @nodes.last << data[p] + @tagstart = p + end +end + end +# line 1 "squiggle_scanner.rl" + when 12 then +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" + when 13 then +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" +# line 24 "squiggle_scanner.rl" + begin + mark_nat = p end +# line 24 "squiggle_scanner.rl" + when 17 then +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" + when 8 then +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" +# line 27 "squiggle_scanner.rl" + begin + @vat = data[mark_vat..p-1] end +# line 27 "squiggle_scanner.rl" + when 22 then +# line 27 "squiggle_scanner.rl" + begin + @vat = data[mark_vat..p-1] end +# line 27 "squiggle_scanner.rl" +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" + when 29 then +# line 29 "squiggle_scanner.rl" + begin + @flavor = :open end +# line 29 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +te = p +p = p - 1; begin + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 71 "squiggle_scanner.rl" + when 28 then +# line 30 "squiggle_scanner.rl" + begin + @flavor = :self end +# line 30 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +te = p +p = p - 1; begin + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 71 "squiggle_scanner.rl" + when 30 then +# line 31 "squiggle_scanner.rl" + begin + @flavor = :close end +# line 31 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +te = p +p = p - 1; begin + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + begin + p += 1 + _goto_level = _out + next + end + + end + end +# line 71 "squiggle_scanner.rl" + when 21 then +# line 1 "squiggle_scanner.rl" + begin +te = p+1 + end +# line 1 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +act = 1; end +# line 71 "squiggle_scanner.rl" + when 26 then +# line 1 "squiggle_scanner.rl" + begin +te = p+1 + end +# line 1 "squiggle_scanner.rl" +# line 80 "squiggle_scanner.rl" + begin +act = 2; end +# line 80 "squiggle_scanner.rl" + when 11 then +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" +# line 24 "squiggle_scanner.rl" + begin + mark_nat = p end +# line 24 "squiggle_scanner.rl" + when 19 then +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" + when 16 then +# line 1 "squiggle_scanner.rl" + begin +te = p+1 + end +# line 1 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +act = 1; end +# line 71 "squiggle_scanner.rl" + when 18 then +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" +# line 24 "squiggle_scanner.rl" + begin + mark_nat = p end +# line 24 "squiggle_scanner.rl" + when 15 then +# line 1 "squiggle_scanner.rl" + begin +te = p+1 + end +# line 1 "squiggle_scanner.rl" +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +act = 1; end +# line 71 "squiggle_scanner.rl" + when 20 then +# line 1 "squiggle_scanner.rl" + begin +te = p+1 + end +# line 1 "squiggle_scanner.rl" +# line 26 "squiggle_scanner.rl" + begin + mark_vat = p end +# line 26 "squiggle_scanner.rl" +# line 14 "squiggle_scanner.rl" + begin + mark_attr = p end +# line 14 "squiggle_scanner.rl" +# line 15 "squiggle_scanner.rl" + begin + + @attrs[@nat] = @vat + end +# line 15 "squiggle_scanner.rl" +# line 71 "squiggle_scanner.rl" + begin +act = 1; end +# line 71 "squiggle_scanner.rl" +# line 1194 "squiggle_scanner.rb" + end + end + end + if _goto_level <= _again + case _parser_to_state_actions[cs] + when 23 then +# line 1 "squiggle_scanner.rl" + begin +ts = nil; end +# line 1 "squiggle_scanner.rl" +# line 1205 "squiggle_scanner.rb" + end + + if cs == 0 + _goto_level = _out + next + end + p += 1 + if p != pe + _goto_level = _resume + next + end + end + if _goto_level <= _test_eof + if p == eof + if _parser_eof_trans[cs] > 0 + _trans = _parser_eof_trans[cs] - 1; + _goto_level = _eof_trans + next; + end + end + + end + if _goto_level <= _out + break + end +end + end + +# line 123 "squiggle_scanner.rl" + return p + end + end +end diff --git a/vendor/plugins/radius/lib/radius/parser/squiggle_scanner.rl b/vendor/plugins/radius/lib/radius/parser/squiggle_scanner.rl new file mode 100644 index 00000000..4ebb55c5 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/parser/squiggle_scanner.rl @@ -0,0 +1,126 @@ +%%{ + machine parser; + + +# action _prefix { mark_pfx = p } +# action prefix { +# if data[mark_pfx..p-1] != @prefix +# @nodes.last << data[mark_pfx-1..p] +# fbreak; +# end +# } + action _starttag { mark_stg = p } + action starttag { @starttag = data[mark_stg..p-1] } + action _attr { mark_attr = p } + action attr { + @attrs[@nat] = @vat + } + + action prematch { + @prematch_end = p + @prematch = data[0..p] if p > 0 + } + + action _nameattr { mark_nat = p } + action nameattr { @nat = data[mark_nat..p-1] } + action _valattr { mark_vat = p } + action valattr { @vat = data[mark_vat..p-1] } + + action opentag { @flavor = :open } + action selftag { @flavor = :self } + action closetag { @flavor = :close } + + action stopparse { + @cursor = p; + fbreak; + } + + + Closeout := empty; + + # words +# PrefixChar = [\-A-Za-z0-9._?] ; + NameChar = [\-A-Za-z0-9._:?] ; + TagName = NameChar+ >_starttag %starttag; +# Prefix = PrefixChar+ >_prefix %prefix; + +# Name = Prefix ":" TagName; + + NameAttr = NameChar+ >_nameattr %nameattr; + Q1Char = ( "\\\'" | [^'] ) ; + Q1Attr = Q1Char* >_valattr %valattr; + Q2Char = ( "\\\"" | [^"] ) ; + Q2Attr = Q2Char* >_valattr %valattr; + + Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr; + Attrs = (space+ Attr* | empty); + + CloseTrailer = "/}" %selftag; + OpenTrailer = "}" %opentag; + + Trailer = (OpenTrailer | CloseTrailer); + +# OpenOrSelfTag = Name Attrs? Trailer; + OpenOrSelfTag = TagName Attrs? Trailer; +# CloseTag = "/" Name space* "}" %closetag; + CloseTag = "/" TagName space* "}" %closetag; + + SomeTag = '{' space* (OpenOrSelfTag | CloseTag); + + main := |* + SomeTag => { + tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} + @prefix = nil + @name = nil + @flavor = :tasteless + @attrs = {} + @nodes << tag << '' + fbreak; + }; + any => { + @nodes.last << data[p] + @tagstart = p + }; + *|; +}%% + +module Radius + class SquiggleScanner + def operate(prefix, data) + data = Radius::OrdString.new data + buf = "" + csel = "" + @prematch = '' + @starttag = nil + @attrs = {} + @flavor = :tasteless + @cursor = 0 + @tagstart = 0 + @nodes = [''] + remainder = data.dup + + until remainder.length == 0 + p = perform_parse(prefix, remainder) + remainder = remainder[p..-1] + end + + return @nodes + end + + private + def perform_parse(prefix, data) + stack = [] + p = 0 + ts = 0 + te = 0 + act = 0 + eof = data.length + + @prefix = prefix + %% write data; + %% write init; + %% write exec; + return p + end + end +end diff --git a/vendor/plugins/radius/lib/radius/tag_binding.rb b/vendor/plugins/radius/lib/radius/tag_binding.rb new file mode 100644 index 00000000..6a27d684 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/tag_binding.rb @@ -0,0 +1,71 @@ +module Radius + # + # A tag binding is passed into each tag definition and contains helper methods for working + # with tags. Use it to gain access to the attributes that were passed to the tag, to + # render the tag contents, and to do other tasks. + # + class TagBinding + # The Context that the TagBinding is associated with. Used internally. Try not to use + # this object directly. + attr_reader :context + + # The locals object for the current tag. + attr_reader :locals + + # The name of the tag (as used in a template string). + attr_reader :name + + # The attributes of the tag. Also aliased as TagBinding#attr. + attr_reader :attributes + alias :attr :attributes + + # The render block. When called expands the contents of the tag. Use TagBinding#expand + # instead. + attr_reader :block + + # Creates a new TagBinding object. + def initialize(context, locals, name, attributes, block) + @context, @locals, @name, @attributes, @block = context, locals, name, attributes, block + end + + # Evaluates the current tag and returns the rendered contents. + def expand + double? ? block.call : '' + end + + # Returns true if the current tag is a single tag. + def single? + block.nil? + end + + # Returns true if the current tag is a container tag. + def double? + not single? + end + + # The globals object from which all locals objects ultimately inherit their values. + def globals + @context.globals + end + + # Returns a list of the way tags are nested around the current tag as a string. + def nesting + @context.current_nesting + end + + # Fires off Context#tag_missing for the current tag. + def missing! + @context.tag_missing(name, attributes, &block) + end + + # Renders the tag using the current context . + def render(tag, attributes = {}, &block) + @context.render_tag(tag, attributes, &block) + end + + # Shortcut for accessing tag.attr[key] + def [](key) + attr[key] + end + end +end \ No newline at end of file diff --git a/vendor/plugins/radius/lib/radius/tag_definitions.rb b/vendor/plugins/radius/lib/radius/tag_definitions.rb new file mode 100644 index 00000000..ca530f6d --- /dev/null +++ b/vendor/plugins/radius/lib/radius/tag_definitions.rb @@ -0,0 +1,78 @@ +module Radius + module TagDefinitions # :nodoc: + class TagFactory # :nodoc: + def initialize(context) + @context = context + end + + def define_tag(name, options, &block) + options = prepare_options(name, options) + validate_params(name, options, &block) + construct_tag_set(name, options, &block) + expose_methods_as_tags(name, options) + end + + protected + + # Adds the tag definition to the context. Override in subclasses to add additional tags + # (child tags) when the tag is created. + def construct_tag_set(name, options, &block) + if block + @context.definitions[name.to_s] = block + else + lp = last_part(name) + @context.define_tag(name) do |tag| + if tag.single? + options[:for] + else + tag.locals.send("#{ lp }=", options[:for]) unless options[:for].nil? + tag.expand + end + end + end + end + + # Normalizes options pased to tag definition. Override in decendants to preform + # additional normalization. + def prepare_options(name, options) + options = Utility.symbolize_keys(options) + options[:expose] = expand_array_option(options[:expose]) + object = options[:for] + options[:attributes] = object.respond_to?(:attributes) unless options.has_key? :attributes + options[:expose] += object.attributes.keys if options[:attributes] + options + end + + # Validates parameters passed to tag definition. Override in decendants to add custom + # validations. + def validate_params(name, options, &block) + unless options.has_key? :for + raise ArgumentError.new("tag definition must contain a :for option or a block") unless block + raise ArgumentError.new("tag definition must contain a :for option when used with the :expose option") unless options[:expose].empty? + end + end + + # Exposes the methods of an object as child tags. + def expose_methods_as_tags(name, options) + options[:expose].each do |method| + tag_name = "#{name}:#{method}" + lp = last_part(name) + @context.define_tag(tag_name) do |tag| + object = tag.locals.send(lp) + object.send(method) + end + end + end + + protected + + def expand_array_option(value) + [*value].compact.map { |m| m.to_s.intern } + end + + def last_part(name) + name.split(':').last + end + end + end +end diff --git a/vendor/plugins/radius/lib/radius/utility.rb b/vendor/plugins/radius/lib/radius/utility.rb new file mode 100644 index 00000000..aa10bc58 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/utility.rb @@ -0,0 +1,40 @@ +module Radius + module Utility # :nodoc: + def self.symbolize_keys(hash) + new_hash = {} + hash.keys.each do |k| + new_hash[k.to_s.intern] = hash[k] + end + new_hash + end + + def self.impartial_hash_delete(hash, key) + string = key.to_s + symbol = string.intern + value1 = hash.delete(symbol) + value2 = hash.delete(string) + value1 || value2 + end + + def self.constantize(camelized_string) + raise "invalid constant name `#{camelized_string}'" unless camelized_string.split('::').all? { |part| part =~ /^[A-Za-z]+$/ } + Object.module_eval(camelized_string) + end + + def self.camelize(underscored_string) + string = '' + underscored_string.split('_').each { |part| string << part.capitalize } + string + end + + if RUBY_VERSION[0,3] == '1.8' + def self.array_to_s(c) + c.to_s + end + else + def self.array_to_s(c) + c.map{|x| x.is_a?(Array) ? array_to_s(x) : x.to_s }.join + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/radius/lib/radius/version.rb b/vendor/plugins/radius/lib/radius/version.rb new file mode 100644 index 00000000..77615b18 --- /dev/null +++ b/vendor/plugins/radius/lib/radius/version.rb @@ -0,0 +1,8 @@ +module Radius #:nodoc: + def self.version + @version ||= begin + filename = File.join(File.dirname(__FILE__), '..', '..', 'VERSION') + IO.read(filename).strip + end + end +end diff --git a/vendor/plugins/radius/radius.gemspec b/vendor/plugins/radius/radius.gemspec new file mode 100644 index 00000000..bd9d08f5 --- /dev/null +++ b/vendor/plugins/radius/radius.gemspec @@ -0,0 +1,91 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{radius} + s.version = "0.7.0.prerelease" + + s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= + s.authors = ["John W. Long (me@johnwlong.com)", "David Chelimsky (dchelimsky@gmail.com)", "Bryce Kerley (bkerley@brycekerley.net)"] + s.date = %q{2010-05-24} + s.description = %q{Radius is a powerful tag-based template language for Ruby inspired by the template languages used in MovableType and TextPattern. It uses tags similar to XML, but can be used to generate any form of plain text (HTML, e-mail, etc...).} + s.email = %q{me@johnwlong.com} + s.extra_rdoc_files = [ + "CHANGELOG", + "LICENSE", + "QUICKSTART.rdoc", + "README.rdoc" + ] + s.files = [ + "CHANGELOG", + "LICENSE", + "QUICKSTART.rdoc", + "README.rdoc", + "Rakefile", + "VERSION", + "lib/radius.rb", + "lib/radius/context.rb", + "lib/radius/delegating_open_struct.rb", + "lib/radius/error.rb", + "lib/radius/parse_tag.rb", + "lib/radius/parser.rb", + "lib/radius/parser/JavaScanner$Flavor.class", + "lib/radius/parser/JavaScanner$Tag.class", + "lib/radius/parser/JavaScanner.class", + "lib/radius/parser/JavaScanner.java", + "lib/radius/parser/JavaScanner.rl", + "lib/radius/parser/java_scanner.jar", + "lib/radius/parser/scanner.rb", + "lib/radius/parser/scanner.rl", + "lib/radius/parser/squiggle_scanner.rb", + "lib/radius/parser/squiggle_scanner.rl", + "lib/radius/tag_binding.rb", + "lib/radius/tag_definitions.rb", + "lib/radius/utility.rb", + "lib/radius/version.rb", + "tasks/jeweler.rake", + "tasks/rdoc.rake", + "tasks/rubinius.rake", + "tasks/scan.rake", + "tasks/test.rake", + "test/benchmarks.rb", + "test/context_test.rb", + "test/multithreaded_test.rb", + "test/parser_test.rb", + "test/quickstart_test.rb", + "test/squiggle_test.rb", + "test/test_helper.rb", + "test/utility_test.rb" + ] + s.homepage = %q{http://github.com/jlong/radius} + s.rdoc_options = ["--charset=UTF-8"] + s.require_paths = ["lib"] + s.rubygems_version = %q{1.3.6} + s.summary = %q{A tag-based templating language for Ruby.} + s.test_files = [ + "test/context_test.rb", + "test/parser_test.rb", + "test/quickstart_test.rb", + "test/test_helper.rb", + "test/multithreaded_test.rb", + "test/squiggle_test.rb", + "test/utility_test.rb", + "test/benchmarks.rb" + ] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 3 + + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + end +end + diff --git a/vendor/plugins/radius/tasks/jeweler.rake b/vendor/plugins/radius/tasks/jeweler.rake new file mode 100644 index 00000000..36b63355 --- /dev/null +++ b/vendor/plugins/radius/tasks/jeweler.rake @@ -0,0 +1,22 @@ +begin + require 'jeweler' + Jeweler::Tasks.new do |gem| + gem.name = "radius" + gem.summary = "A tag-based templating language for Ruby." + gem.description = "Radius is a powerful tag-based template language for Ruby inspired by the template languages used in MovableType and TextPattern. It uses tags similar to XML, but can be used to generate any form of plain text (HTML, e-mail, etc...)." + gem.email = "me@johnwlong.com" + gem.homepage = "http://github.com/jlong/radius" + gem.authors = [ + "John W. Long (me@johnwlong.com)", + "David Chelimsky (dchelimsky@gmail.com)", + "Bryce Kerley (bkerley@brycekerley.net)" + ] + gem.files = FileList["[A-Z]*", "{bin,lib,tasks,test}/**/*"].exclude("tmp") + gem.extra_rdoc_files = ['README.rdoc', 'QUICKSTART.rdoc', 'LICENSE', 'CHANGELOG'] + gem.add_development_dependency('RedCloth') + # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings + end + Jeweler::GemcutterTasks.new +rescue LoadError + puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" +end diff --git a/vendor/plugins/radius/tasks/rdoc.rake b/vendor/plugins/radius/tasks/rdoc.rake new file mode 100644 index 00000000..8e41484c --- /dev/null +++ b/vendor/plugins/radius/tasks/rdoc.rake @@ -0,0 +1,13 @@ +require 'rake/rdoctask' +Rake::RDocTask.new do |rdoc| + version = File.exist?('VERSION') ? File.read('VERSION') : "" + + rdoc.rdoc_dir = 'rdoc' + rdoc.title = "Radius #{version}" + rdoc.main = "README.rdoc" + rdoc.rdoc_files.include('*.rdoc') + rdoc.rdoc_files.include('LICENSE') + rdoc.rdoc_files.include('CHANGELOG') + rdoc.rdoc_files.include('QUICKSTART.rdoc') + rdoc.rdoc_files.include('lib/**/*.rb') +end \ No newline at end of file diff --git a/vendor/plugins/radius/tasks/rubinius.rake b/vendor/plugins/radius/tasks/rubinius.rake new file mode 100644 index 00000000..14103512 --- /dev/null +++ b/vendor/plugins/radius/tasks/rubinius.rake @@ -0,0 +1,4 @@ +desc "remove Rubinius rbc files" +task "rubinius:clean" do + (Dir['**/*.rbc']).each { |f| rm f } +end \ No newline at end of file diff --git a/vendor/plugins/radius/tasks/scan.rake b/vendor/plugins/radius/tasks/scan.rake new file mode 100644 index 00000000..6c194c28 --- /dev/null +++ b/vendor/plugins/radius/tasks/scan.rake @@ -0,0 +1,79 @@ +namespace :scan do + desc 'Generate the parsers' + task 'build' => [ + 'lib/radius/parser/scanner.rb', + 'lib/radius/parser/squiggle_scanner.rb', + 'lib/radius/parser/java_scanner.jar' + ] + + desc 'Generate a PDF state graph from the parsers' + task 'graph' => ['doc/scanner.pdf', 'doc/squiggle_scanner.pdf'] + + desc 'turn the scanner.rl file into a ruby file' + file 'lib/radius/parser/scanner.rb' => 'lib/radius/parser/scanner.rl' do |t| + cd 'lib/radius/parser' do + sh "ragel -R -F1 scanner.rl" + end + end + + desc 'turn the squiggle_scanner.rl file into a ruby file' + file 'lib/radius/parser/squiggle_scanner.rb' => + ['lib/radius/parser/squiggle_scanner.rl'] \ + do |t| + cd 'lib/radius/parser' do + sh "ragel -R -F1 squiggle_scanner.rl" + end + end + + desc 'package JavaScanner into a jar file' + file 'lib/radius/parser/java_scanner.jar' => 'lib/radius/parser/JavaScanner.class' do + cd 'lib' do + sh "jar -cf radius/parser/java_scanner.jar radius/parser/*.class" + end + end + + desc 'turn the JavaScanner.java file into a java class file' + file 'lib/radius/parser/JavaScanner.class' => 'lib/radius/parser/JavaScanner.java' do |t| + cd 'lib' do + jruby_path = ENV['JRUBY_HOME'] || '/usr/local/jruby/current' + sh "javac -cp #{jruby_path}/lib/jruby.jar radius/parser/JavaScanner.java" + end + end + + desc 'turn the JavaScanner.rl file into a java source file' + file 'lib/radius/parser/JavaScanner.java' => 'lib/radius/parser/JavaScanner.rl' do |t| + cd 'lib/radius/parser' do + sh "ragel -J -F1 JavaScanner.rl" + end + end + + desc 'pdf of the ragel scanner' + file 'doc/scanner.pdf' => 'lib/radius/parser/scanner.dot' do |t| + cd 'lib/radius/parser' do + sh "dot -Tpdf -o ../../../doc/scanner.pdf scanner.dot" + end + end + + desc 'pdf of the ragel squiggle scanner' + file 'doc/squiggle_scanner.pdf' => + ['lib/radius/parser/squiggle_scanner.dot'] \ + do |t| + cd 'lib/radius/parser' do + sh "dot -Tpdf -o ../../../doc/squiggle_scanner.pdf squiggle_scanner.dot" + end + end + + file 'lib/radius/parser/scanner.dot' => 'lib/radius/parser/scanner.rl' do |t| + cd 'lib/radius/parser' do + sh "ragel -Vp scanner.rl > scanner.dot" + end + end + + file 'lib/radius/parser/squiggle_scanner.dot' => + ['lib/radius/parser/squiggle_scanner.rl'] \ + do |t| + cd 'lib/radius/parser' do + sh "ragel -Vp squiggle_scanner.rl > squiggle_scanner.dot" + end + end +end diff --git a/vendor/plugins/radius/tasks/test.rake b/vendor/plugins/radius/tasks/test.rake new file mode 100644 index 00000000..5d20c325 --- /dev/null +++ b/vendor/plugins/radius/tasks/test.rake @@ -0,0 +1,7 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs << "lib" << "test" + t.test_files = FileList['test/*_test.rb'] + t.verbose = true +end \ No newline at end of file diff --git a/vendor/plugins/radius/test/benchmarks.rb b/vendor/plugins/radius/test/benchmarks.rb new file mode 100644 index 00000000..40d5b179 --- /dev/null +++ b/vendor/plugins/radius/test/benchmarks.rb @@ -0,0 +1,35 @@ +$: << File.join(File.dirname(__FILE__), '..', 'lib') +require 'radius' + +if RUBY_PLATFORM == 'java' + require 'java' + require 'radius/parser/jscanner' +end + +require 'benchmark' + +document = < + Middle Top + + Middle Bottom + +After it all +EOF + +amount = 1000 + +Benchmark.bmbm do |bm| + bm.report('vanilla') do + scanner = Radius::Scanner.new(:scanner => Radius::Scanner) + amount.times { scanner.operate('r', document) } + end + + if RUBY_PLATFORM == 'java' + bm.report('JavaScanner') do + scanner = Radius::JavaScanner.new(JRuby.runtime) + amount.times { scanner.operate('r', document) } + end + end +end diff --git a/vendor/plugins/radius/test/context_test.rb b/vendor/plugins/radius/test/context_test.rb new file mode 100644 index 00000000..79b911b9 --- /dev/null +++ b/vendor/plugins/radius/test/context_test.rb @@ -0,0 +1,61 @@ +require File.expand_path(File.dirname(__FILE__) + '/test_helper') + +class RadiusContextTest < Test::Unit::TestCase + include RadiusTestHelper + + def setup + @context = new_context + end + + def test_initialize + @context = Radius::Context.new + end + + def test_initialize_with_block + @context = Radius::Context.new do |c| + assert_kind_of Radius::Context, c + c.define_tag('test') { 'just a test' } + end + assert_not_equal Hash.new, @context.definitions + end + + def test_with + got = @context.with do |c| + assert_equal @context, c + end + assert_equal @context, got + end + + def test_render_tag + define_global_tag "hello" do |tag| + "Hello #{tag.attr['name'] || 'World'}!" + end + assert_render_tag_output 'Hello World!', 'hello' + assert_render_tag_output 'Hello John!', 'hello', 'name' => 'John' + end + + def test_render_tag__undefined_tag + e = assert_raises(Radius::UndefinedTagError) { @context.render_tag('undefined_tag') } + assert_equal "undefined tag `undefined_tag'", e.message + end + + def test_tag_missing + class << @context + def tag_missing(tag, attr, &block) + "undefined tag `#{tag}' with attributes #{attr.inspect}" + end + end + + text = '' + expected = %{undefined tag `undefined_tag' with attributes {"cool"=>"beans"}} + assert_nothing_raised { text = @context.render_tag('undefined_tag', 'cool' => 'beans') } + assert_equal expected, text + end + + private + + def assert_render_tag_output(output, *render_tag_params) + assert_equal output, @context.render_tag(*render_tag_params) + end + +end diff --git a/vendor/plugins/radius/test/multithreaded_test.rb b/vendor/plugins/radius/test/multithreaded_test.rb new file mode 100644 index 00000000..8ee9739b --- /dev/null +++ b/vendor/plugins/radius/test/multithreaded_test.rb @@ -0,0 +1,62 @@ +require 'test/unit' +require 'radius' + +class MultithreadTest < Test::Unit::TestCase + + def setup + Thread.abort_on_exception + @context = Radius::Context.new do |c| + c.define_tag('thread') do |tag| + "#{tag.locals.thread_id} / #{tag.globals.object_id}" + end + end + end + + if RUBY_PLATFORM == 'java' + require 'java' + # call once before the thread to keep from using hidden require in a thread + Radius::Parser.new + def test_runs_multithreaded + lock = java.lang.String.new("lock") + threads = [] + 1000.times do |t| + thread = Thread.new do + parser = Radius::Parser.new(@context, :tag_prefix => 'r') + parser.context.globals.thread_id = Thread.current.object_id + expected = "#{Thread.current.object_id} / "+ + "#{parser.context.globals.object_id}" + actual = parser.parse('') + assert_equal expected, actual + end + lock.synchronized do + threads << thread + end + end + lock.synchronized do + threads.each{|t| t.join } + end + end + else + def test_runs_multithreaded + threads = [] + mute = Mutex.new + 1000.times do |t| + thread = Thread.new do + parser = Radius::Parser.new(@context, :tag_prefix => 'r') + parser.context.globals.thread_id = Thread.current.object_id + expected = "#{Thread.current.object_id} / "+ + "#{parser.context.globals.object_id}" + actual = parser.parse('') + assert_equal expected, actual + end + mute.synchronize do + threads << thread + end + end + mute.synchronize do + threads.each{|t| t.join } + end + end + end + +end diff --git a/vendor/plugins/radius/test/ord_string_test.rb b/vendor/plugins/radius/test/ord_string_test.rb new file mode 100644 index 00000000..bcb50995 --- /dev/null +++ b/vendor/plugins/radius/test/ord_string_test.rb @@ -0,0 +1,18 @@ +require 'test/unit' +require 'radius' + +class RadiusOrdStringTest < Test::Unit::TestCase + + def test_string_slice_integer + str = Radius::OrdString.new "abc" + assert_equal str[0], 97 + assert_equal str[1], 98 + assert_equal str[2], 99 + end + + def test_string_slice_range + str = Radius::OrdString.new "abc" + assert_equal str[0..-1], "abc" + end + +end \ No newline at end of file diff --git a/vendor/plugins/radius/test/parser_test.rb b/vendor/plugins/radius/test/parser_test.rb new file mode 100644 index 00000000..ffb1719a --- /dev/null +++ b/vendor/plugins/radius/test/parser_test.rb @@ -0,0 +1,307 @@ +require File.expand_path(File.dirname(__FILE__) + '/test_helper') + +class RadiusParserTest < Test::Unit::TestCase + include RadiusTestHelper + + def setup + @context = new_context + @parser = Radius::Parser.new(@context, :tag_prefix => 'r') + end + + def test_initialize + @parser = Radius::Parser.new + assert_kind_of Radius::Context, @parser.context + end + + def test_initialize_with_params + @parser = Radius::Parser.new(TestContext.new) + assert_kind_of TestContext, @parser.context + + @parser = Radius::Parser.new(:context => TestContext.new) + assert_kind_of TestContext, @parser.context + + @parser = Radius::Parser.new('context' => TestContext.new) + assert_kind_of TestContext, @parser.context + + @parser = Radius::Parser.new(:tag_prefix => 'r') + assert_kind_of Radius::Context, @parser.context + assert_equal 'r', @parser.tag_prefix + + @parser = Radius::Parser.new(TestContext.new, :tag_prefix => 'r') + assert_kind_of TestContext, @parser.context + assert_equal 'r', @parser.tag_prefix + end + + def test_parse_individual_tags_and_parameters + define_tag "add" do |tag| + tag.attr["param1"].to_i + tag.attr["param2"].to_i + end + assert_parse_output "<3>", %{<>} + end + + def test_parse_attributes + attributes = %{{"a"=>"1", "b"=>"2", "c"=>"3", "d"=>"'"}} + assert_parse_output attributes, %{} + assert_parse_output attributes, %{} + end + + def test_parse_attributes_with_slashes_or_angle_brackets + slash = %{{"slash"=>"/"}} + angle = %{{"angle"=>">"}} + assert_parse_output slash, %{} + assert_parse_output slash, %{} + assert_parse_output angle, %{} + end + + def test_parse_quotes + assert_parse_output "test []", %{ } + end + + def test_things_that_should_be_left_alone + [ + %{ test="2"="4" }, + %{="2" } + ].each do |middle| + assert_parsed_is_unchanged "" + assert_parsed_is_unchanged "" + end + end + + def test_tags_inside_html_tags + assert_parse_output %{
tags in yo tags
}, + %{
tags in yo tags
} + end + + def test_parse_result_is_always_a_string + define_tag("twelve") { 12 } + assert_parse_output "12", "" + end + + def test_parse_double_tags + assert_parse_output "test".reverse, "test" + assert_parse_output "tset TEST", "test test" + end + + def test_parse_tag_nesting + define_tag("parent", :for => '') + define_tag("parent:child", :for => '') + define_tag("extra", :for => '') + define_tag("nesting") { |tag| tag.nesting } + define_tag("extra:nesting") { |tag| tag.nesting.gsub(':', ' > ') } + define_tag("parent:child:nesting") { |tag| tag.nesting.gsub(':', ' * ') } + assert_parse_output "nesting", "" + assert_parse_output "parent:nesting", "" + assert_parse_output "extra > nesting", "" + assert_parse_output "parent * child * nesting", "" + assert_parse_output "parent > extra > nesting", "" + assert_parse_output "parent > child > extra > nesting", "" + assert_parse_output "parent * extra * child * nesting", "" + assert_parse_output "parent > extra > child > extra > nesting", "" + assert_parse_output "parent > extra > child > extra > nesting", "" + assert_parse_output "extra * parent * child * nesting", "" + assert_parse_output "extra > parent > nesting", "" + assert_parse_output "extra * parent * child * nesting", "" + assert_raises(Radius::UndefinedTagError) { @parser.parse("") } + end + def test_parse_tag_nesting_2 + define_tag("parent", :for => '') + define_tag("parent:child", :for => '') + define_tag("content") { |tag| tag.nesting } + assert_parse_output 'parent:child:content', '' + end + + def test_parse_tag__binding_do_missing + define_tag 'test' do |tag| + tag.missing! + end + e = assert_raises(Radius::UndefinedTagError) { @parser.parse("") } + assert_equal "undefined tag `test'", e.message + end + + def test_parse_chirpy_bird + # :> chirp chirp + assert_parse_output "<:", "<:" + end + + def test_parse_tag__binding_render_tag + define_tag('test') { |tag| "Hello #{tag.attr['name']}!" } + define_tag('hello') { |tag| tag.render('test', tag.attr) } + assert_parse_output 'Hello John!', '' + end + + def test_accessing_tag_attributes_through_tag_indexer + define_tag('test') { |tag| "Hello #{tag['name']}!" } + assert_parse_output 'Hello John!', '' + end + + def test_parse_tag__binding_render_tag_with_block + define_tag('test') { |tag| "Hello #{tag.expand}!" } + define_tag('hello') { |tag| tag.render('test') { tag.expand } } + assert_parse_output 'Hello John!', 'John' + end + + def test_tag_locals + define_tag "outer" do |tag| + tag.locals.var = 'outer' + tag.expand + end + define_tag "outer:inner" do |tag| + tag.locals.var = 'inner' + tag.expand + end + define_tag "outer:var" do |tag| + tag.locals.var + end + assert_parse_output 'outer', "" + assert_parse_output 'outer:inner:outer', "::" + assert_parse_output 'outer:inner:outer:inner:outer', "::::" + assert_parse_output 'outer', "" + end + + def test_tag_globals + define_tag "set" do |tag| + tag.globals.var = tag.attr['value'] + '' + end + define_tag "var" do |tag| + tag.globals.var + end + assert_parse_output " true false", %{ } + end + + def test_parse_loops + @item = nil + define_tag "each" do |tag| + result = [] + ["Larry", "Moe", "Curly"].each do |item| + tag.locals.item = item + result << tag.expand + end + result.join(tag.attr["between"] || "") + end + define_tag "each:item" do |tag| + tag.locals.item + end + assert_parse_output %{Three Stooges: "Larry", "Moe", "Curly"}, %{Three Stooges: ""} + end + + def test_parse_speed + define_tag "set" do |tag| + tag.globals.var = tag.attr['value'] + '' + end + define_tag "var" do |tag| + tag.globals.var + end + parts = %w{decima nobis augue at facer processus commodo legentis odio lectorum dolore nulla esse lius qui nonummy ullamcorper erat ii notare} + multiplier = parts.map{|p| "#{p}=\"#{rand}\""}.join(' ') + assert_nothing_raised do + Timeout.timeout(10) do + assert_parse_output " false", %{ } + end + end + end + + def test_tag_option_for + define_tag 'fun', :for => 'just for kicks' + assert_parse_output 'just for kicks', '' + end + + def test_tag_expose_option + define_tag 'user', :for => users.first, :expose => ['name', :age] + assert_parse_output 'John', '' + assert_parse_output '25', '' + e = assert_raises(Radius::UndefinedTagError) { @parser.parse "" } + assert_equal "undefined tag `email'", e.message + end + + def test_tag_expose_attributes_option_on_by_default + define_tag 'user', :for => user_with_attributes + assert_parse_output 'John', '' + end + def test_tag_expose_attributes_set_to_false + define_tag 'user_without_attributes', :for => user_with_attributes, :attributes => false + assert_raises(Radius::UndefinedTagError) { @parser.parse "" } + end + + def test_tag_options_must_contain_a_for_option_if_methods_are_exposed + e = assert_raises(ArgumentError) { define_tag('fun', :expose => :today) { 'test' } } + assert_equal "tag definition must contain a :for option when used with the :expose option", e.message + end + + def test_parse_fail_on_missing_end_tag + assert_raises(Radius::MissingEndTagError) { @parser.parse("") } + end + + def test_parse_fail_on_wrong_end_tag + assert_raises(Radius::WrongEndTagError) { @parser.parse("") } + end + + def test_parse_with_default_tag_prefix + @parser = Radius::Parser.new(@context) + define_tag("hello") { |tag| "Hello world!" } + assert_equal "

Hello world!

", @parser.parse('

') + end + + def test_parse_with_other_radius_like_tags + @parser = Radius::Parser.new(@context, :tag_prefix => "ralph") + define_tag('hello') { "hello" } + assert_equal "", @parser.parse("") + end + + def test_copyin_global_values + @context.globals.foo = 'bar' + assert_equal 'bar', Radius::Parser.new(@context).context.globals.foo + end + + def test_does_not_pollute_copied_globals + @context.globals.foo = 'bar' + parser = Radius::Parser.new(@context) + parser.context.globals.foo = '[baz]' + assert_equal 'bar', @context.globals.foo + end + + def test_parse_with_other_namespaces + @parser = Radius::Parser.new(@context, :tag_prefix => 'r') + assert_equal "hello world", @parser.parse("hello world") + end + + protected + + def assert_parse_output(output, input, message = nil) + r = @parser.parse(input) + assert_equal(output, r, message) + end + + def assert_parsed_is_unchanged(something) + assert_parse_output something, something + end + + class User + attr_accessor :name, :age, :email, :friend + def initialize(name, age, email) + @name, @age, @email = name, age, email + end + def <=>(other) + name <=> other.name + end + end + + class UserWithAttributes < User + def attributes + { :name => name, :age => age, :email => email } + end + end + + def users + [ + User.new('John', 25, 'test@johnwlong.com'), + User.new('James', 27, 'test@jameslong.com') + ] + end + + def user_with_attributes + UserWithAttributes.new('John', 25, 'test@johnwlong.com') + end + +end diff --git a/vendor/plugins/radius/test/quickstart_test.rb b/vendor/plugins/radius/test/quickstart_test.rb new file mode 100644 index 00000000..5a7bd1b6 --- /dev/null +++ b/vendor/plugins/radius/test/quickstart_test.rb @@ -0,0 +1,151 @@ +require File.expand_path(File.dirname(__FILE__) + '/test_helper') + +class QuickstartTest < Test::Unit::TestCase + + def test_hello_world + context = Radius::Context.new + context.define_tag "hello" do |tag| + "Hello #{tag.attr['name'] || 'World'}!" + end + parser = Radius::Parser.new(context) + assert_equal "

Hello World!

", parser.parse('

') + assert_equal "

Hello John!

", parser.parse('

') + end + + def test_example_2 + require 'redcloth' + context = Radius::Context.new + context.define_tag "textile" do |tag| + contents = tag.expand + RedCloth.new(contents).to_html + end + parser = Radius::Parser.new(context) + assert_equal "

Hello World!

", parser.parse('Hello **World**!') + end + + def test_nested_example + context = Radius::Context.new + + context.define_tag "stooge" do |tag| + content = '' + ["Larry", "Moe", "Curly"].each do |name| + tag.locals.name = name + content << tag.expand + end + content + end + + context.define_tag "stooge:name" do |tag| + tag.locals.name + end + + parser = Radius::Parser.new(context) + + template = <<-TEMPLATE +
    + +
  • +
    +
+ TEMPLATE + + output = <<-OUTPUT +
    + +
  • Larry
  • + +
  • Moe
  • + +
  • Curly
  • + +
+ OUTPUT + + assert_equal output, parser.parse(template) + end + + class User + attr_accessor :name, :age, :email + end + def test_exposing_objects_example + parser = Radius::Parser.new + + parser.context.define_tag "count", :for => 1 + assert_equal "1", parser.parse("") + + user = User.new + user.name, user.age, user.email = "John", 29, "john@example.com" + parser.context.define_tag "user", :for => user, :expose => [ :name, :age, :email ] + assert_equal "John", parser.parse("") + + assert_equal "John", parser.parse("") + end + + class LazyContext < Radius::Context + def tag_missing(tag, attr, &block) + "ERROR: Undefined tag `#{tag}' with attributes #{attr.inspect}" + end + end + def test_tag_missing_example + parser = Radius::Parser.new(LazyContext.new, :tag_prefix => 'lazy') + output = %{ERROR: Undefined tag `weird' with attributes {"value"=>"true"}} + assert_equal output, parser.parse('') + end + + def test_tag_globals_example + parser = Radius::Parser.new + + parser.context.define_tag "inc" do |tag| + tag.globals.count ||= 0 + tag.globals.count += 1 + "" + end + + parser.context.define_tag "count" do |tag| + tag.globals.count || 0 + end + + assert_equal "0 1", parser.parse(" ") + end + + class Person + attr_accessor :name, :friend + def initialize(name) + @name = name + end + end + def test_tag_locals_and_globals_example + jack = Person.new('Jack') + jill = Person.new('Jill') + jack.friend = jill + jill.friend = jack + + context = Radius::Context.new do |c| + c.define_tag "jack" do |tag| + tag.locals.person = jack + tag.expand + end + c.define_tag "jill" do |tag| + tag.locals.person = jill + tag.expand + end + c.define_tag "name" do |tag| + tag.locals.person.name rescue tag.missing! + end + c.define_tag "friend" do |tag| + tag.locals.person = tag.locals.person.friend rescue tag.missing! + tag.expand + end + end + + parser = Radius::Parser.new(context, :tag_prefix => 'r') + + assert_equal "Jack", parser.parse('') #=> "Jack" + assert_equal "Jill", parser.parse('') #=> "Jill" + assert_equal "Jack", parser.parse('') #=> "Jack" + assert_equal "Jack", parser.parse('') #=> "Jack" + assert_equal "Jack and Jill", parser.parse(' and ') #=> "Jack and Jill" + assert_raises(Radius::UndefinedTagError) { parser.parse('') } # raises a Radius::UndefinedTagError exception + end + +end diff --git a/vendor/plugins/radius/test/squiggle_test.rb b/vendor/plugins/radius/test/squiggle_test.rb new file mode 100644 index 00000000..bbae01b5 --- /dev/null +++ b/vendor/plugins/radius/test/squiggle_test.rb @@ -0,0 +1,281 @@ +require File.expand_path(File.dirname(__FILE__) + '/test_helper') +require 'radius/parser/squiggle_scanner' + +class RadiusSquiggleTest < Test::Unit::TestCase + include RadiusTestHelper + + def setup + @context = new_context + @parser = Radius::Parser.new(@context, :scanner => Radius::SquiggleScanner.new) + end + + def test_sane_scanner_default + assert !Radius::Parser.new.scanner.is_a?(Radius::SquiggleScanner) + end + + def test_initialize_with_params + @parser = Radius::Parser.new(:scanner => Radius::SquiggleScanner.new) + assert_kind_of Radius::SquiggleScanner, @parser.scanner + end + + def test_parse_individual_tags_and_parameters + define_tag "add" do |tag| + tag.attr["param1"].to_i + tag.attr["param2"].to_i + end + assert_parse_output "{3}", %[{{ add param1="1" param2='2'/}}] + end + + def test_parse_attributes + attributes = %[{"a"=>"1", "b"=>"2", "c"=>"3", "d"=>"'"}] + assert_parse_output attributes, %[{attr a="1" b='2'c="3"d="'" /}] + assert_parse_output attributes, %[{attr a="1" b='2'c="3"d="'"}{/attr}] + end + + def test_parse_attributes_with_slashes_or_angle_brackets + slash = %[{"slash"=>"/"}] + angle = %[{"angle"=>">"}] + assert_parse_output slash, %[{attr slash="/"}{/attr}] + assert_parse_output slash, %[{attr slash="/"}{attr /}{/attr}] + assert_parse_output angle, %[{attr angle=">"}{/attr}] + end + + def test_parse_quotes + assert_parse_output "test []", %[{echo value="test" /} {wrap attr="test"}{/wrap}] + end + + def test_things_that_should_be_left_alone + [ + %[ test="2"="4" ], + %[="2" ] + ].each do |middle| + assert_parsed_is_unchanged "{attr#{middle}/}" + assert_parsed_is_unchanged "{attr#{middle}}" + end + end + + def test_tags_inside_html_tags + assert_parse_output %[
tags in yo tags
], + %[
tags in yo tags
] + end + + def test_parse_result_is_always_a_string + define_tag("twelve") { 12 } + assert_parse_output "12", "{ twelve /}" + end + + def test_parse_double_tags + assert_parse_output "test".reverse, "{reverse}test{/reverse}" + assert_parse_output "tset TEST", "{reverse}test{/reverse} {capitalize}test{/capitalize}" + end + + def test_parse_tag_nesting + define_tag("parent", :for => '') + define_tag("parent:child", :for => '') + define_tag("extra", :for => '') + define_tag("nesting") { |tag| tag.nesting } + define_tag("extra:nesting") { |tag| tag.nesting.gsub(':', ' > ') } + define_tag("parent:child:nesting") { |tag| tag.nesting.gsub(':', ' * ') } + assert_parse_output "nesting", "{nesting /}" + assert_parse_output "parent:nesting", "{parent:nesting /}" + assert_parse_output "extra > nesting", "{extra:nesting /}" + assert_parse_output "parent * child * nesting", "{parent:child:nesting /}" + assert_parse_output "parent > extra > nesting", "{parent:extra:nesting /}" + assert_parse_output "parent > child > extra > nesting", "{parent:child:extra:nesting /}" + assert_parse_output "parent * extra * child * nesting", "{parent:extra:child:nesting /}" + assert_parse_output "parent > extra > child > extra > nesting", "{parent:extra:child:extra:nesting /}" + assert_parse_output "parent > extra > child > extra > nesting", "{parent}{extra}{child}{extra}{nesting /}{/extra}{/child}{/extra}{/parent}" + assert_parse_output "extra * parent * child * nesting", "{extra:parent:child:nesting /}" + assert_parse_output "extra > parent > nesting", "{extra}{parent:nesting /}{/extra}" + assert_parse_output "extra * parent * child * nesting", "{extra:parent}{child:nesting /}{/extra:parent}" + assert_raises(Radius::UndefinedTagError) { @parser.parse("{child /}") } + end + def test_parse_tag_nesting_2 + define_tag("parent", :for => '') + define_tag("parent:child", :for => '') + define_tag("content") { |tag| tag.nesting } + assert_parse_output 'parent:child:content', '{parent}{child:content /}{/parent}' + end + + def test_parse_tag__binding_do_missing + define_tag 'test' do |tag| + tag.missing! + end + e = assert_raises(Radius::UndefinedTagError) { @parser.parse("{test /}") } + assert_equal "undefined tag `test'", e.message + end + + def test_parse_chirpy_bird + # :> chirp chirp + assert_parse_output "<:", "<:" + end + + def test_parse_tag__binding_render_tag + define_tag('test') { |tag| "Hello #{tag.attr['name']}!" } + define_tag('hello') { |tag| tag.render('test', tag.attr) } + assert_parse_output 'Hello John!', '{hello name="John" /}' + end + + def test_accessing_tag_attributes_through_tag_indexer + define_tag('test') { |tag| "Hello #{tag['name']}!" } + assert_parse_output 'Hello John!', '{test name="John" /}' + end + + def test_parse_tag__binding_render_tag_with_block + define_tag('test') { |tag| "Hello #{tag.expand}!" } + define_tag('hello') { |tag| tag.render('test') { tag.expand } } + assert_parse_output 'Hello John!', '{hello}John{/hello}' + end + + def test_tag_locals + define_tag "outer" do |tag| + tag.locals.var = 'outer' + tag.expand + end + define_tag "outer:inner" do |tag| + tag.locals.var = 'inner' + tag.expand + end + define_tag "outer:var" do |tag| + tag.locals.var + end + assert_parse_output 'outer', "{outer}{var /}{/outer}" + assert_parse_output 'outer:inner:outer', "{outer}{var /}:{inner}{var /}{/inner}:{var /}{/outer}" + assert_parse_output 'outer:inner:outer:inner:outer', "{outer}{var /}:{inner}{var /}:{outer}{var /}{/outer}:{var /}{/inner}:{var /}{/outer}" + assert_parse_output 'outer', "{outer:var /}" + end + + def test_tag_globals + define_tag "set" do |tag| + tag.globals.var = tag.attr['value'] + '' + end + define_tag "var" do |tag| + tag.globals.var + end + assert_parse_output " true false", %[{var /} {set value="true" /} {var /} {set value="false" /} {var /}] + end + + def test_parse_loops + @item = nil + define_tag "each" do |tag| + result = [] + ["Larry", "Moe", "Curly"].each do |item| + tag.locals.item = item + result << tag.expand + end + result.join(tag.attr["between"] || "") + end + define_tag "each:item" do |tag| + tag.locals.item + end + assert_parse_output %[Three Stooges: "Larry", "Moe", "Curly"], %[Three Stooges: {each between=", "}"{item /}"{/each}] + end + + def test_parse_speed + define_tag "set" do |tag| + tag.globals.var = tag.attr['value'] + '' + end + define_tag "var" do |tag| + tag.globals.var + end + parts = %w{decima nobis augue at facer processus commodo legentis odio lectorum dolore nulla esse lius qui nonummy ullamcorper erat ii notare} + multiplier = parts.map{|p| "#{p}=\"#{rand}\""}.join(' ') + assert_nothing_raised do + Timeout.timeout(10) do + assert_parse_output " false", %[{set value="false" #{multiplier} /} {var /}] + end + end + end + + def test_tag_option_for + define_tag 'fun', :for => 'just for kicks' + assert_parse_output 'just for kicks', '{fun /}' + end + + def test_tag_expose_option + define_tag 'user', :for => users.first, :expose => ['name', :age] + assert_parse_output 'John', '{user:name /}' + assert_parse_output '25', '{user}{age /}{/user}' + e = assert_raises(Radius::UndefinedTagError) { @parser.parse "{user:email /}" } + assert_equal "undefined tag `email'", e.message + end + + def test_tag_expose_attributes_option_on_by_default + define_tag 'user', :for => user_with_attributes + assert_parse_output 'John', '{user:name /}' + end + def test_tag_expose_attributes_set_to_false + define_tag 'user_without_attributes', :for => user_with_attributes, :attributes => false + assert_raises(Radius::UndefinedTagError) { @parser.parse "{user_without_attributes:name /}" } + end + + def test_tag_options_must_contain_a_for_option_if_methods_are_exposed + e = assert_raises(ArgumentError) { define_tag('fun', :expose => :today) { 'test' } } + assert_equal "tag definition must contain a :for option when used with the :expose option", e.message + end + + def test_parse_fail_on_missing_end_tag + assert_raises(Radius::MissingEndTagError) { @parser.parse("{reverse}") } + end + + def test_parse_fail_on_wrong_end_tag + assert_raises(Radius::WrongEndTagError) { @parser.parse("{reverse}{capitalize}{/reverse}") } + end + + def test_copyin_global_values + @context.globals.foo = 'bar' + assert_equal 'bar', Radius::Parser.new(@context).context.globals.foo + end + + def test_does_not_pollute_copied_globals + @context.globals.foo = 'bar' + parser = Radius::Parser.new(@context) + parser.context.globals.foo = '[baz]' + assert_equal 'bar', @context.globals.foo + end + + def test_parse_with_other_namespaces + @parser = Radius::Parser.new(@context, :tag_prefix => 'r') + assert_equal "{fb:test}hello world{/fb:test}", @parser.parse("{fb:test}hello world{/fb:test}") + end + + protected + + def assert_parse_output(output, input, message = nil) + r = @parser.parse(input) + assert_equal(output, r, message) + end + + def assert_parsed_is_unchanged(something) + assert_parse_output something, something + end + + class User + attr_accessor :name, :age, :email, :friend + def initialize(name, age, email) + @name, @age, @email = name, age, email + end + def <=>(other) + name <=> other.name + end + end + + class UserWithAttributes < User + def attributes + { :name => name, :age => age, :email => email } + end + end + + def users + [ + User.new('John', 25, 'test@johnwlong.com'), + User.new('James', 27, 'test@jameslong.com') + ] + end + + def user_with_attributes + UserWithAttributes.new('John', 25, 'test@johnwlong.com') + end + +end diff --git a/vendor/plugins/radius/test/test_helper.rb b/vendor/plugins/radius/test/test_helper.rb new file mode 100644 index 00000000..4b4a8aad --- /dev/null +++ b/vendor/plugins/radius/test/test_helper.rb @@ -0,0 +1,36 @@ +require 'rubygems' +require 'timeout' + +unless defined? RADIUS_LIB + + RADIUS_LIB = File.join(File.dirname(__FILE__), '..', 'lib') + $LOAD_PATH << RADIUS_LIB + + require 'radius' + require 'test/unit' + + module RadiusTestHelper + class TestContext < Radius::Context; end + + def new_context + Radius::Context.new do |c| + c.define_tag("reverse" ) { |tag| tag.expand.reverse } + c.define_tag("capitalize") { |tag| tag.expand.upcase } + c.define_tag("echo" ) { |tag| tag.attr['value'] } + c.define_tag("wrap" ) { |tag| "[#{tag.expand}]" } + c.define_tag("attr") do |tag| + kv = tag.attr.keys.sort.collect{|k| "#{k.inspect}=>#{tag[k].inspect}"} + "{#{kv.join(', ')}}" + end + end + end + + def define_tag(name, options = {}, &block) + @parser.context.define_tag name, options, &block + end + + def define_global_tag(name, options = {}, &block) + @context.define_tag name, options, &block + end + end +end diff --git a/vendor/plugins/radius/test/utility_test.rb b/vendor/plugins/radius/test/utility_test.rb new file mode 100644 index 00000000..9d5ac12a --- /dev/null +++ b/vendor/plugins/radius/test/utility_test.rb @@ -0,0 +1,30 @@ +require 'test/unit' +require 'radius' + +class RadiusUtilityTest < Test::Unit::TestCase + + def test_symbolize_keys + h = Radius::Utility.symbolize_keys({ 'a' => 1, :b => 2 }) + assert_equal h[:a], 1 + assert_equal h[:b], 2 + end + + def test_impartial_hash_delete + h = { 'a' => 1, :b => 2 } + assert_equal Radius::Utility.impartial_hash_delete(h, :a), 1 + assert_equal Radius::Utility.impartial_hash_delete(h, 'b'), 2 + assert_equal h.empty?, true + end + + def test_constantize + assert_equal Radius::Utility.constantize('String'), String + end + + def test_camelize + assert_equal Radius::Utility.camelize('ab_cd_ef'), 'AbCdEf' + end + + def test_array_to_s + assert_equal Radius::Utility.array_to_s(['a', 1, [:c]]), 'a1c' + end +end \ No newline at end of file