]> code.delx.au - gnu-emacs/blobdiff - src/editfns.c
Fix 'transpose-regions' when LEAVE-MARKERS arg is non-nil
[gnu-emacs] / src / editfns.c
index e267c2f2909afa83b5680c4a7d4d3033a90dd1f8..aed884ebe1c40d7b339eb9118d7b23c05e48f5d8 100644 (file)
@@ -216,6 +216,7 @@ tzlookup (Lisp_Object zone, bool settz)
     {
       block_input ();
       emacs_setenv_TZ (zone_string);
     {
       block_input ();
       emacs_setenv_TZ (zone_string);
+      tzset ();
       timezone_t old_tz = local_tz;
       local_tz = new_tz;
       tzfree (old_tz);
       timezone_t old_tz = local_tz;
       local_tz = new_tz;
       tzfree (old_tz);
@@ -2176,17 +2177,16 @@ usage: (decode-time &optional TIME ZONE)  */)
 }
 
 /* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
 }
 
 /* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
-   the result is representable as an int.  Assume OFFSET is small and
-   nonnegative.  */
+   the result is representable as an int.  */
 static int
 check_tm_member (Lisp_Object obj, int offset)
 {
 static int
 check_tm_member (Lisp_Object obj, int offset)
 {
-  EMACS_INT n;
   CHECK_NUMBER (obj);
   CHECK_NUMBER (obj);
-  n = XINT (obj);
-  if (! (INT_MIN + offset <= n && n - offset <= INT_MAX))
+  EMACS_INT n = XINT (obj);
+  int result;
+  if (INT_SUBTRACT_WRAPV (n, offset, &result))
     time_overflow ();
     time_overflow ();
-  return n - offset;
+  return result;
 }
 
 DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
 }
 
 DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
@@ -2459,23 +2459,24 @@ emacs_setenv_TZ (const char *tzstring)
       tzval[tzeqlen] = 0;
     }
 
       tzval[tzeqlen] = 0;
     }
 
-  if (new_tzvalbuf
-#ifdef WINDOWSNT
-      /* MS-Windows implementation of 'putenv' copies the argument
-        string into a block it allocates, so modifying tzval string
-        does not change the environment.  OTOH, the other threads run
-        by Emacs on MS-Windows never call 'xputenv' or 'putenv' or
-        'unsetenv', so the original cause for the dicey in-place
-        modification technique doesn't exist there in the first
-        place.  */
-      || 1
+
+#ifndef WINDOWSNT
+  /* Modifying *TZVAL merely requires calling tzset (which is the
+     caller's responsibility).  However, modifying TZVAL requires
+     calling putenv; although this is not thread-safe, in practice this
+     runs only on startup when there is only one thread.  */
+  bool need_putenv = new_tzvalbuf;
+#else
+  /* MS-Windows 'putenv' copies the argument string into a block it
+     allocates, so modifying *TZVAL will not change the environment.
+     However, the other threads run by Emacs on MS-Windows never call
+     'xputenv' or 'putenv' or 'unsetenv', so the original cause for the
+     dicey in-place modification technique doesn't exist there in the
+     first place.  */
+  bool need_putenv = true;
 #endif
 #endif
-      )
-    {
-      /* Although this is not thread-safe, in practice this runs only
-        on startup when there is only one thread.  */
-      xputenv (tzval);
-    }
+  if (need_putenv)
+    xputenv (tzval);
 
   return 0;
 }
 
   return 0;
 }
@@ -2535,7 +2536,7 @@ insert1 (Lisp_Object arg)
 
 DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
        doc: /* Insert the arguments, either strings or characters, at point.
 
 DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
        doc: /* Insert the arguments, either strings or characters, at point.
-Point and before-insertion markers move forward to end up
+Point and after-insertion markers move forward to end up
  after the inserted text.
 Any other markers at the point of insertion remain before the text.
 
  after the inserted text.
 Any other markers at the point of insertion remain before the text.
 
@@ -2559,7 +2560,7 @@ usage: (insert &rest ARGS)  */)
 DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
    0, MANY, 0,
        doc: /* Insert the arguments at point, inheriting properties from adjoining text.
 DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
    0, MANY, 0,
        doc: /* Insert the arguments at point, inheriting properties from adjoining text.
-Point and before-insertion markers move forward to end up
+Point and after-insertion markers move forward to end up
  after the inserted text.
 Any other markers at the point of insertion remain before the text.
 
  after the inserted text.
 Any other markers at the point of insertion remain before the text.
 
@@ -3363,7 +3364,7 @@ It returns the number of characters changed.  */)
   ptrdiff_t size;              /* Size of translate table. */
   ptrdiff_t pos, pos_byte, end_pos;
   bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
   ptrdiff_t size;              /* Size of translate table. */
   ptrdiff_t pos, pos_byte, end_pos;
   bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
