2011-05-09 07:02:15 +00:00
|
|
|
#ifndef PSYC_TEXT_H
|
2011-11-11 21:18:24 +00:00
|
|
|
#define PSYC_TEXT_H
|
2011-05-09 07:02:15 +00:00
|
|
|
|
2011-05-03 20:18:35 +00:00
|
|
|
/**
|
2011-05-03 23:30:09 +00:00
|
|
|
* @file psyc/text.h
|
|
|
|
* @brief Interface for text template rendering.
|
|
|
|
*
|
|
|
|
* All text template functions and the definitions they use are
|
|
|
|
* defined in this file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @defgroup text Text template functions
|
|
|
|
*
|
|
|
|
* This module contains all text template functions.
|
|
|
|
* @{
|
2011-05-03 20:18:35 +00:00
|
|
|
*/
|
|
|
|
|
2011-05-03 23:30:09 +00:00
|
|
|
/**
|
|
|
|
* Return values for the text template parsing function.
|
|
|
|
* @see psyc_text()
|
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
typedef enum {
|
|
|
|
/// No substitution was made, nothing was written to the buffer.
|
|
|
|
PSYC_TEXT_NO_SUBST = -1,
|
|
|
|
/// Text template parsing & rendering complete.
|
|
|
|
PSYC_TEXT_COMPLETE = 0,
|
|
|
|
/// Text template parsing & rendering is incomplete, because the buffer was too
|
|
|
|
/// small. Another call is required to this function after setting a new buffer.
|
|
|
|
PSYC_TEXT_INCOMPLETE = 1,
|
2011-10-31 19:26:47 +00:00
|
|
|
} PsycTextRC;
|
2011-05-03 20:18:35 +00:00
|
|
|
|
2011-05-03 23:30:09 +00:00
|
|
|
/**
|
2011-10-31 19:26:47 +00:00
|
|
|
* Return values for PsycTextCB.
|
2011-05-03 23:30:09 +00:00
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
typedef enum {
|
|
|
|
/// Value not found, don't substitute anything.
|
|
|
|
PSYC_TEXT_VALUE_NOT_FOUND = -1,
|
|
|
|
/// Value found, substitute contents of the value variable.
|
|
|
|
PSYC_TEXT_VALUE_FOUND = 0,
|
2011-10-31 19:26:47 +00:00
|
|
|
} PsycTextValueRC;
|
2011-05-03 20:18:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Struct for keeping PSYC text parser state.
|
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
typedef struct {
|
|
|
|
size_t cursor; ///< current position in the template
|
|
|
|
size_t written; ///< number of bytes written to buffer
|
|
|
|
PsycString tmpl; ///< input buffer with text template to parse
|
|
|
|
PsycString buffer; ///< output buffer for rendered text
|
|
|
|
PsycString open;
|
|
|
|
PsycString close;
|
2011-10-31 19:26:47 +00:00
|
|
|
} PsycTextState;
|
2011-05-03 20:18:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback for psyc_text() that produces a value for a match.
|
|
|
|
*
|
|
|
|
* The application looks up a match such as _fruit from [_fruit] and
|
2011-11-01 11:06:58 +00:00
|
|
|
* if found sets value->data & value->length to point to the found value,
|
2011-05-03 23:30:09 +00:00
|
|
|
* "Apple" for example. 0 is a legal value for the length.
|
|
|
|
* The callbacks returns either PSYC_TEXT_VALUE_FOUND or
|
|
|
|
* PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text
|
|
|
|
* leaves the original template text as is.
|
2011-05-03 20:18:35 +00:00
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
typedef PsycTextValueRC (*PsycTextCB) (const char *name, size_t len,
|
|
|
|
PsycString *value, void *extra);
|
2011-05-03 20:18:35 +00:00
|
|
|
|
2011-05-03 23:30:09 +00:00
|
|
|
/**
|
|
|
|
* Initializes the PSYC text state struct.
|
|
|
|
*
|
|
|
|
* @param state Pointer to the PSYC text state struct that should be initialized.
|
2011-05-28 17:39:42 +00:00
|
|
|
* @param tmpl Input buffer with text template to be parsed.
|
|
|
|
* @param tmplen Length of input buffer.
|
|
|
|
* @param buffer Output buffer where the rendered text is going to be written.
|
|
|
|
* @param buflen Length of output buffer.
|
2011-05-03 23:30:09 +00:00
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
static inline void
|
|
|
|
psyc_text_state_init (PsycTextState *state,
|
|
|
|
char *tmpl, size_t tmplen,
|
|
|
|
char *buffer, size_t buflen)
|
2011-05-03 21:03:52 +00:00
|
|
|
{
|
2011-11-11 21:18:24 +00:00
|
|
|
state->cursor = 0;
|
|
|
|
state->written = 0;
|
|
|
|
state->tmpl = (PsycString) {
|
|
|
|
tmplen, tmpl};
|
|
|
|
state->buffer = (PsycString) {
|
|
|
|
buflen, buffer};
|
|
|
|
state->open = (PsycString) {
|
|
|
|
1, "["};
|
|
|
|
state->close = (PsycString) {
|
|
|
|
1, "]"};
|
2011-05-03 21:03:52 +00:00
|
|
|
}
|
2011-05-03 20:18:35 +00:00
|
|
|
|
2011-05-03 23:30:09 +00:00
|
|
|
/**
|
2011-05-28 17:39:42 +00:00
|
|
|
* Initializes the PSYC text state struct with custom opening & closing braces.
|
2011-05-03 23:30:09 +00:00
|
|
|
*
|
|
|
|
* @param state Pointer to the PSYC text state struct that should be initialized.
|
2011-05-28 17:39:42 +00:00
|
|
|
* @param tmpl Input buffer with text template to be parsed.
|
|
|
|
* @param tmplen Length of input buffer.
|
|
|
|
* @param buffer Output buffer where the rendered text is going to be written.
|
|
|
|
* @param buflen Length of output buffer.
|
2011-05-03 23:30:09 +00:00
|
|
|
* @param open Opening brace.
|
|
|
|
* @param openlen Length of opening brace.
|
|
|
|
* @param close Closing brace.
|
|
|
|
* @param closelen Length of closing brace.
|
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
static inline void
|
|
|
|
psyc_text_state_init_custom (PsycTextState *state,
|
|
|
|
char *tmpl, size_t tmplen,
|
|
|
|
char *buffer, size_t buflen,
|
|
|
|
char *open, size_t openlen,
|
|
|
|
char *close, size_t closelen)
|
2011-05-03 21:03:52 +00:00
|
|
|
{
|
2011-11-11 21:18:24 +00:00
|
|
|
state->cursor = 0;
|
|
|
|
state->written = 0;
|
|
|
|
state->tmpl = (PsycString) {
|
|
|
|
tmplen, tmpl};
|
|
|
|
state->buffer = (PsycString) {
|
|
|
|
buflen, buffer};
|
|
|
|
state->open = (PsycString) {
|
|
|
|
openlen, open};
|
|
|
|
state->close = (PsycString) {
|
|
|
|
closelen, close};
|
2011-05-03 21:03:52 +00:00
|
|
|
}
|
2011-05-03 20:18:35 +00:00
|
|
|
|
2011-05-03 23:30:09 +00:00
|
|
|
/**
|
2011-05-28 17:39:42 +00:00
|
|
|
* Sets a new output buffer in the PSYC text state struct.
|
2011-05-03 23:30:09 +00:00
|
|
|
*/
|
2011-11-11 21:18:24 +00:00
|
|
|
static inline void
|
|
|
|
psyc_text_buffer_set (PsycTextState *state, char *buffer, size_t length)
|
2011-05-03 21:03:52 +00:00
|
|
|
{
|
2011-11-11 21:18:24 +00:00
|
|
|
state->buffer = (PsycString) {
|
|
|
|
length, buffer};
|
|
|
|
state->written = 0;
|
2011-05-03 21:03:52 +00:00
|
|
|
}
|
2011-05-03 20:18:35 +00:00
|
|
|
|
2011-11-11 21:18:24 +00:00
|
|
|
static inline size_t
|
|
|
|
psyc_text_bytes_written (PsycTextState *state)
|
2011-05-04 02:01:21 +00:00
|
|
|
{
|
2011-11-11 21:18:24 +00:00
|
|
|
return state->written;
|
2011-05-04 02:01:21 +00:00
|
|
|
}
|
|
|
|
|
2011-05-03 20:18:35 +00:00
|
|
|
/**
|
|
|
|
* Fills out text templates by asking a callback for content.
|
|
|
|
*
|
2011-05-03 23:30:09 +00:00
|
|
|
* Copies the contents of the template into the buffer while looking for the
|
|
|
|
* opening and closing brace strings and calling the callback for each enclosed
|
|
|
|
* string between these braces. Should the callback return
|
|
|
|
* PSYC_TEXT_VALUE_NOT_FOUND, the original template text is copied as is.
|
2011-05-03 20:18:35 +00:00
|
|
|
*
|
2011-10-31 19:04:16 +00:00
|
|
|
* Before calling this function psyc_text_state_init should be called to initialize
|
2011-05-28 17:39:42 +00:00
|
|
|
* the state struct. By default PSYC's "[" and "]" are used but you can provide
|
|
|
|
* any other brace strings such as "${" and "}" or "<!--" and "-->" if you use
|
2011-10-31 19:04:16 +00:00
|
|
|
* the psyc_text_state_init_custom variant.
|
2011-05-03 20:18:35 +00:00
|
|
|
*
|
2011-05-03 23:30:09 +00:00
|
|
|
* @see http://about.psyc.eu/psyctext
|
|
|
|
**/
|
2011-11-11 21:18:24 +00:00
|
|
|
PsycTextRC
|
|
|
|
psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra);
|
2011-05-03 23:30:09 +00:00
|
|
|
|
2011-11-30 12:51:50 +00:00
|
|
|
extern const PsycTemplates psyc_templates;
|
|
|
|
|
|
|
|
static inline const char *
|
|
|
|
psyc_template (PsycMethod mc, size_t *len) {
|
|
|
|
PsycString t = psyc_templates.a[mc];
|
|
|
|
if (len)
|
|
|
|
*len = t.length;
|
|
|
|
return t.data;
|
|
|
|
}
|
|
|
|
|
2011-05-03 23:30:09 +00:00
|
|
|
/** @} */ // end of text group
|
2011-05-09 07:02:15 +00:00
|
|
|
|
|
|
|
#endif
|