This commit was generated by cvs2svn to compensate for changes in r1705,
[chise/xemacs-chise.git.1] / src / editfns.c
index 339b431..1129eb1 100644 (file)
@@ -28,9 +28,6 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
 
 #include "buffer.h"
 #include "commands.h"
@@ -45,6 +42,7 @@ Boston, MA 02111-1307, USA.  */
 #include "systime.h"
 #include "sysdep.h"
 #include "syspwd.h"
+#include "sysfile.h"                   /* for getcwd */
 
 /* Some static data, and a function to initialize it for each run */
 
@@ -65,8 +63,6 @@ Lisp_Object Vuser_login_name; /* user name from LOGNAME or USER.  */
 Lisp_Object Vuser_full_name;
 EXFUN (Fuser_full_name, 1);
 
-char *get_system_name (void);
-
 Lisp_Object Qformat;
 
 Lisp_Object Qpoint, Qmark, Qregion_beginning, Qregion_end;
@@ -97,7 +93,7 @@ init_editfns (void)
   if ((p = getenv ("NAME")))
     /* I don't think it's the right thing to do the ampersand
        modification on NAME.  Not that it matters anymore...  -hniksic */
-    Vuser_full_name = build_ext_string (p, FORMAT_OS);
+    Vuser_full_name = build_ext_string (p, Qnative);
   else
     Vuser_full_name = Fuser_full_name (Qnil);
 }
