(wordify): Do the second loop by chars, not by bytes.
[bpt/emacs.git] / src / print.c
index 9484b92..49a0610 100644 (file)
@@ -1,5 +1,6 @@
 /* Lisp object printing and output streams.
-   Copyright (C) 1985, 86, 88, 93, 94, 95, 97, 98 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86, 88, 93, 94, 95, 97, 1998
+       Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -257,9 +258,9 @@ glyph_to_str_cpy (glyphs, str)
        Lisp_Object string;                                     \
        if (print_buffer != 0)                                  \
         {                                                      \
-          string = make_multibyte_string (print_buffer,        \
-                                          print_buffer_pos,    \
-                                          print_buffer_pos_byte); \
+          string = make_string_from_bytes (print_buffer,       \
+                                           print_buffer_pos,   \
+                                           print_buffer_pos_byte); \
           record_unwind_protect (print_unwind, string);        \
         }                                                      \
        else                                                    \
@@ -397,11 +398,15 @@ printchar (ch, fun)
                     0, 1);
          printbufidx = size;
          if (printbufidx > FRAME_MESSAGE_BUF_SIZE (mini_frame))
-           printbufidx = FRAME_MESSAGE_BUF_SIZE (mini_frame);
+           {
+             printbufidx = FRAME_MESSAGE_BUF_SIZE (mini_frame);
+             /* Rewind incomplete multi-byte form.  */
+             while (printbufidx > 0 && tembuf[printbufidx] >= 0xA0)
+               printbufidx--;
+           }
          bcopy (tembuf, FRAME_MESSAGE_BUF (mini_frame), printbufidx);
+         message_enable_multibyte = 1;
        }
-      message_enable_multibyte
-       = ! NILP (current_buffer->enable_multibyte_characters);
 
       if (printbufidx < FRAME_MESSAGE_BUF_SIZE (mini_frame) - len)
        bcopy (str, &FRAME_MESSAGE_BUF (mini_frame)[printbufidx], len),
@@ -488,16 +493,44 @@ strout (ptr, size, size_byte, printcharfun, multibyte)
        }
 
       message_dolog (ptr, size_byte, 0, multibyte);
+
+      /* Convert message to multibyte if we are now adding multibyte text.  */
+      if (multibyte
+         && ! message_enable_multibyte
+         && printbufidx > 0)
+       {
+         int size = count_size_as_multibyte (FRAME_MESSAGE_BUF (mini_frame),
+                                             printbufidx);
+         unsigned char *tembuf = (unsigned char *) alloca (size + 1);
+         copy_text (FRAME_MESSAGE_BUF (mini_frame), tembuf, printbufidx,
+                    0, 1);
+         printbufidx = size;
+         if (printbufidx > FRAME_MESSAGE_BUF_SIZE (mini_frame))
+           {
+             printbufidx = FRAME_MESSAGE_BUF_SIZE (mini_frame);
+             /* Rewind incomplete multi-byte form.  */
+             while (printbufidx > 0 && tembuf[printbufidx] >= 0xA0)
+               printbufidx--;
+           }
+
+         bcopy (tembuf, FRAME_MESSAGE_BUF (mini_frame), printbufidx);
+         message_enable_multibyte = 1;
+       }
+
+      /* Compute how much of the new text will fit there.  */
       if (size_byte > FRAME_MESSAGE_BUF_SIZE (mini_frame) - printbufidx - 1)
        {
          size_byte = FRAME_MESSAGE_BUF_SIZE (mini_frame) - printbufidx - 1;
          /* Rewind incomplete multi-byte form.  */
-         while (size_byte && (unsigned char) ptr[size] >= 0xA0) size--;
+         while (size_byte && (unsigned char) ptr[size_byte] >= 0xA0)
+           size_byte--;
        }
+
+      /* Put that part of the new text in.  */
       bcopy (ptr, &FRAME_MESSAGE_BUF (mini_frame) [printbufidx], size_byte);
       printbufidx += size_byte;
-      echo_area_glyphs_length = printbufidx;
       FRAME_MESSAGE_BUF (mini_frame) [printbufidx] = 0;
+      echo_area_glyphs_length = printbufidx;
 
       return;
     }
