Guessing buffer size needed for sprintf beforehand

Andrew Vignaux andrew at comp.vuw.ac.nz
Wed May 18 12:16:58 AEST 1988


Sorry to (a) get off the subject, and (b) turn it into a tutorial for people
who can't keep up with the standards, but:

In article <11439 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) writes:
>>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....
[...]
>Watch:
>	int prf(const char *fmt, ...) {
[...]
>		va_start(ap, fmt);
>		rv = __printf(stdout, fmt, ap);
>		va_end(ap);
[...]
>	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?

Of course.  How silly of me.  Because I very seldom send a va_list off to
another routine (working on a Pyramid one is not quite sure about what one can
get away with, until one trys :-) I misread the va_list as a va_alist.
However, I have a few questions about varargs:
   ("CAN" means with respect to the standards/manual page)

[] CAN you pass va_list's around like this?  I realise v[fs]?printf
   get away with it, but their implementations are not required to be
   portable.
   (this does work on vax/sun/pyramid)

[] Given that you are allowed to pass va_list's around why CAN't you
   write:
		va_start (ap);
		count = count_printf (fmt, ap);
		rv = vsprintf (new_space, fmt, ap);
		va_end (ap);
   (this does not work on pyramids)

   or equivalently:
		save_ap = ap;
		i = va_arg (ap, int);
		j = va_arg (save_ap, int);
   (this does not work on pyramids)

   or even:
		save_ap = ap;
		rv = vprintf (fmt, ap);
		/* now get the parameter after the printf args */
		i = va_arg (ap, int);
   (this ONLY works on pyramids-re comment)

[] CAN you strip a few arguments off the va_list and then pass it to other
   routines?
		i = va_arg (ap, int);
		s = va_arg (ap, char *);
		switch (i) {
		    case VPRINT_IT:
			fmt = va_arg (ap, char *);
			(void) vprintf (fmt, ap);
			break;
		}
   (this works on vax/sun/pyramid)

I understand why these work/don't work in the current vararg implementations
for each machine (the pyramid stores extra va_arg state information, the
others just move a pointer).  However, I can't see anything in varargs(3) that
allows/forbids doing these things, except perhaps the "multiple traversals"
comment.  Presumably there is a more precise definition of the varargs stuff
somewhere.

Is there any need for a va_rewind ()?

[Aside: does va_start have 2 parameters in the new standard? -- boy am I out
of date :-(]

Anyway to get back to what I am really interested in.

In article <11439 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) continues:
>In article <13597 at comp.vuw.ac.nz> I wrote:
>>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():
[I have non-prototyped the declaration to save space-AJV]
>	FILE *funopen(cookie, readfn, writefn, seekfn, closefn)
>	void * cookie;

Looks really nice and object oriented--just what I wanted.  I guessed you
meant something like this when you referred to a `function oriented stdio'.
How {,un}standard is it?  How can I get it?

I can't quite pick up the semantics of funopen() from the declaration.  My
guess is that the f{whatever}open function performs the appropriate open,
packages whatever info the virtual functions will need into a cookie record,
and then returns the result of funopen()--or am I completely wrong again :-(.
Otherwise, what is the initial cookie parameter?  Where/how do you describe
the `open' call {open()--re:fopen, no-op()--re:fmemopen, fork();pipe()--
re:popen, ...}?  Is there a funreopen() (for those cases where you want to
change functions in mid-stream :-)? etc...

Should I be looking in a standards document for this information? (a little
difficult when you're on the edge of the world :-(

>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

Andrew
------------------------------------------------------------------------------
Domain address: andrew at comp.vuw.ac.nz   Path address: ...!uunet!vuwcomp!andrew



More information about the Comp.unix.wizards mailing list