X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/bb951f0e9e5930e053f8491e419ad59a821fed34..af6ea8ad8d62810d901561ae4a56d89f22ebacf0:/src/callproc.c diff --git a/src/callproc.c b/src/callproc.c index a9b9d2bff6..d8eebac08a 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1,6 +1,6 @@ /* Synchronous subprocess invocation for GNU Emacs. Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001, - 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -75,7 +75,7 @@ extern int errno; #include "lisp.h" #include "commands.h" #include "buffer.h" -#include "charset.h" +#include "character.h" #include "ccl.h" #include "coding.h" #include "composite.h" @@ -203,6 +203,10 @@ t (mix it with ordinary output), or a file name string. Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. Remaining arguments are strings passed as command arguments to PROGRAM. +If executable PROGRAM can't be found as an executable, `call-process' +signals a Lisp error. `call-process' reports errors in execution of +the program only through its return and output. + If BUFFER is 0, `call-process' returns immediately with value nil. Otherwise it waits for PROGRAM to terminate and returns a numeric exit status or a signal description string. @@ -269,6 +273,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (nargs >= 5) { int must_encode = 0; + Lisp_Object coding_attrs; for (i = 4; i < nargs; i++) CHECK_STRING (args[i]); @@ -294,7 +299,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) else val = Qnil; } + val = coding_inherit_eol_type (val, Qnil); setup_coding_system (Fcheck_coding_system (val), &argument_coding); + coding_attrs = CODING_ID_ATTRS (argument_coding.id); + if (NILP (CODING_ATTR_ASCII_COMPAT (coding_attrs))) + { + /* We should not use an ASCII incompatible coding system. */ + val = raw_text_coding_system (val); + setup_coding_system (val, &argument_coding); + } } } @@ -355,11 +368,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) protected by the caller, so all we really have to worry about is buffer. */ { - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; current_dir = current_buffer->directory; - GCPRO3 (infile, buffer, current_dir); + GCPRO4 (infile, buffer, current_dir, error_file); current_dir = expand_and_dir_to_file (Funhandled_file_name_directory (current_dir), @@ -368,6 +381,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) report_file_error ("Setting current directory", Fcons (current_buffer->directory, Qnil)); + if (STRING_MULTIBYTE (infile)) + infile = ENCODE_FILE (infile); + if (STRING_MULTIBYTE (current_dir)) + current_dir = ENCODE_FILE (current_dir); + if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) + error_file = ENCODE_FILE (error_file); UNGCPRO; } @@ -376,6 +395,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) filefd = emacs_open (SDATA (infile), O_RDONLY, 0); if (filefd < 0) { + infile = DECODE_FILE (infile); report_file_error ("Opening process input file", Fcons (infile, Qnil)); } /* Search for program; barf if not found. */ @@ -410,12 +430,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { argument_coding.src_multibyte = STRING_MULTIBYTE (args[i]); if (CODING_REQUIRE_ENCODING (&argument_coding)) - { - /* We must encode this argument. */ - args[i] = encode_coding_string (args[i], &argument_coding, 1); - if (argument_coding.type == coding_type_ccl) - setup_ccl_program (&(argument_coding.spec.ccl.encoder), Qnil); - } + /* We must encode this argument. */ + args[i] = encode_coding_string (&argument_coding, args[i], 1); new_argv[i - 3] = SDATA (args[i]); } UNGCPRO; @@ -533,14 +549,13 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #ifdef MSDOS unlink (tempfile); #endif - report_file_error ("Cannot redirect stderr", - Fcons ((NILP (error_file) - ? build_string (NULL_DEVICE) : error_file), - Qnil)); + if (NILP (error_file)) + error_file = build_string (NULL_DEVICE); + else if (STRINGP (error_file)) + error_file = DECODE_FILE (error_file); + report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil)); } - current_dir = ENCODE_FILE (current_dir); - #ifdef MAC_OS8 { /* Call run_mac_command in sysdep.c here directly instead of doing @@ -728,19 +743,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) else val = Qnil; } - setup_coding_system (Fcheck_coding_system (val), &process_coding); + Fcheck_coding_system (val); /* In unibyte mode, character code conversion should not take place but EOL conversion should. So, setup raw-text or one of the subsidiary according to the information just setup. */ if (NILP (current_buffer->enable_multibyte_characters) && !NILP (val)) - setup_raw_text_coding_system (&process_coding); + val = raw_text_coding_system (val); + setup_coding_system (val, &process_coding); } - process_coding.src_multibyte = 0; - process_coding.dst_multibyte - = (BUFFERP (buffer) - ? ! NILP (XBUFFER (buffer)->enable_multibyte_characters) - : ! NILP (current_buffer->enable_multibyte_characters)); immediate_quit = 1; QUIT; @@ -752,12 +763,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) int carryover = 0; int display_on_the_fly = display_p; struct coding_system saved_coding; - int pt_orig = PT, pt_byte_orig = PT_BYTE; - int inserted; saved_coding = process_coding; - if (process_coding.composing != COMPOSITION_DISABLED) - coding_allocate_composition_data (&process_coding, PT); while (1) { /* Repeatedly read until we've filled as much as possible @@ -790,133 +797,49 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (!NILP (buffer)) { - if (! CODING_MAY_REQUIRE_DECODING (&process_coding)) + if (NILP (current_buffer->enable_multibyte_characters) + && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) insert_1_both (buf, nread, nread, 0, 1, 0); else { /* We have to decode the input. */ - int size; - char *decoding_buf; - - repeat_decoding: - size = decoding_buffer_size (&process_coding, nread); - decoding_buf = (char *) xmalloc (size); - - /* We can't use the macro CODING_REQUIRE_DETECTION - because it always returns nonzero if the coding - system requires EOL detection. Here, we have to - check only whether or not the coding system - requires text-encoding detection. */ - if (process_coding.type == coding_type_undecided) - { - detect_coding (&process_coding, buf, nread); - if (process_coding.composing != COMPOSITION_DISABLED) - /* We have not yet allocated the composition - data because the coding type was undecided. */ - coding_allocate_composition_data (&process_coding, PT); - } - if (process_coding.cmp_data) - process_coding.cmp_data->char_offset = PT; - - decode_coding (&process_coding, buf, decoding_buf, - nread, size); + Lisp_Object curbuf; + XSETBUFFER (curbuf, current_buffer); + decode_coding_c_string (&process_coding, buf, nread, + curbuf); if (display_on_the_fly - && saved_coding.type == coding_type_undecided - && process_coding.type != coding_type_undecided) + && CODING_REQUIRE_DETECTION (&saved_coding) + && ! CODING_REQUIRE_DETECTION (&process_coding)) { /* We have detected some coding system. But, there's a possibility that the detection was - done by insufficient data. So, we try the code - detection again with more data. */ - xfree (decoding_buf); + done by insufficient data. So, we give up + displaying on the fly. */ + if (process_coding.produced > 0) + del_range_2 (process_coding.dst_pos, + process_coding.dst_pos_byte, + process_coding.dst_pos + + process_coding.produced_char, + process_coding.dst_pos_byte + + process_coding.produced, 0); display_on_the_fly = 0; process_coding = saved_coding; carryover = nread; /* This is to make the above condition always fails in the future. */ - saved_coding.type = coding_type_no_conversion; + saved_coding.common_flags + &= ~CODING_REQUIRE_DETECTION_MASK; continue; } - if (process_coding.produced > 0) - insert_1_both (decoding_buf, process_coding.produced_char, - process_coding.produced, 0, 1, 0); - xfree (decoding_buf); - - if (process_coding.result == CODING_FINISH_INCONSISTENT_EOL) - { - Lisp_Object eol_type, coding; - - if (process_coding.eol_type == CODING_EOL_CR) - { - /* CRs have been replaced with LFs. Undo - that in the text inserted above. */ - unsigned char *p; - - move_gap_both (PT, PT_BYTE); - - p = BYTE_POS_ADDR (pt_byte_orig); - for (; p < GPT_ADDR; ++p) - if (*p == '\n') - *p = '\r'; - } - else if (process_coding.eol_type == CODING_EOL_CRLF) - { - /* CR LFs have been replaced with LFs. Undo - that by inserting CRs in front of LFs in - the text inserted above. */ - EMACS_INT bytepos, old_pt, old_pt_byte, nCR; - - old_pt = PT; - old_pt_byte = PT_BYTE; - nCR = 0; - - for (bytepos = PT_BYTE - 1; - bytepos >= pt_byte_orig; - --bytepos) - if (FETCH_BYTE (bytepos) == '\n') - { - EMACS_INT charpos = BYTE_TO_CHAR (bytepos); - TEMP_SET_PT_BOTH (charpos, bytepos); - insert_1_both ("\r", 1, 1, 0, 1, 0); - ++nCR; - } - - TEMP_SET_PT_BOTH (old_pt + nCR, old_pt_byte + nCR); - } - - /* Set the coding system symbol to that for - Unix-like EOL. */ - eol_type = Fget (saved_coding.symbol, Qeol_type); - if (VECTORP (eol_type) - && ASIZE (eol_type) == 3 - && SYMBOLP (AREF (eol_type, CODING_EOL_LF))) - coding = AREF (eol_type, CODING_EOL_LF); - else - coding = saved_coding.symbol; - - process_coding.symbol = coding; - process_coding.eol_type = CODING_EOL_LF; - process_coding.mode - &= ~CODING_MODE_INHIBIT_INCONSISTENT_EOL; - } - - nread -= process_coding.consumed; - carryover = nread; + TEMP_SET_PT_BOTH (PT + process_coding.produced_char, + PT_BYTE + process_coding.produced); + carryover = process_coding.carryover_bytes; if (carryover > 0) /* As CARRYOVER should not be that large, we had better avoid overhead of bcopy. */ - BCOPY_SHORT (buf + process_coding.consumed, buf, - carryover); - if (process_coding.result == CODING_FINISH_INSUFFICIENT_CMP) - { - /* The decoding ended because of insufficient data - area to record information about composition. - We must try decoding with additional data area - before reading more output for the process. */ - coding_allocate_composition_data (&process_coding, PT); - goto repeat_decoding; - } + BCOPY_SHORT (process_coding.carryover, buf, + process_coding.carryover_bytes); } } @@ -947,33 +870,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } give_up: ; - if (!NILP (buffer) - && process_coding.cmp_data) - { - coding_restore_composition (&process_coding, Fcurrent_buffer ()); - coding_free_composition_data (&process_coding); - } - - { - int post_read_count = SPECPDL_INDEX (); - - record_unwind_protect (save_excursion_restore, save_excursion_save ()); - inserted = PT - pt_orig; - TEMP_SET_PT_BOTH (pt_orig, pt_byte_orig); - if (SYMBOLP (process_coding.post_read_conversion) - && !NILP (Ffboundp (process_coding.post_read_conversion))) - call1 (process_coding.post_read_conversion, make_number (inserted)); - - Vlast_coding_system_used = process_coding.symbol; - - /* If the caller required, let the buffer inherit the - coding-system used to decode the process output. */ - if (inherit_process_coding_system) - call1 (intern ("after-insert-file-set-buffer-file-coding-system"), - make_number (total_read)); - - unbind_to (post_read_count, Qnil); - } + Vlast_coding_system_used = CODING_ID_NAME (process_coding.id); + /* If the caller required, let the buffer inherit the + coding-system used to decode the process output. */ + if (inherit_process_coding_system) + call1 (intern ("after-insert-file-set-buffer-file-coding-system"), + make_number (total_read)); } /* Wait for it to terminate, unless it already has. */ @@ -1013,9 +915,11 @@ static Lisp_Object delete_temp_file (name) Lisp_Object name; { - /* Use Fdelete_file (indirectly) because that runs a file name handler. - We did that when writing the file, so we should do so when deleting. */ + /* Suppress jka-compr handling, etc. */ + int count = SPECPDL_INDEX (); + specbind (intern ("file-name-handler-alist"), Qnil); internal_delete_file (name); + unbind_to (count, Qnil); return Qnil; }