Convert (most) functions in src to standard C.
[bpt/emacs.git] / src / editfns.c
index fa1b229..f318705 100644 (file)
@@ -1,14 +1,15 @@
 /* Lisp functions pertaining to editing.
-   Copyright (C) 1985, 1986, 1987, 1989, 1993, 1994, 1995, 1996,
-                 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007 Free Software Foundation, Inc.
+
+Copyright (C) 1985, 1986, 1987, 1989, 1993, 1994, 1995, 1996, 1997,
+  1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+  2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,14 +17,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include <config.h>
 #include <sys/types.h>
 #include <stdio.h>
+#include <setjmp.h>
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>
@@ -69,6 +69,10 @@ Boston, MA 02110-1301, USA.  */
 #define NULL 0
 #endif
 
+#ifndef USER_FULL_NAME
+#define USER_FULL_NAME pw->pw_gecos
+#endif
+
 #ifndef USE_CRT_DLL
 extern char **environ;
 #endif
@@ -82,37 +86,38 @@ extern char **environ;
     (1000 - TM_YEAR_BASE <= (tm_year) && (tm_year) <= 9999 - TM_YEAR_BASE)
 #endif
 
-extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
-                                  const struct tm *, int));
+extern size_t emacs_strftimeu (char *, size_t, const char *,
+                               const struct tm *, int);
 
 #ifdef WINDOWSNT
 extern Lisp_Object w32_get_internal_run_time ();
 #endif
 
-static int tm_diff P_ ((struct tm *, struct tm *));
-static void find_field P_ ((Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *));
-static void update_buffer_properties P_ ((int, int));
-static Lisp_Object region_limit P_ ((int));
-int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
-static size_t emacs_memftimeu P_ ((char *, size_t, const char *,
-                                  size_t, const struct tm *, int));
-static void general_insert_function P_ ((void (*) (const unsigned char *, int),
-                                        void (*) (Lisp_Object, int, int, int,
-                                                  int, int),
-                                        int, int, Lisp_Object *));
-static Lisp_Object subst_char_in_region_unwind P_ ((Lisp_Object));
-static Lisp_Object subst_char_in_region_unwind_1 P_ ((Lisp_Object));
-static void transpose_markers P_ ((int, int, int, int, int, int, int, int));
+static int tm_diff (struct tm *, struct tm *);
+static void find_field (Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *);
+static void update_buffer_properties (int, int);
+static Lisp_Object region_limit (int);
+int lisp_time_argument (Lisp_Object, time_t *, int *);
+static size_t emacs_memftimeu (char *, size_t, const char *,
+                               size_t, const struct tm *, int);
+static void general_insert_function (void (*) (const unsigned char *, EMACS_INT),
+                                    void (*) (Lisp_Object, EMACS_INT,
+                                              EMACS_INT, EMACS_INT,
+                                              EMACS_INT, int),
+                                    int, int, Lisp_Object *);
+static Lisp_Object subst_char_in_region_unwind (Lisp_Object);
+static Lisp_Object subst_char_in_region_unwind_1 (Lisp_Object);
+static void transpose_markers (int, int, int, int, int, int, int, int);
 
 #ifdef HAVE_INDEX
-extern char *index P_ ((const char *, int));
+extern char *index (const char *, int);
 #endif
 
 Lisp_Object Vbuffer_access_fontify_functions;
 Lisp_Object Qbuffer_access_fontify_functions;
 Lisp_Object Vbuffer_access_fontified_property;
 
-Lisp_Object Fuser_full_name P_ ((Lisp_Object));
+Lisp_Object Fuser_full_name (Lisp_Object);
 
 /* Non-nil means don't stop at field boundary in text motion commands.  */
 
@@ -136,7 +141,7 @@ Lisp_Object Qboundary;
 
 
 void
-init_editfns ()
+init_editfns (void)
 {
   char *user_name;
   register unsigned char *p;
@@ -216,6 +221,17 @@ usage: (char-to-string CHAR)  */)
   return make_string_from_bytes (str, 1, len);
 }
 
