     PRINT(3)                                                           PRINT(3)

     NAME
          print - string formatting and printing library

     SYNOPSYS
          #include <print.h>
          typedef struct Format Format;
          typedef int (*Fmtconv)(Format *, int);

          struct Format {
               /* for the formatting routines */
               va_list args;
               long flags, f1, f2;
               Fmtconv* fmttab;
               /* for the buffer maintainence routines */
               char *buf, *bufbegin, *bufend;
               int flushed;
               int (*grow)(Format *, SIZE_T);
               int error;
               union { int n; void *p; } u;
               /* misc */
               void* client_data;
          };
          int print (const char *fmt,...)
          int eprint (const char *fmt,...)
          int fprint (int fd, const char *fmt,...)
          int vfprint (int fd, const char *fmt, va_list)
          int sprint (char *buf, const char *fmt,...)
          int snprint (char *buf, int buflen, const char *fmt,...)
          int vsnprint (char *buf, int buflen, const char *fmt, va_list)
          char *mprint (const char *fmt,...)
          char *smprint (Alloc alloc, SIZE_T* len, const char* fmt, ...)
          char *vsmprint (Alloc alloc, SIZE_T* len, const char* fmt, va_list)
          char *palloc (char* p, SIZE_T size)
          Fmtconv fmtinstall (int c, Fmtconv f)
          int fmtputc (Format *f, const char c)
          int fmtappend (Format *format, const char *s, SIZE_T len)
          int fmtcat (Format *format, const char *s)
          int fmtengine (Format *format, const char *fmt)
          int fmtprint (Format *format, const char *fmt,...)

     SUMMARY
          These routines format strings similarly to the printf family of
          functions.  Unlike printf, they support user supplied format
          specifiers, they can format into memory that is allocated as needed
          (using a user supplied allocation function), they are reentrant
          (except for errno, the global table of format specifiers, and possibly
          malloc if you choose to use it), and they are 8 bit clean ('\0' bytes
          can be printed).  Print is also space efficient.  The program text is
          about 5K when compiled for a sparc.

          fprint writes formatted text to a file descriptor and returns the

                                        - 1 -       Formatted:  November 4, 1999

     PRINT(3)                                                           PRINT(3)

          number of bytes written, or -1 on error.  print writes text to stdout
          while eprint writes text to stderr.  vfprint formats arguments
          supplied in a va_list obtained from stdargs.

          sprint writes text into a user supplied buffer.  It writes at most
          FMT_SPRINT_BUFSIZ bytes including the terminating '\0'.  It returns
          the number of bytes requested (not including the terminating '\0').
          Note that one must check for truncation by comparing this value to the
          size of the buffer.  snprint writes at most n bytes into a user
          supplied buffer.  vsnprint does the same, but takes its  arguments
          from a va_list.

          mprint formats into a dynamically allocated buffer, to which it
          returns a pointer.  The space is obtained from malloc and should be
          freed when no longer needed.  smprint takes a user supplied allocation
          function as an argument.  This function should behave as ANSI-realloc
          does.  Some pre-ANSI systems' realloc fails to treat realloc(0,n) as
          equivalent to malloc(n), so we provide a routine palloc which does.
          smprint also returns the number of bytes generated by writing into the
          *len argument if it is a non-null pointer.  vsmprint is like smprint,
          but that it reads arguments from a va_list.

          fmtinstall installs a user supplied conversion function for a given
          character, and returns the old value.  A conversion function takes a
          pointer to a format structure and the character that induced the call.
          It must return FMT_flag if the format character signals setting a flag
          and FMT_verb if it signals performing a conversion.

          A conversion function can use fmtappend to put new text into the
          output buffer; fmtputc and fmtcat are supplied for convenience.

          fmtengine is the entry point for the actual formatting engine.  Given
          a properly initialized format structure and a format string, it will
          do the specified work.

          fmtprint is a very general interface to fmtengine. Its arguments are a
          properly initialized format structure, a format string, and a matching
          number of parameters. fmtprint saves and restores the argument list
          stored in the format structure, so it can be used inside a conversion
          function to perform arbitrary formatting operations.  This usage
          avoids the temporary buffers that fmtappend would require.  fmtengine
          and fmtprint return the number of characters that they generated.

          The format structure contains three kinds of information.  First,
          variables used by the formatting routines.  These are: args, the
          argument list containing the data to be formatted.  flags, a bitmask
          storing the flags set at the time each conversion function is called.
          Possible values are given in print.h.  f1, f2 are the field width and
          precision of each conversion.  The flags, f1, and f2 are zeroed before
          each conversion begins.  fmttab is a pointer to the per-format array
          of conversion functions, indexed by conversion character.  If it is

                                        - 2 -       Formatted:  November 4, 1999

     PRINT(3)                                                           PRINT(3)

          zero, the global table will be used instead.

          Second, variables used for buffer maintainance: These are: buf,
          bufbegin, bufend, pointers to the insertion point in the output
          buffer, the buffer itself, and the end of the buffer.  flushed, the
          number of characters that have been transmitted to their ultimate
          destination thus far.  grow, the buffer growing function, called when
          the buffer is nearly full so that it can be flushed or reallocated.
          error, nonzero if an error has occurred during formatting.  Formatting
          will stop after the first error is noticed.  u.n, u.p, the name of the
          file descriptor to write to, or the realloc function to call to resize
          a buffer.

          Finally, client_data provides access to other arguments in a reentrant
          way.

          A simple format function, the one for  %c, looks like this:

          static int cconv(Format *format, int c) {
              fmtputc(format, va_arg(format->args, int));
              return FMT_verb;
          }
          A more interesting example is a conversion function that formats a
          string with all unprintable characters quoted as in C.

          int print_cquote_conv (Format* format, int c)
          {
              unsigned char* s = va_arg (format->args, unsigned char*);
              unsigned char ch;

              while ((ch = *s++)) {
               if (isascii (ch) && isalnum (ch)) {
                   if (ch == '\\')
                    fmtputc (format, ch);
                   fmtputc (format, ch);
               } else {
                   fmtprint (format, "\\%03uo", ch);
               }
              }
              return FMT_verb;
          }

     STANDARD CONVERSIONS
        verbs
          %         A literal percent.
          s         A string.  With the # flag, use f2 for size and don't assume
                    '\0' termination.
          c         A single character.

                                        - 3 -       Formatted:  November 4, 1999

     PRINT(3)                                                           PRINT(3)

          d, i      A decimal integer.
          o         An octal integer. With #, prefix 0.
          x         A hex integer. With #, prefix 0x.
          e, f, g   Floating point conversions (not implemented).
          r, m      sys_errlist[errno].  With # flag, errno.
          n         writes the number of characters emitted thus far into into
                    an int* argument.  Note!  Since transput stops if an error
                    occurs, this verb may not be executed.

        flags
          u         Arg is unsigned.
          h         Arg is short.
          l         Arg is long.
          q         Arg is quad (not implemented).
          #         Select alternate output format.
          -         Left justify output.
          0         Zero pad output.
          1-9       Set the f1 (field width) specifier.
          .         The f2 (precision) specifier follows.
          *         Set f1 or f2 from int arg.

     OPTIONAL CONVERSIONS
          Calling fmt_install_runeconv() installs conversion functions which
          support Unicode 16 bit "Runes" by transforming them to the UTF-8
          multibyte encoding.  The %C operator transforms a single Rune, while
          %S transforms a 0 terminated array, analagously to %c and %s.

     NOTES
          Unlike printf, flags like 'u' need to be followed by a verb like 'd'.

          This code is derived from the print routines  that Paul Haahr wrote
          for Byron Rakitzis' implementation of rc.

     AUTHORS
          libprint: Paul Haahr, Byron Rakitzis, Scott Schwartz.  runes: Rob
          Pike, Howard Trickey runeconv: Erik Quanstrom

     BUGS
          What to do when an invalid print char is detected?  BSD printf emits
          the character without comment.  We print a warning to stderr and stop
          formatting.  What should snprint return?  The namespace for
          installable format specifiers is very small, so collisions and
          mistakes will probably cause trouble.  No floating point conversion
          functions (%e, %f, %g) yet.  Quadword conversions (%qd) would be nice
          too.  Does %d really work in boundary cases (signed/unsigned
          long/int/short maxint, minint)?  What should snprint return?  Number
          of bytes requested, or transferred?  fmtputc still feels kludgy.  It

                                        - 4 -       Formatted:  November 4, 1999

     PRINT(3)                                                           PRINT(3)

          used to directly write bytes into the buffer, in an attempt at
          efficiency, but that turned out to complicate snprint. Now it just
          calls fmtappend.

     COPYRIGHT
          All files in this library except rune.c and rune.h are covered by the
          following copyright notice:

               Copyright 1994 Paul Haahr, Scott Schwartz, Byron Rakitzis.  All
               rights reserved.

               This software is not subject to any license of the American
               Telephone and Telegraph Company or of the Regents of the
               University of California.

               Permission is granted to anyone to use this software for any
               purpose on any computer system, and to alter it and redistribute
               it freely, subject to the following restrictions:

               1. The author is not responsible for the consequences of use of
               this software, no matter how awful, even if they arise from flaws
               in it.

               2. The origin of this software must not be misrepresented, either
               by explicit claim or by omission.  Since few users ever read
               sources, credits must appear in the documentation.

               3. Altered versions must be plainly marked as such, and must not
               be misrepresented as being the original software.  Since few
               users ever read sources, credits must appear in the
               documentation.

               4. This notice may not be removed or altered.

               [this copyright notice is adapted from Henry Spencer's "awf"
               copyright notice.]

          The files rune.c and rune.h, originally distributed as part of the sam
          editor, are covered by the following copyright notice:

               The authors of this software are Rob Pike and Howard Trickey.
               Copyright (c) 1992 by AT&T.  Permission to use, copy, modify, and
               distribute this software for any purpose without fee is hereby
               granted, provided that this entire notice is included in all
               copies of any software which is or includes a copy or
               modification of this software and in all copies of the supporting
               documentation for such software.  THIS SOFTWARE IS BEING PROVIDED
               "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.  IN PARTICULAR,
               NEITHER THE AUTHORS NOR AT&T MAKE ANY REPRESENTATION OR WARRANTY
               OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR

                                        - 5 -       Formatted:  November 4, 1999

     PRINT(3)                                                           PRINT(3)

               ITS FITNESS FOR ANY PARTICULAR PURPOSE.

                                        - 6 -       Formatted:  November 4, 1999