Module: RubyHToGo::GoUtil

Defined in:
_tools/ruby_h_to_go/lib/ruby_h_to_go/go_util.rb

Overview

helper methods for generating go code

Constant Summary collapse

C_TYPE_TO_GO_TYPE =
{
  "RUBY_DATA_FUNC"     => "unsafe.Pointer",
  "long long"          => "Longlong",
  "rb_alloc_func_t"    => "unsafe.Pointer",
  "unsigned char"      => "Uchar",
  "unsigned int"       => "uint",
  "unsigned long"      => "uint",
  "unsigned long long" => "Ulonglong",
  "unsigned short"     => "Ushort",
}.freeze
C_TYPE_TO_CGO_TYPE =
{
  "RUBY_DATA_FUNC"       => "toCFunctionPointer",
  "long long"            => "C.longlong",
  "rb_io_wait_readwrite" => "C.enum_rb_io_wait_readwrite",
  "ruby_value_type"      => "C.enum_ruby_value_type",
  "unsigned char"        => "C.uchar",
  "unsigned int"         => "C.uint",
  "unsigned long"        => "C.ulong",
  "unsigned long long"   => "C.ulonglong",
  "unsigned short"       => "C.ushort",
  "st_hash_type"         => "C.struct_st_hash_type",
  "timespec"             => "C.struct_timespec",
  "timeval"              => "C.struct_timeval",
}.freeze

Class Method Summary collapse

Class Method Details

.cast_to_cgo_type(typename) ⇒ String

Cast C type to cgo type. (Used in wrapper function)

Parameters:

  • typename (String)

Returns:

  • (String)


115
116
117
118
119
# File '_tools/ruby_h_to_go/lib/ruby_h_to_go/go_util.rb', line 115

def self.cast_to_cgo_type(typename)
  return C_TYPE_TO_CGO_TYPE[typename] if C_TYPE_TO_CGO_TYPE[typename]

  "C.#{typename}"
end

.generate_initial_go_file(go_file_path) ⇒ Object

Generate initial go file whether not exists

Parameters:

  • go_file_path (String)


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
# File '_tools/ruby_h_to_go/lib/ruby_h_to_go/go_util.rb', line 16

def self.generate_initial_go_file(go_file_path) # rubocop:disable Metrics/MethodLength
  return if File.exist?(go_file_path)

  header = +<<~GO
    // THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS.

    // WARNING: This file has automatically been generated
    // Code generated by ruby_h_to_go. DO NOT EDIT.

  GO

  ruby_build_tag = GoGem::Util.ruby_minor_version_build_tag

  header <<
    if ruby_build_tag == RubyHToGo.config.default_tag
      other_tags = RubyHToGo.config.available_tags - [RubyHToGo.config.default_tag]
      condition = other_tags.map { |tag| "!#{tag}" }.join(" && ")

      <<~GO
        // FIXME: https://pkg.go.dev/ doesn't support custom build tag.
        //        Therefore, if no build tag is passed, treat it as the default tag
        //go:build #{ruby_build_tag} || (#{condition})

      GO
    else
      <<~GO
        //go:build #{ruby_build_tag}

      GO
    end

  header << <<~GO
    package ruby

    /*
    #include "ruby.h"
    */
    import "C"

    import (
      "unsafe"
    )

  GO

  File.binwrite(go_file_path, header)
end

.ruby_c_type_to_go_type(typename, pos: nil, pointer: nil, pointer_length: 0) ⇒ String

Convert C type to Go type. (used in wrapper function args and return type etc)

Parameters:

  • typename (String)
  • pos (Symbol, nil) (defaults to: nil)

    :arg, :typeref, :return

  • pointer (Symbol, nil) (defaults to: nil)

    pointer hint (:ref, :array, :ref_array, :function, :sref, :str_array, :in_ref, :raw)

  • pointer_length (Integer) (defaults to: 0)

Returns:

  • (String)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File '_tools/ruby_h_to_go/lib/ruby_h_to_go/go_util.rb', line 81

def self.ruby_c_type_to_go_type(typename, pos: nil, pointer: nil, pointer_length: 0)
  return ruby_pointer_c_type_to_go_type(typename, pos:, pointer:, pointer_length:) if pointer

  return C_TYPE_TO_GO_TYPE[typename] if C_TYPE_TO_GO_TYPE[typename]

  case typename
  when /^[A-Z]+$/, "int"
    # e.g. VALUE
    return typename
  when "void"
    return "unsafe.Pointer" if pointer == :ref && type == :typeref
  end

  snake_to_camel(typename)
end

.snake_to_camel(str) ⇒ String

Parameters:

  • str (String)

Returns:

  • (String)


8
9
10
11
12
# File '_tools/ruby_h_to_go/lib/ruby_h_to_go/go_util.rb', line 8

def self.snake_to_camel(str)
  return str if %w[VALUE ID].include?(str)

  str.split("_").map(&:capitalize).join.gsub(/(?<=\d)([a-z])/) { _1.upcase } # rubocop:disable Style/SymbolProc
end