class Fluent::Config::V1Parser

Constants

ELEMENT_NAME
ELEM_SYMBOLS
RESERVED_PARAMS

Public Class Methods

new(strscan, include_basepath, fname, eval_context) click to toggle source
Calls superclass method Fluent::Config::LiteralParser.new
# File lib/fluent/config/v1_parser.rb, line 36
def initialize(strscan, include_basepath, fname, eval_context)
  super(strscan, eval_context)
  @include_basepath = include_basepath
  @fname = fname
end
parse(data, fname, basepath = Dir.pwd, eval_context = nil) click to toggle source
# File lib/fluent/config/v1_parser.rb, line 30
def self.parse(data, fname, basepath = Dir.pwd, eval_context = nil)
  ss = StringScanner.new(data)
  ps = V1Parser.new(ss, basepath, fname, eval_context)
  ps.parse!
end

Public Instance Methods

error_sample() click to toggle source

override

# File lib/fluent/config/v1_parser.rb, line 185
def error_sample
  "#{@fname} #{super}"
end
eval_include(attrs, elems, uri) click to toggle source
# File lib/fluent/config/v1_parser.rb, line 149
def eval_include(attrs, elems, uri)
  u = URI.parse(uri)
  if u.scheme == 'file' || (!u.scheme.nil? && u.scheme.length == 1) || u.path == uri # file path
    # When the Windows absolute path then u.scheme.length == 1
    # e.g. C:
    path = u.path
    if path[0] != ?/
      pattern = File.expand_path("#{@include_basepath}/#{path}")
    else
      pattern = path
    end
    Dir.glob(pattern).sort.each { |entry|
      basepath = File.dirname(entry)
      fname = File.basename(entry)
      data = File.read(entry)
      data.force_encoding('UTF-8')
      ss = StringScanner.new(data)
      V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
    }
  else
    require 'open-uri'
    basepath = '/'
    fname = path
    data = open(uri) { |f| f.read }
    data.force_encoding('UTF-8')
    ss = StringScanner.new(data)
    V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
  end

rescue SystemCallError => e
  cpe = ConfigParseError.new("include error #{uri}")
  cpe.set_backtrace(e.backtrace)
  raise cpe
end
parse!() click to toggle source
# File lib/fluent/config/v1_parser.rb, line 42
def parse!
  attrs, elems = parse_element(true, nil)
  root = Element.new('ROOT', '', attrs, elems)
  root.v1_config = true

  spacing
  unless eof?
    parse_error! "expected EOF"
  end

  return root
end
parse_element(root_element, elem_name, attrs = {}, elems = []) click to toggle source
# File lib/fluent/config/v1_parser.rb, line 58
def parse_element(root_element, elem_name, attrs = {}, elems = [])
  while true
    spacing
    if eof?
      if root_element
        break
      end
      parse_error! "expected end tag '</#{elem_name}>' but got end of file"
    end

    if skip(/\<\//)
      e_name = scan(ELEMENT_NAME)
      spacing
      unless skip(/\>/)
        parse_error! "expected character in tag name"
      end
      unless line_end
        parse_error! "expected end of line after end tag"
      end
      if e_name != elem_name
        parse_error! "unmatched end tag"
      end
      break

    elsif skip(/\</)
      e_name = scan(ELEMENT_NAME)
      spacing
      e_arg = scan_nonquoted_string(/(?:#{ZERO_OR_MORE_SPACING}\>)/)
      spacing
      unless skip(/\>/)
        parse_error! "expected '>'"
      end
      unless line_end
        parse_error! "expected end of line after tag"
      end
      e_arg ||= ''
      # call parse_element recursively
      e_attrs, e_elems = parse_element(false, e_name)
      new_e = Element.new(e_name, e_arg, e_attrs, e_elems)
      new_e.v1_config = true
      elems << new_e

    elsif root_element && skip(/(\@include|include)#{SPACING}/)
      if !prev_match.start_with?('@')
        $log.warn "'include' is deprecated. Use '@include' instead"
      end
      parse_include(attrs, elems)

    else
      k = scan_string(SPACING)
      spacing_without_comment
      if prev_match.include?("\n") || eof? # support 'tag_mapped' like "without value" configuration
        attrs[k] = ""
      else
        if k == '@include'
          parse_include(attrs, elems)
        elsif RESERVED_PARAMS.include?(k)
          v = parse_literal
          unless line_end
            parse_error! "expected end of line"
          end
          attrs[k] = v
        else
          if k.start_with?('@')
            if root_element || ELEM_SYMBOLS.include?(elem_name)
              parse_error! "'@' is the system reserved prefix. Don't use '@' prefix parameter in the configuration: #{k}"
            else
              # TODO: This is for backward compatibility. It will throw an error in the future.
              $log.warn "'@' is the system reserved prefix. It works in the nested configuration for now but it will be rejected: #{k}"
            end
          end

          v = parse_literal
          unless line_end
            parse_error! "expected end of line"
          end
          attrs[k] = v
        end
      end
    end
  end

  return attrs, elems
end
parse_include(attrs, elems) click to toggle source
# File lib/fluent/config/v1_parser.rb, line 143
def parse_include(attrs, elems)
  uri = scan_string(LINE_END)
  eval_include(attrs, elems, uri)
  line_end
end