+DEFUN ("byte-to-string", Fbyte_to_string, Sbyte_to_string, 1, 1, 0,
+       doc: /* Convert arg BYTE to a string containing that byte.  */)
+     (byte)
+     Lisp_Object byte;
+{
+  unsigned char b;
+  CHECK_NUMBER (byte);
+  b = XINT (byte);
+  return make_string_from_bytes (&b, 1, 1);
+}
+
 DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
        doc: /* Convert arg STRING to a character, the first character of that string.
 A multibyte character is handled correctly.  */)
@@ -227,7 +243,7 @@ A multibyte character is handled correctly.  */)
   if (SCHARS (string))
     {
       if (STRING_MULTIBYTE (string))
-       XSETFASTINT (val, STRING_CHAR (SDATA (string), SBYTES (string)));
+       XSETFASTINT (val, STRING_CHAR (SDATA (string)));
       else
        XSETFASTINT (val, SREF (string, 0));
     }
@@ -237,8 +253,7 @@ A multibyte character is handled correctly.  */)
 }
 \f
 static Lisp_Object
-buildmark (charpos, bytepos)
-     int charpos, bytepos;
+buildmark (int charpos, int bytepos)
 {
   register Lisp_Object mark;
   mark = Fmake_marker ();
@@ -264,8 +279,7 @@ DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
 }
 
 int
-clip_to_bounds (lower, num, upper)
-     int lower, num, upper;
+clip_to_bounds (int lower, int num, int upper)
 {
   if (num < lower)
     return lower;
@@ -312,8 +326,7 @@ The return value is POSITION.  */)
    If there is no region active, signal an error. */
 
 static Lisp_Object
-region_limit (beginningp)
-     int beginningp;
+region_limit (int beginningp)
 {
   extern Lisp_Object Vmark_even_if_inactive; /* Defined in callint.c. */
   Lisp_Object m;
@@ -361,10 +374,7 @@ If you set the marker not to point anywhere, the buffer will have no mark.  */)
    of length LEN.  */
 
 static int
-overlays_around (pos, vec, len)
-     int pos;
-     Lisp_Object *vec;
-     int len;
+overlays_around (int pos, Lisp_Object *vec, int len)
 {
   Lisp_Object overlay, start, end;
   struct Lisp_Overlay *tail;
@@ -420,9 +430,7 @@ overlays_around (pos, vec, len)
    window-specific overlays are considered only if they are associated
    with OBJECT. */
 Lisp_Object
-get_pos_property (position, prop, object)
-     Lisp_Object position, object;
-     register Lisp_Object prop;
+get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object object)
 {
   CHECK_NUMBER_COERCE_MARKER (position);
 
@@ -482,7 +490,7 @@ get_pos_property (position, prop, object)
            }
        }
 
-      { /* Now check the text-properties.  */
+      { /* Now check the text properties.  */
        int stickiness = text_property_stickiness (prop, position, object);
        if (stickiness > 0)
          return Fget_text_property (position, prop, object);
@@ -517,11 +525,7 @@ get_pos_property (position, prop, object)
    is not stored.  */
 
 static void
-find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
-     Lisp_Object pos;
-     Lisp_Object merge_at_boundary;
-     Lisp_Object beg_limit, end_limit;
-     int *beg, *end;
+find_field (Lisp_Object pos, Lisp_Object merge_at_boundary, Lisp_Object beg_limit, int *beg, Lisp_Object end_limit, int *end)
 {
   /* Fields right before and after the point.  */
   Lisp_Object before_field, after_field;
@@ -658,7 +662,7 @@ If POS is nil, the value of point is used for POS.  */)
 }
 
 DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0,
-       doc: /* Return the contents of the field around POS, without text-properties.
+       doc: /* Return the contents of the field around POS, without text properties.
 A field is a region of text with the same `field' property.
 If POS is nil, the value of point is used for POS.  */)
      (pos)
