You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: struct_generator.rb
    path of file: ./repos/truffleruby/lib/truffle/ffi/tools
    
    the code of the file until where you have to start completion: require 'tempfile'

module FFI

  ##
  # Generates an FFI Struct layout.
  #
  # Given the @@@ portion in:
  #
  #   class Zlib::ZStream < FFI::Struct
  #     @@@
  #     name "struct z_stream_s"
  #     include "zlib.h"
  #
  #     field :next_in,   :pointer
  #     field :avail_in,  :uint
  #     field :total_in,  :ulong
  #
  #     # ...
  #     @@@
  #   end
  #
  # StructGenerator will create the layout:
  #
  #   layout :next_in, :pointer, 0,
  #          :avail_in, :uint, 4,
  #          :total_in, :ulong, 8,
  #          # ...
  #
  # StructGenerator does its best to pad the layout it produces to preserve
  # line numbers.  Place the struct definition as close to the top of the file
  # for best results.

  class StructGenerator
    @options = {}
    attr_accessor :size
    attr_reader   :fields

    def initialize(name, options = {})
      @name = name
      @struct_name = nil
      @includes = []
      @fields = []
      @found = false
      @size = nil

      if block_given? then
        yield self
        calculate self.class.options.merge(options)
      end
   
    
    def calculate(options = {})
      binary = File.join Dir.tmpdir, "rb_struct_gen_bin_#{Process.pid}"

      raise "struct name not set" if @struct_name.nil?

      Tempfile.open("#{@name}.struct_generator") do |f|
        f.puts "#include <stdio.h>"

        @includes.each do |inc|
          f.puts "#include <#{inc}>"
        end

        f.puts "#include <stddef.h>\n\n"
        f.puts "int main(int argc, char **argv)\n{"
        f.puts "  #{@struct_name} s;"
        f.puts %[  printf("sizeof(#{@struct_name}) %u\\n", (unsigned int) sizeof(#{@struct_name}));]

        @fields.each do |field|
          f.puts <<-EOF
    printf("#{field.name} %u %u\\n", (unsigned int) offsetof(#{@struct_name}, #{field.name}),
           (unsigned int) sizeof(s.#{field.name}));
  EOF
        end

        f.puts "\n  return 0;\n}"
        f.flush

        cc = ENV['CC'] || 'gcc'
        output = `#{cc} #{options[:cppflags]} #{options[:cflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary} 2>&1`

        unless $?.success? then
          @found = false
          output = output.split("\n").map { |l| "\t#{l}" }.join "\n"
          raise "Compilation error generating struct #{@name} (#{@struct_name}):\n#{output}"
        end
      end