@@ -132,7 +128,7 @@ An empty string will return the constant `nil'.
 */
        (str))
 {
-  struct Lisp_String *p;
+  Lisp_String *p;
   CHECK_STRING (str);
 
   p = XSTRING (str);
@@ -370,7 +366,7 @@ save_excursion_restore (Lisp_Object info)
         and cleaner never to alter the window/buffer connections.  */
       /* I'm certain some code somewhere depends on this behavior. --jwz */
       /* Even if it did, it certainly doesn't matter anymore, because
-         this has been the behaviour for countless XEmacs releases
+         this has been the behavior for countless XEmacs releases
          now.  --hniksic */
       if (visible
          && (current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)))
@@ -441,7 +437,8 @@ If BUFFER is nil, the current buffer is assumed.
 
 DEFUN ("point-min", Fpoint_min, 0, 1, 0, /*
 Return the minimum permissible value of point in BUFFER.
-This is 1, unless narrowing (a buffer restriction) is in effect.
+This is 1, unless narrowing (a buffer restriction)
+is in effect, in which case it may be greater.
 If BUFFER is nil, the current buffer is assumed.
 */
        (buffer))
@@ -452,7 +449,8 @@ If BUFFER is nil, the current buffer is assumed.
 
 DEFUN ("point-min-marker", Fpoint_min_marker, 0, 1, 0, /*
 Return a marker to the minimum permissible value of point in BUFFER.
-This is the beginning, unless narrowing (a buffer restriction) is in effect.
+This is the beginning, unless narrowing (a buffer restriction)
+is in effect, in which case it may be greater.
 If BUFFER is nil, the current buffer is assumed.
 */
        (buffer))
@@ -464,7 +462,7 @@ If BUFFER is nil, the current buffer is assumed.
 DEFUN ("point-max", Fpoint_max, 0, 1, 0, /*
 Return the maximum permissible value of point in BUFFER.
 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
-is in effect, in which case it is less.
+is in effect, in which case it may be less.
 If BUFFER is nil, the current buffer is assumed.
 */
        (buffer))
@@ -474,9 +472,9 @@ If BUFFER is nil, the current buffer is assumed.
 }
 
 DEFUN ("point-max-marker", Fpoint_max_marker, 0, 1, 0, /*
-Return a marker to the maximum permissible value of point BUFFER.
+Return a marker to the maximum permissible value of point in BUFFER.
 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
-is in effect, in which case it is less.
+is in effect, in which case it may be less.
 If BUFFER is nil, the current buffer is assumed.
 */
        (buffer))
@@ -549,7 +547,6 @@ If BUFFER is nil, the current buffer is assumed.
        (buffer))
 {
   struct buffer *b = decode_buffer (buffer, 1);
-
   return beginning_of_line_p (b, BUF_PT (b)) ? Qt : Qnil;
 }
 
@@ -566,11 +563,11 @@ If BUFFER is nil, the current buffer is assumed.
 }
 
 DEFUN ("char-after", Fchar_after, 0, 2, 0, /*
-Return character in BUFFER at position POS.
-POS is an integer or a buffer pointer.
+Return the character at position POS in BUFFER.
+POS is an integer or a marker.
 If POS is out of range, the value is nil.
-If BUFFER is nil, the current buffer is assumed.
 if POS is nil, the value of point is assumed.
+If BUFFER is nil, the current buffer is assumed.
 */
        (pos, buffer))
 {
@@ -584,17 +581,17 @@ if POS is nil, the value of point is assumed.
 }
 
 DEFUN ("char-before", Fchar_before, 0, 2, 0, /*
-Return character in BUFFER before position POS.
-POS is an integer or a buffer pointer.
+Return the character preceding position POS in BUFFER.
+POS is an integer or a marker.
 If POS is out of range, the value is nil.
-If BUFFER is nil, the current buffer is assumed.
 if POS is nil, the value of point is assumed.
+If BUFFER is nil, the current buffer is assumed.
 */
        (pos, buffer))
 {
   struct buffer *b = decode_buffer (buffer, 1);
-  Bufpos n = ((NILP (pos) ? BUF_PT (b) :
-              get_buffer_pos_char (b, pos, GB_NO_ERROR_IF_BAD)));
+  Bufpos n = (NILP (pos) ? BUF_PT (b) :
+             get_buffer_pos_char (b, pos, GB_NO_ERROR_IF_BAD));
 
   n--;
 
@@ -603,29 +600,75 @@ if POS is nil, the value of point is assumed.
   return make_char (BUF_FETCH_CHAR (b, n));
 }
 
+#if !defined(WINDOWSNT) && !defined(MSDOS)
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#endif
 \f
 DEFUN ("temp-directory", Ftemp_directory, 0, 0, 0, /*
 Return the pathname to the directory to use for temporary files.
-On NT/MSDOS, this is obtained from the TEMP or TMP environment variables,
+On MS Windows, this is obtained from the TEMP or TMP environment variables,
 defaulting to / if they are both undefined.
 On Unix it is obtained from TMPDIR, with /tmp as the default
 */
        ())
 {
   char *tmpdir;
-#if defined(WINDOWSNT) || defined(MSDOS)
+#if defined(WIN32_NATIVE)
   tmpdir = getenv ("TEMP");
   if (!tmpdir)
     tmpdir = getenv ("TMP");
   if (!tmpdir)
     tmpdir = "/";
-#else /* WINDOWSNT || MSDOS */
+#else /* WIN32_NATIVE */
  tmpdir = getenv ("TMPDIR");
  if (!tmpdir)
+    {
+      struct stat st;
+      int myuid = getuid();
+      static char path[5 /* strlen ("/tmp/") */ + 1 + _POSIX_PATH_MAX];
+
+      strcpy (path, "/tmp/");
+      strncat (path, user_login_name (NULL), _POSIX_PATH_MAX);
+      if (lstat(path, &st) < 0 && errno == ENOENT)
+       {
+         mkdir(path, 0700);    /* ignore retval -- checked next anyway. */
+       }
+      if (lstat(path, &st) == 0 && st.st_uid == myuid && S_ISDIR(st.st_mode))
+       {
+         tmpdir = path;
+       }
+      else
+       {
+         strcpy(path, getenv("HOME")); strncat(path, "/tmp/", _POSIX_PATH_MAX);
+         if (stat(path, &st) < 0 && errno == ENOENT)
+           {
+             int fd;
+             char warnpath[1+_POSIX_PATH_MAX];
+             mkdir(path, 0700);        /* ignore retvals */
+             strcpy(warnpath, path);
+             strncat(warnpath, ".created_by_xemacs", _POSIX_PATH_MAX);
+             if ((fd = open(warnpath, O_WRONLY|O_CREAT, 0644)) > 0)
+               {
+                 write(fd, "XEmacs created this directory because /tmp/<yourname> was unavailable -- \nPlease check !\n", 89);
+                 close(fd);
+               }
+           }
+         if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
+           {
+             tmpdir = path;
+           }
+         else
+           {
    tmpdir = "/tmp";
+           }
+       }
+    }
 #endif
 
-  return build_ext_string (tmpdir, FORMAT_FILENAME);
+  return build_ext_string (tmpdir, Qfile_name);
 }
 
 DEFUN ("user-login-name", Fuser_login_name, 0, 1, 0, /*
@@ -639,17 +682,17 @@ ignored and this function returns the login name for that UID, or nil.
        (uid))
 {
   char *returned_name;
-  int local_uid;
+  uid_t local_uid;
 
   if (!NILP (uid))
     {
       CHECK_INT (uid);
-      local_uid = XINT(uid);
-      returned_name = user_login_name(&local_uid);
+      local_uid = XINT (uid);
+      returned_name = user_login_name (&local_uid);
     }
   else
     {
-      returned_name = user_login_name(NULL);
+      returned_name = user_login_name (NULL);
     }
   /* #### - I believe this should return nil instead of "unknown" when pw==0
      pw=0 is indicated by a null return from user_login_name
@@ -665,14 +708,12 @@ ignored and this function returns the login name for that UID, or nil.
    corresponds to a nil argument to Fuser_login_name.
 */
 char*
-user_login_name (int *uid)
+user_login_name (uid_t *uid)
 {
-  struct passwd *pw = NULL;
-  
   /* uid == NULL to return name of this user */
   if (uid != NULL)
     {
-      pw = getpwuid (*uid);
+      struct passwd *pw = getpwuid (*uid);
       return pw ? pw->pw_name : NULL;
     }
   else
@@ -683,7 +724,7 @@ user_login_name (int *uid)
       char *user_name = getenv ("LOGNAME");
       if (!user_name)
        user_name = getenv (
-#ifdef WINDOWSNT
+#ifdef WIN32_NATIVE
                            "USERNAME" /* it's USERNAME on NT */
 #else
                            "USER"
@@ -693,8 +734,8 @@ user_login_name (int *uid)
        return (user_name);
       else
        {
-         pw = getpwuid (geteuid ());
-#ifdef __CYGWIN32__
+         struct passwd *pw = getpwuid (geteuid ());
+#ifdef CYGWIN
          /* Since the Cygwin environment may not have an /etc/passwd,
             return "unknown" instead of the null if the username
             cannot be determined.
@@ -718,14 +759,7 @@ This ignores the environment variables LOGNAME and USER, so it differs from
   struct passwd *pw = getpwuid (getuid ());
   /* #### - I believe this should return nil instead of "unknown" when pw==0 */
 
-#ifdef MSDOS
-  /* We let the real user name default to "root" because that's quite
-     accurate on MSDOG and because it lets Emacs find the init file.
-     (The DVX libraries override the Djgpp libraries here.)  */
-  Lisp_Object tem = build_string (pw ? pw->pw_name : "root");/* no gettext */
-#else
   Lisp_Object tem = build_string (pw ? pw->pw_name : "unknown");/* no gettext */
-#endif
   return tem;
 }
 
@@ -758,7 +792,7 @@ value of `user-full-name' is returned.
   Lisp_Object user_name;
   struct passwd *pw = NULL;
   Lisp_Object tem;
