Back

NAME

conf_parse - parse confetti

LIBRARY

Configuration parser (libconfetti, -lconfetti)

SYNOPSIS

#include <confetti.h>

conf_unit *conf_parse(const char *str, const conf_options *opts, conf_error *err);

DESCRIPTION

The conf_parse() function parses str as Confetti source text and constructs an in-memory representation of the processed configuration unit. It must be freed with conf_free(3).

If an error occurs during parsing, then NULL is returned and err, if provided, is populated with error details.

Any pointers returned by functions listed in SEE ALSO are managed by the unit and do not require separate deallocation. They remain valid until the unit is freed with conf_free(3).

The behavior of the Confetti parser can be controlled with the optional opts argument which is documented below.

Error structure

The conf_error structure includes the following fields:

long where;
conf_errno code;
char description[48];

The code field will be populated by the implementation with a constant described in RETURN VALUE.

The where field will be populated by the implementation with the UTF-8 code unit index of the location where the error occurred in str.

The description field will be populated by the implementation with an error message localized in US English.

Options structure

The conf_options structure includes the following fields:

int max_depth;
bool allow_bidi;
conf_allocfn allocator;
void *user_data;
conf_extensions *extensions;

The max_depth field, if non-zero, specifies the maximum nesting depth of Confetti subdirectives.

The allow_bidi field, if true, allows bidirectional formatting characters in str. It is recommended to disable these characters, unless an implementation is prepared to properly process them. Mishandling these characters can result in unexpected behaviors, such as the Trojan Source vulnerability.

The allocator field, if non-NULL, must point to a user implemented custom memory allocator, the behavior of which is described in the following subsection.

The user_data field is a user pointer passed to the allocator function as-is. It is also passed to the callback associated with the conf_walk(3) function.

The extensions field, if non-NULL, refers to the extensions structure as documented in the subsequent subsection.

Extensions structure

The conf_extensions structure includes the following fields:

const char **punctuator_arguments;
bool c_style_comments;
bool expression_arguments;

The punctuator_arguments field is an array of strings where each string is to be interpreted as a punctuator argument. The last element must be NULL to terminate the array.

The c_style_comments field, if true, enables C style single and multi-line comments.

The expression_arguments field, if true, interprets arguments enclosed in parentheses as expressions.

Allocator function

The conf_allocfn function accepts three arguments:

void *ud;
void *ptr;
size_t size;

If the ptr argument is NULL, then the implementation must behave like malloc(3) and return a valid pointer, otherwise, it must behave like free(3) and free ptr and return NULL. The size argument is either the size of the memory being allocated or the size of the memory being freed depending on if the implementation is to behave like malloc(3) or free(3).

RETURN VALUE

The conf_parse() function returns an instance of a Confetti configuration unit or NULL if an error occurs. If an error occurs, then err, if provided, will be populated with one of the following conf_errno constants:

CONF_NO_ERROR

When str is parsed without errors.

CONF_OUT_OF_MEMORY

If dynamic memory allocation fails. The implementation guarantees all intermediate allocations will be freed to avoid resource leakage.

CONF_BAD_SYNTAX,

If a Confetti syntax error is discovered.

CONF_ILLEGAL_BYTE_SEQUENCE,

If a malformed UTF-8 sequence is found.

CONF_INVALID_OPERATION

If str is NULL.

CONF_MAX_DEPTH_EXCEEDED

If the maximum subdirective nesting depth is exceeded.

EXAMPLES

The following snippet demonstrates how to parse Confetti source text with conf_parse(). The string "..." is used as a placeholder for a Confetti source string.

conf_error error = {0};
conf_unit *unit = conf_parse("...", NULL, &error);
if (unit == NULL) {
    printf("error: %s, error.description);
}

The following snippet demonstrates how to set options and extensions with the conf_options and conf_extensions structures. This particular example enables the punctuator arguments extension to treat ":=", "+", and "-" as distinct arguments. It also limits the maximum subdirective nesting depth to ten.

const char *punctuators[] = {":=", "+", "-", NULL};
const conf_extensions extensions = {
    .punctuator_arguments = punctuators,
};

const conf_options options = {
    .extensions = &extensions,
    .max_depth = 10,
};

conf_unit *unit = conf_parse("...", &options, NULL);

The conf_options structure accepts a custom memory allocator that must behave like malloc(3) or free(3) depending on how it's called. The following snippet shows a simple implementation of a custom memory allocator.

void *allocator(void *ud, void *ptr, size_t size) {
    if (ptr == NULL) {
        return malloc(size);
    } else {
        free(ptr);
        return NULL;
    }
}

const conf_options options = { .allocator = &allocator };
conf_unit *unit = conf_parse("...", &options, NULL);

SEE ALSO

conf_free(3), conf_get_root(3), conf_get_comment(3), conf_get_comment_count(3), conf_get_directive(3), conf_get_directive_count(3), conf_get_argument(3), conf_get_argument_count(3)

LICENSING

Confetti is Open Source software distributed under the MIT License. Please see the LICENSE file included with the Confetti distribution for details.