diff src/buffer.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents aabb7f5b1c81
children a86b2b5e0111
line wrap: on
line diff
--- a/src/buffer.c	Mon Aug 13 11:12:06 2007 +0200
+++ b/src/buffer.c	Mon Aug 13 11:13:30 2007 +0200
@@ -74,8 +74,12 @@
 #include "elhash.h"
 #include "extents.h"
 #include "faces.h"
+#ifdef FILE_CODING
+#include "file-coding.h"
+#endif
 #include "frame.h"
 #include "insdel.h"
+#include "lstream.h"
 #include "process.h"            /* for kill_buffer_processes */
 #ifdef REGION_CACHE_NEEDS_WORK
 #include "region-cache.h"
@@ -96,6 +100,7 @@
    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.
@@ -133,6 +138,7 @@
 /* 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,
@@ -189,7 +195,7 @@
 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;
 
@@ -220,7 +226,7 @@
 }
 
 static Lisp_Object
-mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_buffer (Lisp_Object obj)
 {
   struct buffer *buf = XBUFFER (obj);
 
@@ -229,13 +235,13 @@
                                        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.)  */
@@ -276,7 +282,7 @@
    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);
 
 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /*
@@ -541,7 +547,7 @@
 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));
 
@@ -1180,7 +1186,7 @@
       killp = call1
 	(Qyes_or_no_p,
 	 (emacs_doprnt_string_c
-	  ((CONST Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "),
+	  ((const Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "),
 	   Qnil, -1, XSTRING_DATA (b->name))));
       UNGCPRO;
       if (NILP (killp))
@@ -1406,6 +1412,9 @@
     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;
 }
 
@@ -1619,6 +1628,8 @@
 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.
 */
@@ -1798,6 +1809,342 @@
 
 #endif /* MEMORY_USAGE_STATS */
 
