This commit was generated by cvs2svn to compensate for changes in r5197,
[chise/xemacs-chise.git.1] / src / buffer.c
index d235117..81acfbc 100644 (file)
@@ -80,7 +80,6 @@ Boston, MA 02111-1307, USA.  */
 #ifdef REGION_CACHE_NEEDS_WORK
 #include "region-cache.h"
 #endif
-#include "specifier.h"
 #include "syntax.h"
 #include "sysdep.h"    /* for getwd */
 #include "window.h"
@@ -228,13 +227,11 @@ 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) ((markobj) (buf->x));
 #include "bufslots.h"
 #undef MARKED_SLOT
 
-  markobj (buf->extent_info);
-  if (buf->text)
-    markobj (buf->text->line_number_cache);
+  ((markobj) (buf->extent_info));
 
   /* Don't mark normally through the children slot.
      (Actually, in this case, it doesn't matter.)  */
@@ -311,9 +308,12 @@ returned instead.
 */
        (frame))
 {
-  return Fmapcar (Qcdr,
-                 EQ (frame, Qt) ? Vbuffer_alist :
-                 decode_frame (frame)->buffer_alist);
+  Lisp_Object list;
+  if (EQ (frame, Qt))
+    list = Vbuffer_alist;
+  else
+    list = decode_frame (frame)->buffer_alist;
+  return Fmapcar (Qcdr, list);
 }
 
 Lisp_Object
@@ -433,7 +433,7 @@ the search will still be done on `buffer-file-name'.
        (filename))
 {
   /* This function can GC.  GC checked 1997.04.06. */
-  REGISTER Lisp_Object buf;
+  REGISTER Lisp_Object tail, buf, tem;
   struct gcpro gcpro1;
 
 #ifdef I18N3
@@ -474,20 +474,18 @@ the search will still be done on `buffer-file-name'.
       NUNGCPRO;
     }
 
-  {
-    Lisp_Object elt;
-    LIST_LOOP_2 (elt, Vbuffer_alist)
-      {
-       buf = Fcdr (elt);
-       if (!BUFFERP (buf)) continue;
-       if (!STRINGP (XBUFFER (buf)->filename)) continue;
-       if (!NILP (Fstring_equal (filename,
-                                 (find_file_compare_truenames
-                                  ? XBUFFER (buf)->file_truename
-                                  : XBUFFER (buf)->filename))))
-         return buf;
-      }
-  }
+  LIST_LOOP (tail, Vbuffer_alist)
+    {
+      buf = Fcdr (XCAR (tail));
+      if (!BUFFERP (buf)) continue;
+      if (!STRINGP (XBUFFER (buf)->filename)) continue;
+      tem = Fstring_equal (filename,
+                          (find_file_compare_truenames
+                           ? XBUFFER (buf)->file_truename
+                           : XBUFFER (buf)->filename));
+      if (!NILP (tem))
+       return buf;
+    }
   return Qnil;
 }
 
@@ -579,8 +577,8 @@ finish_init_buffer (struct buffer *b, Lisp_Object name)
   init_buffer_markers (b);
 
   b->generated_modeline_string = Fmake_string (make_int (84), make_int (' '));
-  b->modeline_extent_table = make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK,
-                                                  HASH_TABLE_EQ);
+  b->modeline_extent_table = make_lisp_hashtable (20, HASHTABLE_KEY_WEAK,
+                                                 HASHTABLE_EQ);
 
   return buf;
 }
@@ -616,11 +614,12 @@ The value is never nil.
   b->text = &b->own_text;
   b->base_buffer = 0;
   b->indirect_children = Qnil;
-  init_buffer_text (b);
+  init_buffer_text (b, 0);
 
   return finish_init_buffer (b, name);
 }
 
