]> 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);
+      tzset ();
       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
-   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)
 {
-  EMACS_INT n;
   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 ();
-  return n - offset;
+  return result;
 }
 
 DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
@@ -2459,23 +2459,24 @@ emacs_setenv_TZ (const char *tzstring)
       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
-      )
-    {
-      /* 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;
 }
@@ -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.
-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.
 
@@ -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.
-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.
 
@@ -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));
-  bool string_multibyte IF_LINT (= 0);
+  bool string_multibyte UNINIT;
 
   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
-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
@@ -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
-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.
@@ -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
-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.
@@ -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.
 
+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)
 {
@@ -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 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
@@ -4174,6 +4181,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                      p += padding;
                      nchars += padding;
                    }
+                  info[n].start = nchars;
 
                  if (p > buf
                      && multibyte
@@ -4186,9 +4194,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                                  nbytes,
                                  STRING_MULTIBYTE (args[n]), multibyte);
 
-                  info[n].start = nchars;
                  nchars += nchars_string;
-                 info[n].end = nchars;
 
                  if (minus_flag)
                    {
@@ -4196,6 +4202,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                      p += padding;
                      nchars += padding;
                    }
+                 info[n].end = nchars;
 
                  /* 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;
                    }
 
+                  info[n].start = nchars;
                  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;
 
-                  info[n].start = nchars;
                  nchars += leading_zeros + sprintf_bytes + trailing_zeros;
-                 info[n].end = nchars;
 
                  if (minus_flag)
                    {
@@ -4445,6 +4451,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                      p += padding;
                      nchars += padding;
                    }
+                 info[n].end = nchars;
 
                  continue;
                }
@@ -4452,14 +4459,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
        }
       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 == '\'')
@@ -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 == 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.  */
@@ -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);
-             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)
@@ -5071,6 +5058,14 @@ Transposing beyond buffer boundaries is an error.  */)
                         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;