@@ -884,7 +888,7 @@ This function does not move point.  */)
 
 \f
 Lisp_Object
-save_excursion_save ()
+save_excursion_save (void)
 {
   int visible = (XBUFFER (XWINDOW (selected_window)->buffer)
                 == current_buffer);
@@ -897,8 +901,7 @@ save_excursion_save ()
 }
 
 Lisp_Object
-save_excursion_restore (info)
-     Lisp_Object info;
+save_excursion_restore (Lisp_Object info)
 {
   Lisp_Object tem, tem1, omark, nmark;
   struct gcpro gcpro1, gcpro2, gcpro3;
@@ -993,6 +996,9 @@ functions that change the buffer will still cause deactivation
 of the mark at the end of the command.  To prevent that, bind
 `deactivate-mark' with `let'.
 
+If you only want to save the current buffer but not point nor mark,
+then just use `save-current-buffer', or even `with-current-buffer'.
+
 usage: (save-excursion &rest BODY)  */)
      (args)
      Lisp_Object args;
@@ -1276,12 +1282,13 @@ This is based on the effective uid, not the real uid.
 Also, if the environment variables LOGNAME or USER are set,
 that determines the value of this function.
 
-If optional argument UID is an integer, return the login name of the user
-with that uid, or nil if there is no such user.  */)
+If optional argument UID is an integer or a float, return the login name
+of the user with that uid, or nil if there is no such user.  */)
      (uid)
      Lisp_Object uid;
 {
   struct passwd *pw;
+  uid_t id;
 
   /* Set up the user name info if we didn't do it before.
      (That can happen if Emacs is dumpable
@@ -1292,9 +1299,9 @@ with that uid, or nil if there is no such user.  */)
   if (NILP (uid))
     return Vuser_login_name;
 
-  CHECK_NUMBER (uid);
+  id = (uid_t)XFLOATINT (uid);
   BLOCK_INPUT;
-  pw = (struct passwd *) getpwuid (XINT (uid));
+  pw = (struct passwd *) getpwuid (id);
   UNBLOCK_INPUT;
   return (pw ? build_string (pw->pw_name) : Qnil);
 }
@@ -1316,23 +1323,33 @@ This ignores the environment variables LOGNAME and USER, so it differs from
 
 DEFUN ("user-uid", Fuser_uid, Suser_uid, 0, 0, 0,
        doc: /* Return the effective uid of Emacs.
-Value is an integer or float, depending on the value.  */)
+Value is an integer or float, depending on the value.  */)
      ()
 {
   /* Assignment to EMACS_INT stops GCC whining about limited range of
      data type.  */
   EMACS_INT euid = geteuid ();
+
+  /* Make sure we don't produce a negative UID due to signed integer
+     overflow.  */
+  if (euid < 0)
+    return make_float ((double)geteuid ());
   return make_fixnum_or_float (euid);
 }
 
 DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
        doc: /* Return the real uid of Emacs.
-Value is an integer or float, depending on the value.  */)
+Value is an integer or float, depending on the value.  */)
      ()
 {
   /* Assignment to EMACS_INT stops GCC whining about limited range of
      data type.  */
   EMACS_INT uid = getuid ();
+
+  /* Make sure we don't produce a negative UID due to signed integer
+     overflow.  */
+  if (uid < 0)
+    return make_float ((double)getuid ());
   return make_fixnum_or_float (uid);
 }
 
@@ -1410,7 +1427,7 @@ DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
 /* For the benefit of callers who don't want to include lisp.h */
 
 char *
-get_system_name ()
+get_system_name (void)
 {
   if (STRINGP (Vsystem_name))
     return (char *) SDATA (Vsystem_name);
@@ -1419,7 +1436,7 @@ get_system_name ()
 }
 
 char *
