]> code.delx.au - gnu-emacs/blobdiff - src/editfns.c
Fix C99 incompatibilities in Cairo code
[gnu-emacs] / src / editfns.c
index 7026ccc084ede5eff792ac8271177b2568295e3d..e39eed6e870838507b97f1ccbd7260a93fec0aba 100644 (file)
@@ -849,14 +849,11 @@ save_excursion_save (void)
 {
   return make_save_obj_obj_obj_obj
     (Fpoint_marker (),
-     /* Do not copy the mark if it points to nowhere.  */
-     (XMARKER (BVAR (current_buffer, mark))->buffer
-      ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
-      : Qnil),
+     Qnil,
      /* Selected window if current buffer is shown in it, nil otherwise.  */
      (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
       ? selected_window : Qnil),
-     BVAR (current_buffer, mark_active));
+     Qnil);
 }
 
 /* Restore saved buffer before leaving `save-excursion' special form.  */
@@ -864,8 +861,8 @@ save_excursion_save (void)
 void
 save_excursion_restore (Lisp_Object info)
 {
-  Lisp_Object tem, tem1, omark, nmark;
-  struct gcpro gcpro1, gcpro2, gcpro3;
+  Lisp_Object tem, tem1;
+  struct gcpro gcpro1;
 
   tem = Fmarker_buffer (XSAVE_OBJECT (info, 0));
   /* If we're unwinding to top level, saved buffer may be deleted.  This
@@ -873,8 +870,7 @@ save_excursion_restore (Lisp_Object info)
   if (NILP (tem))
     goto out;
 
-  omark = nmark = Qnil;
-  GCPRO3 (info, omark, nmark);
+  GCPRO1 (info);
 
   Fset_buffer (tem);
 
@@ -883,34 +879,6 @@ save_excursion_restore (Lisp_Object info)
   Fgoto_char (tem);
   unchain_marker (XMARKER (tem));
 
-  /* Mark marker.  */
-  tem = XSAVE_OBJECT (info, 1);
-  omark = Fmarker_position (BVAR (current_buffer, mark));
-  if (NILP (tem))
-    unchain_marker (XMARKER (BVAR (current_buffer, mark)));
-  else
-    {
-      Fset_marker (BVAR (current_buffer, mark), tem, Fcurrent_buffer ());
-      nmark = Fmarker_position (tem);
-      unchain_marker (XMARKER (tem));
-    }
-
-  /* Mark active.  */
-  tem = XSAVE_OBJECT (info, 3);
-  tem1 = BVAR (current_buffer, mark_active);
-  bset_mark_active (current_buffer, tem);
-
-  /* If mark is active now, and either was not active
-     or was at a different place, run the activate hook.  */
-  if (! NILP (tem))
-    {
-      if (! EQ (omark, nmark))
-       run_hook (intern ("activate-mark-hook"));
-    }
-  /* If mark has ceased to be active, run deactivate hook.  */
-  else if (! NILP (tem1))
-    run_hook (intern ("deactivate-mark-hook"));
-
   /* If buffer was visible in a window, and a different window was
      selected, and the old selected window is still showing this
      buffer, restore point in that window.  */
@@ -932,20 +900,18 @@ save_excursion_restore (Lisp_Object info)
 }
 
 DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
