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