-get_operating_system_release()
+get_operating_system_release(void)
 {
   if (STRINGP (Voperating_system_release))
     return (char *) SDATA (Voperating_system_release);
@@ -1487,7 +1504,7 @@ on systems that do not provide resolution finer than a second.  */)
                make_number ((secs >> 0)  & 0xffff),
                make_number (usecs));
 #else /* ! HAVE_GETRUSAGE  */
-#if WINDOWSNT
+#ifdef WINDOWSNT
   return w32_get_internal_run_time ();
 #else /* ! WINDOWSNT  */
   return Fcurrent_time ();
@@ -1497,10 +1514,7 @@ on systems that do not provide resolution finer than a second.  */)
 \f
 
 int
-lisp_time_argument (specified_time, result, usec)
-     Lisp_Object specified_time;
-     time_t *result;
-     int *usec;
+lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec)
 {
   if (NILP (specified_time))
     {
@@ -1551,12 +1565,13 @@ DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
        doc: /* Return the current time, as a float number of seconds since the epoch.
 If SPECIFIED-TIME is given, it is the time to convert to float
 instead of the current time.  The argument should have the form
-(HIGH LOW . IGNORED). Thus, you can use times obtained from
+(HIGH LOW) or (HIGH LOW USEC). Thus, you can use times obtained from
 `current-time' and from `file-attributes'.  SPECIFIED-TIME can also
 have the form (HIGH . LOW), but this is considered obsolete.
 
 WARNING: Since the result is floating point, it may not be exact.
-Do not use this function if precise time stamps are required.  */)
+If precise time stamps are required, use either `current-time',
+or (if you need time as a string) `format-time-string'.  */)
      (specified_time)
      Lisp_Object specified_time;
 {
@@ -1580,13 +1595,7 @@ Do not use this function if precise time stamps are required.  */)
    This function behaves like emacs_strftimeu, except it allows null
    bytes in FORMAT.  */
 static size_t
-emacs_memftimeu (s, maxsize, format, format_len, tp, ut)
-      char *s;
-      size_t maxsize;
-      const char *format;
-      size_t format_len;
-      const struct tm *tp;
-      int ut;
+emacs_memftimeu (char *s, size_t maxsize, const char *format, size_t format_len, const struct tm *tp, int ut)
 {
   size_t total = 0;
 
@@ -1878,7 +1887,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE)  */)
 }
 
 DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
-       doc: /* Return the current time, as a human-readable string.
+       doc: /* Return the current local time, as a human-readable string.
 Programs can use this function to decode a time,
 since the number of columns in each field is fixed
 if the year is in the range 1000-9999.
@@ -1919,8 +1928,7 @@ but this is considered obsolete.  */)
 /* Yield A - B, measured in seconds.
    This function is copied from the GNU C Library.  */
 static int
-tm_diff (a, b)
-     struct tm *a, *b;
+tm_diff (struct tm *a, struct tm *b)
 {
   /* Compute intervening leap days correctly even if year is negative.
      Take care to avoid int overflow in leap day calculations,
@@ -2011,6 +2019,11 @@ the data it can't find.  */)
    has never been called.  */
 static char **environbuf;
 
+/* This holds the startup value of the TZ environment variable so it
+   can be restored if the user calls set-time-zone-rule with a nil
+   argument.  */
+static char *initial_tz;
+
 DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
        doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
 If TZ is nil, use implementation-defined default time zone information.
@@ -2020,8 +2033,12 @@ If TZ is t, use Universal Time.  */)
 {
   char *tzstring;
 
+  /* When called for the first time, save the original TZ.  */
+  if (!environbuf)
+    initial_tz = (char *) getenv ("TZ");
+
   if (NILP (tz))
-    tzstring = 0;
+    tzstring = initial_tz;
   else if (EQ (tz, Qt))
     tzstring = "UTC0";
   else
@@ -2031,8 +2048,7 @@ If TZ is t, use Universal Time.  */)
     }
 
   set_time_zone_rule (tzstring);
