yocton
|
Functions for parsing the contents of a Yocton file. More...
#include <inttypes.h>
Macros | |
#define | YOCTON_IF_PROP(property, name, then) |
Match a particular property name. More... | |
#define | YOCTON_VAR_ARRAY(property, propname, var, len_var, then) |
Match a particular property name and allocate array storage. More... | |
#define | YOCTON_VAR_STRING(property, propname, var) |
Set the value of a string variable if appropriate. More... | |
#define | YOCTON_VAR_STRING_ARRAY(property, propname, var, len_var) |
Append value to a string array if appropriate. More... | |
#define | YOCTON_VAR_INT(property, propname, var_type, var) |
Set the value of a signed integer variable if appropriate. More... | |
#define | YOCTON_VAR_INT_ARRAY(property, propname, var_type, var, len_var) |
Append value to an array of signed integers if appropriate. More... | |
#define | YOCTON_VAR_UINT(property, propname, var_type, var) |
Set the value of an unsigned integer variable if appropriate. More... | |
#define | YOCTON_VAR_UINT_ARRAY(property, propname, var_type, var, len_var) |
Append value to an array of unsigned integers if appropriate. More... | |
#define | YOCTON_VAR_ENUM(property, propname, var, values) |
Set the value of an enum variable if appropriate. More... | |
#define | YOCTON_VAR_ENUM_ARRAY(property, propname, var, len_var, values) |
Append value to an array of enums if appropriate. More... | |
#define | YOCTON_VAR_PTR(property, propname, var, then) |
Allocate memory and set pointer variable if appropriate. More... | |
#define | YOCTON_VAR_PTR_ARRAY(property, propname, var, len_var, then) |
Allocate memory and append pointer to it to an array if appropriate. More... | |
Typedefs | |
typedef size_t(* | yocton_read) (void *buf, size_t buf_size, void *handle) |
Callback invoked to read more data from the input. More... | |
typedef struct yocton_object | yocton_object |
The object is the main abstraction of the Yocton format. More... | |
typedef struct yocton_prop | yocton_prop |
An object can have multiple properties. More... | |
Enumerations | |
enum | yocton_prop_type { YOCTON_PROP_STRING , YOCTON_PROP_OBJECT } |
Type of a yocton_prop. More... | |
Functions | |
struct yocton_object * | yocton_read_with (yocton_read callback, void *handle) |
Start reading a new stream of yocton-encoded data, using the given callback to read more data. More... | |
struct yocton_object * | yocton_read_from (FILE *fstream) |
Start reading a new stream of yocton-encoded data, using the given FILE handle to read more data. More... | |
int | yocton_have_error (struct yocton_object *obj, int *lineno, const char **error_msg) |
Query whether an error occurred during parsing. More... | |
void | yocton_free (struct yocton_object *obj) |
Free the top-level object and stop reading from the input stream. More... | |
void | yocton_check (struct yocton_object *obj, const char *error_msg, int normally_true) |
Perform an assertion and fail with an error if it isn't true. More... | |
struct yocton_prop * | yocton_next_prop (struct yocton_object *obj) |
Read the next property of an object. More... | |
enum yocton_prop_type | yocton_prop_type (struct yocton_prop *property) |
Get the type of a yocton_prop. More... | |
const char * | yocton_prop_name (struct yocton_prop *property) |
Get the name of a yocton_prop. More... | |
const char * | yocton_prop_value (struct yocton_prop *property) |
Get the string value of a yocton_prop of type YOCTON_PROP_STRING. More... | |
char * | yocton_prop_value_dup (struct yocton_prop *property) |
Get newly-allocated copy of a property value. More... | |
struct yocton_object * | yocton_prop_inner (struct yocton_prop *property) |
Get the inner object associated with a yocton_prop of type YOCTON_PROP_OBJECT. More... | |
signed long long | yocton_prop_int (struct yocton_prop *property, size_t n) |
Parse the property value as a signed integer. More... | |
unsigned long long | yocton_prop_uint (struct yocton_prop *property, size_t n) |
Parse the property value as an unsigned integer. More... | |
unsigned int | yocton_prop_enum (struct yocton_prop *property, const char **values) |
Parse the property value as an enumeration. More... | |
Functions for parsing the contents of a Yocton file.
The entrypoint for reading is to use yocton_read_with or yocton_read_from.
#define YOCTON_IF_PROP | ( | property, | |
name, | |||
then | |||
) |
Match a particular property name.
property | The property. |
name | Name of property to match. |
then | Code to execute if yocton_prop_name(property) == name. |
#define YOCTON_VAR_ARRAY | ( | property, | |
propname, | |||
var, | |||
len_var, | |||
then | |||
) |
Match a particular property name and allocate array storage.
This macro is used to build other array macros such as YOCTON_VAR_INT_ARRAY and YOCTON_VAR_STRING_ARRAY. If the name of the given property is equal to propname
, the variable var
(a pointer to array data) will be reallocated so that enough space is available in the array to append a new element. The argument then
is then evaluated to (conditionally) append the new element.
Example that matches a property named "foo" to populate an array of structs:
property | The property. |
propname | The property name to match. |
var | Variable pointing to array data. |
len_var | Variable storing length of array. |
then | Code to evaluate after new element space is allocated. |
#define YOCTON_VAR_ENUM | ( | property, | |
propname, | |||
var, | |||
values | |||
) |
Set the value of an enum variable if appropriate.
If the name of property
is equal to propname
, the variable var
will be initialized to an enum value that matches a name from the given list.
Example to match a property named "foo":
property | Property. |
propname | Name of the property to match. |
var | Variable to initialize. |
values | NULL-terminated array of strings representing enum values (same as values parameter to yocton_prop_enum). |
#define YOCTON_VAR_ENUM_ARRAY | ( | property, | |
propname, | |||
var, | |||
len_var, | |||
values | |||
) |
Append value to an array of enums if appropriate.
If the name of property
is equal to propname
, the property value will be parsed as an enum and then appended to the array pointed at by var
.
Example to populate an array "bar" from a property named "foo":
property | Property. |
propname | Name of property to match. |
var | Variable pointing to array data. |
len_var | Variable containing length of array. |
values | NULL-terminated array of strings representing enum values (same as values parameter to yocton_prop_enum). |
#define YOCTON_VAR_INT | ( | property, | |
propname, | |||
var_type, | |||
var | |||
) |
Set the value of a signed integer variable if appropriate.
If the name of property
is equal to propname
, the variable var
will be initialized to a signed integer value parsed from the property value. If the property value cannot be parsed as a signed integer, the variable will be set to zero and an error set.
This will work with any kind of signed integer variable, but the type of the variable must be provided.
Example to match a property named "foo":
property | Property. |
propname | Name of the property to match. |
var_type | Type of the variable, eg. int or ssize_t . |
var | Variable to set. |
#define YOCTON_VAR_INT_ARRAY | ( | property, | |
propname, | |||
var_type, | |||
var, | |||
len_var | |||
) |
Append value to an array of signed integers if appropriate.
If the name of property
is equal to propname
, the property value will be parsed as a signed integer and appended to the array pointed at by var
.
Example to populate an array "bar" from a property named "foo":
property | Property. |
propname | Name of property to match. |
var_type | Type of array element. |
var | Variable pointing to array data. |
len_var | Variable containing length of array. |
#define YOCTON_VAR_PTR | ( | property, | |
propname, | |||
var, | |||
then | |||
) |
Allocate memory and set pointer variable if appropriate.
If the name of property
is equal to propname
, the pointer variable var
will be initialized to a newly allocated block of sizeof(*var)
bytes.
The pointer variable must be equal to NULL; if it is not, an error will be set. This usually means that the property must be unique in the input. This is to prevent a memory leak if the pointer is allocated twice.
Example to match a property named "foo":
property | Property. |
propname | Name of the property to match. |
var | Pointer variable to initialize. |
then | Block of code to execute if the property is matched. |
#define YOCTON_VAR_PTR_ARRAY | ( | property, | |
propname, | |||
var, | |||
len_var, | |||
then | |||
) |
Allocate memory and append pointer to it to an array if appropriate.
If the name of property
is equal to propname
, a newly allocated block of sizeof(**var)
bytes will be allocated, and appended to the array var
.
The code in the then
block should initialize the new memory pointed at by var[len_var]
, and then increment len_var
. If len_var
is not incremented, the memory block that was allocated will be freed, the assumption being that it was not needed after all.
Example that matches a property named "foo" to populate an array of struct pointers:
property | The property. |
propname | The property name to match. |
var | Variable pointing to array of pointers. |
len_var | Variable storing length of array. |
then | Code to evaluate after new property is matched. |
#define YOCTON_VAR_STRING | ( | property, | |
propname, | |||
var | |||
) |
Set the value of a string variable if appropriate.
If the name of property
is equal to propname
, the variable var
will be initialized to a newly-allocated buffer containing a copy of the string value.
If the variable has an existing value it will be freed. It is therefore important that the variable is initialized to NULL before the first time this macro is used to set it.
Example to match a property named "foo":
property | Property. |
propname | Name of property to match. |
var | Variable to initialize. |
#define YOCTON_VAR_STRING_ARRAY | ( | property, | |
propname, | |||
var, | |||
len_var | |||
) |
Append value to a string array if appropriate.
If the name of property
is equal to propname
, the property value will be appended to the string array pointed at by var
.
Example to populate an array "bar" from a property named "foo":
property | Property. |
propname | Name of property to match. |
var | Variable pointing to array data. |
len_var | Variable containing length of array. |
#define YOCTON_VAR_UINT | ( | property, | |
propname, | |||
var_type, | |||
var | |||
) |
Set the value of an unsigned integer variable if appropriate.
If the name of property
is equal to propname
, the variable var
will be initialized to an unsigned integer value parsed from the property value. If the property value cannot be parsed as an unsigned integer, the variable will be set to zero and an error set.
This will work with any kind of unssigned integer variable, but the type of the variable must be provided.
Example to match a property named "foo":
property | Property. |
propname | Name of the property to match. |
var_type | Type of the variable, eg. uint32_t or size_t . |
var | Variable to set. |
#define YOCTON_VAR_UINT_ARRAY | ( | property, | |
propname, | |||
var_type, | |||
var, | |||
len_var | |||
) |
Append value to an array of unsigned integers if appropriate.
If the name of property
is equal to propname
, the property value will be parsed as an unsigned integer and appended to the array pointed at by var
.
Example to populate an array "bar" from a property named "foo":
property | Property. |
propname | Name of property to match. |
var_type | Type of array element. |
var | Variable pointing to array data. |
len_var | Variable containing length of array. |
typedef struct yocton_object yocton_object |
The object is the main abstraction of the Yocton format.
Each object can have multiple properties (yocton_prop), which can themselves contain more objects.
typedef struct yocton_prop yocton_prop |
An object can have multiple properties.
Each property has a name which is always a string. It also always has a value, which is either a string (YOCTON_PROP_STRING) or an object (YOCTON_PROP_OBJECT). Properties have a very limited lifetime and are only valid until yocton_next_prop is called to read the next property.
typedef size_t(* yocton_read) (void *buf, size_t buf_size, void *handle) |
Callback invoked to read more data from the input.
buf | Buffer to populate with new data. |
buf_size | Size of buffer in bytes. |
handle | Arbitrary pointer, passed through from yocton_read_with. |
enum yocton_prop_type |
Type of a yocton_prop.
Enumerator | |
---|---|
YOCTON_PROP_STRING | Property that has a string value. yocton_prop_value can be used to get the value. |
YOCTON_PROP_OBJECT | Property that has an object value. yocton_prop_inner can be used to read the inner object. |
void yocton_check | ( | struct yocton_object * | obj, |
const char * | error_msg, | ||
int | normally_true | ||
) |
Perform an assertion and fail with an error if it isn't true.
obj | yocton_object; may or may not be the top-level object. |
error_msg | The error message to log if normally_true is zero. |
normally_true | If this is zero, an error is logged. |
void yocton_free | ( | struct yocton_object * | obj | ) |
Free the top-level object and stop reading from the input stream.
obj | Top-level yocton_object. |
int yocton_have_error | ( | struct yocton_object * | obj, |
int * | lineno, | ||
const char ** | error_msg | ||
) |
Query whether an error occurred during parsing.
This should be called once no more data is returned from obj (ie. when yocton_next_prop returns NULL for the top-level object).
obj | Top-level yocton_object. |
lineno | If an error occurs and this is not NULL, the line number on which the error occurred is saved to the pointer address. |
error_msg | If an error occurs and this is not NULL, an error message describing the error is saved to the pointer address. |
struct yocton_prop * yocton_next_prop | ( | struct yocton_object * | obj | ) |
Read the next property of an object.
Example that prints the names and values of all string properties:
obj | yocton_object to read from. |
unsigned int yocton_prop_enum | ( | struct yocton_prop * | property, |
const char ** | values | ||
) |
Parse the property value as an enumeration.
Enumeration values are assumed to be contiguous and start from zero. values[e] gives the string representing enum value e. If the property value is not found in the values array, an error is set.
Note that the lookup of name to enum value is a linear scan so it is relatively inefficient. If efficiency is concerned, an alternative approach should be used (eg. a hash table).
It may be more convenient to use YOCTON_VAR_ENUM which is a wrapper around this function.
property | The property. |
values | Pointer to a NULL-terminated array of strings representing enum values. values[e] is a string representing enum value e. |
struct yocton_object * yocton_prop_inner | ( | struct yocton_prop * | property | ) |
Get the inner object associated with a yocton_prop of type YOCTON_PROP_OBJECT.
It is an error to call this for a property that is not of this type.
Example of a function that recursively reads inner objects:
property | The property. |
signed long long yocton_prop_int | ( | struct yocton_prop * | property, |
size_t | n | ||
) |
Parse the property value as a signed integer.
If the property value is not a valid integer of the given size, zero is returned and an error is set.
It may be more convenient to use YOCTON_VAR_INT which is a wrapper around this function.
property | The property. |
n | Size of the expected property in bytes, eg. sizeof(uint16_t). |
const char * yocton_prop_name | ( | struct yocton_prop * | property | ) |
Get the name of a yocton_prop.
Multiple properties of the same object may have the same name. Encoding of the name depends on the encoding of the input file.
See yocton_next_prop for an example of how this might be used.
property | The property. |
enum yocton_prop_type yocton_prop_type | ( | struct yocton_prop * | property | ) |
Get the type of a yocton_prop.
See yocton_next_prop for an example of how this might be used.
property | The property. |
unsigned long long yocton_prop_uint | ( | struct yocton_prop * | property, |
size_t | n | ||
) |
Parse the property value as an unsigned integer.
If the property value is not a valid integer of the given size, zero is returned and an error is set.
It may be more convenient to use YOCTON_VAR_UINT which is a wrapper around this function.
property | The property. |
n | Size of the expected property in bytes, eg. sizeof(uint16_t). |
const char * yocton_prop_value | ( | struct yocton_prop * | property | ) |
Get the string value of a yocton_prop of type YOCTON_PROP_STRING.
It is an error to call this for a property that is not of this type. Encoding of the string depends on the input file.
See yocton_next_prop for an example of how this might be used.
property | The property. |
char * yocton_prop_value_dup | ( | struct yocton_prop * | property | ) |
Get newly-allocated copy of a property value.
Unlike yocton_prop_value, the returned value is a mutable string that will survive beyond the lifetime of the property. It is the responsibility of the caller to free the string. Calling multiple times returns a newly-allocated string each time.
It is an error to call this for a property that is not of type YOCTON_PROP_STRING. String encoding depends on the input file.
It may be more convenient to use YOCTON_VAR_STRING which is a wrapper around this function.
property | The property. |
struct yocton_object * yocton_read_from | ( | FILE * | fstream | ) |
Start reading a new stream of yocton-encoded data, using the given FILE handle to read more data.
Example:
fstream | File handle. |
struct yocton_object * yocton_read_with | ( | yocton_read | callback, |
void * | handle | ||
) |
Start reading a new stream of yocton-encoded data, using the given callback to read more data.
Simple example of how to use a custom read callback:
callback | Callback function to invoke to read more data. |
handle | Arbitrary pointer passed through when callback is invoked. |