-  char *p, *q;
+  const char *p, *q;
 
   if (NILP (user) && STRINGP (Vuser_full_name))
     return Vuser_full_name;
@@ -766,11 +800,13 @@ value of `user-full-name' is returned.
   user_name = (STRINGP (user) ? user : Fuser_login_name (user));
   if (!NILP (user_name))       /* nil when nonexistent UID passed as arg */
     {
-      CONST char *user_name_ext;
+      const char *user_name_ext;
 
       /* Fuck me.  getpwnam() can call select() and (under IRIX at least)
         things get wedged if a SIGIO arrives during this time. */
-      GET_C_STRING_OS_DATA_ALLOCA (user_name, user_name_ext);
+      TO_EXTERNAL_FORMAT (LISP_STRING, user_name,
+                         C_STRING_ALLOCA, user_name_ext,
+                         Qnative);
       slow_down_interrupts ();
       pw = (struct passwd *) getpwnam (user_name_ext);
       speed_up_interrupts ();
@@ -779,16 +815,16 @@ value of `user-full-name' is returned.
   /* #### - Stig sez: this should return nil instead of "unknown" when pw==0 */
   /* Ben sez: bad idea because it's likely to break something */
 #ifndef AMPERSAND_FULL_NAME
-  p = ((pw) ? USER_FULL_NAME : "unknown"); /* don't gettext */
+  p = pw ? USER_FULL_NAME : "unknown"; /* don't gettext */
   q = strchr (p, ',');
 #else
