summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools
diff options
context:
space:
mode:
authorBen Sanders <ben@sanders.life>2026-08-02 09:49:25 -0400
committerBen Sanders <ben@sanders.life>2026-08-02 09:49:25 -0400
commitb41479c91e6685511c1f8ba8586106b322073b62 (patch)
treec9f1345999d754ae0a533849966427e792d9e68d /vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools
parentcfaceeb9a6d1295f5754be211858155cd309acc2 (diff)
added statscounter code
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools')
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb232
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb105
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb32
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb195
4 files changed, 564 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb
new file mode 100644
index 0000000..70ba9c2
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb
@@ -0,0 +1,232 @@
+require 'tempfile'
+require 'open3'
+
+module FFI
+
+ # ConstGenerator turns C constants into ruby values.
+ #
+ # @example a simple example for stdio
+ # require 'ffi/tools/const_generator'
+ # cg = FFI::ConstGenerator.new('stdio') do |gen|
+ # gen.const(:SEEK_SET)
+ # gen.const('SEEK_CUR')
+ # gen.const('seek_end') # this constant does not exist
+ # end # #calculate called automatically at the end of the block
+ #
+ # cg['SEEK_SET'] # => 0
+ # cg['SEEK_CUR'] # => 1
+ # cg['seek_end'] # => nil
+ # cg.to_ruby # => "SEEK_SET = 0\nSEEK_CUR = 1\n# seek_end not available"
+ class ConstGenerator
+ @options = {}
+ attr_reader :constants
+
+ # Creates a new constant generator that uses +prefix+ as a name, and an
+ # options hash.
+ #
+ # The only option is +:required+, which if set to +true+ raises an error if a
+ # constant you have requested was not found.
+ #
+ # @param [#to_s] prefix
+ # @param [Hash] options
+ # @return
+ # @option options [Boolean] :required
+ # @overload initialize(prefix, options)
+ # @overload initialize(prefix, options) { |gen| ... }
+ # @yieldparam [ConstGenerator] gen new generator is passed to the block
+ # When passed a block, {#calculate} is automatically called at the end of
+ # the block, otherwise you must call it yourself.
+ def initialize(prefix = nil, options = {})
+ @includes = ['stdio.h', 'stddef.h']
+ @constants = {}
+ @prefix = prefix
+
+ @required = options[:required]
+ @options = options
+
+ if block_given? then
+ yield self
+ calculate self.class.options.merge(options)
+ end
+ end
+ # Set class options
+ # These options are merged with {#initialize} options when it is called with a block.
+ # @param [Hash] options
+ # @return [Hash] class options
+ def self.options=(options)
+ @options = options
+ end
+ # Get class options.
+ # @return [Hash] class options
+ def self.options
+ @options
+ end
+ # @param [String] name
+ # @return constant value (converted if a +converter+ was defined).
+ # Access a constant by name.
+ def [](name)
+ @constants[name].converted_value
+ end
+
+ # Request the value for C constant +name+.
+ #
+ # @param [#to_s] name C constant name
+ # @param [String] format a printf format string to print the value out
+ # @param [String] cast a C cast for the value
+ # @param ruby_name alternate ruby name for {#to_ruby}
+ #
+ # @overload const(name, format=nil, cast='', ruby_name=nil, converter=nil)
+ # +converter+ is a Method or a Proc.
+ # @param [#call] converter convert the value from a string to the appropriate
+ # type for {#to_ruby}.
+ # @overload const(name, format=nil, cast='', ruby_name=nil) { |value| ... }
+ # Use a converter block. This block convert the value from a string to the
+ # appropriate type for {#to_ruby}.
+ # @yieldparam value constant value
+ def const(name, format = nil, cast = '', ruby_name = nil, converter = nil,
+ &converter_proc)
+ format ||= '%d'
+ cast ||= ''
+
+ if converter_proc and converter then
+ raise ArgumentError, "Supply only converter or converter block"
+ end
+
+ converter = converter_proc if converter.nil?
+
+ const = Constant.new name, format, cast, ruby_name, converter
+ @constants[name.to_s] = const
+ return const
+ end
+
+ # Calculate constants values.
+ # @param [Hash] options
+ # @option options [String] :cppflags flags for C compiler
+ # @return [nil]
+ # @raise if a constant is missing and +:required+ was set to +true+ (see {#initialize})
+ def calculate(options = {})
+ binary_path = nil
+
+ Tempfile.open("#{@prefix}.const_generator") do |f|
+ binary_path = f.path + ".bin"
+ @includes.each do |inc|
+ f.puts "#include <#{inc}>"
+ end
+ f.puts "\nint main(int argc, char **argv)\n{"
+
+ @constants.each_value do |const|
+ f.puts <<-EOF
+ #ifdef #{const.name}
+ printf("#{const.name} #{const.format}\\n", #{const.cast}#{const.name});
+ #endif
+ EOF
+ end
+
+ f.puts "\n\treturn 0;\n}"
+ f.flush
+
+ cc = ENV['CC'] || 'gcc'
+ output = `#{cc} #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary_path} 2>&1`
+
+ unless $?.success? then
+ output = output.split("\n").map { |l| "\t#{l}" }.join "\n"
+ raise "Compilation error generating constants #{@prefix}:\n#{output}"
+ end
+ end
+
+ output = `#{binary_path}`
+ File.unlink(binary_path + (FFI::Platform.windows? ? ".exe" : ""))
+ output.each_line do |line|
+ line =~ /^(\S+)\s(.*)$/
+ const = @constants[$1]
+ const.value = $2
+ end
+
+ missing_constants = @constants.select do |name, constant|
+ constant.value.nil?
+ end.map { |name,| name }
+
+ if @required and not missing_constants.empty? then
+ raise "Missing required constants for #{@prefix}: #{missing_constants.join ', '}"
+ end
+ end
+
+ # Dump constants to +io+.
+ # @param [#puts] io
+ # @return [nil]
+ def dump_constants(io)
+ @constants.each do |name, constant|
+ name = [@prefix, name].join '.' if @prefix
+ io.puts "#{name} = #{constant.converted_value}"
+ end
+ end
+
+ # Outputs values for discovered constants. If the constant's value was
+ # not discovered it is not omitted.
+ # @return [String]
+ def to_ruby
+ @constants.sort_by { |name,| name }.map do |name, constant|
+ if constant.value.nil? then
+ "# #{name} not available"
+ else
+ constant.to_ruby
+ end
+ end.join "\n"
+ end
+
+ # Add additional C include file(s) to calculate constants from.
+ # @note +stdio.h+ and +stddef.h+ automatically included
+ # @param [List<String>, Array<String>] i include file(s)
+ # @return [Array<String>] array of include files
+ def include(*i)
+ @includes |= i.flatten
+ end
+
+ end
+
+ # This class hold constants for {ConstGenerator}
+ class ConstGenerator::Constant
+
+ attr_reader :name, :format, :cast
+ attr_accessor :value
+
+ # @param [#to_s] name
+ # @param [String] format a printf format string to print the value out
+ # @param [String] cast a C cast for the value
+ # @param ruby_name alternate ruby name for {#to_ruby}
+ # @param [#call] converter convert the value from a string to the appropriate
+ # type for {#to_ruby}.
+ def initialize(name, format, cast, ruby_name = nil, converter=nil)
+ @name = name
+ @format = format
+ @cast = cast
+ @ruby_name = ruby_name
+ @converter = converter
+ @value = nil
+ end
+
+ # Return constant value (converted if a +converter+ was defined).
+ # @return constant value.
+ def converted_value
+ if @converter
+ @converter.call(@value)
+ else
+ @value
+ end
+ end
+
+ # get constant ruby name
+ # @return [String]
+ def ruby_name
+ @ruby_name || @name
+ end
+
+ # Get an evaluable string from constant.
+ # @return [String]
+ def to_ruby
+ "#{ruby_name} = #{converted_value}"
+ end
+
+ end
+
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb
new file mode 100644
index 0000000..5552ea5
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb
@@ -0,0 +1,105 @@
+require 'ffi/tools/struct_generator'
+require 'ffi/tools/const_generator'
+
+module FFI
+
+ ##
+ # Generate files with C structs for FFI::Struct and C constants.
+ #
+ # == A simple example
+ #
+ # In file +zlib.rb.ffi+:
+ # module Zlib
+ # @@@
+ # constants do |c|
+ # c.include "zlib.h"
+ # c.const :ZLIB_VERNUM
+ # end
+ # @@@
+ #
+ # class ZStream < FFI::Struct
+ #
+ # struct do |s|
+ # s.name "struct z_stream_s"
+ # s.include "zlib.h"
+ #
+ # s.field :next_in, :pointer
+ # s.field :avail_in, :uint
+ # s.field :total_in, :ulong
+ # end
+ # @@@
+ # end
+ # end
+ #
+ # Translate the file:
+ # require "ffi/tools/generator"
+ # FFI::Generator.new "zlib.rb.ffi", "zlib.rb"
+ #
+ # Generates the file +zlib.rb+ with constant values and offsets:
+ # module Zlib
+ # ZLIB_VERNUM = 4784
+ #
+ # class ZStream < FFI::Struct
+ # layout :next_in, :pointer, 0,
+ # :avail_in, :uint, 8,
+ # :total_in, :ulong, 16
+ # end
+ #
+ # @see FFI::Generator::Task for easy integration in a Rakefile
+ class Generator
+
+ def initialize(ffi_name, rb_name, options = {})
+ @ffi_name = ffi_name
+ @rb_name = rb_name
+ @options = options
+ @name = File.basename rb_name, '.rb'
+
+ file = File.read @ffi_name
+
+ new_file = file.gsub(/^( *)@@@(.*?)@@@/m) do
+ @constants = []
+ @structs = []
+
+ indent = $1
+ original_lines = $2.count "\n"
+
+ instance_eval $2, @ffi_name, $`.count("\n")
+
+ new_lines = []
+ @constants.each { |c| new_lines << c.to_ruby }
+ @structs.each { |s| new_lines << s.generate_layout }
+
+ new_lines = new_lines.join("\n").split "\n" # expand multiline blocks
+ new_lines = new_lines.map { |line| indent + line }
+
+ padding = original_lines - new_lines.length
+ new_lines += [nil] * padding if padding >= 0
+
+ new_lines.join "\n"
+ end
+
+ open @rb_name, 'w' do |f|
+ f.puts "# This file is generated from `#{@ffi_name}'. Do not edit."
+ f.puts
+ f.puts new_file
+ end
+ end
+
+ def constants(options = {}, &block)
+ @constants << FFI::ConstGenerator.new(@name, @options.merge(options), &block)
+ end
+
+ def struct(options = {}, &block)
+ @structs << FFI::StructGenerator.new(@name, @options.merge(options), &block)
+ end
+
+ ##
+ # Utility converter for constants
+
+ def to_s
+ proc { |obj| obj.to_s.inspect }
+ end
+
+ end
+end
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb
new file mode 100644
index 0000000..da72968
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb
@@ -0,0 +1,32 @@
+require 'ffi/tools/generator'
+require 'rake'
+require 'rake/tasklib'
+
+##
+# Add Rake tasks that generate files with C structs for FFI::Struct and C constants.
+#
+# @example a simple example for your Rakefile
+# require "ffi/tools/generator_task"
+# # Add a task to generate my_object.rb out of my_object.rb.ffi
+# FFI::Generator::Task.new ["my_object.rb"], cflags: "-I/usr/local/mylibrary"
+#
+# The generated files are also added to the 'clear' task.
+#
+# @see FFI::Generator for a description of the file content
+class FFI::Generator::Task < Rake::TaskLib
+
+ def initialize(rb_names, options={})
+ task :clean do rm_f rb_names end
+
+ rb_names.each do |rb_name|
+ ffi_name = "#{rb_name}.ffi"
+
+ file rb_name => ffi_name do |t|
+ puts "Generating #{rb_name}..." if Rake.application.options.trace
+
+ FFI::Generator.new ffi_name, rb_name, options
+ end
+ end
+ end
+
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb
new file mode 100644
index 0000000..3a951c3
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb
@@ -0,0 +1,195 @@
+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
+ end
+ def self.options=(options)
+ @options = options
+ end
+ def self.options
+ @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
+
+ output = `#{binary}`.split "\n"
+ File.unlink(binary + (FFI::Platform.windows? ? ".exe" : ""))
+ sizeof = output.shift
+ unless @size
+ m = /\s*sizeof\([^)]+\) (\d+)/.match sizeof
+ @size = m[1]
+ end
+
+ line_no = 0
+ output.each do |line|
+ md = line.match(/.+ (\d+) (\d+)/)
+ @fields[line_no].offset = md[1].to_i
+ @fields[line_no].size = md[2].to_i
+
+ line_no += 1
+ end
+
+ @found = true
+ end
+
+ def field(name, type=nil)
+ field = Field.new(name, type)
+ @fields << field
+ return field
+ end
+
+ def found?
+ @found
+ end
+
+ def dump_config(io)
+ io.puts "rbx.platform.#{@name}.sizeof = #{@size}"
+
+ @fields.each { |field| io.puts field.to_config(@name) }
+ end
+
+ def generate_layout
+ buf = ""
+
+ @fields.each_with_index do |field, i|
+ if buf.empty?
+ buf << "layout :#{field.name}, :#{field.type}, #{field.offset}"
+ else
+ buf << " :#{field.name}, :#{field.type}, #{field.offset}"
+ end
+
+ if i < @fields.length - 1
+ buf << ",\n"
+ end
+ end
+
+ buf
+ end
+
+ def get_field(name)
+ @fields.find { |f| name == f.name }
+ end
+
+ def include(i)
+ @includes << i
+ end
+
+ def name(n)
+ @struct_name = n
+ end
+
+ end
+
+ ##
+ # A field in a Struct.
+
+ class StructGenerator::Field
+
+ attr_reader :name
+ attr_reader :type
+ attr_reader :offset
+ attr_accessor :size
+
+ def initialize(name, type)
+ @name = name
+ @type = type
+ @offset = nil
+ @size = nil
+ end
+
+ def offset=(o)
+ @offset = o
+ end
+
+ def to_config(name)
+ buf = []
+ buf << "rbx.platform.#{name}.#{@name}.offset = #{@offset}"
+ buf << "rbx.platform.#{name}.#{@name}.size = #{@size}"
+ buf << "rbx.platform.#{name}.#{@name}.type = #{@type}" if @type
+ buf
+ end
+
+ end
+
+end
+