pyr201@psc90.UUCP (d^2) (02/10/90)
Below is a piece of code used in the recently posted Tetris game.
On our system, (BSD), this produces crap. Namely the last text
output is kept forever in some buffer somewhere and it shows up
in the integer output, ie, 15Press any key.
I made some hacks to it, but I need to know what the library function
_doprnt does or better yet what this function form() does.
Can anyone answer this question for me? Thanks in advance.
char *form (va_alist)
va_dcl
{
va_list pvar;
char *fmt_string;
static char result[LINELEN];
FILE b;
va_start (pvar);
fmt_string = va_arg (pvar, char*);
b._flag = _IOWRT|_IOSTRG;
b._ptr = result;
b._cnt = LINELEN;
---> _doprnt(fmt_string, pvar, &b); <---
putc('\0', &b);
va_end (pvar);
return (result);
}
meissner@osf.org (Michael Meissner) (02/13/90)
In article <1152@psc90.UUCP> pyr201@psc90.UUCP (d^2) writes: | Below is a piece of code used in the recently posted Tetris game. | On our system, (BSD), this produces crap. Namely the last text | output is kept forever in some buffer somewhere and it shows up | in the integer output, ie, 15Press any key. | | I made some hacks to it, but I need to know what the library function | _doprnt does or better yet what this function form() does. | | Can anyone answer this question for me? Thanks in advance. | | char *form (va_alist) | va_dcl | { | va_list pvar; | char *fmt_string; | static char result[LINELEN]; | FILE b; | | va_start (pvar); | fmt_string = va_arg (pvar, char*); | | b._flag = _IOWRT|_IOSTRG; | b._ptr = result; | b._cnt = LINELEN; | | ---> _doprnt(fmt_string, pvar, &b); <--- | | putc('\0', &b); | | va_end (pvar); | return (result); | } The above function basically does sprintf into a static buffer, and returns the result. It sets up the FILE structure in theory so that any excess output will be thrown away, rather than writing randomly past the end of the static array. There is unfortunately no portable means of doing this. Some people suggested 'snprintf', which would be like sprintf, except it would take an extra argument, specifing the buffer size, but the ANSI standard rejected the proposal. One way to deal with this, is to declare a real large buffer, use vsprintf, and hope for the best. Another is to write your own printf clone. If you have vsprintf, the above function would be written: char *form (va_va_alist) va_dcl { va_list pvar; char *fmt_string; static char result[BIG_LINELEN]; va_start (pvar); fmt_string = va_arg (pvar, char *); vsprintf (result, fmt_string, pvar); va_end (pvar); return (result); } If you have ANSI C, it would be written as follows: char *form (char *fmt_string, ...) { va_list pvar; static char result[BIG_LINELEN]; va_start (pvar, fmt_string); vsprintf (result, fmt_string, pvar); va_end (pvar); return (result); } Note for ANSI C, to be fully legal, a prototype of the form: extern char *form (char *, ...); must appear in the scope of any calls to form. -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA Catproof is an oxymoron, Childproof is nearly so