(read_minibuf_unwind): Clear last_overlay_modified field.
[bpt/emacs.git] / src / editfns.c
index dc5e798..92daf88 100644 (file)
@@ -178,7 +178,7 @@ Beginning of buffer is position (point-min)")
   ()
 {
   Lisp_Object temp;
-  XSETFASTINT (temp, point);
+  XSETFASTINT (temp, PT);
   return temp;
 }
 
@@ -186,7 +186,7 @@ DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
    "Return value of point, as a marker object.")
   ()
 {
-  return buildmark (point);
+  return buildmark (PT);
 }
 
 int
@@ -224,8 +224,8 @@ region_limit (beginningp)
     Fsignal (Qmark_inactive, Qnil);
   m = Fmarker_position (current_buffer->mark);
   if (NILP (m)) error ("There is no region now");
-  if ((point < XFASTINT (m)) == beginningp)
-    return (make_number (point));
+  if ((PT < XFASTINT (m)) == beginningp)
+    return (make_number (PT));
   else
     return (m);
 }
@@ -393,10 +393,10 @@ At the end of the buffer or accessible region, return 0.")
   ()
 {
   Lisp_Object temp;
-  if (point >= ZV)
+  if (PT >= ZV)
     XSETFASTINT (temp, 0);
   else
-    XSETFASTINT (temp, FETCH_CHAR (point));
+    XSETFASTINT (temp, FETCH_CHAR (PT));
   return temp;
 }
 
@@ -406,10 +406,10 @@ At the beginning of the buffer or accessible region, return 0.")
   ()
 {
   Lisp_Object temp;
-  if (point <= BEGV)
+  if (PT <= BEGV)
     XSETFASTINT (temp, 0);
   else
-    XSETFASTINT (temp, FETCH_CHAR (point - 1));
+    XSETFASTINT (temp, FETCH_CHAR (PT - 1));
   return temp;
 }
 
