]> code.delx.au - gnu-emacs/blobdiff - src/buffer.c
Convert most remaining function definitions to standard C.
[gnu-emacs] / src / buffer.c
index 2fc7a8b3a7ced2cab8ed44c30e5e1cae5d646e60..57e4986a0bb09ca4b5cf7f57916a1a74b237f8af 100644 (file)
@@ -1,7 +1,7 @@
 /* Buffer manipulation primitives for GNU Emacs.
    Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994,
                  1995, 1997, 1998, 1999, 2000, 2001, 2002,
-                 2003, 2004, 2005, 2006, 2007, 2008, 2009
+                 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -28,11 +28,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <setjmp.h>
 
-#ifndef USE_CRT_DLL
-extern int errno;
-#endif
-
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -83,9 +78,6 @@ static Lisp_Object Vbuffer_defaults;
    be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
    and the corresponding slot in buffer_defaults is not used.
 
-   If a slot is -2, then there is no DEFVAR_PER_BUFFER for it,
-   but there is a default value which is copied into each buffer.
-
    If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
    zero, that is a bug */
 
@@ -99,6 +91,12 @@ DECL_ALIGN (struct buffer, buffer_local_symbols);
 /* A Lisp_Object pointer to the above, used for staticpro */
 static Lisp_Object Vbuffer_local_symbols;
 
+/* Return the symbol of the per-buffer variable at offset OFFSET in
+   the buffer structure.  */
+
+#define PER_BUFFER_SYMBOL(OFFSET) \
+      (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols))
+
 /* Flags indicating which built-in buffer-local variables
    are permanent locals.  */
 static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
@@ -108,13 +106,13 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
 int last_per_buffer_idx;
 
 EXFUN (Fset_buffer, 1);
-void set_buffer_internal P_ ((struct buffer *b));
-void set_buffer_internal_1 P_ ((struct buffer *b));
-static void call_overlay_mod_hooks P_ ((Lisp_Object list, Lisp_Object overlay,
-                                       int after, Lisp_Object arg1,
-                                       Lisp_Object arg2, Lisp_Object arg3));
-static void swap_out_buffer_local_variables P_ ((struct buffer *b));
-static void reset_buffer_local_variables P_ ((struct buffer *b, int permanent_too));
+void set_buffer_internal (struct buffer *b);
+void set_buffer_internal_1 (struct buffer *b);
+static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
+                                    int after, Lisp_Object arg1,
+                                    Lisp_Object arg2, Lisp_Object arg3);
+static void swap_out_buffer_local_variables (struct buffer *b);
+static void reset_buffer_local_variables (struct buffer *b, int permanent_too);
 
 /* Alist of all buffer names vs the buffers. */
 /* This used to be a variable, but is no longer,
@@ -170,20 +168,19 @@ Lisp_Object Qmodification_hooks;
 Lisp_Object Qinsert_in_front_hooks;
 Lisp_Object Qinsert_behind_hooks;
 
-static void alloc_buffer_text P_ ((struct buffer *, size_t));
-static void free_buffer_text P_ ((struct buffer *b));
-static struct Lisp_Overlay * copy_overlays P_ ((struct buffer *, struct Lisp_Overlay *));
-static void modify_overlay P_ ((struct buffer *, EMACS_INT, EMACS_INT));
-static Lisp_Object buffer_lisp_local_variables P_ ((struct buffer *));
+static void alloc_buffer_text (struct buffer *, size_t);
+static void free_buffer_text (struct buffer *b);
+static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
+static void modify_overlay (struct buffer *, EMACS_INT, EMACS_INT);
+static Lisp_Object buffer_lisp_local_variables (struct buffer *);
 
-extern char * emacs_strerror P_ ((int));
+extern char * emacs_strerror (int);
 
 /* For debugging; temporary.  See set_buffer_internal.  */
 /* Lisp_Object Qlisp_mode, Vcheck_symbol; */
 
 void
-nsberror (spec)
-     Lisp_Object spec;
+nsberror (Lisp_Object spec)
 {
   if (STRINGP (spec))
     error ("No buffer named %s", SDATA (spec));
@@ -250,9 +247,7 @@ frame parameter come first, followed by the rest of the buffers.  */)
    and don't ever QUIT.  */
 
 static Lisp_Object
