class Fluent::Config::LiteralParser
Public Class Methods
new(strscan, eval_context)
click to toggle source
Calls superclass method
Fluent::Config::BasicParser::new
# File lib/fluent/config/literal_parser.rb, line 52 def initialize(strscan, eval_context) super(strscan) @eval_context = eval_context unless @eval_context.respond_to?(:use_nil) def @eval_context.use_nil raise SetNil end end unless @eval_context.respond_to?(:use_default) def @eval_context.use_default raise SetDefault end end end
unescape_char(c)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 29 def self.unescape_char(c) case c when '"' '\"' when "'" "\\'" when '\\' '\\\\' when "\r" '\r' when "\n" '\n' when "\t" '\t' when "\f" '\f' when "\b" '\b' else c end end
Public Instance Methods
eval_embedded_code(code)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 183 def eval_embedded_code(code) if @eval_context.nil? parse_error! "embedded code is not allowed in this file" end # Add hostname and worker_id to code for preventing unused warnings code = <<EOM + code hostname = Socket.gethostname worker_id = ENV['SERVERENGINE_WORKER_ID'] || '' EOM begin @eval_context.instance_eval(code) rescue SetNil nil rescue SetDefault :default end end
eval_escape_char(c)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 201 def eval_escape_char(c) case c when '"' '"' when "'" "'" when "r" "\r" when "n" "\n" when "t" "\t" when "f" "\f" when "b" "\b" when "0" "\0" when /[a-zA-Z0-9]/ parse_error! "unexpected back-slash escape character '#{c}'" else # symbols c end end
parse_literal(string_boundary_charset = LINE_END)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 67 def parse_literal(string_boundary_charset = LINE_END) spacing_without_comment value = if skip(/\[/) scan_json(true) elsif skip(/\{/) scan_json(false) else scan_string(string_boundary_charset) end value end
scan_double_quoted_string()
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 90 def scan_double_quoted_string string = [] while true if skip(/\"/) if string.include?(nil) return nil elsif string.include?(:default) return :default else return string.join end elsif check(/[^"]#{LINE_END_WITHOUT_SPACING_AND_COMMENT}/) if s = check(/[^\\]#{LINE_END_WITHOUT_SPACING_AND_COMMENT}/) string << s end skip(/[^"]#{LINE_END_WITHOUT_SPACING_AND_COMMENT}/) elsif s = scan(/\\./) string << eval_escape_char(s[1,1]) elsif skip(/\#\{/) string << eval_embedded_code(scan_embedded_code) skip(/\}/) elsif s = scan(/./) string << s else parse_error! "unexpected end of file in a double quoted string" end end end
scan_embedded_code()
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 157 def scan_embedded_code src = '"#{'+@ss.rest+"\n=begin\n=end\n}" seek = -1 while (seek = src.index('}', seek + 1)) unless Ripper.sexp(src[0..seek] + '"').nil? # eager parsing until valid expression break end end unless seek raise Fluent::ConfigParseError, @ss.rest end code = src[3, seek-3] if @ss.rest.length < code.length @ss.pos += @ss.rest.length parse_error! "expected end of embedded code but $end" end @ss.pos += code.length '"#{' + code + '}"' end
scan_json(is_array)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 226 def scan_json(is_array) result = nil # Yajl does not raise ParseError for incomplete json string, like '[1', '{"h"', '{"h":' or '{"h1":1' # This is the reason to use JSON module. buffer = (is_array ? "[" : "{") line_buffer = "" until result char = getch break if char.nil? if char == "#" # If this is out of json string literals, this object can be parsed correctly # '{"foo":"bar", #' -> '{"foo":"bar"}' (to check) parsed = nil begin parsed = JSON.parse(buffer + line_buffer.rstrip.sub(/,$/, '') + (is_array ? "]" : "}")) rescue JSON::ParserError # This '#' is in json string literals end if parsed # ignore chars as comment before newline while (char = getch) != "\n" # ignore comment char end buffer << line_buffer + "\n" line_buffer = "" else # '#' is a char in json string line_buffer << char end next # This char '#' MUST NOT terminate json object. end if char == "\n" buffer << line_buffer + "\n" line_buffer = "" next end line_buffer << char begin result = JSON.parse(buffer + line_buffer) rescue JSON::ParserError # Incomplete json string yet end end unless result parse_error! "got incomplete JSON #{is_array ? 'array' : 'hash'} configuration" end JSON.dump(result) end
scan_nonquoted_string(boundary_charset = LINE_END)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 136 def scan_nonquoted_string(boundary_charset = LINE_END) charset = /(?!#{boundary_charset})./ string = [] while true if s = scan(/\#/) string << '#' elsif s = scan(charset) string << s else break end end if string.empty? return nil end string.join end
scan_single_quoted_string()
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 119 def scan_single_quoted_string string = [] while true if skip(/\'/) return string.join elsif s = scan(/\\'/) string << "'" elsif s = scan(/\\\\/) string << "\\" elsif s = scan(/./) string << s else parse_error! "unexpected end of file in a single quoted string" end end end
scan_string(string_boundary_charset = LINE_END)
click to toggle source
# File lib/fluent/config/literal_parser.rb, line 80 def scan_string(string_boundary_charset = LINE_END) if skip(/\"/) return scan_double_quoted_string elsif skip(/\'/) return scan_single_quoted_string else return scan_nonquoted_string(string_boundary_charset) end end