This part of the manual describes MiST Engine public API. It is implemented in a shared library (libmist_engine.so.1
on Linux, mist_engine.dll
on Microsoft Windows) and can be used by the applications written in C or C++.
The applications should rely only on MiST Engine API described here. Other types, functions, macros, constants, etc., that can be found in the header and source files of MiST Engine library are for internal use only and subject to change.
Most of the API functions described here deal with the structures representing template groups in memory. They allow to create a template group on the heap, set the values of the parameters referred to by the templates, evaluate the template group to construct the resulting values, clear (reset) or destroy the group.
Unlike MiST Engine command line tool, the templates are loaded from the memory by the API functions rather than from the file system. This makes the API more generic.
The syntax of the templates should be as described in Section 3, “Templates for Output Files”. Otherwise mist_tg_create*
functions will report an error.
The templates should be named according to the rules described in Section 4.3, “Naming rules”.
Unless specifically stated, if an API function takes pointer as an argument and NULL is passed to it as the value of this argument, behaviour of the function is undefined. For example, if a function takes name
argument of type const char*
, it must not be NULL.
Note that if a function takes error_descr
argument, the function may return the description of the error in *error_descr
in case of failure although it is not mandatory. This string should be freed by the caller when no longer needed. If the function succeeds or just does not provide the description of the error, it will set *error_descr
to NULL.
An application built using a particular version of MiST Engine API will be able to work with newer versions of MiST Engine shared library too if these versions differ only in minor or micro version from the original one. That is, backward source (API) and binary (ABI) compatibility is guaranteed. Neither source nor binary compatibility is guaranteed between MiST Engine libraries with different major versions. In addition, the sets of header files provided to build the applications using these libraries will be different.
To use MiST Engine API, the application should #include the main header file of the library:
#include <mist_engine/mist_engine.h>
#define MIST_ENGINE_VERSION_MAJOR #define MIST_ENGINE_VERSION_MINOR #define MIST_ENGINE_VERSION_MICRO
These preprocessor macros have numeric values of the major, minor and micro version of the MiST Engine package used when building the application. As it was mentioned above, the application may actually use a newer version of MiST Engine. Still, it is safer not to expect that the version will be newer than that defined by these macros.
The above macros are mostly useful if you want to output the version of MiST Engine API in some kind of a diagnostic message.
The following two macros are used to specify the version of MiST Engine API to request in mist_engine_init()
. Note that the major version of the library is not involved here: no API and ABI compatibility is guaranteed between the libraries with different major versions. Different header files must be used if the application depends on MiST Engine API with a different major version.
#define MIST_ENGINE_API_VERSION(minor_version, micro_version)
MIST_ENGINE_API_VERSION
combines the specified minor and micro versions of API into a single number that can be passed to mist_engine_init()
.
#define MIST_ENGINE_API_MAX_VERSION
This macro is equivalent to the following:
MIST_ENGINE_API_VERSION( \ MIST_ENGINE_VERSION_MINOR, \ MIST_ENGINE_VERSION_MICRO \ )
This is the maximum API version supported by the MiST Engine package where the given mist_engine/mist_engine.h
header file came from.
Each MiST Engine API function returns an error code of type EMistErrorCode
.
The functions may return at least the following error codes:
MIST_OK
This value is returned in case of success.
MIST_OUT_OF_MEMORY
There is not enough memory to perform the operation. MIST_UNSPECIFIED_ERROR
can be also returned in this case.
MIST_SYNTAX_ERROR
A syntax error has been detected in the data being loaded (usually, in the templates).
MIST_BAD_NAME
There is a placeholder or a template with an invalid name.
MIST_FAILED_TO_LOAD_TEMPLATE
The function failed to load template for some reason. If *error_descr
is not NULL, it contains the description of what exactly is wrong.
MIST_UNSPECIFIED_ERROR
Some error has occured. If *error_descr
is not NULL, it contains the description of what exactly is wrong. If it is NULL, it is likely that an out-of-memory condition was encountered or some other critical failure took place.
MIST_VERSION_NOT_SUPPORTED
This error code is returned by mist_engine_init()
if the requested version of MiST Engine API is not supported (usually, if it is higher than the actual version of API in the shared library).
MIST_LIBRARY_NOT_INITIALIZED
This error code is returned by mist_tg_*()
functions if MiST Engine library has not been initialized yet, i.e. mist_engine_init()
has not been called.
To check whether a MiST Engine API function has succeeded, you should check if its return value is MIST_OK
.
struct CMistTemplateGroup_; typedef struct CMistTemplateGroup_ CMistTGroup;
This structure represents a template group. The structure is opaque, its fields should never be used directly.
A template group contains one or more templates, each of which has a unique name. A template from the group may refer to other templates from this group. A group always has a main (top-level) template which will be evaluated when mist_tg_evaluate()
is called for the group (see Section 4.4, “Evaluation of a template group” for details).
typedef struct CMistNameValuePair_ { const char* name; const char* val; } CMistNameValuePair;
This helper structure holds two pointers to constant strings, a <name, value>
pair. It is used to group some of the parameters passed to MiST API functions. In this structure, name
points to the name of an entity (parameter, template, etc.), value
points to a string associated with the entity. It can be the value of a parameter to be set or the string to load a template from, etc.
EMistErrorCode mist_engine_init( unsigned int api_ver );
Initializes MiST Engine and requests a particular version of API.
Usually it is enough to simply pass MIST_ENGINE_API_MAX_VERSION
here. This is the maximum API version supported by the MiST Engine package where the mist_engine/mist_engine.h
header file used by the application came from.
If the requested version is not supported, the function returns MIST_VERSION_NOT_SUPPORTED
.
This function must be called before the application uses any other MiST API function.
EMistErrorCode mist_tg_create( CMistTGroup** ptg, const CMistNameValuePair* source, size_t num, size_t main_index, const char* begin_marker, const char* end_marker, size_t* bad_index, char** error_descr );
Creates a template group and returns a pointer to it in *ptg
.
source
array contains the names of the templates to be stored in the group and the strings to load the templates from.
The index of the main template in source
array is main_index
. This template will be the top-level template of the group. main_index
is zero-based and should be less than num
.
num
specifies the number of elements of source
array to be processed. source
should contain at least one element and num
should not be 0: it makes no sense to create a group with no templates in it anyway.
The function copies all necessary strings and parts of strings from source
array (string chunks, names of the templates, etc.) rather than stores pointers to them. So, once the template group is created, it no longer depends on the contents of source
array.
Each template in a group must have a unique name. If there are two or more identical names specified in source
array, the behaviour of the function is undefined.
begin_marker
and end_marker
specify the placeholders in the strings that the templates are loaded from. The markers must not be empty strings.
In case of failure, *bad_index
will be the index of the template that failed to load (source[*bad_index].name
will be its name). If no error occured or something wrong happened to the group as a whole (out of memory, for example), *bad_index
will be (size_t)(-1)
.
EMistErrorCode mist_tg_create_single( CMistTGroup** ptg, const char* name, const char* str, const char* begin_marker, const char* end_marker, char** error_descr );
Like mist_tg_create()
, except that the group will contain only one template. The name of the template is name
and its contents are loaded from string str
.
name
must not be an empty string.
EMistErrorCode mist_tg_destroy( CMistTGroup* mtg );
Destroys the template group releasing the memory the group (with all its contents) occupies.
EMistErrorCode mist_tg_add_value( CMistTGroup* mtg, const char* name, const char* val );
Adds (appends) a copy of the specified value to the list of values of the parameter with the given name. Does nothing if there is no template in the group that refers to such parameter, this case is not considered an error. No parameter - no problem.
name
must not be an empty string.
If the group has already been evaluated, mist_tg_clear_values()
should be called to “reset” it before setting new values with one or more calls of mist_tg_add_value()
. Otherwise the following evaluation of the group may give incorrect results.
EMistErrorCode mist_tg_set_values( CMistTGroup* mtg, const CMistNameValuePair* attrs, size_t num );
Sets the values of the parameters in the template group, that is, appends them to the lists of values of the respective parameters.
<name_of_parameter, value>
pairs are stored in the attrs
array. num
is the number of its elements to be processed. If num
is 0, the function does nothing except for checking that the library is initialized.
attrs
array may contain more than one <name_of_parameter, value>
pair with the same name_of_parameter
. If this is the case, all these values will be set for this multi-valued parameter in the same order as they are listed in attrs
array.
The function leaves previously set values intact, i.e. it can be called several times with various sets of parameters.
Like it is for mist_tg_add_value()
, if there is no template in the group that refers to a parameter from attrs
, the function just does nothing for this parameter.
If the group has already been evaluated, mist_tg_clear_values()
should be called to “reset” it before setting new values with one or more calls of mist_tg_set_values()
. Otherwise the following evaluation of the group may give incorrect results.
EMistErrorCode mist_tg_clear_values( CMistTGroup* mtg );
Clears the values of each template contained in the group and of the values parameters referred to by the templates. That is, the templates and parameters will contain no values after mist_tg_clear_values()
is executed.
This function should always be used to “reset” the group before setting new values for the parameters in it.
EMistErrorCode mist_tg_evaluate( CMistTGroup* mtg, const char*** presult, size_t* nvals );
Evaluates the group, i.e. constructs the string value(s) of its main (top-level) template performing all necessary substitutions, joining, etc.
The result can be multi-valued, so the function returns the values of the template in *presult
((*presult)[i]
being the string value #i) and the number of these values - in *nvals
.
The array returned in *presult
and the strings contained in it are owned by the template group and must not be freed by the caller. In addition, subsequent calls of MiST API functions may change the contents of the array.
The function returns MIST_OUT_OF_MEMORY
if there is not enough memory to perform the operation. In this case, *presult
will be NULL and *nvals
will remain unchanged.