This file is indexed.

/usr/lib/ruby/vendor_ruby/gir_ffi/builders/argument_builder.rb is in ruby-gir-ffi 0.9.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 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
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
require 'gir_ffi/builders/base_argument_builder'
require 'gir_ffi/builders/closure_to_pointer_convertor'
require 'gir_ffi/builders/full_c_to_ruby_convertor'
require 'gir_ffi/builders/ruby_to_c_convertor'
require 'gir_ffi/builders/null_convertor'

module GirFFI
  module Builders
    # Implements building pre- and post-processing statements for arguments.
    class ArgumentBuilder < BaseArgumentBuilder
      def method_argument_name
        name if has_input_value? && !helper_argument?
      end

      # TODO: Improve this so each method can only have one block argument.
      def block_argument?
        specialized_type_tag == :callback
      end

      def post_converted_name
        @post_converted_name ||= if has_post_conversion?
                                   new_variable
                                 else
                                   call_argument_name
                                 end
      end

      def return_value_name
        if has_output_value?
          post_converted_name unless array_length_parameter?
        end
      end

      def capture_variable_name
        nil
      end

      def pre_conversion
        pr = []
        case direction
        when :in
          pr << fixed_array_size_check if needs_size_check?
          pr << array_length_assignment if array_length_parameter?
          pr << "#{call_argument_name} = #{ingoing_convertor.conversion}"
        when :inout
          pr << fixed_array_size_check if needs_size_check?
          pr << array_length_assignment if array_length_parameter?
          pr << out_parameter_preparation
          pr << "#{call_argument_name}.set_value #{ingoing_convertor.conversion}"
        when :out
          pr << out_parameter_preparation
        end
        pr
      end

      def post_conversion
        if has_post_conversion?
          value = output_value
          ["#{post_converted_name} = #{value}"]
        else
          []
        end
      end

      private

      def has_post_conversion?
        has_output_value? && (!caller_allocated_object? || gvalue?)
      end

      def output_value
        if caller_allocated_object? && gvalue?
          return "#{call_argument_name}.get_value"
        end
        base = "#{call_argument_name}.to_value"
        if needs_out_conversion?
          FullCToRubyConvertor.new(@type_info, base, length_argument_name).conversion
        elsif allocated_by_them?
          "GirFFI::InOutPointer.new(#{type_info.tag_or_class[1].inspect}, #{base}).to_value"
        else
          base
        end
      end

      def needs_out_conversion?
        @type_info.needs_c_to_ruby_conversion_for_functions?
      end

      def gvalue?
        @type_info.gvalue?
      end

      # Check if an out argument needs to be allocated by them, the callee. Since
      # caller_allocates is false by default, we must also check that the type
      # is a pointer. For example, an out parameter of type gint8* will always
      # be allocated by the caller (that's us).
      def allocated_by_them?
        !@arginfo.caller_allocates? && @type_info.pointer?
      end

      def length_argument_name
        length_arg && length_arg.post_converted_name
      end

      def needs_size_check?
        specialized_type_tag == :c && type_info.array_fixed_size > -1
      end

      def fixed_array_size_check
        size = type_info.array_fixed_size
        "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{name}, \"#{name}\""
      end

      def skipped?
        @arginfo.skip? ||
          @array_arg && @array_arg.specialized_type_tag == :strv
      end

      def has_output_value?
        (direction == :inout || direction == :out) && !skipped?
      end

      def has_input_value?
        (direction == :inout || direction == :in) && !skipped?
      end

      def array_length_assignment
        arrname = @array_arg.name
        "#{name} = #{arrname}.nil? ? 0 : #{arrname}.length"
      end

      def out_parameter_preparation
        value = if caller_allocated_object?
                  if specialized_type_tag == :array
                    "#{argument_class_name}.new #{type_info.element_type.inspect}"
                  else
                    "#{argument_class_name}.new"
                  end
                else
                  "GirFFI::InOutPointer.for #{type_info.tag_or_class.inspect}"
                end
        "#{call_argument_name} = #{value}"
      end

      def caller_allocated_object?
        [:struct, :array].include?(specialized_type_tag) &&
          @arginfo.caller_allocates?
      end

      DESTROY_NOTIFIER = 'GLib::DestroyNotify.default'

      def ingoing_convertor
        if skipped?
          NullConvertor.new('0')
        elsif destroy_notifier?
          NullConvertor.new(DESTROY_NOTIFIER)
        elsif closure?
          ClosureToPointerConvertor.new(pre_convertor_argument, @is_closure)
        elsif @type_info.needs_ruby_to_c_conversion_for_functions?
          RubyToCConvertor.new(@type_info, pre_convertor_argument)
        else
          NullConvertor.new(pre_convertor_argument)
        end
      end

      def pre_convertor_argument
        if ownership_transfer == :everything && specialized_type_tag == :object
          "#{name}.ref"
        else
          name
        end
      end
    end
  end
end