libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

main.rb (2238B)


      1 # frozen_string_literal: true
      2 
      3 require_relative '../ext/ffi-clang/lib/ffi/clang'
      4 require_relative '../tools/ci_lib'
      5 
      6 class Parser
      7   CLANG_VERSION = FFI::Clang.clang_version_string.match(/\d+\.\d+\.\d+/).match 0
      8   alias inspect to_s
      9 
     10   @@opts = %w(
     11     -std=c++17 -Wno-undefined-inline -Wno-undefined-internal -Wno-assume
     12   )
     13   clangdir = File.join ENV['PREFIX'] || '/usr', 'lib/clang', CLANG_VERSION
     14   if File.exist? File.join clangdir, 'include/stddef.h'
     15     @@opts << "-resource-dir=#{clangdir}"
     16   end
     17 
     18   def self.add_opts opts
     19     @@opts.concat opts
     20   end
     21 
     22   @@src = {}
     23   def self.add_src handlers, src
     24     src.each do |s|
     25       (@@src[s] ||= Set.new).merge handlers
     26     end
     27   end
     28   def self.src = @@src
     29 
     30   def self.gen_binding src, dst, args
     31     new.gen_binding src, dst, args
     32   end
     33 
     34   attr_reader :tu, :filter
     35 
     36   def parse src, args
     37     src_noext = src.gsub(/\.[^.]*$/, '')
     38     fname_map = {}
     39     @filter = ->c, parent do
     40       c.visit_children do |c2|
     41         if c2.kind == :annotate_attr && c2.spelling.start_with?('alias_file ')
     42           fname_map[c2.location.file] = c2.spelling[11..]
     43         end
     44         :break
     45       end
     46 
     47       loc = c.location.file or return true
     48       loc = fname_map[loc] || loc
     49       loc.gsub(/\.[^.]*$/, '') == src_noext
     50     end
     51 
     52     parse_tu src, args
     53   end
     54 
     55   def parse_tu fname, extra_opts
     56     index = FFI::Clang::Index.new
     57     @tu = index.parse_translation_unit fname, @@opts + extra_opts, [],
     58                                        %i(keep_going skip_function_bodies)
     59     @tu.diagnostics.each do |d|
     60       if d.severity == :error || d.severity == :fatal
     61         CI.eerror d.format
     62       else
     63         CI.ewarn d.format
     64       end
     65     end
     66     self
     67   end
     68 
     69   def gen dst
     70     dst.puts <<EOS
     71 // Auto generated code, do not edit. See gen_binding in project root.
     72 #ifndef LIBSHIT_BINDING_GENERATOR
     73 EOS
     74     @hs.each {|h| h.generate dst }
     75     dst.puts '#endif'
     76     self
     77   end
     78 
     79   def gen_binding src, dst, args
     80     dst ||= "#{src.sub /\.[^.]+\z/, ''}.binding.hpp"
     81     hs = @@src[src] or fail "Unknown source #{src.inspect}"
     82     parse src, args
     83     @hs = hs.map {|h| h.new self }
     84     @hs.each &:parse
     85 
     86     if dst == '-'
     87       gen $stdout
     88     else
     89       File.open(dst, 'w') {|f| gen f }
     90     end
     91     self
     92   end
     93 end