Mercurial > emacs
changeset 147:0f50f1badd75
*** empty log message ***
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Wed, 26 Dec 1990 22:28:51 +0000 |
parents | db0041ccc1e6 |
children | a099f0c77321 |
files | src/doprnt.c |
diffstat | 1 files changed, 52 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doprnt.c Tue Dec 25 23:11:33 1990 +0000 +++ b/src/doprnt.c Wed Dec 26 22:28:51 1990 +0000 @@ -23,6 +23,14 @@ #include <stdio.h> #include <ctype.h> +/* Generate output from a format-spec FORMAT, + terminated at position FORMAT_END. + Output goes in BUFFER, which has room for BUFSIZE chars. + If the output does not fit, truncate it to fit. + Returns the number of characters stored into BUFFER. + ARGS points to the vector of arguments, and NARGS says how many. + A double counts as two arguments. */ + doprnt (buffer, bufsize, format, format_end, nargs, args) char *buffer; register int bufsize; @@ -34,7 +42,14 @@ int cnt = 0; /* Number of arg to gobble next */ register char *fmt = format; /* Pointer into format string */ register char *bufptr = buffer; /* Pointer into output buffer.. */ - char tembuf[512]; + /* Use this for sprintf unless we need something really big. */ + char tembuf[100]; + /* Size of sprintf_buffer. */ + int size_allocated = 100; + /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ + char *sprintf_buffer = tembuf; + /* Buffer we have got with malloc. */ + char *big_buffer = 0; register int tem; char *string; char fmtcpy[20]; @@ -50,6 +65,8 @@ { if (*fmt == '%') /* Check for a '%' character */ { + int size_bound; + fmt++; /* Copy this one %-spec into fmtcopy. */ string = fmtcpy; @@ -62,6 +79,18 @@ fmt++; } *string = 0; + /* Get an idea of how much space we might need. */ + size_bound = atoi (&fmtcpy[1]) + 50; + /* Make sure we have that much. */ + if (size_bound > size_allocated) + { + if (big_buffer) + big_buffer = (char *) xrealloc (big_buffer, size_bound); + else + big_buffer = (char *) xmalloc (size_bound); + sprintf_buffer = big_buffer; + size_allocated = size_bound; + } minlen = 0; switch (*fmt++) { @@ -74,11 +103,26 @@ case 'x': if (cnt == nargs) error ("Format string wants too many arguments"); - sprintf (tembuf, fmtcpy, args[cnt++]); - /* Now copy tembuf into final output, truncating as nec. */ - string = tembuf; + sprintf (sprintf_buffer, fmtcpy, args[cnt++]); + /* Now copy into final output, truncating as nec. */ + string = sprintf_buffer; goto doit; + case 'f': + case 'e': + case 'g': + { + union { double d; char *half[2]; } u; + if (cnt + 1 == nargs) + error ("Format string wants too many arguments"); + u.half[0] = args[cnt++]; + u.half[1] = args[cnt++]; + sprintf (sprintf_buffer, fmtcpy, u.d); + /* Now copy into final output, truncating as nec. */ + string = sprintf_buffer; + goto doit; + } + case 'S': string[-1] = 's'; case 's': @@ -132,6 +176,10 @@ bufsize--; }; + /* If we had to malloc something, free it. */ + if (big_buffer) + free (big_buffer); + *bufptr = 0; /* Make sure our string end with a '\0' */ return bufptr - buffer; }