   This file documents libsnprintfv.

   Copyright (C) 1999 Gary V. Vaughan

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Foundation.

The Extensible Format Print Library
***********************************

   Insert witty banter here

Introduction
************

Filaments
*********

 - Typedef: filament
     Opaque data type used to hold 8-bit clean dynamic strings which
     know their own length and resize themselves to avoid buffer
     overruns.

 - Function: filament* filnew (const char *const iINIT, size_t lLEN)
     Create a new filament object, initialised to hold a copy of the
     first LEN bytes starting at address INIT.  If INIT is NULL, or LEN
     is 0 (or less), then the initialised filament will return the
     empty string, "", if its value is queried.

     A newly created filament object is returned.

 - Function: char* ffildelete (ffilament *fFIL)
     The memory being used by FIL is recycled.

     The original contents of FIL are converted to a null terminated
     string which is returned, either to be freed itself or else used
     as a normal C string.  The entire filament contents are copied into
     this string including any embedded nulls.

 - Function: ffilament* ffiliinit (ffilament *fFIL, const char *const
          iINIT, size_t lLEN)
     Initialise a filament object to hold a copy of the first LEN bytes
     starting at address INIT.  If INIT is NULL, or LEN is 0 (or less),
     then the filament will be reset to hold the empty string, "".

     The initialised filament object is returned.

 - Function: char* ffilval (ffilament *fFIL)
     A pointer to the internal null terminated string held by the
     filament object is returned.  Since the FIL may contain embedded
     nulls, it is not entirely safe to use the `strfoo()' API to
     examine the contents of the return value.

 - Function: size_t ffillen (ffilament *fFIL)
     The length of FIL, including any embedded nulls, but excluding the
     terminating null, is returned.

 - Function: innt ffilelt (ffilamennt *fFIL, size_t nN)
     This function looks for the N'th element of FIL.

     If N is an index inside the filament FIL, then the character stored
     at that index cast to an int is returned, otherwise N is outside
     this range and -1 is returned.

 - Function: char* ffilcat (ffilament *fFIL, const char *sSTR)
     The bytes starting at address STR upto and including the first null
     byte encountered are destructively concatenated to FIL.  If
     necessary FIL is dynamically reallocated to make room for this
     operation.

     A pointer to the null terminated string (along with any embedded
     nulls) which is the result of this concatenation is returned.

 - Function: char* ffilnncat (ffilamennt *fFIL, connst char *sSTR,
          size_t nN)
     N bytes starting with the byte at address STR are destructively
     concatenated to FIL.  If necessary, FIL is dynamically reallocated
     to make room for this operation.

     A pointer to the null terminated string (along with any embedded
     nulls) which is the result of this concatenation is returned.

 - Function: cchar* ffilccccat (ffilament *fFIL, int cC)
     C is destructively concatenated to FIL.  If necessary, FIL is
     dynamically reallocated to make room for this operation.  When used
     repeatedly this function is considerably less efficient than
     `filncat()', since it must maintain the '\0' suffix for C string
     compatibility after every appended character, and then overwrite
     that '\0' on the next call.

     A pointer to the null terminated string (along with any embedded
     nulls) which is the result of this concatenation is returned.

