Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
TMPL(3)		       FreeBSD Library Functions Manual		       TMPL(3)

NAME
     tmpl -- templates

LIBRARY
     PDEL Library (libpdel, -lpdel)

SYNOPSIS
     struct tmpl *
     tmpl_create(FILE *input, int *num_errors, const char *mtype);

     struct tmpl *
     tmpl_create_mmap(const char *path,	int *num_errors, const char *mtype);

     void
     tmpl_destroy(struct tmpl **tmplp);

     struct tmpl_ctx *
     tmpl_ctx_create(void *arg,	const char *mtype, tmpl_handler_t *handler,
	 tmpl_errfmtr_t	*errfmtr);

     void *
     tmpl_ctx_get_arg(struct tmpl_ctx *ctx);

     const char	*
     tmpl_ctx_get_mtype(struct tmpl_ctx	*ctx);

     const char	*
     tmpl_ctx_get_var(struct tmpl_ctx *ctx, const char *name);

     int
     tmpl_ctx_set_var(struct tmpl_ctx *ctx, const char *name,
	 const char *value);

     char *
     tmpl_list_handler(struct tmpl_ctx *ctx,
	 const struct tmpl_func	*userfuncs, u_int uflen, char **errmsgp,
	 int argc, char	**argv);

     void
     tmpl_ctx_destroy(struct tmpl_ctx **ctxp);

     int
     tmpl_execute(struct tmpl *tmpl, struct tmpl_ctx *ctx, FILE	*output,
	 int flags);

     int
     tmpl_execute_func(struct tmpl_ctx *ctx, FILE *output, char	**errmsgp,
	 int argc, char	**argv,	int flags);

     void
     tmpl_ctx_reset(struct tmpl_ctx *ctx);

DESCRIPTION
   Overview
     The tmpl library supports programmatic generation of output based on in-
     put from tmpl template files.  Output is generated	by parsing and then
     executing a tmpl file.

     The tmpl file simply contains the desired output, with invocations	of
     various tmpl functions, denoted by	the "@"	character, interspersed.  Tmpl
     functions take zero or more arguments, where each argument	can be either
     a doubly-quoted string or another,	nested tmpl function.

     When executed, the	output of a tmpl file is simply	the contents of	the
     file, with	each tmpl function replaced by the value returned by that
     function.	Several	functions, including control flow constructs, are
     built-in, and compile-time	and run-time user defined functions are	sup-
     ported.

     Here is a simple example tmpl input file:

	I'm going to count to three:

	@set("i", "1")
	@while(@le(@get("i"), "3"))
	      @get("i")
	      @set("i",	@add(@get("i"),	"1"))
	@endwhile

	Done.

     If	this template were executed, the output	would be:

	I'm going to count to three:

	      1

	      2

	      3

	Done.

     While the example above uses only built-in	functions, user-defined	func-
     tions written in C	may be invoked in the same way.

