rlibconfig 1.0.1

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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/ext/extconf.rb +11 -0
  3. data/ext/rlibconfig.c +700 -0
  4. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b45b2d7f4a2ef35bb0f1cb31bc9fa84cd1b2c969
4
+ data.tar.gz: f3e1575539ec2304d3c2291a813abe0e51765705
5
+ SHA512:
6
+ metadata.gz: fc82f67bb88c0712e5b6cced377c9ac27fdf459df9e7a3ced0592fc77afb23cc90212cf13df7241ea092262f6f95bd2bd83113c92efb46f7e3150f01eb90f4fc
7
+ data.tar.gz: d8d895a9fa0590b06c0223efef75fc732c6a7ddae0c6c47323b39bceb257423ef319a8acfa1d22986ddfbd67e7a1ae03f6269156f84f408a527b9e3e9dad3ede
data/ext/extconf.rb ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/ruby
2
+ require "mkmf"
3
+
4
+ unless pkg_config('libconfig')
5
+ puts 'failure: need libconfig'
6
+ exit 1
7
+ end
8
+
9
+ have_func('rb_block_call', 'ruby/ruby.h')
10
+
11
+ create_makefile("rlibconfig")
data/ext/rlibconfig.c ADDED
@@ -0,0 +1,700 @@
1
+ #include <ruby.h>
2
+ #include <libconfig.h>
3
+
4
+ static VALUE cConfig, cConfigBaseSetting, cConfigSetting, cConfigAggregate;
5
+ static VALUE cConfigFormatDefault, cConfigFormatHex;
6
+ static VALUE cConfigFixnum, cConfigBignum, cConfigFloat, cConfigBoolean, cConfigString;
7
+ static VALUE cConfigGroup, cConfigList, cConfigArray;
8
+
9
+ static VALUE rSettingNameRegexp;
10
+ static VALUE aConfigSettings, aConfigScalars, aConfigAggregates;
11
+ static VALUE eConfigParseError, eSettingNotFoundError, eSettingFormatError, eSettingNameError;
12
+
13
+ static VALUE rconfig_wrap_value(config_setting_t* setting)
14
+ {
15
+ switch(config_setting_type(setting)) {
16
+ case CONFIG_TYPE_INT:
17
+ return LONG2FIX(config_setting_get_int(setting));
18
+
19
+ case CONFIG_TYPE_INT64:
20
+ return rb_ll2inum(config_setting_get_int64(setting));
21
+
22
+ case CONFIG_TYPE_FLOAT:
23
+ return rb_float_new(config_setting_get_float(setting));
24
+
25
+ case CONFIG_TYPE_STRING:
26
+ return rb_str_new2(config_setting_get_string(setting));
27
+
28
+ case CONFIG_TYPE_BOOL:
29
+ return config_setting_get_bool(setting) ? Qtrue : Qfalse;
30
+
31
+ default:
32
+ rb_bug("unknown value type %d", config_setting_type(setting));
33
+ }
34
+ }
35
+
36
+ static void rconfig_free_setting(config_setting_t* setting)
37
+ {
38
+ // dummy
39
+ }
40
+
41
+ static VALUE rconfig_prepare_setting(config_setting_t* setting)
42
+ {
43
+ VALUE wrapper = Data_Wrap_Struct(rb_cObject, 0, rconfig_free_setting, setting);
44
+ config_setting_set_hook(setting, (void*) wrapper);
45
+ return wrapper;
46
+ }
47
+
48
+ static void rconfig_destroy_setting(void* hook)
49
+ {
50
+ if(hook != NULL) {
51
+ VALUE wrapper = (VALUE) hook;
52
+ rb_iv_set(wrapper, "@setting", Qnil);
53
+ }
54
+ }
55
+
56
+ static VALUE rconfig_wrap_setting(config_setting_t* setting)
57
+ {
58
+ VALUE rbSetting = rconfig_prepare_setting(setting);
59
+
60
+ switch(config_setting_type(setting)) {
61
+ case CONFIG_TYPE_INT:
62
+ return rb_funcall(cConfigFixnum, rb_intern("new"), 2, LONG2FIX(config_setting_get_int(setting)), rbSetting);
63
+
64
+ case CONFIG_TYPE_INT64:
65
+ return rb_funcall(cConfigBignum, rb_intern("new"), 2, rb_ll2inum(config_setting_get_int64(setting)), rbSetting);
66
+
67
+ case CONFIG_TYPE_FLOAT:
68
+ return rb_funcall(cConfigFloat, rb_intern("new"), 2, rb_float_new(config_setting_get_float(setting)), rbSetting);
69
+
70
+ case CONFIG_TYPE_STRING:
71
+ return rb_funcall(cConfigString, rb_intern("new"), 2, rb_str_new2(config_setting_get_string(setting)), rbSetting);
72
+
73
+ case CONFIG_TYPE_BOOL:
74
+ return rb_funcall(cConfigBoolean, rb_intern("new"), 2, config_setting_get_bool(setting) ? Qtrue : Qfalse, rbSetting);
75
+
76
+ case CONFIG_TYPE_ARRAY:
77
+ return rb_funcall(cConfigArray, rb_intern("new"), 2, Qnil, rbSetting);
78
+
79
+ case CONFIG_TYPE_LIST:
80
+ return rb_funcall(cConfigList, rb_intern("new"), 1, rbSetting);
81
+
82
+ case CONFIG_TYPE_GROUP:
83
+ return rb_funcall(cConfigGroup, rb_intern("new"), 1, rbSetting);
84
+
85
+ default:
86
+ rb_bug("[r] unknown setting type %d", config_setting_type(setting));
87
+ }
88
+ }
89
+
90
+ static void rconfig_update_setting(config_setting_t* setting, VALUE value)
91
+ {
92
+ switch(config_setting_type(setting)) {
93
+ case CONFIG_TYPE_INT:
94
+ config_setting_set_int(setting, FIX2LONG(value));
95
+ break;
96
+
97
+ case CONFIG_TYPE_INT64:
98
+ if(TYPE(value) == T_BIGNUM)
99
+ config_setting_set_int64(setting, rb_big2ll(value));
100
+ else // T_FIXNUM
101
+ config_setting_set_int64(setting, FIX2INT(value));
102
+ break;
103
+
104
+ case CONFIG_TYPE_FLOAT:
105
+ // ruby1.9 check
106
+ #if HAVE_RB_BLOCK_CALL
107
+ config_setting_set_float(setting, RFLOAT(value)->float_value);
108
+ #else
109
+ config_setting_set_float(setting, RFLOAT(value)->value);
110
+ #endif
111
+ break;
112
+
113
+ case CONFIG_TYPE_STRING:
114
+ config_setting_set_string(setting, RSTRING_PTR(value));
115
+ break;
116
+
117
+ case CONFIG_TYPE_BOOL:
118
+ config_setting_set_bool(setting, value == Qtrue);
119
+ break;
120
+
121
+ default:
122
+ rb_bug("[w] unknown setting type %d", config_setting_type(setting));
123
+ }
124
+ }
125
+
126
+ static void rconfig_check_setting_type(VALUE object, VALUE value)
127
+ {
128
+ if(rb_obj_class(object) == cConfigFixnum) {
129
+ Check_Type(value, T_FIXNUM);
130
+ } else if(rb_obj_class(object) == cConfigBignum) {
131
+ if(TYPE(value) != T_BIGNUM && TYPE(value) != T_FIXNUM)
132
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or Bignum)", rb_obj_classname(value));
133
+ } else if(rb_obj_class(object) == cConfigFloat) {
134
+ Check_Type(value, T_FLOAT);
135
+ } else if(rb_obj_class(object) == cConfigString) {
136
+ Check_Type(value, T_STRING);
137
+ } else if(rb_obj_class(object) == cConfigBoolean) {
138
+ if(value != Qtrue && value != Qfalse)
139
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected boolean)", rb_obj_classname(value));
140
+ } else {
141
+ rb_raise(rb_eException, "never use Config::Setting itself");
142
+ }
143
+ }
144
+
145
+ static int rconfig_do_append(config_setting_t* setting, VALUE target, VALUE name)
146
+ {
147
+ int type;
148
+ if(rb_obj_class(target) == cConfigFixnum)
149
+ type = CONFIG_TYPE_INT;
150
+ else if(rb_obj_class(target) == cConfigBignum)
151
+ type = CONFIG_TYPE_INT64;
152
+ else if(rb_obj_class(target) == cConfigFloat)
153
+ type = CONFIG_TYPE_FLOAT;
154
+ else if(rb_obj_class(target) == cConfigString)
155
+ type = CONFIG_TYPE_STRING;
156
+ else if(rb_obj_class(target) == cConfigBoolean)
157
+ type = CONFIG_TYPE_BOOL;
158
+ else if(rb_obj_class(target) == cConfigGroup)
159
+ type = CONFIG_TYPE_GROUP;
160
+ else if(rb_obj_class(target) == cConfigList)
161
+ type = CONFIG_TYPE_LIST;
162
+ else if(rb_obj_class(target) == cConfigArray)
163
+ type = CONFIG_TYPE_ARRAY;
164
+ else
165
+ rb_bug("unknown setting class %s", rb_obj_classname(target));
166
+
167
+ config_setting_t* new_setting;
168
+ if(name == Qnil) {
169
+ new_setting = config_setting_add(setting, NULL, type);
170
+ } else {
171
+ Check_Type(name, T_STRING);
172
+ new_setting = config_setting_add(setting, RSTRING_PTR(name), type);
173
+ }
174
+
175
+ if(new_setting == NULL)
176
+ return 0;
177
+
178
+ VALUE rbNewSetting = rconfig_prepare_setting(new_setting);
179
+ rb_iv_set(target, "@setting", rbNewSetting);
180
+
181
+ if(rb_ary_includes(aConfigScalars, rb_obj_class(target)) == Qtrue)
182
+ rconfig_update_setting(new_setting, rb_iv_get(target, "@value"));
183
+
184
+ if(rb_ary_includes(aConfigAggregates, rb_obj_class(target)) == Qtrue) {
185
+ if(rb_obj_class(target) == cConfigGroup) {
186
+ VALUE hash = rb_iv_get(target, "@hash");
187
+ VALUE children = rb_funcall(hash, rb_intern("keys"), 0);
188
+ int i;
189
+ for(i = 0; i < RARRAY_LEN(children); i++) {
190
+ VALUE key = RARRAY_PTR(children)[i];
191
+ rconfig_do_append(new_setting, rb_hash_aref(hash, key), key);
192
+ }
193
+ } else {
194
+ VALUE children = rb_iv_get(target, "@list");
195
+ int i;
196
+ for(i = 0; i < RARRAY_LEN(children); i++) {
197
+ rconfig_do_append(new_setting, RARRAY_PTR(children)[i], Qnil);
198
+ }
199
+ }
200
+ }
201
+
202
+ return 1;
203
+ }
204
+
205
+ static VALUE rbConfigBaseSetting_initialize(VALUE self, VALUE setting)
206
+ {
207
+ if(setting != Qnil)
208
+ Check_Type(setting, T_DATA);
209
+ rb_iv_set(self, "@setting", setting);
210
+
211
+ return self;
212
+ }
213
+
214
+ static VALUE rbConfigBaseSetting_name(VALUE self)
215
+ {
216
+ if(rb_iv_get(self, "@setting") != Qnil) {
217
+ config_setting_t* setting = NULL;
218
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
219
+ return rb_str_new2(config_setting_name(setting));
220
+ } else {
221
+ return Qnil;
222
+ }
223
+ }
224
+
225
+ static VALUE rbConfigBaseSetting_parent(VALUE self)
226
+ {
227
+ if(rb_iv_get(self, "@setting") != Qnil) {
228
+ config_setting_t* setting = NULL;
229
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
230
+ return rconfig_wrap_setting(config_setting_parent(setting));
231
+ } else {
232
+ return Qnil;
233
+ }
234
+ }
235
+
236
+ static VALUE rbConfigBaseSetting_is_root(VALUE self)
237
+ {
238
+ if(rb_iv_get(self, "@setting") != Qnil) {
239
+ config_setting_t* setting = NULL;
240
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
241
+ return config_setting_is_root(setting) ? Qtrue : Qfalse;
242
+ } else {
243
+ return Qnil;
244
+ }
245
+ }
246
+
247
+ static VALUE rbConfigBaseSetting_index(VALUE self)
248
+ {
249
+ if(rb_iv_get(self, "@setting") != Qnil) {
250
+ config_setting_t* setting = NULL;
251
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
252
+ return INT2FIX(config_setting_index(setting));
253
+ } else {
254
+ return Qnil;
255
+ }
256
+ }
257
+
258
+ static VALUE rbConfigBaseSetting_line(VALUE self)
259
+ {
260
+ if(rb_iv_get(self, "@setting") != Qnil) {
261
+ config_setting_t* setting = NULL;
262
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
263
+ return INT2FIX(config_setting_source_line(setting));
264
+ } else {
265
+ return Qnil;
266
+ }
267
+ }
268
+
269
+ static VALUE rbConfigSetting_initialize(int argc, VALUE* argv, VALUE self)
270
+ {
271
+ VALUE value, setting;
272
+ rb_scan_args(argc, argv, "11", &value, &setting);
273
+
274
+ rb_call_super(1, &setting);
275
+
276
+ rconfig_check_setting_type(self, value);
277
+ rb_iv_set(self, "@value", value);
278
+
279
+ if(rb_iv_get(self, "@setting") != Qnil) {
280
+ config_setting_t* c_setting = NULL;
281
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, c_setting);
282
+ rb_iv_set(self, "@format", INT2FIX(config_setting_get_format(c_setting)));
283
+ } else {
284
+ rb_iv_set(self, "@format", cConfigFormatDefault);
285
+ }
286
+
287
+ return self;
288
+ }
289
+
290
+ static VALUE rbConfigSetting_get_value(VALUE self)
291
+ {
292
+ if(rb_iv_get(self, "@setting") != Qnil) {
293
+ config_setting_t* setting;
294
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
295
+ return rconfig_wrap_value(setting);
296
+ } else {
297
+ return rb_iv_get(self, "@value");
298
+ }
299
+ }
300
+
301
+ static VALUE rbConfigSetting_set_value(VALUE self, VALUE new_value)
302
+ {
303
+ rconfig_check_setting_type(self, new_value);
304
+
305
+ if(rb_iv_get(self, "@setting") != Qnil) {
306
+ config_setting_t* setting;
307
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
308
+ rconfig_update_setting(setting, new_value);
309
+ }
310
+
311
+ rb_iv_set(self, "@value", new_value);
312
+
313
+ return new_value;
314
+ }
315
+
316
+ static VALUE rbConfigSetting_get_format(VALUE self)
317
+ {
318
+ if(rb_iv_get(self, "@setting") != Qnil) {
319
+ config_setting_t* setting;
320
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
321
+ return INT2FIX(config_setting_get_format(setting));
322
+ } else {
323
+ return rb_iv_get(self, "format");
324
+ }
325
+ }
326
+
327
+ static VALUE rbConfigSetting_set_format(VALUE self, VALUE new_format)
328
+ {
329
+ if(rb_iv_get(self, "@setting") != Qnil) {
330
+ config_setting_t* setting;
331
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
332
+ if(!config_setting_set_format(setting, FIX2INT(new_format)))
333
+ rb_raise(eSettingFormatError, "invalid setting format %d", FIX2INT(new_format));
334
+ }
335
+
336
+ rb_iv_set(self, "@format", new_format);
337
+
338
+ return new_format;
339
+ }
340
+
341
+ static VALUE rbConfigAggregate_get(VALUE self, VALUE index);
342
+
343
+ static VALUE rbConfigAggregate_initialize(int argc, VALUE* argv, VALUE self)
344
+ {
345
+ VALUE setting = Qnil;
346
+ if(rb_obj_class(self) == cConfigGroup || rb_obj_class(self) == cConfigList) {
347
+ rb_scan_args(argc, argv, "01", &setting);
348
+ } else if(rb_obj_class(self) == cConfigArray) {
349
+ VALUE type = Qnil;
350
+ rb_scan_args(argc, argv, "02", &type, &setting);
351
+
352
+ if(type != Qnil && rb_ary_includes(aConfigScalars, type) != Qtrue)
353
+ rb_raise(rb_eTypeError, "invalid setting array type %s", rb_class2name(type));
354
+
355
+ rb_iv_set(self, "@type", type);
356
+ } else {
357
+ rb_raise(rb_eException, "never create Config::Aggregate itself");
358
+ }
359
+
360
+ rb_call_super(1, &setting);
361
+
362
+ rb_iv_set(self, "@list", rb_ary_new());
363
+ if(rb_obj_class(self) == cConfigGroup)
364
+ rb_iv_set(self, "@hash", rb_hash_new());
365
+
366
+ if(setting != Qnil && rb_obj_class(self) == cConfigArray) {
367
+ config_setting_t* c_setting;
368
+ Data_Get_Struct(setting, config_setting_t, c_setting);
369
+ if(config_setting_length(c_setting) > 0)
370
+ rb_iv_set(self, "@type", rb_obj_class(rbConfigAggregate_get(self, INT2FIX(0))));
371
+ }
372
+
373
+ return self;
374
+ }
375
+
376
+ static VALUE rbConfigAggregate_size(VALUE self)
377
+ {
378
+ config_setting_t* setting = NULL;
379
+ if(rb_iv_get(self, "@setting") != Qnil)
380
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
381
+
382
+ if(setting)
383
+ return INT2FIX(config_setting_length(setting));
384
+ else
385
+ return INT2FIX(RARRAY_LEN(rb_iv_get(self, "@list")));
386
+ }
387
+
388
+ static VALUE rbConfigAggregate_get(VALUE self, VALUE index)
389
+ {
390
+ config_setting_t* setting = NULL;
391
+ if(rb_iv_get(self, "@setting") != Qnil)
392
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
393
+
394
+ VALUE rbTarget = Qnil;
395
+
396
+ if(TYPE(index) == T_STRING && rb_obj_class(self) == cConfigGroup) {
397
+ if(setting) {
398
+ config_setting_t* target = config_setting_get_member(setting, RSTRING_PTR(index));
399
+ if(target)
400
+ rbTarget = rconfig_wrap_setting(target);
401
+ } else {
402
+ rbTarget = rb_hash_aref(rb_iv_get(self, "@hash"), index);
403
+ }
404
+ } else if(TYPE(index) == T_FIXNUM) {
405
+ if(setting) {
406
+ config_setting_t* target = config_setting_get_elem(setting, FIX2INT(index));
407
+ if(target)
408
+ rbTarget = rconfig_wrap_setting(target);
409
+ } else {
410
+ rbTarget = rb_ary_entry(rb_iv_get(self, "@list"), FIX2INT(index));
411
+ }
412
+ } else {
413
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_obj_classname(index));
414
+ }
415
+
416
+ if(rbTarget == Qnil)
417
+ if(TYPE(index) == T_STRING)
418
+ rb_raise(eSettingNotFoundError, "setting `%s' not found", RSTRING_PTR(index));
419
+ else
420
+ rb_raise(eSettingNotFoundError, "setting [%d] not found", FIX2INT(index));
421
+
422
+ return rbTarget;
423
+ }
424
+
425
+ static VALUE rbConfigAggregate_append(VALUE self, VALUE target)
426
+ {
427
+ config_setting_t* setting = NULL;
428
+ if(rb_iv_get(self, "@setting") != Qnil)
429
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
430
+
431
+ Check_Type(target, T_OBJECT);
432
+
433
+ VALUE type = rb_iv_get(self, "@type");
434
+ if(rb_obj_class(self) == cConfigArray) {
435
+ if(type != Qnil && type != rb_obj_class(target))
436
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", rb_obj_classname(target), rb_class2name(type));
437
+ if(type == Qnil && rb_ary_includes(aConfigScalars, rb_obj_class(target)) != Qtrue)
438
+ rb_raise(rb_eTypeError, "invalid setting array type %s", rb_obj_classname(target));
439
+ }
440
+
441
+ if(rb_ary_includes(aConfigSettings, rb_obj_class(target)) == Qtrue) {
442
+ if(setting)
443
+ rconfig_do_append(setting, target, Qnil);
444
+ rb_ary_push(rb_iv_get(self, "@list"), target);
445
+ } else {
446
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Config::BaseSetting)", rb_obj_classname(target));
447
+ }
448
+
449
+ if(rb_obj_class(self) == cConfigArray && type == Qnil)
450
+ rb_iv_set(self, "@type", rb_obj_class(target));
451
+
452
+ return target;
453
+ }
454
+
455
+ static VALUE rbConfigGroup_append(VALUE self, VALUE name, VALUE target)
456
+ {
457
+ Check_Type(name, T_STRING);
458
+ Check_Type(target, T_OBJECT);
459
+
460
+ config_setting_t* setting = NULL;
461
+ if(rb_iv_get(self, "@setting") != Qnil)
462
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
463
+
464
+ if(rb_ary_includes(aConfigSettings, rb_obj_class(target)) == Qtrue) {
465
+ if(rb_reg_match(rSettingNameRegexp, name) == Qnil)
466
+ rb_raise(eSettingNameError, "setting name `%s' contains invalid characters", RSTRING_PTR(name));
467
+ if(setting) {
468
+ if(!rconfig_do_append(setting, target, name))
469
+ rb_raise(eSettingNameError, "setting `%s' already exists", RSTRING_PTR(name));
470
+ } else if(rb_hash_aref(rb_iv_get(self, "@hash"), name) != Qnil) {
471
+ rb_raise(eSettingNameError, "setting `%s' already exists", RSTRING_PTR(name));
472
+ }
473
+ rb_ary_push(rb_iv_get(self, "@list"), target);
474
+ rb_hash_aset(rb_iv_get(self, "@hash"), name, target);
475
+ } else {
476
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Config::BaseSetting)", rb_obj_classname(target));
477
+ }
478
+
479
+ return target;
480
+ }
481
+
482
+ static VALUE rbConfigAggregate_delete(VALUE self, VALUE target)
483
+ {
484
+ config_setting_t* setting = NULL;
485
+ if(rb_iv_get(self, "@setting") != Qnil)
486
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
487
+
488
+ VALUE hash = rb_iv_get(self, "@hash"), list = rb_iv_get(self, "@list");
489
+
490
+ if(TYPE(target) == T_STRING && rb_obj_class(self) == cConfigGroup) {
491
+ if(setting)
492
+ config_setting_remove(setting, RSTRING_PTR(target));
493
+
494
+ rb_ary_delete_at(list, rb_hash_aref(hash, target));
495
+ rb_hash_delete(hash, target);
496
+ } else if(TYPE(target) == T_FIXNUM) {
497
+ int index = FIX2INT(target);
498
+ if(setting)
499
+ config_setting_remove_elem(setting, index);
500
+
501
+ if(rb_obj_class(self) == cConfigGroup)
502
+ rb_hash_delete(hash, rbConfigBaseSetting_name(rb_ary_entry(list, index)));
503
+ rb_ary_delete_at(list, index);
504
+ } else if(rb_ary_includes(aConfigSettings, rb_obj_class(target)) == Qtrue) {
505
+ VALUE name = rbConfigBaseSetting_name(target);
506
+ if(setting)
507
+ config_setting_remove(setting, RSTRING_PTR(name));
508
+
509
+ if(rb_obj_class(self) == cConfigGroup)
510
+ rb_hash_delete(hash, name);
511
+ rb_ary_delete(list, target);
512
+ } else {
513
+ if(rb_obj_class(self) == cConfigGroup)
514
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String, Fixnum or Config::BaseSetting)", rb_obj_classname(target));
515
+ else
516
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or Config::BaseSetting)", rb_obj_classname(target));
517
+ }
518
+
519
+ return Qnil;
520
+ }
521
+
522
+ static VALUE rbConfig_initialize(VALUE self)
523
+ {
524
+ config_t* config = (config_t*) malloc(sizeof(config_t));
525
+ config_init(config);
526
+ config_set_destructor(config, &rconfig_destroy_setting);
527
+
528
+ VALUE rbConfig = Data_Wrap_Struct(rb_cObject, 0, config_destroy, config);
529
+ rb_iv_set(self, "@config", rbConfig);
530
+
531
+ return self;
532
+ }
533
+
534
+ static VALUE rbConfig_read_bang(VALUE self, VALUE path)
535
+ {
536
+ Check_Type(path, T_STRING);
537
+
538
+ config_t* config;
539
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
540
+
541
+ if(!config_read_file(config, RSTRING_PTR(path))) {
542
+ if(config_error_line(config) == 0)
543
+ rb_raise(rb_eIOError, "cannot load config: I/O error");
544
+ else
545
+ rb_raise(eConfigParseError, "cannot parse config on line %d: `%s'",
546
+ config_error_line(config), config_error_text(config));
547
+ }
548
+
549
+ return Qtrue;
550
+ }
551
+
552
+ static VALUE rbConfig_write_bang(VALUE self, VALUE path)
553
+ {
554
+ Check_Type(path, T_STRING);
555
+
556
+ config_t* config;
557
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
558
+
559
+ if(!config_write_file(config, RSTRING_PTR(path)))
560
+ rb_raise(rb_eIOError, "cannot save config: I/O error");
561
+
562
+ return Qtrue;
563
+ }
564
+
565
+ static VALUE rbConfig_read(VALUE self, VALUE path)
566
+ {
567
+ Check_Type(path, T_STRING);
568
+
569
+ config_t* config;
570
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
571
+
572
+ return config_read_file(config, RSTRING_PTR(path)) ? Qtrue : Qfalse;
573
+ }
574
+
575
+ static VALUE rbConfig_write(VALUE self, VALUE path)
576
+ {
577
+ Check_Type(path, T_STRING);
578
+
579
+ config_t* config;
580
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
581
+
582
+ return config_write_file(config, RSTRING_PTR(path)) ? Qtrue : Qfalse;
583
+ }
584
+
585
+ static VALUE rbConfig_root(VALUE self)
586
+ {
587
+ config_t* config;
588
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
589
+
590
+ return rconfig_wrap_setting(config_root_setting(config));
591
+ }
592
+
593
+ static VALUE rbConfig_lookup(VALUE self, VALUE handle)
594
+ {
595
+ if(TYPE(handle) == T_STRING) {
596
+ config_t* config;
597
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
598
+
599
+ config_setting_t* setting;
600
+ setting = config_lookup(config, RSTRING_PTR(handle));
601
+
602
+ if(setting == NULL)
603
+ rb_raise(eSettingNotFoundError, "setting `%s' not found", RSTRING_PTR(handle));
604
+
605
+ return rconfig_wrap_setting(setting);
606
+ } else if(TYPE(handle) == T_FIXNUM) {
607
+ return rbConfigAggregate_get(rbConfig_root(self), handle);
608
+ } else {
609
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_obj_classname(handle));
610
+ }
611
+ }
612
+
613
+ static VALUE rbConfig_append(VALUE self, VALUE name, VALUE target)
614
+ {
615
+ return rbConfigGroup_append(rbConfig_root(self), name, target);
616
+ }
617
+
618
+ static VALUE rbConfig_delete(VALUE self, VALUE name)
619
+ {
620
+ return rbConfigAggregate_delete(rbConfig_root(self), name);
621
+ }
622
+
623
+ static VALUE rbConfig_size(VALUE self)
624
+ {
625
+ return rbConfigAggregate_size(rbConfig_root(self));
626
+ }
627
+
628
+ void Init_rlibconfig()
629
+ {
630
+ cConfig = rb_define_class("LibConfig", rb_cObject);
631
+ rb_define_method(cConfig, "initialize", rbConfig_initialize, 0);
632
+ rb_define_method(cConfig, "read!", rbConfig_read_bang, 1);
633
+ rb_define_method(cConfig, "write!", rbConfig_write_bang, 1);
634
+ rb_define_method(cConfig, "read", rbConfig_read, 1);
635
+ rb_define_method(cConfig, "write", rbConfig_write, 1);
636
+ rb_define_method(cConfig, "root", rbConfig_root, 0);
637
+ rb_define_method(cConfig, "lookup", rbConfig_lookup, 1);
638
+ rb_define_method(cConfig, "[]", rbConfig_lookup, 1);
639
+ rb_define_method(cConfig, "append", rbConfig_append, 2);
640
+ rb_define_method(cConfig, "delete", rbConfig_delete, 1);
641
+ rb_define_method(cConfig, "size", rbConfig_size, 0);
642
+
643
+ cConfigBaseSetting = rb_define_class_under(cConfig, "BaseSetting", rb_cObject);
644
+ rb_define_method(cConfigBaseSetting, "initialize", rbConfigBaseSetting_initialize, 1);
645
+ rb_define_method(cConfigBaseSetting, "name", rbConfigBaseSetting_name, 0);
646
+ rb_define_method(cConfigBaseSetting, "parent", rbConfigBaseSetting_parent, 0);
647
+ rb_define_method(cConfigBaseSetting, "root?", rbConfigBaseSetting_is_root, 0);
648
+ rb_define_method(cConfigBaseSetting, "index", rbConfigBaseSetting_index, 0);
649
+ rb_define_method(cConfigBaseSetting, "line", rbConfigBaseSetting_line, 0);
650
+
651
+ cConfigSetting = rb_define_class_under(cConfig, "Setting", cConfigBaseSetting);
652
+ rb_define_method(cConfigSetting, "initialize", rbConfigSetting_initialize, -1);
653
+ rb_define_method(cConfigSetting, "value", rbConfigSetting_get_value, 0);
654
+ rb_define_method(cConfigSetting, "value=", rbConfigSetting_set_value, 1);
655
+ rb_define_method(cConfigSetting, "format", rbConfigSetting_get_format, 0);
656
+ rb_define_method(cConfigSetting, "format=", rbConfigSetting_set_format, 1);
657
+
658
+ cConfigFormatDefault = INT2FIX(CONFIG_FORMAT_DEFAULT);
659
+ rb_define_const(cConfig, "FORMAT_DEFAULT", cConfigFormatDefault);
660
+ cConfigFormatHex = INT2FIX(CONFIG_FORMAT_HEX);
661
+ rb_define_const(cConfig, "FORMAT_HEX", cConfigFormatHex);
662
+
663
+ cConfigFixnum = rb_define_class_under(cConfig, "Fixnum", cConfigSetting);
664
+ cConfigBignum = rb_define_class_under(cConfig, "Bignum", cConfigSetting);
665
+ cConfigFloat = rb_define_class_under(cConfig, "Float", cConfigSetting);
666
+ cConfigBoolean = rb_define_class_under(cConfig, "Boolean", cConfigSetting);
667
+ cConfigString = rb_define_class_under(cConfig, "String", cConfigSetting);
668
+
669
+ cConfigAggregate = rb_define_class_under(cConfig, "Aggregate", cConfigBaseSetting);
670
+ rb_define_method(cConfigAggregate, "initialize", rbConfigAggregate_initialize, -1);
671
+ rb_define_method(cConfigAggregate, "size", rbConfigAggregate_size, 0);
672
+ rb_define_method(cConfigAggregate, "get", rbConfigAggregate_get, 1);
673
+ rb_define_method(cConfigAggregate, "[]", rbConfigAggregate_get, 1);
674
+ rb_define_method(cConfigAggregate, "delete", rbConfigAggregate_delete, 1);
675
+
676
+ cConfigGroup = rb_define_class_under(cConfig, "Group", cConfigAggregate);
677
+ rb_define_method(cConfigGroup, "append", rbConfigGroup_append, 2);
678
+ cConfigArray = rb_define_class_under(cConfig, "Array", cConfigAggregate);
679
+ rb_define_method(cConfigArray, "append", rbConfigAggregate_append, 1);
680
+ rb_define_method(cConfigArray, "<<", rbConfigAggregate_append, 1);
681
+ cConfigList = rb_define_class_under(cConfig, "List", cConfigAggregate);
682
+ rb_define_method(cConfigList, "append", rbConfigAggregate_append, 1);
683
+ rb_define_method(cConfigList, "<<", rbConfigAggregate_append, 1);
684
+
685
+ aConfigScalars = rb_ary_new3(5, cConfigFixnum, cConfigBignum, cConfigFloat, cConfigBoolean, cConfigString);
686
+ aConfigAggregates = rb_ary_new3(3, cConfigGroup, cConfigArray, cConfigList);
687
+ aConfigSettings = rb_ary_plus(aConfigScalars, aConfigAggregates);
688
+
689
+ rb_define_const(cConfig, "SCALARS", aConfigScalars);
690
+ rb_define_const(cConfig, "AGGREGATES", aConfigAggregates);
691
+ rb_define_const(cConfig, "SETTINGS", aConfigSettings);
692
+
693
+ char* settingNameRegexp = "^[A-Za-z*][A-Za-z\\-_*]*$";
694
+ rSettingNameRegexp = rb_reg_new(settingNameRegexp, strlen(settingNameRegexp), 0);
695
+
696
+ eConfigParseError = rb_define_class("ConfigParseError", rb_eException);
697
+ eSettingNotFoundError = rb_define_class("SettingNotFoundError", rb_eException);
698
+ eSettingFormatError = rb_define_class("SettingFormatError", rb_eException);
699
+ eSettingNameError = rb_define_class("SettingNameError", rb_eException);
700
+ }
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rlibconfig
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - John Mah
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: johnmah@rogers.com
15
+ executables: []
16
+ extensions:
17
+ - ext/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ext/extconf.rb
21
+ - ext/rlibconfig.c
22
+ homepage:
23
+ licenses: []
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.2.2
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: libconfig bindings
45
+ test_files: []