@@ -418,7 +418,7 @@ DEFUN ("bobp", Fbobp, Sbobp, 0, 0, 0,
 If the buffer is narrowed, this means the beginning of the narrowed part.")
   ()
 {
-  if (point == BEGV)
+  if (PT == BEGV)
     return Qt;
   return Qnil;
 }
@@ -428,7 +428,7 @@ DEFUN ("eobp", Feobp, Seobp, 0, 0, 0,
 If the buffer is narrowed, this means the end of the narrowed part.")
   ()
 {
-  if (point == ZV)
+  if (PT == ZV)
     return Qt;
   return Qnil;
 }
@@ -437,7 +437,7 @@ DEFUN ("bolp", Fbolp, Sbolp, 0, 0, 0,
   "Return T if point is at the beginning of a line.")
   ()
 {
-  if (point == BEGV || FETCH_CHAR (point - 1) == '\n')
+  if (PT == BEGV || FETCH_CHAR (PT - 1) == '\n')
     return Qt;
   return Qnil;
 }
@@ -447,7 +447,7 @@ DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
 `End of a line' includes point being at the end of the buffer.")
   ()
 {
-  if (point == ZV || FETCH_CHAR (point) == '\n')
+  if (PT == ZV || FETCH_CHAR (PT) == '\n')
     return Qt;
   return Qnil;
 }
@@ -693,7 +693,7 @@ ZONE is an integer indicating the number of seconds east of Greenwich.\n\
   XSETFASTINT (list_args[2], decoded_time->tm_hour);
   XSETFASTINT (list_args[3], decoded_time->tm_mday);
   XSETFASTINT (list_args[4], decoded_time->tm_mon + 1);
-  XSETFASTINT (list_args[5], decoded_time->tm_year + 1900);
+  XSETINT (list_args[5], decoded_time->tm_year + 1900);
   XSETFASTINT (list_args[6], decoded_time->tm_wday);
   list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
 
@@ -711,7 +711,7 @@ DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
   "Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.\n\
 This is the reverse operation of `decode-time', which see.\n\
 ZONE defaults to the current time zone rule.  This can\n\
-be a string (as from `set-time-zone-rule'), or it can be a list\n\
+be a string or t (as from `set-time-zone-rule'), or it can be a list\n\
 (as from `current-time-zone') or an integer (as from `decode-time')\n\
 applied without consideration for daylight savings time.\n\
 \n\
@@ -757,7 +757,9 @@ If you want them to stand for years in this century, you must do that yourself."
       char *tzstring;
       char **oldenv = environ, **newenv;
       
-      if (STRINGP (zone))
+      if (zone == Qt)
+       tzstring = "UTC0";
+      else if (STRINGP (zone))
        tzstring = (char *) XSTRING (zone)->data;
       else if (INTEGERP (zone))
        {
@@ -828,14 +830,17 @@ difftm (a, b)
 {
   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
+  /* Divide years by 100, rounding towards minus infinity.  */
+  int ac = ay / 100 - (ay % 100 < 0);
+  int bc = by / 100 - (by % 100 < 0);
   /* Some compilers can't handle this as a single return statement.  */
   long days = (
              /* difference in day of year */
              a->tm_yday - b->tm_yday
              /* + intervening leap days */
              +  ((ay >> 2) - (by >> 2))
-             -  (ay/100 - by/100)
-             +  ((ay/100 >> 2) - (by/100 >> 2))
+             -  (ac - bc)
+             +  ((ac >> 2) - (bc >> 2))
              /* + difference in years * 365 */
              +  (long)(ay-by) * 365
              );
@@ -907,7 +912,8 @@ static char **environbuf;
 
 DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
   "Set the local time zone using TZ, a string specifying a time zone rule.\n\
-If TZ is nil, use implementation-defined default time zone information.")
+If TZ is nil, use implementation-defined default time zone information.\n\
+If TZ is t, use Universal Time.")
   (tz)
      Lisp_Object tz;
 {
@@ -915,6 +921,8 @@ If TZ is nil, use implementation-defined default time zone information.")
 
   if (NILP (tz))
     tzstring = 0;
+  else if (tz == Qt)
+    tzstring = "UTC0";
   else
     {
       CHECK_STRING (tz, 0);
@@ -929,6 +937,17 @@ If TZ is nil, use implementation-defined default time zone information.")
   return Qnil;
 }
 
+/* These two values are known to load tz files in buggy implementations.
+   Their values shouldn't matter in non-buggy implementations.
+   We don't use string literals for these strings, 
+   since if a string in the environment is in readonly
+   storage, it runs afoul of bugs in SVR4 and Solaris 2.3.
+   See Sun bugs 1113095 and 1114114, ``Timezone routines
+   improperly modify environment''.  */
+
+static char set_time_zone_rule_tz1[] = "TZ=GMT0";
+static char set_time_zone_rule_tz2[] = "TZ=GMT1";
+
 /* Set the local time zone rule to TZSTRING.
    This allocates memory into `environ', which it is the caller's
    responsibility to free.  */
@@ -939,11 +958,14 @@ set_time_zone_rule (tzstring)
   int envptrs;
   char **from, **to, **newenv;
 
+  /* Make the ENVIRON vector longer with room for TZSTRING.  */
   for (from = environ; *from; from++)
     continue;
   envptrs = from - environ + 2;
   newenv = to = (char **) xmalloc (envptrs * sizeof (char *)
                                   + (tzstring ? strlen (tzstring) + 4 : 0));
+
+  /* Add TZSTRING to the end of environ, as a value for TZ.  */
   if (tzstring)
     {
       char *t = (char *) (to + envptrs);
@@ -952,6 +974,9 @@ set_time_zone_rule (tzstring)
       *to++ = t;
     }
 
+  /* Copy the old environ vector elements into NEWENV,
+     but don't copy the TZ variable.
+     So we have only one definition of TZ, which came from TZSTRING.  */
   for (from = environ; *from; from++)
     if (strncmp (*from, "TZ=", 3) != 0)
       *to++ = *from;
@@ -959,7 +984,45 @@ set_time_zone_rule (tzstring)
 
   environ = newenv;
 
+  /* If we do have a TZSTRING, NEWENV points to the vector slot where
+     the TZ variable is stored.  If we do not have a TZSTRING,
+     TO points to the vector slot which has the terminating null.  */
+
 #ifdef LOCALTIME_CACHE
+  {
+    /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
+       "US/Pacific" that loads a tz file, then changes to a value like
+       "XXX0" that does not load a tz file, and then changes back to
+       its original value, the last change is (incorrectly) ignored.
+       Also, if TZ changes twice in succession to values that do
+       not load a tz file, tzset can dump core (see Sun bug#1225179).
+       The following code works around these bugs.  */
+
+    if (tzstring)
+      {
+       /* Temporarily set TZ to a value that loads a tz file
+          and that differs from tzstring.  */
+       char *tz = *newenv;
+       *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0
+                  ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1);
+       tzset ();
+       *newenv = tz;
+      }
+    else
+      {
+       /* The implied tzstring is unknown, so temporarily set TZ to
+          two different values that each load a tz file.  */
+       *to = set_time_zone_rule_tz1;
+       to[1] = 0;
+       tzset ();
+       *to = set_time_zone_rule_tz2;
+       tzset ();
+       *to = 0;
+      }
+
+    /* Now TZ has the desired value, and tzset can be invoked safely.  */
+  }
+
   tzset ();
 #endif
 }
@@ -1301,6 +1364,8 @@ They default to the beginning and the end of BUFFER.")
   if (NILP (buffer))
     nsberror (buf);
   bp = XBUFFER (buffer);
+  if (NILP (bp->name))
+    error ("Selecting deleted buffer");
 
   if (NILP (start))
     b = BUF_BEGV (bp);
@@ -1361,6 +1426,8 @@ determines whether case is significant or ignored.")
       if (NILP (buf1))
        nsberror (buffer1);
       bp1 = XBUFFER (buf1);
+      if (NILP (bp1->name))
+       error ("Selecting deleted buffer");
     }
 
   if (NILP (start1))
@@ -1397,6 +1464,8 @@ determines whether case is significant or ignored.")
       if (NILP (buf2))
        nsberror (buffer2);
       bp2 = XBUFFER (buf2);
+      if (NILP (bp2->name))
+       error ("Selecting deleted buffer");
     }
 
   if (NILP (start2))
@@ -1636,9 +1705,9 @@ or markers) bounding the text that should remain visible.")
 
   BEGV = XFASTINT (start);
   SET_BUF_ZV (current_buffer, XFASTINT (end));
-  if (point < XFASTINT (start))
+  if (PT < XFASTINT (start))
     SET_PT (XFASTINT (start));
-  if (point > XFASTINT (end))
+  if (PT > XFASTINT (end))
     SET_PT (XFASTINT (end));
   current_buffer->clip_changed = 1;
   /* Changing the buffer bounds invalidates any recorded current column.  */
@@ -1984,7 +2053,7 @@ Use %% to put a single % into the output.")
             because it is the format string.  */
          strings[i++] = XSTRING (args[n])->data;
        else
-         strings[i++] = (unsigned char *) XFASTINT (args[n]);
+         strings[i++] = (unsigned char *) XSTRING (args[n]);
       }
 
     /* Make room in result for all the non-%-codes in the control string.  */