summaryrefslogtreecommitdiffhomepage
path: root/scan.rb
blob: 38dd95ba8a8ff3d37bd12ab47262be3337ad679c (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
require 'json'

#file_to_scan = 'raylib.h'

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