+
+/************************************************************************/
+/*           Implement TO_EXTERNAL_FORMAT, TO_INTERNAL_FORMAT           */
+/************************************************************************/
+
+/* This implementation should probably be elsewhere, but it can't be
+   in file-coding.c since that file is only available if FILE_CODING
+   is defined. */
+#ifdef FILE_CODING
+static int
+coding_system_is_binary (Lisp_Object coding_system)
+{
+  Lisp_Coding_System *cs = XCODING_SYSTEM (coding_system);
+  return
+    (CODING_SYSTEM_TYPE (cs) == CODESYS_NO_CONVERSION &&
+     CODING_SYSTEM_EOL_TYPE (cs) == EOL_LF &&
+     EQ (CODING_SYSTEM_POST_READ_CONVERSION (cs), Qnil) &&
+     EQ (CODING_SYSTEM_PRE_WRITE_CONVERSION (cs), Qnil));
+}
+#else
+#define coding_system_is_binary(coding_system) 1
+#endif
+
+static Extbyte_dynarr *conversion_out_dynarr;
+static Bufbyte_dynarr *conversion_in_dynarr;
+
+static int dfc_convert_to_external_format_in_use;
+static int dfc_convert_to_internal_format_in_use;
+
+static Lisp_Object
+dfc_convert_to_external_format_reset_in_use (Lisp_Object value)
+{
+  dfc_convert_to_external_format_in_use = XINT (value);
+  return Qnil;
+}
+
+static Lisp_Object
+dfc_convert_to_internal_format_reset_in_use (Lisp_Object value)
+{
+  dfc_convert_to_internal_format_in_use = XINT (value);
+  return Qnil;
+}
+
+void
+dfc_convert_to_external_format (dfc_conversion_type source_type,
+				dfc_conversion_data *source,
+#ifdef FILE_CODING
+				Lisp_Object coding_system,
+#endif
+				dfc_conversion_type sink_type,
+				dfc_conversion_data *sink)
+{
+  int count = specpdl_depth ();
+
+  type_checking_assert
+    (((source_type == DFC_TYPE_DATA) ||
+      (source_type == DFC_TYPE_LISP_LSTREAM && LSTREAMP (source->lisp_object)) ||
+      (source_type == DFC_TYPE_LISP_STRING && STRINGP (source->lisp_object)))
+     &&
+     ((sink_type == DFC_TYPE_DATA) ||
+      (sink_type == DFC_TYPE_LISP_LSTREAM && LSTREAMP (source->lisp_object))));
+
+  if (dfc_convert_to_external_format_in_use != 0)
+    error ("Can't call a conversion function from a conversion function");
+  else
+    dfc_convert_to_external_format_in_use = 1;
+
+  record_unwind_protect (dfc_convert_to_external_format_reset_in_use,
+			 Qzero);
+
+#ifdef FILE_CODING
+  coding_system = Fget_coding_system (coding_system);
+#endif
+
+  Dynarr_reset (conversion_out_dynarr);
+
+  /* Here we optimize in the case where the coding system does no
+     conversion. However, we don't want to optimize in case the source
+     or sink is an lstream, since writing to an lstream can cause a
+     garbage collection, and this could be problematic if the source
+     is a lisp string. */
+  if (source_type != DFC_TYPE_LISP_LSTREAM &&
+      sink_type   != DFC_TYPE_LISP_LSTREAM &&
+      coding_system_is_binary (coding_system))
+    {
+      const Bufbyte *ptr;
+      Bytecount len;
+
+      if (source_type == DFC_TYPE_LISP_STRING)
+	{
+	  ptr = XSTRING_DATA   (source->lisp_object);
+	  len = XSTRING_LENGTH (source->lisp_object);
+	}
+      else
+	{
+	  ptr = (Bufbyte *) source->data.ptr;
+	  len = source->data.len;
+	}
+
+#ifdef MULE
+      {
+	const Bufbyte *end;
+	for (end = ptr + len; ptr < end;)
+	  {
+	    Bufbyte c =
+	      (BYTE_ASCII_P (*ptr))		   ? *ptr :
+	      (*ptr == LEADING_BYTE_CONTROL_1)	   ? (*(ptr+1) - 0x20) :
+	      (*ptr == LEADING_BYTE_LATIN_ISO8859_1) ? (*(ptr+1)) :
+	      '~';
+
+	    Dynarr_add (conversion_out_dynarr, (Extbyte) c);
+	    INC_CHARPTR (ptr);
+	  }
+	bufpos_checking_assert (ptr == end);
+      }
+#else
+      Dynarr_add_many (conversion_out_dynarr, ptr, len);
+#endif
+
+    }
+  else
+    {
+      Lisp_Object streams_to_delete[3];
+      int delete_count = 0;
+      Lisp_Object instream, outstream;
+      Lstream *reader, *writer;
+      struct gcpro gcpro1, gcpro2;
+
+      if (source_type == DFC_TYPE_LISP_LSTREAM)
+	instream = source->lisp_object;
+      else if (source_type == DFC_TYPE_DATA)
+	streams_to_delete[delete_count++] = instream =
+	  make_fixed_buffer_input_stream (source->data.ptr, source->data.len);
+      else
+	{
+	  type_checking_assert (source_type == DFC_TYPE_LISP_STRING);
+	  streams_to_delete[delete_count++] = instream =
+	    make_lisp_string_input_stream (source->lisp_object, 0, -1);
+	}
+
+      if (sink_type == DFC_TYPE_LISP_LSTREAM)
+	outstream = sink->lisp_object;
+      else
+	{
+	  type_checking_assert (sink_type == DFC_TYPE_DATA);
+	  streams_to_delete[delete_count++] = outstream =
+	    make_dynarr_output_stream
+	    ((unsigned_char_dynarr *) conversion_out_dynarr);
+	}
+
+#ifdef FILE_CODING
+      streams_to_delete[delete_count++] = outstream =
+	make_encoding_output_stream (XLSTREAM (outstream), coding_system);
+#endif
+
+      reader = XLSTREAM (instream);
+      writer = XLSTREAM (outstream);
+      /* decoding_stream will gc-protect outstream */
+      GCPRO2 (instream, outstream);
+
+      while (1)
+        {
+          ssize_t size_in_bytes;
+	  char tempbuf[1024]; /* some random amount */
+
+	  size_in_bytes = Lstream_read (reader, tempbuf, sizeof (tempbuf));
+
+          if (size_in_bytes == 0)
+            break;
+	  else if (size_in_bytes < 0)
+	    error ("Error converting to external format");
+
+	  size_in_bytes = Lstream_write (writer, tempbuf, size_in_bytes);
+
+	  if (size_in_bytes <= 0)
+	    error ("Error converting to external format");
+        }
+
+      /* Closing writer will close any stream at the other end of writer. */
+      Lstream_close (writer);
+      Lstream_close (reader);
+      UNGCPRO;
+
+      /* The idea is that this function will create no garbage. */
+      while (delete_count)
+	Lstream_delete (XLSTREAM (streams_to_delete [--delete_count]));
+    }
+
+  unbind_to (count, Qnil);
+
+  if (sink_type != DFC_TYPE_LISP_LSTREAM)
+    {
+      sink->data.len = Dynarr_length (conversion_out_dynarr);
+      Dynarr_add (conversion_out_dynarr, 0);
+      sink->data.ptr = Dynarr_atp (conversion_out_dynarr, 0);
+    }
+}
+
+void
+dfc_convert_to_internal_format (dfc_conversion_type source_type,
+				dfc_conversion_data *source,
+#ifdef FILE_CODING
+				Lisp_Object coding_system,
+#endif
+				dfc_conversion_type sink_type,
+				dfc_conversion_data *sink)
+{
+  int count = specpdl_depth ();
+
+  type_checking_assert
+    ((source_type == DFC_TYPE_DATA ||
+      source_type == DFC_TYPE_LISP_LSTREAM)
+    &&
+    (sink_type   == DFC_TYPE_DATA ||
+     sink_type   == DFC_TYPE_LISP_LSTREAM));
+
+  if (dfc_convert_to_internal_format_in_use != 0)
+    error ("Can't call a conversion function from a conversion function");
+  else
+    dfc_convert_to_internal_format_in_use = 1;
+
+  record_unwind_protect (dfc_convert_to_internal_format_reset_in_use,
+			 Qzero);
+
+#ifdef FILE_CODING
+  coding_system = Fget_coding_system (coding_system);
+#endif
+
+  Dynarr_reset (conversion_in_dynarr);
+
+  if (source_type != DFC_TYPE_LISP_LSTREAM &&
+      sink_type   != DFC_TYPE_LISP_LSTREAM &&
+      coding_system_is_binary (coding_system))
+    {
+#ifdef MULE
+      const Bufbyte *ptr = (const Bufbyte *) source->data.ptr;
+      Bytecount len = source->data.len;
+      const Bufbyte *end = ptr + len;
+
+      for (; ptr < end; ptr++)
+        {
+          Extbyte c = *ptr;
+
+	  if (BYTE_ASCII_P (c))
+	    Dynarr_add (conversion_in_dynarr, c);
+	  else if (BYTE_C1_P (c))
+	    {
+	      Dynarr_add (conversion_in_dynarr, LEADING_BYTE_CONTROL_1);
+	      Dynarr_add (conversion_in_dynarr, c + 0x20);
+	    }
+	  else
+	    {
+	      Dynarr_add (conversion_in_dynarr, LEADING_BYTE_LATIN_ISO8859_1);
+	      Dynarr_add (conversion_in_dynarr, c);
+	    }
+        }
+#else
+      Dynarr_add_many (conversion_in_dynarr, source->data.ptr, source->data.len);
+#endif
+    }
+  else
+    {
+      Lisp_Object streams_to_delete[3];
+      int delete_count = 0;
+      Lisp_Object instream, outstream;
+      Lstream *reader, *writer;
+      struct gcpro gcpro1, gcpro2;
+
+      if (source_type == DFC_TYPE_LISP_LSTREAM)
+	instream = source->lisp_object;
+      else
+	{
+	  type_checking_assert (source_type == DFC_TYPE_DATA);
+	  streams_to_delete[delete_count++] = instream =
+	    make_fixed_buffer_input_stream (source->data.ptr, source->data.len);
+	}
+
+      if (sink_type == DFC_TYPE_LISP_LSTREAM)
+	outstream = sink->lisp_object;
+      else
+	{
+	  type_checking_assert (sink_type == DFC_TYPE_DATA);
+	  streams_to_delete[delete_count++] = outstream =
+	    make_dynarr_output_stream
+	    ((unsigned_char_dynarr *) conversion_in_dynarr);
+	}
+
+#ifdef FILE_CODING
+      streams_to_delete[delete_count++] = outstream =
+	make_decoding_output_stream (XLSTREAM (outstream), coding_system);
+#endif
+
+      reader = XLSTREAM (instream);
+      writer = XLSTREAM (outstream);
+      /* outstream will gc-protect its sink stream, if necessary */
+      GCPRO2 (instream, outstream);
+
+      while (1)
+        {
+          ssize_t size_in_bytes;
+	  char tempbuf[1024]; /* some random amount */
+
+	  size_in_bytes = Lstream_read (reader, tempbuf, sizeof (tempbuf));
+
+          if (size_in_bytes == 0)
+            break;
+	  else if (size_in_bytes < 0)
+	    error ("Error converting to internal format");
+
+	  size_in_bytes = Lstream_write (writer, tempbuf, size_in_bytes);
+
+	  if (size_in_bytes <= 0)
+	    error ("Error converting to internal format");
+        }
+
+      /* Closing writer will close any stream at the other end of writer. */
+      Lstream_close (writer);
+      Lstream_close (reader);
+      UNGCPRO;
+
+      /* The idea is that this function will create no garbage. */
+      while (delete_count)
+	Lstream_delete (XLSTREAM (streams_to_delete [--delete_count]));
+    }
+
+  unbind_to (count, Qnil);
+
+  if (sink_type != DFC_TYPE_LISP_LSTREAM)
+    {
+      sink->data.len = Dynarr_length (conversion_in_dynarr);
+      Dynarr_add (conversion_in_dynarr, 0); /* remember to zero-terminate! */
+      sink->data.ptr = Dynarr_atp (conversion_in_dynarr, 0);
+    }
+}
+
+
 void
 syms_of_buffer (void)
 {
@@ -1806,6 +2153,7 @@
   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 +2164,6 @@
   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 +2216,29 @@
 	    "Attempt to modify a protected field", Qerror);
 }
 