-       doc: /* Save point, mark, and current buffer; execute BODY; restore those things.
+       doc: /* Save point, and current buffer; execute BODY; restore those things.
 Executes BODY just like `progn'.
-The values of point, mark and the current buffer are restored
+The values of point and the current buffer are restored
 even in case of abnormal exit (throw or error).
-The state of activation of the mark is also restored.
-
-This construct does not save `deactivate-mark', and therefore
-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,
+If you only want to save the current buffer but not point,
 then just use `save-current-buffer', or even `with-current-buffer'.
 
+Before Emacs 25.1, `save-excursion' used to save the mark state.
+To save the marker state as well as the point and buffer, use
+`save-mark-and-excursion'.
+
 usage: (save-excursion &rest BODY)  */)
   (Lisp_Object args)
 {
@@ -1059,10 +1025,20 @@ DEFUN ("byte-to-position", Fbyte_to_position, Sbyte_to_position, 1, 1, 0,
 If BYTEPOS is out of range, the value is nil.  */)
   (Lisp_Object bytepos)
 {
+  ptrdiff_t pos_byte;
+
   CHECK_NUMBER (bytepos);
-  if (XINT (bytepos) < BEG_BYTE || XINT (bytepos) > Z_BYTE)
+  pos_byte = XINT (bytepos);
+  if (pos_byte < BEG_BYTE || pos_byte > Z_BYTE)
     return Qnil;
-  return make_number (BYTE_TO_CHAR (XINT (bytepos)));
+  if (Z != Z_BYTE)
+    /* There are multibyte characters in the buffer.
+       The argument of BYTE_TO_CHAR must be a byte position at
+       a character boundary, so search for the start of the current
+       character.  */
+    while (!CHAR_HEAD_P (FETCH_BYTE (pos_byte)))
+      pos_byte--;
+  return make_number (BYTE_TO_CHAR (pos_byte));
 }
 \f
 DEFUN ("following-char", Ffollowing_char, Sfollowing_char, 0, 0, 0,
@@ -1229,7 +1205,7 @@ of the user with that uid, or nil if there is no such user.  */)
   /* Set up the user name info if we didn't do it before.
      (That can happen if Emacs is dumpable
      but you decide to run `temacs -l loadup' and not dump.  */
-  if (INTEGERP (Vuser_login_name))
+  if (NILP (Vuser_login_name))
     init_editfns ();
 
   if (NILP (uid))
@@ -1252,7 +1228,7 @@ This ignores the environment variables LOGNAME and USER, so it differs from
   /* Set up the user name info if we didn't do it before.
      (That can happen if Emacs is dumpable
      but you decide to run `temacs -l loadup' and not dump.  */
-  if (INTEGERP (Vuser_login_name))
+  if (NILP (Vuser_login_name))
     init_editfns ();
   return Vuser_real_login_name;
 }
@@ -1395,10 +1371,23 @@ invalid_time (void)
   error ("Invalid time specification");
 }
 
+/* Check a return value compatible with that of decode_time_components.  */
+static void
+check_time_validity (int validity)
+{
+  if (validity <= 0)
+    {
+      if (validity < 0)
+       time_overflow ();
+      else
+       invalid_time ();
+    }
+}
+
 /* A substitute for mktime_z on platforms that lack it.  It's not
    thread-safe, but should be good enough for Emacs in typical use.  */
 #ifndef HAVE_TZALLOC
-time_t
+static time_t
 mktime_z (timezone_t tz, struct tm *tm)
 {
   char *oldtz = getenv ("TZ");
@@ -1698,9 +1687,9 @@ decode_float_time (double t, struct lisp_time *result)
    If *DRESULT is not null, store into *DRESULT the number of
    seconds since the start of the POSIX Epoch.
 
-   Return true if successful, false if the components are of the
-   wrong type or represent a time out of range.  */
-bool
+   Return 1 if successful, 0 if the components are of the
+   wrong type, and -1 if the time is out of range.  */
+int
 decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
                        Lisp_Object psec,
                        struct lisp_time *result, double *dresult)
@@ -1708,17 +1697,17 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
   EMACS_INT hi, lo, us, ps;
   if (! (INTEGERP (high)
         && INTEGERP (usec) && INTEGERP (psec)))
-    return false;
+    return 0;
   if (! INTEGERP (low))
     {
       if (FLOATP (low))
        {
          double t = XFLOAT_DATA (low);
          if (result && ! decode_float_time (t, result))
-           return false;
+           return -1;
          if (dresult)
            *dresult = t;
-         return true;
+         return 1;
        }
       else if (NILP (low))
        {
@@ -1732,10 +1721,10 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
            }
          if (dresult)
            *dresult = now.tv_sec + now.tv_nsec / 1e9;
-         return true;
+         return 1;
        }
       else
-       return false;
+       return 0;
     }
 
   hi = XINT (high);
@@ -1755,7 +1744,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
   if (result)
     {
       if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM))
-       return false;
+       return -1;
       result->hi = hi;
       result->lo = lo;
       result->us = us;
