kendall@wjh12.UUCP (Sam Kendall) (10/13/83)
As previously noted, %r takes as argument a char **, which is a pointer to a bunch of printf-style arguments, starting with a format string, on the stack. So %r can be used to write functions which take printf-like variable argument lists, and call printf to print them. THIS IS OTHERWISE IMPOSSIBLE, without either (1) rewriting printf and including the code in your function, or (2) calling _doprnt, the undocumented function shared by all printf and [sf]printf. (By the way, there was once an article on the net on how to use _dorpnt for this purpose. Maybe it should be re-submitted.) So %r is really useful. It was documented in PWB, if I remember correctly (can anyone check me there?); but why was it subsequently un-documented, and then removed? Well, the problem with %r is that it CANNOT be implemented on one system, GCOS (a Honeywell somethingorother). Maybe it was removed from USG UNIX because USG wants their UNIX to be portable, even to GCOS. On the other hand, perhaps it was just un-documented accidentally, and then removed because it was undocumented. But it is (was) so useful! And it could be respecified to be portable using the usually undocumented varargs(3) package. I am told that Andrew Koenig (sp?) is the author both of the varargs(3) package and of the System III printf. Perhaps he can shed some light on this. Can someone ask him? Sam Kendall {allegra,ihnp4}!wjh12!kendall Delft Consulting Corp. decvax!genrad!wjh12!kendall
usenet@abnjh.UUCP (usenet) (10/14/83)
Will somebody who has a copy of the article that describes how to use the _doprnt() subroutine please post it. I missed it the last time around. Thanks in advance. Rick Thomas abnji!rbt (201)-560-6565
eric@washu.UUCP (Eric Kiebler) (10/17/83)
BEWARE the _doprnt code, my son! The bits that twitch; the types that clash! Use the portable varargs stuff, Avoid the _doprnt's teeth that gnash! As Mark Horton pointed out, the _doprnt() routine is *not* portable and should not be used for that reason. Yes, of course, the code will *never* leave your machine, but... Just for you "my code stays at home and watches TV" folks out there, here is a little collection of error functions which I used in code that wasn't supposed to leave my machine either... /* Error Handling Functions Wash. U. Computer Systems Lab E. Kiebler Sept, 1982 Distribution allowed if and only if this entire comment is included */ #include <stdio.h> #include <sys/types.h> #include <time.h> extern char *ProgramName; extern int DebugFlag; extern FILE *stdlog; warning(fmt,args) char *fmt; { fprintf(stderr,"%s: (warning) ",ProgramName); _doprnt(fmt, &args, stderr); /* magic */ return(ferror(stderr)? EOF : 0); } error(fmt,args) char *fmt; { fprintf(stderr,"%s: (error) ",ProgramName); _doprnt(fmt, &args, stderr); /* voodoo */ return(ferror(stderr)? EOF : 0); } fatal(fmt,args) char *fmt; { fprintf(stderr,"%s: (fatal) ",ProgramName); _doprnt(fmt, &args, stderr); /* read the manuals */ exit(0); } debug(fmt,args) char *fmt; { if(DebugFlag){ fprintf(stderr,"%s: (debug) ",ProgramName); _doprnt(fmt, &args, stderr); /* wonderful! */ fprintf(stderr,"\n"); } } log(fmt,args) char *fmt; { struct tm *tp; extern struct tm *localtime(); time_t clock; time(&clock); tp = localtime(&clock); fprintf(stdlog, "(%d/%d-%d:%d) ", tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min); _doprnt(fmt,&args,stdlog); fprintf(stdlog,"\n"); } This code was written by myself and, as far as I know, does not use any proprietary (sp?) code (unless telling people that _doprnt() exists is proprietary, in which case eat the code and call your lawyer). C A V E A T E M P T O R ========================== -- eric ..!ihnp4!washu!eric
decot@cwruecmp.UUCP (Dave Decot) (10/21/83)
It is not exactly impossible, without the aid of %r, to make something that
reacts in an expected way to a call like
err("identifier '%s' not declared in function %s", id, fun);
Declare err() as:
/*VARARGS 1*/
err(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
char *fmt;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
{
fprintf(stderr, "%d: ", Linenum);
fprintf(stderr, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
fputs(stderr, "!!!\007\n");
}
This can be extended if you REALLY need more than up to 10 arguments.
----------------------------------------
Dave Decot ..!decvax!cwruecmp!decot