+void
+reinit_vars_of_buffer (void)
+{
+  conversion_in_dynarr  = Dynarr_new (Bufbyte);
+  conversion_out_dynarr = Dynarr_new (Extbyte);
+
+  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.
@@ -2023,10 +2378,26 @@
    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 };						\
+  static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C =		\
+  { /* struct symbol_value_forward */						\
+    { /* struct symbol_value_magic */						\
+      { /* struct lcrecord_header */						\
+	{ /* struct lrecord_header */						\
+	  1, /* type - index into lrecord_implementations_table */		\
+	  0, /* mark bit */							\
+	  0, /* c_readonly bit */						\
+	  0  /* lisp_readonly bit */						\
+	},									\
+	0, /* next */								\
+	0, /* uid  */								\
+	0  /* free */								\
+      },									\
+      &(buffer_local_flags.field_name),						\
+      forward_type								\
+    },										\
+    magicfun									\
+  };										\
+										\
   {										\
     int offset = ((char *)symbol_value_forward_forward (&I_hate_C) -		\
 		  (char *)&buffer_local_flags);					\
@@ -2063,21 +2434,21 @@
   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);
-
-  staticpro (&Vbuffer_defaults);
-  staticpro (&Vbuffer_local_symbols);
+  struct buffer *defs = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
+  struct buffer *syms = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
+
+  staticpro_nodump (&Vbuffer_defaults);
+  staticpro_nodump (&Vbuffer_local_symbols);
   XSETBUFFER (Vbuffer_defaults, defs);
   XSETBUFFER (Vbuffer_local_symbols, syms);
 
