(M40310): Separate U+925B, C1-6745 and J90-3174.
[chise/xemacs-chise.git] / src / buffer.c
index d235117..19d6345 100644 (file)
@@ -96,6 +96,7 @@ struct buffer *current_buffer;        /* the current buffer */
    Setting the default value also goes through the alist of buffers
    and stores into each buffer that does not say it has a local value.  */
 Lisp_Object Vbuffer_defaults;
+static void *buffer_defaults_saved_slots;
 
 /* This structure marks which slots in a buffer have corresponding
    default values in Vbuffer_defaults.
@@ -126,12 +127,14 @@ struct buffer buffer_local_flags;
 
 /* This is the initial (startup) directory, as used for the *scratch* buffer.
    We're making this a global to make others aware of the startup directory.
+   `initial_directory' is stored in external format.
  */
 char initial_directory[MAXPATHLEN+1];
 
 /* This structure holds the names of symbols whose values may be
    buffer-local.  It is indexed and accessed in the same way as the above. */
 static Lisp_Object Vbuffer_local_symbols;
+static void *buffer_local_symbols_saved_slots;
 
 /* Alist of all buffer names vs the buffers. */
 /* This used to be a variable, but is no longer,
@@ -188,7 +191,7 @@ Lisp_Object QSscratch;          /* "*scratch*" */
 Lisp_Object Qdefault_directory;
 
 Lisp_Object Qkill_buffer_hook;
-Lisp_Object Qbuffer_file_name, Qbuffer_undo_list;
+Lisp_Object Qrecord_buffer_hook;
 
 Lisp_Object Qrename_auto_save_file;
 
@@ -219,7 +222,7 @@ make_buffer (struct buffer *buf)
 }
 
 static Lisp_Object
-mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_buffer (Lisp_Object obj)
 {
   struct buffer *buf = XBUFFER (obj);
 
@@ -228,13 +231,13 @@ mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object))
                                        undo_threshold,
                                        undo_high_threshold);
 
-#define MARKED_SLOT(x) ((void) (markobj (buf->x)));
+#define MARKED_SLOT(x) mark_object (buf->x)
 #include "bufslots.h"
 #undef MARKED_SLOT
 
-  markobj (buf->extent_info);
+  mark_object (buf->extent_info);
   if (buf->text)
-    markobj (buf->text->line_number_cache);
+    mark_object (buf->text->line_number_cache);
 
   /* Don't mark normally through the children slot.
      (Actually, in this case, it doesn't matter.)  */