+#if 0 /* #### implement this!  Need various changes in insdel.c */
 DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, 2, 2,
        "bMake indirect buffer (to buffer): \nBName of indirect buffer: ", /*
 Create and return an indirect buffer for buffer BASE, named NAME.
@@ -632,40 +631,44 @@ If BASE is an indirect buffer itself, the base buffer for that buffer
 */
        (base_buffer, name))
 {
-  /* This function can GC */
-
-  /* #### The above interactive specification is totally bogus,
-     because it offers an existing buffer as default answer to the
-     second question.  However, the second argument may not BE an
-     existing buffer!  */
-  struct buffer *b;
-
-  base_buffer = get_buffer (base_buffer, 1);
+  Lisp_Object buf;
+  REGISTER struct buffer *b;
 
 #ifdef I18N3
   /* #### Doc string should indicate that the buffer name will get
      translated. */
 #endif
-  CHECK_STRING (name);
+
   name = LISP_GETTEXT (name);
-  if (!NILP (Fget_buffer (name)))
-    signal_simple_error ("Buffer name already in use", name);
+  buf = Fget_buffer (name);
+  if (!NILP (buf))
+    error ("Buffer name `%s' is in use", XSTRING_DATA (name));
+
+  base_buffer = Fget_buffer (base_buffer);
+  if (NILP (base_buffer))
+    error ("No such buffer: `%s'", XSTRING_DATA (XBUFFER (base_buffer)->name));
+
   if (XSTRING_LENGTH (name) == 0)
     error ("Empty string for buffer name is not allowed");
 
   b = allocate_buffer ();
 
-  b->base_buffer = BUFFER_BASE_BUFFER (XBUFFER (base_buffer));
+  if (XBUFFER (base_buffer)->base_buffer)
+    b->base_buffer = XBUFFER (base_buffer)->base_buffer;
+  else
+    b->base_buffer = XBUFFER (base_buffer);
 
   /* Use the base buffer's text object.  */
   b->text = b->base_buffer->text;
   b->indirect_children = Qnil;
+  XSETBUFFER (buf, b);
   b->base_buffer->indirect_children =
-    Fcons (make_buffer (b), b->base_buffer->indirect_children);
-  init_buffer_text (b);
+    Fcons (buf, b->base_buffer->indirect_children);
+  init_buffer_text (b, 1);
 
   return finish_init_buffer (b, name);
 }
+#endif /* 0 */
 
 
 \f
@@ -811,6 +814,41 @@ If BUFFER is indirect, the return value will always be nil; see
   return Fcopy_sequence (buf->indirect_children);
 }
 
+/* Map MAPFUN over all buffers that share the same text as BUF
+   (this includes BUF).  Pass two arguments to MAPFUN: a buffer,
+   and CLOSURE.  If any invocation of MAPFUN returns non-zero,
+   halt immediately and return that value.  Otherwise, continue
+   the mapping to the end and return 0. */
+
+int
+map_over_sharing_buffers (struct buffer *buf,
+                         int (*mapfun) (struct buffer *buf, void *closure),
+                         void *closure)
+{
+  int result;
+  Lisp_Object tail;
+
+  if (buf->base_buffer)
+    {
+      buf = buf->base_buffer;
+      assert (!buf->base_buffer);
+    }
+
+  result = (mapfun) (buf, closure);
+  if (result)
+    return result;
+
+  LIST_LOOP (tail, buf->indirect_children)
+    {
+      Lisp_Object buffer = XCAR (tail);
+      result = (mapfun) (XBUFFER (buffer), closure);
+      if (result)
+       return result;
+    }
+
+  return 0;
+}
+
 DEFUN ("buffer-local-variables", Fbuffer_local_variables, 0, 1, 0, /*
 Return an alist of variables that are buffer-local in BUFFER.
 Most elements look like (SYMBOL . VALUE), describing one variable.
@@ -1249,12 +1287,7 @@ with `delete-process'.
       GCPRO1 (buf);
 
       LIST_LOOP (rest, b->indirect_children)
-       {
-         Fkill_buffer (XCAR (rest));
-         /* Keep indirect_children updated in case a
-             query-function/hook throws.  */
-         b->indirect_children = XCDR (rest);
-       }
+       Fkill_buffer (XCAR (rest));
 
       UNGCPRO;
     }
