gobject-introspection 3.4.0 → 3.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gobject-introspection/extconf.rb +1 -4
  3. data/ext/gobject-introspection/rb-gi-argument.c +10 -3
  4. data/ext/gobject-introspection/rb-gi-arguments-in.c +82 -122
  5. data/ext/gobject-introspection/rb-gi-arguments-out.c +31 -11
  6. data/ext/gobject-introspection/rb-gi-arguments.c +217 -18
  7. data/ext/gobject-introspection/rb-gi-base-info.c +11 -1
  8. data/ext/gobject-introspection/rb-gi-callable-info.c +10 -2
  9. data/ext/gobject-introspection/rb-gi-callback.c +156 -2
  10. data/ext/gobject-introspection/rb-gi-conversions.h +6 -6
  11. data/ext/gobject-introspection/rb-gi-interface-info.c +1 -7
  12. data/ext/gobject-introspection/rb-gi-loader.c +58 -10
  13. data/ext/gobject-introspection/rb-gi-object-info.c +11 -1
  14. data/ext/gobject-introspection/rb-gi-private-arguments-in.h +3 -1
  15. data/ext/gobject-introspection/rb-gi-private-arguments.h +6 -2
  16. data/ext/gobject-introspection/rb-gi-private-callback.h +6 -3
  17. data/ext/gobject-introspection/rb-gi-private.h +1 -0
  18. data/ext/gobject-introspection/rb-gi-repository.c +1 -1
  19. data/ext/gobject-introspection/rb-gi-struct-info.c +15 -3
  20. data/ext/gobject-introspection/rb-gi-vfunc-info.c +2 -2
  21. data/ext/gobject-introspection/rb-gobject-introspection.c +231 -0
  22. data/lib/gobject-introspection/loader.rb +66 -2
  23. data/lib/gobject-introspection/type-tag.rb +2 -0
  24. data/test/gobject-introspection-test-utils.rb +2 -2
  25. data/test/run-test.rb +18 -25
  26. data/test/test-base-info.rb +5 -1
  27. data/test/test-callable-info.rb +16 -2
  28. data/test/test-loader.rb +53 -7
  29. data/test/test-object-info.rb +5 -1
  30. data/test/test-struct-info.rb +6 -1
  31. metadata +5 -8
  32. data/ext/gobject-introspection/gobject-introspection-enum-types.c +0 -230
  33. data/ext/gobject-introspection/gobject-introspection-enum-types.h +0 -42
  34. data/ext/gobject-introspection/rbgiversion.h +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 439904c07c9ece750e11324a9e7220e92703960c464e3096b592b4a0c60089ed
4
- data.tar.gz: 43364a70a42e79df745fa61912d528b47442025f42b7456ee950dbcad7b259e6
3
+ metadata.gz: '073080df7a1c63c600038ca2b3f5edce7e4b090c580b530bed49ab72afc02310'
4
+ data.tar.gz: 9cb1dd9c3f5badc0c0a917206d42d18783626db421a701a8737fa7398c7cefa5
5
5
  SHA512:
6
- metadata.gz: 96504ea3a2364df9625cf2b3846479f07cf0dbea4aeb81b5761aca751959476db272a15479c64d244ad72ab77f0b21698a3896ebec0efb1bdac56cc2f444958d
7
- data.tar.gz: 9b8b9e7ad2545423e95baa93241ba7ac4679cf5e5871361ffe58f503f3abb4b8997da90d2e85ec17423ead5abe80aa2a54b4ca6c6d1d024fd399bc67be0d157f
6
+ metadata.gz: 8e0ca0522ffbc58c6276455fb7d27c90afc1d959881af569c63b17607bd46cb6fca3463a74699ac1b8f244ec159d5c09edd736eb67641631ed5da48cebff4c8f
7
+ data.tar.gz: f2d8856c0cb47cf65cd54753a2d0dcad71a4c2519a64ccd5a9f515ba5c8eb42dfe6dea034f7498ca8eeac438e79b83ff84bae139bcc7e799693f55aeb43347b7
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (C) 2012-2019 Ruby-GNOME Project Team
3
+ # Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  #
5
5
  # This library is free software; you can redistribute it and/or
6
6
  # modify it under the terms of the GNU Lesser General Public
@@ -62,9 +62,6 @@ end
62
62
  # TODO: Remove this when we dropped support for GObject Introspection < 1.60
63
63
  make_version_header("GI", package_id, ".")
64
64
 
65
- gi_headers = ["girepository.h"]
66
- have_func("g_interface_info_find_signal", gi_headers)
67
-
68
65
  enum_type_prefix = "gobject-introspection-enum-types"
69
66
  include_paths = PKGConfig.cflags_only_I(package_id)
