/* The pwb version this is based on */
static char *printf_id
= "@(#) printf.c:2.2 6/5/79";
/* The local sccs version within ex */
static char *sccsid
= "@(#)printf.c 7.1 %G%";
* This version of printf is compatible with the Version 7 C
* printf. The differences are only minor except that this
* printf assumes it is to print through putchar. Version 7
* printf is more general (and is much larger) and includes
* provisions for floating point.
#define MAXOCT 11 /* Maximum octal digits in a long */
#define MAXINT 32767 /* largest normal length positive integer */
#define BIG 1000000000 /* largest power of 10 less than an unsigned long */
#define MAXDIGS 10 /* number of digits in BIG */
static int width
, sign
, fill
;
int length
,mask1
,nbits
,n
;
/* process format string first */
while ((fcode
= *fmt
++)!='%') {
/* ordinary (non-%) character */
/* length modifier: -1 for h, 1 for l, 0 for none */
/* check for a leading - sign */
/* a '0' may follow the - sign */
/* this is the requested fill character */
/* Now comes a digit string which may be a '*' */
while (*fmt
>='0' && *fmt
<='9')
width
= width
* 10 + (*fmt
++ - '0');
/* maybe a decimal point followed by more digits (or '*') */
while (*fmt
>='0' && *fmt
<='9')
prec
= prec
* 10 + (*fmt
++ - '0');
* At this point, "sign" is nonzero if there was
* a sign, "fill" is 0 if there was a leading
* zero and 1 otherwise, "width" and "prec"
* contain numbers corresponding to the digit
* strings before and after the decimal point,
* respectively, and "fmt" addresses the next
* character after the whole mess. If there was
* no decimal point, "prec" will be -1.
* At exit from the following switch, we will
* emit the characters starting at "bptr" and
* ending at "ptr"-1, unless fcode is '\0'.
switch (fcode
= *fmt
++) {
/* process characters and strings first */
buf
[0] = va_arg(ap
, int);
bptr
= va_arg(ap
,char *);
for (n
=0; *bptr
++ && n
< prec
; n
++) ;
num
= (unsigned)va_arg(ap
,int);
/* shift and mask for speed */
if (((int) num
& mask1
) < 10)
*--bptr
= ((int) num
& mask1
) + 060;
*--bptr
= ((int) num
& mask1
) + 0127;
while (num
= (num
>> nbits
) & mask2
);
if (!sign
&& fill
<= 0) {
fcode
= fcode
+ 'a' - 'A';
if (n
= (fcode
!= 'u' && num
< 0))
/* now convert to digits */
bptr
= _p_dconv(num
, buf
);
/* not a control character,
/* _p_dconv converts the unsigned long integer "value" to
* printable decimal and places it in "buffer", right-justified.
* The value returned is the address of the first non-zero character,
* or the address of the last character if all are zero.
* The result is NOT null terminated, and is MAXDIGS characters long,
* starting at buffer[1] (to allow for insertion of a sign).
* This program assumes it is running on 2's complement machine
* with reasonable overflow treatment.
/* zero is a special case */
/* develop the leading digit of the value in "n" */
value
-= BIG
; /* will eventually underflow */
while ((lval
= value
- BIG
) >= 0) {
/* stash it in buffer[1] to allow for a sign */
* Now develop the rest of the digits. Since speed counts here,
* we do it in two loops. The first gets "value" down until it
* is no larger than MAXINT. The second one uses integer divides
* rather than long divides to speed it up.
*--bp
= (int)(value
% 10) + '0';
/* cannot lose precision */
*--bp
= (svalue
% 10) + '0';
/* fill in intermediate zeroes if needed */
* This program sends string "s" to putchar. The character after
* the end of "s" is given by "send". This allows the size of the
* field to be computed; it is stored in "alen". "width" contains the
* user specified length. If width<alen, the width will be taken to
* be alen. "sign" is zero if the string is to be right-justified
* in the field, nonzero if it is to be left-justified. "fill" is
* 0 if the string is to be padded with '0', positive if it is to be
* padded with ' ', and negative if an initial '-' should appear before
* any padding in right-justification (to avoid printing "-3" as
* "000-3" where "-0003" was intended).
cfill
= fill
>0? ' ': '0';
/* we may want to print a leading '-' before anything */
if (*s
== '-' && fill
< 0) {
/* emit any leading pad characters */
/* emit the string itself */
/* emit trailing pad characters */