@@ -275,7 +278,7 @@ print_buffer (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
    because all buffers have `kill-buffer' applied to them before
    they disappear, and the children removal happens then. */
 DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer,
-                               mark_buffer, print_buffer, 0, 0, 0,
+                               mark_buffer, print_buffer, 0, 0, 0, 0,
                               struct buffer);
 \f
 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /*
@@ -540,7 +543,7 @@ get_truename_buffer (REGISTER Lisp_Object filename)
 static struct buffer *
 allocate_buffer (void)
 {
-  struct buffer *b = alloc_lcrecord_type (struct buffer, lrecord_buffer);
+  struct buffer *b = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
 
   copy_lcrecord (b, XBUFFER (Vbuffer_defaults));
 
@@ -1125,7 +1128,7 @@ No argument or nil as argument means do this for the current buffer.
 }
 
 DEFUN ("kill-buffer", Fkill_buffer, 1, 1, "bKill buffer: ", /*
-Kill the buffer BUFNAME.
+Kill the buffer BUFFER.
 The argument may be a buffer or may be the name of a buffer.
 An argument of nil means kill the current buffer.
 
@@ -1139,21 +1142,21 @@ when the hook functions are called.
 Any processes that have this buffer as the `process-buffer' are killed
 with `delete-process'.
 */
-       (bufname))
+       (buffer))
 {
   /* This function can call lisp */
   Lisp_Object buf;
   REGISTER struct buffer *b;
   struct gcpro gcpro1, gcpro2;
 
-  if (NILP (bufname))
+  if (NILP (buffer))
     buf = Fcurrent_buffer ();
-  else if (BUFFERP (bufname))
-    buf = bufname;
+  else if (BUFFERP (buffer))
+    buf = buffer;
   else
     {
-      buf = get_buffer (bufname, 0);
-      if (NILP (buf)) nsberror (bufname);
+      buf = get_buffer (buffer, 0);
+      if (NILP (buf)) nsberror (buffer);
     }
 
   b = XBUFFER (buf);
@@ -1175,7 +1178,7 @@ with `delete-process'.
       && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
     {
       Lisp_Object killp;
-      GCPRO2 (buf, bufname);
+      GCPRO1 (buf);
       killp = call1
        (Qyes_or_no_p,
         (emacs_doprnt_string_c
@@ -1361,7 +1364,7 @@ with `delete-process'.
 }
 \f
 DEFUN ("record-buffer", Frecord_buffer, 1, 1, 0, /*
-Place buffer BUF first in the buffer order.
+Place buffer BUFFER first in the buffer order.
 Call this function when a buffer is selected "visibly".
 
 This function changes the global buffer order and the per-frame buffer
@@ -1369,7 +1372,7 @@ order for the selected frame.  The buffer order keeps track of recency
 of selection so that `other-buffer' will return a recently selected
 buffer.  See `other-buffer' for more information.
 */
-       (buf))
+       (buffer))
 {
   REGISTER Lisp_Object lynk, prev;
   struct frame *f = selected_frame ();
@@ -1377,7 +1380,7 @@ buffer.  See `other-buffer' for more information.
   prev = Qnil;
   for (lynk = Vbuffer_alist; CONSP (lynk); lynk = XCDR (lynk))
     {
-      if (EQ (XCDR (XCAR (lynk)), buf))
+      if (EQ (XCDR (XCAR (lynk)), buffer))
        break;
       prev = lynk;
     }
@@ -1394,7 +1397,7 @@ buffer.  See `other-buffer' for more information.
   prev = Qnil;
   for (lynk = f->buffer_alist; CONSP (lynk); lynk = XCDR (lynk))
     {
-      if (EQ (XCDR (XCAR (lynk)), buf))
+      if (EQ (XCDR (XCAR (lynk)), buffer))
        break;
       prev = lynk;
     }
@@ -1405,6 +1408,9 @@ buffer.  See `other-buffer' for more information.
     XCDR (prev) = XCDR (XCDR (prev));
   XCDR (lynk) = f->buffer_alist;
   f->buffer_alist = lynk;
+
+  va_run_hook_with_args (Qrecord_buffer_hook, 1, buffer);
+  
   return Qnil;
 }
 
@@ -1413,15 +1419,14 @@ Set an appropriate major mode for BUFFER, according to `default-major-mode'.
 Use this function before selecting the buffer, since it may need to inspect
 the current buffer's major mode.
 */
-       (buf))
+       (buffer))
 {
   int speccount = specpdl_depth ();
-  REGISTER Lisp_Object function, tem;
+  Lisp_Object function = XBUFFER (Vbuffer_defaults)->major_mode;
 
-  function = XBUFFER (Vbuffer_defaults)->major_mode;
   if (NILP (function))
     {
-      tem = Fget (current_buffer->major_mode, Qmode_class, Qnil);
+      Lisp_Object tem = Fget (current_buffer->major_mode, Qmode_class, Qnil);
       if (NILP (tem))
        function = current_buffer->major_mode;
     }
@@ -1434,7 +1439,7 @@ the current buffer's major mode.
 
   record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
 
-  Fset_buffer (buf);
+  Fset_buffer (buffer);
   call0 (function);
 
   return unbind_to (speccount, Qnil);
@@ -1452,9 +1457,9 @@ Return the current buffer as a Lisp object.
 */
        ())
 {
-  Lisp_Object buf;
-  XSETBUFFER (buf, current_buffer);
-  return buf;
+  Lisp_Object buffer;
+  XSETBUFFER (buffer, current_buffer);
+  return buffer;
 }
 \f
 /* Set the current buffer to B.  */
@@ -1619,6 +1624,8 @@ thus, the least likely buffer for \\[switch-to-buffer] to select by default.
 If BUFFER is nil or omitted, bury the current buffer.
 Also, if BUFFER is nil or omitted, remove the current buffer from the
 selected window if it is displayed there.
+Because of this, you may need to specify (current-buffer) as
+BUFFER when calling from minibuffer.
 If BEFORE is non-nil, it specifies a buffer before which BUFFER
 will be placed, instead of being placed at the end.
 */
@@ -1806,6 +1813,7 @@ syms_of_buffer (void)
   defsymbol (&Qmode_class, "mode-class");
   defsymbol (&Qrename_auto_save_file, "rename-auto-save-file");
   defsymbol (&Qkill_buffer_hook, "kill-buffer-hook");
+  defsymbol (&Qrecord_buffer_hook, "record-buffer-hook");
   defsymbol (&Qpermanent_local, "permanent-local");
 
   defsymbol (&Qfirst_change_hook, "first-change-hook");
@@ -1816,8 +1824,6 @@ syms_of_buffer (void)
   defsymbol (&Qbefore_change_function, "before-change-function");
   defsymbol (&Qafter_change_function, "after-change-function");
 
-  defsymbol (&Qbuffer_file_name, "buffer-file-name");
-  defsymbol (&Qbuffer_undo_list, "buffer-undo-list");
   defsymbol (&Qdefault_directory, "default-directory");
 
   defsymbol (&Qget_file_buffer, "get-file-buffer");
@@ -1870,20 +1876,26 @@ syms_of_buffer (void)
            "Attempt to modify a protected field", Qerror);
 }
 
+void
+reinit_vars_of_buffer (void)
+{
+  staticpro_nodump (&Vbuffer_alist);
+  Vbuffer_alist = Qnil;
+  current_buffer = 0;
+}
+
 /* initialize the buffer routines */
 void
 vars_of_buffer (void)
 {
   /* This function can GC */
+  reinit_vars_of_buffer ();
+
   staticpro (&QSFundamental);
   staticpro (&QSscratch);
-  staticpro (&Vbuffer_alist);
 
-  QSFundamental = Fpurecopy (build_string ("Fundamental"));
-  QSscratch = Fpurecopy (build_string (DEFER_GETTEXT ("*scratch*")));
-
-  Vbuffer_alist = Qnil;
-  current_buffer = 0;
+  QSFundamental = build_string ("Fundamental");
+  QSscratch = build_string (DEFER_GETTEXT ("*scratch*"));
 
   DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook /*
 List of hooks to be run before killing local variables in a buffer.
@@ -2063,21 +2075,21 @@ nuke_all_buffer_slots (struct buffer *b, Lisp_Object zap)
   b->indirect_children = Qnil;
   b->own_text.line_number_cache = Qnil;
 
-#define MARKED_SLOT(x) b->x = (zap);
+#define MARKED_SLOT(x) b->x = zap
 #include "bufslots.h"
 #undef MARKED_SLOT
 }
 
-void
-complex_vars_of_buffer (void)
+static void
+common_init_complex_vars_of_buffer (void)
 {
   /* Make sure all markable slots in buffer_defaults
      are initialized reasonably, so mark_buffer won't choke. */
-  struct buffer *defs = alloc_lcrecord_type (struct buffer, lrecord_buffer);
-  struct buffer *syms = alloc_lcrecord_type (struct buffer, lrecord_buffer);
+  struct buffer *defs = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
+  struct buffer *syms = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
 
-  staticpro (&Vbuffer_defaults);
-  staticpro (&Vbuffer_local_symbols);
+  staticpro_nodump (&Vbuffer_defaults);
+  staticpro_nodump (&Vbuffer_local_symbols);
   XSETBUFFER (Vbuffer_defaults, defs);
   XSETBUFFER (Vbuffer_local_symbols, syms);
 
@@ -2193,11 +2205,57 @@ complex_vars_of_buffer (void)
     buffer_local_flags.buffer_file_coding_system  = make_int (1<<14);
 #endif
 
-    /* #### Warning: 1<<28 is the largest number currently allowable
+    /* #### Warning: 1<<31 is the largest number currently allowable
        due to the XINT() handling of this value.  With some
        rearrangement you can get 3 more bits. */
   }
+}
+
+#define BUFFER_SLOTS_SIZE (offsetof (struct buffer, BUFFER_SLOTS_LAST_NAME) - offsetof (struct buffer, BUFFER_SLOTS_FIRST_NAME) + sizeof (Lisp_Object))
+#define BUFFER_SLOTS_COUNT (BUFFER_SLOTS_SIZE / sizeof (Lisp_Object))
 
+void
+reinit_complex_vars_of_buffer (void)
+{
+  struct buffer *defs, *syms;
+
+  common_init_complex_vars_of_buffer ();
+
+  defs = XBUFFER (Vbuffer_defaults);
+  syms = XBUFFER (Vbuffer_local_symbols);
+  memcpy (&defs->BUFFER_SLOTS_FIRST_NAME,
+         buffer_defaults_saved_slots,
+         BUFFER_SLOTS_SIZE);
+  memcpy (&syms->BUFFER_SLOTS_FIRST_NAME,
+         buffer_local_symbols_saved_slots,
+         BUFFER_SLOTS_SIZE);
+}
+
+
+static const struct lrecord_description buffer_slots_description_1[] = {
+  { XD_LISP_OBJECT, 0, BUFFER_SLOTS_COUNT },
+  { XD_END }
+};
+
+static const struct struct_description buffer_slots_description = {
+  BUFFER_SLOTS_SIZE,
+  buffer_slots_description_1
+};
+
+void
+complex_vars_of_buffer (void)
+{
+  struct buffer *defs, *syms;
+
+  common_init_complex_vars_of_buffer ();
+
+  defs = XBUFFER (Vbuffer_defaults);
+  syms = XBUFFER (Vbuffer_local_symbols);
+  buffer_defaults_saved_slots      = &defs->BUFFER_SLOTS_FIRST_NAME;
+  buffer_local_symbols_saved_slots = &syms->BUFFER_SLOTS_FIRST_NAME;
+  dumpstruct (&buffer_defaults_saved_slots,      &buffer_slots_description);
+  dumpstruct (&buffer_local_symbols_saved_slots, &buffer_slots_description);
+  
   DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /*
 Default value of `modeline-format' for buffers that don't override it.
 This is the same as (default-value 'modeline-format).
@@ -2688,37 +2746,53 @@ handled:
   }
 }
 
+/* Is PWD another name for `.' ? */
+static int
+directory_is_current_directory (char *pwd)
+{
+  Bufbyte *pwd_internal;
+  struct stat dotstat, pwdstat;
+
+  GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal);
+
+  return (IS_DIRECTORY_SEP (*pwd_internal)
+         && stat ((char *) pwd_internal, &pwdstat) == 0
+         && stat (".", &dotstat) == 0
+         && dotstat.st_ino == pwdstat.st_ino
+         && dotstat.st_dev == pwdstat.st_dev
+         && (int) strlen ((char *) pwd_internal) < MAXPATHLEN);
+}
+
 void
 init_initial_directory (void)
 {
   /* This function can GC */
 
   char *pwd;
-  struct stat dotstat, pwdstat;
-  int rc;
 
   initial_directory[0] = 0;
 
   /* If PWD is accurate, use it instead of calling getcwd.  This is faster
      when PWD is right, and may avoid a fatal error.  */
-  if ((pwd = getenv ("PWD")) != 0 && IS_DIRECTORY_SEP (*pwd)
-      && stat (pwd, &pwdstat) == 0
-      && stat (".", &dotstat) == 0
-      && dotstat.st_ino == pwdstat.st_ino
-      && dotstat.st_dev == pwdstat.st_dev
-      && (int) strlen (pwd) < MAXPATHLEN)
+  if ((pwd = getenv ("PWD")) != NULL
+      && directory_is_current_directory (pwd))
     strcpy (initial_directory, pwd);
   else if (getcwd (initial_directory, MAXPATHLEN) == NULL)
     fatal ("`getcwd' failed: %s\n", strerror (errno));
 
-  /* Maybe this should really use some standard subroutine
+  /* Make sure pwd is DIRECTORY_SEP-terminated.
+     Maybe this should really use some standard subroutine
      whose definition is filename syntax dependent.  */
-  rc = strlen (initial_directory);
-  if (!(IS_DIRECTORY_SEP (initial_directory[rc - 1])))
-    {
-      initial_directory[rc] = DIRECTORY_SEP;
-      initial_directory[rc + 1] = '\0';
-    }
+  {
+    int len = strlen (initial_directory);
+
+    if (! IS_DIRECTORY_SEP (initial_directory[len - 1]))
+      {
+       initial_directory[len] = DIRECTORY_SEP;
+       initial_directory[len + 1] = '\0';
+      }
+  }
+
   /* XEmacs change: store buffer's default directory
      using preferred (i.e. as defined at compile-time)
      directory separator. --marcpa */
@@ -2739,7 +2813,8 @@ init_buffer (void)
 
   Fset_buffer (Fget_buffer_create (QSscratch));
 
-  current_buffer->directory = build_string (initial_directory);
+  current_buffer->directory =
+    build_ext_string (initial_directory, FORMAT_FILENAME);
 
 #if 0 /* FSFmacs */
   /* #### is this correct? */