-  p = ((pw) ? USER_FULL_NAME : "unknown"); /* don't gettext */
+  p = pw ? USER_FULL_NAME : "unknown"; /* don't gettext */
   q = strchr (p, ',');
 #endif
   tem = ((!NILP (user) && !pw)
         ? Qnil
         : make_ext_string ((Extbyte *) p, (q ? q - p : strlen (p)),
-                           FORMAT_OS));
+                           Qnative));
 
 #ifdef AMPERSAND_FULL_NAME
   if (!NILP (tem))
@@ -813,7 +849,7 @@ value of `user-full-name' is returned.
   return tem;
 }
 
-static char *cached_home_directory;
+static Extbyte *cached_home_directory;
 
 void
 uncache_home_directory (void)
@@ -822,28 +858,42 @@ uncache_home_directory (void)
                                   of a few bytes */
 }
 
-char *
+/* !!#### not Mule correct. */
+
+/* Returns the home directory, in external format */
+Extbyte *
 get_home_directory (void)
 {
+  /* !!#### this is hopelessly bogus.  Rule #1: Do not make any assumptions
+     about what format an external string is in.  Could be Unicode, for all
+     we know, and then all the operations below are totally bogus.
+     Instead, convert all data to internal format *right* at the juncture
+     between XEmacs and the outside world, the very moment we first get
+     the data.  --ben */
   int output_home_warning = 0;
 
   if (cached_home_directory == NULL)
     {
-      if ((cached_home_directory = getenv("HOME")) == NULL)
+      if ((cached_home_directory = (Extbyte *) getenv("HOME")) == NULL)
        {
-#if defined(WINDOWSNT) && !defined(__CYGWIN32__)
-         char  *homedrive, *homepath;
+#if defined(WIN32_NATIVE)
+         char *homedrive, *homepath;
+
          if ((homedrive = getenv("HOMEDRIVE")) != NULL &&
              (homepath = getenv("HOMEPATH")) != NULL)
            {
              cached_home_directory =
-               (char *) xmalloc(strlen(homedrive) + strlen(homepath) + 1);
-             sprintf(cached_home_directory, "%s%s", homedrive, homepath);
+               (Extbyte *) xmalloc (strlen (homedrive) +
+                                    strlen (homepath) + 1);
+             sprintf((char *) cached_home_directory, "%s%s",
+                     homedrive,
+                     homepath);
            }
          else
            {
-# if 1
+# if 0 /* changed by ben.  This behavior absolutely stinks, and the
+         possibility being addressed here occurs quite commonly.
+         Using the current directory makes absolutely no sense. */
              /*
               * Use the current directory.
               * This preserves the existing XEmacs behavior, but is different
@@ -851,44 +901,44 @@ get_home_directory (void)
               */
              if (initial_directory[0] != '\0')
                {
-                 cached_home_directory = initial_directory;
+                 cached_home_directory = (Extbyte*) initial_directory;
                }
              else
                {
                  /* This will probably give the wrong value */
-                 cached_home_directory = getcwd (NULL, 0);
+                 cached_home_directory = (Extbyte*) getcwd (NULL, 0);
                }
 # else
              /*
               * This is NT Emacs behavior
               */
-             cached_home_directory = "C:\\";
+             cached_home_directory = (Extbyte *) "C:\\";
              output_home_warning = 1;
 # endif
            }
-#else  /* !WINDOWSNT */
+#else  /* !WIN32_NATIVE */
          /*
           * Unix, typically.
           * Using "/" isn't quite right, but what should we do?
           * We probably should try to extract pw_dir from /etc/passwd,
           * before falling back to this.
           */
-         cached_home_directory = "/";
+         cached_home_directory = (Extbyte *) "/";
          output_home_warning = 1;
-#endif /* !WINDOWSNT */
+#endif /* !WIN32_NATIVE */
        }
       if (initialized && output_home_warning)
        {
-         warn_when_safe(Quser_files_and_directories, Qwarning, "\n"
+         warn_when_safe (Quser_files_and_directories, Qwarning, "\n"
 "      XEmacs was unable to determine a good value for the user's $HOME\n"
 "      directory, and will be using the value:\n"
 "              %s\n"
 "      This is probably incorrect.",
-                        cached_home_directory
-                        );
+                         cached_home_directory
+                         );
        }
     }
-  return (cached_home_directory);
+  return cached_home_directory;
 }
 
 DEFUN ("user-home-directory", Fuser_home_directory, 0, 0, 0, /*
@@ -896,18 +946,12 @@ Return the user's home directory, as a string.
 */
        ())
 {
-  Lisp_Object directory;
-  char *path;
+  Extbyte *path = get_home_directory ();
 
-  directory = Qnil;
-  path = get_home_directory ();
-  if (path != NULL)
-    {
-      directory =
-       Fexpand_file_name (Fsubstitute_in_file_name (build_string (path)),
-                          Qnil);
-    }
-  return (directory);
+  return path == NULL ? Qnil :
+    Fexpand_file_name (Fsubstitute_in_file_name
+                      (build_ext_string ((char *) path, Qfile_name)),
+                      Qnil);
 }
 
 DEFUN ("system-name", Fsystem_name, 0, 0, 0, /*
@@ -918,14 +962,6 @@ Return the name of the machine you are running on, as a string.
     return Fcopy_sequence (Vsystem_name);
 }
 
-/* For the benefit of callers who don't want to include lisp.h.
-   Caller must free! */
-char *
-get_system_name (void)
-{
-  return xstrdup ((char *) XSTRING_DATA (Vsystem_name));
-}
-
 DEFUN ("emacs-pid", Femacs_pid, 0, 0, 0, /*
 Return the process ID of Emacs, as an integer.
 */
@@ -1014,9 +1050,9 @@ time_to_lisp (time_t the_time)
   return Fcons (make_int (item >> 16), make_int (item & 0xffff));
 }
 
-size_t emacs_strftime (char *string, size_t max, CONST char *format,
-                      CONST struct tm *tm);
-static long difftm (CONST struct tm *a, CONST struct tm *b);
+size_t emacs_strftime (char *string, size_t max, const char *format,
+                      const struct tm *tm);
+static long difftm (const struct tm *a, const struct tm *b);
 
 
 DEFUN ("format-time-string", Fformat_time_string, 1, 2, 0, /*
@@ -1046,6 +1082,8 @@ FORMAT-STRING may contain %-sequences to substitute parts of the time.
 %p is replaced by AM or PM, as appropriate.
 %r is a synonym for "%I:%M:%S %p".
 %R is a synonym for "%H:%M".
+%s is replaced by the time in seconds since 00:00:00, Jan 1, 1970 (a
+      nonstandard extension)
 %S is replaced by the second (00-60).
 %t is a synonym for "\\t".
 %T is a synonym for "%H:%M:%S".
@@ -1063,14 +1101,14 @@ The number of options reflects the `strftime' function.
 BUG: If the charset used by the current locale is not ISO 8859-1, the
 characters appearing in the day and month names may be incorrect.
 */
