[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug] `format' with a partially propertized format stringdoesn't wor
From: |
Richard Stallman |
Subject: |
Re: [Bug] `format' with a partially propertized format stringdoesn't work |
Date: |
Tue, 08 Apr 2003 02:46:26 -0400 |
If the format string is not propertized completely, it doesn't:
(let ((s "x: %s, y"))
(set-text-properties 3 5 '(face bold) s)
(format s "123456"))
=> #("x: 123456, y" 0 3 nil 3 5 (face bold) 5 12 nil)
(format (concat "x: " (propertize "%s" 'face 'bold) ", y") "123456")
=> #("x: 123456, y" 0 3 nil 3 5 (face bold) 5 12 nil)
The code never tried to handle that. I implemented it.
Thanks.
*** editfns.c.~1.353.~ Fri Apr 4 16:11:53 2003
--- editfns.c Tue Apr 8 02:36:13 2003
***************
*** 3220,3228 ****
int *precision = (int *) (alloca(nargs * sizeof (int)));
int longest_format;
Lisp_Object val;
struct info
{
! int start, end;
} *info = 0;
/* It should not be necessary to GCPRO ARGS, because
--- 3220,3233 ----
int *precision = (int *) (alloca(nargs * sizeof (int)));
int longest_format;
Lisp_Object val;
+ int arg_intervals = 0;
+
+ /* Each element records, for one argument,
+ the start and end charpos in the output string,
+ and the length of the spec that applied to it. */
struct info
{
! int start, end, speclen, intervals;
} *info = 0;
/* It should not be necessary to GCPRO ARGS, because
***************
*** 3254,3259 ****
--- 3259,3271 ----
/* Make room in result for all the non-%-codes in the control string. */
total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]);
+ /* Allocate the INFO table. */
+ {
+ int nbytes = nargs * sizeof *info;
+ info = (struct info *) alloca (nbytes);
+ bzero (info, nbytes);
+ }
+
/* Add to TOTAL enough space to hold the converted arguments. */
n = 0;
***************
*** 3482,3487 ****
--- 3494,3501 ----
++n;
+ info[n].start = p - buf;
+
if (STRINGP (args[n]))
{
/* handle case (precision[n] >= 0) */
***************
*** 3541,3557 ****
/* If this argument has text properties, record where
in the result string it appears. */
if (STRING_INTERVALS (args[n]))
! {
! if (!info)
! {
! int nbytes = nargs * sizeof *info;
! info = (struct info *) alloca (nbytes);
! bzero (info, nbytes);
! }
!
! info[n].start = start;
! info[n].end = end;
! }
}
else if (INTEGERP (args[n]) || FLOATP (args[n]))
{
--- 3555,3561 ----
/* If this argument has text properties, record where
in the result string it appears. */
if (STRING_INTERVALS (args[n]))
! info[n].intervals = arg_intervals = 1;
}
else if (INTEGERP (args[n]) || FLOATP (args[n]))
{
***************
*** 3578,3583 ****
--- 3582,3590 ----
p += this_nchars;
nchars += this_nchars;
}
+
+ info[n].end = p - buf;
+ info[n].speclen = format - this_format_start;
}
else if (STRING_MULTIBYTE (args[0]))
{
***************
*** 3619,3625 ****
arguments has text properties, set up text properties of the
result string. */
! if (STRING_INTERVALS (args[0]) || info)
{
Lisp_Object len, new_len, props;
struct gcpro gcpro1;
--- 3626,3632 ----
arguments has text properties, set up text properties of the
result string. */
! if (STRING_INTERVALS (args[0]) || arg_intervals)
{
Lisp_Object len, new_len, props;
struct gcpro gcpro1;
***************
*** 3631,3645 ****
if (CONSP (props))
{
! new_len = make_number (SCHARS (val));
! extend_property_ranges (props, len, new_len);
add_text_properties_from_list (val, props, make_number (0));
}
/* Add text properties from arguments. */
! if (info)
for (n = 1; n < nargs; ++n)
! if (info[n].end)
{
len = make_number (SCHARS (args[n]));
new_len = make_number (info[n].end - info[n].start);
--- 3638,3677 ----
if (CONSP (props))
{
! Lisp_Object list;
! /* Adjust the bounds of each text property
! to the proper start and end in the output string. */
! for (list = props; CONSP (list); list = XCDR (list))
! {
! Lisp_Object item;
! int i, pos;
!
! item = XCAR (list);
!
! pos = XINT (XCAR (item));
!
! for (i = 0; i < nargs; i++)
! if (pos > info[i].start)
! pos += info[i].end - info[i].start - info[i].speclen;
!
! XSETCAR (item, make_number (pos));
!
! pos = XINT (XCAR (XCDR (item)));
!
! for (i = 0; i < nargs; i++)
! if (pos > info[i].start)
! pos += info[i].end - info[i].start - info[i].speclen;
!
! XSETCAR (XCDR (item), make_number (pos));
! }
!
add_text_properties_from_list (val, props, make_number (0));
}
/* Add text properties from arguments. */
! if (arg_intervals)
for (n = 1; n < nargs; ++n)
! if (info[n].intervals)
{
len = make_number (SCHARS (args[n]));
new_len = make_number (info[n].end - info[n].start);