(Fstart_process): Use raw-text instead of emacs-mule
[bpt/emacs.git] / src / process.c
index d050718..59bb8e3 100644 (file)
@@ -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;
 }
 \f
@@ -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);
            }