-       (format_string, _time))
+       (format_string, time_))
 {
   time_t value;
   size_t size;
 
   CHECK_STRING (format_string);
 
-  if (! lisp_to_time (_time, &value))
+  if (! lisp_to_time (time_, &value))
     error ("Invalid time specification");
 
   /* This is probably enough.  */
@@ -1081,10 +1119,10 @@ characters appearing in the day and month names may be incorrect.
       char *buf = (char *) alloca (size);
       *buf = 1;
       if (emacs_strftime (buf, size,
-                         (CONST char *) XSTRING_DATA (format_string),
+                         (const char *) XSTRING_DATA (format_string),
                          localtime (&value))
          || !*buf)
-       return build_ext_string (buf, FORMAT_BINARY);
+       return build_ext_string (buf, Qbinary);
       /* If buffer was too small, make it bigger.  */
       size *= 2;
     }
@@ -1115,13 +1153,13 @@ ZONE is an integer indicating the number of seconds east of Greenwich.
     error ("Invalid time specification");
 
   decoded_time = localtime (&time_spec);
-  XSETINT (list_args[0], decoded_time->tm_sec);
-  XSETINT (list_args[1], decoded_time->tm_min);
-  XSETINT (list_args[2], decoded_time->tm_hour);
-  XSETINT (list_args[3], decoded_time->tm_mday);
-  XSETINT (list_args[4], decoded_time->tm_mon + 1);
-  XSETINT (list_args[5], decoded_time->tm_year + 1900);
-  XSETINT (list_args[6], decoded_time->tm_wday);
+  list_args[0] = make_int (decoded_time->tm_sec);
+  list_args[1] = make_int (decoded_time->tm_min);
+  list_args[2] = make_int (decoded_time->tm_hour);
+  list_args[3] = make_int (decoded_time->tm_mday);
+  list_args[4] = make_int (decoded_time->tm_mon + 1);
+  list_args[5] = make_int (decoded_time->tm_year + 1900);
+  list_args[6] = make_int (decoded_time->tm_wday);
   list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
 
   /* Make a copy, in case gmtime modifies the struct.  */
