summaryrefslogtreecommitdiffhomepage
path: root/src/scan.rb
blob: 9f9aedebc5daddc34d3301385ecda6aa0c5a3f44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require 'json'
require 'cast'

#file_to_scan = 'raylib.h'
module FelBind
  class Scan
    class << self
      # ctags --list-kinds=c
      # p  function prototypes
      # s  structure names
      # z  function parameters inside function or prototype definitions
      # m  struct, and union members
      def ctag(file)
        `ctags --output-format=json --c-kinds=pm --fields=+S --language-force=c #{file}`
      end
      #File.write('json.json', parse)
      #$garbage = []

      def param_strip(signature)
        signature[1...-1].split(',')
      end


      def parse_header(path)
        parse = `ctags --output-format=json --c-kinds=pm --fields=+S --language-force=c #{path}`
        structs = {}
        functions = {}
        failed = []
        parse.each_line do |line|
          json_line = JSON.parse line
          if json_line['kind'] == 'prototype'
            functions["#{json_line['typeref'].sub(/^[^ ][^ ]* /,'')} #{json_line['name']}"] = param_strip(json_line['signature'])
          elsif json_line['kind'] == 'member'
            if json_line['scopeKind'] == 'struct'
              structs[json_line['scope']] ||= []
              structs[json_line['scope']].push "#{json_line['typeref'].delete_prefix('typename:')} #{json_line['name']}"
            else
              failed.push json_line
            end
          elsif json_line['kind'] == 'struct'
            structs[json_line['name']] =  json_line
          else
            failed.push json_line
          end
        end
        [functions, structs, failed]
      end


      def debug_show(type, hash)
        puts "#{type.upcase}:"
        puts '---'
        hash.each do |key, params|
          puts "#{type.capitalize}: #{key}"
          params.each do |param|
            puts param
          end
          puts '---'
        end
        puts
      end

      def scan(file, destination)
        functions, structs, failed = parse_header(file)
        debug_show('functions', functions)
        debug_show('structs', structs)

        if !failed.empty?
          puts "-- Failed: --"
          pp failed
          puts
        end

        puts "Functions: #{functions.size}"
        puts "Structs:   #{structs.size}"
        puts "Failed:    #{failed.size}"
        puts

        result = [functions, structs]

        File.write(destination, JSON.generate(result))
      end
    end
  end
end