Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ (2) — Plan9 3rd Edition (Vita Nuova)

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

fprintf(2)

utf(6)

errstr(2)

PRINT(2)

NAME

print, fprint, sprint, snprint, seprint, fmtinstall, strconv, Strconv, numbconv, fltconv, doprint − print formatted output

SYNOPSIS

­#include <u.h>
­#include <libc.h>

intprint(char ∗format, ...) 

intfprint(int fd, char ∗format, ...) 

intsprint(char ∗s, char ∗format, ...) 

intsnprint(char ∗s, int len, char ∗format, ...) 

char∗seprint(char ∗s, char ∗e, char ∗format, ...) 

intfmtinstall(int c, int (∗f)(va_list∗, Fconv∗))

voidstrconv(char ∗s, Fconv ∗fp)

voidStrconv(Rune ∗s, Fconv ∗fp)

intnumbconv(va_list ∗arg, Fconv ∗fp)

intfltconv(va_list ∗arg, Fconv ∗fp)

char∗doprint(char ∗s, char ∗es, char ∗format, va_list arg)

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 bytes transmitted (not including the NUL in the case of sprint), or a negative value if an output error was encountered.

­Snprint is like sprint, but will not place more than ­len bytes in s. Its result is always NUL-terminated and holds the maximal number of complete UTF-8 characters that can fit. ­Seprint is like snprint, except that the end is indicated by a pointer ­e rather than a count and the return value points to the terminating NUL of the resulting string. 

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

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, otherwise 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 interpreted 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 omitted, the number is padded on the left with zeros until at least ­f2 digits appear.  Then, if alternate format is specified, 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 number 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 produces 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 output.  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 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. 

The ­p verb formats a pointer value.  At the moment, it is a synonym for ux, but that will change once pointers and integers are different sizes. 

The ­r verb takes no arguments; it copies the error string returned by a call to errstr(2).

­Fmtinstall is used to install custom verbs and flags labeled by character c, which must have value less than 512. ­Fn should be declared as

intfn(va_list ∗arg, Fconv ∗fp)

Fp->chr is the flag or verb character to cause ­fn to be called.  In fn, fp->f1 and fp->f2 are the decoded flags in the conversion.  A missing fp->f1 is denoted by the value zero.  A missing fp->f2 is denoted by a negative number.  Fp->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).  ­Fn is passed a pointer ­arg to the argument list.  If fp->chr is a verb, ­fn should use va_arg to fetch its argument from the list, then format it, and return zero.  If fp->chr is a flag, ­fn should return a negative value: the negation of one of the above flag values, or some otherwise unused power of two.  All interpretation of fp->f1, fp->f2, and fp->f3 is left up to the conversion routine.  ­Fmtinstall returns 0 if the installation succeeds, −1 if it fails. 

Sprint, snprint, and ­seprint are re-entrant; they may be called to help prepare output in custom conversion routines. 

The function ­strconv formats a UTF string.  ­S is the string, ­fp has the same meaning as above.  The ­strconv routine interprets the ­- flag in fp->f3 as left-justification.  The function ­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 character.  Tabs, backspaces and carriage returns are interpreted appropriately. 

­Numbconv and ­fltconv are used to implement the integer and floating verbs.  Their arguments are like those of the function argument to fmtinstall. Both ­numbconv and ­fltconv use ­strconv to put their results into the current print buffer. 

One of strconv or ­Strconv must be called to produce output; no other routine puts characters in the output buffer. 

­Doprint formats the argument list arg ­arg 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;
va_list arg;
 out = doprint(buf, buf+sizeof(buf), "Fatal error: ");
va_start(arg, msg);
out = doprint(out, buf+sizeof(buf), msg, arg);
va_end(arg);
write(2, buf, out-buf);
exits("fatal error");
}

This example adds a verb to print complex numbers. 

typedef
struct {
doubler, i;
} Complex;
 int
Xconv(va_list ∗arg, Fconv ∗fp)
{
char str[50];
Complex c;
 c = va_arg(∗arg, Complex);
sprint(str, "(%g,%g)", c.r, c.i);
strconv(str, fp);
return 0;
}
 main(...)
{
Complex x = (Complex){ 1.5, -2.3 };
 fmtinstall(’X’, Xconv);
print("x = %X\n", x);
}

SOURCE

­/sys/src/libc/port

SEE ALSO

fprintf(2), utf(6), errstr(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

there are no ­0 or space flags here

there are no ­P or ­n verbs here

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

Plan 9  —  July 29, 2000

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026