ORT(3)

NAME
ort - ort code generator library

LIBRARY
libort

SYNOPSIS
#include <sys/queue.h>
#include <stdio.h>
#include <ort.h>
struct bitf
struct bitidx
struct config
struct eitem
struct enm
struct label
struct role
struct rolemap
struct strct

DESCRIPTION
The ort library parses ort(5) configuration files. The most common usage is as follows:

1.  create a configuration with ort_config_alloc(3)

2.  parse one or multiple files with ort_parse_file(3)

3.  finalise the configuration with ort_parse_close(3)

4.  manipulate the configuration

5.  free the configuration with ort_config_free(3)

To compile applications with ort, include the ort.h as follows:

    #include <sys/queue.h>
    #include <stdio.h> /* FILE */
    #include <ort.h>

To compile and link, use pkg-config(1):

    % cc `pkg-config --cflags ort` -c -o sample.o sample.c
    % cc -o sample sample.o `pkg-config --libs ort`

  Pledge Promises
The ort library is built to operate in security-sensitive environments, including pledge(2) on OpenBSD. The only promise required is "stdio".

DATA STRUCTURES
In this documentation, all structures ending in "q", such as "struct bitidxq", are represented as tail-queue macros in <sys/queue.h>.

The central structure of ort is struct config, which represents one or more configuration files. It is allocated with ort_config_alloc(3), filled with ort_parse_file(3), and finalised with ort_parse_close(3). It must be freed with ort_config_free(3).

struct strctq sq
    A non-empty queue of structures.

struct enmq eq
    A possibly-empty queue of user-defined enumerations.

struct bitfq bq
    A possibly-empty queue of user-defined bitfields.

struct roleq rq
    A possibly-empty queue of top-level roles. If non-empty, this consists of only the "all", "none", and "default" roles: other roles are children to those as defined in the subrq queue in each role. These use the entries queue macro variable in struct role. If empty, role-sensitive code should not be produced.

struct roleq arq
    A possibly-empty queue of all roles. These use the allentries queue macro variable in struct role. If empty, role-sensitive code should not be produced.

char **langs
    All languages used by the exported labels.

size_t langsz
    Number of pointers in langs. If zero, there are no languages exported.

char **fnames
    Filenames of parsed configurations. These should only be used for reporting.

size_t fnamesz
    The number of pointers in fnames.

struct msgq *mq
    Warnings and errors encountered during processing.

unsigned int flags
    Bit-field of configuration flags. This may consist of CONFIG_HAS_PASS if any passwords are declared in the configuration.

  Data
The central component of struct config is the queue of struct strct. These collectively represent the data, operations, and other properties. It may be represented as an SQL table, a C structure, a TypeScript class, or a JavaScript object.

char *name
    The non-empty name of the structure. It is unique (case insensitive) among all structures.

char *doc
    If not NULL, free-form documentation. May be empty.

struct pos pos
    Parse position.

struct field *rowid
    If not NULL, the row identifier field.

struct fieldq fq
    A non-empty queue of fields.

struct searchq sq
    A possibly-empty queue of queries. Queries are used to extract data.

struct aliasq aq
    A possibly-empty queue of aliases. Aliases are used when generating SQL. This structure may be removed in the future.

struct updateq uq
    A possibly-empty queue of update statements. Updates are used to modify data.

struct updateq dq
    A possibly-empty queue of delete statements. Updates are used to modify (delete) data.

struct uniqueq nq
    A possibly-empty queue of unique statements. These are used to specify data uniqueness among multiple fields. (Individual fields may be marked unique on their own.)

struct rolemapq rq
    A possibly-empty queue of role assignments defined for this strutcure.

struct insert *ins
    If not NULL, the insert statement for the structure. Inserts are used to create data.

unsigned int flags
    Useful bits (or zero) set on the structure: STRCT_HAS_QUEUE if any list queries are defined, STRCT_HAS_ITERATOR if any iterator queries are defined, STRCT_HAS_BLOB if any blob fields are defined, and STRCT_HAS_NULLREFS if any reference structures can be null.

struct config *cfg
    The configuration containing the structure.

The data of struct strct is defined by its queue of struct field. It may be represented as a column in an SQL table, a field of a C structure, or a member of a JavaScript object.

char *name
    The non-empty name of the field. It is unique (case insensitive) among other fields in the structure.

struct ref *ref
    This is set for FTYPE_STRUCT fields or references to other structures. Otherwise it is NULL.

struct enm *enm
    Set for FTYPE_ENUM fields to the enumeration. Otherwise it is NULL.

struct bitf *bitf
    Set for FTYPE_BITFIELD fields to the bitfield. Otherwise it is NULL.

char *doc
    If not NULL, free-form documentation. May be empty.

struct pos pos
    Parse point.

<anon union> def
    An anonymous union with the default value of the field. This consists of int64_t integer for a default integer type (one of FTYPE_DATE, FTYPE_BIT, FTYPE_BITFIELD, FTYPE_EPOCH, FTYPE_INT), double decimal for a default real value FTYPE_REAL, char *string for a default string type (one of FTYPE_EMAIL or FTYPE_TEXT), or struct eitem *eitem for a default enumeration.

enum ftype type
    Type type of the data.

enum upact actdel
    For references to other structures, behaviour to take for when the referenced data is deleted. This may be one of UPACT_NONE for not specifying a delete handler, UPACT_RESTRICT for inhibiting the default, UPACT_NULLIFY for nullifying the field, UPACT_CASCADE from propogating changes to the field, or UPACT_DEFAULT for the default behaviour.

struct rolemap *rolemap
    If not NULL, role assignments for not exporting this field.

enum upact actup
    For references to other structures, behaviour to take for when the referenced data is updated. See actdel for a list of possible scenarios.

struct strct *parent
    Link to parent structure.

struct fvalidq fvq
    A possibly-empty queue of validators. If data is being inserted or updated, it must conform to the validators.

unsigned int flags
    A bit-field consisting of FIELD_ROWID if being the structure's unique row identifier (only available for FTYPE_INT), FIELD_UNIQUE if a unique field within the structure, FIELD_NULL if the field may be null, FIELD_NOEXPORT if the field may not be exported ever, and FIELD_HASDEF if the field has a default type-specific value set.

References are a central part of ort and allow fields to link to other fields. These are governed by struct ref in struct field. Any field not of type FTYPE_STRUCT may link to any other field in another structure that has the same type. This is called a foreign reference. Fields with the special FTYPE_STRUCT type have a reference that points to a foreign reference in the same structure. This is called a local reference.

struct field *target
    For both local and remote references, this is the field in the linked-to structure.

struct field *source
    For remote references, this is the same as parent. For local references, this is the field in the current structure that's the remote reference.

struct field *parent
    The field upon which the reference is set.

Validation allows constraining the data accepted for native types, i.e., not enum or bits. A struct field may contain zero or more validation statements in fvq:

enum vtype type
    The constrained inequality type. For numeric types, the inequality compares by value. For string types, the comparison is by string length.

<anon union> d.value
    An anonymous union containing a value depending upon the type of the parent struct field. If of type FTYPE_BIT, FTYPE_BITFIELD, FTYPE_DATE, FTYPE_EPOCH, or FTYPE_INT, this is int64_t integer; if FTYPE_REAL, this is double decimal; otherwise, it is size_t len.

Unique data is stipulated on a per-field basis with FIELD_UNIQUE or using struct unique for the concatenation of multiple fields.

struct nrefq nq
    A queue whose objects consist primarily of field, a field in the unique set. The queue is ordered in by the case-insensitive name (a–z) of the field.

struct strct *parent
    The encompassing structure.

struct pos pos
    Parse position.

  User-defined Data Types
The data in struct field may be typed as an enumeration or bit-field, both of which are defined within the configuration. In short, both of these limit the integers accepted to those defined as enumeration values or bit masks.

The user-defined enumerations in eq limit integer types to specific values. Its struct enm is defined as follows:

