changeset 19448:950a178e8783

(Vauto_file_coding_system_function): New variable. (Finsert_file_contents): Decide coding system after opening a file. Call functions set in Vauto_file_coding_system_function. (syms_of_fileio): Declare auto-file-coding-system as a Lisp variable.
author Kenichi Handa <handa@m17n.org>
date Fri, 22 Aug 1997 01:19:27 +0000
parents 34099ec680df
children 7574338c92e2
files src/fileio.c
diffstat 1 files changed, 57 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/fileio.c	Fri Aug 22 01:19:27 1997 +0000
+++ b/src/fileio.c	Fri Aug 22 01:19:27 1997 +0000
@@ -169,6 +169,9 @@
 /* Lisp functions for translating file formats */
 Lisp_Object Qformat_decode, Qformat_annotate_function;
 
+/* Function to be called to decide a coding system of a reading file.  */
+Lisp_Object Vauto_file_coding_system_function;
+
 /* Functions to be called to process text properties in inserted file.  */
 Lisp_Object Vafter_insert_file_functions;
 
@@ -3063,26 +3066,6 @@
       goto handled;
     }
 
-  /* Decide the coding-system of the file.  */
-  {
-    Lisp_Object val;
-
-    if (!NILP (Vcoding_system_for_read))
-      val = Vcoding_system_for_read;
-    else if (NILP (current_buffer->enable_multibyte_characters))
-      val = Qemacs_mule;
-    else
-      {
-	Lisp_Object args[6], coding_systems;
-
-	args[0] = Qinsert_file_contents, args[1] = filename, args[2] = visit,
-	  args[3] = beg, args[4] = end, args[5] = replace;
-	coding_systems = Ffind_operation_coding_system (6, args);
-	val = CONSP (coding_systems) ? XCONS (coding_systems)->car : Qnil;
-      }
-    setup_coding_system (Fcheck_coding_system (val), &coding);
-  }
-
   fd = -1;
 
 #ifndef APOLLO
@@ -3154,6 +3137,50 @@
 	}
     }
 
+  /* Decide the coding-system of the file.  */
+  {
+    Lisp_Object val = Qnil;
+
+    if (!NILP (Vcoding_system_for_read))
+      val = Vcoding_system_for_read;
+    else if (NILP (current_buffer->enable_multibyte_characters))
+      val = Qemacs_mule;
+    else
+      {
+	if (SYMBOLP (Vauto_file_coding_system_function)
+	    && Fboundp (Vauto_file_coding_system_function))
+	  {
+	    /* Find a coding system specified in a few lines at the
+	       head of the file.  We assume that the fist 1K bytes is
+	       sufficient fot this purpose.  */
+	    int nread = read (fd, read_buf, 1024);
+	 
+	    if (nread < 0)
+	      error ("IO error reading %s: %s",
+		     XSTRING (filename)->data, strerror (errno));
+	    else if (nread > 0)
+	      {
+		val = call1 (Vauto_file_coding_system_function,
+			     make_string (read_buf, nread));
+		/* Rewind the file for the actual read done later.  */
+		if (lseek (fd, 0, 0) < 0)
+		  report_file_error ("Setting file position",
+				     Fcons (filename, Qnil));
+	      }
+	  }
+	if (NILP (val))
+	  {
+	    Lisp_Object args[6], coding_systems;
+
+	    args[0] = Qinsert_file_contents, args[1] = filename,
+	      args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
+	    coding_systems = Ffind_operation_coding_system (6, args);
+	    if (CONSP (coding_systems)) val = XCONS (coding_systems)->car;
+	  }
+      }
+    setup_coding_system (Fcheck_coding_system (val), &coding);
+  }
+
   /* If requested, replace the accessible part of the buffer
      with the file contents.  Avoid replacing text at the
      beginning or end of the buffer that matches the file contents;
@@ -5126,6 +5153,16 @@
 for its argument.");
   Vfile_name_handler_alist = Qnil;
 
+  DEFVAR_LISP ("auto-file-coding-system-function",
+	       &Vauto_file_coding_system_function,
+    "If non-nil, a function to call to decide a coding system of file.
+One argument is passed to this function: the string of the first
+few lines of a file to be read.
+This function should return a coding system to decode the file contents
+specified in the heading lines with the format:
+	-*- ... coding: CODING-SYSTEM; ... -*-");
+  Vauto_file_coding_system_function = Qnil;
+
   DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
     "A list of functions to be called at the end of `insert-file-contents'.\n\
 Each is passed one argument, the number of bytes inserted.  It should return\n\