% limb manual
% copa_init(3)
% limb 0.1.0
% 2023-07-24
# NAME
copa\_init, copa\_is\_section, copa\_name, copa\_next, copa\_nlen, copa\_value,
copa\_vlen - configuration parsing
# SYNOPSIS
#include <limb/copa.h>
```pre hl
void copa_init(const char *<em>data</em>, size_t <em>dlen</em>, struct copa *<em>copa</em>)
int copa_next(struct copa *<em>copa</em>)
int copa_is_section(struct copa *<em>copa</em>)
const char *copa_name(struct copa *<em>copa</em>)
size_t copa_nlen(struct copa *<em>copa</em>)
const char *copa_value(struct copa *<em>copa</em>)
size_t copa_vlen(struct copa *<em>copa</em>)
```
# DESCRIPTION
The `copa_init`() function will initialize the opaque structure pointed to by
`copa` for parsing configuration pointed by `data` of length `dlen` bytes.
Once initialized, repeated calls can be made to the `copa_next`() function to
progress through parsing of the configuration. It is required that the data
pointed by `data` not change during the entire process.
Configuration data here is expected to be an INI-like text, processed line by
line using LF (`\n`) as delimiter, that can be be organized into sections. A
section is begins with a name having the section's name enclosed within square
brackets, e.g:
[section name]
Options can be specified with or without value. If an equal sign (`=`) is found
on a line, the option name is what comes before, its value what comes after.
Else the option has no value.
If an equal sign if found, there must be a value, i.e. using `option=` is
invalid.
Characters considered space (refer to [isspace](3)) on the beginning of a line
are skipped, as are those of the end of a line.
Any line beginning (past spaces) with a semi-colon (`;`) or a dash sign (`#`) is
considered a comment and skipped entirely.
! HINT:
! To allow setting an option to nothing, or have a value beginning/ending with
! spaces, it is possible to use quotes, e.g. use `option = ""`
!
! Note that copa itself doesn't deal with quoting, and would in such a case
! return a pointer to the string `""` (of length 2) as value. It is up to the
! caller to then process that as being an empty string/value.
The `copa_next`() function must be called on a previously initialized opaque
structure, pointed to be `copa`, and will advance parsing up to the next element
(section or option), if any.
If it returns 1, parsing was successful and the macros below can then be used to
process things further. Otherwise, parsing stops there. It is possible to then
re-use the same opaque structure with a new call to `copa_init`() in order to
parse another configuration.
The `copa_is_section`() macro will return non-zero is the current element, as
defined by the state of the opaque structure pointed to by `copa`, is of a
section, and zero otherwise.
The `copa_name`() macro will return a pointer to the name of the current
element, as defined by the state of the opaque structure pointed to by `copa`.
This is *not* a NUL-terminated string, and instead shall only be read for a
length whose value will be returned by the `copa_nlen`() macro.
The `copa_value`() macro is similar to the `copa_name`() macro, only for the
value of the option. It should not be used for sections, nor if there are no
value given for the current option, which should be determined by checking if
the length of the value is non-zero, as returned by the `copa_vlen`() macro.
# RETURN VALUE
The `copa_next`() function returns 1 when parsing successfully progressed into
the next element. It returns 0 if parsing was successful and the end of data
was reached, i.e. parsing successfully ended.
Otherwise it returns -1 and sets `errno` to indicate the error.
The `copa_name`() macro returns a pointer to the name of the current element,
which is /not/ a NUL-terminated string.
The `cop_nlen`() macro returns the length of the name of the current element.
The `copa_value`() returns a pointer to the value of the current option, which
is /not/ a NUL-terminated string, *only if there is one*. It should /not/ be
used otherwise, nor to determine whether or not an value was specified.
The `copa_vlen`() macro returns the length of the value of the current option,
or 0 when there are none. /This/ is what should be used to determine if the
current option had a value specified or not.
# ERRORS
The `copa_next`() function may fail if :
: *ENODATA*
:: Empty section, i.e. a line `[]` without a name.
: *EINVAL*
:: Invalid assignment, i.e. an equal sign without option name (e.g: a line `=bar`)
: *ENOMSG*
:: Option without value, i.e. an equal sign with nothing after (e.g: a line `foo=`)
# SEE ALSO
[esc_scan](3)