-  bool string_multibyte IF_LINT (= 0);
+  bool string_multibyte UNINIT;
 
   validate_region (&start, &end);
   if (CHAR_TABLE_P (table))
 
   validate_region (&start, &end);
   if (CHAR_TABLE_P (table))
@@ -3716,10 +3717,11 @@ In batch mode, the message is printed to the standard error stream,
 followed by a newline.
 
 The first argument is a format control string, and the rest are data
 followed by a newline.
 
 The first argument is a format control string, and the rest are data
-to be formatted under control of the string.  See `format' for details.
+to be formatted under control of the string.  See `format-message' for
+details.
 
 
-Note: Use (message "%s" VALUE) to print the value of expressions and
-variables to avoid accidentally interpreting `%' as format specifiers.
+Note: (message "%s" VALUE) displays the string VALUE without
+interpreting format characters like `%', `\\=`', and `\\=''.
 
 If the first argument is nil or the empty string, the function clears
 any existing message; this lets the minibuffer contents show.  See
 
 If the first argument is nil or the empty string, the function clears
 any existing message; this lets the minibuffer contents show.  See
@@ -3747,7 +3749,8 @@ DEFUN ("message-box", Fmessage_box, Smessage_box, 1, MANY, 0,
        doc: /* Display a message, in a dialog box if possible.
 If a dialog box is not available, use the echo area.
 The first argument is a format control string, and the rest are data
        doc: /* Display a message, in a dialog box if possible.
 If a dialog box is not available, use the echo area.
 The first argument is a format control string, and the rest are data
-to be formatted under control of the string.  See `format' for details.
+to be formatted under control of the string.  See `format-message' for
+details.
 
 If the first argument is nil or the empty string, clear any existing
 message; let the minibuffer contents show.
 
 If the first argument is nil or the empty string, clear any existing
 message; let the minibuffer contents show.
@@ -3778,7 +3781,8 @@ If this command was invoked with the mouse, use a dialog box if
 `use-dialog-box' is non-nil.
 Otherwise, use the echo area.
 The first argument is a format control string, and the rest are data
 `use-dialog-box' is non-nil.
 Otherwise, use the echo area.
 The first argument is a format control string, and the rest are data
-to be formatted under control of the string.  See `format' for details.
+to be formatted under control of the string.  See `format-message' for
+details.
 
 If the first argument is nil or the empty string, clear any existing
 message; let the minibuffer contents show.
 
 If the first argument is nil or the empty string, clear any existing
 message; let the minibuffer contents show.
@@ -3881,6 +3885,9 @@ precision specifier says how many decimal places to show; if zero, the
 decimal point itself is omitted.  For %s and %S, the precision
 specifier truncates the string to the given width.
 
 decimal point itself is omitted.  For %s and %S, the precision
 specifier truncates the string to the given width.
 
+Text properties, if any, are copied from the format-string to the
+produced text.
+
 usage: (format STRING &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
 usage: (format STRING &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
@@ -3915,7 +3922,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
   ptrdiff_t bufsize = sizeof initial_buffer;
   ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1;
   char *p;
   ptrdiff_t bufsize = sizeof initial_buffer;
   ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1;
   char *p;
-  ptrdiff_t buf_save_value_index IF_LINT (= 0);
+  ptrdiff_t buf_save_value_index UNINIT;
   char *format, *end;
   ptrdiff_t nchars;
   /* When we make a multibyte string, we must pay attention to the
   char *format, *end;
   ptrdiff_t nchars;
   /* When we make a multibyte string, we must pay attention to the
@@ -4174,6 +4181,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                      p += padding;
                      nchars += padding;
                    }
                      p += padding;
                      nchars += padding;
                    }
+                  info[n].start = nchars;
 
                  if (p > buf
                      && multibyte
 
                  if (p > buf
                      && multibyte
@@ -4186,9 +4194,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                                  nbytes,
                                  STRING_MULTIBYTE (args[n]), multibyte);
 
                                  nbytes,
                                  STRING_MULTIBYTE (args[n]), multibyte);
 
-                  info[n].start = nchars;
                  nchars += nchars_string;
                  nchars += nchars_string;
-                 info[n].end = nchars;
 
                  if (minus_flag)
                    {
 
                  if (minus_flag)
                    {
@@ -4196,6 +4202,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                      p += padding;
                      nchars += padding;
                    }
                      p += padding;
                      nchars += padding;
                    }
+                 info[n].end = nchars;
 
                  /* If this argument has text properties, record where
                     in the result string it appears.  */
 
                  /* If this argument has text properties, record where
                     in the result string it appears.  */
@@ -4413,6 +4420,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                        exponent_bytes = src + sprintf_bytes - e;
                    }
 
                        exponent_bytes = src + sprintf_bytes - e;
                    }
 
+                  info[n].start = nchars;
                  if (! minus_flag)
                    {
                      memset (p, ' ', padding);
                  if (! minus_flag)
                    {
                      memset (p, ' ', padding);
@@ -4435,9 +4443,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                  memcpy (p, src, exponent_bytes);
                  p += exponent_bytes;
 
                  memcpy (p, src, exponent_bytes);
                  p += exponent_bytes;
 
-                  info[n].start = nchars;
                  nchars += leading_zeros + sprintf_bytes + trailing_zeros;
                  nchars += leading_zeros + sprintf_bytes + trailing_zeros;
-                 info[n].end = nchars;
 
                  if (minus_flag)
                    {
 
                  if (minus_flag)
                    {
@@ -4445,6 +4451,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                      p += padding;
                      nchars += padding;
                    }
                      p += padding;
                      nchars += padding;
                    }
+                 info[n].end = nchars;
 
                  continue;
                }
 
                  continue;
                }
@@ -4452,14 +4459,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
        }
       else
        {
        }
       else
        {
-         /* Named constants for the UTF-8 encodings of U+2018 LEFT SINGLE
-            QUOTATION MARK and U+2019 RIGHT SINGLE QUOTATION MARK.  */
-         enum
-         {
-           uLSQM0 = 0xE2, uLSQM1 = 0x80, uLSQM2 = 0x98,
-           /* uRSQM0 = 0xE2, uRSQM1 = 0x80, */ uRSQM2 = 0x99
-         };
-
          unsigned char str[MAX_MULTIBYTE_LENGTH];
 
          if ((format_char == '`' || format_char == '\'')
          unsigned char str[MAX_MULTIBYTE_LENGTH];
 
          if ((format_char == '`' || format_char == '\'')
@@ -4475,18 +4474,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
            }
          else if (format_char == '`' && quoting_style == STRAIGHT_QUOTING_STYLE)
            convsrc = "'";
            }
          else if (format_char == '`' && quoting_style == STRAIGHT_QUOTING_STYLE)
            convsrc = "'";