-  if (environbuf)
-    free (environbuf);
+  free (environbuf);
   environbuf = environ;
 
   return Qnil;
@@ -2059,8 +2075,7 @@ static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
    responsibility to free.  */
 
 void
-set_time_zone_rule (tzstring)
-     char *tzstring;
+set_time_zone_rule (char *tzstring)
 {
   int envptrs;
   char **from, **to, **newenv;
@@ -2140,12 +2155,12 @@ set_time_zone_rule (tzstring)
    INSERT_FROM_STRING_FUNC as the last argument.  */
 
 static void
-general_insert_function (insert_func, insert_from_string_func,
-                        inherit, nargs, args)
-     void (*insert_func) P_ ((const unsigned char *, int));
-     void (*insert_from_string_func) P_ ((Lisp_Object, int, int, int, int, int));
-     int inherit, nargs;
-     register Lisp_Object *args;
+general_insert_function (void (*insert_func)
+                             (const unsigned char *, EMACS_INT),
+                        void (*insert_from_string_func)
+                             (Lisp_Object, EMACS_INT, EMACS_INT,
+                              EMACS_INT, EMACS_INT, int),
+                        int inherit, int nargs, Lisp_Object *args)
 {
   register int argnum;
   register Lisp_Object val;
@@ -2182,8 +2197,7 @@ general_insert_function (insert_func, insert_from_string_func,
 }
 
 void
-insert1 (arg)
-     Lisp_Object arg;
+insert1 (Lisp_Object arg)
 {
   Finsert (1, &arg);
 }
@@ -2369,9 +2383,7 @@ from adjoining text, if those properties are sticky.  */)
    buffer substrings.  */
 
 Lisp_Object
-make_buffer_string (start, end, props)
-     int start, end;
-     int props;
+make_buffer_string (int start, int end, int props)
 {
   int start_byte = CHAR_TO_BYTE (start);
   int end_byte = CHAR_TO_BYTE (end);
@@ -2395,9 +2407,7 @@ make_buffer_string (start, end, props)
    buffer substrings.  */
 
 Lisp_Object
-make_buffer_string_both (start, start_byte, end, end_byte, props)
-     int start, start_byte, end, end_byte;
-     int props;
+make_buffer_string_both (int start, int start_byte, int end, int end_byte, int props)
 {
   Lisp_Object result, tem, tem1;
 
@@ -2431,8 +2441,7 @@ make_buffer_string_both (start, start_byte, end, end_byte, props)
    in the current buffer, if necessary.  */
 
 static void
-update_buffer_properties (start, end)
-     int start, end;
+update_buffer_properties (int start, int end)
 {
   /* If this buffer has some access functions,
      call them, specifying the range of the buffer being accessed.  */
@@ -2676,7 +2685,7 @@ determines whether case is significant or ignored.  */)
       else
        {
          c1 = BUF_FETCH_BYTE (bp1, i1);
-         c1 = unibyte_char_to_multibyte (c1);
+         MAKE_CHAR_MULTIBYTE (c1);
          i1++;
        }
 
@@ -2689,7 +2698,7 @@ determines whether case is significant or ignored.  */)
       else
        {
          c2 = BUF_FETCH_BYTE (bp2, i2);
-         c2 = unibyte_char_to_multibyte (c2);
+         MAKE_CHAR_MULTIBYTE (c2);
          i2++;
        }
 
@@ -2718,15 +2727,13 @@ determines whether case is significant or ignored.  */)
 }
 \f
 static Lisp_Object
-subst_char_in_region_unwind (arg)
-     Lisp_Object arg;
+subst_char_in_region_unwind (Lisp_Object arg)
 {
   return current_buffer->undo_list = arg;
 }
 
 static Lisp_Object
-subst_char_in_region_unwind_1 (arg)
-     Lisp_Object arg;
+subst_char_in_region_unwind_1 (Lisp_Object arg)
 {
   return current_buffer->filename = arg;
 }
