rlibconfig 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []