unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [Bug] `format' with a partially propertized format string doesn't work
@ 2003-04-07 17:27 Wedler, Christoph
  2003-04-08  6:46 ` [Bug] `format' with a partially propertized format stringdoesn't work Richard Stallman
  0 siblings, 1 reply; 2+ messages in thread
From: Wedler, Christoph @ 2003-04-07 17:27 UTC (permalink / raw)


[Test using Emacs-21.2.95.1.]

If you propertize a format string completely, `format' works as
expected:

    (format (propertize "x: %s, y" 'face 'bold) "123456")
    => #("x: 123456, y" 0 12 (face bold))

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)

- Christoph

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Bug] `format' with a partially propertized format stringdoesn't work
  2003-04-07 17:27 [Bug] `format' with a partially propertized format string doesn't work Wedler, Christoph
@ 2003-04-08  6:46 ` Richard Stallman
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Stallman @ 2003-04-08  6:46 UTC (permalink / raw)
  Cc: emacs-devel

    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);

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-04-08  6:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-07 17:27 [Bug] `format' with a partially propertized format string doesn't work Wedler, Christoph
2003-04-08  6:46 ` [Bug] `format' with a partially propertized format stringdoesn't work Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).