modification to /usr/src/lib/libc/vax/stdio/doprnt.s

Jay Lepreau lepreau at utah-cs.UUCP
Thu Dec 27 13:09:30 AEST 1984


Chris Torek (foolishly?) asks:
	Anyone else have any favorite additions to printf?

I like this one best, as it's the most general: a superset of all the
rest.  It's less than a dozen lines added to the 4.2 BSD doprnt.s--
they are appended below.

>From utah-gr!thomas (Spencer W. Thomas) Thu Mar 10 16:34:39 1983
Subject: New printf format (feep)
Newsgroups: vax.general

From: Spencer W. Thomas  <thomas>
A new format effector has been added to printf.  The %p format can be
used to format an argument using an arbitrary procedure (thus p).

The %p format takes TWO arguments - the first is the address of the
procedure to call, the second is the data item.  The procedure is
called as shown:

	proc( fdesc, arg, flags, width, ndigits )
	FILE *fdesc;
	char *arg;
	int flags, width, ndigits;

fdesc is the FILE which is being written to.
arg is a pointer to the item in the printf argument list.
flags is a bit mask describing the presence of various options between
	the `%' and the `p'.  The bits are:
 	0x01	width was specified.  The number is passed in width.
	0x02	ndigits was specified.  The number is passed in ndigits.
	0x04	width was specified with a leading 0.
	0x08	a minus sign was included.
	0x10	a plus sign was included.
	0x20	a # was included.
	0x40	a capital `P' was used rather than a lower case `p'.
	0x80	a space was included.
The printf specification may include numbers between the % and the p,
	separated by a `.'.  The first is passed in the variable width,
	the second in ndigits.  These arguments should be ignored if the
	appropriate flag bit is not set.

The formatting function must return the number of bytes used from the
printf argument list  (i.e. when formatting an int, return sizeof(int),
when formatting a double or float, return sizeof(double), when
formatting a pointer, return sizeof(pointer).  The formatting function
may call printf recursively.  

A sample function which formats a point is given below, along with a
sample call.

struct point {
	float xyz[3];
} p;

/* Format a point as [x y z] using `g' format.  Ignore flags, etc. */

prpoint( f, pt, flags, wid, nd )
FILE *f;
point *pt;
{
	fprintf(f, "[%g %g %g]", pt->xyz[0], pt->xyz[1], pt->xyz[2]);
	return sizeof(point);
}

	/* 
	 * A sample call.  Note that the actual point is put in the
	 * arguments, NOT a pointer.

	printf("p value = %p\n", prpoint, p);

198c198
< 	.word fmtbad-L5			# P
---
> 	.word capital-L5		# P
230c230
< 	.word fmtbad-L5			# p
---
> 	.word procfmt-L5		# p
246a247,258
> 
> 
> procfmt:				# use a procedure to format value
> 	movl	(ap)+,r0
> 	pushl	ndigit
> 	pushl	width
> 	pushl	flags
> 	pushl	ap			# address of data item
> 	pushl	fdesc
> 	calls	$5,(r0)			# proc( file, arg, flags, width, prec )
> 	addl2	r0,ap			# proc returns # bytes "consumed"
> 	jbr	loop



More information about the Comp.unix.wizards mailing list