Guessing buffer size needed for sprintf beforehand

Chris Torek chris at mimsy.UUCP
Wed May 11 15:17:14 AEST 1988


>In article <11331 at mimsy.UUCP> I wrote:
>>By the time you reach a routine that takes a `va_list' argument,
>>it is too late to scan the argument list twice....

In article <13597 at comp.vuw.ac.nz> andrew at comp.vuw.ac.nz (Andrew Vignaux) writes:
>The `varargs' manual page says "Multiple traversals, each bracketed by
>va_start ...  va_end, are possible." so it is possible to rescan the
>argument list.  (or have I misinterpreted what you said?)

You have.  Watch:

	int prf(const char *fmt, ...) {
		va_list ap;
		int rv;
		va_start(ap, fmt);
		rv = __printf(stdout, fmt, ap);
		va_end(ap);
		return (rv);
	}

	int __printf(FILE *fp, const char *fmt, va_list ap) {
		...

Which function takes a va_list argument?  Which one has the
va_start/va_end pair?  You *could* do this:

	int prf(const char *fmt, ...) {
		...
		va_start(ap, fmt);
		_first_fn(fmt, ap);
		va_end(ap);
		va_start(ap, fmt);
		_second_fn(fmt, ap);
		va_end(ap);
		...
	}

except that the original problem requires that the solution be
contained within the __printf function.

>BTW, I think there should be a stropen()-like function so mere-mortals
>can open string based stdio streams.  Is this in the standard?

It is not in the standard, but I have one; mine is called fmemopen().
There is a more general interface called funopen():

	/* declaration (prototype version) */
	FILE *funopen(const void *cookie,
		int (*readfn)(void *cookie, char *buf, int n),
		int (*writefn)(void *cookie, const char *buf, int n),
		long (*seekfn)(void *cookie, long off, int whence),
		int (*closefn)(void *cookie));
	#define	fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
	#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)

Unix stdio needs only these four operations.  By restructuring the
stdio internals slightly, `normal' file I/O is done with read, write,
seek, and close functions that just call read, write, seek, and close,
and anyone can easily write `special' I/O routines.  fmemopen() is just
a special instance of this same general case---in principle, it uses
read and write functions that transfer to user memory, although in
practise just aims the internal stdio buffers directly at that memory;
its read and write functions return an error, and get called only when
the declared region is full (write) or empty (read).  (Being an
internal stdio function, it is allowed to cheat like this.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.wizards mailing list