char *name
    The non-empty name of the enumeration. It is unique (case insensitive) among all enumerations and bit-fields.

char *doc
    If not NULL, free-form documentation. May be empty.

struct pos pos
    Parse position.

struct eitemq eq
    Non-empty list of all enumeration values.

Each enumeration has a non-empty list of struct eitem that define the enumeration's values.

char *name
    The non-empty name of the enumeration item. It is unique (case insensitive) among other items in the enumeration.

int64_t value
    The value less than INT64_MAX and greater than INT64_MIN. It is unique among other items in the enumeration.

char *doc
    If not NULL, free-form documentation. May be empty.

struct labelq labels
    A possibly-empty list of exported labels describing the item.

struct pos pos
    Parse position.

struct enm *parent
    The encompassing enumeration.

unsigned int flags
    Flags. May be set to EITEM_AUTO if the value was assigned dynamically. Dynamic assignment occurs after parsing and works by taking the maximum assigned value (bound below at zero), adding one, then assigning and adding one in the order of declaration.

The label queue of struct label is exported, so its contents must be considered public. It consists of names for each item.

char *label
    The non-empty free-form label. It may not contain the "<" left right-angle bracket.

size_t lang
    Language index in lang of struct config.

struct pos pos
    Parse position.

The user-defined bit-field struct bitf is similar to an enumeration:

char *name
    The non-empty name of the bit-field. It is unique (case insensitive) among other bit-fields and enumerations.

char *doc
    If not NULL, free-form documentation. May be empty.

struct labelq labels_unset
    A possibly-empty list of exported labels for formatting if the bit-field has no bits set.

struct labelq labels_null
    A possibly-empty list of exported labels for formatting if the bit-field is null.

struct pos pos
    Parse position.

struct bitidxq bq
    A non-empty queue of bit values.

The bit-field is composed of multiple struct bitidx bits that are recognised by the application.

char *name
    The non-empty name of the bit. It is unique (case insensitive) among other bits in the bit-field.

char *doc
    If not NULL, free-form documentation. May be empty.

struct labelq labels
    A possibly-empty list of exported labels for formatting the bit.

int64_t values
    The bit itself inclusive of 0–63.

struct bitf *parent
    The parent bit-field structure.

struct pos pos
    Parse position.

User-based types all have text representations of their numeric values. These labels may be assigned in any number of languages. All languages are defined in the char **langs array in struct config. Labels are defined in queues of type struct label in all user-defined types:

char *label
    The label in natural language. This is commonly in UTF-8, although there are no restrictions except that the string be non-empty and NUL-terminated in the usual way.

size_t lang
    The language as indexed into char **langs in struct config.

  Role-based Access Control
The role-based access control of the system is defined by struct role. If the rq queue in the top-level struct config is empty, there are no roles defined. (This should not change a generated API.) Roles are hierarchical, so the roles in struct config are top-level roles. Roles inherit the operations (defined by struct rolemap) available to the parent.

char *name
    The non-empty name of the role. It is unique (case insensitive) among other roles.

char *doc
    If not NULL, free-form documentation. May be empty.

struct role *parent
    The parent role. If NULL, this is a top-level role.

struct roleq subrq
    A possibly-empty queue of inheriting roles. These use the entries queue macro variable.

struct pos pos
    Parse position.

One or more role are assigned to operations or data with struct rolemap.

struct rrefq rq
    The non-empty roles that are to be assigned. Roles are hierarchical, so each role's descendents are implicitly mapped to the given operation as well.

enum rolemapt type
    The type of operation to be assigned. This may be one of ROLEMAP_ALL, which is an alias for all types except ROLEMAP_NOEXPORT; ROLEMAP_COUNT, ROLEMAP_ITERATE, ROLEMAP_LIST, and ROLEMAP_SEARCH for queries; ROLEMAP_DELETE for deletions; ROLEMAP_UPDATE for updates; ROLEMAP_INSERT for insertions; and ROLEMAP_NOEXPORT for making specific fields unexportable to the role.

