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