@@ -536,7 +569,7 @@ print_string (string, printcharfun)
     /* strout is safe for output to a frame (echo area) or to print_buffer.  */
     strout (XSTRING (string)->data,
            XSTRING (string)->size,
-           XSTRING (string)->size_byte,
+           STRING_BYTES (XSTRING (string)),
            printcharfun, STRING_MULTIBYTE (string));
   else
     {
@@ -544,7 +577,7 @@ print_string (string, printcharfun)
         So re-fetch the string address for each character.  */
       int i;
       int size = XSTRING (string)->size;
-      int size_byte = XSTRING (string)->size_byte;
+      int size_byte = STRING_BYTES (XSTRING (string));
       struct gcpro gcpro1;
       GCPRO1 (string);
       if (size == size_byte)
@@ -633,6 +666,12 @@ temp_output_buffer_setup (bufname)
 
   current_buffer->directory = old->directory;
   current_buffer->read_only = Qnil;
+  current_buffer->filename = Qnil;
+  current_buffer->undo_list = Qt;
+  current_buffer->overlays_before = Qnil;
+  current_buffer->overlays_after = Qnil;
+  current_buffer->enable_multibyte_characters
+    = buffer_defaults.enable_multibyte_characters;
   Ferase_buffer ();
 
   XSETBUFFER (buf, current_buffer);
@@ -644,7 +683,7 @@ temp_output_buffer_setup (bufname)
 Lisp_Object
 internal_with_output_to_temp_buffer (bufname, function, args)
      char *bufname;
-     Lisp_Object (*function) ();
+     Lisp_Object (*function) P_ ((Lisp_Object));
      Lisp_Object args;
 {
   int count = specpdl_ptr - specpdl;
@@ -1150,6 +1189,9 @@ print (obj, printcharfun, escapeflag)
          register unsigned char c;
          struct gcpro gcpro1;
          int size_byte;
+         /* 1 means we must ensure that the next character we output
+            cannot be taken as part of a hex character escape.  */
+         int need_nonhex = 0;
 
          GCPRO1 (obj);
 
@@ -1162,7 +1204,7 @@ print (obj, printcharfun, escapeflag)
 #endif
 
          PRINTCHAR ('\"');
-         size_byte = XSTRING (obj)->size_byte;
+         size_byte = STRING_BYTES (XSTRING (obj));
 
          for (i = 0, i_byte = 0; i_byte < size_byte;)
            {
@@ -1196,6 +1238,7 @@ print (obj, printcharfun, escapeflag)
                  unsigned char outbuf[50];
                  sprintf (outbuf, "\\x%x", c);
                  strout (outbuf, -1, -1, printcharfun, 0);
+                 need_nonhex = 1;
                }
              else if (SINGLE_BYTE_CHAR_P (c)
                       && ! ASCII_BYTE_P (c)
@@ -1210,6 +1253,18 @@ print (obj, printcharfun, escapeflag)
                }
              else
                {
+                 /* If we just had a hex escape, and this character
+                    could be taken as part of it,
+                    output `\ ' to prevent that.  */
+                 if (need_nonhex)
+                   {
+                     need_nonhex = 0;
+                     if ((c >= 'a' && c <= 'f')
+                         || (c >= 'A' && c <= 'F')
+                         || (c >= '0' && c <= '9'))
+                       strout ("\\ ", -1, -1, printcharfun, 0);
+                   }
+
                  if (c == '\"' || c == '\\')
                    PRINTCHAR ('\\');
                  PRINTCHAR (c);
@@ -1234,7 +1289,7 @@ print (obj, printcharfun, escapeflag)
       {
        register int confusing;
        register unsigned char *p = XSYMBOL (obj)->name->data;
-       register unsigned char *end = p + XSYMBOL (obj)->name->size_byte;
+       register unsigned char *end = p + STRING_BYTES (XSYMBOL (obj)->name);
        register int c;
        int i, i_byte, size_byte;
        Lisp_Object name;
@@ -1296,7 +1351,7 @@ print (obj, printcharfun, escapeflag)
            PRINTCHAR (':');
          }
 
-       size_byte = XSTRING (name)->size_byte;
+       size_byte = STRING_BYTES (XSTRING (name));
 
        for (i = 0, i_byte = 0; i_byte < size_byte;)
          {
@@ -1356,10 +1411,10 @@ print (obj, printcharfun, escapeflag)
          PRINTCHAR ('(');
          {
            register int i = 0;
-           register int max = 0;
+           register int print_length = 0;
 
            if (INTEGERP (Vprint_length))
-             max = XINT (Vprint_length);
+             print_length = XINT (Vprint_length);
            /* Could recognize circularities in cdrs here,
               but that would make printing of long lists quadratic.
               It's not worth doing.  */
@@ -1367,7 +1422,7 @@ print (obj, printcharfun, escapeflag)
              {
                if (i++)
                  PRINTCHAR (' ');
-               if (max && i > max)
+               if (print_length && i > print_length)
                  {
                    strout ("...", 3, 3, printcharfun, 0);
                    break;