X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/ea4496e6c5677a14100f3dc021cbd2d451d36839..e7fbaa6567934bb483d3bf383fbef30528013957:/src/process.c diff --git a/src/process.c b/src/process.c index d05071824d..59bb8e3757 100644 --- a/src/process.c +++ b/src/process.c @@ -1,5 +1,5 @@ /* Asynchronous subprocess control for GNU Emacs. - Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1996 + Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 1998 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -1089,12 +1089,12 @@ Remaining arguments are strings to give program as arguments.") #ifdef VMS /* Make a one member argv with all args concatenated together separated by a blank. */ - len = XSTRING (program)->size + 2; + len = XSTRING (program)->size_byte + 2; for (i = 3; i < nargs; i++) { tem = args[i]; CHECK_STRING (tem, i); - len += XSTRING (tem)->size + 1; /* count the blank */ + len += XSTRING (tem)->size_byte + 1; /* count the blank */ } new_argv = (unsigned char *) alloca (len); strcpy (new_argv, XSTRING (program)->data); @@ -1159,8 +1159,9 @@ Remaining arguments are strings to give program as arguments.") /* Make the process marker point into the process buffer (if any). */ if (!NILP (buffer)) - Fset_marker (XPROCESS (proc)->mark, - make_number (BUF_ZV (XBUFFER (buffer))), buffer); + set_marker_both (XPROCESS (proc)->mark, buffer, + BUF_ZV (XBUFFER (buffer)), + BUF_ZV_BYTE (XBUFFER (buffer))); if (!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters) || NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)) @@ -1179,7 +1180,7 @@ Remaining arguments are strings to give program as arguments.") if (!NILP (Vcoding_system_for_read)) val = Vcoding_system_for_read; else if (NILP (current_buffer->enable_multibyte_characters)) - val = Qemacs_mule; + val = Qraw_text; else { args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); @@ -1224,7 +1225,9 @@ Remaining arguments are strings to give program as arguments.") } XPROCESS (proc)->decoding_buf = make_uninit_string (0); + XPROCESS (proc)->decoding_carryover = make_number (0); XPROCESS (proc)->encoding_buf = make_uninit_string (0); + XPROCESS (proc)->encoding_carryover = make_number (0); create_process (proc, (char **) new_argv, current_dir); @@ -1410,23 +1413,22 @@ create_process (process, new_argv, current_dir) int i = 1; struct coding_system *coding = proc_encode_coding_system[outchannel]; - coding->last_block = 1; + coding->mode |= CODING_MODE_LAST_BLOCK; GCPRO1 (process); while (new_argv[i] != 0) { int len = strlen (new_argv[i]); int size = encoding_buffer_size (coding, len); unsigned char *buf = (unsigned char *) alloca (size); - int produced, dmy; - produced = encode_coding (coding, new_argv[i], buf, len, size, &dmy); - buf[produced] = 0; + encode_coding (coding, new_argv[i], buf, len, size); + buf[coding->produced] = 0; /* We don't have to free new_argv[i] because it points to a Lisp string given as an argument to `start-process'. */ new_argv[i++] = buf; } UNGCPRO; - coding->last_block = 0; + coding->mode &= ~CODING_MODE_LAST_BLOCK; } /* Delay interrupts until we have a chance to store @@ -1958,7 +1960,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ val = Vcoding_system_for_read; else if (NILP (current_buffer->enable_multibyte_characters)) /* We dare not decode end-of-line format by setting VAL to - Qemacs_mule, because the existing Emacs Lisp libraries + Qraw_text, because the existing Emacs Lisp libraries assume that they receive bare code including a sequene of CR LF. */ val = Qnil; @@ -2014,7 +2016,9 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ proc_encode_coding_system[outch]); XPROCESS (proc)->decoding_buf = make_uninit_string (0); + XPROCESS (proc)->decoding_carryover = make_number (0); XPROCESS (proc)->encoding_buf = make_uninit_string (0); + XPROCESS (proc)->encoding_carryover = make_number (0); UNGCPRO; return proc; @@ -2709,7 +2713,7 @@ read_process_output (proc, channel) Lisp_Object proc; register int channel; { - register int nchars; + register int nchars, nbytes; char *chars; #ifdef VMS int chars_allocated = 0; /* If 1, `chars' should be freed later. */ @@ -2723,6 +2727,7 @@ read_process_output (proc, channel) struct coding_system *coding = proc_decode_coding_system[channel]; int chars_in_decoding_buf = 0; /* If 1, `chars' points XSTRING (p->decoding_buf)->data. */ + int carryover = XINT (p->decoding_carryover); #ifdef VMS VMS_PROC_STUFF *vs, *get_vms_process_pointer(); @@ -2738,67 +2743,70 @@ read_process_output (proc, channel) else error ("Could not get VMS process pointer"); chars = vs->inputBuffer; - nchars = clean_vms_buffer (chars, vs->iosb[1]); - if (nchars <= 0) + nbytes = clean_vms_buffer (chars, vs->iosb[1]); + if (nbytes <= 0) { start_vms_process_read (vs); /* Crank up the next read on the process */ return 1; /* Nothing worth printing, say we got 1 */ } - if (coding->carryover_size) + if (carryover > 0) { - /* The data carried over in the previous decoding should be - prepended to the new data read to decode all together. */ - char *buf = (char *) xmalloc (nchars + coding->carryover_size); - - bcopy (coding->carryover, buf, coding->carryover_size); - bcopy (chars, buf + coding->carryover_size, nchars); + /* The data carried over in the previous decoding (which are at + the tail of decoding buffer) should be prepended to the new + data read to decode all together. */ + char *buf = (char *) xmalloc (nbytes + carryover); + + bcopy (XSTRING (p->decoding_buf)->data + + XSTRING (p->decoding_buf)->size_byte - carryover, + buf, carryover); + bcopy (chars, buf + carryover, nbytes); chars = buf; chars_allocated = 1; } #else /* not VMS */ - if (coding->carryover_size) - /* The data carried over in the previous decoding should be - prepended to the new data read to decode all together. */ - bcopy (coding->carryover, buf, coding->carryover_size); + if (carryover) + /* See the comment above. */ + bcopy (XSTRING (p->decoding_buf)->data + + XSTRING (p->decoding_buf)->size_byte - carryover, + buf, carryover); if (proc_buffered_char[channel] < 0) - nchars = read (channel, buf + coding->carryover_size, - (sizeof buf) - coding->carryover_size); + nbytes = read (channel, buf + carryover, (sizeof buf) - carryover); else { - buf[coding->carryover_size] = proc_buffered_char[channel]; + buf[carryover] = proc_buffered_char[channel]; proc_buffered_char[channel] = -1; - nchars = read (channel, buf + coding->carryover_size + 1, - (sizeof buf) - coding->carryover_size - 1); - if (nchars < 0) - nchars = 1; + nbytes = read (channel, buf + carryover + 1, + (sizeof buf) - carryover - 1); + if (nbytes < 0) + nbytes = 1; else - nchars = nchars + 1; + nbytes = nbytes + 1; } chars = buf; #endif /* not VMS */ - /* At this point, NCHARS holds number of characters just received + /* At this point, NBYTES holds number of characters just received (including the one in proc_buffered_char[channel]). */ - if (nchars <= 0) return nchars; + if (nbytes <= 0) return nbytes; - /* Now set NCHARS how many bytes we must decode. */ - nchars += coding->carryover_size; + /* Now set NBYTES how many bytes we must decode. */ + nbytes += carryover; + nchars = nbytes; - if (CODING_REQUIRE_DECODING (coding) - || CODING_REQUIRE_DETECTION (coding)) + if (CODING_MAY_REQUIRE_DECODING (coding)) { - int require = decoding_buffer_size (coding, nchars); - int consumed, produced; + int require = decoding_buffer_size (coding, nbytes); + int result; - if (XSTRING (p->decoding_buf)->size < require) + if (XSTRING (p->decoding_buf)->size_byte < require) p->decoding_buf = make_uninit_string (require); - produced = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data, - nchars, XSTRING (p->decoding_buf)->size, - &consumed); + result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data, + nbytes, XSTRING (p->decoding_buf)->size_byte); + carryover = nbytes - coding->consumed; - /* New coding-system might be found by `decode_coding'. */ + /* A new coding system might be found by `decode_coding'. */ if (!EQ (p->decode_coding_system, coding->symbol)) { p->decode_coding_system = coding->symbol; @@ -2807,28 +2815,32 @@ read_process_output (proc, channel) proc_decode_coding_system[channel] here. It is done in detect_coding called via decode_coding above. */ - /* If coding-system for encoding is not yet decided, we set it - as the same as coding-system for decoding. */ - if (NILP (p->encode_coding_system)) + /* If a coding system for encoding is not yet decided, we set + it as the same as coding-system for decoding. + + But, before doing that we must check if + proc_encode_coding_system[p->outfd] surely points to a + valid memory because p->outfd will be changed once EOF is + sent to the process. */ + if (NILP (p->encode_coding_system) + && proc_encode_coding_system[p->outfd]) { p->encode_coding_system = coding->symbol; - if (!proc_encode_coding_system[p->outfd]) - proc_encode_coding_system[p->outfd] - = ((struct coding_system *) - xmalloc (sizeof (struct coding_system))); setup_coding_system (coding->symbol, proc_encode_coding_system[p->outfd]); } } + #ifdef VMS /* Now we don't need the contents of `chars'. */ if (chars_allocated) free (chars); #endif - if (produced == 0) + if (coding->produced == 0) return 0; chars = (char *) XSTRING (p->decoding_buf)->data; - nchars = produced; + nbytes = coding->produced; + nchars = coding->produced_char; chars_in_decoding_buf = 1; } #ifdef VMS @@ -2837,15 +2849,20 @@ read_process_output (proc, channel) /* Although we don't have to decode the received data, we must move it to an area which we don't have to free. */ if (! STRINGP (p->decoding_buf) - || XSTRING (p->decoding_buf)->size < nchars) - p->decoding_buf = make_uninit_string (nchars); - bcopy (chars, XSTRING (p->decoding_buf)->data, nchars); + || XSTRING (p->decoding_buf)->size < nbytes) + p->decoding_buf = make_uninit_string (nbytes); + bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes); free (chars); chars = XSTRING (p->decoding_buf)->data; chars_in_decoding_buf = 1; + carryover = 0; } #endif + XSETINT (p->decoding_carryover, carryover); + Vlast_coding_system_used = coding->symbol; + + /* Read and dispose of the process output. */ outstream = p->filter; if (!NILP (outstream)) { @@ -2855,6 +2872,7 @@ read_process_output (proc, channel) int count = specpdl_ptr - specpdl; Lisp_Object odeactivate; Lisp_Object obuffer, okeymap; + Lisp_Object text; int outer_running_asynch_code = running_asynch_code; /* No need to gcpro these, because all we do with them later @@ -2883,13 +2901,10 @@ read_process_output (proc, channel) save the match data in a special nonrecursive fashion. */ running_asynch_code = 1; - /* Read and dispose of the process output. */ + text = make_multibyte_string (chars, nchars, nbytes); internal_condition_case_1 (read_process_output_call, Fcons (outstream, - Fcons (proc, - Fcons (make_string (chars, - nchars), - Qnil))), + Fcons (proc, Fcons (text, Qnil))), !NILP (Vdebug_on_error) ? Qnil : Qerror, read_process_output_error_handler); @@ -2924,16 +2939,21 @@ read_process_output (proc, channel) { Lisp_Object old_read_only; int old_begv, old_zv; + int old_begv_byte, old_zv_byte; Lisp_Object odeactivate; - int before; + int before, before_byte; + int opoint_byte; odeactivate = Vdeactivate_mark; Fset_buffer (p->buffer); opoint = PT; + opoint_byte = PT_BYTE; old_read_only = current_buffer->read_only; old_begv = BEGV; old_zv = ZV; + old_begv_byte = BEGV_BYTE; + old_zv_byte = ZV_BYTE; current_buffer->read_only = Qnil; @@ -2941,10 +2961,13 @@ read_process_output (proc, channel) at the current end-of-output marker, thus preserving logical ordering of input and output. */ if (XMARKER (p->mark)->buffer) - SET_PT (clip_to_bounds (BEGV, marker_position (p->mark), ZV)); + SET_PT_BOTH (clip_to_bounds (BEGV, marker_position (p->mark), ZV), + clip_to_bounds (BEGV_BYTE, marker_byte_position (p->mark), + ZV_BYTE)); else - SET_PT (ZV); + SET_PT_BOTH (ZV, ZV_BYTE); before = PT; + before_byte = PT_BYTE; /* If the output marker is outside of the visible region, save the restriction and widen. */ @@ -2954,21 +2977,31 @@ read_process_output (proc, channel) /* Insert before markers in case we are inserting where the buffer's mark is, and the user's next command is Meta-y. */ if (chars_in_decoding_buf) - insert_from_string_before_markers (p->decoding_buf, 0, nchars, 0); + insert_from_string_before_markers (p->decoding_buf, 0, 0, + nchars, nbytes, 0); else - insert_before_markers (chars, nchars); - Fset_marker (p->mark, make_number (PT), p->buffer); + insert_1_both (chars, nchars, nbytes, 0, 1, 1); + set_marker_both (p->mark, p->buffer, PT, PT_BYTE); update_mode_lines++; /* Make sure opoint and the old restrictions float ahead of any new text just as point would. */ if (opoint >= before) - opoint += PT - before; + { + opoint += PT - before; + opoint_byte += PT_BYTE - before_byte; + } if (old_begv > before) - old_begv += PT - before; + { + old_begv += PT - before; + old_begv_byte += PT_BYTE - before_byte; + } if (old_zv >= before) - old_zv += PT - before; + { + old_zv += PT - before; + old_zv_byte += PT_BYTE - before_byte; + } /* If the restriction isn't what it should be, set it. */ if (old_begv != BEGV || old_zv != ZV) @@ -2978,13 +3011,13 @@ read_process_output (proc, channel) Vdeactivate_mark = odeactivate; current_buffer->read_only = old_read_only; - SET_PT (opoint); + SET_PT_BOTH (opoint, opoint_byte); set_buffer_internal (old); } #ifdef VMS start_vms_process_read (vs); #endif - return nchars; + return nbytes; } DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p, @@ -3031,6 +3064,7 @@ send_process (proc, buf, len, object) volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data; struct coding_system *coding; struct gcpro gcpro1; + int carryover = XINT (XPROCESS (proc)->encoding_carryover); GCPRO1 (object); @@ -3047,6 +3081,8 @@ send_process (proc, buf, len, object) error ("Output file descriptor of %s is closed", procname); coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; + Vlast_coding_system_used = coding->symbol; + if (CODING_REQUIRE_ENCODING (coding)) { int require = encoding_buffer_size (coding, len); @@ -3057,44 +3093,49 @@ send_process (proc, buf, len, object) be relocated. Setting OFFSET to -1 means we don't have to care relocation. */ offset = (BUFFERP (object) - ? BUF_PTR_CHAR_POS (XBUFFER (object), buf) + ? BUF_PTR_BYTE_POS (XBUFFER (object), buf) : (STRINGP (object) ? offset = buf - XSTRING (object)->data : -1)); - if (coding->carryover_size > 0) + if (carryover > 0) { - temp_buf = (unsigned char *) xmalloc (len + coding->carryover_size); + temp_buf = (unsigned char *) xmalloc (len + carryover); if (offset >= 0) { if (BUFFERP (object)) - buf = BUF_CHAR_ADDRESS (XBUFFER (object), offset); + buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); else if (STRINGP (object)) buf = offset + XSTRING (object)->data; /* Now we don't have to care relocation. */ offset = -1; } - bcopy (coding->carryover, temp_buf, coding->carryover_size); - bcopy (buf, temp_buf + coding->carryover_size, len); + bcopy ((XSTRING (XPROCESS (proc)->encoding_buf)->data + + XSTRING (XPROCESS (proc)->encoding_buf)->size_byte + - carryover), + temp_buf, + carryover); + bcopy (buf, temp_buf + carryover, len); buf = temp_buf; } - if (XSTRING (XPROCESS (proc)->encoding_buf)->size < require) + if (XSTRING (XPROCESS (proc)->encoding_buf)->size_byte < require) { XPROCESS (proc)->encoding_buf = make_uninit_string (require); if (offset >= 0) { if (BUFFERP (object)) - buf = BUF_CHAR_ADDRESS (XBUFFER (object), offset); + buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); else if (STRINGP (object)) buf = offset + XSTRING (object)->data; } } object = XPROCESS (proc)->encoding_buf; - len = encode_coding (coding, buf, XSTRING (object)->data, - len, XSTRING (object)->size, &dummy); + encode_coding (coding, buf, XSTRING (object)->data, + len, XSTRING (object)->size_byte); + len = coding->produced; buf = XSTRING (object)->data; if (temp_buf) xfree (temp_buf); @@ -3184,7 +3225,7 @@ send_process (proc, buf, len, object) /* Running filters might relocate buffers or strings. Arrange to relocate BUF. */ if (BUFFERP (object)) - offset = BUF_PTR_CHAR_POS (XBUFFER (object), buf); + offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf); else if (STRINGP (object)) offset = buf - XSTRING (object)->data; @@ -3196,7 +3237,7 @@ send_process (proc, buf, len, object) #endif if (BUFFERP (object)) - buf = BUF_CHAR_ADDRESS (XBUFFER (object), offset); + buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); else if (STRINGP (object)) buf = offset + XSTRING (object)->data; @@ -3247,7 +3288,7 @@ Output from processes can arrive in between bunches.") Lisp_Object process, start, end; { Lisp_Object proc; - int start1; + int start1, end1; proc = get_process (process); validate_region (&start, &end); @@ -3255,8 +3296,9 @@ Output from processes can arrive in between bunches.") if (XINT (start) < GPT && XINT (end) > GPT) move_gap (XINT (start)); - start1 = XINT (start); - send_process (proc, POS_ADDR (start1), XINT (end) - XINT (start), + start1 = CHAR_TO_BYTE (XINT (start)); + end1 = CHAR_TO_BYTE (XINT (end)); + send_process (proc, BYTE_POS_ADDR (start1), end1 - start1, Fcurrent_buffer ()); return Qnil; @@ -3276,7 +3318,8 @@ Output from processes can arrive in between bunches.") Lisp_Object proc; CHECK_STRING (string, 1); proc = get_process (process); - send_process (proc, XSTRING (string)->data, XSTRING (string)->size, string); + send_process (proc, XSTRING (string)->data, + XSTRING (string)->size_byte, string); return Qnil; } @@ -4093,8 +4136,8 @@ status_notify () { Lisp_Object ro, tem; struct buffer *old = current_buffer; - int opoint; - int before; + int opoint, opoint_byte; + int before, before_byte; ro = XBUFFER (buffer)->read_only; @@ -4105,15 +4148,17 @@ status_notify () Fset_buffer (buffer); opoint = PT; + opoint_byte = PT_BYTE; /* Insert new output into buffer at the current end-of-output marker, thus preserving logical ordering of input and output. */ if (XMARKER (p->mark)->buffer) - SET_PT (marker_position (p->mark)); + Fgoto_char (p->mark); else - SET_PT (ZV); + SET_PT_BOTH (ZV, ZV_BYTE); before = PT; + before_byte = PT_BYTE; tem = current_buffer->read_only; current_buffer->read_only = Qnil; @@ -4122,12 +4167,13 @@ status_notify () insert_string (" "); Finsert (1, &msg); current_buffer->read_only = tem; - Fset_marker (p->mark, make_number (PT), p->buffer); + set_marker_both (p->mark, p->buffer, PT, PT_BYTE); if (opoint >= before) - SET_PT (opoint + (PT - before)); + SET_PT_BOTH (opoint + (PT - before), + opoint_byte + (PT_BYTE - before_byte)); else - SET_PT (opoint); + SET_PT_BOTH (opoint, opoint_byte); set_buffer_internal (old); }