Parsing
     This section describes the	precise	rules that govern how tmpl files are
     parsed.

     A tmpl file is parsed by scanning for special function calls.  A function
     call is an	at sign	('@') followed by a contiguous sequence	of letters,
     digits, and underscores, followed by matching parentheses containing zero
     or	more function arguments.  The text between functions calls is ignored
     (it doesn't even have to be text).

     Function arguments	may be either other nested function calls (the argu-
     ment to the outer function	is the result of the inner function invoca-
     tion), or constant	literal	strings	in double quotes (the argument is the
     value of the string).  Therefore, all function arguments begin with ei-
     ther an at	sign or	a double quote character.  Function arguments are sep-
     arated by commas and may have surrounding whitespace, which is ignored.

     Constant literal strings are enclosed in double quotes and	respect	the
     usual C backslash escapes.

     Built-in functions	(see below) that take zero arguments do	not require
     parentheses, but parentheses may be included for separation purposes.

     A parsed tmpl file	is represented by a struct tmpl.

Execution
     The parsing of a tmpl file	and its	execution are separate steps.  Once a
     tmpl file has been	parsed,	it may be executed several times.  Execution
     requires a	context, represented by	a struct tmpl_ctx, and generates out-
     put which is written to an	output stream.

     When the template is executed, the	text between function calls is copied
     to	the output stream without modification,	while the function calls are
     replaced with their values, which are strings.  Functions are evaluated
     as	they are encountered during execution.

     The tmpl library includes several built-in	functions, including special
     control flow functions that control input processing.  The	user code may
     also implement custom functions.

     User functions may	return NULL and	set errno to indicate an error;	they
     may also set an error string (if no error string is set, strerror(3) is
     used to generate one).  When such an error	occurs,	the function does not
     return at all.  Instead, an error message is propagated up	to the outer-
     most function call.  The error message is reformatted by an optional
     user-supplied error formatter function, and then the formatted message is
     written to	the output stream.

Built-in Functions
     The built-in functions are	listed below.  In these	definitions, the nu-
     meric value of a string is	the result of parsing it with strtol(3), and a
     string is considered "true" if it has a numeric value other than zero.

     Control flow

	 @while(x) ... @endwhile

	     The text in between is repeated as	long as	the argument supplied
	     to	@while() is true.

	 @loop(x) ... @endloop

	     The text in between is repeated N times, where N is the numerical
	     value of the argument passed to @loop().

	 @loopindex(x)

	     Takes zero	or one argument; returns the loop index	(counting from
	     zero) of the loop that is N loops out from	the innermost contain-
	     ing loop, where N is the numerical	value of the argument, or -1
	     if	no such	loop exists.  If the argument is omitted it is assumed
	     to	be zero.

	 @if(x)	... [ @elif(y) ... ] [ @else ... ] @endif

	     Conditional execution depending on	the truth value	of the argu-
	     ment to @if().  Zero or more @elif() blocks may be	followed by
	     zero or one @else block.  An @endif is always required.

	 @break()

	     Break out of the innermost	enclosing @loop	or @while.

	 @continue()

	     Continue with the next iteration of the nearest enclosing @loop
	     or	@while.

	 @return()

	     Return from within	a run-time function.

	 @eval(x)

	     Parses the	argument as a template,	executes it, and returns the
	     resulting output.

     Run-time variables	and functions

	 @set(name, value)

	     Sets the run-time variable	named by the first argument to have
	     the value equal to	the second argument.  All run-time variables
	     are global	and exist as long as the associated execution context
	     exists.

	 @get(name)

	     Returns the value of the run-time variable	named by the first ar-
	     gument, or	the empty string if the	variable is not	set.

	 @define(name) ... @enddef

	     Defines a run-time	function.  The text in between is executed
	     whenever @name(...) is invoked.  During this execution, the vari-
	     ables argc	and arg0, arg1,	... are	set to the function argument
	     count and arguments, respectively;	arg0 is	always equal to	the
	     name of the function.  All	run-time functions are global and ex-
	     ist as long as the	associated execution context exists.

	 @invoke()

	     Invokes a function.  The function to be invoked and its arguments
	     are described by the run-time variables argc and arg0, arg1, ...
	     as	above.	So arg0	is the function	name and arg0, arg1, ...  are
	     the function arguments.  @invoke()	itself does not	take any argu-
	     ments.

     Evaluators

	 @equal(x, y)

	     Returns "1" if x and y are	identical, otherwise "0".

	 @not(x)

	     Returns "1" if x is false,	otherwise "0".

	 @and(...)

	     Returns "1" if all	of the arguments are true, otherwise "0".

	 @or(...)

	     Returns "1" if any	of the arguments is true, otherwise "0".

	 @add(...)

	     Returns the sum of	the arguments.

	 @sub(x, ...)

	     Returns the second	and subsequent arguments subtracted from the
	     first.

	 @mul(...)

	     Returns the product of the	arguments.

	 @div(x, y)

	     Returns the first argument	divided	by the second.

	 @mod(x, y)

	     Returns the first argument	modulo the second.

	 @lt(x,	y)

	     Returns "1" if the	first argument is less than the	second,	other-
	     wise "0".

	 @le(x,	y)

	     Returns "1" if the	first argument is less than or equal to	the
	     second, otherwise "0".

	 @gt(x,	y)

	     Returns "1" if the	first argument is greater than the second,
	     otherwise "0".

	 @ge(x,	y)

	     Returns "1" if the	first argument is greater than or equal	to the
	     second, otherwise "0".

     String functions

	 @cat(...)

	     Returns the concatenation of all of the arguments.

	 @@()

	     Returns "@".

	 @error(arg)

	     Returns the argument formatted using the caller-supplied error
	     formatter.

	 @htmlencode(arg)

	     Encodes the argument with HTML escapes and	returns	the result.

	 @urlencode(arg)

	     Encodes the argument with URL escapes and returns the result.

     I/O functions

	 @flush()

	     Flushes the output	stream.

	 @output(arg)

	     Outputs the argument directly to the output stream. That is, if
	     this function is invoked from within a user-defined function, the
	     argument goes directly to the template output rather than being
	     concatenated to the return	value of the function.

API
     tmpl_create() parses input	from input and creates and returns a new tem-
     plate object, which uses typed_mem(3) type	mtype.	If num_errors is not
     NULL, then	the number of parse errors detected is stored in *num_errors.
     A parse error is an occurrence of the "@" character that is not the be-
     ginning of	a well-formed tmpl function invocation.

     tmpl_create_mmap()	parses the contents of the file	named path, using
     mmap(2) internally	to avoid having	to store the entire file in memory.
     This results in less memory being used; however, if the file's contents
     are changed then subsequent invocations of	tmpl_execute() may give	gar-
     bled output.

     tmpl_destroy() destroys a template	object.	 Upon return, *tmplp will be
     set to NULL.  If *tmplp is	already	NULL when tmpl_destroy() is invoked,
     nothing happens.

     tmpl_ctx_create() creates a new template execution	context.  mtype	is the
     typed_mem(3) type used not	only for the execution context object itself,
     but also for all strings generated	during execution.  In particular, all
     strings returned by user functions	must be	stored in buffers allocated
     with this type.  The arg is a user	cookie ignored by the tmpl functions.
     The parameters arg	and mtype may be retrieved with	tmpl_ctx_get_arg() and
     tmpl_ctx_get_mtype(), respectively.

     handler and errfmtr point to functions having these types:

	typedef	char *tmpl_handler_t(struct tmpl_ctx *ctx, char	**errmsgp,
			  int argc, char **argv);
	typedef	char *tmpl_errfmtr_t(struct tmpl_ctx *ctx, const char *errmsg);

     handler() returns the result of invoking the function described by	argc
     and argv as a '\0'-terminated string allocated with the typed_mem(3) type
     mtype.  The first argument	is always the function name, and subsequent
     arguments are the (evaluated) arguments passed to the function.  There-
     fore, argc	is always at least one.

     handler() may indicate an error by	returning NULL,	in which case it
     should either set errno appropriately or else set *errmsgp	to point to an
     error message (which should also be allocated with	typed_mem(3) type
     mtype); *errmsgp will be NULL when	handler() is invoked.

     The error formatter function errfmtr() is optional.  It should return an
     error string allocated with typed_mem(3) type mtype and formatted appro-
     priately for the template output (e.g., in	HTML).	The errmsg is the
     original, unformatted error string	returned by the	function handler; if
     the handler did not return	an explicit error message, strerror(errno) is
     used for errmsg.

     tmpl_list_handler() may be	useful for implementing	handler() when there
     is	a fixed	list of	user functions.	 The userfuncs parameter points	to a
     length uflen array	of struct tmpl_func:

	struct tmpl_func {
	    const char	    *name;	/* function name, null to end list */
	    u_int	    min_args;	/* min # args (not counting name) */
	    u_int	    max_args;	/* max # args (not counting name) */
	    tmpl_handler_t  *handler;	/* handler for function	*/
	};

     Each entry	in the array describes a user function.	 The function called
     name accepts at least min_args and	at most	max_args parameters, and is
     implemented by the	handler.  The array must be sorted lexicographically
     by	name.  tmpl_list_handler() finds the function named by argv[0] using a
     binary search of the array	and invokes its	handler() with the supplied
     arguments.	 In the	case of	an error, tmpl_list_handler() prepends the re-
     turned error string with the offending function call and arguments.

     tmpl_ctx_set_var()	and tmpl_ctx_get_var() may be used to set and retrieve
     variables associated with ctx.

     tmpl_ctx_destroy()	destroys a template context.  Upon return, *ctxp will
     be	set to NULL.  If *ctxp is already NULL when tmpl_ctx_destroy() is in-
     voked, nothing happens.

     tmpl_execute() executes the parsed	template tmpl using the	execution con-
     text ctx, and writes the output to	output.	 flags may contain any of the
     following values OR'd together:

	TMPL_SKIP_NL_WHITE    Skip newline plus	whitespace

     TMPL_SKIP_NL_WHITE	causes any inter-function occurrences of a newline
     followed by whitespace to be ignored.  This often generates more intu-
     itive output.  The	example	template given previously would	generate this
     output if TMPL_SKIP_NL_WHITE were specified:

	I'm going to count to three:

	123

	Done.

     tmpl_execute_func() can be	used to	execute	a single function defined in a
     template context.	This includes non-control flow built-in	functions,
     user functions, and run-time functions.  ctx, output, and flags are as
     with tmpl_execute().  The function	and arguments are described by argc
     and argv, and errmsgp must	point to a char	* error	message	pointer.

     tmpl_ctx_reset() resets an	execution context to its initial state.	 This
     causes any	runtime	variables and functions	defined	during a previous exe-
     cution using ctx to be forgotten.

RETURN VALUES
     tmpl_create(), tmpl_ctx_create(), and tmpl_execute() return NULL or -1 to
     indicate an error,	with errno set appropriately.

     tmpl_execute_func() returns -1 if there was an error.  In the case	of a
     system error, *errmsgp will be set	to NULL	and errno will be set appro-
     priately; otherwise, *errmsgp will	point to an appropriate	error message
     allocated with typed_mem(3) type mtype, which the caller must eventually
     free.

SEE ALSO
     http_servlet_tmpl(3), libpdel(3), strtol(3), typed_mem(3)

IMPLEMENTATION NOTES
     Here are two common sources of bugs:

	-   User functions returning constant strings or strings allocated
	    with the wrong typed_mem(3)	type.
	-   Not	sorting	the user function array	given to tmpl_list_handler().

HISTORY
     The PDEL library was developed at Packet Design, LLC.
     http://www.packetdesign.com/

AUTHORS
     Archie Cobbs <archie@freebsd.org>

BUGS
     tmpl_create(), tmpl_execute(), and	tmpl_execute_func() may	leak small
     amounts of	memory if the thread is	canceled.

FreeBSD	13.0			April 22, 2002			  FreeBSD 13.0

NAME | LIBRARY | SYNOPSIS | DESCRIPTION | Parsing | Execution | Built-in Functions | API | RETURN VALUES | SEE ALSO | IMPLEMENTATION NOTES | HISTORY | AUTHORS | BUGS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=tmpl&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help