glib2 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +3023 -0
- data/README +28 -0
- data/Rakefile +87 -0
- data/extconf.rb +61 -0
- data/sample/bookmarkfile.rb +66 -0
- data/sample/completion.rb +45 -0
- data/sample/idle.rb +41 -0
- data/sample/iochannel.rb +44 -0
- data/sample/keyfile.rb +62 -0
- data/sample/shell.rb +36 -0
- data/sample/spawn.rb +25 -0
- data/sample/timeout.rb +28 -0
- data/sample/timeout2.rb +35 -0
- data/sample/timer.rb +40 -0
- data/sample/type-register.rb +103 -0
- data/sample/type-register2.rb +104 -0
- data/sample/utils.rb +54 -0
- data/src/glib-enum-types.c +1032 -0
- data/src/glib-enum-types.h +140 -0
- data/src/lib/glib-mkenums.rb +199 -0
- data/src/lib/glib2.rb +220 -0
- data/src/lib/mkmf-gnome2.rb +390 -0
- data/src/lib/pkg-config.rb +137 -0
- data/src/rbgcompat.h +30 -0
- data/src/rbglib.c +320 -0
- data/src/rbglib.h +96 -0
- data/src/rbglib_bookmarkfile.c +595 -0
- data/src/rbglib_completion.c +192 -0
- data/src/rbglib_convert.c +195 -0
- data/src/rbglib_error.c +95 -0
- data/src/rbglib_fileutils.c +83 -0
- data/src/rbglib_i18n.c +44 -0
- data/src/rbglib_int64.c +157 -0
- data/src/rbglib_iochannel.c +883 -0
- data/src/rbglib_keyfile.c +846 -0
- data/src/rbglib_maincontext.c +917 -0
- data/src/rbglib_mainloop.c +87 -0
- data/src/rbglib_messages.c +150 -0
- data/src/rbglib_pollfd.c +111 -0
- data/src/rbglib_shell.c +68 -0
- data/src/rbglib_source.c +190 -0
- data/src/rbglib_spawn.c +345 -0
- data/src/rbglib_threads.c +51 -0
- data/src/rbglib_timer.c +127 -0
- data/src/rbglib_unicode.c +611 -0
- data/src/rbglib_utils.c +386 -0
- data/src/rbglib_win32.c +136 -0
- data/src/rbgobj_boxed.c +251 -0
- data/src/rbgobj_closure.c +337 -0
- data/src/rbgobj_convert.c +167 -0
- data/src/rbgobj_enums.c +961 -0
- data/src/rbgobj_fundamental.c +30 -0
- data/src/rbgobj_object.c +892 -0
- data/src/rbgobj_param.c +390 -0
- data/src/rbgobj_paramspecs.c +305 -0
- data/src/rbgobj_signal.c +963 -0
- data/src/rbgobj_strv.c +61 -0
- data/src/rbgobj_type.c +851 -0
- data/src/rbgobj_typeinstance.c +121 -0
- data/src/rbgobj_typeinterface.c +148 -0
- data/src/rbgobj_typemodule.c +66 -0
- data/src/rbgobj_typeplugin.c +49 -0
- data/src/rbgobj_value.c +313 -0
- data/src/rbgobj_valuearray.c +59 -0
- data/src/rbgobj_valuetypes.c +298 -0
- data/src/rbgobject.c +406 -0
- data/src/rbgobject.h +265 -0
- data/src/rbgprivate.h +88 -0
- data/src/rbgutil.c +222 -0
- data/src/rbgutil.h +82 -0
- data/src/rbgutil_callback.c +231 -0
- data/test/glib-test-init.rb +6 -0
- data/test/glib-test-utils.rb +12 -0
- data/test/run-test.rb +25 -0
- data/test/test_enum.rb +99 -0
- data/test/test_file_utils.rb +15 -0
- data/test/test_glib2.rb +120 -0
- data/test/test_iochannel.rb +275 -0
- data/test/test_key_file.rb +38 -0
- data/test/test_mkenums.rb +25 -0
- data/test/test_signal.rb +20 -0
- data/test/test_timeout.rb +28 -0
- data/test/test_unicode.rb +369 -0
- data/test/test_utils.rb +37 -0
- data/test/test_win32.rb +13 -0
- metadata +165 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
|
+
/************************************************
|
3
|
+
|
4
|
+
rbgobj_convert.c -
|
5
|
+
|
6
|
+
$Author: mutoh $
|
7
|
+
$Date: 2006/05/22 17:13:05 $
|
8
|
+
|
9
|
+
Copyright (C) 2006 Sjoerd Simons, Masao Mutoh
|
10
|
+
************************************************/
|
11
|
+
|
12
|
+
#include "rbgobject.h"
|
13
|
+
#include "rbgprivate.h"
|
14
|
+
|
15
|
+
static GHashTable *tables, *class_to_g_type_map;
|
16
|
+
|
17
|
+
void
|
18
|
+
Init_gobject_convert(void)
|
19
|
+
{
|
20
|
+
tables = g_hash_table_new(g_int_hash, g_int_equal);
|
21
|
+
class_to_g_type_map = g_hash_table_new(g_int_hash, g_int_equal);
|
22
|
+
}
|
23
|
+
|
24
|
+
void
|
25
|
+
rbgobj_convert_define(RGConvertTable *table)
|
26
|
+
{
|
27
|
+
g_hash_table_insert(tables, &(table->type), table);
|
28
|
+
if (table->klass && !NIL_P(table->klass)) {
|
29
|
+
g_hash_table_insert(class_to_g_type_map,
|
30
|
+
&(table->klass), &(table->type));
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
RGConvertTable *
|
35
|
+
rbgobj_convert_lookup(GType type)
|
36
|
+
{
|
37
|
+
return g_hash_table_lookup(tables, &type);
|
38
|
+
}
|
39
|
+
|
40
|
+
gboolean
|
41
|
+
rbgobj_convert_has_type(GType type)
|
42
|
+
{
|
43
|
+
return rbgobj_convert_lookup(type) != NULL;
|
44
|
+
}
|
45
|
+
|
46
|
+
gboolean
|
47
|
+
rbgobj_convert_get_superclass(GType type, VALUE *result)
|
48
|
+
{
|
49
|
+
RGConvertTable *table;
|
50
|
+
|
51
|
+
table = rbgobj_convert_lookup(type);
|
52
|
+
if (table && table->get_superclass) {
|
53
|
+
*result = table->get_superclass();
|
54
|
+
return TRUE;
|
55
|
+
}
|
56
|
+
|
57
|
+
return FALSE;
|
58
|
+
}
|
59
|
+
|
60
|
+
gboolean
|
61
|
+
rbgobj_convert_type_init_hook(GType type, VALUE klass)
|
62
|
+
{
|
63
|
+
RGConvertTable *table;
|
64
|
+
|
65
|
+
table = rbgobj_convert_lookup(type);
|
66
|
+
if (table && table->type_init_hook) {
|
67
|
+
table->type_init_hook(klass);
|
68
|
+
return TRUE;
|
69
|
+
}
|
70
|
+
|
71
|
+
return FALSE;
|
72
|
+
}
|
73
|
+
|
74
|
+
gboolean
|
75
|
+
rbgobj_convert_rvalue2gvalue(GType type, VALUE value, GValue *result)
|
76
|
+
{
|
77
|
+
RGConvertTable *table;
|
78
|
+
|
79
|
+
table = rbgobj_convert_lookup(type);
|
80
|
+
if (table && table->rvalue2gvalue) {
|
81
|
+
table->rvalue2gvalue(value, result);
|
82
|
+
return TRUE;
|
83
|
+
}
|
84
|
+
|
85
|
+
return FALSE;
|
86
|
+
}
|
87
|
+
|
88
|
+
gboolean
|
89
|
+
rbgobj_convert_gvalue2rvalue(GType type, const GValue *value, VALUE *result)
|
90
|
+
{
|
91
|
+
RGConvertTable *table;
|
92
|
+
|
93
|
+
table = rbgobj_convert_lookup(type);
|
94
|
+
if (table && table->gvalue2rvalue) {
|
95
|
+
*result = table->gvalue2rvalue(value);
|
96
|
+
return TRUE;
|
97
|
+
}
|
98
|
+
|
99
|
+
return FALSE;
|
100
|
+
}
|
101
|
+
|
102
|
+
GType
|
103
|
+
rbgobj_convert_rvalue2gtype(VALUE value)
|
104
|
+
{
|
105
|
+
VALUE klass;
|
106
|
+
GType *result;
|
107
|
+
|
108
|
+
klass = rb_class_of(value);
|
109
|
+
result = g_hash_table_lookup(class_to_g_type_map, &klass);
|
110
|
+
return result ? *result : 0;
|
111
|
+
}
|
112
|
+
|
113
|
+
gboolean
|
114
|
+
rbgobj_convert_initialize(GType type, VALUE obj, gpointer cobj)
|
115
|
+
{
|
116
|
+
RGConvertTable *table;
|
117
|
+
|
118
|
+
table = rbgobj_convert_lookup(type);
|
119
|
+
if (table && table->initialize) {
|
120
|
+
table->initialize(obj, cobj);
|
121
|
+
return TRUE;
|
122
|
+
}
|
123
|
+
|
124
|
+
return FALSE;
|
125
|
+
}
|
126
|
+
|
127
|
+
gboolean
|
128
|
+
rbgobj_convert_robj2instance(GType type, VALUE obj, gpointer *result)
|
129
|
+
{
|
130
|
+
RGConvertTable *table;
|
131
|
+
|
132
|
+
table = rbgobj_convert_lookup(type);
|
133
|
+
if (table && table->robj2instance) {
|
134
|
+
*result = table->robj2instance(obj);
|
135
|
+
return TRUE;
|
136
|
+
}
|
137
|
+
|
138
|
+
return FALSE;
|
139
|
+
}
|
140
|
+
|
141
|
+
gboolean
|
142
|
+
rbgobj_convert_instance2robj(GType type, gpointer instance, VALUE *result)
|
143
|
+
{
|
144
|
+
RGConvertTable *table;
|
145
|
+
|
146
|
+
table = rbgobj_convert_lookup(type);
|
147
|
+
if (table && table->instance2robj) {
|
148
|
+
*result = table->instance2robj(instance);
|
149
|
+
return TRUE;
|
150
|
+
}
|
151
|
+
|
152
|
+
return FALSE;
|
153
|
+
}
|
154
|
+
|
155
|
+
gboolean
|
156
|
+
rbgobj_convert_unref(GType type, gpointer instance)
|
157
|
+
{
|
158
|
+
RGConvertTable *table;
|
159
|
+
|
160
|
+
table = rbgobj_convert_lookup(type);
|
161
|
+
if (table && table->unref) {
|
162
|
+
table->unref(instance);
|
163
|
+
return TRUE;
|
164
|
+
}
|
165
|
+
|
166
|
+
return FALSE;
|
167
|
+
}
|
data/src/rbgobj_enums.c
ADDED
@@ -0,0 +1,961 @@
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
|
+
/**********************************************************************
|
3
|
+
|
4
|
+
rbgobj_enums.c -
|
5
|
+
|
6
|
+
$Author: ktou $
|
7
|
+
$Date: 2007/08/08 11:53:09 $
|
8
|
+
created at: Sat Jul 27 16:56:01 JST 2002
|
9
|
+
|
10
|
+
Copyright (C) 2004-2006 Ruby-GNOME2 Project Team
|
11
|
+
Copyright (C) 2002,2003 Masahiro Sakai
|
12
|
+
**********************************************************************/
|
13
|
+
|
14
|
+
#include "rbgprivate.h"
|
15
|
+
#include <ctype.h>
|
16
|
+
|
17
|
+
VALUE rbgobj_cEnum, rbgobj_cFlags;
|
18
|
+
|
19
|
+
static ID id_new;
|
20
|
+
static ID id_module_eval;
|
21
|
+
static ID id_to_s;
|
22
|
+
static ID id_or;
|
23
|
+
|
24
|
+
/**********************************************************************/
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
char *original;
|
28
|
+
char *replacement;
|
29
|
+
} constant_map;
|
30
|
+
|
31
|
+
static GSList *rbgobj_cmap = NULL;
|
32
|
+
|
33
|
+
static gchar *
|
34
|
+
nick_to_const_name(const gchar *nick)
|
35
|
+
{
|
36
|
+
gchar *const_name;
|
37
|
+
gchar *p;
|
38
|
+
|
39
|
+
if (!nick)
|
40
|
+
return NULL;
|
41
|
+
|
42
|
+
const_name = g_strdup(nick);
|
43
|
+
for (p = const_name; *p; p++) {
|
44
|
+
if (*p == '-' || *p == ' ')
|
45
|
+
*p = '_';
|
46
|
+
else
|
47
|
+
*p = g_ascii_toupper(*p);
|
48
|
+
}
|
49
|
+
return const_name;
|
50
|
+
}
|
51
|
+
|
52
|
+
static VALUE
|
53
|
+
resolve_enum_value(VALUE klass, VALUE nick)
|
54
|
+
{
|
55
|
+
VALUE value = Qnil;
|
56
|
+
gchar *const_nick;
|
57
|
+
ID const_nick_id;
|
58
|
+
|
59
|
+
if (RVAL2CBOOL(rb_obj_is_kind_of(nick, klass)))
|
60
|
+
return nick;
|
61
|
+
|
62
|
+
nick = rb_funcall(nick, id_to_s, 0);
|
63
|
+
const_nick = nick_to_const_name(RVAL2CSTR(nick));
|
64
|
+
const_nick_id = rb_intern(const_nick);
|
65
|
+
if (rb_const_defined(klass, const_nick_id)) {
|
66
|
+
value = rb_const_get(klass, const_nick_id);
|
67
|
+
}
|
68
|
+
g_free(const_nick);
|
69
|
+
|
70
|
+
return value;
|
71
|
+
}
|
72
|
+
|
73
|
+
static VALUE
|
74
|
+
resolve_flags_value(VALUE klass, VALUE nick_or_nicks)
|
75
|
+
{
|
76
|
+
int i, len;
|
77
|
+
VALUE flags_value;
|
78
|
+
|
79
|
+
if (!RVAL2CBOOL(rb_obj_is_kind_of(nick_or_nicks, rb_cArray)))
|
80
|
+
return resolve_enum_value(klass, nick_or_nicks);
|
81
|
+
|
82
|
+
len = RARRAY_LEN(nick_or_nicks);
|
83
|
+
flags_value = rb_funcall(klass, id_new, 0);
|
84
|
+
for (i = 0; i < len; i++) {
|
85
|
+
VALUE value;
|
86
|
+
|
87
|
+
value = resolve_enum_value(klass, RARRAY_PTR(nick_or_nicks)[i]);
|
88
|
+
if (NIL_P(value))
|
89
|
+
return Qnil;
|
90
|
+
|
91
|
+
flags_value = rb_funcall(flags_value, id_or, 1, value);
|
92
|
+
}
|
93
|
+
|
94
|
+
return flags_value;
|
95
|
+
}
|
96
|
+
|
97
|
+
static gint
|
98
|
+
rbgobj_constant_find(constant_map *a, char *name)
|
99
|
+
{
|
100
|
+
return strcmp(a->original, name);
|
101
|
+
}
|
102
|
+
|
103
|
+
void
|
104
|
+
rbgobj_constant_remap(const char *original, const char *replacement)
|
105
|
+
{
|
106
|
+
constant_map *map = g_new(constant_map,1);
|
107
|
+
|
108
|
+
map -> original = g_strdup(original);
|
109
|
+
map -> replacement = g_strdup(replacement);
|
110
|
+
|
111
|
+
rbgobj_cmap = g_slist_append(rbgobj_cmap, map);
|
112
|
+
}
|
113
|
+
|
114
|
+
static char *
|
115
|
+
rbgobj_constant_lookup(const char *name)
|
116
|
+
{
|
117
|
+
GSList *p = rbgobj_cmap;
|
118
|
+
|
119
|
+
p = g_slist_find_custom(rbgobj_cmap, name,
|
120
|
+
(GCompareFunc)rbgobj_constant_find);
|
121
|
+
if (p)
|
122
|
+
{
|
123
|
+
char *replacement;
|
124
|
+
constant_map *map;
|
125
|
+
|
126
|
+
map = (constant_map*) p -> data;
|
127
|
+
rbgobj_cmap = g_slist_delete_link(rbgobj_cmap, p);
|
128
|
+
replacement = map -> replacement;
|
129
|
+
|
130
|
+
g_free(map -> original);
|
131
|
+
g_free(map);
|
132
|
+
|
133
|
+
return replacement;
|
134
|
+
}
|
135
|
+
return NULL;
|
136
|
+
}
|
137
|
+
|
138
|
+
void
|
139
|
+
rbgobj_define_const(VALUE mod, const char *name,
|
140
|
+
VALUE value)
|
141
|
+
{
|
142
|
+
if (name[0] >= 'A' && name[0] <= 'Z')
|
143
|
+
{
|
144
|
+
rb_define_const(mod, name, value);
|
145
|
+
}
|
146
|
+
else
|
147
|
+
{
|
148
|
+
char *new_name = rbgobj_constant_lookup(name);
|
149
|
+
|
150
|
+
if (new_name)
|
151
|
+
{
|
152
|
+
rb_define_const(mod, new_name, value);
|
153
|
+
g_free(new_name);
|
154
|
+
}
|
155
|
+
else
|
156
|
+
{
|
157
|
+
rb_warn("Invalid constant name '%s' - skipped", name);
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
static void
|
163
|
+
rbgobj_enum_add_constants(VALUE mod, GType enum_type,
|
164
|
+
const gchar *strip_prefix)
|
165
|
+
{
|
166
|
+
GEnumClass *gclass;
|
167
|
+
int i;
|
168
|
+
int prefix_len = strlen(strip_prefix);
|
169
|
+
|
170
|
+
gclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
|
171
|
+
|
172
|
+
for (i = 0; i < gclass->n_values; i++) {
|
173
|
+
const GEnumValue* value = &gclass->values[i];
|
174
|
+
|
175
|
+
if (strncmp(value->value_name, strip_prefix, prefix_len)) {
|
176
|
+
g_warning("\"%s\" doesn't have prefix \"%s\"",
|
177
|
+
value->value_name, strip_prefix);
|
178
|
+
} else {
|
179
|
+
const char* name = value->value_name + prefix_len;
|
180
|
+
rbgobj_define_const(mod, name,
|
181
|
+
rbgobj_make_enum(value->value, enum_type));
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
g_type_class_unref(gclass);
|
186
|
+
}
|
187
|
+
|
188
|
+
static void
|
189
|
+
rbgobj_flags_add_constants(VALUE mod, GType flags_type,
|
190
|
+
const gchar *strip_prefix)
|
191
|
+
{
|
192
|
+
GFlagsClass *gclass;
|
193
|
+
int i;
|
194
|
+
int prefix_len = strlen(strip_prefix);
|
195
|
+
|
196
|
+
gclass = G_FLAGS_CLASS(g_type_class_ref(flags_type));
|
197
|
+
|
198
|
+
for (i = 0; i < gclass->n_values; i++) {
|
199
|
+
const GFlagsValue* value = &gclass->values[i];
|
200
|
+
|
201
|
+
if (strncmp(value->value_name, strip_prefix, prefix_len)) {
|
202
|
+
g_warning("\"%s\" doesn't have prefix \"%s\"",
|
203
|
+
value->value_name, strip_prefix);
|
204
|
+
} else {
|
205
|
+
const char* name = value->value_name + prefix_len;
|
206
|
+
rbgobj_define_const(mod, name,
|
207
|
+
rbgobj_make_flags(value->value, flags_type));
|
208
|
+
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
g_type_class_unref(gclass);
|
213
|
+
}
|
214
|
+
|
215
|
+
void
|
216
|
+
rbgobj_add_constants(VALUE mod, GType type, const gchar *strip_prefix)
|
217
|
+
{
|
218
|
+
if (G_TYPE_IS_ENUM(type)) {
|
219
|
+
rbgobj_enum_add_constants(mod, type, strip_prefix);
|
220
|
+
} else if (G_TYPE_IS_FLAGS(type)) {
|
221
|
+
rbgobj_flags_add_constants(mod, type, strip_prefix);
|
222
|
+
} else {
|
223
|
+
g_warning("`%s' is not an enum/flags type", g_type_name(type));
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
/**********************************************************************/
|
228
|
+
|
229
|
+
typedef struct {
|
230
|
+
GEnumClass* gclass;
|
231
|
+
gint value;
|
232
|
+
GEnumValue* info;
|
233
|
+
} enum_holder;
|
234
|
+
|
235
|
+
static void
|
236
|
+
enum_free(enum_holder* p)
|
237
|
+
{
|
238
|
+
g_type_class_unref(p->gclass);
|
239
|
+
free(p);
|
240
|
+
}
|
241
|
+
|
242
|
+
static enum_holder*
|
243
|
+
enum_get_holder(VALUE obj)
|
244
|
+
{
|
245
|
+
enum_holder* p;
|
246
|
+
Data_Get_Struct(obj, enum_holder, p);
|
247
|
+
return p;
|
248
|
+
}
|
249
|
+
|
250
|
+
static VALUE
|
251
|
+
make_enum(gint n, VALUE klass)
|
252
|
+
{
|
253
|
+
return rb_funcall(klass, id_new, 1, INT2NUM(n));
|
254
|
+
}
|
255
|
+
|
256
|
+
VALUE
|
257
|
+
rbgobj_make_enum(gint n, GType gtype)
|
258
|
+
{
|
259
|
+
return make_enum(n, GTYPE2CLASS(gtype));
|
260
|
+
}
|
261
|
+
|
262
|
+
gint
|
263
|
+
rbgobj_get_enum(VALUE obj, GType gtype)
|
264
|
+
{
|
265
|
+
VALUE klass;
|
266
|
+
|
267
|
+
if (!g_type_is_a(gtype, G_TYPE_ENUM))
|
268
|
+
rb_raise(rb_eTypeError, "%s is not a %s: %s",
|
269
|
+
g_type_name(gtype), g_type_name(G_TYPE_ENUM),
|
270
|
+
RBG_INSPECT(obj));
|
271
|
+
|
272
|
+
/* for compatibility */
|
273
|
+
if (rb_obj_is_kind_of(obj, rb_cInteger))
|
274
|
+
obj = rbgobj_make_enum(NUM2INT(obj), gtype);
|
275
|
+
|
276
|
+
klass = GTYPE2CLASS(gtype);
|
277
|
+
|
278
|
+
if (!rb_obj_is_kind_of(obj, klass)) {
|
279
|
+
VALUE enum_value;
|
280
|
+
|
281
|
+
enum_value = resolve_enum_value(klass, obj);
|
282
|
+
if (!NIL_P(enum_value))
|
283
|
+
obj = enum_value;
|
284
|
+
}
|
285
|
+
|
286
|
+
if (rb_obj_is_kind_of(obj, klass))
|
287
|
+
return enum_get_holder(obj)->value;
|
288
|
+
else
|
289
|
+
rb_raise(rb_eTypeError, "not a %s: %s",
|
290
|
+
rb_class2name(klass), RBG_INSPECT(obj));
|
291
|
+
}
|
292
|
+
|
293
|
+
/**********************************************************************/
|
294
|
+
|
295
|
+
void
|
296
|
+
rbgobj_init_enum_class(VALUE klass)
|
297
|
+
{
|
298
|
+
GEnumClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
299
|
+
int i;
|
300
|
+
|
301
|
+
for (i = 0; i < gclass->n_values; i++) {
|
302
|
+
GEnumValue* entry = &(gclass->values[i]);
|
303
|
+
gchar *const_nick_name;
|
304
|
+
|
305
|
+
const_nick_name = nick_to_const_name(entry->value_nick);
|
306
|
+
|
307
|
+
#if 0
|
308
|
+
{
|
309
|
+
ID id = rb_intern(const_nick_name);
|
310
|
+
if (rb_is_const_id(id)) {
|
311
|
+
VALUE value;
|
312
|
+
|
313
|
+
value = make_enum(entry->value, klass);
|
314
|
+
rb_define_const(klass, const_nick_name, value);
|
315
|
+
}
|
316
|
+
}
|
317
|
+
#else
|
318
|
+
{
|
319
|
+
if (const_nick_name) {
|
320
|
+
VALUE value;
|
321
|
+
|
322
|
+
value = make_enum(entry->value, klass);
|
323
|
+
rbgobj_define_const(klass, const_nick_name, value);
|
324
|
+
}
|
325
|
+
}
|
326
|
+
#endif
|
327
|
+
|
328
|
+
g_free(const_nick_name);
|
329
|
+
}
|
330
|
+
|
331
|
+
g_type_class_unref(gclass);
|
332
|
+
}
|
333
|
+
|
334
|
+
static VALUE
|
335
|
+
enum_s_range(self)
|
336
|
+
VALUE self;
|
337
|
+
{
|
338
|
+
GEnumClass* gclass = g_type_class_ref(CLASS2GTYPE(self));
|
339
|
+
VALUE result = rb_range_new(INT2NUM(gclass->minimum),
|
340
|
+
INT2NUM(gclass->maximum),
|
341
|
+
FALSE);
|
342
|
+
g_type_class_unref(gclass);
|
343
|
+
return result;
|
344
|
+
}
|
345
|
+
|
346
|
+
static VALUE
|
347
|
+
enum_s_values(VALUE self)
|
348
|
+
{
|
349
|
+
GEnumClass *gclass;
|
350
|
+
VALUE result;
|
351
|
+
int i;
|
352
|
+
|
353
|
+
gclass = g_type_class_ref(CLASS2GTYPE(self));;
|
354
|
+
result = rb_ary_new();
|
355
|
+
for (i = 0; i < gclass->n_values; i++) {
|
356
|
+
GEnumValue *p = &(gclass->values[i]);
|
357
|
+
rb_ary_push(result, make_enum(p->value, self));
|
358
|
+
}
|
359
|
+
|
360
|
+
g_type_class_unref(gclass);
|
361
|
+
return result;
|
362
|
+
}
|
363
|
+
|
364
|
+
static VALUE
|
365
|
+
enum_s_allocate(VALUE self)
|
366
|
+
{
|
367
|
+
GType gtype = CLASS2GTYPE(self);
|
368
|
+
|
369
|
+
if (G_TYPE_IS_ABSTRACT(gtype)) {
|
370
|
+
rb_raise(rb_eTypeError, "abstract class");
|
371
|
+
} else {
|
372
|
+
enum_holder* p;
|
373
|
+
VALUE result = Data_Make_Struct(self, enum_holder, NULL, enum_free, p);
|
374
|
+
p->gclass = g_type_class_ref(gtype);
|
375
|
+
p->info = NULL;
|
376
|
+
return result;
|
377
|
+
}
|
378
|
+
}
|
379
|
+
|
380
|
+
static VALUE
|
381
|
+
enum_initialize(VALUE self, VALUE arg)
|
382
|
+
{
|
383
|
+
enum_holder* p = enum_get_holder(self);
|
384
|
+
|
385
|
+
if (rb_respond_to(arg, rb_intern("to_str"))) {
|
386
|
+
const char* str = StringValuePtr(arg);
|
387
|
+
p->info = g_enum_get_value_by_name(p->gclass, str);
|
388
|
+
if (! p->info)
|
389
|
+
p->info = g_enum_get_value_by_nick(p->gclass, str);
|
390
|
+
if (! p->info)
|
391
|
+
rb_raise(rb_eArgError, "invalid argument");
|
392
|
+
} else {
|
393
|
+
p->value = NUM2INT(arg);
|
394
|
+
p->info = g_enum_get_value(p->gclass, p->value);
|
395
|
+
}
|
396
|
+
|
397
|
+
return Qnil;
|
398
|
+
}
|
399
|
+
|
400
|
+
static VALUE
|
401
|
+
enum_to_i(VALUE self)
|
402
|
+
{
|
403
|
+
enum_holder* p = enum_get_holder(self);
|
404
|
+
return INT2NUM(p->value);
|
405
|
+
}
|
406
|
+
|
407
|
+
static VALUE
|
408
|
+
enum_name(VALUE self)
|
409
|
+
{
|
410
|
+
enum_holder* p = enum_get_holder(self);
|
411
|
+
return p->info ? rb_str_new2(p->info->value_name) : Qnil;
|
412
|
+
}
|
413
|
+
|
414
|
+
static VALUE
|
415
|
+
enum_nick(VALUE self)
|
416
|
+
{
|
417
|
+
enum_holder* p = enum_get_holder(self);
|
418
|
+
return p->info ? rb_str_new2(p->info->value_nick) : Qnil;
|
419
|
+
}
|
420
|
+
|
421
|
+
static VALUE
|
422
|
+
enum_inspect(VALUE self)
|
423
|
+
{
|
424
|
+
const char* cname = rb_class2name(CLASS_OF(self));
|
425
|
+
enum_holder* p = enum_get_holder(self);
|
426
|
+
gchar* str;
|
427
|
+
VALUE result;
|
428
|
+
|
429
|
+
if (p->info)
|
430
|
+
str = g_strdup_printf("#<%s %s>",
|
431
|
+
cname, p->info->value_nick);
|
432
|
+
else
|
433
|
+
str = g_strdup_printf("#<%s %d>",
|
434
|
+
cname, p->value);
|
435
|
+
result = rb_str_new2(str);
|
436
|
+
g_free(str);
|
437
|
+
|
438
|
+
return result;
|
439
|
+
}
|
440
|
+
|
441
|
+
static VALUE
|
442
|
+
enum_eqv(VALUE self, VALUE rhs)
|
443
|
+
{
|
444
|
+
enum_holder* p = enum_get_holder(self);
|
445
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
446
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
447
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
448
|
+
return Qnil;
|
449
|
+
return CBOOL2RVAL(rbgobj_get_enum(self, gtype) == rbgobj_get_enum(rhs, gtype));
|
450
|
+
}
|
451
|
+
|
452
|
+
static VALUE
|
453
|
+
enum_hash(VALUE self)
|
454
|
+
{
|
455
|
+
enum_holder* p = enum_get_holder(self);
|
456
|
+
return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass));
|
457
|
+
}
|
458
|
+
|
459
|
+
static VALUE
|
460
|
+
enum_coerce(VALUE self, VALUE other)
|
461
|
+
{
|
462
|
+
enum_holder *holder;
|
463
|
+
GType gtype;
|
464
|
+
|
465
|
+
if (!rb_obj_is_kind_of(other, rb_cInteger))
|
466
|
+
rb_raise(rb_eTypeError, "can't coerce");
|
467
|
+
|
468
|
+
holder = enum_get_holder(self);
|
469
|
+
gtype = G_TYPE_FROM_CLASS(holder->gclass);
|
470
|
+
other = rbgobj_make_enum(NUM2INT(other), gtype);
|
471
|
+
return rb_ary_new3(2, other, self);
|
472
|
+
}
|
473
|
+
|
474
|
+
static void
|
475
|
+
Init_enum()
|
476
|
+
{
|
477
|
+
VALUE cEnum;
|
478
|
+
|
479
|
+
rbgobj_cEnum = G_DEF_CLASS(G_TYPE_ENUM, "Enum", mGLib);
|
480
|
+
cEnum = rbgobj_cEnum;
|
481
|
+
|
482
|
+
rb_define_singleton_method(cEnum, "gtype", generic_s_gtype, 0);
|
483
|
+
rb_define_method(cEnum, "gtype", generic_gtype, 0);
|
484
|
+
|
485
|
+
rb_define_singleton_method(cEnum, "range", enum_s_range, 0);
|
486
|
+
rb_define_singleton_method(cEnum, "values", enum_s_values, 0);
|
487
|
+
|
488
|
+
rb_define_alloc_func(cEnum, enum_s_allocate);
|
489
|
+
|
490
|
+
rb_define_method(cEnum, "initialize", enum_initialize, 1);
|
491
|
+
rb_define_method(cEnum, "to_i", enum_to_i, 0);
|
492
|
+
rb_define_method(cEnum, "name", enum_name, 0);
|
493
|
+
rb_define_method(cEnum, "nick", enum_nick, 0);
|
494
|
+
|
495
|
+
rb_define_method(cEnum, "inspect", enum_inspect, 0);
|
496
|
+
rb_define_method(cEnum, "==", enum_eqv, 1);
|
497
|
+
rb_define_method(cEnum, "hash", enum_hash, 0);
|
498
|
+
rb_define_method(cEnum, "eql?", enum_eqv, 1);
|
499
|
+
|
500
|
+
/* for compatibility */
|
501
|
+
rb_define_method(cEnum, "coerce", enum_coerce, 1);
|
502
|
+
rb_define_alias(cEnum, "to_int", "to_i");
|
503
|
+
}
|
504
|
+
|
505
|
+
/**********************************************************************/
|
506
|
+
|
507
|
+
typedef struct {
|
508
|
+
GFlagsClass* gclass;
|
509
|
+
guint value;
|
510
|
+
GFlagsValue* info;
|
511
|
+
} flags_holder;
|
512
|
+
|
513
|
+
static void
|
514
|
+
flags_free(enum_holder* p)
|
515
|
+
{
|
516
|
+
g_type_class_unref(p->gclass);
|
517
|
+
free(p);
|
518
|
+
}
|
519
|
+
|
520
|
+
static flags_holder*
|
521
|
+
flags_get_holder(VALUE obj)
|
522
|
+
{
|
523
|
+
flags_holder* p;
|
524
|
+
Data_Get_Struct(obj, flags_holder, p);
|
525
|
+
return p;
|
526
|
+
}
|
527
|
+
|
528
|
+
static VALUE
|
529
|
+
make_flags(guint n, VALUE klass)
|
530
|
+
{
|
531
|
+
return rb_funcall(klass, id_new, 1, UINT2NUM(n));
|
532
|
+
}
|
533
|
+
|
534
|
+
VALUE
|
535
|
+
rbgobj_make_flags(guint n, GType gtype)
|
536
|
+
{
|
537
|
+
return make_flags(n, GTYPE2CLASS(gtype));
|
538
|
+
}
|
539
|
+
|
540
|
+
guint
|
541
|
+
rbgobj_get_flags(VALUE obj, GType gtype)
|
542
|
+
{
|
543
|
+
VALUE klass;
|
544
|
+
|
545
|
+
if (!g_type_is_a(gtype, G_TYPE_FLAGS))
|
546
|
+
rb_raise(rb_eTypeError, "%s is not a %s",
|
547
|
+
g_type_name(gtype), g_type_name(G_TYPE_FLAGS));
|
548
|
+
|
549
|
+
/* for compatibility */
|
550
|
+
if (rb_obj_is_kind_of(obj, rb_cInteger))
|
551
|
+
obj = rbgobj_make_flags(NUM2UINT(obj), gtype);
|
552
|
+
|
553
|
+
klass = GTYPE2CLASS(gtype);
|
554
|
+
|
555
|
+
if (!rb_obj_is_kind_of(obj, klass)) {
|
556
|
+
VALUE flags_value = Qnil;
|
557
|
+
|
558
|
+
flags_value = resolve_flags_value(klass, obj);
|
559
|
+
if (!NIL_P(flags_value))
|
560
|
+
obj = flags_value;
|
561
|
+
}
|
562
|
+
|
563
|
+
if (rb_obj_is_kind_of(obj, klass))
|
564
|
+
return flags_get_holder(obj)->value;
|
565
|
+
else
|
566
|
+
rb_raise(rb_eTypeError, "not a %s: %s",
|
567
|
+
rb_class2name(klass), RBG_INSPECT(obj));
|
568
|
+
}
|
569
|
+
|
570
|
+
/**********************************************************************/
|
571
|
+
|
572
|
+
void
|
573
|
+
rbgobj_init_flags_class(VALUE klass)
|
574
|
+
{
|
575
|
+
GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
576
|
+
GString* source = g_string_new(NULL);
|
577
|
+
int i;
|
578
|
+
|
579
|
+
for (i = 0; i < gclass->n_values; i++) {
|
580
|
+
GFlagsValue* entry = &(gclass->values[i]);
|
581
|
+
gchar* nick;
|
582
|
+
gchar* p;
|
583
|
+
gchar* replace_nick;
|
584
|
+
|
585
|
+
replace_nick = rbgobj_constant_lookup(entry->value_nick);
|
586
|
+
if (replace_nick){
|
587
|
+
nick = g_strdup(replace_nick);
|
588
|
+
} else {
|
589
|
+
nick = g_strdup(entry->value_nick);
|
590
|
+
}
|
591
|
+
|
592
|
+
for (p = nick; *p; p++)
|
593
|
+
if (*p == '-' || *p == ' ')
|
594
|
+
*p = '_';
|
595
|
+
else
|
596
|
+
*p = tolower(*p);
|
597
|
+
|
598
|
+
g_string_append_printf(
|
599
|
+
source,
|
600
|
+
"def %s%s?; self >= self.class.new(%d); end\n",
|
601
|
+
g_ascii_isdigit(nick[0]) ? "_" : "",
|
602
|
+
nick, entry->value);
|
603
|
+
|
604
|
+
for (p = nick; *p; p++)
|
605
|
+
*p = g_ascii_toupper(*p);
|
606
|
+
|
607
|
+
#if 0
|
608
|
+
{
|
609
|
+
ID id = rb_intern(nick);
|
610
|
+
if (rb_is_const_id(id)) {
|
611
|
+
rb_define_const(klass, nick, make_flags(entry->value, klass));
|
612
|
+
}
|
613
|
+
}
|
614
|
+
#else
|
615
|
+
{
|
616
|
+
rbgobj_define_const(klass, nick, make_flags(entry->value, klass));
|
617
|
+
}
|
618
|
+
#endif
|
619
|
+
|
620
|
+
g_free(nick);
|
621
|
+
}
|
622
|
+
|
623
|
+
rb_funcall(klass, id_module_eval, 1, rb_str_new2(source->str));
|
624
|
+
g_string_free(source, TRUE);
|
625
|
+
|
626
|
+
g_type_class_unref(gclass);
|
627
|
+
}
|
628
|
+
|
629
|
+
static VALUE
|
630
|
+
flags_s_mask(VALUE klass)
|
631
|
+
{
|
632
|
+
GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
633
|
+
VALUE result = UINT2NUM(gclass->mask);
|
634
|
+
g_type_class_unref(gclass);
|
635
|
+
return result;
|
636
|
+
}
|
637
|
+
|
638
|
+
static VALUE
|
639
|
+
flags_s_values(VALUE klass)
|
640
|
+
{
|
641
|
+
GFlagsClass *gclass;
|
642
|
+
VALUE result;
|
643
|
+
int i;
|
644
|
+
|
645
|
+
gclass = g_type_class_ref(CLASS2GTYPE(klass));
|
646
|
+
result = rb_ary_new();
|
647
|
+
for (i = 0; i < gclass->n_values; i++) {
|
648
|
+
GFlagsValue *p = &(gclass->values[i]);
|
649
|
+
rb_ary_push(result, make_flags(p->value, klass));
|
650
|
+
}
|
651
|
+
g_type_class_unref(gclass);
|
652
|
+
|
653
|
+
return result;
|
654
|
+
}
|
655
|
+
|
656
|
+
static VALUE
|
657
|
+
flags_s_allocate(VALUE self)
|
658
|
+
{
|
659
|
+
GType gtype = CLASS2GTYPE(self);
|
660
|
+
|
661
|
+
if (G_TYPE_IS_ABSTRACT(gtype)) {
|
662
|
+
rb_raise(rb_eTypeError, "abstract class");
|
663
|
+
} else {
|
664
|
+
flags_holder* p;
|
665
|
+
VALUE result = Data_Make_Struct(self, flags_holder, NULL, flags_free, p);
|
666
|
+
p->gclass = g_type_class_ref(gtype);
|
667
|
+
p->value = 0;
|
668
|
+
p->info = NULL;
|
669
|
+
return result;
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
673
|
+
static VALUE
|
674
|
+
flags_initialize(int argc, VALUE* argv, VALUE self)
|
675
|
+
{
|
676
|
+
flags_holder* p = flags_get_holder(self);
|
677
|
+
VALUE arg;
|
678
|
+
|
679
|
+
rb_scan_args(argc, argv, "01", &arg);
|
680
|
+
|
681
|
+
if (argc == 0) {
|
682
|
+
p->value = 0;
|
683
|
+
} else {
|
684
|
+
if (rb_respond_to(arg, rb_intern("to_str"))) {
|
685
|
+
const char* str = StringValuePtr(arg);
|
686
|
+
p->info = g_flags_get_value_by_name(p->gclass, str);
|
687
|
+
if (!p->info)
|
688
|
+
p->info = g_flags_get_value_by_nick(p->gclass, str);
|
689
|
+
if (!p->info)
|
690
|
+
rb_raise(rb_eArgError, "invalid argument");
|
691
|
+
p->value = p->info->value;
|
692
|
+
} else {
|
693
|
+
p->value = NUM2UINT(arg);
|
694
|
+
}
|
695
|
+
}
|
696
|
+
|
697
|
+
if (!p->info) {
|
698
|
+
int i;
|
699
|
+
for (i = 0; i < p->gclass->n_values; i++){
|
700
|
+
GFlagsValue* val = &(p->gclass->values[i]);
|
701
|
+
if (val->value == p->value){
|
702
|
+
p->info = val;
|
703
|
+
break;
|
704
|
+
}
|
705
|
+
}
|
706
|
+
}
|
707
|
+
|
708
|
+
return Qnil;
|
709
|
+
}
|
710
|
+
|
711
|
+
static VALUE
|
712
|
+
flags_to_i(VALUE self)
|
713
|
+
{
|
714
|
+
flags_holder* p = flags_get_holder(self);
|
715
|
+
return UINT2NUM(p->value);
|
716
|
+
}
|
717
|
+
|
718
|
+
static VALUE
|
719
|
+
flags_name(VALUE self)
|
720
|
+
{
|
721
|
+
flags_holder* p = flags_get_holder(self);
|
722
|
+
return p->info ? rb_str_new2(p->info->value_name) : Qnil;
|
723
|
+
}
|
724
|
+
|
725
|
+
static VALUE
|
726
|
+
flags_nick(VALUE self)
|
727
|
+
{
|
728
|
+
flags_holder* p = flags_get_holder(self);
|
729
|
+
return p->info ? rb_str_new2(p->info->value_nick) : Qnil;
|
730
|
+
}
|
731
|
+
|
732
|
+
static VALUE
|
733
|
+
flags_compare(VALUE self, VALUE rhs)
|
734
|
+
{
|
735
|
+
flags_holder* p = flags_get_holder(self);
|
736
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
737
|
+
guint rhs_val;
|
738
|
+
|
739
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
740
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
741
|
+
return Qnil;
|
742
|
+
|
743
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
744
|
+
|
745
|
+
if (p->value == rhs_val)
|
746
|
+
return INT2FIX(0);
|
747
|
+
else if ((p->value & rhs_val) == rhs_val)
|
748
|
+
return INT2FIX(1);
|
749
|
+
else if ((p->value & rhs_val) == p->value)
|
750
|
+
return INT2FIX(-1);
|
751
|
+
else
|
752
|
+
return Qnil;
|
753
|
+
}
|
754
|
+
|
755
|
+
static VALUE
|
756
|
+
flags_eqv(VALUE self, VALUE rhs)
|
757
|
+
{
|
758
|
+
flags_holder* p = flags_get_holder(self);
|
759
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
760
|
+
guint rhs_val;
|
761
|
+
|
762
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
763
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
764
|
+
return Qnil;
|
765
|
+
|
766
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
767
|
+
return CBOOL2RVAL(p->value == rhs_val);
|
768
|
+
}
|
769
|
+
|
770
|
+
static VALUE
|
771
|
+
flags_gt_eq(VALUE self, VALUE rhs)
|
772
|
+
{
|
773
|
+
flags_holder* p = flags_get_holder(self);
|
774
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
775
|
+
guint rhs_val;
|
776
|
+
|
777
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
778
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
779
|
+
return Qnil;
|
780
|
+
|
781
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
782
|
+
return CBOOL2RVAL((p->value & rhs_val) == rhs_val);
|
783
|
+
}
|
784
|
+
|
785
|
+
static VALUE
|
786
|
+
flags_lt_eq(VALUE self, VALUE rhs)
|
787
|
+
{
|
788
|
+
flags_holder* p = flags_get_holder(self);
|
789
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
790
|
+
guint rhs_val;
|
791
|
+
|
792
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
793
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
794
|
+
return Qnil;
|
795
|
+
|
796
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
797
|
+
return CBOOL2RVAL((p->value & rhs_val) == p->value);
|
798
|
+
}
|
799
|
+
|
800
|
+
static VALUE
|
801
|
+
flags_gt(VALUE self, VALUE rhs)
|
802
|
+
{
|
803
|
+
flags_holder* p = flags_get_holder(self);
|
804
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
805
|
+
guint rhs_val;
|
806
|
+
|
807
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
808
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
809
|
+
return Qnil;
|
810
|
+
|
811
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
812
|
+
return CBOOL2RVAL((p->value & rhs_val) == rhs_val &&
|
813
|
+
p->value != rhs_val);
|
814
|
+
}
|
815
|
+
|
816
|
+
static VALUE
|
817
|
+
flags_lt(VALUE self, VALUE rhs)
|
818
|
+
{
|
819
|
+
flags_holder* p = flags_get_holder(self);
|
820
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
821
|
+
guint rhs_val;
|
822
|
+
|
823
|
+
if (CLASS_OF(rhs) != CLASS_OF(self) &&
|
824
|
+
!rb_obj_is_kind_of(rhs, rb_cInteger))
|
825
|
+
return Qnil;
|
826
|
+
|
827
|
+
rhs_val = rbgobj_get_flags(rhs, gtype);
|
828
|
+
return CBOOL2RVAL((p->value & rhs_val) == p->value &&
|
829
|
+
p->value != rhs_val);
|
830
|
+
}
|
831
|
+
|
832
|
+
static VALUE
|
833
|
+
flags_not(VALUE self, VALUE rhs)
|
834
|
+
{
|
835
|
+
flags_holder* p = flags_get_holder(self);
|
836
|
+
return rbgobj_make_flags((~ p->value) & p->gclass->mask,
|
837
|
+
G_TYPE_FROM_CLASS(p->gclass));
|
838
|
+
}
|
839
|
+
|
840
|
+
#define LIFT_BINARY_OP(funcname, op) \
|
841
|
+
static VALUE \
|
842
|
+
funcname(VALUE self, VALUE rhs) \
|
843
|
+
{ \
|
844
|
+
flags_holder* p = flags_get_holder(self); \
|
845
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass); \
|
846
|
+
return rbgobj_make_flags(p->value op rbgobj_get_flags(rhs, gtype), \
|
847
|
+
gtype); \
|
848
|
+
}
|
849
|
+
|
850
|
+
LIFT_BINARY_OP(flags_and, &)
|
851
|
+
LIFT_BINARY_OP(flags_or, |)
|
852
|
+
LIFT_BINARY_OP(flags_xor, ^)
|
853
|
+
|
854
|
+
static VALUE
|
855
|
+
flags_minus(VALUE self, VALUE rhs)
|
856
|
+
{
|
857
|
+
flags_holder* p = flags_get_holder(self);
|
858
|
+
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
|
859
|
+
return rbgobj_make_flags(p->value & ~rbgobj_get_flags(rhs, gtype),
|
860
|
+
gtype);
|
861
|
+
}
|
862
|
+
|
863
|
+
static VALUE
|
864
|
+
flags_empty_p(VALUE self)
|
865
|
+
{
|
866
|
+
flags_holder* p = flags_get_holder(self);
|
867
|
+
return CBOOL2RVAL(p->value == 0);
|
868
|
+
}
|
869
|
+
|
870
|
+
static VALUE
|
871
|
+
flags_hash(VALUE self)
|
872
|
+
{
|
873
|
+
flags_holder* p = flags_get_holder(self);
|
874
|
+
return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass));
|
875
|
+
}
|
876
|
+
|
877
|
+
static VALUE
|
878
|
+
flags_coerce(VALUE self, VALUE other)
|
879
|
+
{
|
880
|
+
flags_holder *holder;
|
881
|
+
GType gtype;
|
882
|
+
|
883
|
+
if (rb_obj_is_kind_of(other, rb_cInteger))
|
884
|
+
rb_raise(rb_eTypeError, "can't coerce");
|
885
|
+
|
886
|
+
holder = flags_get_holder(self);
|
887
|
+
gtype = G_TYPE_FROM_CLASS(holder->gclass);
|
888
|
+
other = rbgobj_make_flags(NUM2UINT(other), gtype);
|
889
|
+
return rb_ary_new3(2, other, self);
|
890
|
+
}
|
891
|
+
|
892
|
+
static VALUE
|
893
|
+
flags_nonzero_p(VALUE self)
|
894
|
+
{
|
895
|
+
flags_holder* p = flags_get_holder(self);
|
896
|
+
return CBOOL2RVAL(p->value != 0);
|
897
|
+
}
|
898
|
+
|
899
|
+
static void
|
900
|
+
Init_flags()
|
901
|
+
{
|
902
|
+
VALUE cFlags;
|
903
|
+
|
904
|
+
rbgobj_cFlags = G_DEF_CLASS(G_TYPE_FLAGS, "Flags", mGLib);
|
905
|
+
cFlags = rbgobj_cFlags;
|
906
|
+
|
907
|
+
rb_define_singleton_method(cFlags, "gtype", generic_s_gtype, 0);
|
908
|
+
rb_define_method(cFlags, "gtype", generic_gtype, 0);
|
909
|
+
|
910
|
+
rb_define_singleton_method(cFlags, "mask", flags_s_mask, 0);
|
911
|
+
rb_define_singleton_method(cFlags, "values", flags_s_values, 0);
|
912
|
+
|
913
|
+
rb_define_alloc_func(cFlags, flags_s_allocate);
|
914
|
+
|
915
|
+
rb_define_method(cFlags, "initialize", flags_initialize, -1);
|
916
|
+
|
917
|
+
rb_define_method(cFlags, "to_i", flags_to_i, 0);
|
918
|
+
rb_define_alias(cFlags, "to_int", "to_i");
|
919
|
+
rb_define_method(cFlags, "name", flags_name, 0);
|
920
|
+
rb_define_method(cFlags, "nick", flags_nick, 0);
|
921
|
+
|
922
|
+
/*
|
923
|
+
rb_define_method(cFlags, "inspect", flags_inspect, 0);
|
924
|
+
*/
|
925
|
+
|
926
|
+
rb_define_method(cFlags, "<=>", flags_compare, 1);
|
927
|
+
rb_define_method(cFlags, "==", flags_eqv, 1);
|
928
|
+
rb_define_method(cFlags, ">=", flags_gt_eq, 1);
|
929
|
+
rb_define_method(cFlags, "<=", flags_lt_eq, 1);
|
930
|
+
rb_define_method(cFlags, ">", flags_gt, 1);
|
931
|
+
rb_define_method(cFlags, "<", flags_lt, 1);
|
932
|
+
rb_define_method(cFlags, "~", flags_not, 0);
|
933
|
+
rb_define_method(cFlags, "&", flags_and, 1);
|
934
|
+
rb_define_method(cFlags, "|", flags_or, 1);
|
935
|
+
rb_define_method(cFlags, "^", flags_xor, 1);
|
936
|
+
rb_define_method(cFlags, "-", flags_minus, 1);
|
937
|
+
|
938
|
+
rb_define_method(cFlags, "empty?", flags_empty_p, 0);
|
939
|
+
|
940
|
+
rb_define_method(cFlags, "hash", flags_hash, 0);
|
941
|
+
rb_define_method(cFlags, "eql?", flags_eqv, 1);
|
942
|
+
|
943
|
+
/* for compatibility */
|
944
|
+
rb_define_method(cFlags, "coerce", flags_coerce, 1);
|
945
|
+
rb_define_method(cFlags, "zero?", flags_empty_p, 0);
|
946
|
+
rb_define_method(cFlags, "nonzero?", flags_nonzero_p, 0);
|
947
|
+
}
|
948
|
+
|
949
|
+
/**********************************************************************/
|
950
|
+
|
951
|
+
void
|
952
|
+
Init_gobject_genums()
|
953
|
+
{
|
954
|
+
id_module_eval = rb_intern("module_eval");
|
955
|
+
id_new = rb_intern("new");
|
956
|
+
id_to_s = rb_intern("to_s");
|
957
|
+
id_or = rb_intern("|");
|
958
|
+
|
959
|
+
Init_enum();
|
960
|
+
Init_flags();
|
961
|
+
}
|