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

FreeBSD Manual Pages

  
 
  

home | help
TMPL(3)			    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
       input 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
       functions 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	 func-
       tion call is an at sign ('@') followed by a contiguous sequence of let-
       ters,  digits,  and  underscores, followed by matching parentheses con-
       taining 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
       either  an at sign or a double quote character.	Function arguments are
       separated by commas and may have	surrounding whitespace,	which  is  ig-
       nored.

       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.	Execu-
       tion  requires  a context, represented by a struct tmpl_ctx, and	gener-
       ates output 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 op-
       tional 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  sup-
	       plied to	@while() is true.

	   @loop(x) ...	@endloop

	       The text	in between is repeated N times,	where N	is the numeri-
	       cal 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
	       containing  loop,  where	 N is the numerical value of the argu-
	       ment, 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  con-
	       text exists.

	   @get(name)

	       Returns	the  value of the run-time variable named by the first
	       argument, 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
	       variables argc and arg0,	arg1, ... are set to the function  ar-
	       gument  count and arguments, respectively; arg0 is always equal
	       to the name of the function.  All run-time functions are	global
	       and exist as long as the	associated execution context exists.

	   @invoke()

	       Invokes a function.  The	function to be invoked and  its	 argu-
	       ments  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 arguments.

       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, oth-
	       erwise "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
       template	 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 beginning 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  par-
       ticular,	 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	subse-
       quent arguments are the (evaluated) arguments passed to	the  function.
       Therefore, 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
       appropriately  for  the template	output (e.g., in HTML).	 The errmsg is
       the original, unformatted error string returned by  the	function  han-
       dler;  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 sup-
       plied arguments.	 In the	case of	an error, tmpl_list_handler() prepends
       the returned error string with the offending function  call  and	 argu-
       ments.

       tmpl_ctx_set_var()  and	tmpl_ctx_get_var()  may	be used	to set and re-
       trieve 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 invoked, nothing happens.

       tmpl_execute() executes the parsed template tmpl	 using	the  execution
       context 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	previ-
       ous execution 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  mes-
       sage  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	ports 15.0		April 22, 2002			       TMPL(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=tmpl_destroy&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help