@@ -2843,8 +2850,8 @@ Both characters must have the same length of multi-byte form.  */)
                {
                  if (MODIFF - 1 == SAVE_MODIFF)
                    SAVE_MODIFF++;
-                 if (MODIFF - 1 == current_buffer->auto_save_modified)
-                   current_buffer->auto_save_modified++;
+                 if (MODIFF - 1 == BUF_AUTOSAVE_MODIFF (current_buffer))
+                   BUF_AUTOSAVE_MODIFF (current_buffer)++;
                }
 
              /* The before-change-function may have moved the gap
@@ -2914,7 +2921,7 @@ Both characters must have the same length of multi-byte form.  */)
 }
 
 
-static Lisp_Object check_translation P_ ((int, int, int, Lisp_Object));
+static Lisp_Object check_translation (int, int, int, Lisp_Object);
 
 /* Helper function for Ftranslate_region_internal.
 
@@ -2923,9 +2930,7 @@ static Lisp_Object check_translation P_ ((int, int, int, Lisp_Object));
    element is found, return it.  Otherwise return Qnil.  */
 
 static Lisp_Object
-check_translation (pos, pos_byte, end, val)
-     int pos, pos_byte, end;
-     Lisp_Object val;
+check_translation (int pos, int pos_byte, int end, Lisp_Object val)
 {
   int buf_size = 16, buf_used = 0;
   int *buf = alloca (sizeof (int) * buf_size);
@@ -2960,7 +2965,7 @@ check_translation (pos, pos_byte, end, val)
                      memcpy (newbuf, buf, sizeof (int) * buf_used);
                      buf = newbuf;
                    }
-                 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, 0, len);
+                 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len);
                  pos_byte += len;
                }
              if (XINT (AREF (elt, i)) != buf[i])
@@ -3029,7 +3034,7 @@ It returns the number of characters changed.  */)
       Lisp_Object val;
 
       if (multibyte)
-       oc = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);
+       oc = STRING_CHAR_AND_LENGTH (p, len);
       else
        oc = *p, len = 1;
       if (oc < size)
@@ -3041,8 +3046,7 @@ It returns the number of characters changed.  */)
              if (string_multibyte)
                {
                  str = tt + string_char_to_byte (table, oc);
-                 nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH, 
-                                              str_len);
+                 nc = STRING_CHAR_AND_LENGTH (str, str_len);
                }
              else
                {
@@ -3125,12 +3129,7 @@ It returns the number of characters changed.  */)
 
              if (VECTORP (val))
                {
-                 int i;
-
-                 string = Fmake_string (make_number (ASIZE (val)),
-                                        AREF (val, 0));
-                 for (i = 1; i < ASIZE (val); i++)
-                   Faset (string, make_number (i), AREF (val, i));
+                 string = Fconcat (1, &val);
                }
              else
                {
@@ -3230,7 +3229,7 @@ or markers) bounding the text that should remain visible.  */)
 }
 
 Lisp_Object