-assoc_ignore_text_properties (key, list)
-     register Lisp_Object key;
-     Lisp_Object list;
+assoc_ignore_text_properties (register Lisp_Object key, Lisp_Object list)
 {
   register Lisp_Object tail;
   for (tail = list; CONSP (tail); tail = XCDR (tail))
@@ -314,8 +309,7 @@ See also `find-buffer-visiting'.  */)
 }
 
 Lisp_Object
-get_truename_buffer (filename)
-     register Lisp_Object filename;
+get_truename_buffer (register Lisp_Object filename)
 {
   register Lisp_Object tail, buf, tem;
 
@@ -439,9 +433,7 @@ even if it is dead.  The return value is never nil.  */)
    LIST, but for buffer B.  */
 
 static struct Lisp_Overlay *
-copy_overlays (b, list)
-     struct buffer *b;
-     struct Lisp_Overlay *list;
+copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
 {
   Lisp_Object buffer;
   struct Lisp_Overlay *result = NULL, *tail = NULL;
@@ -491,8 +483,7 @@ copy_overlays (b, list)
    copied.  */
 
 static void
-clone_per_buffer_values (from, to)
-     struct buffer *from, *to;
+clone_per_buffer_values (struct buffer *from, struct buffer *to)
 {
   Lisp_Object to_buffer;
   int offset;
@@ -512,7 +503,7 @@ clone_per_buffer_values (from, to)
        continue;
 
       obj = PER_BUFFER_VALUE (from, offset);
-      if (MARKERP (obj))
+      if (MARKERP (obj) && XMARKER (obj)->buffer == from)
        {
          struct Lisp_Marker *m = XMARKER (obj);
          obj = Fmake_marker ();
@@ -660,8 +651,7 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
 }
 
 void
-delete_all_overlays (b)
-     struct buffer *b;
+delete_all_overlays (struct buffer *b)
 {
   Lisp_Object overlay;
 
@@ -691,20 +681,20 @@ delete_all_overlays (b)
    claims it doesn't belong to it.  */
 
 void
-reset_buffer (b)
-     register struct buffer *b;
+reset_buffer (register struct buffer *b)
 {
   b->filename = Qnil;
   b->file_truename = Qnil;
   b->directory = (current_buffer) ? current_buffer->directory : Qnil;
   b->modtime = 0;
+  b->modtime_size = -1;
   XSETFASTINT (b->save_length, 0);
   b->last_window_start = 1;
   /* It is more conservative to start out "changed" than "unchanged".  */
   b->clip_changed = 0;
   b->prevent_redisplay_optimizations_p = 1;
   b->backed_up = Qnil;
-  b->auto_save_modified = 0;
+  BUF_AUTOSAVE_MODIFF (b) = 0;
   b->auto_save_failure_time = -1;
   b->auto_save_file_name = Qnil;
   b->read_only = Qnil;
@@ -735,9 +725,7 @@ reset_buffer (b)
    we preserve those.  */
 
 static void
-reset_buffer_local_variables (b, permanent_too)
-     register struct buffer *b;
-     int permanent_too;
+reset_buffer_local_variables (register struct buffer *b, int permanent_too)
 {
   register int offset;
   int i;
@@ -774,9 +762,7 @@ reset_buffer_local_variables (b, permanent_too)
     {
       Lisp_Object tmp, prop, last = Qnil;
       for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp))
-       if (CONSP (XCAR (tmp))
-           && SYMBOLP (XCAR (XCAR (tmp)))
-           && !NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
+       if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
          {
            /* If permanent-local, keep it.  */
            last = tmp;
@@ -826,9 +812,7 @@ reset_buffer_local_variables (b, permanent_too)
       int idx = PER_BUFFER_IDX (offset);
       if ((idx > 0
           && (permanent_too
-              || buffer_permanent_local_flags[idx] == 0))
-         /* Is -2 used anywhere?  */
-         || idx == -2)
+              || buffer_permanent_local_flags[idx] == 0)))
        PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset);
     }
 }
@@ -942,59 +926,49 @@ is the default binding of the variable. */)
   CHECK_SYMBOL (variable);
   CHECK_BUFFER (buffer);
   buf = XBUFFER (buffer);
+  sym = XSYMBOL (variable);
 
-  sym = indirect_variable (XSYMBOL (variable));
-  XSETSYMBOL (variable, sym);
-
-  /* Look in local_var_list */
-  result = Fassoc (variable, buf->local_var_alist);
-  if (NILP (result))
+ start:
+  switch (sym->redirect)
     {
-      int offset, idx;
-      int found = 0;
-
-      /* Look in special slots */
-      /* buffer-local Lisp variables start at `undo_list',
-        tho only the ones from `name' on are GC'd normally.  */
-      for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
-          offset < sizeof (struct buffer);
-          /* sizeof EMACS_INT == sizeof Lisp_Object */
-          offset += (sizeof (EMACS_INT)))
-       {
-         idx = PER_BUFFER_IDX (offset);
-         if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
-             && SYMBOLP (PER_BUFFER_SYMBOL (offset))
-             && EQ (PER_BUFFER_SYMBOL (offset), variable))
-           {
-             result = PER_BUFFER_VALUE (buf, offset);
-             found = 1;
-             break;
-           }
-       }
-
-      if (!found)
-       result = Fdefault_value (variable);
-    }
-  else
-    {
-      Lisp_Object valcontents;
-      Lisp_Object current_alist_element;
-
-      /* What binding is loaded right now?  */
-      valcontents = sym->value;
-      current_alist_element
-       = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
-
-      /* The value of the currently loaded binding is not
-        stored in it, but rather in the realvalue slot.
-        Store that value into the binding it belongs to
-        in case that is the one we are about to use.  */
+    case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
+    case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
+    case SYMBOL_LOCALIZED:
+      { /* Look in local_var_alist.  */
+       struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
+       XSETSYMBOL (variable, sym); /* Update In case of aliasing.  */
+       result = Fassoc (variable, buf->local_var_alist);
+       if (!NILP (result))
+         {
+           if (blv->fwd)
+             { /* What binding is loaded right now?  */
+               Lisp_Object current_alist_element = blv->valcell;
 
-      Fsetcdr (current_alist_element,
-              do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
+               /* The value of the currently loaded binding is not
+                  stored in it, but rather in the realvalue slot.
+                  Store that value into the binding it belongs to
+                  in case that is the one we are about to use.  */
 
-      /* Now get the (perhaps updated) value out of the binding.  */
-      result = XCDR (result);
+               XSETCDR (current_alist_element,
+                        do_symval_forwarding (blv->fwd));
+             }
+           /* Now get the (perhaps updated) value out of the binding.  */
+           result = XCDR (result);
+         }
+       else
+         result = Fdefault_value (variable);
+       break;
+      }
+    case SYMBOL_FORWARDED:
+      {
+       union Lisp_Fwd *fwd = SYMBOL_FWD (sym);
+       if (BUFFER_OBJFWDP (fwd))
+         result = PER_BUFFER_VALUE (buf, XBUFFER_OBJFWD (fwd)->offset);
+       else
+         result = Fdefault_value (variable);
+       break;
+      }
+    default: abort ();
     }
 
   if (!EQ (result, Qunbound))
@@ -1008,8 +982,7 @@ is the default binding of the variable. */)
    in special slots in the buffer object.  */
 
 static Lisp_Object
-buffer_lisp_local_variables (buf)
-     struct buffer *buf;
+buffer_lisp_local_variables (struct buffer *buf)
 {
   Lisp_Object result = Qnil;
   register Lisp_Object tail;
@@ -1029,12 +1002,7 @@ buffer_lisp_local_variables (buf)
       if (buf != current_buffer)
        val = XCDR (elt);
 
-      /* If symbol is unbound, put just the symbol in the list.  */
-      if (EQ (val, Qunbound))
-       result = Fcons (XCAR (elt), result);
-      /* Otherwise, put (symbol . value) in the list.  */
-      else
-       result = Fcons (Fcons (XCAR (elt), val), result);
+      result = Fcons (Fcons (XCAR (elt), val), result);
     }
 
   return result;
@@ -1132,7 +1100,25 @@ A non-nil FLAG means mark the buffer modified.  */)
     }
 #endif /* CLASH_DETECTION */
 
-  SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
+  /* Here we have a problem.  SAVE_MODIFF is used here to encode
+     buffer-modified-p (as SAVE_MODIFF<MODIFF) as well as
+     recent-auto-save-p (as SAVE_MODIFF<auto_save_modified).  So if we
+     modify SAVE_MODIFF to affect one, we may affect the other
+     as well.
+     E.g. if FLAG is nil we need to set SAVE_MODIFF to MODIFF, but
+     if SAVE_MODIFF<auto_save_modified that means we risk changing
+     recent-auto-save-p from t to nil.
+     Vice versa, if FLAG is non-nil and SAVE_MODIFF>=auto_save_modified
+     we risk changing recent-auto-save-p from nil to t.  */
+  SAVE_MODIFF = (NILP (flag)
+                /* FIXME: This unavoidably sets recent-auto-save-p to nil.  */
+                ? MODIFF
+                /* Let's try to preserve recent-auto-save-p.  */
+                : SAVE_MODIFF < MODIFF ? SAVE_MODIFF
+                /* If SAVE_MODIFF == auto_save_modified == MODIFF,
+                   we can either decrease SAVE_MODIFF and auto_save_modified
+                   or increase MODIFF.  */
+                : MODIFF++);
 
   /* Set update_mode_lines only if buffer is displayed in some window.
      Packages like jit-lock or lazy-lock preserve a buffer's modified
@@ -1295,13 +1281,15 @@ If BUFFER is omitted or nil, some interesting buffer is returned.  */)
      (buffer, visible_ok, frame)
      register Lisp_Object buffer, visible_ok, frame;
 {
-  Lisp_Object Fset_buffer_major_mode ();
+  Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
   register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
   notsogood = Qnil;
 
   if (NILP (frame))
     frame = selected_frame;
 
+  CHECK_FRAME (frame);
+
   tail = Vbuffer_alist;
   pred = frame_buffer_predicate (frame);
 
@@ -1541,8 +1529,8 @@ with SIGHUP.  */)
   /* Delete any auto-save file, if we saved it in this session.
      But not if the buffer is modified.  */
   if (STRINGP (b->auto_save_file_name)
-      && b->auto_save_modified != 0
-      && BUF_SAVE_MODIFF (b) < b->auto_save_modified
+      && BUF_AUTOSAVE_MODIFF (b) != 0
+      && BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b)
       && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
       && NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
     {
@@ -1618,8 +1606,7 @@ with SIGHUP.  */)
    means that other_buffer is more likely to choose a relevant buffer.  */
 
 void
-record_buffer (buf)
-     Lisp_Object buf;
+record_buffer (Lisp_Object buf)
 {
   register Lisp_Object link, prev;
   Lisp_Object frame;
@@ -1734,8 +1721,7 @@ the current buffer's major mode.  */)
    If NORECORD is non-nil, don't call record_buffer.  */
 
 Lisp_Object
-switch_to_buffer_1 (buffer_or_name, norecord)
-     Lisp_Object buffer_or_name, norecord;
+switch_to_buffer_1 (Lisp_Object buffer_or_name, Lisp_Object norecord)
 {
   register Lisp_Object buffer;
 
@@ -1787,8 +1773,6 @@ messing with the window-buffer correspondences.  */)
      (buffer_or_name, norecord)
      Lisp_Object buffer_or_name, norecord;
 {
-  char *err;
-
   if (EQ (buffer_or_name, Fwindow_buffer (selected_window)))
     {
       /* Basically a NOP.  Avoid signalling an error in the case where
@@ -1833,8 +1817,7 @@ DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
    time, and that increments windows_or_buffers_changed.  */
 
 void
-set_buffer_internal (b)
-     register struct buffer *b;
+set_buffer_internal (register struct buffer *b)
 {
   if (current_buffer != b)
     set_buffer_internal_1 (b);
@@ -1844,12 +1827,10 @@ set_buffer_internal (b)
    This is used by redisplay.  */
 
 void
-set_buffer_internal_1 (b)
-     register struct buffer *b;
+set_buffer_internal_1 (register struct buffer *b)
 {
   register struct buffer *old_buf;
-  register Lisp_Object tail, valcontents;
-  Lisp_Object tem;
+  register Lisp_Object tail;
 
 #ifdef USE_MMAP_FOR_BUFFERS
   if (b->text->beg == NULL)
@@ -1921,42 +1902,28 @@ set_buffer_internal_1 (b)
   /* Look down buffer's list of local Lisp variables
      to find and update any that forward into C variables. */
 
-  for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
+  do
     {
-      if (CONSP (XCAR (tail))
-         && SYMBOLP (XCAR (XCAR (tail)))
-         && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))),
-             (BUFFER_LOCAL_VALUEP (valcontents)))
-         && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
-             (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
-       /* Just reference the variable to cause it to become set for
-          this buffer.  */
-       Fsymbol_value (XCAR (XCAR (tail)));
+      for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
+       {
+         Lisp_Object var = XCAR (XCAR (tail));
+         struct Lisp_Symbol *sym = XSYMBOL (var);
+         if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure.  */
+             && SYMBOL_BLV (sym)->fwd)
+           /* Just reference the variable
+              to cause it to become set for this buffer.  */
+           Fsymbol_value (var);
+       }
     }
-
   /* Do the same with any others that were local to the previous buffer */
-
-  if (old_buf)
-    for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
-      {
-       if (CONSP (tail)
-           && SYMBOLP (XCAR (XCAR (tail)))
-           && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))),
-               (BUFFER_LOCAL_VALUEP (valcontents)))
-           && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
-               (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
-         /* Just reference the variable to cause it to become set for
-            this buffer.  */
-         Fsymbol_value (XCAR (XCAR (tail)));
-      }
+  while (b != old_buf && (b = old_buf, b));
 }
 
 /* Switch to buffer B temporarily for redisplay purposes.
    This avoids certain things that don't need to be done within redisplay.  */
 
 void
-set_buffer_temp (b)
-     struct buffer *b;
+set_buffer_temp (struct buffer *b)
 {
   register struct buffer *old_buf;
 
@@ -2035,8 +2002,7 @@ ends when the current command terminates.  Use `switch-to-buffer' or
 /* Set the current buffer to BUFFER provided it is alive.  */
 
 Lisp_Object
-set_buffer_if_live (buffer)
-     Lisp_Object buffer;
+set_buffer_if_live (Lisp_Object buffer)
 {
   if (! NILP (XBUFFER (buffer)->name))
     Fset_buffer (buffer);
@@ -2136,8 +2102,7 @@ so the buffer is truly empty after this.  */)
 }
 
 void
