PRINT(2)                                                 PRINT(2)

     NAME
          print, fprint, sprint, fmtinstall, strconv, Strconv,
          numbconv, fltconv, doprint, donprint - print formatted
          output

     SYNOPSIS
          int   print(char *format, ...)

          int   fprint(int fd, char *format, ...)

          int   sprint(char *s, char *format, ...)

          int   fmtinstall(char c, int (*f)(void*, int, int, int,
          int))

          void  strconv(char *s, int f1, int f2, int f3)

          void  Strconv(Rune *s, int f1, int f2, int f3)

          int   numbconv(void *o, int f1, int f2, int f3, int chr)

          int   fltconv(double f, int f1, int f2, int f3, int chr)

          char* doprint(char *s, char *es, char *format, void *argp)

          extern int printcol;

     DESCRIPTION
          Print writes text to the standard output.  Fprint writes to
          the named output file descriptor; a buffered form is
          described in bio(2). Sprint places text followed by the NUL
          character (\0) in consecutive bytes starting at s; it is the
          user's responsibility to ensure that enough storage is
          available.  Each function returns the number of characters
          transmitted (not including the NUL in the case of sprint),
          or a negative value if an output error was encountered.

          Each of these functions converts, formats, and prints its
          trailing arguments under control of a format string.  The
          format contains two types of objects: plain characters,
          which are simply copied to the output stream, and conversion
          specifications, each of which results in fetching of zero or
          more arguments.  The results are undefined if there are
          arguments of the wrong type or too few arguments for the
          format.  If the format is exhausted while arguments remain,
          the excess is ignored.

          Each conversion specification has the following format:

               % [flags] verb

     Page 1                       Plan 9             (printed 3/28/24)

     PRINT(2)                                                 PRINT(2)

          The verb is a single character and each flag is a single
          character or a (decimal) numeric string.  Up to two numeric
          strings may be used; the first is called f1, the second f2.
          A period can be used to separate them, and if the period is
          present then f1 and f2 are taken to be zero if missing, oth-
          erwise they are `omitted'.  Either or both of the numbers
          may be replaced with the character *, meaning that the
          actual number will be obtained from the argument list as an
          integer.  The flags and numbers are arguments to the verb
          described below.

          The numeric verbs d, o, x, and X format their arguments in
          decimal, octal, hexadecimal, and upper case hexadecimal.
          Each interprets the flags h, l, u, #, and - to mean short,
          long, unsigned, alternate format, and left justified.  If
          neither short nor long is specified, then the argument is an
          int.  If unsigned is specified, then the argument is inter-
          preted as a positive number and no sign is output.  If two l
          flags are given, then the argument is interpreted as a vlong
          (a 4-byte or sometimes 8-byte integer).  If f2 is not omit-
          ted, the number is padded on the left with zeros until at
          least f2 digits appear.  Then, if alternate format is speci-
          fied, for o conversion, the number is preceded by a 0 if it
          doesn't already begin with one; for x conversion, the number
          is preceded by 0x; for X conversion, the number is preceded
          by 0X.  Finally, if f1 is not omitted, the number is padded
          on the left (or right, if left justification is specified)
          with enough blanks to make the field at least f1 characters
          long.

          The floating point verbs f, e, E, g, and G take a double
          argument.  Each interprets the flags +, -, and # to mean
          always print a sign, left justified, and alternate format.
          F1 is the minimum field width and, if the converted value
          takes up less than f1 characters, it is padded on the left
          (or right, if `left justified') with spaces.  F2 is the num-
          ber of digits that are converted after the decimal place for
          e, E, and f conversions, and f2 is the maximum number of
          significant digits for g and G conversions.  The f verb pro-
          duces output of the form [-]digits[.digits].  e conversion
          appends an exponent e[-]digits, and E conversion appends an
          exponent E[-]digits.  The g verb will output the argument in
          either e or f with the goal of producing the smallest out-
          put.  Also, trailing zeros are omitted from the fraction
          part of the output, and a trailing decimal point appears
          only if it is followed by a digit.  The G verb is similar,
          but uses E format instead of e.  When alternate format is
          specified, the result will always contain a decimal point,
          and for g and G conversions, trailing zeros are not removed.

          The s verb copies a string (pointer to char) to the output.
          The number of characters copied (n) is the minimum of the

     Page 2                       Plan 9             (printed 3/28/24)

     PRINT(2)                                                 PRINT(2)

          size of the string and f2. These n characters are justified
          within a field of f1 characters as described above.  The S
          verb is similar, but it interprets its pointer as an array
          of runes (see utf(6)); the runes are converted to UTF before
          output.

          The c verb copies a single char (promoted to int ) justified
          within a field of f1 characters as described above.  The C
          verb is similar, but works on runes.

          Fmtinstall is used to install custom verbs and flags.  Fn
          should be declared as

               int   fn(void *o, int f1, int f2, int f3, int chr)

          Fn is passed a pointer o to whatever argument appears next
          in the list to print. Chr is the flag or verb character to
          cause fn to be called; it must have value less than 512.  In
          fn, f1 and f2 are the decoded flags in the conversion.  A
          missing f1 is denoted by the value zero.  A missing f2 is
          denoted by a negative number.  F3 is the bitwise OR of all
          the flags seen since the most recent `%'.  The standard
          flags values are: 1 (+), 2 (-), 4 (#), 8 (l), 16 (h), 32
          (u), and 64 (ll).  If chr is a verb, fn should return the
          size of the argument in bytes so print can skip over it.  If
          chr is a flag, fn should return a negative value: the nega-
          tion of one of the above flag values, or some otherwise
          unused power of two.  All interpretation of f1, f2, and f3
          is left up to the conversion routine.

          Sprint is reentrant; it may be called to help prepare output
          in custom conversion routines.

          Strconv (with a lower-case s) formats a UTF string.  S is
          the string, f1 and f2 have the same meaning as above.  The
          strconv routine interprets the `-' flag in f3 as left-
          justification.  Strconv (with a capital S) is like strconv,
          but its input is a rune string, which is converted to UTF on
          output.

          Printcol indicates the position of the next output charac-
          ter.  Tabs, backspaces and carriage returns are interpreted
          appropriately.

          Numbconv is used to implement the integer verbs; its argu-
          ments are like those of the function argument to fmtinstall.
          Fltconv is used to implement the floating verbs.  Its argu-
          ments are like those of the function argument to fmtinstall,
          except that the first argument is the double itself rather
          than a pointer to it.  Both numbconv and fltconv use strconv
          to put their results into the current print buffer.

     Page 3                       Plan 9             (printed 3/28/24)

     PRINT(2)                                                 PRINT(2)

          One of strconv, Strconv, or numbconv must be called to pro-
          duce output; no other routine puts characters in the output
          buffer.

          Doprint formats the arguments starting at argp into the
          buffer starting at s, but it writes no characters after the
          address es. It returns a pointer to the NUL terminating the
          formatted string.

     EXAMPLES
          This function prints an error message with a variable number
          of arguments and then quits.

               void fatal(char *msg, ...)
               {
                     char buf[1024], *out;

                     out = doprint(buf, buf+sizeof(buf), "Fatal error: ");
                     out = doprint(out, buf+sizeof(buf), msg, (&msg+1));
                     write(2, buf, out-buf);
                     exits("fatal error");
               }

          This example adds a verb to print complex numbers.

               typedef
               struct {
                     double      r, i;
               } Complex;

               int
               Xconv(void *v, int f1, int f2, int f3, int chr)
               {
                     char str[50];
                     Complex *o;

                     o = v;
                     sprint(str, "(%g,%g)", o->r, o->i);
                     strconv(str, f1, f2, f3);
                     return(sizeof(Complex));
               }

               main(...)
               {
                     Complex x = (Complex){ 1.5, -2.3 };

                     fmtinstall('X', Xconv);
                     print("x = %X\n", x);
               }

     SEE ALSO
          fprintf(2), utf(6), errstr(2)

     Page 4                       Plan 9             (printed 3/28/24)

     PRINT(2)                                                 PRINT(2)

     DIAGNOSTICS
          Print and fprint set errstr.

     BUGS
          The formatting is close to that specified for ANSI
          fprintf(2); the differences are:

               the - flag doesn't work

               u is a flag here instead of a verb

               X conversion doesn't use uppercase A-F for digits ten
               to fifteen

               there are no 0 or space flags here

               there are no P or n verbs here

          Also, and not a bug, print and friends generate UTF rather
          than ASCII.

     Page 5                       Plan 9             (printed 3/28/24)