Annotation of embedaddon/libpdel/tmpl/tmpl.h, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (c) 2001-2002 Packet Design, LLC.
! 4: * All rights reserved.
! 5: *
! 6: * Subject to the following obligations and disclaimer of warranty,
! 7: * use and redistribution of this software, in source or object code
! 8: * forms, with or without modifications are expressly permitted by
! 9: * Packet Design; provided, however, that:
! 10: *
! 11: * (i) Any and all reproductions of the source or object code
! 12: * must include the copyright notice above and the following
! 13: * disclaimer of warranties; and
! 14: * (ii) No rights are granted, in any manner or form, to use
! 15: * Packet Design trademarks, including the mark "PACKET DESIGN"
! 16: * on advertising, endorsements, or otherwise except as such
! 17: * appears in the above copyright notice or in the software.
! 18: *
! 19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
! 20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
! 21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
! 22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
! 23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
! 24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
! 25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
! 26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
! 27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
! 28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
! 29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
! 30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
! 31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
! 32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
! 33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
! 35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
! 36: * THE POSSIBILITY OF SUCH DAMAGE.
! 37: *
! 38: * Author: Archie Cobbs <archie@freebsd.org>
! 39: */
! 40:
! 41: #ifndef _PDEL_TMPL_TMPL_H_
! 42: #define _PDEL_TMPL_TMPL_H_
! 43:
! 44: /*
! 45: * This code supports a simple text template language. An input file
! 46: * is scanned for special function tags. A function tag is an at sign
! 47: * ('@') followed by a contiguous sequence of letters, digits, and
! 48: * underscores, followed by parentheses containing zero or more
! 49: * function arguments.
! 50: *
! 51: * Function arguments may be either other function tags (the argument
! 52: * to the outer function is the result of the inner function invocation),
! 53: * or constant literal strings in double quotes (the argument is the
! 54: * value of the string). Note this means that all function arguments
! 55: * begin with either an at sign or a double quote character. Function
! 56: * arguments are enclosed in parentheses, separated by commas, and
! 57: * may have whitespace around them.
! 58: *
! 59: * When processed, function tags result in a function invocation
! 60: * which returns some text which is then substituted into the output
! 61: * stream. Special control flow function tags control input processing
! 62: * and return the empty string.
! 63: *
! 64: * Non-function tag text input is passed through unaltered.
! 65: *
! 66: * Constant literal strings (enclosed in double quotes) respect the
! 67: * normal C backslash escapes.
! 68: *
! 69: * Built-in functions that take no arguments do not require parentheses,
! 70: * but parentheses may be included for separation purposes.
! 71: *
! 72: * User-supplied functions may return NULL and set errno to indicate
! 73: * an error, in which case the corresponding error string is substituted,
! 74: * after being formatted by the caller-supplied error formatter.
! 75: *
! 76: * The predefined functions are:
! 77: *
! 78: * @while(x) ... @endwhile
! 79: * The text in between is repeated as long as x is true
! 80: * (x is true if it is an integer whose value is non-zero).
! 81: *
! 82: * @loop(numloops) ... @endloop
! 83: * The text in between is repeated 'numloops' times, which
! 84: * must be an integer value.
! 85: *
! 86: * @loopindex(i)
! 87: * Returns the loop index (counting from zero) of the loop
! 88: * that is 'i' loops out from the innermost loop, else -1.
! 89: * If argument is omitted it is assumed to be zero.
! 90: *
! 91: * @if(x) ... [ @elif ... [ @elif ... ] ] [ @else ... ] @endif
! 92: * Conditional execution depending on the truth value of x.
! 93: *
! 94: * @define(name) ... @enddef
! 95: * Defines a run-time function. The text in between is executed
! 96: * whenever @name(...) is subsequently invoked. During this execution,
! 97: * the variables "argc" and "arg0", "arg1", ... are set to the
! 98: * function argument count and arguments, respectively (the function
! 99: * name itself is always the value of "arg0".
! 100: *
! 101: * @break
! 102: * Break out of the nearest enclosing @loop or @while loop.
! 103: *
! 104: * @continue
! 105: * Continue with the next iteration of the nearest enclosing
! 106: * @loop or @while loop.
! 107: *
! 108: * @return
! 109: * Return from within a run-time function.
! 110: *
! 111: * @equal(x,y)
! 112: * Returns "1" if x and y are identical, else "0".
! 113: *
! 114: * @not(x)
! 115: * Returns "1" unless x is an integer whose value is non-zero.
! 116: *
! 117: * @and(arg1, arg2, ...)
! 118: * Returns logical "and" of the truth values of the arguments.
! 119: *
! 120: * @or(arg1, arg2, ...)
! 121: * Returns logical "or" of the truth values of the arguments.
! 122: *
! 123: * @add(arg1, ...)
! 124: * Returns sum of the numerical values of the arguments.
! 125: *
! 126: * @mul(arg1, ...)
! 127: * Returns product of the numerical values of the arguments.
! 128: *
! 129: * @div(arg1, arg2)
! 130: * Returns the first argument divided by the second.
! 131: *
! 132: * @mod(arg1, arg2)
! 133: * Returns the first argument modulo by the second.
! 134: *
! 135: * @lt(arg1, arg2)
! 136: * @gt(arg1, arg2)
! 137: * @le(arg1, arg2)
! 138: * @ge(arg1, arg2)
! 139: * Returns "0" or "1" as arg1 is <, >, <=, or >= arg2.
! 140: *
! 141: * @sub(arg1, ...)
! 142: * Returns subtraction of the numerical values of the second
! 143: * and subsequent arguments from the first.
! 144: *
! 145: * @error(arg)
! 146: * Output the argument using the caller's error formatting.
! 147: *
! 148: * @eval(arg)
! 149: * The argument itself is processed. Embedded function tags
! 150: * are processed normally, while the rest is passed unaltered.
! 151: *
! 152: * @funcname(arg1, arg2, ...)
! 153: * Invoke the generic user-supplied function handler.
! 154: *
! 155: * @@
! 156: * Expands to ``@''
! 157: *
! 158: * @cat(arg1, arg2, ...)
! 159: * Returns concatentated arguments.
! 160: *
! 161: * @set(var, value)
! 162: * Sets run-time variable 'var' to have value 'value'. Variables
! 163: * are global and live until tmpl_process() returns. Returns the
! 164: * empty string.
! 165: *
! 166: * @get(var)
! 167: * Retrieves the value of run-time variable 'var'.
! 168: * Returns the empty string if 'var' is not set.
! 169: *
! 170: * @urlencode(arg)
! 171: * Expands and URL-encodes the argument.
! 172: *
! 173: * @htmlencode(arg)
! 174: * Expands and HTML-encodes the first argument.
! 175: *
! 176: * @output(arg)
! 177: * Outputs the argument directly to the output stream. That is,
! 178: * if this function is invoked from within a user-defined function,
! 179: * the argument goes directly to the template output rather than
! 180: * being concatenated to the return value of the function.
! 181: *
! 182: * @flush()
! 183: * Flushes the template output.
! 184: *
! 185: * @foobar(...)
! 186: * If "foobar" is not defined as a run-time function, then this
! 187: * invokes the supplied handler for user-defined functions.
! 188: * Here "foobar" is any name other than the above function names,
! 189: * consisting of only letters, digits, and underscores.
! 190: *
! 191: */
! 192:
! 193: struct tmpl;
! 194: struct tmpl_ctx;
! 195:
! 196: #define TMPL_FUNCTION_CHARACTER '@'
! 197:
! 198: /***********************************************************************
! 199: CALLBACK FUNCTION TYPES
! 200: ***********************************************************************/
! 201:
! 202: /*
! 203: * Generic function handler type. Should return a malloc'd string (allocated
! 204: * with the same memory type as passed to tmpl_ctx_create()), or else return
! 205: * NULL and either set errno or set *errmsgp to point to a malloc'd string
! 206: * (same memory type) containing an error message. *errmsgp will be NULL
! 207: * initially.
! 208: *
! 209: * The first argument is the function name. Subsequent arguments are the
! 210: * (evaluated) arguments passed to the function. Note that this means "argc"
! 211: * is always >= 1. argv[argc] is NOT guaranteed to be NULL.
! 212: */
! 213: typedef char *tmpl_handler_t(struct tmpl_ctx *ctx, char **errmsgp,
! 214: int argc, char **argv);
! 215:
! 216: /*
! 217: * Error formatter type. This should format the error message string
! 218: * using whatever formatting is desired and return the result in a
! 219: * malloc'd buffer (note: just returning 'errmsg' is wrong; use
! 220: * strdup(3) instead). Return NULL and set errno if there is an error.
! 221: * The "arg" parameter is the same "arg" passed to tmpl_ctx_create().
! 222: */
! 223: typedef char *tmpl_errfmtr_t(struct tmpl_ctx *ctx, const char *errmsg);
! 224:
! 225: /***********************************************************************
! 226: PUBLIC FUNCTIONS
! 227: ***********************************************************************/
! 228:
! 229: __BEGIN_DECLS
! 230:
! 231: /*
! 232: * Create template object by parsing "input". The input stream must
! 233: * be seekable, and is not used again after this function returns.
! 234: *
! 235: * If num_errors != NULL, it will be set to the number of parse
! 236: * errors encountered while parsing the input.
! 237: *
! 238: * Returns NULL and sets errno on failure.
! 239: */
! 240: extern struct tmpl *tmpl_create(FILE *input,
! 241: int *num_errors, const char *mtype);
! 242:
! 243: /*
! 244: * Similar to tmpl_create(), but memory map the file so that its
! 245: * contents don't have to be stored in heap memory. However, the
! 246: * file contents must not change or else subsequent executions will
! 247: * give garbled output.
! 248: */
! 249: extern struct tmpl *tmpl_create_mmap(const char *path,
! 250: int *num_errors, const char *mtype);
! 251:
! 252: /*
! 253: * Destroy and free a template file created by tmpl_create().
! 254: *
! 255: * Upon return, *tmplp is set to NULL. If *tmplp is already NULL,
! 256: * this does nothing.
! 257: */
! 258: extern void tmpl_destroy(struct tmpl **tmplp);
! 259:
! 260: /*
! 261: * Create a template execution context.
! 262: *
! 263: * For all functions that are not predefined, the function is looked up
! 264: * in the 'userfuncs' array (which is not copied and so must remain
! 265: * valid for the life of the exectution context). This array must be
! 266: * sorted by name and terminated with an entry having a NULL name.
! 267: * All userfuncs will have 'arg' passed as their first argument.
! 268: *
! 269: * All strings returned by "handler" MUST be dynamically allocated
! 270: * using memory type 'mtype'.
! 271: *
! 272: * The 'errfmtr' is called to specially format any generated error
! 273: * messages; if it is NULL, error messages are output as plain text.
! 274: */
! 275: extern struct tmpl_ctx *tmpl_ctx_create(void *arg, const char *mtype,
! 276: tmpl_handler_t *handler, tmpl_errfmtr_t *errfmtr);
! 277:
! 278: /*
! 279: * Get context argument.
! 280: */
! 281: extern void *tmpl_ctx_get_arg(struct tmpl_ctx *ctx);
! 282:
! 283: /*
! 284: * Get context memory type.
! 285: */
! 286: extern const char *tmpl_ctx_get_mtype(struct tmpl_ctx *ctx);
! 287:
! 288: /*
! 289: * Execute a template and output the result to 'output'.
! 290: *
! 291: * If a system error is encountered, execution halts and -1
! 292: * is returned with 'errno' set. Otherwise, zero is returned.
! 293: *
! 294: * Flags:
! 295: *
! 296: * TMPL_SKIP_NL_WHITE Skip inter-function text consisting only of
! 297: * one or more newlines followed by whitespace.
! 298: */
! 299: extern int tmpl_execute(struct tmpl *tmpl, struct tmpl_ctx *ctx,
! 300: FILE *output, int flags);
! 301:
! 302: #define TMPL_SKIP_NL_WHITE 0x0001
! 303:
! 304: /*
! 305: * Destroy and free a template context created by tmpl_ctx_create().
! 306: *
! 307: * Upon return, *ctxp is set to NULL. If *ctxp is already NULL,
! 308: * this does nothing.
! 309: */
! 310: extern void tmpl_ctx_destroy(struct tmpl_ctx **ctxp);
! 311:
! 312: /*
! 313: * Functions to get and set variables associated with a context.
! 314: */
! 315: extern const char *tmpl_ctx_get_var(struct tmpl_ctx *ctx, const char *name);
! 316: extern int tmpl_ctx_set_var(struct tmpl_ctx *ctx,
! 317: const char *name, const char *value);
! 318:
! 319: /*
! 320: * Invoke a template function and write the output to "output".
! 321: *
! 322: * Returns zero if successful, otherwise returns -1 and either
! 323: * sets *errmsgp to NULL and errno to the error code, or else
! 324: * sets *errmsgp to some appropriate error message.
! 325: */
! 326: extern int tmpl_execute_func(struct tmpl_ctx *ctx, FILE *output,
! 327: char **errmsgp, int argc, char **argv,
! 328: int flags);
! 329:
! 330: /*
! 331: * Reset a template context.
! 332: *
! 333: * This undoes the result of any variable assignments and run-time
! 334: * function definitions from a previous execution using the context.
! 335: * That is, the context is returned to original state as returned by
! 336: * tmpl_ctx_create().
! 337: */
! 338: extern void tmpl_ctx_reset(struct tmpl_ctx *ctx);
! 339:
! 340: /*
! 341: * Built-in handler for handling a fixed list of user functions.
! 342: *
! 343: * The 'userfuncs' array must be sorted lexicographically by name.
! 344: */
! 345:
! 346: /* Structure describing a user-supplied function */
! 347: struct tmpl_func {
! 348: const char *name; /* function name, null to end list */
! 349: u_int min_args; /* min # args (not counting name) */
! 350: u_int max_args; /* max # args (not counting name) */
! 351: tmpl_handler_t *handler; /* handler for function */
! 352: };
! 353:
! 354: extern char *tmpl_list_handler(struct tmpl_ctx *ctx,
! 355: const struct tmpl_func *userfuncs, u_int uflen,
! 356: char **errmsgp, int argc, char **argv);
! 357:
! 358: __END_DECLS
! 359:
! 360: #endif /* _PDEL_TMPL_TMPL_H_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>