@@ -1130,7 +1168,7 @@ ZONE is an integer indicating the number of seconds east of Greenwich.
   if (decoded_time == 0)
     list_args[8] = Qnil;
   else
-    XSETINT (list_args[8], difftm (&save_tm, decoded_time));
+    list_args[8] = make_int (difftm (&save_tm, decoded_time));
   return Flist (9, list_args);
 }
 
@@ -1156,7 +1194,7 @@ If you want them to stand for years in this century, you must do that yourself.
 */
        (int nargs, Lisp_Object *args))
 {
-  time_t _time;
+  time_t the_time;
   struct tm tm;
   Lisp_Object zone = (nargs > 6) ? args[nargs - 1] : Qnil;
 
@@ -1172,7 +1210,7 @@ If you want them to stand for years in this century, you must do that yourself.
   if (CONSP (zone))
     zone = XCAR (zone);
   if (NILP (zone))
-    _time = mktime (&tm);
+    the_time = mktime (&tm);
   else
     {
       char tzbuf[100];
@@ -1195,7 +1233,7 @@ If you want them to stand for years in this century, you must do that yourself.
         value doesn't suffice, since that would mishandle leap seconds.  */
       set_time_zone_rule (tzstring);
 
-      _time = mktime (&tm);
+      the_time = mktime (&tm);
 
       /* Restore TZ to previous value.  */
       newenv = environ;
@@ -1206,10 +1244,10 @@ If you want them to stand for years in this century, you must do that yourself.
 #endif
     }
 
-  if (_time == (time_t) -1)
+  if (the_time == (time_t) -1)
     error ("Specified time is not representable");
 
-  return wasteful_word_to_lisp (_time);
+  return wasteful_word_to_lisp (the_time);
 }
 
 DEFUN ("current-time-string", Fcurrent_time_string, 0, 1, 0, /*
@@ -1228,24 +1266,26 @@ and from `file-attributes'.
        (specified_time))
 {
   time_t value;
-  char buf[30];
-  char *tem;
+  char *the_ctime;
+  size_t len;
 
   if (! lisp_to_time (specified_time, &value))
     value = -1;
-  tem = (char *) ctime (&value);
+  the_ctime = ctime (&value);
 
-  strncpy (buf, tem, 24);
-  buf[24] = 0;
+  /* ctime is documented as always returning a "\n\0"-terminated
+     26-byte American time string, but let's be careful anyways. */
+  for (len = 0; the_ctime[len] != '\n' && the_ctime[len] != '\0'; len++)
+    ;
 
-  return build_ext_string (buf, FORMAT_BINARY);
+  return make_ext_string ((Extbyte *) the_ctime, len, Qbinary);
 }
 
 #define TM_YEAR_ORIGIN 1900
 
 /* Yield A - B, measured in seconds.  */
 static long
