ucl 0.1.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.
- checksums.yaml +7 -0
- data/ext/extconf.rb +6 -0
- data/ext/ucl.c +210 -0
- data/ucl.gemspec +19 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 123bfade721343ef51a1b839b450365e7d2aa934e16e9d537a708582336aca60
|
4
|
+
data.tar.gz: c2f59b562e9a13fb4535e65055acf6d4fa8e140161ecb445875699314163cc93
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fe5a117504dd4694952d5555107a8c7c886ca25a5a2bebe5e52f394552fbf39386175040080a85dcaf4a240d7837af436a483255ae0f2411932de2b62bbed98f
|
7
|
+
data.tar.gz: ccebbfb07adabb8e892c855ccacf385ee79a81415b5f57a1b1ce50fffb7fb01e233902265bac6f6950fc3aa93e44f8a8067c122a08e029ce85df1348294bb94c
|
data/ext/extconf.rb
ADDED
data/ext/ucl.c
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <ruby/io.h>
|
3
|
+
#include <ucl.h>
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <stdbool.h>
|
6
|
+
|
7
|
+
/* Fake flag */
|
8
|
+
#define UCL_PARSER_KEY_SYMBOL (1 << 10)
|
9
|
+
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Document-class: UCL
|
13
|
+
*
|
14
|
+
* UCL configuration file.
|
15
|
+
*/
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Document-class: UCL::Error
|
19
|
+
*
|
20
|
+
* Generic error raised by UCL.
|
21
|
+
*/
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
static VALUE mUCL = Qundef;
|
26
|
+
static VALUE eUCLError = Qundef;
|
27
|
+
|
28
|
+
|
29
|
+
VALUE
|
30
|
+
_iterate_valid_ucl(ucl_object_t const *root, int flags)
|
31
|
+
{
|
32
|
+
const ucl_object_t *obj;
|
33
|
+
ucl_object_iter_t it = NULL;
|
34
|
+
const ucl_object_t *cur;
|
35
|
+
ucl_object_iter_t it_obj = NULL;
|
36
|
+
|
37
|
+
VALUE lst = rb_ary_new();
|
38
|
+
|
39
|
+
while ((obj = ucl_object_iterate (root, &it, false))) {
|
40
|
+
VALUE val;
|
41
|
+
|
42
|
+
switch (obj->type) {
|
43
|
+
case UCL_INT:
|
44
|
+
val = rb_ll2inum((long long)ucl_object_toint(obj));
|
45
|
+
break;
|
46
|
+
|
47
|
+
case UCL_FLOAT:
|
48
|
+
val = rb_float_new(ucl_object_todouble(obj));
|
49
|
+
break;
|
50
|
+
|
51
|
+
case UCL_STRING:
|
52
|
+
val = rb_str_new_cstr(ucl_object_tostring(obj));
|
53
|
+
break;
|
54
|
+
|
55
|
+
case UCL_BOOLEAN:
|
56
|
+
val = ucl_object_toboolean(obj) ? Qtrue : Qfalse;
|
57
|
+
break;
|
58
|
+
|
59
|
+
case UCL_TIME:
|
60
|
+
val = rb_float_new(ucl_object_todouble(obj));
|
61
|
+
break;
|
62
|
+
|
63
|
+
case UCL_OBJECT:
|
64
|
+
it_obj = NULL;
|
65
|
+
val = rb_hash_new();
|
66
|
+
while ((cur = ucl_object_iterate(obj, &it_obj, true))) {
|
67
|
+
const char *obj_key = ucl_object_key(cur);
|
68
|
+
VALUE key = (flags & UCL_PARSER_KEY_SYMBOL)
|
69
|
+
? rb_id2sym(rb_intern(obj_key))
|
70
|
+
: rb_str_new_cstr(obj_key);
|
71
|
+
rb_hash_aset(val, key, _iterate_valid_ucl(cur, flags));
|
72
|
+
}
|
73
|
+
break;
|
74
|
+
|
75
|
+
case UCL_ARRAY:
|
76
|
+
it_obj = NULL;
|
77
|
+
val = rb_ary_new();
|
78
|
+
while ((cur = ucl_object_iterate (obj, &it_obj, true))) {
|
79
|
+
rb_ary_push(val, _iterate_valid_ucl(cur, flags));
|
80
|
+
}
|
81
|
+
break;
|
82
|
+
|
83
|
+
case UCL_USERDATA:
|
84
|
+
val = rb_str_new(obj->value.sv, obj->len);
|
85
|
+
break;
|
86
|
+
|
87
|
+
case UCL_NULL:
|
88
|
+
val = Qnil;
|
89
|
+
break;
|
90
|
+
|
91
|
+
default:
|
92
|
+
rb_bug("unhandled type (%d)", obj->type);
|
93
|
+
|
94
|
+
}
|
95
|
+
rb_ary_push(lst, val);
|
96
|
+
|
97
|
+
}
|
98
|
+
|
99
|
+
switch(RARRAY_LENINT(lst)) {
|
100
|
+
case 0: return Qnil;
|
101
|
+
case 1: return RARRAY_PTR(lst)[0];
|
102
|
+
default: return lst;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Parse a configuration file
|
110
|
+
*
|
111
|
+
* @param data [String]
|
112
|
+
* @param flags [Integer]
|
113
|
+
*
|
114
|
+
* @return configuration file as ruby objects.
|
115
|
+
*/
|
116
|
+
static VALUE
|
117
|
+
ucl_s_parse(int argc, VALUE *argv, VALUE klass)
|
118
|
+
{
|
119
|
+
static int allowed_flags = UCL_PARSER_KEY_LOWERCASE |
|
120
|
+
UCL_PARSER_NO_TIME |
|
121
|
+
UCL_PARSER_DISABLE_MACRO |
|
122
|
+
UCL_PARSER_NO_FILEVARS ;
|
123
|
+
|
124
|
+
VALUE data, flags;
|
125
|
+
rb_scan_args(argc, argv, "11", &data, &flags);
|
126
|
+
if (NIL_P(flags)) flags = INT2FIX(0);
|
127
|
+
|
128
|
+
rb_check_type(data, T_STRING);
|
129
|
+
rb_check_type(flags, T_FIXNUM);
|
130
|
+
|
131
|
+
int c_flags = FIX2INT(flags) & allowed_flags;
|
132
|
+
|
133
|
+
struct ucl_parser *parser =
|
134
|
+
ucl_parser_new(c_flags | UCL_PARSER_NO_IMPLICIT_ARRAYS);
|
135
|
+
|
136
|
+
ucl_parser_add_chunk(parser,
|
137
|
+
(unsigned char *)RSTRING_PTR(data),
|
138
|
+
RSTRING_LEN(data));
|
139
|
+
|
140
|
+
if (ucl_parser_get_error(parser)) {
|
141
|
+
rb_raise(eUCLError, "%s", ucl_parser_get_error(parser));
|
142
|
+
}
|
143
|
+
|
144
|
+
ucl_object_t *root = ucl_parser_get_object(parser);
|
145
|
+
|
146
|
+
VALUE res = _iterate_valid_ucl(root, FIX2INT(flags));
|
147
|
+
|
148
|
+
if (parser != NULL) {
|
149
|
+
ucl_parser_free(parser);
|
150
|
+
}
|
151
|
+
|
152
|
+
if (root != NULL) {
|
153
|
+
ucl_object_unref(root);
|
154
|
+
}
|
155
|
+
|
156
|
+
return res;
|
157
|
+
}
|
158
|
+
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Load configuration file
|
162
|
+
*
|
163
|
+
* @param file [String]
|
164
|
+
* @param flags [Integer]
|
165
|
+
*
|
166
|
+
* @example
|
167
|
+
* UCL.load_file('foo.conf', UCL::KEY_SYMBOL)
|
168
|
+
*
|
169
|
+
* @return configuration file as ruby objects.
|
170
|
+
*/
|
171
|
+
static VALUE
|
172
|
+
ucl_s_load_file(int argc, VALUE *argv, VALUE klass)
|
173
|
+
{
|
174
|
+
VALUE file, flags;
|
175
|
+
rb_scan_args(argc, argv, "11", &file, &flags);
|
176
|
+
|
177
|
+
VALUE read_kwargs = rb_hash_new();
|
178
|
+
rb_hash_aset(read_kwargs, rb_id2sym(rb_intern("encoding")),
|
179
|
+
rb_str_new_cstr("BINARY"));
|
180
|
+
|
181
|
+
VALUE read_args[] = { file, read_kwargs };
|
182
|
+
VALUE data = rb_funcallv_kw(rb_cFile, rb_intern("read"),
|
183
|
+
2, read_args, RB_PASS_KEYWORDS);
|
184
|
+
|
185
|
+
VALUE parse_args[] = { data, flags };
|
186
|
+
return ucl_s_parse(2, parse_args, klass);
|
187
|
+
}
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
void Init_ucl(void) {
|
193
|
+
/* Main classes */
|
194
|
+
mUCL = rb_define_class("UCL", rb_cObject);
|
195
|
+
eUCLError = rb_define_class_under(mUCL, "Error", rb_eStandardError);
|
196
|
+
|
197
|
+
/* Constants */
|
198
|
+
rb_define_const(mUCL, "KEY_LOWERCASE", INT2FIX(UCL_PARSER_KEY_LOWERCASE));
|
199
|
+
rb_define_const(mUCL, "NO_TIME", INT2FIX(UCL_PARSER_NO_TIME ));
|
200
|
+
rb_define_const(mUCL, "DISABLE_MACRO", INT2FIX(UCL_PARSER_DISABLE_MACRO));
|
201
|
+
rb_define_const(mUCL, "NO_FILEVARS", INT2FIX(UCL_PARSER_NO_FILEVARS ));
|
202
|
+
rb_define_const(mUCL, "KEY_SYMBOL", INT2FIX(UCL_PARSER_KEY_SYMBOL ));
|
203
|
+
|
204
|
+
/* Definitions */
|
205
|
+
rb_define_singleton_method(mUCL, "load_file", ucl_s_load_file, -1);
|
206
|
+
rb_define_singleton_method(mUCL, "parse", ucl_s_parse, -1);
|
207
|
+
|
208
|
+
}
|
209
|
+
|
210
|
+
|
data/ucl.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'ucl'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.summary = " Universal configuration library parser"
|
5
|
+
s.description = <<~EOF
|
6
|
+
|
7
|
+
Read configuration file in UCL format (binding to the libucl).
|
8
|
+
|
9
|
+
EOF
|
10
|
+
|
11
|
+
s.homepage = 'https://github.com/sdalu/ruby-ucl'
|
12
|
+
s.license = 'MIT'
|
13
|
+
|
14
|
+
s.authors = [ "Stéphane D'Alu" ]
|
15
|
+
s.email = [ 'sdalu@sdalu.com' ]
|
16
|
+
|
17
|
+
s.extensions = [ 'ext/extconf.rb' ]
|
18
|
+
s.files = %w[ ucl.gemspec ] + Dir['ext/**/*.{c,h,rb}']
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ucl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stéphane D'Alu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-12-19 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2+
|
14
|
+
|
15
|
+
Read configuration file in UCL format (binding to the libucl).
|
16
|
+
|
17
|
+
email:
|
18
|
+
- sdalu@sdalu.com
|
19
|
+
executables: []
|
20
|
+
extensions:
|
21
|
+
- ext/extconf.rb
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- ext/extconf.rb
|
25
|
+
- ext/ucl.c
|
26
|
+
- ucl.gemspec
|
27
|
+
homepage: https://github.com/sdalu/ruby-ucl
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubygems_version: 3.3.23
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: Universal configuration library parser
|
50
|
+
test_files: []
|
51
|
+
...
|