NAME
ort
—
ort code generator library
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:
- create a configuration with ort_config_alloc(3)
- parse one or multiple files with ort_parse_file(3)
- finalise the configuration with ort_parse_close(3)
- manipulate the configuration
- 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, andSTRCT_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 isNULL
. - struct enm *enm
- Set for
FTYPE_ENUM
fields to the enumeration. Otherwise it isNULL
. - struct bitf *bitf
- Set for
FTYPE_BITFIELD
fields to the bitfield. Otherwise it isNULL
. - 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 valueFTYPE_REAL
, char *string for a default string type (one ofFTYPE_EMAIL
orFTYPE_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, orUPACT_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 forFTYPE_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, andFIELD_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
, orFTYPE_INT
, this is int64_t integer; ifFTYPE_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 thanINT64_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 exceptROLEMAP_NOEXPORT
;ROLEMAP_COUNT
,ROLEMAP_ITERATE
,ROLEMAP_LIST
, andROLEMAP_SEARCH
for queries;ROLEMAP_DELETE
for deletions;ROLEMAP_UPDATE
for updates;ROLEMAP_INSERT
for insertions; andROLEMAP_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
, orROLEMAP_SEARCH
, the query to receive the assignment. - struct update *u
- If
ROLEMAP_DELETE
orROLEMAP_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 orUP_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, orSTYPE_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...) andORDTYPE_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 orAGGR_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, orMSGTYPE_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);