struct strct *parent
    The structure for which the assignment is applicable.

struct field *f
    If ROLEMAP_NOEXPORT, the field that shouldn't be exported.

struct search *s
    If ROLEMAP_COUNT, ROLEMAP_ITERATE, ROLEMAP_LIST, or ROLEMAP_SEARCH, the query to receive the assignment.

struct update *u
    If ROLEMAP_DELETE or ROLEMAP_UPDATE, the deletion or update to receive the assignment.

  Updates
Data may be modified or deleted as defined by struct update, used in uq and dq, respectively, in struct strct.

struct urefq mrq
    Fields that are to be modified (always non-empty in this case), or empty for deletion.

struct urefq crq
    Constrain what to update or delete by these fields.

char *name
    The name of the operation or NULL if anonymous.

char *doc
    If not NULL, free-form documentation. May be empty.

enum upt type
    Either UP_MODIFY to modify data or UP_DELETE to delete.

struct pos pos
    Parse point.

struct strct *parent
    Parent containing the operation.

struct rolemap *rolemap
    If not NULL, roles allowed to perform the operation.

unsigned int flags
    Set to UPDATE_ALL if the operation is an update and all modifier fields were specified by leaving the modifier field empty during configuration.

Fields by which operations are constrained or modified are defined in struct uref:

enum optype op
    The way in which a field will be constrained. This is only applicable to UP_DELETE references.

enum modtype mod
    How a field will be modified. This is only applicable to UP_MODIFY references.

struct field *field
    The field doing the constraining or modifying.

struct pos pos
    Parse point.

struct update *parent
    Parent containing the reference.

  Inserts
New data may be inserted as defined by struct insert, which is only used in ins of struct strct.

struct rolemap *rolemap
    If not NULL, roles allowed to perform insertions.

struct strct *parent
    Parent containing the insertion.

struct pos pos
    Parse point.

  Queries
Data may be extracted by using queries. These are defined for each struct strct. The foundation for all queries is struct search, which is used for all types of query.

struct sentq sntq
    A possibly-empty queue of the search constraints. An empty queue exists if searching for everything.

struct ordq ordq
    A possibly-empty queue of how to order the results.

struct aggr *aggr
    If not NULL, how to aggregate search results. This is used with group.

struct group *group
    If not NULL, the field that is used for grouping results. This field will be unique among the results, with the choice of which object to use for the unique result being set by aggr.

struct pos pos
    Parse point.

struct dstnct *dst
    If not NULL, only return distinct results of a reference within the query. It may be set to the current structure.

char *name
    A non-empty name unique (case insensitive) among other queries of this type or NULL to have an automatically-generated name.

char *doc
    If not NULL, free-form documentation. May be empty.

struct strct *parent
    Parent containing the query.

enum stype type
    Type of query. This may be STYPE_COUNT to return only the count of results, STYPE_SEARCH to query for a single result, STYPE_LIST to return all results, or STYPE_ITERATE to provide a callback to iterate over results.

int64_t limit
    Zero or a limit to the returned results.

int64_t offset
    Zero or the offset of when to start returning results.

struct rolemap *rolemap
    If not NULL, roles allowed to perform this query.

unsigned int flags
    This may be only SEARCH_IS_UNIQUE if the query will return a single result. (That is, it queries unique values.)

Search parameters are listed in a queue of struct sent. The queue may have multiple parameters of the same field, as there may be multiple ways of indirecting to the same field.

struct pos pos
    Parse position.

struct search *parent
    The encompassing search component.

struct field *field
    The field upon which to search. There can be multiple similar field entries in one queue, as different foreign references may indirectly reference the same field. Use fname for uniqueness checks.

enum optype op
    The type of search constraint.

char *name
    Like fname, but not including the last field and trailing period. This is NULL if within the same structure as parent.

char *fname
    Dot-separated field lookup.

char *uname
    Like fname, but using underscores instead of periods.

struct alias *alias
    Resolved alias.

struct field **chain
    The fields referenced within each component of fname or uname.

