mkprotos.rb 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/ruby
  2. class String
  3. def scan_for_structenum(target)
  4. scan(/(struct\s+\w+)/) do
  5. target[$1] = true
  6. end
  7. scan(/enum\((\w+)\)/) do
  8. target["enum #$1"] = true
  9. end
  10. end
  11. end
  12. class FuncDef
  13. attr_accessor :name,:files,:proto,:referenced
  14. def initialize(name,files,proto)
  15. @name = name
  16. @files = files
  17. @proto = proto
  18. @referenced = []
  19. end
  20. def to_s
  21. (files.length==1 ? files[0] : "{"+files.join(",")+"}")+":#{name} [[#{proto}]]"
  22. end
  23. def inspect
  24. "{{FuncDef #{to_s}}}"
  25. end
  26. def compatible?(oth)
  27. name==oth.name && proto==oth.proto
  28. end
  29. def static?
  30. proto =~ /^\bstatic\b/
  31. end
  32. end
  33. funcs = {}
  34. structenum = {}
  35. while x=gets
  36. if x !~ /^(\w+):(.*?):(.*)$/
  37. throw x
  38. else
  39. func = FuncDef.new($1,[$2],$3)
  40. if !func.static?
  41. func.proto.scan_for_structenum(structenum)
  42. name = func.name
  43. if funcs[name]
  44. if funcs[name].compatible?(func)
  45. funcs[name].files += func.files
  46. else
  47. $stderr.puts "conflict between #{funcs[name]} and #{func}"
  48. throw :conflict
  49. end
  50. else
  51. funcs[name] = func
  52. end
  53. end
  54. end
  55. end
  56. banlist = %w(debug isidch isalnum isdigit isspace unary declare nl Compile err_int warn_int error_do AP_app AP_about sUnpack)
  57. banlist.each do |name|
  58. funcs.delete(name)
  59. end
  60. class Union
  61. include Enumerable
  62. def initialize(*sets)
  63. @sets = sets
  64. end
  65. def each
  66. @sets.each do |set|
  67. set.each do |item|
  68. yield item
  69. end
  70. end
  71. end
  72. end
  73. Union.new(Dir['**/*.c']).each do |path|
  74. File.open(path) do |f|
  75. words = Hash.new 0
  76. f.each do |line|
  77. line.scan(/\w+/) do |word|
  78. if funcs[word]
  79. words[word] += 1
  80. end
  81. end
  82. end
  83. words.each do |word,count|
  84. if funcs[word].files != [path]
  85. funcs[word].referenced << path
  86. end
  87. end
  88. end
  89. end
  90. puts "// Auto-generated file, do not edit!"
  91. puts
  92. puts "#ifndef PROTOS_H_"
  93. puts "#define PROTOS_H_"
  94. puts
  95. structenum.keys.sort.each do |decl|
  96. puts "#{decl};"
  97. end
  98. puts
  99. funcs.each do |name,func|
  100. if !func.referenced.empty? || func.files!=["src/out68k_as.c"]
  101. puts func.proto
  102. end
  103. end
  104. puts
  105. puts "#endif"