sean@etnibsd.UUCP (Sean McElroy) (03/18/89)
O.K. Unix/C gurus, since vsprintf requires the user to ensure that there is enough space in the output string, how does one predict the size of the output string? Is there a routine which returns the predicted length of the output string (effectively preforming the printf conversions) without actually producing the output string? First an abridged description of what vsprintf does. Here's it's declaration: char *vsprintf (s, format, ap) char *s, *format; va_list ap; Allow me some hand-waving here and let va_list mean "pointer to an argument list" (see varargs(3) for more detail). The first argument, "s", is a pointer to a suitably sized piece of memory. It is supposed to be large enough to hold the result of converting the arguments listed in "ap" by the specifications listed in "format". Thus the second argument, "format", is the format string optionally containing conversion specifications. Finally, "ap" is a pointer to a list of data items which will supply the data to be converted and then substituted into the string "s". The function returns a pointer to "s". Here's a more general view of the problem. You are given a format string of unknown contents (assume that it is a legitamate format string), and a list of arguments of unknown type (assume that they correspond appropriately with the conversion specifications in the format string). How do you allocate storage for the output string, "s"? One suggestion is to reproduce the functionality of vsprintf up to the point where it outputs a character and replace the output-a-character functionality with count-the-number-of-characters functionality. I quess since I don't possess the source to vsprintf, et al, I can't be as certain of reproducing its functionality. Also this strikes me as such a fundamental obstacle that it must already have been conquered by someone. Any suggestions welcome. -- ____,.,_..,__.,_.,__ Sean Philip McElroy __'..__._,_.__.__.__ Eaton Corp., SED _,___`_.'__.__.__.__ 108 Cherry Hill Dr., Beverly, MA 01922 ___`..'_,___.__.__,_ uunet!etnibsd!sean
sean@etnibsd.UUCP (Sean McElroy) (03/18/89)
It turns out that vfprintf returns the number of characters transmitted to the file. If you use /dev/null as the file then it effectively returns the size of the output message string for vsprintf (less the terminator.) This solution has satisfied me for now although it's inefficient (and uses up a file descriptor). Perhaps there are others that I'm not aware of which don't have the same inefficiencies. I'm still interested in hearing about them. -- ____,.,_..,__.,_.,__ Sean Philip McElroy __'..__._,_.__.__.__ Eaton Corp., SED _,___`_.'__.__.__.__ 108 Cherry Hill Dr., Beverly, MA 01922 ___`..'_,___.__.__,_ uunet!etnibsd!sean
gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/19/89)
In article <993@etnibsd.UUCP> sean@etnibsd.UUCP (Sean McElroy) writes: >O.K. Unix/C gurus, since vsprintf requires the user to ensure that there >is enough space in the output string, how does one predict the size of >the output string? Is there a routine which returns the predicted >length of the output string (effectively preforming the printf conversions) >without actually producing the output string? No. Sometimes you can accurately predict an upper bound on the output string length; for example if the format is "%d" and the numerical argument is known to lie between 0 and 5000, the maximum number of characters for the *sprintf() output will be 5 (including the null byte at the end). >Any suggestions welcome. Don't use *sprintf() when you can't be sure that the output length will be small enough. Seriously.
bzs@bu-cs.BU.EDU (Barry Shein) (03/19/89)
It seems like the obvious solution would have been to treat a NULL string or file pointer as meaning "just return the number of characters in the result". Oh well. -Barry Shein
bzs@bu-cs.BU.EDU (Barry Shein) (03/19/89)
From: gwyn@smoke.BRL.MIL (Doug Gwyn ) >No. Sometimes you can accurately predict an upper bound on the output >string length; for example if the format is "%d" and the numerical >argument is known to lie between 0 and 5000, the maximum number of >characters for the *sprintf() output will be 5 (including the null >byte at the end). Another way to say that is: print_width = LOGx(N) + 1 where x (the log base) is the base to be printed in, 10 for %d, 16 for %x, 8 for %o etc. And add one for sign (+-) if needed. But of course that doesn't help a lot except with the simplest cases (eg. try "%-5.*g"). -Barry Shein
mike@thor.acc.stolaf.edu (Mike Haertel) (03/20/89)
In article <9872@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >No. Sometimes you can accurately predict an upper bound on the output >string length; for example if the format is "%d" and the numerical >argument is known to lie between 0 and 5000, the maximum number of >characters for the *sprintf() output will be 5 (including the null >byte at the end). > ... > >Don't use *sprintf() when you can't be sure that the output length >will be small enough. Seriously. The (unreleased) GNU C library contains routines something like: int snprintf(char *str, size_t len, const char *fmt, ...); int vsnprintf(char *str, size_t len, const char *fmt, va_list ap); that do bounds checking on their output. Richard Stallman suggested to ANSI that they include such routines in the C standard; I am of the impression that various other people independently made the same or a similar suggestion. I also recall a posting by Chris Torek a few months ago that included an excerpt from a <stdio.h> that included a routine that looked something like: FILE *fmemopen(void *mem, size_t len, const char *how); This solves the same problem, and offers additional advantages as well. I do not understand why the pANS does not address this problem in some way. -- Mike Haertel <mike@stolaf.edu> In Hell they run VMS.
henry@utzoo.uucp (Henry Spencer) (03/20/89)
In article <1618@thor.acc.stolaf.edu> mike@stolaf.edu writes: > int snprintf(char *str, size_t len, const char *fmt, ...); > int vsnprintf(char *str, size_t len, const char *fmt, va_list ap); > >that do bounds checking on their output. Richard Stallman suggested to >ANSI that they include such routines in the C standard; I am of the >impression that various other people independently made the same or a >similar suggestion... This is correct. >I do not understand why the pANS does not address this problem in some way. Two reasons: 1. Lack of prior experience with it. Believe it or not, standards committees are supposed to be consolidating existing, proven practices, not endorsing new and untested ideas. X3J11, while not perfect, has done much better in this area than a lot of other language committees. This is a feature, not a bug! 2. The fact that most of the proposals came very late in the standardization process, when quite strong majorities were required to add new stuff. I have been told that at least one attempt to add snprintf and friends failed by one or two votes. -- Welcome to Mars! Your | Henry Spencer at U of Toronto Zoology passport and visa, comrade? | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
sean@etnibsd.UUCP (Sean McElroy) (03/21/89)
In article <9872@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >No. Sometimes you can accurately predict an upper bound on the output >string length; for example if the format is "%d" and the numerical >argument is known to lie between 0 and 5000, the maximum number of >characters for the *sprintf() output will be 5 (including the null >byte at the end). If the format specification contains field width specifiers, this will not work (e.g. sprintf ("%10d", 5000); uses 10 chars + 1 for terminator). This implies that the format specifications need to be parsed in a manner similar to *sprintf in order to accurately predict the number of chars in the result. I was looking for something which did nor require me to re-write *sprintf. Also recall that the original problem stated that the types of the input arguments were unknown. This implies that the type must be gleaned from the format specification itself. Although I'm no expert, I presume that this is the mechanism *sprintf uses as well (e.g. %d means take whatever the next input argument is and treat it as an int). -- ____,.,_..,__.,_.,__ Sean Philip McElroy __'..__._,_.__.__.__ Eaton Corp., SED _,___`_.'__.__.__.__ 108 Cherry Hill Dr., Beverly, MA 01922 ___`..'_,___.__.__,_ uunet!etnibsd!sean
paul@athertn.Atherton.COM (Paul Sander) (03/21/89)
I seem to have missed the original posting, so I'll follow up Doug Gwyn's followup... In article <9872@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes: > In article <993@etnibsd.UUCP> sean@etnibsd.UUCP (Sean McElroy) writes: > >O.K. Unix/C gurus, since vsprintf requires the user to ensure that there > >is enough space in the output string, how does one predict the size of > >the output string? Is there a routine which returns the predicted > >length of the output string (effectively preforming the printf conversions) > >without actually producing the output string? > > No. Sometimes you can accurately predict an upper bound on the output > string length; for example if the format is "%d" and the numerical > argument is known to lie between 0 and 5000, the maximum number of > characters for the *sprintf() output will be 5 (including the null > byte at the end). > > >Any suggestions welcome. > > Don't use *sprintf() when you can't be sure that the output length > will be small enough. Seriously. My guess is that Sean wants to malloc enough space for his output, since he doesn't know how long it is. I like to do that from time to time myself when I have to copy user data (which I have very little control over) into an array of strings that I display later (e.g., in a scrollpane). So far, I've been lucky in that my data are usually displayed in some fixed format, followed by a variable length string. Calculating the length of *sprintf is easy in this case (at least in a platform- and application- dependent way) by summing the ceilings of the lengths of the fixed part of the output, and adding the strlen of the variable length part (plus 1 for the null). It seems to me that it should be possible to write a printf-like function that scans the format string and remaining arguments, returning the ceiling of the length of the result of the *sprintf. I realize that this problem can only be solved on a platform-by-platform basis, but thisseems like a fundamental enough problem that someone somewhere must have done it for some platforms. Has anyone tried? -- Paul Sander (408) 734-9822 | Do YOU get nervous when a paul@Atherton.COM | sys{op,adm,prg,engr} says {decwrl,sun,hplabs!hpda}!athertn!paul | "oops..." ?
scs@adam.pika.mit.edu (Steve Summit) (03/21/89)
In article <28831@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >Another way to say that is: > print_width = LOGx(N) + 1 >where x (the log base) is the base to be printed in... An occasionally-useful observation is that an upper bound on this value is something like 8*sizeof(int), which is the number of characters it could take to print an int in base 2 (some printf's even provide %b for this purpose!). As Barry noted, this helps only in the simplest cases. (I use it internally to my own version of printf, for the buffer size in which integer conversion, before padding, is performed. Unfortunately, the assumption that sizeof deals in 8-bit units is not perfectly valid.) In article <1618@thor.acc.stolaf.edu> mike@stolaf.edu writes: >The (unreleased) GNU C library contains routines something like: > int snprintf(char *str, size_t len, const char *fmt, ...); > int vsnprintf(char *str, size_t len, const char *fmt, va_list ap); >that do bounds checking on their output. >I also recall a posting by Chris Torek a few >months ago that included an excerpt from a <stdio.h> that included >a routine that looked something like: > FILE *fmemopen(void *mem, size_t len, const char *how); >This solves the same problem, and offers additional advantages as well. My own soon-to-be-released stdio replacement contains char *smprintf(char *fmt, ...) which returns a malloc'ed pointer to an area of memory just big enough for the formatted string. (snprintf only allows you to prevent overflow of a finite-sized buffer; smprintf lets the resultant buffer be arbitrarily big.) I may also add FILE *strmopen(); char *strmclose(FILE *); which would give you a fd on which you could do arbitrary stdio output, dynamically allocating (and reallocating as needed) an in-memory buffer, the eventual pointer to which would be returned by strmclose. (I've got to think of better names for these; the 'm' is supposed to stand for "malloc" but the overall effect ends up sounding like "stream" which is misleading.) Steve Summit scs@adam.pika.mit.edu
scs@adam.pika.mit.edu (Steve Summit) (03/21/89)
[Apologies if you see this twice; is there a known problem with canceling cross-posted articles under nntp?] In article <28831@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >Another way to say that is: > print_width = LOGx(N) + 1 >where x (the log base) is the base to be printed in... An occasionally-useful observation is that an upper bound on this value is something like 8*sizeof(int), which is the number of characters it could take to print an int in base 2 (some printf's even provide %b for this purpose!). As Barry noted, this helps only in the simplest cases. (I use it internally to my own version of printf, for the buffer size in which integer conversion, before padding, is performed. Unfortunately, the assumption that sizeof deals in 8-bit units is not perfectly valid.) In article <1618@thor.acc.stolaf.edu> mike@stolaf.edu writes: >The (unreleased) GNU C library contains routines something like: > int snprintf(char *str, size_t len, const char *fmt, ...); > int vsnprintf(char *str, size_t len, const char *fmt, va_list ap); >that do bounds checking on their output. >I also recall a posting by Chris Torek a few >months ago that [mentioned] a routine that looked something like: > FILE *fmemopen(void *mem, size_t len, const char *how); >This solves the same problem, and offers additional advantages as well. My own soon-to-be-released stdio replacement contains char *smprintf(char *fmt, ...) which returns a malloc'ed pointer to an area of memory just big enough for the formatted string. (snprintf only allows you to prevent overflow of a finite-sized buffer; smprintf lets the resultant buffer be as big as it needs to be.) I may also add FILE *strmopen(); char *strmclose(FILE *); which would give you a fd on which you could do arbitrary stdio output, dynamically allocating (and reallocating as needed) an in-memory buffer, the eventual pointer to which would be returned by strmclose. (I've got to think of better names for these; the 'm' is supposed to stand for "malloc" but the overall effect ends up sounding like "stream" which is misleading.) [Exercise for the student: implement smprintf in terms of strmopen, vfprintf, and strmclose.] Steve Summit scs@adam.pika.mit.edu
henry@utzoo.uucp (Henry Spencer) (03/22/89)
In article <9979@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >My own soon-to-be-released stdio replacement contains > > char *smprintf(char *fmt, ...) I would urge changing the name, perhaps to msprintf, to avoid a name that looks very similar to snprintf at first glance. -- Welcome to Mars! Your | Henry Spencer at U of Toronto Zoology passport and visa, comrade? | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
bzs@bu-cs.BU.EDU (Barry Shein) (03/22/89)
Ok, there are two thoughts here: 1. How to find out the number of characters a printf operation will generate. 2. How to limit a printf operation to a buffer size. I suggested the first might be the result of printing to a null pointer (buffer or file.) The second could be solved completely transparently by adding a format effector which indicated the maximum buffer size ("must come first!") Such as using %n# as in: sprintf(buf,"%80#%s",string); /* 80 char buf including \0 */ or sprintf(buf,"%*#%s",BUFSIZ,string); /* BUFSIZ char buf */ Not sure what "%n.m#" or "%#" might indicate (perhaps the latter would just return a count of characters, ie, a zero length buffer?) -Barry Shein, Software Tool & Die
bader+@andrew.cmu.edu (Miles Bader) (03/22/89)
bzs@bu-cs.BU.EDU (Barry Shein) writes: > Ok, there are two thoughts here: > > 1. How to find out the number of characters a printf > operation will generate. > > 2. How to limit a printf operation to a buffer size. > > I suggested the first might be the result of printing to a null > pointer (buffer or file.) What I'd really like would be a new function that could act as a basis for all the other printf functions, and make it possible to emulate them in nice ways. I would make it a varargs function that takes a bounded output buffer and is restartable at the point where it stops due to running into the end of the buffer. E.g. (pardon the name, but I can't think of a better one): /* fmtP and valP are modified so that re-calling the function * will start formatting where it left off */ int rvsnprintf(buf,maxlen,fmtP,valP) char *buf; int maxlen; char **fmtP; /* in/out */ va_list *valP; /* in/out */ vsprintf, vfprintf, etc, are all trivially derivable from this (as is the one someone mentioned a while ago that returned a realloced buffer). Say I write my own buffered io package; I can just call rvsnprintf like: streamvprintf(stream,fmt,val) STREAM *stream; char *fmt; va_list val; { ... while(*fmt!='\0){ int written=rvsnprintf(stream->pos,stream->left,&fmt,&val); if(*fmt!='\0') /* ran out of space */ streamflush(stream); else{ stream->pos+=written; stream->left-=written; } } ... } None of the other proposals I've seen give you this capability (or do it expensively, like mallocing the buffer), and I can't see how it would be much more difficult to implement than existing printfs... -Miles
bader+@andrew.cmu.edu (Miles Bader) (03/22/89)
[Why do problems with my messages always become evident 10 seconds AFTER I send them?] Miles Bader <bader+@andrew.cmu.edu> writes: > /* fmtP and valP are modified so that re-calling the function > * will start formatting where it left off > */ > int rvsnprintf(buf,maxlen,fmtP,valP) > char *buf; > int maxlen; > char **fmtP; /* in/out */ > va_list *valP; /* in/out */ Oops, you need one more variable, since sometimes a directive (%s, etc) can be too large for the buffer, so now: /* fmtP, valP and offsP are modified so that re-calling the function * will start formatting where it left off */ int rvsnprintf(buf,maxlen,fmtP,valP,offsP) char *buf; int maxlen; char **fmtP; /* in/out */ va_list *valP; /* in/out */ int *offsP; /* in/out */ *offsP says how many characters to drop before putting stuff into the buffer, and should initially be 0. With this change, it should work correctly for any size output buffer (even small ones). > { > ... > while(*fmt!='\0){ > int written=rvsnprintf(stream->pos,stream->left,&fmt,&val); Becomes: { int offs=0; ... while(*fmt!='\0){ int written=rvsnprintf(stream->pos,stream->left,&fmt,&val,&offs); -Miles
chris@mimsy.UUCP (Chris Torek) (03/22/89)
In article <28874@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >The [limiting problem] could be solved completely transparently by adding >a format effector which indicated the maximum buffer size ("must come >first!") Such as using %n# as in: `#' is out; it is a flag (meaning `alternate output format' and used by o, x, and e f and g conversions). But aesthetically speaking, it seems to me that this is almost as bad as the `%n' format. (Well, maybe half as bad.) I would prefer snprintf() and/or msprintf(). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
chris@mimsy.UUCP (Chris Torek) (03/22/89)
In article <wY9m4Hy00UkaI=3Ihb@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes: >What I'd really like would be a new function that could act as a basis >for all the other printf functions, and make it possible to emulate >them in nice ways. > >I would make it a varargs function that takes a bounded output buffer >and is restartable at the point where it stops due to running into the >end of the buffer. This is fairly difficult to implement (one wants coroutines for something like this). Instead, why not allow stdio streams to `read' and `write' via user-provided functions? Everyone knows how to use read() and write(); simply provide your own write() that mallocs space, or prints in a window, or whatever. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
rbutterworth@watmath.waterloo.edu (Ray Butterworth) (03/22/89)
In article <16491@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <wY9m4Hy00UkaI=3Ihb@andrew.cmu.edu> bader+@andrew.cmu.edu > (Miles Bader) writes: > >What I'd really like would be a new function that could act as a basis > >for all the other printf functions, and make it possible to emulate > >them in nice ways. > > > >I would make it a varargs function that takes a bounded output buffer > >and is restartable at the point where it stops due to running into the > >end of the buffer. > > This is fairly difficult to implement (one wants coroutines for something > like this). Instead, why not allow stdio streams to `read' and `write' > via user-provided functions? Everyone knows how to use read() and > write(); simply provide your own write() that mallocs space, or prints > in a window, or whatever. There is something else that is usually fairly easy to implement though, even if the code for the implementation is non-portable. A typical implementation of sprintf simply builds a FILE* and calls fprintf on it, while a typical implementation of stdio has some function that is called when an output buffer fills. One could easily write a function that is similar to sprintf but is passed a pointer to the buffer size. When the buffer fills up, instead of "flushing" it, realloc is called and the fprintf continues. The function would return the pointer to the possibly reallocated buffer and would possibly have stuffed a new size through the buffer size pointer. In many stdio implementations this can be written with only a few lines of code, and I'd say it is far more useful than many of the alternatives that have been suggested. e.g. a function that returns an estimate of how many characters would be needed (this doubles the cpu since it effectively calls printf twice), or a function that limits the output to the buffer (you have to check if the buffer filled, and if it did you have to realloc another bigger one and call the function right from the beginning again).
mike@thor.acc.stolaf.edu (Mike Haertel) (03/23/89)
In article <16491@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >This is fairly difficult to implement (one wants coroutines for something >like this). Instead, why not allow stdio streams to `read' and `write' >via user-provided functions? Everyone knows how to use read() and >write(); simply provide your own write() that mallocs space, or prints >in a window, or whatever. I have been writing just exactly such a stdio package lately. The only things I have left to do are printf() and friends, and scanf() and friends. The reason I am writing it is I am experimenting with standalone programs on my machine, and I wanted a stdio library. It also works on Unix, that is where I test it. Incidentally the stuff that is written so far all conforms to the pANS. When I finish it I will make it available to anyone who is interested. The way it works is like this: typedef struct _FILE { ... struct __iofuncs *__iofuncs; /* Vector to actual I/O functions. */ void *__info; /* Opaque info for I/O functions. */ ... } FILE; When fopen() is called it loops through all available I/O function tables, trying the open() entry in each one (iofuncs->open() just gets the same arguments as fopen()); the first to return non-NULL has that value installed in FILE->__info. Then, for example, the actual write call in fflush() looks like this: (*fp->__iofuncs->write)(fp->__info, buf, len); There will be a library entry point to install user-defined I/O function tables. I haven't decided exactly how to do printf() yet; I would like to have a function switch table based on format letters so I can have an extensible printf(). I will probably try that tonight. I will not be doing the floating point stuff in the near future as the standalone environment I am using is a 68010, and I have not yet written the floating point run time support for the compiler, and I really don't feel like doing that any time soon, I don't use floating point much . . . I got the idea for the extensible printf() from the manual page describing the FIO package and in particular fmtinstall() in the Ninth Edition manual. Whoever you are at Bell Labs who invented that, thanks, it's a cool idea. -- Mike Haertel <mike@stolaf.edu> In Hell they run VMS.
les@chinet.chi.il.us (Leslie Mikesell) (03/23/89)
In article <28874@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >Ok, there are two thoughts here: > 1. How to find out the number of characters a printf > operation will generate. > 2. How to limit a printf operation to a buffer size. Or a third, which is what I usually want: 3. Give me a pointer to a buffer with my formatted string in it. This is trivial after doing operation (1) but shouldn't it be possible to do it in one operation? Les Mikesell
bader+@andrew.cmu.edu (Miles Bader) (03/23/89)
chris@mimsy.UUCP (Chris Torek) writes: > In article <wY9m4Hy00UkaI=3Ihb@andrew.cmu.edu> bader+@andrew.cmu.edu > (Miles Bader) writes: > >What I'd really like would be a new function that could act as a basis > >for all the other printf functions, and make it possible to emulate > >them in nice ways. > > > >I would make it a varargs function that takes a bounded output buffer > >and is restartable at the point where it stops due to running into the > >end of the buffer. > > This is fairly difficult to implement (one wants coroutines for something > like this). Instead, why not allow stdio streams to `read' and `write' > via user-provided functions? Everyone knows how to use read() and > write(); simply provide your own write() that mallocs space, or prints > in a window, or whatever. I agree that stdio should have been written with user-provided read/write routines. But I disagree that a restartable sprintf would be difficult. The code needn't be much different at all from a putc based printf (the only difference is that state changes inside the routine are passed out of it). One reason why I like the restartable printf idea is that it's lower overhead and less complex than creating/destroying a stream just for the purpose of implementing sprintf. I just wrote my own stdio-type package; I don't want to have to go though the overhead of passing things through a stdio stream just to get put into MY stream (not that it would be that high; but it's the principle of the thing). -Miles
karl@haddock.ima.isc.com (Karl Heuer) (03/23/89)
In <1989Mar21.183741.1089@utzoo.uucp> henry@utzoo (Henry Spencer) writes: >In <9979@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >>My own soon-to-be-released stdio replacement contains >> char *smprintf(char *fmt, ...) > >I would urge changing the name, perhaps to msprintf, to avoid a name that >looks very similar to snprintf at first glance. But `msprintf' has the flaw that the va_list version would be named `vmsprintf', which suggests that it has something to do with a certain obscure operating system. I think I'd go with `mprintf'. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
michael@garfield.MUN.EDU (Mike Rendell) (03/23/89)
In article <wY9m4Hy00UkaI=3Ihb@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes: >What I'd really like would be a new function that could act as a basis >for all the other printf functions, and make it possible to emulate >them in nice ways. > >I would make it a varargs function that takes a bounded output buffer >and is restartable at the point where it stops due to running into the >end of the buffer. I wrote a version of doprnt() which does something like this. Instead of taking a FILE * argument it's passed a function pointer and a "generic argument" (void/char *). new_doprnt() fills up a stack buffer and calls the function (which takes the same arguments as fwrite()) to deal with it. This makes printf() and a bounds checking sprintf() (or a re-alloc()ing sprintf()) easy to write as well as providing a simple method for programmers to hook into it. I've used it in some screen based programs to page output and in some stand alone programs to do output to a console. The only draw back is that it doesn't handle %[egf] - but who needs those anyway :-). Mike Rendell Department of Computer Science michael@garfield.mun.edu Memorial University of Newfoundland uunet!garfield!michael St. John's, Nfld., Canada (709) 737-4550 A1C 5S7
jbayer@ispi.UUCP (Jonathan Bayer) (03/27/89)
In article <1989Mar21.183741.1089@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >In article <9979@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >>My own soon-to-be-released stdio replacement contains >> >> char *smprintf(char *fmt, ...) > >I would urge changing the name, perhaps to msprintf, to avoid a name that ^^^^^^^^ So now Microsoft has it's own version of printf :-) JB -- Jonathan Bayer Beware: The light at the end of the Intelligent Software Products, Inc. tunnel may be an oncoming dragon 19 Virginia Ave. ...uunet!ispi!jbayer Rockville Centre, NY 11570 (516) 766-2867 jbayer@ispi.UUCP
orr@taux01.UUCP (Orr Michael ) (04/03/89)
In article <12135@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: > >But `msprintf' has the flaw that the va_list version would be named >`vmsprintf', which suggests that it has something to do with a certain >obscure operating system. > >Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint ... In which 'printf' itself is limited to 512 chars at most, getting you a crash if you try printing longer strings ... -- orr@nsc IBM's motto: Machines should work, {amdahl,decwrl,hplabs,pyramid,sun}!nsc!orr People should think. Orr's remark: Neither do. Disclaimer: Opinions, come home. All is forgiven. Papa.