size_t chainsz
    The number of elements in chain, so also the number of components in fname and uname.

Ordering within query results is dictated by the queue of struct ord. By default, search results are ordered arbitrarily.

struct field **chain
    The fields referenced within each component of fname.

size_t chainsz
    The number of elements in chain, so also the number of components in fname.

struct field *field
    Final field used for the ordering.

char *name
    Order structure (reference sub-fields separated by dots, not including the last field) or NULL if in the current structure.

char *fname
    Order field (reference sub-fields separated by dots).

enum ordtype op
    Type of ordering: ORDTYPE_ASC for ascending (1, 2, 3...) and ORDTYPE_DESC for descending (...3, 2, 1).

struct pos pos
    Parse point.

struct search *parent
    Parent reference.

struct alias *alias
    Resolved alias.

The dst field of type struct dstnct allows results to be returned from unique sub-structures (referenced structures).

struct field **chain
    The fields referenced within each component of fname.

size_t chainsz
    The number of elements in chain, so also the number of components in fname.

char *fname
    The canonical dotted name. If this is a single dot only, it refers to the current structure.

struct pos pos
    Parse point.

struct strct *strct
    Final structure used for distinct check.

struct search *parent
    Parent reference.

Result aggregation is effected through a group, which defines the grouping field (i.e., results are placed into buckets having the same field value); and the aggregator, which defines how groups are distilled into a single value.

The group pointer, if not NULL, is a struct group with the following. If not NULL, it must be pair with a aggr that is also not NULL.

struct field **chain
    The fields referenced within each component of fname.

size_t chainsz
    The number of elements in chain, so also the number of components in fname.

struct field *field
    Final field used for grouping.

char *name
    Grouping structure (reference sub-fields separated by dots, not including the last field) or NULL if in the current structure.

char *fname
    Grouping field (reference sub-fields separated by dots).

struct pos pos
    Parse point.

struct search *parent
    Parent reference.

struct alias *alias
    Resolved alias.

The aggregate function is in aggr of type struct aggr, which if not NULL, implies that group is also not NULL.

struct field *chain
    The fields referenced within each component of fname.

size_t chainsz
    The number of elements in chain, so also the number of components in fname.

struct field *field
    Final field used for aggregation.

char *name
    Aggregation structure (reference sub-fields separated by dots, not including the last field) or NULL if in the current structure.

char *fname
    Aggregation field (reference sub-fields separated by dots).

struct pos pos
    Parse point.

struct search *parent
    Parent reference.

struct alias *alias
    Resolved alias.

enum aggrtype op
    Method of aggregation: either AGGR_MAXROW to select the maximum row or AGGR_MINROW. If there are multiple maxima or minima, the selection criterion is not yet specified.

  Messages
Messages are generated by parsing, linking, and front-end formatting to indicate some sort of bad condition. These messages are accumulated in struct config and should be reported to the operator. They are represented by struct msg.

char *fname
    Filename where message occurred or NULL.

size_t line
    Line number where message occurred or zero if not associated.

size_t column
    Line column where message occurred or zero if not associated.

enum msgtype type
    A message that is either MSGTYPE_WARN for a message that may be ignored, MSGTYPE_ERROR when a parse/format sequence should be stopped due to errors, or MSGTYPE_FATAL when a system error has occurred.

char *buf
    This is the message contents or NULL, usually used in conjunction with er. If both buf and er aren't set, the message is considered a noop.

int er
    This is the errno(2) or zero if not set.

EXAMPLES
The following parses standard input and repeats the parsed, canonicalised configuration on standard output.

    struct config *cfg;
    if ((cfg = ort_config_alloc()) == NULL)
    	err(1, NULL);
    if (!ort_parse_file(cfg, stdin, "<stdin>");
    	errx(1, "ort_parse_file");
    if (!ort_parse_close(cfg))
    	errx(1, "ort_parse_close");
    if (!ort_write_file(stdout, cfg))
    	errx(1, "ort_write_file");
    ort_config_free(cfg);