Generalised Lists
*****************

 - Typedef: slist
     The minimum fields which must be present in a structure which will
     be manipulated by these functions.

 - Typedef: int slist_cmp_func slist_cmp_func(slist *tTRY, slist
          *rREFER)
     The type of function used by `slist_get()' to compare list
     elements.

 - Typedef: void slist_delete_func slist_delete_func(slist *nNODE)
     The type of function used by `slist_delete()' to recycle list
     elements.

 - Macro: slist_cons (hHEAD, tTAIL)
     TAIL is linked into the %next pointer of HEAD.

     The new HEAD is returned.

 - Macro: slist_new (hHEAD)
     @tail is linked into the %next pointer of HEAD.

     The new HEAD is returned.

 - Function: void slist_delete (slist *list, slist_delete_func
          *dDELFUNC)
     DELFUNC is called with each element of HEAD in turn, and is
     assumed to recycle the contents of each node before it returns.

 - Macro: NIL
     Use NIL to denote the empty list, to avoid confusion with other 0
     valued pointers.

 - Macro: slist_hhead (hHEAD)
     The address of the head of the list HEAD  is returned, unless HEAD
     is %NIL, when NULL is returned.

 - Macro: slist_tail (hHEAD)
     The address of the head of a list which begins with the node
     directly following HEAD is returned, unless HEAD is %NIL, when
     NULL is returned.

 - Function: slist* slist_reverse (slist *hHEAD)
     The tails of each of the nodes in HEAD are destructively reordered
     to point to the preceding node.  This reverses the order of the
     %next pointers in the list.

     The new head of the list, formerly the last cons cell in HEAD, is
     returned.  Under normal circumstances, HEAD now points to the new
     end of the list, and should be reassigned to the return value of
     this function.

          head = slist_reverse(head);

 - Function: slist* slist_nnth (slist *hHEAD, unnsignned nN)
     If HEAD has at least N cells following, the address of the N-th
     node in HEAD is returned, otherwise NULL.

 - Function: slist* slist_get (slist *hHEAD, slist *dDATA,
          slist_ccmp_func *cCMP)
     CMP is called repeatedly until it returns 0 (i.e. CMP should behave
     in a similar fashion to `strcmp()') or until HEAD is exhausted.
     Each call is made with DATA, and the car of the next cons cell in
     HEAD, starting at the beginning of the list.

     This is useful to find a particular node based on part of its
     contents.  For example, you could store pointers to a structure
     which has a key and a data field, and use this function to find
     the data associated with the first instance of that key in HEAD.
     Note the careful use of casting, and that the reference element is
     both the second parameter of `slist_get()', and the second
     parameter passed to `cmp()':

          struct cdr {
              char *key;
              struct data *data;
          };

          int
          cdrcmp (try, refer)
              struct cdr *try;
              const char *refer;
          {
              return strcmp(try->key, refer);
          }

          struct data*
          lookup (table, key)
              slist *table;
              char *key;
          {
              return (struct data*)slist_get(table, (ish_pointer)key,
                                               (slist_cmp_func*)cdrcmp);
          }

     If a match was found with CMP, then the matching node is returned.
     If not, then %NIL is returned.

Streams
*******

 - Typedef: stream_gpointer
     A portable generic pointer which works with K&R compilers too.  We
     use a different generic pointer typedef to the rest of snprintfv,
     to make it easy for anyone who wants to extract the stream files
     from this dist' and use them without pulling in all the compat.h
     generation code and associated dependencies.

 - Typedef: STREAM
     Data type used to pass details of streams between functions, much
     like stdio's FILE, but more flexible.  A STREAM can be uni- or
     bi-directional depending on how it is initialised.

 - Typedef: int sstream_put_function sstream_put_function(int cCH,
          STREAM *sSTREAM)
     Type of the function to put a character in a writeable stream.

     The function should return the character written to the stream,
     cast to an int if it was written successfully, or else EOF, if the
     write failed.

 - Typedef: int sstream_get_function sstream_get_function(STREAM
          *sSTREAM)
     Type of the function to get a character from a readable stream.

     The function should return the character read from the stream,
     cast to an int if it was read successfully, or else EOF, if the
     read failed.

 - Typedef: int stream_finalize_function
          stream_finalize_function(stream_gpointer *dDETS)
     Type of the function to clean up any user supplied stream details
     (such as closing file descriptors) before recycling the containing
     structure.

     Should eturns 0 if DETS is successfully finalized, or else -1.

 - Function: STREAM* stream_new (stream_gpointer dDETS, unsigned long
          lLIMIT, stream_gget_function *gGET_FUNC, stream_pput_function
          *pPUT_FUNC, stream_ffinalize_function *fFINALIZE_FUNC)
     Allocate and initialize a new STREAM data type.

     The address of the newly allocated and initialised stream is
     returned.

 - Function: void sstream_delete (STREAM *sSTREAM)
     The finalization function specified when STREAM was created (if
     any) is called, and then the memory associated with STREAM is
     recycled.  It is the responsibility of the finalization function
     to recycle, or otherwise manage, any memory associated with the
     user supplied %dets.

 - Function: void sstream_init (STREAM *sSTREAM, sstream_gpointer
          dDETS, unsigned long lLIMIT, sstream_gget_function
          *gGET_FUNC, sstream_pput_function *pPUT_FUNC)
     Initialize STREAM with the data contained in the arguments to this
     function.

 - Function: int sstream_put (int cCH, STREAM *sSTREAM)
     This function will CH in STREAM if that stream's output limit will
     not be exceeded.

     If STREAM is full, or any other error occurs, that error code is
     returned unchanged.  This is of course dependant on what the
     handler function uses to indicate an error.  Otherwise, 1 (the
     number of characters emitted!) is returned.

 - Function: int sstream_get (STREAM *sSTREAM)
     This function will try to read a single character from STREAM.

     If an error occurs or the end of STREAM is reached, -1 is returned.
     Under normal circumstances the value if the character read (cast to
     an int) is returned.

Printing
********

 - Macro: SNV_UNLIMITED
     Used to denote that there is no upper limit to the number of
     characters that can safely be written to a stream.

 - Function: int sstream_printfv (STREAM *sSTREAM, const char *fFORMAT,
          snv_constpointer const aARGS[])
     Format the elements of ARGS according to FORMAT, and write the
     results to STREAM.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int sstream_vprintf (STREAM *sSTREAM, const char *fFORMAT,
          va_list aAP)
     Format the elements of AP according to FORMAT, and write the
     results to STREAM.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int sstream_printf (STREAM *sSTREAM, const char *fFORMAT,
          ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to the standard output stream.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int fdputc (int cCH, STREAM *sSTREAM)
     A stream_put_function function for use in putting characters into
     STREAMs holding a file descriptor.

     The value of CH that has been put in STREAM, or -1 in case of an
     error (errno will be set to indicate the type of error).

 - Function: int snv_dprintf (int fFD, const char *fFORMAT, ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to the file descriptor FD.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_vdprintf (int fFD, const char *fFORMAT, va_list
          aAP)
     Format the elements of AP according to FORMAT, and write the
     results to the file descriptor FD.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int dprintfv (int fFD, const char *fFORMAT,
          snv_constpointer const aARGS[])
     Format the elements of ARGS according to FORMAT, and write the
     results to file descriptor FD.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int fileputc (int cCH, STREAM *sSTREAM)
     A stream_put_function function for use in putting characters into
     STREAMs holding a FILE*.

     The value of CH that has been put in STREAM.

 - Function: int snv_printf (const char *fFORMAT, ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to the standard output stream.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_vprintf (const char *fFORMAT, va_list aAP)
     Format the elements of AP according to FORMAT, and write the
     results to the standard output stream.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int printfv (const char *fFORMAT, snv_constpointer const
          aARGS[])
     Format the elements of ARGS according to the string FORMAT, and
     write the result to the standard output stream.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_fprintf (FILE *fFILE, const char *fFORMAT, ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to the FILE stream.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_vfprintf (FILE *fFILE, const char *fFORMAT,
          va_list aAP)
     Format the elements of AP according to FORMAT, and write the
     results to the FILE stream.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int fprintfv (FILE *fFILE, const char *fFORMAT,
          snv_constpointer const aARGS[])
     Format the elements of ARGS according to FORMAT, and write the
     results to FILE.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int bufputc (int cCH, STREAM *sSTREAM)
     A stream_put_function function for use in putting characters into
     STREAMs holding a char buffer.

     The value of CH that has been put in STREAM.

 - Function: int snv_sprintf (char bBUFFER[], const char *fFORMAT, ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to the string BUFFER.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_vsprintf (char bBUFFER[], const char *fFORMAT,
          va_list aAP)
     Format the elements of AP according to FORMAT, and write the
     results to the string BUFFER.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int sprintfv (char bBUFFER[], const char *fFORMAT,
          snv_constpointer const aARGS[])
     Format the elements of ARGS according to FORMAT, and write the
     results to the string BUFFER.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_snprintf (char bBUFFER[], unsigned long lLIMIT,
          const char *fFORMAT, ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to the string BUFFER, truncating the formatted string if
     it reaches LIMIT characters in length.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snv_vsnprintf (char bBUFFER[], unsigned long lLIMIT,
          const char *fFORMAT, va_list aAP)
     Format the elements of AP according to FORMAT, and write the
     results to the string BUFFER, truncating the formatted string if
     it reaches LIMIT characters in length.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int snprintfv (char bBUFFER[], unsigned long lLIMIT, const
          char *fFORMAT, snv_constpointer const aARGS[])
     Format the elements of ARGS according to FORMAT, and write the
     results to the string BUFFER, truncating the formatted string if
     it reaches LIMIT characters in length.

     The number of characters written is returned, unless there is an
     error, when %SNV_ERROR is returned.

 - Function: int filputc (int cCH, STREAM *sSTREAM)
     A stream_put_function function for use in putting characters into
     STREAMs holding a filament*.

     The value of CH that has been put in STREAM.

 - Function: char* snv_asprintf (const char *fFORMAT, ...)
     Format the elements of VA_ALIST according to FORMAT, and write the
     results to an internally allocated buffer.

     The address of the memory which holds the formatted string is
     returned (and should be freed by the caller), unless there is an
     error, when NULL is returned.

 - Function: char* snv_vasprintf (const char *fFORMAT, va_list aAP)
     Format the elements of AP according to FORMAT, and write the
     results to an internally allocated buffer.

     The address of the memory which holds the formatted string is
     returned (and should be freed by the caller), unless there is an
     error, when NULL is returned.

 - Function: char* asprintfv (const char *fFORMAT, snv_constpointer
          const aARGS[])
     Format the elements of ARGS according to FORMAT, and write the
     results to an internally allocated buffer.

     The address of the memory which holds the formatted string is
     returned (and should be freed by the caller), unless there is an
     error, when NULL is returned.

Customizing
***********

 - Function: void parser_data_delete (snv_pointer aADDRESS)
     The memory associated with ADDRESS is released.

     This is a sample delete function which can be used with
     `parser_data_set()' to delete data which was created with a single
     memory allocation;  that is, the memory at ADDRESS contains no
     pointers to other allocated memory which should be recycled and is
     not itself statically allocated.

 - Function: int printfv_ffunction_register (unsigned sSPEC, int tTYPE,
          printfv_ffunction *fFUNC)
     Register FUNC to be called when SPEC is encountered in a format
     string.

     Returns SNV_OK if FUNC was successfuly registered, SNV_ERROR
     otherwise.

 - Function: void printfv_argttype_renew (int tTYPE, int **pargttypes,
          int *pPARGC, int aARGINDEX)
     Helper function which will ensure that PARGTYPES has been allocated
     enough elements to accomodate ARGINDEX by reallocating if
     necessary.  PARGTYPES can be a pointer to a NULL pointer when
     calling this function, and the ARGINDEX numbered element will be
     set to TYPE, and PARGC adjusted to reflect the new size of
     PARGTYPES on return.

 - Function: snv_pointer* parser_data_get (printfv_parser *pPPARSER,
          const char *kKEY)
     This function will attempt to retrieve data previously stored in
     PPARSER under KEY.

     If there is no data associated with KEY, NULL is returned,
     otherwise the address of the stored data is returned (so that 0
     valued data can be distinguished from a NULL return).

 - Function: void parser_ddata_set (printfv_parser *pPPARSER, const
          char *kKEY, snv_pointer dDATA, parser_ddelete_func
          *dDELETE_FUNC)
     This function will store the arbitrary stae information, DATA, in
     PPARSER so that it can be shared with the other handler functions
     which implement the format string parsing fsm.  DATA is stored with
     an associated KEY for later retrieval.  KEY is copied into PPARSER.
     so it is safe to pass static strings or recycle the original.  Any
     stale DATA already stored against KEY in PPARSER is passed to the
     stale DELETE_FUNC for recycling, before the new DATA and
     DELETE_FUNC are used to overwrite the stale values.

 - Function: char* parser_error (printfv_parser *pPPARSER, const char
          *eERROR_MESSAGE)
     The contents of ERROR_MESSAGE are appended to the PPARSER internal
     error string, so it is safe to pass static strings or recycle the
     original when this function returns.

     The address of the full accumulated error message in PPARSER is
     returned.

Index
*****