enums.rb 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env ruby
  2. require "rtruckboris"
  3. require "active_support/inflector"
  4. PATH = File.expand_path(File.dirname(__FILE__))
  5. require "#{PATH}/binder"
  6. def to_snake_case(camel_cased_word)
  7. return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
  8. word = camel_cased_word.to_s.gsub(/::/, '/')
  9. word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{ActiveSupport::Inflector.inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" }
  10. word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
  11. word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
  12. word.tr!("-", "_")
  13. word
  14. end
  15. def rename_enum_constant(enum_name, enum_constant)
  16. new_name = enum_constant.gsub(/CX[^\_]*\_/,"")
  17. new_name = to_snake_case(new_name)
  18. new_name.upcase
  19. end
  20. def create_module_constant(main_module, enum)
  21. name = enum.name == "" ? enum.typedef_name : enum.name
  22. enum_module_name = name.gsub(/^CX\_?/,"")
  23. c_value_enum_module_name = "m_#{enum_module_name}"
  24. s="VALUE #{c_value_enum_module_name} = rb_define_module_under(#{main_module},\"#{enum_module_name}\");\n"
  25. enum.enum_constants.each do |c|
  26. s+= "rb_define_const(#{c_value_enum_module_name},\"#{rename_enum_constant(name, c.name)}\", INT2NUM(#{c.value}));\n"
  27. end
  28. s
  29. end
  30. def create_module_constants(main_module, enums, id = nil )
  31. id = id ? "_" + id : ""
  32. s="void init_clang#{id}_enums_to_constants(VALUE #{main_module}){\n"
  33. enums.each_with_index do |e, i|
  34. s+="#{create_module_constant(main_module, e)}\n"
  35. end
  36. s+="}\n"
  37. end
  38. headerPaths = []
  39. #get gcc include if needed
  40. gccLibBase='/usr/lib/gcc/' << `llvm-config --host-target`.chomp << "/*"
  41. gccLib = Dir.glob(gccLibBase ).sort.last + "/include"
  42. headerPaths << gccLib
  43. headerPaths << "/usr/include"
  44. headerPaths << "/usr/include/clang-c"
  45. clang_c = "/usr/include/clang-c/Index.h"
  46. parser = Rtruckboris::HeaderParser.new(clang_c, headerPaths)
  47. if(!parser.parse(true))
  48. puts "Whada fock??"
  49. exit
  50. end
  51. enums = parser.enums
  52. constants = Binder::OutputFiles.new("constants")
  53. constants._h.puts <<EOF
  54. #include <ruby/ruby.h>
  55. void
  56. init_clang_enums_to_constants(VALUE);
  57. EOF
  58. constants._c.puts "#include \"constants.h\"\n"
  59. constants._c.puts create_module_constants("m_clang", enums)
  60. clang_c = "/usr/include/clang-c/CXErrorCode.h"
  61. parser = Rtruckboris::HeaderParser.new(clang_c, headerPaths)
  62. if(!parser.parse(true))
  63. puts "Whada fock??"
  64. exit
  65. end
  66. enums = parser.enums
  67. constants._h.puts <<EOF
  68. void
  69. init_clang_errors_enums_to_constants(VALUE);
  70. EOF
  71. constants._c.puts create_module_constants("m_clang", enums, "errors")
  72. constants.close_all