Class: UCL

Inherits:
Object
  • Object
show all
Defined in:
ext/ucl.c,
ext/ucl.c

Overview

Parser for configuration files written in the Universal Configuration Language (UCL), a JSON-superset format handled by the libucl library.

Parsed configurations are returned as plain Ruby objects (Hash, Array, String, Integer, Float, true/false, nil).

Examples:

Parse a string

UCL.parse('name = value')        #=> { "name" => "value" }

Load a file with symbol keys

UCL.load_file('foo.conf', UCL::KEY_SYMBOL)

See Also:

Defined Under Namespace

Classes: Error

Constant Summary collapse

KEY_LOWERCASE =

convert all object keys to lower case.

Flag
NO_TIME =

do not parse time values; keep them as strings.

Flag
DISABLE_MACRO =

disable processing of macros (e.g. .include).

Flag
NO_FILEVARS =

do not predefine the file variables ($FILENAME, $CURDIR). This affects parse; load_file still derives those variables from the file being loaded.

Flag
KEY_SYMBOL =

return object keys as Symbol instead of String.

Flag

Class Method Summary collapse

Class Method Details

.flagsInteger

Default flags applied by parse and load_file when none are given explicitly.

Returns:

  • (Integer)

    the current default flags (0 by default)



163
164
165
166
167
# File 'ext/ucl.c', line 163

static VALUE
ucl_s_get_flags(VALUE klass)
{
    return rb_iv_get(klass, "@flags");
}

.flags=(val) ⇒ Integer

Set the default flags applied by parse and load_file when none are given explicitly.

Parameters:

  • val (Integer)

    flags, combined with a bitwise OR

Returns:

  • (Integer)

    the flags that were set



181
182
183
184
185
186
187
# File 'ext/ucl.c', line 181

static VALUE
ucl_s_set_flags(VALUE klass, VALUE val)
{
    rb_check_type(val, T_FIXNUM);
    rb_iv_set(klass, "@flags", val);
    return val;
}

.load_file(*args) ⇒ Hash, ...

Load and parse a UCL configuration from a file.

Unlike parse, this defines the file variables ($FILENAME, $CURDIR) from the loaded file, so they can be referenced from within the configuration.

Examples:

UCL.load_file('foo.conf', UCL::KEY_SYMBOL)

Parameters:

  • file (String)

    path to the configuration file

  • flags (Integer)

    parsing flags combined with a bitwise OR; defaults to flags when omitted

Returns:

  • (Hash, Array, Object)

    the configuration as Ruby objects

Raises:

  • (UCL::Error)

    if the file cannot be read or is malformed



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'ext/ucl.c', line 267

static VALUE
ucl_s_load_file(int argc, VALUE *argv, VALUE klass)
{
    VALUE file, flags;
    rb_scan_args(argc, argv, "11", &file, &flags);
    if (NIL_P(flags)) flags = ucl_s_get_flags(mUCL);

    rb_check_type(file,  T_STRING);
    rb_check_type(flags, T_FIXNUM);
	
    int   c_flags = FIX2INT(flags) & ucl_allowed_c_flags;
    char *c_file  = StringValueCStr(file);

    struct ucl_parser *parser =
	ucl_parser_new(c_flags | UCL_PARSER_NO_IMPLICIT_ARRAYS);
    if (parser == NULL)
	rb_raise(eUCLError, "failed to allocate UCL parser");

    ucl_parser_add_file(parser, c_file);
    ucl_parser_set_filevars(parser, c_file, false);

    if (ucl_parser_get_error(parser)) {
	/* Copy the message into the exception before freeing the parser:
	 * ucl_parser_get_error() points into memory owned by the parser. */
	VALUE err = rb_exc_new2(eUCLError, ucl_parser_get_error(parser));
	ucl_parser_free(parser);
	rb_exc_raise(err);
    }

    bool          failed = false;
    ucl_object_t *root   = ucl_parser_get_object(parser);
    VALUE         res    = _iterate_valid_ucl(root, FIX2INT(flags), &failed);

    ucl_parser_free(parser);
    if (root != NULL) { ucl_object_unref(root); }

    if (failed) {
    	rb_raise(eUCLError, "failed to iterate over ucl object");
    }

    return res;
}

.parse(*args) ⇒ Hash, ...

Parse a UCL configuration from a string.

Examples:

UCL.parse('name = value')            #=> { "name" => "value" }
UCL.parse('name = value', UCL::KEY_SYMBOL)  #=> { :name => "value" }

Parameters:

  • data (String)

    the UCL configuration to parse

  • flags (Integer)

    parsing flags combined with a bitwise OR; defaults to flags when omitted

Returns:

  • (Hash, Array, Object)

    the configuration as Ruby objects

Raises:

  • (UCL::Error)

    if the configuration is malformed



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'ext/ucl.c', line 205

static VALUE
ucl_s_parse(int argc, VALUE *argv, VALUE klass)
{
    VALUE data, flags;
    rb_scan_args(argc, argv, "11", &data, &flags);
    if (NIL_P(flags)) flags = ucl_s_get_flags(mUCL);

    rb_check_type(data,  T_STRING);
    rb_check_type(flags, T_FIXNUM);
	
    int c_flags = FIX2INT(flags) & ucl_allowed_c_flags;

    struct ucl_parser *parser =
	ucl_parser_new(c_flags | UCL_PARSER_NO_IMPLICIT_ARRAYS);
    if (parser == NULL)
	rb_raise(eUCLError, "failed to allocate UCL parser");

    ucl_parser_add_chunk(parser,
			 (unsigned char *)RSTRING_PTR(data),
			 RSTRING_LEN(data));

    if (ucl_parser_get_error(parser)) {
	/* Copy the message into the exception before freeing the parser:
	 * ucl_parser_get_error() points into memory owned by the parser. */
	VALUE err = rb_exc_new2(eUCLError, ucl_parser_get_error(parser));
	ucl_parser_free(parser);
	rb_exc_raise(err);
    }

    bool          failed = false;
    ucl_object_t *root   = ucl_parser_get_object(parser);
    VALUE         res    = _iterate_valid_ucl(root, FIX2INT(flags), &failed);

    ucl_parser_free(parser);
    if (root != NULL) { ucl_object_unref(root); }

    if (failed) {
    	rb_raise(eUCLError, "failed to iterate over ucl object");
    }

    return res;
}