X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/67e8e2b8092fe8e79b24e079dfccde390db4f58c..d243e605a05e28cfd0d68fee5d28b05593ec6969:/src/fileio.c diff --git a/src/fileio.c b/src/fileio.c index b3fcda88e9..29367875ac 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -177,6 +177,10 @@ Lisp_Object Vset_auto_coding_function; /* Functions to be called to process text properties in inserted file. */ Lisp_Object Vafter_insert_file_functions; +/* Lisp function for setting buffer-file-coding-system and the + multibyteness of the current buffer after inserting a file. */ +Lisp_Object Qafter_insert_file_set_coding; + /* Functions to be called to create text property annotations for file. */ Lisp_Object Vwrite_region_annotate_functions; @@ -447,9 +451,7 @@ on VMS, perhaps instead a string ending in `:', `]' or `>'. */) CORRECT_DIR_SEPS (beg); #endif /* DOS_NT */ - if (STRING_MULTIBYTE (filename)) - return make_string (beg, p - beg); - return make_unibyte_string (beg, p - beg); + return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); } DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, @@ -488,9 +490,7 @@ or the entire name if it contains no slash. */) ) p--; - if (STRING_MULTIBYTE (filename)) - return make_string (p, end - p); - return make_unibyte_string (p, end - p); + return make_specified_string (p, -1, end - p, STRING_MULTIBYTE (filename)); } DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, @@ -631,7 +631,9 @@ On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc. */) return call2 (handler, Qfile_name_as_directory, file); buf = (char *) alloca (SBYTES (file) + 10); - return build_string (file_name_as_directory (buf, SDATA (file))); + file_name_as_directory (buf, SDATA (file)); + return make_specified_string (buf, -1, strlen (buf), + STRING_MULTIBYTE (file)); } /* @@ -831,7 +833,8 @@ it returns a file name such as \"[X]Y.DIR.1\". */) buf = (char *) alloca (SBYTES (directory) + 20); #endif directory_file_name (SDATA (directory), buf); - return build_string (buf); + return make_specified_string (buf, -1, strlen (buf), + STRING_MULTIBYTE (directory)); } static char make_temp_name_tbl[64] = @@ -1027,7 +1030,7 @@ See also the function `substitute-in-file-name'. */) int is_escaped = 0; #endif /* DOS_NT */ int length; - Lisp_Object handler; + Lisp_Object handler, result; CHECK_STRING (name); @@ -1275,7 +1278,11 @@ See also the function `substitute-in-file-name'. */) { #ifdef VMS if (index (nm, '/')) - return build_string (sys_translate_unix (nm)); + { + nm = sys_translate_unix (nm); + return make_specified_string (nm, -1, strlen (nm), + STRING_MULTIBYTE (name)); + } #endif /* VMS */ #ifdef DOS_NT /* Make sure directories are all separated with / or \ as @@ -1286,22 +1293,27 @@ See also the function `substitute-in-file-name'. */) if (IS_DIRECTORY_SEP (nm[1])) { if (strcmp (nm, SDATA (name)) != 0) - name = build_string (nm); + name = make_specified_string (nm, -1, strlen (nm), + STRING_MULTIBYTE (name)); } else #endif /* drive must be set, so this is okay */ if (strcmp (nm - 2, SDATA (name)) != 0) { - name = make_string (nm - 2, p - nm + 2); - SSET (name, 0, DRIVE_LETTER (drive)); - SSET (name, 1, ':'); + char temp[] = " :"; + + name = make_specified_string (nm, -1, p - nm, + STRING_MULTIBYTE (name)); + temp[0] = DRIVE_LETTER (drive); + name = concat2 (build_string (temp), name); } return name; #else /* not DOS_NT */ if (nm == SDATA (name)) return name; - return build_string (nm); + return make_specified_string (nm, -1, strlen (nm), + STRING_MULTIBYTE (name)); #endif /* not DOS_NT */ } } @@ -1670,7 +1682,19 @@ See also the function `substitute-in-file-name'. */) CORRECT_DIR_SEPS (target); #endif /* DOS_NT */ - return make_string (target, o - target); + result = make_specified_string (target, -1, o - target, + STRING_MULTIBYTE (name)); + + /* Again look to see if the file name has special constructs in it + and perhaps call the corresponding file handler. This is needed + for filenames such as "/foo/../user@host:/bar/../baz". Expanding + the ".." component gives us "/user@host:/bar/../baz" which needs + to be expanded again. */ + handler = Ffind_file_name_handler (result, Qexpand_file_name); + if (!NILP (handler)) + return call3 (handler, Qexpand_file_name, result, default_directory); + + return result; } #if 0 @@ -2052,13 +2076,13 @@ duplicates what `expand-file-name' does. */) for (p = nm; p != endp; p++) { if ((p[0] == '~' -#if defined (APOLLO) || defined (WINDOWSNT) - /* // at start of file name is meaningful in Apollo and - WindowsNT systems. */ +#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN) + /* // at start of file name is meaningful in Apollo, + WindowsNT and Cygwin systems. */ || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm) -#else /* not (APOLLO || WINDOWSNT) */ +#else /* not (APOLLO || WINDOWSNT || CYGWIN) */ || IS_DIRECTORY_SEP (p[0]) -#endif /* not (APOLLO || WINDOWSNT) */ +#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */ ) && p != nm && (0 @@ -2101,7 +2125,8 @@ duplicates what `expand-file-name' does. */) } #ifdef VMS - return build_string (nm); + return make_specified_string (nm, -1, strlen (nm), + STRING_MULTIBYTE (filename)); #else /* See if any variables are substituted into the string @@ -2230,11 +2255,11 @@ duplicates what `expand-file-name' does. */) for (p = xnm; p != x; p++) if ((p[0] == '~' -#if defined (APOLLO) || defined (WINDOWSNT) +#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN) || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm) -#else /* not (APOLLO || WINDOWSNT) */ +#else /* not (APOLLO || WINDOWSNT || CYGWIN) */ || IS_DIRECTORY_SEP (p[0]) -#endif /* not (APOLLO || WINDOWSNT) */ +#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */ ) && p != xnm && IS_DIRECTORY_SEP (p[-1])) xnm = p; @@ -2244,9 +2269,7 @@ duplicates what `expand-file-name' does. */) xnm = p; #endif - if (STRING_MULTIBYTE (filename)) - return make_string (xnm, x - xnm); - return make_unibyte_string (xnm, x - xnm); + return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE (filename)); badsubst: error ("Bad format environment-variable substitution"); @@ -2405,7 +2428,8 @@ A prefix arg makes KEEP-TIME non-nil. */) SDATA (encoded_newname), FALSE)) report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil))); - else if (!NILP (keep_time)) + /* CopyFile retains the timestamp by default. */ + else if (NILP (keep_time)) { EMACS_TIME now; DWORD attributes; @@ -3162,7 +3186,7 @@ If there is no error, we return nil. */) DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0, doc: /* Return non-nil if file FILENAME is the name of a symbolic link. -The value is the name of the file to which it is linked. +The value is the link target, as a string. Otherwise returns nil. */) (filename) Lisp_Object filename; @@ -3554,7 +3578,7 @@ read_non_regular_quit () DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, 1, 5, 0, doc: /* Insert contents of file FILENAME after point. -Returns list of absolute file name and number of bytes inserted. +Returns list of absolute file name and number of characters inserted. If second argument VISIT is non-nil, the buffer's visited filename and last save file modtime are set, and it is marked unmodified. If visiting and the file does not exist, visiting is completed @@ -4473,6 +4497,8 @@ actually used. */) inserted); } + /* Now INSERTED is measured in characters. */ + #ifdef DOS_NT /* Use the conversion type to determine buffer-file-type (find-buffer-file-type is now used to help determine the @@ -4518,6 +4544,19 @@ actually used. */) Fcons (orig_filename, Qnil))); } + if (set_coding_system) + Vlast_coding_system_used = coding.symbol; + + if (! NILP (Ffboundp (Qafter_insert_file_set_coding))) + { + insval = call1 (Qafter_insert_file_set_coding, make_number (inserted)); + if (! NILP (insval)) + { + CHECK_NUMBER (insval); + inserted = XFASTINT (insval); + } + } + /* Decode file format */ if (inserted > 0) { @@ -4541,9 +4580,6 @@ actually used. */) current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt; } - if (set_coding_system) - Vlast_coding_system_used = coding.symbol; - /* Call after-change hooks for the inserted text, aside from the case of normal visiting (not with REPLACE), which is done in a new buffer "before" the buffer is changed. */ @@ -6022,6 +6058,7 @@ provides a file dialog box. */) Lisp_Object val, insdef, tem; struct gcpro gcpro1, gcpro2; register char *homedir; + Lisp_Object decoded_homedir; int replace_in_history = 0; int add_to_history = 0; int count; @@ -6044,25 +6081,29 @@ provides a file dialog box. */) CORRECT_DIR_SEPS (homedir); } #endif + if (homedir != 0) + decoded_homedir + = DECODE_FILE (make_unibyte_string (homedir, strlen (homedir))); if (homedir != 0 && STRINGP (dir) - && !strncmp (homedir, SDATA (dir), strlen (homedir)) - && IS_DIRECTORY_SEP (SREF (dir, strlen (homedir)))) + && !strncmp (SDATA (decoded_homedir), SDATA (dir), + SBYTES (decoded_homedir)) + && IS_DIRECTORY_SEP (SREF (dir, SBYTES (decoded_homedir)))) { - dir = make_string (SDATA (dir) + strlen (homedir) - 1, - SBYTES (dir) - strlen (homedir) + 1); - SSET (dir, 0, '~'); + dir = Fsubstring (dir, make_number (SCHARS (decoded_homedir)), Qnil); + dir = concat2 (build_string ("~"), dir); } /* Likewise for default_filename. */ if (homedir != 0 && STRINGP (default_filename) - && !strncmp (homedir, SDATA (default_filename), strlen (homedir)) - && IS_DIRECTORY_SEP (SREF (default_filename, strlen (homedir)))) + && !strncmp (SDATA (decoded_homedir), SDATA (default_filename), + SBYTES (decoded_homedir)) + && IS_DIRECTORY_SEP (SREF (default_filename, SBYTES (decoded_homedir)))) { default_filename - = make_string (SDATA (default_filename) + strlen (homedir) - 1, - SBYTES (default_filename) - strlen (homedir) + 1); - SSET (default_filename, 0, '~'); + = Fsubstring (default_filename, + make_number (SCHARS (decoded_homedir)), Qnil); + default_filename = concat2 (build_string ("~"), default_filename); } if (!NILP (default_filename)) { @@ -6116,7 +6157,7 @@ provides a file dialog box. */) (NILP (predicate) ? Qfile_exists_p : predicate)); GCPRO2 (insdef, default_filename); - + #if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) && use_dialog_box @@ -6317,6 +6358,8 @@ same format as a regular save would use. */); staticpro (&Qformat_decode); Qformat_annotate_function = intern ("format-annotate-function"); staticpro (&Qformat_annotate_function); + Qafter_insert_file_set_coding = intern ("after-insert-file-set-coding"); + staticpro (&Qafter_insert_file_set_coding); Qcar_less_than_car = intern ("car-less-than-car"); staticpro (&Qcar_less_than_car); @@ -6389,10 +6432,11 @@ or local variable spec of the tailing lines with `coding:' tag. */); DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions, doc: /* A list of functions to be called at the end of `insert-file-contents'. -Each is passed one argument, the number of bytes inserted. It should return -the new byte count, and leave point the same. If `insert-file-contents' is -intercepted by a handler from `file-name-handler-alist', that handler is -responsible for calling the after-insert-file-functions if appropriate. */); +Each is passed one argument, the number of characters inserted. +It should return the new character count, and leave point the same. +If `insert-file-contents' is intercepted by a handler from +`file-name-handler-alist', that handler is responsible for calling the +functions in `after-insert-file-functions' if appropriate. */); Vafter_insert_file_functions = Qnil; DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,