70
67
  headers = include_paths.split.inject([]) do |result, path|
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012-2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -2011,11 +2011,18 @@ rb_gi_return_argument_to_ruby(GICallableInfo *callable_info,
2011
2011
  GITypeInfo return_value_info;
2012
2012
 
2013
2013
  may_return_null = g_callable_info_may_return_null(callable_info);
2014
+ g_callable_info_load_return_type(callable_info, &return_value_info);
2014
2015
  if (may_return_null && !argument->v_pointer) {
2015
- return Qnil;
2016
+ GITypeTag return_value_tag = g_type_info_get_tag(&return_value_info);
2017
+ switch (return_value_tag) {
2018
+ case GI_TYPE_TAG_GLIST:
2019
+ case GI_TYPE_TAG_GSLIST:
2020
+ return rb_ary_new();
2021
+ default:
2022
+ return Qnil;
2023
+ }
2016
2024
  }
2017
2025
 
2018
- g_callable_info_load_return_type(callable_info, &return_value_info);
2019
2026
  rb_argument = rb_gi_argument_to_ruby(argument, FALSE, &return_value_info,
2020
2027
  in_args, out_args, args_metadata);
2021
2028
  switch (g_callable_info_get_caller_owns(callable_info)) {
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012-2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -27,13 +27,7 @@ rb_gi_callback_data_destroy_notify(gpointer data)
27
27
  rb_gi_callback_data_free(callback_data);
28
28
  }
29
29
 
30
- typedef struct {
31
- RBGIArguments *args;
32
- RBGICallback *callback;
33
- RBGICallbackData *callback_data;
34
- } RBGICallbackInvokeData;
35
-
36
- static VALUE
30
+ VALUE
37
31
  rb_gi_arguments_in_to_ruby(RBGIArguments *args)
38
32
  {
39
33
  VALUE rb_in_args;
@@ -68,85 +62,6 @@ rb_gi_arguments_in_to_ruby(RBGIArguments *args)
68
62
  return rb_in_args;
69
63
  }
70
64
 
71
- static VALUE
72
- rb_gi_callback_invoke(VALUE user_data)
73
- {
74
- RBGICallbackInvokeData *data = (RBGICallbackInvokeData *)user_data;
75
- ID id_call;
76
- VALUE rb_callback = rb_gi_callback_data_get_rb_callback(data->callback_data);
77
- VALUE rb_args = rb_gi_arguments_in_to_ruby(data->args);
78
-
79
- CONST_ID(id_call, "call");
80
- return rb_funcallv(rb_callback,
81
- id_call,
82
- RARRAY_LENINT(rb_args),
83
- RARRAY_CONST_PTR(rb_args));
84
- }
85
-
86
- static void
87
- rb_gi_ffi_closure_callback(G_GNUC_UNUSED ffi_cif *cif,
88
- void *return_value,
89
- void **raw_args,
90
- void *data)
91
- {
92
- RBGICallback *callback = data;
93
- RBGICallbackData *callback_data = NULL;
94
- RBGIArguments args;
95
- VALUE rb_results;
96
-
97
- rb_gi_arguments_init(&args,
98
- callback->callback_info,
99
- Qnil,
100
- Qnil,
101
- raw_args);
102
- {
103
- guint i;
104
-
105
- for (i = 0; i < args.metadata->len; i++) {
106
- RBGIArgMetadata *metadata;
107
-
108
- metadata = g_ptr_array_index(args.metadata, i);
109
- if (!metadata->closure_p) {
110
- continue;
111
- }
112
-
113
- callback_data = *((RBGICallbackData **)(raw_args[i]));
114
- break;
115
- }
116
-
117
- if (!callback_data && args.metadata->len > 0) {
118
- RBGIArgMetadata *metadata;
119
-
120
- i = args.metadata->len - 1;
121
- metadata = g_ptr_array_index(args.metadata, i);
122
- if (metadata->type.tag == GI_TYPE_TAG_VOID &&
123
- metadata->pointer_p &&
124
- strcmp(metadata->name, "data") == 0) {
125
- callback_data = *((RBGICallbackData **)(raw_args[i]));
126
- }
127
- }
128
- }
129
-
130
- {
131
- RBGICallbackInvokeData data;
132
- data.args = &args;
133
- data.callback = callback;
134
- data.callback_data = callback_data;
135
- rb_results = rbgutil_invoke_callback(rb_gi_callback_invoke,
136
- (VALUE)&data);
137
- }
138
- rb_gi_arguments_fill_raw_results(&args, rb_results, return_value);
139
- rb_gi_arguments_clear(&args);
140
-
141
- {
142
- RBGIArgMetadata *callback_metadata =
143
- rb_gi_callback_data_get_metadata(callback_data);
144
- if (callback_metadata->scope_type == GI_SCOPE_TYPE_ASYNC) {
145
- rb_gi_callback_data_free(callback_data);
146
- }
147
- }
148
- }
149
-
150
65
  static void
151
66
  rb_gi_arguments_in_init_arg_ruby_callback(RBGIArguments *args,
152
67
  RBGIArgMetadata *metadata)
@@ -187,14 +102,11 @@ rb_gi_arguments_in_init_arg_ruby_callback(RBGIArguments *args,
187
102
  if (callback_function) {
188
103
  callback_argument->v_pointer = callback_function;
189
104
  } else {
190
- callback = RB_ZALLOC(RBGICallback);
191
- callback->type_info = g_arg_info_get_type(arg_info);
192
- callback->callback_info = g_type_info_get_interface(callback->type_info);
193
- callback->closure =
194
- g_callable_info_prepare_closure(callback->callback_info,
195
- &(callback->cif),
196
- rb_gi_ffi_closure_callback,
197
- callback);
105
+ GITypeInfo *type_info = g_arg_info_get_type(arg_info);
106
+ GICallbackInfo *callback_info = g_type_info_get_interface(type_info);
107
+ callback = rb_gi_callback_new(callback_info, NULL);
108
+ g_base_info_unref(callback_info);
109
+ g_base_info_unref(type_info);
198
110
  callback_argument->v_pointer = callback->closure;
199
111
  }
200
112
 
@@ -682,7 +594,7 @@ rb_gi_arguments_in_init_arg_ruby_array_c_gtype(RBGIArguments *args,
682
594
  raw_array = ALLOC_N(GType, n_elements);
683
595
  for (i = 0; i < n_elements; i++) {
684
596
  VALUE rb_type = RARRAY_AREF(rb_array, i);
685
- raw_array[i] = rbgobj_gtype_get(rb_type);
597
+ raw_array[i] = rbgobj_gtype_from_ruby(rb_type);
686
598
  }
687
599
 
688
600
  rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
@@ -721,26 +633,50 @@ rb_gi_arguments_in_init_arg_ruby_array_c_interface_struct(RBGIArguments *args,
721
633
  {
722
634
  GIStructInfo *struct_info =
723
635
  (GIStructInfo *)(metadata->element_type.interface_info);
724
- guint8 *raw_array;
725
- gsize struct_size;
726
636
  long i, n_elements;
727
637
 
728
638
  n_elements = RARRAY_LEN(rb_array);
729
- struct_size = g_struct_info_get_size(struct_info);
730
- raw_array = ALLOC_N(guint8, struct_size * n_elements);
731
- for (i = 0; i < n_elements; i++) {
732
- VALUE rb_element = RARRAY_AREF(rb_array, i);
733
- gpointer element;
734
- element = rb_gi_struct_info_from_ruby(struct_info, rb_element);
735
- memcpy(raw_array + (struct_size * i),
736
- element,
737
- struct_size);
639
+ if (metadata->element_type.pointer_p) {
640
+ if (metadata->transfer != GI_TRANSFER_NOTHING) {
641
+ rb_raise(rb_eNotImpError,
642
+ "TODO: [%s::%s] %s "
643
+ "Ruby -> GIArgument(array/%s)[interface(%s)](%s)[%s]",
644
+ args->name,
645
+ metadata->name,
646
+ rb_gi_direction_to_string(metadata->direction),
647
+ rb_gi_array_type_to_string(metadata->array_type),
648
+ g_info_type_to_string(metadata->element_type.interface_type),
649
+ g_type_name(metadata->element_type.interface_gtype),
650
+ rb_gi_transfer_to_string(metadata->transfer));
651
+ }
652
+ gpointer *raw_array = ALLOC_N(gpointer, n_elements);
653
+ for (i = 0; i < n_elements; i++) {
654
+ VALUE rb_element = RARRAY_AREF(rb_array, i);
655
+ gpointer element;
656
+ element = rb_gi_struct_info_from_ruby(struct_info, rb_element);
657
+ raw_array[i] = element;
658
+ }
659
+ rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
660
+ metadata,
661
+ rb_array,
662
+ raw_array);
663
+ } else {
664
+ gsize struct_size = g_struct_info_get_size(struct_info);
665
+ guint8 *raw_array = ALLOC_N(guint8, struct_size * n_elements);
666
+ for (i = 0; i < n_elements; i++) {
667
+ VALUE rb_element = RARRAY_AREF(rb_array, i);
668
+ gpointer element;
669
+ element = rb_gi_struct_info_from_ruby(struct_info, rb_element);
670
+ memcpy(raw_array + (struct_size * i),
671
+ element,
672
+ struct_size);
673
+ }
674
+ rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
675
+ metadata,
676
+ rb_array,
677
+ raw_array);
738
678
  }
739
679
 
740
- rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
741
- metadata,
742
- rb_array,
743
- raw_array);
744
680
  metadata->free_func = rb_gi_arguments_in_free_array_c_interface_struct;
745
681
  }
746
682
 
@@ -980,7 +916,15 @@ rb_gi_arguments_in_init_arg_ruby_array_c(RBGIArguments *args,
980
916
  rb_arg);
981
917
  break;
982
918
  case GI_TYPE_TAG_UTF8:
983
- {
919
+ /* Workaround for rsvg_handle_set_stylesheet():
920
+ https://gitlab.gnome.org/GNOME/librsvg/-/issues/596 */
921
+ if (strcmp(metadata->name, "css") == 0) {
922
+ metadata->in_arg->v_pointer = (char *)RVAL2CSTR(rb_arg);
923
+ rb_gi_arguments_in_init_arg_ruby_array_set_length(args,
924
+ metadata,
925
+ RSTRING_LEN(rb_arg));
926
+ metadata->free_func = NULL;
927
+ } else {
984
928
  GIArgument *array_argument = metadata->in_arg;
985
929
  gchar **raw_array;
986
930
  long length;
@@ -1230,15 +1174,6 @@ rb_gi_arguments_in_init_arg_ruby_interface(RBGIArguments *args,
1230
1174
  rb_gi_transfer_to_string(metadata->transfer));
1231
1175
  break;
1232
1176
  case GI_INFO_TYPE_STRUCT:
1233
- if (metadata->transfer != GI_TRANSFER_NOTHING) {
1234
- rb_raise(rb_eNotImpError,
1235
- "TODO: [%s] %s Ruby -> GIArgument(interface)[%s][%s][%s]",
1236
- metadata->name,
1237
- rb_gi_direction_to_string(metadata->direction),
1238
- g_info_type_to_string(metadata->type.interface_type),
1239
- g_type_name(metadata->type.interface_gtype),
1240
- rb_gi_transfer_to_string(metadata->transfer));
1241
- }
1242
1177
  metadata->free_func = rb_gi_arguments_in_free_interface_struct;
1243
1178
  if (metadata->type.interface_gtype == G_TYPE_VALUE) {
1244
1179
  GValue *gvalue;
@@ -1645,7 +1580,15 @@ rb_gi_arguments_in_init_arg_ruby_ghash_body(VALUE value_data)
1645
1580
  case GI_TYPE_TAG_FLOAT:
1646
1581
  case GI_TYPE_TAG_DOUBLE:
1647
1582
  case GI_TYPE_TAG_GTYPE:
1583
+ rb_raise(rb_eNotImpError,
1584
+ "TODO: Ruby -> GIArgument(GHash)[value][%s]",
1585
+ g_type_tag_to_string(metadata->value_type.tag));
1586
+ break;
1648
1587
  case GI_TYPE_TAG_UTF8:
1588
+ value_destroy_func = g_free;
1589
+ value_ruby_to_c_func = ruby_to_c_utf8;
1590
+ value_ruby_to_c_data.context = "Ruby -> GIArgument(GHash)[value][utf8]";
1591
+ break;
1649
1592
  case GI_TYPE_TAG_FILENAME:
1650
1593
  case GI_TYPE_TAG_ARRAY:
1651
1594
  rb_raise(rb_eNotImpError,
@@ -2029,13 +1972,30 @@ rb_gi_arguments_in_init_arg_ruby(RBGIArguments *args,
2029
1972
  case GI_TYPE_TAG_UNICHAR:
2030
1973
  {
2031
1974
  gunichar *target;
1975
+ VALUE rb_unichar;
2032
1976
  if (metadata->direction == GI_DIRECTION_INOUT) {
2033
1977
  target = ALLOC(gunichar);
2034
1978
  metadata->in_arg->v_pointer = target;
2035
1979
  } else {
2036
1980
  target = &(metadata->in_arg->v_uint32);
2037
1981
  }
2038
- *target = NUM2UINT(metadata->rb_arg);
1982
+ if (RB_TYPE_P(metadata->rb_arg, RUBY_T_STRING)) {
1983
+ VALUE rb_codepoints;
1984
+ if (rb_str_strlen(metadata->rb_arg) != 1) {
1985
+ rb_raise(rb_eArgError,
1986
+ "[%s][%s] must be one character: %+" PRIsVALUE,
1987
+ metadata->name,
1988
+ g_type_tag_to_string(metadata->type.tag),
1989
+ metadata->rb_arg);
1990
+ }
1991
+ rb_codepoints = rb_funcall(metadata->rb_arg,
1992
+ rb_intern("codepoints"),
1993
+ 0);
1994
+ rb_unichar = RARRAY_PTR(rb_codepoints)[0];
1995
+ } else {
1996
+ rb_unichar = metadata->rb_arg;
1997
+ }
1998
+ *target = NUM2UINT(rb_unichar);
2039
1999
  }
2040
2000
  break;
2041
2001
  default:
@@ -105,10 +105,11 @@ rb_gi_arguments_out_free_array_c_interface(RBGIArguments *args,
105
105
  case GI_TRANSFER_EVERYTHING:
106
106
  default:
107
107
  rb_raise(rb_eNotImpError,
108
- "TODO: [%s] %s free GIArgument(%s)[%s]",
108
+ "TODO: [%s] %s free GIArgument(%s/%s)[%s]",
109
109
  metadata->name,
110
110
  rb_gi_direction_to_string(metadata->direction),
111
111
  g_type_tag_to_string(metadata->type.tag),
112
+ rb_gi_array_type_to_string(metadata->array_type),
112
113
  rb_gi_transfer_to_string(metadata->transfer));
113
114
  }
114
115
  xfree(target);
@@ -120,17 +121,34 @@ rb_gi_arguments_out_free_array_array_interface_struct(RBGIArguments *args,
120
121
  gpointer user_data)
121
122
  {
122
123
  GArray *target = metadata->out_arg->v_pointer;
124
+ GType gtype = metadata->element_type.interface_gtype;
123
125
  switch (metadata->transfer) {
124
126
  case GI_TRANSFER_NOTHING:
125
127
  break;
126
128
  case GI_TRANSFER_CONTAINER:
129
+ break;
127
130
  case GI_TRANSFER_EVERYTHING:
131
+ if (gtype == G_TYPE_NONE) {
132
+ /* If the target struct is raw (not GType-ed) struct, we
133
+ * can't know how to free fields in the target struct. We
134
+ * assume that the target struct doesn't allocate nothing
135
+ * for its fields.
136
+ *
137
+ * e.g.: The attributes out argument in
138
+ * vte_terminal_get_text_range():
139
+ * https://developer.gnome.org/vte/unstable/VteTerminal.html#vte-terminal-get-text-range
140
+ */
141
+ break;
142
+ }
128
143
  default:
129
144
  rb_raise(rb_eNotImpError,
130
- "TODO: [%s] %s free GIArgument(%s)[%s]",
145
+ "TODO: [%s] %s free GIArgument(%s/%s)[interface(%s)](%s)[%s]",
131
146
  metadata->name,
132
147
  rb_gi_direction_to_string(metadata->direction),
133
148
  g_type_tag_to_string(metadata->type.tag),
149
+ rb_gi_array_type_to_string(metadata->array_type),
150
+ g_info_type_to_string(metadata->element_type.interface_type),
151
+ g_type_name(metadata->element_type.interface_gtype),
134
152
  rb_gi_transfer_to_string(metadata->transfer));
135
153
  }
136
154
  g_array_free(target, TRUE);
@@ -505,16 +523,18 @@ rb_gi_arguments_out_init_arg_interface(RBGIArguments *args,
505
523
  g_info_type_to_string(metadata->type.interface_type));
506
524
  break;
507
525
  case GI_INFO_TYPE_STRUCT:
508
- {
509
- gsize struct_size;
510
-
511
- /* Should we care gtype?
512
- Related: rb_gi_arguments_out_arg_clear_interface() */
513
- struct_size = g_struct_info_get_size(metadata->type.interface_info);
526
+ /* Should we care gtype? */
527
+ if (metadata->type.pointer_p) {
528
+ gpointer *struct_location = RB_ALLOC(gpointer);
529
+ *struct_location = NULL;
530
+ argument->v_pointer = struct_location;
531
+ } else {
532
+ gsize struct_size =
533
+ g_struct_info_get_size(metadata->type.interface_info);
514
534
  argument->v_pointer = xmalloc(struct_size);
515
535
  memset(argument->v_pointer, 0, struct_size);
516
- metadata->free_func = rb_gi_arguments_out_free_interface_struct;
517
536
  }
537
+ metadata->free_func = rb_gi_arguments_out_free_interface_struct;
518
538
  break;
519
539
  case GI_INFO_TYPE_BOXED:
520
540
  rb_raise(rb_eNotImpError,
@@ -584,7 +604,7 @@ rb_gi_arguments_out_init_arg(RBGIArguments *args,
584
604
  memset(argument, 0, sizeof(GIArgument));
585
605
  switch (metadata->type.tag) {
586
606
  case GI_TYPE_TAG_VOID:
587
- if (metadata->pointer_p) {
607
+ if (metadata->type.pointer_p) {
588
608
  gpointer *pointer = ALLOC(gpointer);
589
609
  *pointer = NULL;
590
610
  argument->v_pointer = pointer;
@@ -800,7 +820,7 @@ rb_gi_arguments_out_to_ruby_arg(RBGIArguments *args,
800
820
  memset(&normalized_argument, 0, sizeof(GIArgument));
801
821
  switch (metadata->type.tag) {
802
822
  case GI_TYPE_TAG_VOID:
803
- if (metadata->pointer_p) {
823
+ if (metadata->type.pointer_p) {
804
824
  normalized_argument.v_pointer = *((gpointer *)(argument->v_pointer));
805
825
  }
806
826
  break;
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012-2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -23,16 +23,7 @@
23
23
  static gboolean
24
24
  rb_gi_arg_info_may_be_null(GIArgInfo *arg_info)
25
25
  {
26
- #if GI_CHECK_VERSION(1, 42, 0)
27
26
  return g_arg_info_may_be_null(arg_info);
28
- #else
29
- /*
30
- GObject Introspection < 1.42 doesn't support "(nullable)" yet.
31
- So, we assume that all argument may be NULL. It's danger but
32
- convenient.
33
- */
34
- return TRUE;
35
- #endif
36
27
  }
37
28
 
38
29
  static gboolean
@@ -57,12 +48,14 @@ rb_gi_arg_metadata_type_init(RBGIArgMetadataType *type,
57
48
  GITypeInfo *type_info)
58
49
  {
59
50
  type->info = type_info;
51
+ type->pointer_p = FALSE;
60
52
  type->tag = GI_TYPE_TAG_VOID;
61
53
  type->interface_info = NULL;
62
54
  type->interface_type = GI_INFO_TYPE_INVALID;
63
55
  type->interface_gtype = G_TYPE_INVALID;
64
56
 
65
57
  if (type->info) {
58
+ type->pointer_p = g_type_info_is_pointer(type->info);
66
59
  type->tag = g_type_info_get_tag(type->info);
67
60
  }
68
61
  if (type->tag == GI_TYPE_TAG_INTERFACE) {
@@ -114,7 +107,6 @@ rb_gi_arg_metadata_new(GICallableInfo *callable_info, gint i)
114
107
  metadata->array_p = (metadata->type.tag == GI_TYPE_TAG_ARRAY);
115
108
  metadata->array_length_p = FALSE;
116
109
  metadata->may_be_null_p = rb_gi_arg_info_may_be_null(arg_info);
117
- metadata->pointer_p = g_type_info_is_pointer(type_info);
118
110
  metadata->caller_allocates_p = g_arg_info_is_caller_allocates(arg_info);
119
111
  metadata->zero_terminated_p = FALSE;
120
112
  metadata->output_buffer_p = rb_gi_arg_info_is_output_buffer(arg_info);
@@ -505,6 +497,48 @@ rb_gi_arguments_get_rb_out_args(RBGIArguments *args)
505
497
  return rb_gi_arguments_out_to_ruby(args);
506
498
  }
507
499
 
500
+ void
501
+ rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
502
+ VALUE rb_error)
503
+ {
504
+ if (!g_callable_info_can_throw_gerror(args->info)) {
505
+ return;
506
+ }
507
+
508
+ gint n_args = g_callable_info_get_n_args(args->info);
509
+ /* GError ** isn't listed in args. */
510
+ GError **gerror = *((gpointer *)(args->raw_args[n_args]));
511
+ VALUE cGLibError = rb_const_get(mGLib, rb_intern("Error"));
512
+ if (NIL_P(rb_error)) {
513
+ g_set_error(gerror,
514
+ RBG_RUBY_ERROR,
515
+ RBG_RUBY_ERROR_UNKNOWN,
516
+ "Unknown error");
517
+ } else {
518
+ VALUE message = rb_funcall(rb_error, rb_intern("message"), 0);
519
+ VALUE backtrace = rb_funcall(rb_error, rb_intern("backtrace"), 0);
520
+ VALUE formatted_backtrace =
521
+ rb_ary_join(backtrace, rb_str_new_cstr(" \n"));
522
+ if (CBOOL2RVAL(rb_obj_is_kind_of(rb_error, cGLibError))) {
523
+ VALUE domain = rb_funcall(rb_error, rb_intern("domain"), 0);
524
+ VALUE code = rb_funcall(rb_error, rb_intern("code"), 0);
525
+ g_set_error(gerror,
526
+ g_quark_from_string(RVAL2CSTR(domain)),
527
+ NUM2INT(code),
528
+ "%s\n %s\n",
529
+ RVAL2CSTR(message),
530
+ RVAL2CSTR(formatted_backtrace));
531
+ } else {
532
+ g_set_error(gerror,
533
+ RBG_RUBY_ERROR,
534
+ RBG_RUBY_ERROR_UNKNOWN,
535
+ "%s\n %s\n",
536
+ RVAL2CSTR(message),
537
+ RVAL2CSTR(formatted_backtrace));
538
+ }
539
+ }
540
+ }
541
+
508
542
  static void
509
543
  rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
510
544
  VALUE rb_result,
@@ -585,6 +619,160 @@ rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
585
619
  g_base_info_unref(interface_info);
586
620
  }
587
621
 
622
+ static void
623
+ rb_gi_arguments_fill_raw_result_glist_interface(
624
+ RBGIArguments *args,
625
+ VALUE rb_result,
626
+ gpointer raw_result,
627
+ GITypeInfo *type_info,
628
+ GITypeInfo *element_type_info,
629
+ G_GNUC_UNUSED GITransfer transfer /* TODO */,
630
+ gboolean is_return_value)
631
+ {
632
+ GIFFIReturnValue *ffi_return_value = raw_result;
633
+ GIBaseInfo *interface_info;
634
+ GIInfoType interface_type;
635
+ const gchar *interface_name;
636
+ GType gtype;
637
+ GList *list = NULL;
638
+
639
+ interface_info = g_type_info_get_interface(element_type_info);
640
+ interface_type = g_base_info_get_type(interface_info);
641
+ interface_name = g_info_type_to_string(interface_type);
642
+ gtype = g_registered_type_info_get_g_type(interface_info);
643
+
644
+ switch (interface_type) {
645
+ case GI_INFO_TYPE_INVALID:
646
+ case GI_INFO_TYPE_FUNCTION:
647
+ case GI_INFO_TYPE_CALLBACK:
648
+ case GI_INFO_TYPE_STRUCT:
649
+ case GI_INFO_TYPE_BOXED:
650
+ case GI_INFO_TYPE_ENUM:
651
+ case GI_INFO_TYPE_FLAGS:
652
+ g_base_info_unref(interface_info);
653
+ g_base_info_unref(element_type_info);
654
+ rb_raise(rb_eNotImpError,
655
+ "TODO: %s::%s: out raw result(glist)[interface(%s)](%s)",
656
+ g_base_info_get_namespace(args->info),
657
+ g_base_info_get_name(args->info),
658
+ interface_name,
659
+ g_type_name(gtype));
660
+ break;
661
+ case GI_INFO_TYPE_OBJECT:
662
+ list = RVAL2GOBJGLIST(rb_result);
663
+ if (transfer == GI_TRANSFER_EVERYTHING) {
664
+ g_list_foreach(list, (GFunc)g_object_ref, NULL);
665
+ }
666
+ break;
667
+ case GI_INFO_TYPE_INTERFACE:
668
+ case GI_INFO_TYPE_CONSTANT:
669
+ case GI_INFO_TYPE_INVALID_0:
670
+ case GI_INFO_TYPE_UNION:
671
+ case GI_INFO_TYPE_VALUE:
672
+ case GI_INFO_TYPE_SIGNAL:
673
+ case GI_INFO_TYPE_VFUNC:
674
+ case GI_INFO_TYPE_PROPERTY:
675
+ case GI_INFO_TYPE_FIELD:
676
+ case GI_INFO_TYPE_ARG:
677
+ case GI_INFO_TYPE_TYPE:
678
+ case GI_INFO_TYPE_UNRESOLVED:
679
+ g_base_info_unref(interface_info);
680
+ g_base_info_unref(element_type_info);
681
+ rb_raise(rb_eNotImpError,
682
+ "TODO: %s::%s: out raw result(glist)[interface(%s)](%s)",
683
+ g_base_info_get_namespace(args->info),
684
+ g_base_info_get_name(args->info),
685
+ interface_name,
686
+ g_type_name(gtype));
687
+ break;
688
+ default:
689
+ g_base_info_unref(interface_info);
690
+ g_base_info_unref(element_type_info);
691
+ g_assert_not_reached();
692
+ break;
693
+ }
694
+
695
+ if (is_return_value) {
696
+ ffi_return_value->v_ulong = (gulong)list;
697
+ } else {
698
+ *((gpointer *)raw_result) = list;
699
+ }
700
+ }
701
+
702
+ static void
703
+ rb_gi_arguments_fill_raw_result_glist(RBGIArguments *args,
704
+ VALUE rb_result,
705
+ gpointer raw_result,
706
+ GITypeInfo *type_info,
707
+ GITransfer transfer,
708
+ gboolean is_return_value)
709
+ {
710
+ GIFFIReturnValue *ffi_return_value = raw_result;
711
+ GITypeInfo *element_type_info;
712
+ GITypeTag element_type_tag;
713
+
714
+ element_type_info = g_type_info_get_param_type(type_info, 0);
715
+ element_type_tag = g_type_info_get_tag(element_type_info);
716
+
717
+ if (is_return_value) {
718
+ ffi_return_value->v_ulong = (gulong)NULL;
719
+ } else {
720
+ *((gpointer *)raw_result) = NULL;
721
+ }
722
+
723
+ switch (element_type_tag) {
724
+ case GI_TYPE_TAG_VOID:
725
+ case GI_TYPE_TAG_BOOLEAN:
726
+ case GI_TYPE_TAG_INT8:
727
+ case GI_TYPE_TAG_UINT8:
728
+ case GI_TYPE_TAG_INT16:
729
+ case GI_TYPE_TAG_UINT16:
730
+ case GI_TYPE_TAG_INT32:
731
+ case GI_TYPE_TAG_UINT32:
732
+ case GI_TYPE_TAG_INT64:
733
+ case GI_TYPE_TAG_UINT64:
734
+ case GI_TYPE_TAG_FLOAT:
735
+ case GI_TYPE_TAG_DOUBLE:
736
+ case GI_TYPE_TAG_GTYPE:
737
+ case GI_TYPE_TAG_UTF8:
738
+ case GI_TYPE_TAG_FILENAME:
739
+ case GI_TYPE_TAG_ARRAY:
740
+ g_base_info_unref(element_type_info);
741
+ rb_raise(rb_eNotImpError,
742
+ "TODO: %s::%s: out raw result(GList)[%s]",
743
+ g_base_info_get_namespace(args->info),
744
+ g_base_info_get_name(args->info),
745
+ g_type_tag_to_string(element_type_tag));
746
+ break;
747
+ case GI_TYPE_TAG_INTERFACE:
748
+ rb_gi_arguments_fill_raw_result_glist_interface(
749
+ args,
750
+ rb_result,
751
+ raw_result,
752
+ type_info,
753
+ element_type_info,
754
+ transfer,
755
+ is_return_value);
756
+ break;
757
+ case GI_TYPE_TAG_GLIST:
758
+ case GI_TYPE_TAG_GSLIST:
759
+ case GI_TYPE_TAG_GHASH:
760
+ case GI_TYPE_TAG_ERROR:
761
+ case GI_TYPE_TAG_UNICHAR:
762
+ g_base_info_unref(element_type_info);
763
+ rb_raise(rb_eNotImpError,
764
+ "TODO: %s::%s: out raw result(GList)[%s]",
765
+ g_base_info_get_namespace(args->info),
766
+ g_base_info_get_name(args->info),
767
+ g_type_tag_to_string(element_type_tag));
768
+ break;
769
+ default:
770
+ g_base_info_unref(element_type_info);
771
+ g_assert_not_reached();
772
+ break;
773
+ }
774
+ }
775
+
588
776
  /*
589
777
  We need to cast from different type for return value. (We don't
590
778
  need it for out arguments.) Because of libffi specification:
@@ -703,12 +891,16 @@ rb_gi_arguments_fill_raw_result(RBGIArguments *args,
703
891
  }
704
892
  break;
705
893
  case GI_TYPE_TAG_UTF8:
706
- if (is_return_value) {
707
- ffi_return_value->v_ulong =
708
- (gulong)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
709
- } else {
710
- *((gchar **)raw_result) =
711
- (gchar *)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
894
+ {
895
+ gchar *result = (gchar *)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
896
+ if (transfer == GI_TRANSFER_EVERYTHING) {
897
+ result = g_strdup(result);
898
+ }
899
+ if (is_return_value) {
900
+ ffi_return_value->v_ulong = (gulong)result;
901
+ } else {
902
+ *((gchar **)raw_result) = (gchar *)result;
903
+ }
712
904
  }
713
905
  break;
714
906
  case GI_TYPE_TAG_FILENAME:
@@ -747,6 +939,13 @@ rb_gi_arguments_fill_raw_result(RBGIArguments *args,
747
939
  is_return_value);
748
940
  break;
749
941
  case GI_TYPE_TAG_GLIST:
942
+ rb_gi_arguments_fill_raw_result_glist(args,
943
+ rb_result,
944
+ raw_result,
945
+ type_info,
946
+ transfer,
947
+ is_return_value);
948
+ break;
750
949
  case GI_TYPE_TAG_GSLIST:
751
950
  case GI_TYPE_TAG_GHASH:
752
951
  rb_raise(rb_eNotImpError,
@@ -841,7 +1040,7 @@ rb_gi_arguments_fill_raw_results(RBGIArguments *args,
841
1040
  rb_gi_arguments_fill_raw_result(args,
842
1041
  RARRAY_AREF(rb_results, i_rb_result),
843
1042
  argument->v_pointer,
844
- return_type_info,
1043
+ type_info,
845
1044
  transfer,
846
1045
  FALSE);
847
1046
  i_rb_result++;