diff options
| author | Richard M. Stallman | 1990-12-26 22:28:51 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1990-12-26 22:28:51 +0000 |
| commit | f4c730d34eff80253fe45c454f460a9efc0267a8 (patch) | |
| tree | 9f5dfe10e02a823389f7efe4a12d7629115923ba | |
| parent | 7942b8aeb70be250a05fd2ff793c0c402bbb67d0 (diff) | |
| download | emacs-f4c730d34eff80253fe45c454f460a9efc0267a8.tar.gz emacs-f4c730d34eff80253fe45c454f460a9efc0267a8.zip | |
*** empty log message ***
| -rw-r--r-- | src/doprnt.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/src/doprnt.c b/src/doprnt.c index 8a7a68c2f0b..731afe400cc 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -23,6 +23,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 23 | #include <stdio.h> | 23 | #include <stdio.h> |
| 24 | #include <ctype.h> | 24 | #include <ctype.h> |
| 25 | 25 | ||
| 26 | /* Generate output from a format-spec FORMAT, | ||
| 27 | terminated at position FORMAT_END. | ||
| 28 | Output goes in BUFFER, which has room for BUFSIZE chars. | ||
| 29 | If the output does not fit, truncate it to fit. | ||
| 30 | Returns the number of characters stored into BUFFER. | ||
| 31 | ARGS points to the vector of arguments, and NARGS says how many. | ||
| 32 | A double counts as two arguments. */ | ||
| 33 | |||
| 26 | doprnt (buffer, bufsize, format, format_end, nargs, args) | 34 | doprnt (buffer, bufsize, format, format_end, nargs, args) |
| 27 | char *buffer; | 35 | char *buffer; |
| 28 | register int bufsize; | 36 | register int bufsize; |
| @@ -34,7 +42,14 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 34 | int cnt = 0; /* Number of arg to gobble next */ | 42 | int cnt = 0; /* Number of arg to gobble next */ |
| 35 | register char *fmt = format; /* Pointer into format string */ | 43 | register char *fmt = format; /* Pointer into format string */ |
| 36 | register char *bufptr = buffer; /* Pointer into output buffer.. */ | 44 | register char *bufptr = buffer; /* Pointer into output buffer.. */ |
| 37 | char tembuf[512]; | 45 | /* Use this for sprintf unless we need something really big. */ |
| 46 | char tembuf[100]; | ||
| 47 | /* Size of sprintf_buffer. */ | ||
| 48 | int size_allocated = 100; | ||
| 49 | /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */ | ||
| 50 | char *sprintf_buffer = tembuf; | ||
| 51 | /* Buffer we have got with malloc. */ | ||
| 52 | char *big_buffer = 0; | ||
| 38 | register int tem; | 53 | register int tem; |
| 39 | char *string; | 54 | char *string; |
| 40 | char fmtcpy[20]; | 55 | char fmtcpy[20]; |
| @@ -50,6 +65,8 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 50 | { | 65 | { |
| 51 | if (*fmt == '%') /* Check for a '%' character */ | 66 | if (*fmt == '%') /* Check for a '%' character */ |
| 52 | { | 67 | { |
| 68 | int size_bound; | ||
| 69 | |||
| 53 | fmt++; | 70 | fmt++; |
| 54 | /* Copy this one %-spec into fmtcopy. */ | 71 | /* Copy this one %-spec into fmtcopy. */ |
| 55 | string = fmtcpy; | 72 | string = fmtcpy; |
| @@ -62,6 +79,18 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 62 | fmt++; | 79 | fmt++; |
| 63 | } | 80 | } |
| 64 | *string = 0; | 81 | *string = 0; |
| 82 | /* Get an idea of how much space we might need. */ | ||
| 83 | size_bound = atoi (&fmtcpy[1]) + 50; | ||
| 84 | /* Make sure we have that much. */ | ||
| 85 | if (size_bound > size_allocated) | ||
| 86 | { | ||
| 87 | if (big_buffer) | ||
| 88 | big_buffer = (char *) xrealloc (big_buffer, size_bound); | ||
| 89 | else | ||
| 90 | big_buffer = (char *) xmalloc (size_bound); | ||
| 91 | sprintf_buffer = big_buffer; | ||
| 92 | size_allocated = size_bound; | ||
| 93 | } | ||
| 65 | minlen = 0; | 94 | minlen = 0; |
| 66 | switch (*fmt++) | 95 | switch (*fmt++) |
| 67 | { | 96 | { |
| @@ -74,11 +103,26 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 74 | case 'x': | 103 | case 'x': |
| 75 | if (cnt == nargs) | 104 | if (cnt == nargs) |
| 76 | error ("Format string wants too many arguments"); | 105 | error ("Format string wants too many arguments"); |
| 77 | sprintf (tembuf, fmtcpy, args[cnt++]); | 106 | sprintf (sprintf_buffer, fmtcpy, args[cnt++]); |
| 78 | /* Now copy tembuf into final output, truncating as nec. */ | 107 | /* Now copy into final output, truncating as nec. */ |
| 79 | string = tembuf; | 108 | string = sprintf_buffer; |
| 80 | goto doit; | 109 | goto doit; |
| 81 | 110 | ||
| 111 | case 'f': | ||
| 112 | case 'e': | ||
| 113 | case 'g': | ||
| 114 | { | ||
| 115 | union { double d; char *half[2]; } u; | ||
| 116 | if (cnt + 1 == nargs) | ||
| 117 | error ("Format string wants too many arguments"); | ||
| 118 | u.half[0] = args[cnt++]; | ||
| 119 | u.half[1] = args[cnt++]; | ||
| 120 | sprintf (sprintf_buffer, fmtcpy, u.d); | ||
| 121 | /* Now copy into final output, truncating as nec. */ | ||
| 122 | string = sprintf_buffer; | ||
| 123 | goto doit; | ||
| 124 | } | ||
| 125 | |||
| 82 | case 'S': | 126 | case 'S': |
| 83 | string[-1] = 's'; | 127 | string[-1] = 's'; |
| 84 | case 's': | 128 | case 's': |
| @@ -132,6 +176,10 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 132 | bufsize--; | 176 | bufsize--; |
| 133 | }; | 177 | }; |
| 134 | 178 | ||
| 179 | /* If we had to malloc something, free it. */ | ||
| 180 | if (big_buffer) | ||
| 181 | free (big_buffer); | ||
| 182 | |||
| 135 | *bufptr = 0; /* Make sure our string end with a '\0' */ | 183 | *bufptr = 0; /* Make sure our string end with a '\0' */ |
| 136 | return bufptr - buffer; | 184 | return bufptr - buffer; |
| 137 | } | 185 | } |