-validate_region (b, e)
-     register Lisp_Object *b, *e;
+validate_region (register Lisp_Object *b, register Lisp_Object *e)
 {
   CHECK_NUMBER_COERCE_MARKER (*b);
   CHECK_NUMBER_COERCE_MARKER (*e);
@@ -2157,8 +2122,7 @@ validate_region (b, e)
    and return the adjusted position.  */
 
 static int
-advance_to_char_boundary (byte_pos)
-     int byte_pos;
+advance_to_char_boundary (int byte_pos)
 {
   int c;
 
@@ -2191,7 +2155,7 @@ advance_to_char_boundary (byte_pos)
 }
 
 #ifdef REL_ALLOC
-extern void r_alloc_reset_variable P_ ((POINTER_TYPE *, POINTER_TYPE *));
+extern void r_alloc_reset_variable (POINTER_TYPE *, POINTER_TYPE *);
 #endif /* REL_ALLOC */
 
 DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
@@ -2205,7 +2169,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
   other_buffer = XBUFFER (buffer);
 
   if (NILP (other_buffer->name))
-    error ("Cannot swap a dead buffer's text");    
+    error ("Cannot swap a dead buffer's text");
 
   /* Actually, it probably works just fine.
    * if (other_buffer == current_buffer)
@@ -2261,6 +2225,8 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
   swapfield (undo_list, Lisp_Object);
   swapfield (mark, Lisp_Object);
   swapfield (enable_multibyte_characters, Lisp_Object);
+  swapfield (bidi_display_reordering, Lisp_Object);
+  swapfield (bidi_paragraph_direction, Lisp_Object);
   /* FIXME: Not sure what we should do with these *_marker fields.
      Hopefully they're just nil anyway.  */
   swapfield (pt_marker, Lisp_Object);
@@ -2409,7 +2375,7 @@ current buffer is cleared.  */)
            p++, pos++;
          else if (CHAR_BYTE8_HEAD_P (*p))
            {
-             c = STRING_CHAR_AND_LENGTH (p, stop - pos, bytes);
+             c = STRING_CHAR_AND_LENGTH (p, bytes);
              /* Delete all bytes for this 8-bit character but the
                 last one, and change the last one to the charcter
                 code.  */
@@ -2450,7 +2416,7 @@ current buffer is cleared.  */)
          unsigned char *p = GPT_ADDR - 1;
 
          while (! CHAR_HEAD_P (*p) && p > BEG_ADDR) p--;
