Annotation of embedaddon/libpdel/tmpl/tmpl.h, revision 1.1.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>