-difftm (CONST struct tm *a, CONST struct tm *b)
+difftm (const struct tm *a, const struct tm *b)
 {
   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
@@ -1832,7 +1872,7 @@ Returns the number of substitutions performed.
   mc_count = begin_multiple_change (buf, pos, stop);
   if (STRINGP (table))
     {
-      struct Lisp_String *stable = XSTRING (table);
+      Lisp_String *stable = XSTRING (table);
       Charcount size = string_char_length (stable);
 #ifdef MULE
       /* Under Mule, string_char(n) is O(n), so for large tables or
@@ -1912,7 +1952,7 @@ Returns the number of substitutions performed.
           && (XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_GENERIC
               || XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_CHAR))
     {
-      struct Lisp_Char_Table *ctable = XCHAR_TABLE (table);
+      Lisp_Char_Table *ctable = XCHAR_TABLE (table);
 
       for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
        {
@@ -2246,17 +2286,16 @@ If BUFFER is nil, the current buffer is assumed.
     ? Qt : Qnil;
 }
 
-DEFUN ("char=", Fchar_Equal, 2, 3, 0, /*
+DEFUN ("char=", Fchar_Equal, 2, 2, 0, /*
 Return t if two characters match, case is significant.
 Both arguments must be characters (i.e. NOT integers).
-The optional buffer argument is for symmetry and is ignored.
 */
-       (c1, c2, buffer))
+       (c1, c2))
 {
   CHECK_CHAR_COERCE_INT (c1);
   CHECK_CHAR_COERCE_INT (c2);
 
-  return XCHAR(c1) == XCHAR(c2) ? Qt : Qnil;
+  return EQ (c1, c2) ? Qt : Qnil;
 }
 \f
 #if 0 /* Undebugged FSFmacs code */
@@ -2522,6 +2561,8 @@ zmacs-activate-region. Setting this to true lets a command be non-intrusive.
 See the variable `zmacs-regions'.
 
 The same effect can be achieved using the `_' interactive specification.
+
+`zmacs-region-stays' is reset to nil before each command is executed.
 */ );
   zmacs_region_stays = 0;