@@ -2193,10 +2564,56 @@
     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_ARRAY, 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.
@@ -2690,19 +3107,22 @@
 
 /* Is PWD another name for `.' ? */
 static int
-directory_is_current_directory (char *pwd)
+directory_is_current_directory (Extbyte *pwd)
 {
   Bufbyte *pwd_internal;
+  Bytecount pwd_internal_len;
   struct stat dotstat, pwdstat;
 
-  GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal);
+  TO_INTERNAL_FORMAT (DATA, (pwd, strlen ((char *)pwd) + 1),
+		      ALLOCA, (pwd_internal, pwd_internal_len),
+		      Qfile_name);
 
   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);
+	  && pwd_internal_len < MAXPATHLEN);
 }
 
 void
@@ -2710,15 +3130,15 @@
 {
   /* This function can GC */
 
-  char *pwd;
+  Extbyte *pwd;
 
   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")) != NULL
+  if ((pwd = (Extbyte *) getenv ("PWD")) != NULL
       && directory_is_current_directory (pwd))
-    strcpy (initial_directory, pwd);
+    strcpy (initial_directory, (char *) pwd);
   else if (getcwd (initial_directory, MAXPATHLEN) == NULL)
     fatal ("`getcwd' failed: %s\n", strerror (errno));
 
@@ -2756,7 +3176,7 @@
   Fset_buffer (Fget_buffer_create (QSscratch));
 
   current_buffer->directory =
-    build_ext_string (initial_directory, FORMAT_FILENAME);
+    build_ext_string (initial_directory, Qfile_name);
 
 #if 0 /* FSFmacs */
   /* #### is this correct? */