-         if (BASE_LEADING_CODE_P (*p))
+         if (LEADING_CODE_P (*p))
            {
              int new_gpt = GPT_BYTE - (GPT_ADDR - p);
 
@@ -2479,7 +2445,9 @@ current buffer is cleared.  */)
 
          if (ASCII_BYTE_P (*p))
            p++, pos++;
-         else if (EQ (flag, Qt) && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
+         else if (EQ (flag, Qt)
+                  && ! CHAR_BYTE8_HEAD_P (*p)
+                  && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
            p += bytes, pos += bytes;
          else
            {
@@ -2656,26 +2624,24 @@ the normal hook `change-major-mode-hook'.  */)
    for their current values.  */
 
 static void
-swap_out_buffer_local_variables (b)
-     struct buffer *b;
+swap_out_buffer_local_variables (struct buffer *b)
 {
-  Lisp_Object oalist, alist, sym, buffer;
+  Lisp_Object oalist, alist, buffer;
 
   XSETBUFFER (buffer, b);
   oalist = b->local_var_alist;
 
   for (alist = oalist; CONSP (alist); alist = XCDR (alist))
     {
-      if (CONSP (XCAR (alist))
-         && (sym = XCAR (XCAR (alist)), SYMBOLP (sym))
-         /* Need not do anything if some other buffer's binding is
-            now encached.  */
-         && EQ (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer,
-                buffer))
+      Lisp_Object sym = XCAR (XCAR (alist));
+      eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED);
+      /* Need not do anything if some other buffer's binding is
+        now encached.  */
+      if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
        {
          /* Symbol is set up for this buffer's old local value:
             swap it out!  */
-         swap_in_global_binding (sym);
+         swap_in_global_binding (XSYMBOL (sym));
        }
     }
 }
@@ -2703,14 +2669,8 @@ swap_out_buffer_local_variables (b)
    default (BEGV or ZV).  */
 
 int
-overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req)
-     EMACS_INT pos;
-     int extend;
-     Lisp_Object **vec_ptr;
-     int *len_ptr;
-     EMACS_INT *next_ptr;
-     EMACS_INT *prev_ptr;
-     int change_req;
+overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
+            EMACS_INT *next_ptr, EMACS_INT *prev_ptr, int change_req)
 {
   Lisp_Object overlay, start, end;
   struct Lisp_Overlay *tail;
@@ -2848,13 +2808,8 @@ overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req)
    But we still return the total number of overlays.  */
 
 static int
-overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
-     int beg, end;
-     int extend;
-     Lisp_Object **vec_ptr;
-     int *len_ptr;
-     int *next_ptr;
-     int *prev_ptr;
+overlays_in (int beg, int end, int extend, Lisp_Object **vec_ptr, int *len_ptr,
+            int *next_ptr, int *prev_ptr)
 {
   Lisp_Object overlay, ostart, oend;
   struct Lisp_Overlay *tail;
@@ -2975,8 +2930,7 @@ overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
    `mouse-face' property overlapping OVERLAY.  */
 
 int
-mouse_face_overlay_overlaps (overlay)
-     Lisp_Object overlay;
+mouse_face_overlay_overlaps (Lisp_Object overlay)
 {
   int start = OVERLAY_POSITION (OVERLAY_START (overlay));
   int end = OVERLAY_POSITION (OVERLAY_END (overlay));
@@ -3005,8 +2959,7 @@ mouse_face_overlay_overlaps (overlay)
 \f
 /* Fast function to just test if we're at an overlay boundary.  */
 int
-overlay_touches_p (pos)
-     int pos;
+overlay_touches_p (int pos)
 {
   Lisp_Object overlay;
   struct Lisp_Overlay *tail;
@@ -3051,8 +3004,7 @@ struct sortvec
 };
 
 static int
-compare_overlays (v1, v2)
-     const void *v1, *v2;
+compare_overlays (const void *v1, const void *v2)
 {
   const struct sortvec *s1 = (const struct sortvec *) v1;
   const struct sortvec *s2 = (const struct sortvec *) v2;
@@ -3069,10 +3021,7 @@ compare_overlays (v1, v2)
    The return value is the new size; this may be smaller than the original
    size if some of the overlays were invalid or were window-specific.  */
 int
-sort_overlays (overlay_vec, noverlays, w)
-     Lisp_Object *overlay_vec;
-     int noverlays;
-     struct window *w;
+sort_overlays (Lisp_Object *overlay_vec, int noverlays, struct window *w)
 {
   int i, j;
   struct sortvec *sortvec;
@@ -3152,8 +3101,7 @@ static int overlay_str_len;
 
 /* A comparison function suitable for passing to qsort.  */
 static int
-cmp_for_strings (as1, as2)
-     char *as1, *as2;
+cmp_for_strings (const void *as1, const void *as2)
 {
   struct sortstr *s1 = (struct sortstr *)as1;
   struct sortstr *s2 = (struct sortstr *)as2;
@@ -3165,10 +3113,7 @@ cmp_for_strings (as1, as2)
 }
 
 static void
-record_overlay_string (ssl, str, str2, pri, size)
-     struct sortstrlist *ssl;
-     Lisp_Object str, str2, pri;
-     int size;
+record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str2, Lisp_Object pri, int size)
 {
   int nbytes;
 
@@ -3224,10 +3169,7 @@ record_overlay_string (ssl, str, str2, pri, size)
    subsequent calls.  */
 
 int
-overlay_strings (pos, w, pstr)
-     EMACS_INT pos;
-     struct window *w;
-     unsigned char **pstr;
+overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
 {
   Lisp_Object overlay, window, str;
   struct Lisp_Overlay *ov;
@@ -3350,9 +3292,7 @@ overlay_strings (pos, w, pstr)
 /* Shift overlays in BUF's overlay lists, to center the lists at POS.  */
 
 void
-recenter_overlay_lists (buf, pos)
-     struct buffer *buf;
-     EMACS_INT pos;
+recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
 {
   Lisp_Object overlay, beg, end;
   struct Lisp_Overlay *prev, *tail, *next;
@@ -3501,9 +3441,7 @@ recenter_overlay_lists (buf, pos)
 }
 
 void
-adjust_overlays_for_insert (pos, length)
-     EMACS_INT pos;
-     EMACS_INT length;
+adjust_overlays_for_insert (EMACS_INT pos, EMACS_INT length)
 {
   /* After an insertion, the lists are still sorted properly,
      but we may need to update the value of the overlay center.  */
@@ -3512,9 +3450,7 @@ adjust_overlays_for_insert (pos, length)
 }
 
 void
-adjust_overlays_for_delete (pos, length)
-     EMACS_INT pos;
-     EMACS_INT length;
+adjust_overlays_for_delete (EMACS_INT pos, EMACS_INT length)
 {
   if (current_buffer->overlay_center < pos)
     /* The deletion was to our right.  No change needed; the before- and
@@ -3539,8 +3475,7 @@ adjust_overlays_for_delete (pos, length)
    Such an overlay might even have negative size at this point.
    If so, we'll make the overlay empty. */
 void
-fix_start_end_in_overlays (start, end)
-     register int start, end;
+fix_start_end_in_overlays (register int start, register int end)
 {
   Lisp_Object overlay;
   struct Lisp_Overlay *before_list, *after_list;
@@ -3686,9 +3621,7 @@ fix_start_end_in_overlays (start, end)
    was at PREV, and now is at POS.  */
 
 void
-fix_overlays_before (bp, prev, pos)
-     struct buffer *bp;
-     EMACS_INT prev, pos;
+fix_overlays_before (struct buffer *bp, EMACS_INT prev, EMACS_INT pos)
 {
   /* If parent is nil, replace overlays_before; otherwise, parent->next.  */
   struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
@@ -3854,9 +3787,7 @@ for the rear of the overlay advance when text is inserted there
 /* Mark a section of BUF as needing redisplay because of overlays changes.  */
 
 static void
-modify_overlay (buf, start, end)
-     struct buffer *buf;
-     EMACS_INT start, end;
+modify_overlay (struct buffer *buf, EMACS_INT start, EMACS_INT end)
 {
   if (start > end)
     {
@@ -3883,11 +3814,10 @@ modify_overlay (buf, start, end)
 }
 
 \f
-Lisp_Object Fdelete_overlay ();
+Lisp_Object Fdelete_overlay (Lisp_Object overlay);
 
 static struct Lisp_Overlay *
-unchain_overlay (list, overlay)
-     struct Lisp_Overlay *list, *overlay;
+unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
 {
   struct Lisp_Overlay *tmp, *prev;
   for (tmp = list, prev = NULL; tmp; prev = tmp, tmp = tmp->next)
@@ -4346,13 +4276,12 @@ static int last_overlay_modification_hooks_used;
    to the end of last_overlay_modification_hooks.  */
 
 static void
-add_overlay_mod_hooklist (functionlist, overlay)
-     Lisp_Object functionlist, overlay;
+add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
 {
   int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
 
   if (last_overlay_modification_hooks_used == oldsize)
-    last_overlay_modification_hooks = larger_vector 
+    last_overlay_modification_hooks = larger_vector
       (last_overlay_modification_hooks, oldsize * 2, Qnil);
   ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
        functionlist); last_overlay_modification_hooks_used++;
@@ -4375,10 +4304,8 @@ add_overlay_mod_hooklist (functionlist, overlay)
    and the length of deleted or replaced old text.  */
 
 void
-report_overlay_modification (start, end, after, arg1, arg2, arg3)
-     Lisp_Object start, end;
-     int after;
-     Lisp_Object arg1, arg2, arg3;
+report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
+                            Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
 {
   Lisp_Object prop, overlay;
   struct Lisp_Overlay *tail;
@@ -4503,10 +4430,8 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
 }
 
 static void
-call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
-     Lisp_Object list, overlay;
-     int after;
-     Lisp_Object arg1, arg2, arg3;
+call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, int after,
+                       Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
 {
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
@@ -4526,8 +4451,7 @@ call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
 /* Delete any zero-sized overlays at position POS, if the `evaporate'
    property is set.  */
 void
-evaporate_overlays (pos)
-     EMACS_INT pos;
+evaporate_overlays (EMACS_INT pos)
 {
   Lisp_Object overlay, hit_list;
   struct Lisp_Overlay *tail;
@@ -4565,15 +4489,13 @@ evaporate_overlays (pos)
    in the slot with offset OFFSET.  */
 
 void
-buffer_slot_type_mismatch (newval, type)
-     Lisp_Object newval;
-     int type;
+buffer_slot_type_mismatch (Lisp_Object newval, int type)
 {
   Lisp_Object predicate;
 
   switch (type)
     {
-    case Lisp_Int:    predicate = Qintegerp; break;
+    case_Lisp_Int:    predicate = Qintegerp; break;
     case Lisp_String: predicate = Qstringp;  break;
     case Lisp_Symbol: predicate = Qsymbolp;  break;
     default: abort ();
@@ -4605,7 +4527,6 @@ buffer_slot_type_mismatch (newval, type)
 #endif
 
 #include <stdio.h>
-#include <errno.h>
 
 #if MAP_ANON == 0
 #include <fcntl.h>
@@ -4707,13 +4628,13 @@ static int mmap_initialized_p;
 
 /* Function prototypes.  */
 
-static int mmap_free_1 P_ ((struct mmap_region *));
-static int mmap_enlarge P_ ((struct mmap_region *, int));
-static struct mmap_region *mmap_find P_ ((POINTER_TYPE *, POINTER_TYPE *));
-static POINTER_TYPE *mmap_alloc P_ ((POINTER_TYPE **, size_t));
-static POINTER_TYPE *mmap_realloc P_ ((POINTER_TYPE **, size_t));
-static void mmap_free P_ ((POINTER_TYPE **ptr));
-static void mmap_init P_ ((void));
+static int mmap_free_1 (struct mmap_region *);
+static int mmap_enlarge (struct mmap_region *, int);
+static struct mmap_region *mmap_find (POINTER_TYPE *, POINTER_TYPE *);
+static POINTER_TYPE *mmap_alloc (POINTER_TYPE **, size_t);
+static POINTER_TYPE *mmap_realloc (POINTER_TYPE **, size_t);
+static void mmap_free (POINTER_TYPE **ptr);
+static void mmap_init (void);
 
 
 /* Return a region overlapping address range START...END, or null if
@@ -5046,18 +4967,16 @@ mmap_init ()
  ***********************************************************************/
 
 #ifdef REL_ALLOC
-extern POINTER_TYPE *r_alloc P_ ((POINTER_TYPE **, size_t));
-extern POINTER_TYPE *r_re_alloc P_ ((POINTER_TYPE **, size_t));
-extern void r_alloc_free P_ ((POINTER_TYPE **ptr));
+extern POINTER_TYPE *r_alloc (POINTER_TYPE **, size_t);
+extern POINTER_TYPE *r_re_alloc (POINTER_TYPE **, size_t);
+extern void r_alloc_free (POINTER_TYPE **ptr);
 #endif /* REL_ALLOC */
 
 
 /* Allocate NBYTES bytes for buffer B's text buffer.  */
 
 static void
-alloc_buffer_text (b, nbytes)
-     struct buffer *b;
-     size_t nbytes;
+alloc_buffer_text (struct buffer *b, size_t nbytes)
 {
   POINTER_TYPE *p;
 
@@ -5112,8 +5031,7 @@ enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
 /* Free buffer B's text buffer.  */
 
 static void
-free_buffer_text (b)
-     struct buffer *b;
+free_buffer_text (struct buffer *b)
 {
   BLOCK_INPUT;
 
@@ -5136,7 +5054,7 @@ free_buffer_text (b)
  ***********************************************************************/
 
 void
-init_buffer_once ()
+init_buffer_once (void)
 {
   int idx;
 
@@ -5145,7 +5063,9 @@ init_buffer_once ()
   /* Make sure all markable slots in buffer_defaults
      are initialized reasonably, so mark_buffer won't choke.  */
   reset_buffer (&buffer_defaults);
+  eassert (EQ (buffer_defaults.name, make_number (0)));
   reset_buffer_local_variables (&buffer_defaults, 1);
+  eassert (EQ (buffer_local_symbols.name, make_number (0)));
   reset_buffer (&buffer_local_symbols);
   reset_buffer_local_variables (&buffer_local_symbols, 1);
   /* Prevent GC from getting confused.  */
@@ -5162,7 +5082,7 @@ init_buffer_once ()
   /* Must do these before making the first buffer! */
 
   /* real setup is done in bindings.el */
-  buffer_defaults.mode_line_format = build_string ("%-");
+  buffer_defaults.mode_line_format = make_pure_c_string ("%-");
   buffer_defaults.header_line_format = Qnil;
   buffer_defaults.abbrev_mode = Qnil;
   buffer_defaults.overwrite_mode = Qnil;
@@ -5186,7 +5106,8 @@ init_buffer_once ()
   buffer_defaults.truncate_lines = Qnil;
   buffer_defaults.word_wrap = Qnil;
   buffer_defaults.ctl_arrow = Qt;
-  buffer_defaults.direction_reversed = Qnil;
+  buffer_defaults.bidi_display_reordering = Qnil;
+  buffer_defaults.bidi_paragraph_direction = Qnil;
   buffer_defaults.cursor_type = Qt;
   buffer_defaults.extra_line_spacing = Qnil;
   buffer_defaults.cursor_in_non_selected_windows = Qt;
@@ -5271,7 +5192,8 @@ init_buffer_once ()
   XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx;
   XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
   XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
-  XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.bidi_paragraph_direction, idx); ++idx;
   XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
   /* Make this one a permanent local.  */
   buffer_permanent_local_flags[idx++] = 1;
@@ -5302,33 +5224,33 @@ init_buffer_once ()
   current_buffer = 0;
   all_buffers = 0;
 
-  QSFundamental = build_string ("Fundamental");
+  QSFundamental = make_pure_c_string ("Fundamental");
 
-  Qfundamental_mode = intern ("fundamental-mode");
+  Qfundamental_mode = intern_c_string ("fundamental-mode");
   buffer_defaults.major_mode = Qfundamental_mode;
 
-  Qmode_class = intern ("mode-class");
+  Qmode_class = intern_c_string ("mode-class");
 
-  Qprotected_field = intern ("protected-field");
+  Qprotected_field = intern_c_string ("protected-field");
 
-  Qpermanent_local = intern ("permanent-local");
+  Qpermanent_local = intern_c_string ("permanent-local");
 
-  Qkill_buffer_hook = intern ("kill-buffer-hook");
+  Qkill_buffer_hook = intern_c_string ("kill-buffer-hook");
   Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
 
-  Qucs_set_table_for_input = intern ("ucs-set-table-for-input");
+  Qucs_set_table_for_input = intern_c_string ("ucs-set-table-for-input");
 
   /* super-magic invisible buffer */
-  Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
+  Vprin1_to_string_buffer = Fget_buffer_create (make_pure_c_string (" prin1"));
   Vbuffer_alist = Qnil;
 
-  Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
+  Fset_buffer (Fget_buffer_create (make_pure_c_string ("*scratch*")));
 
   inhibit_modification_hooks = 0;
 }
 
 void
-init_buffer ()
+init_buffer (void)
 {
   char *pwd;
   Lisp_Object temp;
@@ -5400,33 +5322,37 @@ init_buffer ()
    in the buffer that is current now. */
 
 /* TYPE is nil for a general Lisp variable.
-   An integer specifies a type; then only LIsp values
+   An integer specifies a type; then only Lisp values
    with that type code are allowed (except that nil is allowed too).
-   LNAME is the LIsp-level variable name.
+   LNAME is the Lisp-level variable name.
    VNAME is the name of the buffer slot.
    DOC is a dummy where you write the doc string as a comment.  */
-#define DEFVAR_PER_BUFFER(lname, vname, type, doc)  \
- defvar_per_buffer (lname, vname, type, 0)
+#define DEFVAR_PER_BUFFER(lname, vname, type, doc)                     \
+  do {                                                                 \
+    static struct Lisp_Buffer_Objfwd bo_fwd;                           \
+    defvar_per_buffer (&bo_fwd, lname, vname, type, 0);                        \
+  } while (0)
 
 static void
-defvar_per_buffer (namestring, address, type, doc)
-     char *namestring;
-     Lisp_Object *address;
-     Lisp_Object type;
-     char *doc;
+defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, char *namestring,
+                  Lisp_Object *address, Lisp_Object type, char *doc)
 {
-  Lisp_Object sym, val;
+  struct Lisp_Symbol *sym;
   int offset;
 
-  sym = intern (namestring);
-  val = allocate_misc ();
+  sym = XSYMBOL (intern (namestring));
   offset = (char *)address - (char *)current_buffer;
 
-  XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd;
-  XBUFFER_OBJFWD (val)->offset = offset;
-  XBUFFER_OBJFWD (val)->slottype = type;
-  SET_SYMBOL_VALUE (sym, val);
-  PER_BUFFER_SYMBOL (offset) = sym;
+  bo_fwd->type = Lisp_Fwd_Buffer_Obj;
+  bo_fwd->offset = offset;
+  bo_fwd->slottype = type;
+  sym->redirect = SYMBOL_FORWARDED;
+  {
+    /* I tried to do the job without a cast, but it seems impossible.
+       union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd;  */
+    SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd);
+  }
+  XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
 
   if (PER_BUFFER_IDX (offset) == 0)
     /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
@@ -5437,7 +5363,7 @@ defvar_per_buffer (namestring, address, type, doc)
 
 /* initialize the buffer routines */
 void
-syms_of_buffer ()
+syms_of_buffer (void)
 {
   staticpro (&last_overlay_modification_hooks);
   last_overlay_modification_hooks
@@ -5451,45 +5377,45 @@ syms_of_buffer ()
   staticpro (&Vbuffer_alist);
   staticpro (&Qprotected_field);
   staticpro (&Qpermanent_local);
-  Qpermanent_local_hook = intern ("permanent-local-hook");
+  Qpermanent_local_hook = intern_c_string ("permanent-local-hook");
   staticpro (&Qpermanent_local_hook);
   staticpro (&Qkill_buffer_hook);
-  Qoverlayp = intern ("overlayp");
+  Qoverlayp = intern_c_string ("overlayp");
   staticpro (&Qoverlayp);
-  Qevaporate = intern ("evaporate");
+  Qevaporate = intern_c_string ("evaporate");
   staticpro (&Qevaporate);
-  Qmodification_hooks = intern ("modification-hooks");
+  Qmodification_hooks = intern_c_string ("modification-hooks");
   staticpro (&Qmodification_hooks);
-  Qinsert_in_front_hooks = intern ("insert-in-front-hooks");
+  Qinsert_in_front_hooks = intern_c_string ("insert-in-front-hooks");
   staticpro (&Qinsert_in_front_hooks);
-  Qinsert_behind_hooks = intern ("insert-behind-hooks");
+  Qinsert_behind_hooks = intern_c_string ("insert-behind-hooks");
   staticpro (&Qinsert_behind_hooks);
-  Qget_file_buffer = intern ("get-file-buffer");
+  Qget_file_buffer = intern_c_string ("get-file-buffer");
   staticpro (&Qget_file_buffer);
-  Qpriority = intern ("priority");
+  Qpriority = intern_c_string ("priority");
   staticpro (&Qpriority);
-  Qwindow = intern ("window");
+  Qwindow = intern_c_string ("window");
   staticpro (&Qwindow);
-  Qbefore_string = intern ("before-string");
+  Qbefore_string = intern_c_string ("before-string");
   staticpro (&Qbefore_string);
-  Qafter_string = intern ("after-string");
+  Qafter_string = intern_c_string ("after-string");
   staticpro (&Qafter_string);
-  Qfirst_change_hook = intern ("first-change-hook");
+  Qfirst_change_hook = intern_c_string ("first-change-hook");
   staticpro (&Qfirst_change_hook);
-  Qbefore_change_functions = intern ("before-change-functions");
+  Qbefore_change_functions = intern_c_string ("before-change-functions");
   staticpro (&Qbefore_change_functions);
-  Qafter_change_functions = intern ("after-change-functions");
+  Qafter_change_functions = intern_c_string ("after-change-functions");
   staticpro (&Qafter_change_functions);
   /* The next one is initialized in init_buffer_once.  */
   staticpro (&Qucs_set_table_for_input);
 
-  Qkill_buffer_query_functions = intern ("kill-buffer-query-functions");
+  Qkill_buffer_query_functions = intern_c_string ("kill-buffer-query-functions");
   staticpro (&Qkill_buffer_query_functions);
 
   Fput (Qprotected_field, Qerror_conditions,
-       Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
+       pure_cons (Qprotected_field, pure_cons (Qerror, Qnil)));
   Fput (Qprotected_field, Qerror_message,
-       build_string ("Attempt to modify a protected field"));
+       make_pure_c_string ("Attempt to modify a protected field"));
 
   /* All these use DEFVAR_LISP_NOPRO because the slots in
      buffer_defaults will all be marked via Vbuffer_defaults.  */
@@ -5528,11 +5454,6 @@ This is the same as (default-value 'abbrev-mode).  */);
                     doc: /* Default value of `ctl-arrow' for buffers that do not override it.
 This is the same as (default-value 'ctl-arrow).  */);
 
-  DEFVAR_LISP_NOPRO ("default-direction-reversed",
-                     &buffer_defaults.direction_reversed,
-                     doc: /* Default value of `direction-reversed' for buffers that do not override it.
-This is the same as (default-value 'direction-reversed).  */);
-
   DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
                      &buffer_defaults.enable_multibyte_characters,
                      doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
@@ -5738,17 +5659,17 @@ Format with `format-mode-line' to produce a string value.  */);
                     doc: /* *Non-nil if searches and matches should ignore case.  */);
 
   DEFVAR_PER_BUFFER ("fill-column", &current_buffer->fill_column,
-                    make_number (Lisp_Int),
+                    make_number (LISP_INT_TAG),
                     doc: /* *Column beyond which automatic line-wrapping should happen.
 Interactively, you can set the buffer local value using \\[set-fill-column].  */);
 
   DEFVAR_PER_BUFFER ("left-margin", &current_buffer->left_margin,
-                    make_number (Lisp_Int),
+                    make_number (LISP_INT_TAG),
                     doc: /* *Column for the default `indent-line-function' to indent to.
 Linefeed indents to this column in Fundamental mode.  */);
 
   DEFVAR_PER_BUFFER ("tab-width", &current_buffer->tab_width,
-                    make_number (Lisp_Int),
+                    make_number (LISP_INT_TAG),
                     doc: /* *Distance between tab stops (for display of tab characters), in columns.  */);
 
   DEFVAR_PER_BUFFER ("ctl-arrow", &current_buffer->ctl_arrow, Qnil,
@@ -5769,7 +5690,7 @@ use the function `set-buffer-multibyte' to change a buffer's representation.
 Changing its default value with `setq-default' is supported.
 See also variable `default-enable-multibyte-characters' and Info node
 `(elisp)Text Representations'.  */);
-  XSYMBOL (intern ("enable-multibyte-characters"))->constant = 1;
+  XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1;
 
   DEFVAR_PER_BUFFER ("buffer-file-coding-system",
                     &current_buffer->buffer_file_coding_system, Qnil,
@@ -5789,11 +5710,23 @@ The variable `coding-system-for-write', if non-nil, overrides this variable.
 
 This variable is never applied to a way of decoding a file while reading it.  */);
 
-  DEFVAR_PER_BUFFER ("direction-reversed", &current_buffer->direction_reversed,
-                    Qnil,
-                    doc: /* *Non-nil means lines in the buffer are displayed right to left.  */);
+  DEFVAR_PER_BUFFER ("bidi-display-reordering",
+                    &current_buffer->bidi_display_reordering, Qnil,
+                    doc: /* Non-nil means reorder bidirectional text for display in the visual order.  */);
+
+  DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
+                    &current_buffer->bidi_paragraph_direction, Qnil,
+                    doc: /* *If non-nil, forces directionality of text paragraphs in the buffer.
+
+If this is nil (the default), the direction of each paragraph is
+determined by the first strong directional character of its text.
+The values of `right-to-left' and `left-to-right' override that.
+Any other value is treated as nil.
+
+This variable has no effect unless the buffer's value of
+\`bidi-display-reordering' is non-nil.  */);
 
 DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
+ DEFVAR_PER_BUFFER ("truncate-lines", &current_buffer->truncate_lines, Qnil,
                     doc: /* *Non-nil means do not display continuation lines.
 Instead, give each line of text just one screen line.
 
@@ -5859,7 +5792,7 @@ If it is nil, that means don't auto-save this buffer.  */);
 Backing up is done before the first time the file is saved.  */);
 
   DEFVAR_PER_BUFFER ("buffer-saved-size", &current_buffer->save_length,
-                    make_number (Lisp_Int),
+                    make_number (LISP_INT_TAG),
                     doc: /* Length of current buffer when last read in, saved or auto-saved.
 0 initially.
 -1 means auto-saving turned off until next real save.
@@ -6278,7 +6211,7 @@ If any of them returns nil, the buffer is not killed.  */);
               doc: /* Normal hook run before changing the major mode of a buffer.
 The function `kill-all-local-variables' runs this before doing anything else.  */);
   Vchange_major_mode_hook = Qnil;
-  Qchange_major_mode_hook = intern ("change-major-mode-hook");
+  Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
   staticpro (&Qchange_major_mode_hook);
 
   defsubr (&Sbuffer_live_p);
@@ -6333,14 +6266,14 @@ The function `kill-all-local-variables' runs this before doing anything else.  *
 }
 
 void
-keys_of_buffer ()
+keys_of_buffer (void)
 {
   initial_define_key (control_x_map, 'b', "switch-to-buffer");
   initial_define_key (control_x_map, 'k', "kill-buffer");
 
   /* This must not be in syms_of_buffer, because Qdisabled is not
      initialized when that function gets called.  */
-  Fput (intern ("erase-buffer"), Qdisabled, Qt);
+  Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
 }
 
 /* arch-tag: e48569bf-69a9-4b65-a23b-8e68769436e1