aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKai Großjohann2002-12-09 10:44:25 +0000
committerKai Großjohann2002-12-09 10:44:25 +0000
commitac42d7b99183dc6a2850a1852057b7447ecb148d (patch)
treed702e1735e1226d1c41b5f4bc8a786c540242d5d /src
parent12332637d4e501df29051beb4b1b999319f31cf0 (diff)
downloademacs-ac42d7b99183dc6a2850a1852057b7447ecb148d.tar.gz
emacs-ac42d7b99183dc6a2850a1852057b7447ecb148d.zip
(Fformat): Handle precision in string conversion specifiers like libc
functions do (ie, print at most that many characters). From Matthew Swift <swift@alum.mit.edu>.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog6
-rw-r--r--src/editfns.c82
2 files changed, 70 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e6c8c650880..7d1f0999700 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12002-12-09 Kai Gro,A_(Bjohann <kai.grossjohann@uni-duisburg.de>
2
3 * editfns.c (Fformat): Handle precision in string conversion
4 specifiers like libc functions do (ie, print at most that many
5 characters). From Matthew Swift <swift@alum.mit.edu>.
6
12002-12-08 Richard M. Stallman <rms@gnu.org> 72002-12-08 Richard M. Stallman <rms@gnu.org>
2 8
3 * xdisp.c (row_containing_pos): Check more carefully 9 * xdisp.c (row_containing_pos): Check more carefully
diff --git a/src/editfns.c b/src/editfns.c
index d814f9f857c..8ab359dea96 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3207,6 +3207,12 @@ usage: (format STRING &rest OBJECTS) */)
3207 must consider such a situation or not. */ 3207 must consider such a situation or not. */
3208 int maybe_combine_byte; 3208 int maybe_combine_byte;
3209 unsigned char *this_format; 3209 unsigned char *this_format;
3210 /* Precision for each spec, or -1, a flag value meaning no precision
3211 was given in that spec. Element 0, corresonding to the format
3212 string itself, will not be used. Element NARGS, corresponding to
3213 no argument, *will* be assigned to in the case that a `%' and `.'
3214 occur after the final format specifier. */
3215 int precision[nargs];
3210 int longest_format; 3216 int longest_format;
3211 Lisp_Object val; 3217 Lisp_Object val;
3212 struct info 3218 struct info
@@ -3221,9 +3227,12 @@ usage: (format STRING &rest OBJECTS) */)
3221 This is not always right; sometimes the result needs to be multibyte 3227 This is not always right; sometimes the result needs to be multibyte
3222 because of an object that we will pass through prin1, 3228 because of an object that we will pass through prin1,
3223 and in that case, we won't know it here. */ 3229 and in that case, we won't know it here. */
3224 for (n = 0; n < nargs; n++) 3230 for (n = 0; n < nargs; n++) {
3225 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n])) 3231 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n]))
3226 multibyte = 1; 3232 multibyte = 1;
3233 /* Piggyback on this loop to initialize precision[N]. */
3234 precision[n] = -1;
3235 }
3227 3236
3228 CHECK_STRING (args[0]); 3237 CHECK_STRING (args[0]);
3229 3238
@@ -3247,7 +3256,7 @@ usage: (format STRING &rest OBJECTS) */)
3247 int thissize = 0; 3256 int thissize = 0;
3248 int actual_width = 0; 3257 int actual_width = 0;
3249 unsigned char *this_format_start = format - 1; 3258 unsigned char *this_format_start = format - 1;
3250 int field_width, precision; 3259 int field_width = 0;
3251 3260
3252 /* General format specifications look like 3261 /* General format specifications look like
3253 3262
@@ -3263,12 +3272,17 @@ usage: (format STRING &rest OBJECTS) */)
3263 the output should be padded with blanks, iff the output 3272 the output should be padded with blanks, iff the output
3264 string is shorter than field-width. 3273 string is shorter than field-width.
3265 3274
3266 if precision is specified, it specifies the number of 3275 If precision is specified, it specifies the number of
3267 digits to print after the '.' for floats, or the max. 3276 digits to print after the '.' for floats, or the max.
3268 number of chars to print from a string. */ 3277 number of chars to print from a string. */
3269 3278
3270 precision = field_width = 0; 3279 /* NOTE the handling of specifiers here differs in some ways
3271 3280 from the libc model. There are bugs in this code that lead
3281 to incorrect formatting when flags recognized by C but
3282 neither parsed nor rejected here are used. Further
3283 revisions will be made soon. */
3284
3285 /* incorrect list of flags to skip; will be fixed */
3272 while (index ("-*# 0", *format)) 3286 while (index ("-*# 0", *format))
3273 ++format; 3287 ++format;
3274 3288
@@ -3278,11 +3292,13 @@ usage: (format STRING &rest OBJECTS) */)
3278 field_width = 10 * field_width + *format - '0'; 3292 field_width = 10 * field_width + *format - '0';
3279 } 3293 }
3280 3294
3295 /* N is not incremented for another few lines below, so refer to
3296 element N+1 (which might be precision[NARGS]). */
3281 if (*format == '.') 3297 if (*format == '.')
3282 { 3298 {
3283 ++format; 3299 ++format;
3284 for (precision = 0; *format >= '0' && *format <= '9'; ++format) 3300 for (precision[n+1] = 0; *format >= '0' && *format <= '9'; ++format)
3285 precision = 10 * precision + *format - '0'; 3301 precision[n+1] = 10 * precision[n+1] + *format - '0';
3286 } 3302 }
3287 3303
3288 if (format - this_format_start + 1 > longest_format) 3304 if (format - this_format_start + 1 > longest_format)
@@ -3322,7 +3338,10 @@ usage: (format STRING &rest OBJECTS) */)
3322 string: 3338 string:
3323 if (*format != 's' && *format != 'S') 3339 if (*format != 's' && *format != 'S')
3324 error ("Format specifier doesn't match argument type"); 3340 error ("Format specifier doesn't match argument type");
3325 thissize = CONVERTED_BYTE_SIZE (multibyte, args[n]); 3341 /* In the case (PRECISION[N] > 0), THISSIZE may not need
3342 to be as large as is calculated here. Easy check for
3343 the case PRECISION = 0. */
3344 thissize = precision[n] ? CONVERTED_BYTE_SIZE (multibyte, args[n]) : 0;
3326 actual_width = lisp_string_width (args[n], -1, NULL, NULL); 3345 actual_width = lisp_string_width (args[n], -1, NULL, NULL);
3327 } 3346 }
3328 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */ 3347 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
@@ -3366,7 +3385,10 @@ usage: (format STRING &rest OBJECTS) */)
3366 /* Note that we're using sprintf to print floats, 3385 /* Note that we're using sprintf to print floats,
3367 so we have to take into account what that function 3386 so we have to take into account what that function
3368 prints. */ 3387 prints. */
3369 thissize = MAX_10_EXP + 100 + precision; 3388 /* Filter out flag value of -1. This is a conditional with omitted
3389 operand: the value is PRECISION[N] if the conditional is >=0 and
3390 otherwise is 0. */
3391 thissize = MAX_10_EXP + 100 + (precision[n] > 0 ? : 0);
3370 } 3392 }
3371 else 3393 else
3372 { 3394 {
@@ -3416,10 +3438,14 @@ usage: (format STRING &rest OBJECTS) */)
3416 format++; 3438 format++;
3417 3439
3418 /* Process a numeric arg and skip it. */ 3440 /* Process a numeric arg and skip it. */
3441 /* NOTE atoi is the wrong thing to use here; will be fixed */
3419 minlen = atoi (format); 3442 minlen = atoi (format);
3420 if (minlen < 0) 3443 if (minlen < 0)
3421 minlen = - minlen, negative = 1; 3444 minlen = - minlen, negative = 1;
3422 3445
3446 /* NOTE the parsing here is not consistent with the first
3447 pass, and neither attempt is what we want to do. Will be
3448 fixed. */
3423 while ((*format >= '0' && *format <= '9') 3449 while ((*format >= '0' && *format <= '9')
3424 || *format == '-' || *format == ' ' || *format == '.') 3450 || *format == '-' || *format == ' ' || *format == '.')
3425 format++; 3451 format++;
@@ -3435,8 +3461,28 @@ usage: (format STRING &rest OBJECTS) */)
3435 3461
3436 if (STRINGP (args[n])) 3462 if (STRINGP (args[n]))
3437 { 3463 {
3438 int padding, nbytes, start, end; 3464 /* handle case (precision[n] >= 0) */
3439 int width = lisp_string_width (args[n], -1, NULL, NULL); 3465
3466 int width, padding;
3467 int nbytes, start, end;
3468 int nchars_string;
3469
3470 /* lisp_string_width ignores a precision of 0, but GNU
3471 libc functions print 0 characters when the precision
3472 is 0. Imitate libc behavior here. Changing
3473 lisp_string_width is the right thing, and will be
3474 done, but meanwhile we work with it. */
3475
3476 if (precision[n] == 0)
3477 width = nchars_string = nbytes = 0;
3478 else if (precision[n] > 0)
3479 width = lisp_string_width (args[n], precision[n], &nchars_string, &nbytes);
3480 else
3481 { /* no precision spec given for this argument */
3482 width = lisp_string_width (args[n], -1, NULL, NULL);
3483 nbytes = SBYTES (args[n]);
3484 nchars_string = SCHARS (args[n]);
3485 }
3440 3486
3441 /* If spec requires it, pad on right with spaces. */ 3487 /* If spec requires it, pad on right with spaces. */
3442 padding = minlen - width; 3488 padding = minlen - width;
@@ -3448,19 +3494,19 @@ usage: (format STRING &rest OBJECTS) */)
3448 } 3494 }
3449 3495
3450 start = nchars; 3496 start = nchars;
3451 3497 nchars += nchars_string;
3498 end = nchars;
3499
3452 if (p > buf 3500 if (p > buf
3453 && multibyte 3501 && multibyte
3454 && !ASCII_BYTE_P (*((unsigned char *) p - 1)) 3502 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3455 && STRING_MULTIBYTE (args[n]) 3503 && STRING_MULTIBYTE (args[n])
3456 && !CHAR_HEAD_P (SREF (args[n], 0))) 3504 && !CHAR_HEAD_P (SREF (args[n], 0)))
3457 maybe_combine_byte = 1; 3505 maybe_combine_byte = 1;
3458 nbytes = copy_text (SDATA (args[n]), p, 3506
3459 SBYTES (args[n]), 3507 p += copy_text (SDATA (args[n]), p,
3460 STRING_MULTIBYTE (args[n]), multibyte); 3508 nbytes,
3461 p += nbytes; 3509 STRING_MULTIBYTE (args[n]), multibyte);
3462 nchars += SCHARS (args[n]);
3463 end = nchars;
3464 3510
3465 if (negative) 3511 if (negative)
3466 while (padding-- > 0) 3512 while (padding-- > 0)