-save_restriction_save ()
+save_restriction_save (void)
 {
   if (BEGV == BEG && ZV == Z)
     /* The common case that the buffer isn't narrowed.
@@ -3254,15 +3253,28 @@ save_restriction_save ()
 }
 
 Lisp_Object
-save_restriction_restore (data)
-     Lisp_Object data;
+save_restriction_restore (Lisp_Object data)
 {
+  struct buffer *cur = NULL;
+  struct buffer *buf = (CONSP (data)
+                       ? XMARKER (XCAR (data))->buffer
+                       : XBUFFER (data));
+
+  if (buf && buf != current_buffer && !NILP (buf->pt_marker))
+    { /* If `buf' uses markers to keep track of PT, BEGV, and ZV (as
+        is the case if it is or has an indirect buffer), then make
+        sure it is current before we update BEGV, so
+        set_buffer_internal takes care of managing those markers.  */
+      cur = current_buffer;
+      set_buffer_internal (buf);
+    }
+
   if (CONSP (data))
     /* A pair of marks bounding a saved restriction.  */
     {
       struct Lisp_Marker *beg = XMARKER (XCAR (data));
       struct Lisp_Marker *end = XMARKER (XCDR (data));
-      struct buffer *buf = beg->buffer; /* END should have the same buffer. */
+      eassert (buf == end->buffer);
 
       if (buf /* Verify marker still points to a buffer.  */
          && (beg->charpos != BUF_BEGV (buf) || end->charpos != BUF_ZV (buf)))
@@ -3287,8 +3299,6 @@ save_restriction_restore (data)
   else
     /* A buffer, which means that there was no old restriction.  */
     {
-      struct buffer *buf = XBUFFER (data);
-
       if (buf /* Verify marker still points to a buffer.  */
          && (BUF_BEGV (buf) != BUF_BEG (buf) || BUF_ZV (buf) != BUF_Z (buf)))
        /* The buffer has been narrowed, get rid of the narrowing.  */
@@ -3300,6 +3310,9 @@ save_restriction_restore (data)
        }
     }
 
+  if (cur)
+    set_buffer_internal (cur);
+
   return Qnil;
 }
 
@@ -3513,7 +3526,10 @@ DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
        doc: /* Format a string out of a format-string and arguments.
 The first argument is a format control string.
 The other arguments are substituted into it to make the result, a string.
-It may contain %-sequences meaning to substitute the next argument.
+
+The format control string may contain %-sequences meaning to substitute
+the next available argument:
+
 %s means print a string argument.  Actually, prints any object, with `princ'.
 %d means print as number in decimal (%o octal, %x hex).
 %X is like %x, but uses upper case.
@@ -3523,12 +3539,34 @@ It may contain %-sequences meaning to substitute the next argument.
   or decimal-point notation, whichever uses fewer characters.
 %c means print a number as a single character.
 %S means print any object as an s-expression (using `prin1').
-  The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
+
+The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
 Use %% to put a single % into the output.
 
-The basic structure of a %-sequence is
-  % <flags> <width> <precision> character
-where flags is [-+ #0]+, width is [0-9]+, and precision is .[0-9]+
+A %-sequence may contain optional flag, width, and precision
+specifiers, as follows:
+
+  %<flags><width><precision>character
+
+where flags is [+ #-0]+, width is [0-9]+, and precision is .[0-9]+
+
+The + flag character inserts a + before any positive number, while a
+space inserts a space before any positive number; these flags only
+affect %d, %e, %f, and %g sequences, and the + flag takes precedence.
+The # flag means to use an alternate display form for %o, %x, %X, %e,
+%f, and %g sequences.  The - and 0 flags affect the width specifier,
+as described below.
+
+The width specifier supplies a lower limit for the length of the
+printed representation.  The padding, if any, normally goes on the
+left, but it goes on the right if the - flag is present.  The padding
+character is normally a space, but it is 0 if the 0 flag is present.
+The - flag takes precedence over the 0 flag.
+
+For %e, %f, and %g sequences, the number after the "." in the
+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.
 
 usage: (format STRING &rest OBJECTS)  */)
      (nargs, args)
@@ -3721,7 +3759,11 @@ usage: (format STRING &rest OBJECTS)  */)
               to be as large as is calculated here.  Easy check for
               the case PRECISION = 0. */
            thissize = precision[n] ? CONVERTED_BYTE_SIZE (multibyte, args[n]) : 0;
+           /* The precision also constrains how much of the argument
+              string will finally appear (Bug#5710). */
            actual_width = lisp_string_width (args[n], -1, NULL, NULL);
+           if (precision[n] != -1)
+             actual_width = min(actual_width,precision[n]);
          }
        /* Would get MPV otherwise, since Lisp_Int's `point' to low memory.  */
        else if (INTEGERP (args[n]) && *format != 's')
