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

FreeBSD Manual Pages

  
 
  

home | help
sf_fmt(3)		    Library Functions Manual		     sf_fmt(3)

NAME
       format_init,  format_free, format_metarule, formatf, format_lastresult,
       format_lastsize,	format_detach -- template formatting functions.

SYNOPSIS
       #include	<strfunc.h>

       fmt_base	*
       format_init();

       void
       format_free(fmt_base *base);

       int
       format_metarule(fmt_base	 *base,	 char  leftBrace,   char   rightBrace,
	   char	**(*function)(char *found, void	*optKeyPassed));

       char *
       formatf(fmt_base	*base, char *template, void *optKeyToPass);

       char *
       format_lastresult(fmt_base *base, size_t	*optSize);

       size_t
       format_lastsize(fmt_base	*base);

       char *
       format_detach(fmt_base *base, size_t *optReturnSize);

DESCRIPTION
       It  is widely used for programs to read a template and display the data
       according to it.

       Those functions forms a powerful	solution to work with a	kind  of  "ac-
       tive"  templates.  The term "active" means that some operations,	like a
       test of existence of a keyword, or equality tests, can  be  placed  di-
       rectly to the template and no special handling needed in	an application
       to support it.  strfunc(3) library will automagically do	the dirty work
       for you.

       The  internal language of defining the template is powerful yet simple.
       Before we run into detailed explanation,	let's talk about programming.

       First, programmer needed	to initialize the formatting engine by	defin-
       ing  the	 formatting rules. Formatting rules are	stored inside the spe-
       cial structure fmt_base.	 format_init() creates an empty	structure  and
       returns	the  pointer to	it. One	may define a numerous formatting bases
       and  randomly  use  them.  Formatting   base   may   be	 freed	 using
       format_free(fmt_base *).	 Please	note that format_init()	will never re-
       turn the	NULL pointer.

       Second,	there is a need	to fill	this empty structure with some format-
       ting rules using	the format_metarule() function.	Formatting  rules  are
       defined	by  specifiyng a braces	and the	function which will handle the
       data inside the braces.

       Say, we have a template	"abc${def}ghi".	 Programmer  should  call  the
       format_metarule(fb,  '{', '}', handler),	where fb is the	pointer	to the
       formatting base returned	by format_init().  If two  braces  are	equal,
       the  result  is undefined.  handler is the function which should	be de-
       fined as

       char ** handler(char *found, void *optKeyPassed).

       It is possible to define	a number  of  such  a  rules  for  the	single
       fmt_base.  The handler function should return the pointer to the	inter-
       nal  char  **  data  when  it  is possible, and NULL pointer otherwise.
       Please NOTE that	this pointer is	never modified or freed	 and  probably
       it should be the	semi-static structure inside the handler function.

       When  you're finished to	fill the fmt_base with the rules, the function
       formatf() can be	used multiple times to convert the specified  template
       to  the	destination  text.  The	 optional optKeyToPass argument	may be
       specified to pass some additional data, if necessary.

       formatf() will place the	output to the buffer located in	 the  fmt_base
       and  return a pointer to	it. The	pointer	will never be NULL, and	is not
       to be freed. If you need	this buffer to be completely yours and do  not
       want to strdup(3) it, there is a	function called	format_detach(fmt_base
       *, size_t *optReturnSize) to achive this.

       Two  other  functions,  char  *	format_lastresult(fmt_base  *,	size_t
       *optSize) and size_t format_lastsize(fmt_base *), are to	be used	to ob-
       tain the	pointer	to the buffer and its size without invoking  formatf()
       once more.

ACTIVE TEMPLATE	DEFINITION
       If  a  template is not containing the special tokens it will considered
       as plain	text and returned unmodified.

       Special token and the whole template are	defined	in the following BNF:

	     <template>	 :=  *(*<string> *<token> *<string>)

	     <token>	 :=  <simple> |	<join> | <index> | <choice> | <equality>

	     <simple>	 :=  '$' <LB> <param> <RB>

	     <join>	 :=  '$' <LB> <param> '+' <delimiter> <RB>

	     <index>	 :=  '$' <LB> <param> '[' <number> ']' <RB>

	     <choice>	 :=  '$' <LB> <param> '?' <iftrue> ':' <iffalse> <RB>

	     <equality>	 :=  '$' <LB> <param> {	"==" | "!=" } *<string>	'?' <iftrue> ':' <iffalse> <RB>

	     <LB>	 :=  <the second argument of format_metarule()>

	     <RB>	 :=  <the third	argument of format_metarule()>

	     <param>	 := <string>

	     <delimiter> := <string>

	     <iftrue>	 := <template>

	     <iffalse>	 := <template>

	     <string>	 :=  *<CHAR>

	     <number>	 :=  1*<character from '0' to '9'>

       The word	param defined above, will be passed as the first  argument  to
       the handler function.

