class FFIDB::LibraryParser

Attributes

path[R]

Public Class Methods

new(path) click to toggle source

@param [Pathname, to_s] path

# File lib/ffidb/library_parser.rb, line 16
def initialize(path)
  @path = Pathname(path).freeze
end

Public Instance Methods

each_enum(&block) click to toggle source

@yield [enum] @yieldparam [enum] Enum @return [Enumerator]

# File lib/ffidb/library_parser.rb, line 33
def each_enum(&block)
  return self.to_enum(:each_enum) unless block_given?
  self.parse_yaml_dir(self.path, [:enum], &block)
end
each_function(&block) click to toggle source

@yield [function] @yieldparam [function] Function @return [Enumerator]

# File lib/ffidb/library_parser.rb, line 60
def each_function(&block)
  return self.to_enum(:each_function) unless block_given?
  self.parse_yaml_dir(self.path, [:function], &block)
end
each_struct(&block) click to toggle source

@yield [struct] @yieldparam [struct] Struct @return [Enumerator]

# File lib/ffidb/library_parser.rb, line 42
def each_struct(&block)
  return self.to_enum(:each_struct) unless block_given?
  self.parse_yaml_dir(self.path, [:struct], &block)
end
each_symbol(&block) click to toggle source

@yield [symbol] @yieldparam [symbol] Symbolic @return [Enumerator]

# File lib/ffidb/library_parser.rb, line 69
def each_symbol(&block)
  return self.to_enum(:each_symbol) unless block_given?
  self.parse_yaml_dir(self.path, nil, &block)
end
each_typedef(&block) click to toggle source

@yield [typedef] @yieldparam [symbol] Symbolic @return [Enumerator]

# File lib/ffidb/library_parser.rb, line 24
def each_typedef(&block)
  return self.to_enum(:each_typedef) unless block_given?
  self.parse_yaml_dir(self.path, [:typedef], &block)
end
each_union(&block) click to toggle source

@yield [union] @yieldparam [union] Union @return [Enumerator]

# File lib/ffidb/library_parser.rb, line 51
def each_union(&block)
  return self.to_enum(:each_union) unless block_given?
  self.parse_yaml_dir(self.path, [:union], &block)
end
parse_yaml_dir(path, kind_filter = nil, &block) click to toggle source

@param [Pathname] path @param [Array<Symbol>] kind_filter @yield [symbol] @yieldparam [symbol] Symbolic @return [void]

# File lib/ffidb/library_parser.rb, line 80
def parse_yaml_dir(path, kind_filter = nil, &block)
  self.path.glob('*.yaml') do |path|
    path.open do |file|
      self.parse_yaml_file(file, kind_filter, &block)
    end
  end
end
parse_yaml_file(file, kind_filter = nil) { |typedef(yaml, for, yaml)| ... } click to toggle source

@param [IO] file @param [Array<Symbol>] kind_filter @yield [symbol] @yieldparam [symbol] Symbolic @return [void]

# File lib/ffidb/library_parser.rb, line 94
def parse_yaml_file(file, kind_filter = nil, &block)
  Psych.parse_stream(file) do |yaml_doc|
    kind = yaml_doc.children.first.tag[1..-1].to_sym
    next if kind_filter && !kind_filter.include?(kind)
    yaml = yaml_doc.to_ruby.transform_keys!(&:to_sym)
    case kind
      when :typedef
        yield Typedef.new(yaml[:name], Type.for(yaml[:type]), yaml[:comment])
      when :enum
        yield Enum.new(yaml[:name], yaml[:values] || {}, yaml[:comment])
      when :struct
        fields = (yaml[:fields] || {}).inject({}) do |fs, (k, v)|
          fs[k.to_sym] = Type.for(v)
          fs
        end
        yield Struct.new(yaml[:name], fields, yaml[:comment])
      when :union
        yield Union.new(yaml[:name], yaml[:fields] || {}, yaml[:comment])
      when :function
        parameters = (yaml[:parameters] || {}).inject({}) do |ps, (k, v)|
          k = k.to_sym
          ps[k] = Parameter.new(k, Type.for(v))
          ps
        end
        yield Function.new(
          name: yaml[:name],
          type: Type.for(yaml[:type]),
          parameters: parameters,
          definition: !yaml.has_key?(:definition) ? nil : Location.new(
            file: yaml.dig(:definition, 'file'),
            line: yaml.dig(:definition, 'line'),
          ),
          comment: yaml[:comment],
        )
    end
  end
end