-         else if (format_char == uLSQM0 && CURVE_QUOTING_STYLE < quoting_style
-                  && multibyte_format
-                  && (unsigned char) format[0] == uLSQM1
-                  && ((unsigned char) format[1] == uLSQM2
-                      || (unsigned char) format[1] == uRSQM2))
-           {
-             convsrc = (((unsigned char) format[1] == uLSQM2
-                         && quoting_style == GRAVE_QUOTING_STYLE)
-                        ? "`" : "'");
-             format += 2;
-             memset (&discarded[format0 + 1 - format_start], 2, 2);
-           }
          else
            {
              /* Copy a single character from format to buf.  */
          else
            {
              /* Copy a single character from format to buf.  */
@@ -4644,7 +4631,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
              len = make_number (SCHARS (args[i]));
              Lisp_Object new_len = make_number (info[i].end - info[i].start);
              props = text_property_list (args[i], make_number (0), len, Qnil);
              len = make_number (SCHARS (args[i]));
              Lisp_Object new_len = make_number (info[i].end - info[i].start);
              props = text_property_list (args[i], make_number (0), len, Qnil);
-             props = extend_property_ranges (props, new_len);
+             props = extend_property_ranges (props, len, new_len);
              /* If successive arguments have properties, be sure that
                 the value of `composition' property be the copy.  */
              if (1 < i && info[i - 1].end)
              /* If successive arguments have properties, be sure that
                 the value of `composition' property be the copy.  */
              if (1 < i && info[i - 1].end)
@@ -5071,6 +5058,14 @@ Transposing beyond buffer boundaries is an error.  */)
                         start2_byte, start2_byte + len2_byte);
       fix_start_end_in_overlays (start1, end2);
     }
                         start2_byte, start2_byte + len2_byte);
       fix_start_end_in_overlays (start1, end2);
     }
+  else
+    {
+      /* The character positions of the markers remain intact, but we
+        still need to update their byte positions, because the
+        transposed regions might include multibyte sequences which
+        make some original byte positions of the markers invalid.  */
+      adjust_markers_bytepos (start1, start1_byte, end2, end2_byte, 0);
+    }
 
   signal_after_change (start1, end2 - start1, end2 - start1);
   return Qnil;
 
   signal_after_change (start1, end2 - start1, end2 - start1);
   return Qnil;