ACTIVE TEMPLATE	EXAMPLE
       The  following  is an example of	the typical template. It may be	placed
       to a file, then read and	passed to formatf().  It is also  can  be  de-
       fined  as  the  argument's  value within	the configuration file read by
       cfgread(3).

	     Login: ${login[0]}
	     Password: ${password}
	     Username: ${name?${name}:Unknown name}
	     Comments: ${comment+, }
	     $<status==Busy?User is busy>

       You can see the index token "${login[0]}", the  simple  token  "${pass-
       word}", the join	token right after the "Comments: ", and	equality token
       is the whole last string. Please	note that the last token is formed us-
       ing the angle braces: you should	specify	an additional handler function
       to handle this case. Refer to the PROGRAMMING EXAMPLE section.

       Simple  tokens  are  used to display the	data returned by the handler()
       function	almost without the modification. One exception from this  rule
       exists: if handler return multiple values they are joined together with
       the string ", " as the separator.

       Join  tokens  are used to join the multiple values. As mentioned	above,
       the handler function return the string array. In	this case  all	values
       will  be	joined together	separated by the specified delimiter. For this
       primer the delimiter is ", " (comma followed by single space).

       Index token used	to get the specified value from	the string  array  re-
       turned  by  handler.   Values are counted from zero, so zero index will
       represent the first available string.

       Choice token used to give the dynamic behavior to  the  templates.  The
       <iftrue>	section	will be	placed to the output buffer if the handler re-
       turn  the  valid	non-NULL pointer to the	non-empty array. This form can
       be used to rule the output if the expected parameter is not present  or
       empty.

       Equality	 token	used to	test the array returned	by the handler against
       the string value. The <iftrue> section will be  placed  to  the	output
       buffer  if  this	string match at	least one of the array's elements. All
       comparisons are canse-insensitive.

PROGRAMMING EXAMPLE
       Here's how to implement the above template example's parsing.

       #include	<strfunc.h>

       char **handler1(char *found, void *optKeyPassed);
       char **handler2(char *found, void *optKeyPassed);

       int
       main() {
	       fmt_base	*fb;
	       char *template =	"Login:	${login[0]}\nPassword: ${password}\nUsername: ${name?${name}:Unknown name}\nComments: ${comment+, }\n$<status==Busy?User is busy>\n";
	       char *s;

	       /* Create empty structure */
	       fb = format_init();

	       /* Add one formatting rule */
	       format_metarule(fb, '{',	'}', handler1);

	       /* Add another formatting rule to parse angle braces */
	       format_metarule(fb, '<',	'>', handler1);

	       /* Format the template */
	       s = formatf(fb, template, NULL);

	       /* Print	out the	result */
	       printf("%s", s);

	       /* Free the formatting structure	*/
	       format_free(fb);

	       return 0;
       };

       char **
       handler1(char *found, void *optKeyPassed) {
	       static char *arr[3] = { NULL, NULL, NULL	};

	       (void)optKeyPassed;

	       arr[1] =	NULL;

	       if(strcasecmp(found, "login") ==	0) {
		       arr[0] =	"john";
		       return arr;
	       };

	       if(strcasecmp(found, "name") == 0) {
		       arr[0] =	"John Smith";
		       return arr;
	       };

	       if(strcasecmp(found, "password")	== 0) {
		       arr[0] =	"123";
		       return arr;
	       };

	       if(strcasecmp(found, "comment") == 0) {
		       arr[0] =	"Comment value #1";
		       arr[1] =	"Comment value #2";
		       return arr;
	       };

	       return NULL;
       };

       char **
       handler2(char *found, void *optKeyPassed) {
	       static char *arr[] = { NULL, NULL };

	       (void)optKeyPassed;

	       if(strcasecmp(found, status) == 0) {
		       arr[0] =	"busy";
		       return arr;
	       };

	       return NULL;
       };

SEE ALSO
       strfunc(3), cfgread(3).

AUTHORS
       Lev Walkin <vlm@lionet.info>

FreeBSD	Ports 14.quarterly	October	1, 2000			     sf_fmt(3)

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

home | help