Xref: utzoo comp.unix.questions:7079 comp.unix.wizards:8589 Path: utzoo!attcan!uunet!munnari!vuwcomp!andrew From: andrew@comp.vuw.ac.nz (Andrew Vignaux) Newsgroups: comp.unix.questions,comp.unix.wizards Subject: Re: Guessing buffer size needed for sprintf beforehand Message-ID: <13621@comp.vuw.ac.nz> Date: 18 May 88 02:16:58 GMT References: <136@insyte.uucp> <11331@mimsy.UUCP> <13597@comp.vuw.ac.nz> <11439@mimsy.UUCP> Reply-To: andrew@comp.vuw.ac.nz (Andrew Vignaux) Organization: Comp Sci, Victoria Univ, Wellington, New Zealand Lines: 111 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@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >>In article <11331@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@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) continues: >In article <13597@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@mimsy.umd.edu Path: uunet!mimsy!chris Andrew ------------------------------------------------------------------------------ Domain address: andrew@comp.vuw.ac.nz Path address: ...!uunet!vuwcomp!andrew