@@ -1339,7 +1372,7 @@ with `delete-process'.
     kill_buffer_local_variables (b);
 
     b->name = Qnil;
-    uninit_buffer_text (b);
+    uninit_buffer_text (b, !!b->base_buffer);
     b->undo_list = Qnil;
     uninit_buffer_extents (b);
     if (b->base_buffer)
@@ -1836,7 +1869,9 @@ syms_of_buffer (void)
   DEFSUBR (Fget_buffer);
   DEFSUBR (Fget_file_buffer);
   DEFSUBR (Fget_buffer_create);
+#if 0
   DEFSUBR (Fmake_indirect_buffer);
+#endif
 
   DEFSUBR (Fgenerate_new_buffer_name);
   DEFSUBR (Fbuffer_name);
@@ -2014,55 +2049,81 @@ List of functions called with no args to query before killing a buffer.
   delete_auto_save_files = 1;
 }
 
-/* The docstrings for DEFVAR_* are recorded externally by make-docfile.  */
-
+/* DOC is ignored because it is snagged and recorded externally
+ *  by make-docfile */
 /* Renamed from DEFVAR_PER_BUFFER because FSFmacs D_P_B takes
-   a bogus extra arg, which confuses an otherwise identical make-docfile.c */
-
+ *  a bogus extra arg, which confuses an otherwise identical make-docfile.c */
 /* Declaring this stuff as const produces 'Cannot reinitialize' messages
    from SunPro C's fix-and-continue feature (a way neato feature that
    makes debugging unbelievably more bearable) */
-#define DEFVAR_BUFFER_LOCAL_1(lname, field_name, forward_type, magicfun) do {  \
-  static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C               \
-    = { { { symbol_value_forward_lheader_initializer,                          \
-           (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },  \
-         forward_type }, magicfun };                                           \
-  {                                                                            \
-    int offset = ((char *)symbol_value_forward_forward (&I_hate_C) -           \
-                 (char *)&buffer_local_flags);                                 \
-    defvar_magic (lname, &I_hate_C);                                           \
-                                                                               \
-    *((Lisp_Object *)(offset + (char *)XBUFFER (Vbuffer_local_symbols)))       \
-      = intern (lname);                                                                \
-  }                                                                            \
-} while (0)
-
-#define DEFVAR_BUFFER_LOCAL_MAGIC(lname, field_name, magicfun)         \
-       DEFVAR_BUFFER_LOCAL_1 (lname, field_name,                       \
-                              SYMVAL_CURRENT_BUFFER_FORWARD, magicfun)
-#define DEFVAR_BUFFER_LOCAL(lname, field_name)                         \
-       DEFVAR_BUFFER_LOCAL_MAGIC (lname, field_name, 0)
-#define DEFVAR_CONST_BUFFER_LOCAL_MAGIC(lname, field_name, magicfun)   \
-       DEFVAR_BUFFER_LOCAL_1 (lname, field_name,                       \
-                              SYMVAL_CONST_CURRENT_BUFFER_FORWARD, magicfun)
-#define DEFVAR_CONST_BUFFER_LOCAL(lname, field_name)                   \
-       DEFVAR_CONST_BUFFER_LOCAL_MAGIC (lname, field_name, 0)
-
-#define DEFVAR_BUFFER_DEFAULTS_MAGIC(lname, field_name, magicfun)      \
-       DEFVAR_SYMVAL_FWD (lname, &(buffer_local_flags.field_name),     \
-                          SYMVAL_DEFAULT_BUFFER_FORWARD, magicfun)
-#define DEFVAR_BUFFER_DEFAULTS(lname, field_name)                      \
-       DEFVAR_BUFFER_DEFAULTS_MAGIC (lname, field_name, 0)
+#define DEFVAR_BUFFER_LOCAL(lname, field_name) do {                    \
+static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C         \
+  = { { { symbol_value_forward_lheader_initializer,                    \
+     (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },        \
+      SYMVAL_CURRENT_BUFFER_FORWARD }, 0 };                            \
+      defvar_buffer_local ((lname), &I_hate_C);                                \
+ } while (0)
+
+#define DEFVAR_BUFFER_LOCAL_MAGIC(lname, field_name, magicfun) do {    \
+static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C         \
+  = { { { symbol_value_forward_lheader_initializer,                    \
+     (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },        \
+      SYMVAL_CURRENT_BUFFER_FORWARD }, magicfun };                     \
+      defvar_buffer_local ((lname), &I_hate_C);                                \
+ } while (0)
+
+#define DEFVAR_CONST_BUFFER_LOCAL(lname, field_name) do {              \
+static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C         \
+  = { { { symbol_value_forward_lheader_initializer,                    \
+     (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },        \
+      SYMVAL_CONST_CURRENT_BUFFER_FORWARD }, 0 };                      \
+      defvar_buffer_local ((lname), &I_hate_C);                                \
+ } while (0)
+
+#define DEFVAR_CONST_BUFFER_LOCAL_MAGIC(lname, field_name, magicfun) do{\
+static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C         \
+  = { { { symbol_value_forward_lheader_initializer,                    \
+     (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },        \
+      SYMVAL_CONST_CURRENT_BUFFER_FORWARD }, magicfun };               \
+      defvar_buffer_local ((lname), &I_hate_C);                                \
+ } while (0)
+
+static void
+defvar_buffer_local (CONST char *namestring,
+                     CONST struct symbol_value_forward *m)
+{
+  int offset = ((char *)symbol_value_forward_forward (m)
+                - (char *)&buffer_local_flags);
+
+  defvar_mumble (namestring, m, sizeof (*m));
+
+  *((Lisp_Object *)(offset + (char *)XBUFFER (Vbuffer_local_symbols)))
+    = intern (namestring);
+}
+
+/* DOC is ignored because it is snagged and recorded externally
+ *  by make-docfile */
+#define DEFVAR_BUFFER_DEFAULTS(lname, field_name) do {                 \
+static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C         \
+  = { { { symbol_value_forward_lheader_initializer,                    \
+     (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },        \
+      SYMVAL_DEFAULT_BUFFER_FORWARD }, 0 };                            \
+      defvar_mumble ((lname), &I_hate_C, sizeof (I_hate_C));           \
+ } while (0)
+
+#define DEFVAR_BUFFER_DEFAULTS_MAGIC(lname, field_name, magicfun) do { \
+static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C         \
+  = { { { symbol_value_forward_lheader_initializer,                    \
+     (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 },        \
+      SYMVAL_DEFAULT_BUFFER_FORWARD }, magicfun };                     \
+      defvar_mumble ((lname), &I_hate_C, sizeof (I_hate_C));           \
+ } while (0)
 
 static void
 nuke_all_buffer_slots (struct buffer *b, Lisp_Object zap)
 {
   zero_lcrecord (b);
 
-  b->extent_info = Qnil;
-  b->indirect_children = Qnil;
-  b->own_text.line_number_cache = Qnil;
-
 #define MARKED_SLOT(x) b->x = (zap);
 #include "bufslots.h"
 #undef MARKED_SLOT
@@ -2091,17 +2152,15 @@ complex_vars_of_buffer (void)
   defs->major_mode = Qfundamental_mode;
   defs->mode_name = QSFundamental;
   defs->abbrev_table = Qnil;    /* real default setup by Lisp code */
-
-  defs->downcase_table  = Vascii_downcase_table;
-  defs->upcase_table    = Vascii_upcase_table;
+  defs->downcase_table = Vascii_downcase_table;
+  defs->upcase_table = Vascii_upcase_table;
   defs->case_canon_table = Vascii_canon_table;
-  defs->case_eqv_table  = Vascii_eqv_table;
+  defs->case_eqv_table = Vascii_eqv_table;
 #ifdef MULE
-  defs->mirror_downcase_table  = Vmirror_ascii_downcase_table;
-  defs->mirror_upcase_table    = Vmirror_ascii_upcase_table;
+  defs->mirror_downcase_table = Vmirror_ascii_downcase_table;
+  defs->mirror_upcase_table = Vmirror_ascii_upcase_table;
   defs->mirror_case_canon_table = Vmirror_ascii_canon_table;
-  defs->mirror_case_eqv_table  = Vmirror_ascii_eqv_table;
-
+  defs->mirror_case_eqv_table = Vmirror_ascii_eqv_table;
   defs->category_table = Vstandard_category_table;
 #endif /* MULE */
   defs->syntax_table = Vstandard_syntax_table;
@@ -2135,7 +2194,7 @@ complex_vars_of_buffer (void)
      */
     Lisp_Object always_local_no_default = make_int (0);
     Lisp_Object always_local_resettable = make_int (-1);
-    Lisp_Object resettable             = make_int (-3);
+    Lisp_Object resettable = make_int (-3);
 
     /* Assign the local-flags to the slots that have default values.
        The local flag is a bit that is used in the buffer
@@ -2144,58 +2203,58 @@ complex_vars_of_buffer (void)
        buffer.  */
 
     nuke_all_buffer_slots (&buffer_local_flags, make_int (-2));
-    buffer_local_flags.filename                   = always_local_no_default;
-    buffer_local_flags.directory          = always_local_no_default;
-    buffer_local_flags.backed_up          = always_local_no_default;
-    buffer_local_flags.saved_size         = always_local_no_default;
+    buffer_local_flags.filename = always_local_no_default;
+    buffer_local_flags.directory = always_local_no_default;
+    buffer_local_flags.backed_up = always_local_no_default;
+    buffer_local_flags.saved_size = always_local_no_default;
     buffer_local_flags.auto_save_file_name = always_local_no_default;
-    buffer_local_flags.read_only          = always_local_no_default;
+    buffer_local_flags.read_only = always_local_no_default;
 
-    buffer_local_flags.major_mode         = always_local_resettable;
-    buffer_local_flags.mode_name          = always_local_resettable;
-    buffer_local_flags.undo_list          = always_local_no_default;
+    buffer_local_flags.major_mode = always_local_resettable;
+    buffer_local_flags.mode_name = always_local_resettable;
+    buffer_local_flags.undo_list = always_local_no_default;
 #if 0 /* FSFmacs */
-    buffer_local_flags.mark_active        = always_local_resettable;
+    buffer_local_flags.mark_active = always_local_resettable;
 #endif
     buffer_local_flags.point_before_scroll = always_local_resettable;
-    buffer_local_flags.file_truename      = always_local_no_default;
-    buffer_local_flags.invisibility_spec   = always_local_resettable;
-    buffer_local_flags.file_format        = always_local_resettable;
+    buffer_local_flags.file_truename = always_local_no_default;
+    buffer_local_flags.invisibility_spec = always_local_resettable;
+    buffer_local_flags.file_format = always_local_resettable;
     buffer_local_flags.generated_modeline_string = always_local_no_default;
 
-    buffer_local_flags.keymap          = resettable;
-    buffer_local_flags.downcase_table  = resettable;
-    buffer_local_flags.upcase_table    = resettable;
+    buffer_local_flags.keymap = resettable;
+    buffer_local_flags.downcase_table = resettable;
+    buffer_local_flags.upcase_table = resettable;
     buffer_local_flags.case_canon_table = resettable;
-    buffer_local_flags.case_eqv_table  = resettable;
-    buffer_local_flags.syntax_table    = resettable;
+    buffer_local_flags.case_eqv_table = resettable;
+    buffer_local_flags.syntax_table = resettable;
 #ifdef MULE
-    buffer_local_flags.category_table  = resettable;
+    buffer_local_flags.category_table = resettable;
 #endif
 
-    buffer_local_flags.modeline_format           = make_int (1<<0);
-    buffer_local_flags.abbrev_mode               = make_int (1<<1);
-    buffer_local_flags.overwrite_mode            = make_int (1<<2);
-    buffer_local_flags.case_fold_search                  = make_int (1<<3);
-    buffer_local_flags.auto_fill_function        = make_int (1<<4);
-    buffer_local_flags.selective_display         = make_int (1<<5);
-    buffer_local_flags.selective_display_ellipses = make_int (1<<6);
-    buffer_local_flags.tab_width                 = make_int (1<<7);
-    buffer_local_flags.truncate_lines            = make_int (1<<8);
-    buffer_local_flags.ctl_arrow                 = make_int (1<<9);
-    buffer_local_flags.fill_column               = make_int (1<<10);
-    buffer_local_flags.left_margin               = make_int (1<<11);
-    buffer_local_flags.abbrev_table              = make_int (1<<12);
+    buffer_local_flags.modeline_format = make_int (1);
+    buffer_local_flags.abbrev_mode = make_int (2);
+    buffer_local_flags.overwrite_mode = make_int (4);
+    buffer_local_flags.case_fold_search = make_int (8);
+    buffer_local_flags.auto_fill_function = make_int (0x10);
+    buffer_local_flags.selective_display = make_int (0x20);
+    buffer_local_flags.selective_display_ellipses = make_int (0x40);
+    buffer_local_flags.tab_width = make_int (0x80);
+    buffer_local_flags.truncate_lines = make_int (0x100);
+    buffer_local_flags.ctl_arrow = make_int (0x200);
+    buffer_local_flags.fill_column = make_int (0x400);
+    buffer_local_flags.left_margin = make_int (0x800);
+    buffer_local_flags.abbrev_table = make_int (0x1000);
 #ifdef REGION_CACHE_NEEDS_WORK
-    buffer_local_flags.cache_long_line_scans     = make_int (1<<13);
+    buffer_local_flags.cache_long_line_scans = make_int (0x2000);
 #endif
 #ifdef FILE_CODING
-    buffer_local_flags.buffer_file_coding_system  = make_int (1<<14);
+    buffer_local_flags.buffer_file_coding_system = make_int (0x4000);
 #endif
 
-    /* #### Warning: 1<<28 is the largest number currently allowable
-       due to the XINT() handling of this value.  With some
-       rearrangement you can get 3 more bits. */
+    /* #### Warning, 0x4000000 (that's six zeroes) is the largest number
+       currently allowable due to the XINT() handling of this value.
+       With some rearrangement you can get 4 more bits. */
   }
 
   DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /*
@@ -2405,7 +2464,7 @@ its mnemonic abbreviation.
 The default value for this variable (which is normally used for
 buffers without associated files) is also used when automatic
 detection of a file's encoding is called for and there was no
-discernible encoding in the file (i.e. it was entirely or almost
+discernable encoding in the file (i.e. it was entirely or almost
 entirely ASCII).  The default value should generally *not* be set to
 nil (equivalent to `no-conversion'), because if extended characters
 are ever inserted into the buffer, they will be lost when the file is
@@ -2433,7 +2492,7 @@ particular operation, you should bind the variable
 variables just mentioned, which are intended to be used for
 global environment specification.
 */ );
-#endif /* FILE_CODING */
+#endif
 
   DEFVAR_BUFFER_LOCAL ("auto-fill-function", auto_fill_function /*
 Function called (if non-nil) to perform auto-fill.
@@ -2720,7 +2779,7 @@ init_initial_directory (void)
       initial_directory[rc + 1] = '\0';
     }
   /* XEmacs change: store buffer's default directory
-     using preferred (i.e. as defined at compile-time)
+     using prefered (i.e. as defined at compile-time)
      directory separator. --marcpa */
 #ifdef DOS_NT
 #define CORRECT_DIR_SEPS(s) \