@@ -4116,8 +4158,8 @@ usage: (format STRING &rest OBJECTS)  */)
              len = make_number (SCHARS (args[n]));
              new_len = make_number (info[n].end - info[n].start);
              props = text_property_list (args[n], make_number (0), len, Qnil);
-             extend_property_ranges (props, len, new_len);
-             /* If successive arguments have properites, be sure that
+             props = extend_property_ranges (props, new_len);
+             /* If successive arguments have properties, be sure that
                 the value of `composition' property be the copy.  */
              if (n > 1 && info[n - 1].end)
                make_composition_value_copy (props);
@@ -4132,9 +4174,7 @@ usage: (format STRING &rest OBJECTS)  */)
 }
 
 Lisp_Object
-format2 (string1, arg0, arg1)
-     char *string1;
-     Lisp_Object arg0, arg1;
+format2 (char *string1, Lisp_Object arg0, Lisp_Object arg1)
 {
   Lisp_Object args[3];
   args[0] = build_string (string1);
@@ -4151,8 +4191,10 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer.  */)
      register Lisp_Object c1, c2;
 {
   int i1, i2;
-  CHECK_NUMBER (c1);
-  CHECK_NUMBER (c2);
+  /* Check they're chars, not just integers, otherwise we could get array
+     bounds violations in DOWNCASE.  */
+  CHECK_CHARACTER (c1);
+  CHECK_CHARACTER (c2);
 
   if (XINT (c1) == XINT (c2))
     return Qt;
@@ -4265,7 +4307,7 @@ transpose_markers (start1, end1, start2, end2,
 
 DEFUN ("transpose-regions", Ftranspose_regions, Stranspose_regions, 4, 5, 0,
        doc: /* Transpose region STARTR1 to ENDR1 with STARTR2 to ENDR2.
-The regions may not be overlapping, because the size of the buffer is
+The regions should not be overlapping, because the size of the buffer is
 never changed in a transposition.
 
 Optional fifth arg LEAVE-MARKERS, if non-nil, means don't update
@@ -4560,12 +4602,13 @@ Transposing beyond buffer boundaries is an error.  */)
 
 \f
 void
-syms_of_editfns ()
+syms_of_editfns (void)
 {
   environbuf = 0;
+  initial_tz = 0;
 
   Qbuffer_access_fontify_functions
-    = intern ("buffer-access-fontify-functions");
+    = intern_c_string ("buffer-access-fontify-functions");
   staticpro (&Qbuffer_access_fontify_functions);
 
   DEFVAR_LISP ("inhibit-field-text-motion", &Vinhibit_field_text_motion,
@@ -4586,7 +4629,7 @@ of the buffer being accessed.  */);
     /* Do this here, because init_buffer_once is too early--it won't work.  */
     Fset_buffer (Vprin1_to_string_buffer);
     /* Make sure buffer-access-fontify-functions is nil in this buffer.  */
-    Fset (Fmake_local_variable (intern ("buffer-access-fontify-functions")),
+    Fset (Fmake_local_variable (intern_c_string ("buffer-access-fontify-functions")),
          Qnil);
     Fset_buffer (obuf);
   }
@@ -4618,6 +4661,7 @@ functions if all the text being accessed has this property.  */);
   defsubr (&Sgoto_char);
   defsubr (&Sstring_to_char);
   defsubr (&Schar_to_string);
+  defsubr (&Sbyte_to_string);
   defsubr (&Sbuffer_substring);
   defsubr (&Sbuffer_substring_no_properties);
   defsubr (&Sbuffer_string);
@@ -4629,9 +4673,9 @@ functions if all the text being accessed has this property.  */);
   defsubr (&Sregion_end);
 
   staticpro (&Qfield);
-  Qfield = intern ("field");
+  Qfield = intern_c_string ("field");
   staticpro (&Qboundary);
-  Qboundary = intern ("boundary");
+  Qboundary = intern_c_string ("boundary");
   defsubr (&Sfield_beginning);
   defsubr (&Sfield_end);
   defsubr (&Sfield_string);