aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-04-25 11:04:22 +0300
committerEli Zaretskii2011-04-25 11:04:22 +0300
commit825cd63ca98121d602b4a8dcffa55d29841224a0 (patch)
tree0ecfbd1149dd944fb7b77132ef8ef0c6201d9180 /src
parente2822bd2ea32c577342b9618a301f8661551f7a3 (diff)
downloademacs-825cd63ca98121d602b4a8dcffa55d29841224a0.tar.gz
emacs-825cd63ca98121d602b4a8dcffa55d29841224a0.zip
Improve doprnt and its use in verror. (Bug#8545)
src/doprnt.c (doprnt): Document the set of format control sequences supported by the function. Use SAFE_ALLOCA instead of always using `alloca'. src/eval.c (verror): Don't limit the buffer size at size_max-1, that is one byte too soon. Don't use xrealloc; instead xfree and xmalloc anew.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/doprnt.c62
-rw-r--r--src/eval.c11
3 files changed, 70 insertions, 14 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 410a3b15ffb..cd03d1fa186 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12011-04-25 Eli Zaretskii <eliz@gnu.org>
2
3 Improve doprnt and its use in verror. (Bug#8545)
4 * doprnt.c (doprnt): Document the set of format control sequences
5 supported by the function. Use SAFE_ALLOCA instead of always
6 using `alloca'.
7
8 * eval.c (verror): Don't limit the buffer size at size_max-1, that
9 is one byte too soon. Don't use xrealloc; instead xfree and
10 xmalloc anew.
11
12011-04-24 Teodor Zlatanov <tzz@lifelogs.com> 122011-04-24 Teodor Zlatanov <tzz@lifelogs.com>
2 13
3 * gnutls.h: Add GNUTLS_STAGE_CALLBACKS enum to denote we're in the 14 * gnutls.h: Add GNUTLS_STAGE_CALLBACKS enum to denote we're in the
diff --git a/src/doprnt.c b/src/doprnt.c
index f124db13221..3ac1d9963a9 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -43,10 +43,54 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
43 43
44 OTOH, this function supports only a small subset of the standard C formatted 44 OTOH, this function supports only a small subset of the standard C formatted
45 output facilities. E.g., %u and %ll are not supported, and precision is 45 output facilities. E.g., %u and %ll are not supported, and precision is
46 largely ignored except for converting floating-point values. However, this 46 ignored %s and %c conversions. (See below for the detailed documentation of
47 is okay, as this function is supposed to be called from `error' and similar 47 what is supported.) However, this is okay, as this function is supposed to
48 functions, and thus does not need to support features beyond those in 48 be called from `error' and similar functions, and thus does not need to
49 `Fformat', which is used by `error' on the Lisp level. */ 49 support features beyond those in `Fformat', which is used by `error' on the
50 Lisp level. */
51
52/* This function supports the following %-sequences in the `format'
53 argument:
54
55 %s means print a string argument.
56 %S is silently treated as %s, for loose compatibility with `Fformat'.
57 %d means print a `signed int' argument in decimal.
58 %l means print a `long int' argument in decimal.
59 %o means print an `unsigned int' argument in octal.
60 %x means print an `unsigned int' argument in hex.
61 %e means print a `double' argument in exponential notation.
62 %f means print a `double' argument in decimal-point notation.
63 %g means print a `double' argument in exponential notation
64 or in decimal-point notation, whichever uses fewer characters.
65 %c means print a `signed int' argument as a single character.
66 %% means produce a literal % character.
67
68 A %-sequence may contain optional flag, width, and precision specifiers, as
69 follows:
70
71 %<flags><width><precision>character
72
73 where flags is [+ -0l], width is [0-9]+, and precision is .[0-9]+
74
75 The + flag character inserts a + before any positive number, while a space
76 inserts a space before any positive number; these flags only affect %d, %l,
77 %o, %x, %e, %f, and %g sequences. The - and 0 flags affect the width
78 specifier, as described below.
79
80 The l (lower-case letter ell) flag is a `long' data type modifier: it is
81 supported for %d, %o, and %x conversions of integral arguments, and means
82 that the respective argument is to be treated as `long int' or `unsigned
83 long int'. The EMACS_INT data type should use this modifier.
84
85 The width specifier supplies a lower limit for the length of the printed
86 representation. The padding, if any, normally goes on the left, but it goes
87 on the right if the - flag is present. The padding character is normally a
88 space, but (for numerical arguments only) it is 0 if the 0 flag is present.
89 The - flag takes precedence over the 0 flag.
90
91 For %e, %f, and %g sequences, the number after the "." in the precision
92 specifier says how many decimal places to show; if zero, the decimal point
93 itself is omitted. For %s and %S, the precision specifier is ignored. */
50 94
51#include <config.h> 95#include <config.h>
52#include <stdio.h> 96#include <stdio.h>
@@ -79,9 +123,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
79 terminated at position FORMAT_END. 123 terminated at position FORMAT_END.
80 Output goes in BUFFER, which has room for BUFSIZE chars. 124 Output goes in BUFFER, which has room for BUFSIZE chars.
81 If the output does not fit, truncate it to fit. 125 If the output does not fit, truncate it to fit.
82 Returns the number of bytes stored into BUFFER. 126 Returns the number of bytes stored into BUFFER, excluding
83 ARGS points to the vector of arguments, and NARGS says how many. 127 the terminating null byte. Output is always null-terminated.
84 A double counts as two arguments.
85 String arguments are passed as C strings. 128 String arguments are passed as C strings.
86 Integers are passed as C integers. */ 129 Integers are passed as C integers. */
87 130
@@ -110,6 +153,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
110 char *fmtcpy; 153 char *fmtcpy;
111 int minlen; 154 int minlen;
112 char charbuf[MAX_MULTIBYTE_LENGTH + 1]; /* Used for %c. */ 155 char charbuf[MAX_MULTIBYTE_LENGTH + 1]; /* Used for %c. */
156 USE_SAFE_ALLOCA;
113 157
114 if (format_end == 0) 158 if (format_end == 0)
115 format_end = format + strlen (format); 159 format_end = format + strlen (format);
@@ -117,7 +161,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
117 if ((format_end - format + 1) < sizeof (fixed_buffer)) 161 if ((format_end - format + 1) < sizeof (fixed_buffer))
118 fmtcpy = fixed_buffer; 162 fmtcpy = fixed_buffer;
119 else 163 else
120 fmtcpy = (char *) alloca (format_end - format + 1); 164 SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
121 165
122 bufsize--; 166 bufsize--;
123 167
@@ -342,5 +386,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
342 xfree (big_buffer); 386 xfree (big_buffer);
343 387
344 *bufptr = 0; /* Make sure our string ends with a '\0' */ 388 *bufptr = 0; /* Make sure our string ends with a '\0' */
389
390 SAFE_FREE ();
345 return bufptr - buffer; 391 return bufptr - buffer;
346} 392}
diff --git a/src/eval.c b/src/eval.c
index c3676720940..d1f327021e6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2012,15 +2012,14 @@ verror (const char *m, va_list ap)
2012 break; 2012 break;
2013 if (size <= size_max / 2) 2013 if (size <= size_max / 2)
2014 size *= 2; 2014 size *= 2;
2015 else if (size < size_max - 1) 2015 else if (size < size_max)
2016 size = size_max - 1; 2016 size = size_max;
2017 else 2017 else
2018 break; /* and leave the message truncated */ 2018 break; /* and leave the message truncated */
2019 2019
2020 if (buffer == buf) 2020 if (buffer != buf)
2021 buffer = (char *) xmalloc (size); 2021 xfree (buffer);
2022 else 2022 buffer = (char *) xmalloc (size);
2023 buffer = (char *) xrealloc (buffer, size);
2024 } 2023 }
2025 2024
2026 string = make_string (buffer, used); 2025 string = make_string (buffer, used);