faustus@ucbcad.BERKELEY.EDU (Wayne A. Christopher) (07/08/86)
I want to be able to write a function that will take an unknown number of arguments and then call another such function with these arguments, namely something like printf() that calls _doprnt() without processing its arguments at all. I know there is no way to write this code portably, but is it reasonable to assume that I will be able to do it at all in most common implementations of C? Also, how safe is it to assume that there will be something like _doprnt() available? I know it's not good to depend on things like this, but I don't want to have to write my own printf()... Wayne
gwyn@BRL.ARPA (VLD/VMB) (07/08/86)
Most UNIX and some other C implementations have a <varargs.h> header file that defines macros for getting at variably-sized argument lists; unfortunately this is not sufficient for an interface to a printf-like routine, where you need to pass the remaining argument list along. Many UNIX and some other C implementations provide v*printf functions that are useful in such situations. There is normally some function like _doprnt in the C library, but it may go by another name and have slightly different arguments. For the time being, people usually either invoke *printf using functions with fixed arguments (perhaps several of them to cover all necessary cases) or provide an interface that must be adapted by each site. Other commonly-used approaches tend to be non-portable.
hansen@mips.UUCP (07/09/86)
> I want to be able to write a function that will take an unknown number > of arguments and then call another such function with these arguments, > namely something like printf() that calls _doprnt() without processing > its arguments at all. I know there is no way to write this code portably, > but is it reasonable to assume that I will be able to do it at all in > most common implementations of C? Also, how safe is it to assume that there > will be something like _doprnt() available? I know it's not good to depend on > things like this, but I don't want to have to write my own printf()... > > Wayne System V defines functions named vprintf, vfprintf, and vsprintf, that combined with the macros defined in varargs.h, provide a reasonably portable interface to _doprnt. The first two functions are trivial to implement on a machine that has _doprnt, the third is a little tricker, since you must trick the stdio package into outputting into a string, and the necessary flag setting is rather unportable (which is why the v...printf functions should be defined in the system-provided library). Using varargs.h goes a long way toward making such functions portable. -- Craig Hansen | "Evahthun' tastes MIPS Computer Systems | bettah when it ...decwrl!mips!hansen | sits on a RISC"
meissner@dg_rtp.UUCP (Michael Meissner) (07/09/86)
In article <809@ucbcad.BERKELEY.EDU> faustus@ucbcad.UUCP writes: > > I want to be able to write a function that will take an unknown number > of arguments and then call another such function with these arguments, > namely something like printf() that calls _doprnt() without processing > its arguments at all. I know there is no way to write this code portably, > but is it reasonable to assume that I will be able to do it at all in > most common implementations of C? Also, how safe is it to assume that there > will be something like _doprnt() available? I know it's not good to depend on > things like this, but I don't want to have to write my own printf()... > > Wayne In the forthcoming ANSI X3J11 standard, as well as System V, are the functions vprintf, vfprintf, and vsprintf. Instead of taking the argument list directly, the take the varargs pointer. Thus the calling sequence looks like (in the ANSI declarative style): int vprintf( const char *fmt, va_list varargs_ptr ); int vfprintf( FILE *stream, const char *fmt, va_list varargs_ptr ); int vsprintf( char *buffer, const char *fmt, va_list varargs_ptr ); For systems that do not have vprintf and friends yet, you could write the vprintf, et. al, in a few lines of code calling _doprnt. This would have to be tailored for each system. Michael Meissner, Data General ...{ decvax, ucbvax, ihnp4 }!mcnc!rti-sel!dg_rtp!meissner
chris@umcp-cs.UUCP (Chris Torek) (07/10/86)
In article <434@dg_rtp.UUCP> meissner@dg_rtp.UUCP (Michael Meissner) writes: > In the forthcoming ANSI X3J11 standard, as well as System V, are the >functions vprintf, vfprintf, and vsprintf. Instead of taking the argument >list directly, the take the varargs pointer. Thus the calling sequence looks >like (in the ANSI declarative style): > > int vprintf( const char *fmt, va_list varargs_ptr ); > int vfprintf( FILE *stream, const char *fmt, va_list varargs_ptr ); > int vsprintf( char *buffer, const char *fmt, va_list varargs_ptr ); Since none of 4.[123]BSD Vax Unix have these, but they are trivial, here is an (untested) implementation. (Unfortunately, implementing the proper return value is not so trivial, except for vsprintf.) I believe this code will work on a Pyramid as well. #include <stdio.h> int vprintf(fmt, args) char *fmt; va_list args; { _doprnt(fmt, args, stdout); return (ferror(stdout) ? EOF : 0); } int vfprintf(f, fmt, args) FILE *f; char *fmt; va_list args; { _doprnt(fmt, args, f); return (ferror(f) ? EOF : 0); } int vsprintf(s, fmt, args) char *s, *fmt; va_list args; { FILE fakebuf; fakebuf._flag = _IOSTRG; /* no _IOWRT: avoid stdio bug */ fakebuf._ptr = s; fakebuf._cnt = 32767; _doprnt(fmt, args, &fakebuf); return (strlen(s)); } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu