exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

mustach.h (12665B)


      1 /*
      2  Author: José Bollo <jobol@nonadev.net>
      3 
      4  https://gitlab.com/jobol/mustach
      5 
      6  SPDX-License-Identifier: 0BSD
      7 */
      8 
      9 #ifndef _mustach_h_included_
     10 #define _mustach_h_included_
     11 
     12 #include <stdio.h>
     13 
     14 struct mustach_sbuf; /* see below */
     15 
     16 /**
     17  * Current version of mustach and its derivates
     18  */
     19 #define MUSTACH_VERSION 102
     20 #define MUSTACH_VERSION_MAJOR (MUSTACH_VERSION / 100)
     21 #define MUSTACH_VERSION_MINOR (MUSTACH_VERSION % 100)
     22 
     23 /**
     24  * Maximum nested section supported
     25  */
     26 #define MUSTACH_MAX_DEPTH  256
     27 
     28 /**
     29  * Maximum nested template supported
     30  */
     31 #define MUSTACH_MAX_NESTING  64
     32 
     33 /**
     34  * Maximum length of tags in mustaches {{...}}
     35  */
     36 #define MUSTACH_MAX_LENGTH 4096
     37 
     38 /**
     39  * Maximum length of delimitors (2 normally but extended here)
     40  */
     41 #define MUSTACH_MAX_DELIM_LENGTH 8
     42 
     43 /**
     44  * Flags specific to mustach core
     45  */
     46 #define Mustach_With_NoExtensions   0
     47 #define Mustach_With_Colon          1
     48 #define Mustach_With_EmptyTag       2
     49 #define Mustach_With_AllExtensions  3
     50 
     51 /*
     52  * Definition of error codes returned by mustach
     53  */
     54 #define MUSTACH_OK                       0
     55 #define MUSTACH_ERROR_SYSTEM            -1
     56 #define MUSTACH_ERROR_UNEXPECTED_END    -2
     57 #define MUSTACH_ERROR_EMPTY_TAG         -3
     58 #define MUSTACH_ERROR_TAG_TOO_LONG      -4
     59 #define MUSTACH_ERROR_BAD_SEPARATORS    -5
     60 #define MUSTACH_ERROR_TOO_DEEP          -6
     61 #define MUSTACH_ERROR_CLOSING           -7
     62 #define MUSTACH_ERROR_BAD_UNESCAPE_TAG  -8
     63 #define MUSTACH_ERROR_INVALID_ITF       -9
     64 #define MUSTACH_ERROR_ITEM_NOT_FOUND    -10
     65 #define MUSTACH_ERROR_PARTIAL_NOT_FOUND -11
     66 #define MUSTACH_ERROR_UNDEFINED_TAG     -12
     67 #define MUSTACH_ERROR_TOO_MUCH_NESTING  -13
     68 
     69 /*
     70  * You can use definition below for user specific error
     71  *
     72  * The macro MUSTACH_ERROR_USER is involutive so for any value
     73  *   value = MUSTACH_ERROR_USER(MUSTACH_ERROR_USER(value))
     74  */
     75 #define MUSTACH_ERROR_USER_BASE         -100
     76 #define MUSTACH_ERROR_USER(x)           (MUSTACH_ERROR_USER_BASE-(x))
     77 #define MUSTACH_IS_ERROR_USER(x)        (MUSTACH_ERROR_USER(x) >= 0)
     78 
     79 /**
     80  * mustach_itf - pure abstract mustach - interface for callbacks
     81  *
     82  * The functions enter and next should return 0 or 1.
     83  *
     84  * All other functions should normally return MUSTACH_OK (zero).
     85  *
     86  * If any function returns a negative value, it means an error that
     87  * stop the processing and that is reported to the caller. Mustach
     88  * also has its own error codes. Using the macros MUSTACH_ERROR_USER
     89  * and MUSTACH_IS_ERROR_USER could help to avoid clashes.
     90  *
     91  * @start: If defined (can be NULL), starts the mustach processing
     92  *         of the closure, called at the very beginning before any
     93  *         mustach processing occurs.
     94  *
     95  * @put: If defined (can be NULL), writes the value of 'name'
     96  *       to 'file' with 'escape' or not.
     97  *       As an extension (see NO_ALLOW_EMPTY_TAG), the 'name' can be
     98  *       the empty string. In that later case an implementation can
     99  *       return MUSTACH_ERROR_EMPTY_TAG to refuse empty names.
    100  *       If NULL and 'get' NULL the error MUSTACH_ERROR_INVALID_ITF
    101  *       is returned.
    102  *
    103  * @enter: Enters the section of 'name' if possible.
    104  *         Musts return 1 if entered or 0 if not entered.
    105  *         When 1 is returned, the function 'leave' will always be called.
    106  *         Conversely 'leave' is never called when enter returns 0 or
    107  *         a negative value.
    108  *         When 1 is returned, the function must activate the first
    109  *         item of the section.
    110  *
    111  * @next: Activates the next item of the section if it exists.
    112  *        Musts return 1 when the next item is activated.
    113  *        Musts return 0 when there is no item to activate.
    114  *
    115  * @leave: Leaves the last entered section
    116  *
    117  * @partial: If defined (can be NULL), returns in 'sbuf' the content of the
    118  *           partial of 'name'. @see mustach_sbuf
    119  *           If NULL but 'get' not NULL, 'get' is used instead of partial.
    120  *           If NULL and 'get' NULL and 'put' not NULL, 'put' is called with
    121  *           a true FILE.
    122  *
    123  * @emit: If defined (can be NULL), writes the 'buffer' of 'size' with 'escape'.
    124  *        If NULL the standard function 'fwrite' is used with a true FILE.
    125  *        If not NULL that function is called instead of 'fwrite' to output
    126  *        text.
    127  *        It implies that if you define either 'partial' or 'get' callback,
    128  *        the meaning of 'FILE *file' is abstract for mustach's process and
    129  *        then you can use 'FILE*file' pass any kind of pointer (including NULL)
    130  *        to the function 'fmustach'. An example of a such behaviour is given by
    131  *        the implementation of 'mustach_json_c_write'.
    132  *
    133  * @get: If defined (can be NULL), returns in 'sbuf' the value of 'name'.
    134  *       As an extension (see NO_ALLOW_EMPTY_TAG), the 'name' can be
    135  *       the empty string. In that later case an implementation can
    136  *       return MUSTACH_ERROR_EMPTY_TAG to refuse empty names.
    137  *       If 'get' is NULL and 'put' NULL the error MUSTACH_ERROR_INVALID_ITF
    138  *       is returned.
    139  *
    140  * @stop: If defined (can be NULL), stops the mustach processing
    141  *        of the closure, called at the very end after all mustach
    142  *        processing occurered. The status returned by the processing
    143  *        is passed to the stop.
    144  *
    145  * The array below summarize status of callbacks:
    146  *
    147  *    FULLY OPTIONAL:   start partial
    148  *    MANDATORY:        enter next leave
    149  *    COMBINATORIAL:    put emit get
    150  *
    151  * Not definig a MANDATORY callback returns error MUSTACH_ERROR_INVALID_ITF.
    152  *
    153  * For COMBINATORIAL callbacks the array below summarize possible combinations:
    154  *
    155  *  combination  : put     : emit    : get     : abstract FILE
    156  *  -------------+---------+---------+---------+-----------------------
    157  *  HISTORIC     : defined : NULL    : NULL    : NO: standard FILE
    158  *  MINIMAL      : NULL    : NULL    : defined : NO: standard FILE
    159  *  CUSTOM       : NULL    : defined : defined : YES: abstract FILE
    160  *  DUCK         : defined : NULL    : defined : NO: standard FILE
    161  *  DANGEROUS    : defined : defined : any     : YES or NO, depends on 'partial'
    162  *  INVALID      : NULL    : any     : NULL    : -
    163  *
    164  * The DUCK case runs on one leg. 'get' is not used if 'partial' is defined
    165  * but is used for 'partial' if 'partial' is NULL. Thus for clarity, do not use
    166  * it that way but define 'partial' and let 'get' be NULL.
    167  *
    168  * The DANGEROUS case is special: it allows abstract FILE if 'partial' is defined
    169  * but forbids abstract FILE when 'partial' is NULL.
    170  *
    171  * The INVALID case returns error MUSTACH_ERROR_INVALID_ITF.
    172  */
    173 struct mustach_itf {
    174 	int (*start)(void *closure);
    175 	int (*put)(void *closure, const char *name, int escape, FILE *file);
    176 	int (*enter)(void *closure, const char *name);
    177 	int (*next)(void *closure);
    178 	int (*leave)(void *closure);
    179 	int (*partial)(void *closure, const char *name, struct mustach_sbuf *sbuf);
    180 	int (*emit)(void *closure, const char *buffer, size_t size, int escape, FILE *file);
    181 	int (*get)(void *closure, const char *name, struct mustach_sbuf *sbuf);
    182 	void (*stop)(void *closure, int status);
    183 };
    184 
    185 /**
    186  * mustach_sbuf - Interface for handling zero terminated strings
    187  *
    188  * That structure is used for returning zero terminated strings -in 'value'-
    189  * to mustach. The callee can provide a function for releasing the returned
    190  * 'value'. Three methods for releasing the string are possible.
    191  *
    192  *  1. no release: set either 'freecb' or 'releasecb' with NULL (done by default)
    193  *  2. release without closure: set 'freecb' to its expected value
    194  *  3. release with closure: set 'releasecb' and 'closure' to their expected values
    195  *
    196  * @value: The value of the string. That value is not changed by mustach -const-.
    197  *
    198  * @freecb: The function to call for freeing the value without closure.
    199  *          For convenience, signature of that callback is compatible with 'free'.
    200  *          Can be NULL.
    201  *
    202  * @releasecb: The function to release with closure.
    203  *             Can be NULL.
    204  *
    205  * @closure: The closure to use for 'releasecb'.
    206  *
    207  * @length: Length of the value or zero if unknown and value null terminated.
    208  *          To return the empty string, let it to zero and let value to NULL.
    209  */
    210 struct mustach_sbuf {
    211 	const char *value;
    212 	union {
    213 		void (*freecb)(void*);
    214 		void (*releasecb)(const char *value, void *closure);
    215 	};
    216 	void *closure;
    217 	size_t length;
    218 };
    219 
    220 /**
    221  * mustach_file - Renders the mustache 'template' in 'file' for 'itf' and 'closure'.
    222  *
    223  * @template: the template string to instantiate
    224  * @length:   length of the template or zero if unknown and template null terminated
    225  * @itf:      the interface to the functions that mustach calls
    226  * @closure:  the closure to pass to functions called
    227  * @file:     the file where to write the result
    228  *
    229  * Returns 0 in case of success, -1 with errno set in case of system error
    230  * a other negative value in case of error.
    231  */
    232 extern int mustach_file(const char *template, size_t length, const struct mustach_itf *itf, void *closure, int flags, FILE *file);
    233 
    234 /**
    235  * mustach_fd - Renders the mustache 'template' in 'fd' for 'itf' and 'closure'.
    236  *
    237  * @template: the template string to instantiate
    238  * @length:   length of the template or zero if unknown and template null terminated
    239  * @itf:      the interface to the functions that mustach calls
    240  * @closure:  the closure to pass to functions called
    241  * @fd:       the file descriptor number where to write the result
    242  *
    243  * Returns 0 in case of success, -1 with errno set in case of system error
    244  * a other negative value in case of error.
    245  */
    246 extern int mustach_fd(const char *template, size_t length, const struct mustach_itf *itf, void *closure, int flags, int fd);
    247 
    248 /**
    249  * mustach_mem - Renders the mustache 'template' in 'result' for 'itf' and 'closure'.
    250  *
    251  * @template: the template string to instantiate
    252  * @length:   length of the template or zero if unknown and template null terminated
    253  * @itf:      the interface to the functions that mustach calls
    254  * @closure:  the closure to pass to functions called
    255  * @result:   the pointer receiving the result when 0 is returned
    256  * @size:     the size of the returned result
    257  *
    258  * Returns 0 in case of success, -1 with errno set in case of system error
    259  * a other negative value in case of error.
    260  */
    261 extern int mustach_mem(const char *template, size_t length, const struct mustach_itf *itf, void *closure, int flags, char **result, size_t *size);
    262 
    263 /***************************************************************************
    264 * compatibility with version before 1.0
    265 */
    266 #ifdef __GNUC__
    267 #define DEPRECATED_MUSTACH(func) func __attribute__ ((deprecated))
    268 #elif defined(_MSC_VER)
    269 #define DEPRECATED_MUSTACH(func) __declspec(deprecated) func
    270 #elif !defined(DEPRECATED_MUSTACH)
    271 #pragma message("WARNING: You need to implement DEPRECATED_MUSTACH for this compiler")
    272 #define DEPRECATED_MUSTACH(func) func
    273 #endif
    274 /**
    275  * OBSOLETE use mustach_file
    276  *
    277  * fmustach - Renders the mustache 'template' in 'file' for 'itf' and 'closure'.
    278  *
    279  * @template: the template string to instantiate, null terminated
    280  * @itf:      the interface to the functions that mustach calls
    281  * @closure:  the closure to pass to functions called
    282  * @file:     the file where to write the result
    283  *
    284  * Returns 0 in case of success, -1 with errno set in case of system error
    285  * a other negative value in case of error.
    286  */
    287 DEPRECATED_MUSTACH(extern int fmustach(const char *template, const struct mustach_itf *itf, void *closure, FILE *file));
    288 
    289 /**
    290  * OBSOLETE use mustach_fd
    291  *
    292  * fdmustach - Renders the mustache 'template' in 'fd' for 'itf' and 'closure'.
    293  *
    294  * @template: the template string to instantiate, null terminated
    295  * @itf:      the interface to the functions that mustach calls
    296  * @closure:  the closure to pass to functions called
    297  * @fd:       the file descriptor number where to write the result
    298  *
    299  * Returns 0 in case of success, -1 with errno set in case of system error
    300  * a other negative value in case of error.
    301  */
    302 DEPRECATED_MUSTACH(extern int fdmustach(const char *template, const struct mustach_itf *itf, void *closure, int fd));
    303 
    304 /**
    305  * OBSOLETE use mustach_mem
    306  *
    307  * mustach - Renders the mustache 'template' in 'result' for 'itf' and 'closure'.
    308  *
    309  * @template: the template string to instantiate, null terminated
    310  * @itf:      the interface to the functions that mustach calls
    311  * @closure:  the closure to pass to functions called
    312  * @result:   the pointer receiving the result when 0 is returned
    313  * @size:     the size of the returned result
    314  *
    315  * Returns 0 in case of success, -1 with errno set in case of system error
    316  * a other negative value in case of error.
    317  */
    318 DEPRECATED_MUSTACH(extern int mustach(const char *template, const struct mustach_itf *itf, void *closure, char **result, size_t *size));
    319 
    320 #endif
    321