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>