@@ -1768,7 +1757,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
       *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS);
     }
 
-  return true;
+  return 1;
 }
 
 struct timespec
@@ -1792,8 +1781,8 @@ lisp_time_struct (Lisp_Object specified_time, int *plen)
   Lisp_Object high, low, usec, psec;
   struct lisp_time t;
   int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
-  if (! (len && decode_time_components (high, low, usec, psec, &t, 0)))
-    invalid_time ();
+  int val = len ? decode_time_components (high, low, usec, psec, &t, 0) : 0;
+  check_time_validity (val);
   *plen = len;
   return t;
 }
@@ -1818,13 +1807,20 @@ lisp_seconds_argument (Lisp_Object specified_time)
 {
   Lisp_Object high, low, usec, psec;
   struct lisp_time t;
-  if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
-        && decode_time_components (high, low, make_number (0),
-                                   make_number (0), &t, 0)))
-    invalid_time ();
-  if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi)
-        && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
-    time_overflow ();
+
+  int val = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
+  if (val != 0)
+    {
+      val = decode_time_components (high, low, make_number (0),
+                                   make_number (0), &t, 0);
+      if (0 < val
+         && ! ((TYPE_SIGNED (time_t)
+                ? TIME_T_MIN >> LO_TIME_BITS <= t.hi
+                : 0 <= t.hi)
+               && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
+       val = -1;
+    }
+  check_time_validity (val);
   return (t.hi << LO_TIME_BITS) + t.lo;
 }
 
@@ -2332,7 +2328,18 @@ set_time_zone_rule (const char *tzstring)
       tzval[tzeqlen] = 0;
     }
 
-  if (new_tzvalbuf)
+  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
+#endif
+      )
     {
       /* Although this is not thread-safe, in practice this runs only
         on startup when there is only one thread.  */
@@ -2746,7 +2753,15 @@ DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_subst
        doc: /* Insert before point a substring of the contents of BUFFER.
 BUFFER may be a buffer or a buffer name.
 Arguments START and END are character positions specifying the substring.
-They default to the values of (point-min) and (point-max) in BUFFER.  */)
+They default to the values of (point-min) and (point-max) in BUFFER.
+
+Point and before-insertion markers move forward to end up after the
+inserted text.
+Any other markers at the point of insertion remain before the text.
+
+If the current buffer is multibyte and BUFFER is unibyte, or vice
+versa, strings are converted from unibyte to multibyte or vice versa
+using `string-make-multibyte' or `string-make-unibyte', which see.  */)
   (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
 {
   register EMACS_INT b, e, temp;
@@ -4396,9 +4411,6 @@ usage: (format STRING &rest OBJECTS)  */)
     nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf);
   val = make_specified_string (buf, nchars, p - buf, multibyte);
 
-  /* If we allocated BUF with malloc, free it too.  */
-  SAFE_FREE ();
-
   /* If the format string has text properties, or any of the string
      arguments has text properties, set up text properties of the
      result string.  */
@@ -4504,14 +4516,10 @@ usage: (format STRING &rest OBJECTS)  */)
       UNGCPRO;
     }
 
-  return val;
-}
+  /* If we allocated BUF or INFO with malloc, free it too.  */
+  SAFE_FREE ();
 
-Lisp_Object
-format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1)
-{
-  AUTO_STRING (format, string1);
-  return CALLN (Fformat, format, arg0, arg1);
+  return val;
 }
 \f
 DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
@@ -4953,8 +4961,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_c_string ("buffer-access-fontify-functions")),
-         Qnil);
+    Fset (Fmake_local_variable (Qbuffer_access_fontify_functions), Qnil);
     Fset_buffer (obuf);
   }
 
@@ -4974,6 +4981,7 @@ functions if all the text being accessed has this property.  */);
 
   DEFVAR_LISP ("user-login-name", Vuser_login_name,
               doc: /* The user's name, taken from environment variables if possible.  */);
+  Vuser_login_name = Qnil;
 
   DEFVAR_LISP ("user-real-login-name", Vuser_real_login_name,
               doc: /* The user's name, based upon the real uid only.  */);