aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-04-30 13:05:43 -0700
committerPaul Eggert2011-04-30 13:05:43 -0700
commitad5f9eeaa2f0f872e063849f8f0d24d2c200acfa (patch)
tree76239a33017e6e08652b9067af7f34c8fe809081 /src
parentb5611f17a7bd64578fc43874a727a8f1081614e9 (diff)
downloademacs-ad5f9eeaa2f0f872e063849f8f0d24d2c200acfa.tar.gz
emacs-ad5f9eeaa2f0f872e063849f8f0d24d2c200acfa.zip
* doprnt.c (doprnt): Support arbitrary pI values, such as "I64".
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog2
-rw-r--r--src/doprnt.c58
2 files changed, 28 insertions, 32 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 310d32a6432..d043bf7f691 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,7 @@
12011-04-30 Paul Eggert <eggert@cs.ucla.edu> 12011-04-30 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * doprnt.c (doprnt): Support arbitrary pI values, such as "I64".
4
3 * dispnew.c (scrolling_window): Return 1 if we scrolled, 5 * dispnew.c (scrolling_window): Return 1 if we scrolled,
4 to match comment at start of function. This also removes a 6 to match comment at start of function. This also removes a
5 GCC warning about overflow in a 32+64-bit port. 7 GCC warning about overflow in a 32+64-bit port.
diff --git a/src/doprnt.c b/src/doprnt.c
index 7b4bd35d5b1..d2abc119912 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -70,9 +70,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
70 %<flags><width><precision><length>character 70 %<flags><width><precision><length>character
71 71
72 where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length 72 where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length
73 is empty or l or ll. Also, %% in a format stands for a single % in the 73 is empty or l or the value of the pI macro. Also, %% in a format
74 output. A % that does not introduce a valid %-sequence causes 74 stands for a single % in the output. A % that does not introduce a
75 undefined behavior. 75 valid %-sequence causes undefined behavior.
76 76
77 The + flag character inserts a + before any positive number, while a space 77 The + flag character inserts a + before any positive number, while a space
78 inserts a space before any positive number; these flags only affect %d, %o, 78 inserts a space before any positive number; these flags only affect %d, %o,
@@ -85,11 +85,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
85 modifier: it is supported for %d, %o, and %x conversions of integral 85 modifier: it is supported for %d, %o, and %x conversions of integral
86 arguments, must immediately precede the conversion specifier, and means that 86 arguments, must immediately precede the conversion specifier, and means that
87 the respective argument is to be treated as `long int' or `unsigned long 87 the respective argument is to be treated as `long int' or `unsigned long
88 int'. Similarly, ll (two letter ells) means to use `long long int' or 88 int'. Similarly, the value of the pI macro means to use EMACS_INT or
89 `unsigned long long int'; this can be used only on hosts that have 89 EMACS_UINT and the empty length modifier means `int' or `unsigned int'.
90 these two types. The empty length modifier means to use `int' or
91 `unsigned int'. EMACS_INT arguments should use the pI macro, which
92 expands to whatever length modifier is needed for the target host.
93 90
94 The width specifier supplies a lower limit for the length of the printed 91 The width specifier supplies a lower limit for the length of the printed
95 representation. The padding, if any, normally goes on the left, but it goes 92 representation. The padding, if any, normally goes on the left, but it goes
@@ -186,6 +183,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
186 size_t size_bound = 0; 183 size_t size_bound = 0;
187 EMACS_INT width; /* Columns occupied by STRING on display. */ 184 EMACS_INT width; /* Columns occupied by STRING on display. */
188 int long_flag = 0; 185 int long_flag = 0;
186 int pIlen = sizeof pI - 1;
189 187
190 fmt++; 188 fmt++;
191 /* Copy this one %-spec into fmtcpy. */ 189 /* Copy this one %-spec into fmtcpy. */
@@ -201,7 +199,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
201 %1.1000f and %1000.1f both might need 1000+ bytes. 199 %1.1000f and %1000.1f both might need 1000+ bytes.
202 Parse the width or precision, checking for overflow. */ 200 Parse the width or precision, checking for overflow. */
203 size_t n = *fmt - '0'; 201 size_t n = *fmt - '0';
204 while (fmt < format_end 202 while (fmt + 1 < format_end
205 && '0' <= fmt[1] && fmt[1] <= '9') 203 && '0' <= fmt[1] && fmt[1] <= '9')
206 { 204 {
207 /* Avoid size_t overflow. Avoid int overflow too, as 205 /* Avoid size_t overflow. Avoid int overflow too, as
@@ -218,20 +216,25 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
218 if (size_bound < n) 216 if (size_bound < n)
219 size_bound = n; 217 size_bound = n;
220 } 218 }
221 else if (*fmt == '-' || *fmt == ' ' || *fmt == '.' || *fmt == '+') 219 else if (! (*fmt == '-' || *fmt == ' ' || *fmt == '.'
222 ; 220 || *fmt == '+'))
223 else if (*fmt == 'l')
224 {
225 long_flag = 1 + (fmt + 1 < format_end && fmt[1] == 'l');
226 fmt += long_flag;
227 break;
228 }
229 else
230 break; 221 break;
231 fmt++; 222 fmt++;
232 } 223 }
233 if (fmt > format_end) 224
234 fmt = format_end; 225 if (0 < pIlen && pIlen <= format_end - fmt
226 && memcmp (fmt, pI, pIlen) == 0)
227 {
228 long_flag = 2;
229 memcpy (string, fmt + 1, pIlen);
230 string += pIlen;
231 fmt += pIlen;
232 }
233 else if (fmt < format_end && *fmt == 'l')
234 {
235 long_flag = 1;
236 *string++ = *++fmt;
237 }
235 *string = 0; 238 *string = 0;
236 239
237 /* Make the size bound large enough to handle floating point formats 240 /* Make the size bound large enough to handle floating point formats
@@ -253,8 +256,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
253 switch (*fmt++) 256 switch (*fmt++)
254 { 257 {
255 default: 258 default:
256 error ("Invalid format operation %%%s%c", 259 error ("Invalid format operation %s", fmtcpy);
257 "ll" + 2 - long_flag, fmt[-1]);
258 260
259/* case 'b': */ 261/* case 'b': */
260 case 'l': 262 case 'l':
@@ -265,12 +267,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
265 267
266 if (1 < long_flag) 268 if (1 < long_flag)
267 { 269 {
268#ifdef HAVE_LONG_LONG_INT 270 EMACS_INT ll = va_arg (ap, EMACS_INT);
269 long long ll = va_arg (ap, long long);
270 sprintf (sprintf_buffer, fmtcpy, ll); 271 sprintf (sprintf_buffer, fmtcpy, ll);
271#else
272 error ("Invalid format operation %%ll%c", fmt[-1]);
273#endif
274 } 272 }
275 else if (long_flag) 273 else if (long_flag)
276 { 274 {
@@ -295,12 +293,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
295 293
296 if (1 < long_flag) 294 if (1 < long_flag)
297 { 295 {
298#ifdef HAVE_UNSIGNED_LONG_LONG_INT 296 EMACS_UINT ull = va_arg (ap, EMACS_UINT);
299 unsigned long long ull = va_arg (ap, unsigned long long);
300 sprintf (sprintf_buffer, fmtcpy, ull); 297 sprintf (sprintf_buffer, fmtcpy, ull);
301#else
302 error ("Invalid format operation %%ll%c", fmt[-1]);
303#endif
304 } 298 }
305 else if (long_flag) 299 else if (long_flag)
306 { 300 {