]> code.delx.au - gnu-emacs/blobdiff - src/print.c
Add a note how to use `tramp-own-remote-path'
[gnu-emacs] / src / print.c
index 916276bc961426b454a932c729845e81870e956c..5531210e1b8e6faad5704f0ae30ae722eb16df3f 100644 (file)
@@ -1,14 +1,14 @@
 /* Lisp object printing and output streams.
 
-Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2015 Free Software
+Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2016 Free Software
 Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,22 +24,26 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "lisp.h"
 #include "character.h"
+#include "coding.h"
 #include "buffer.h"
 #include "charset.h"
-#include "keyboard.h"
 #include "frame.h"
-#include "window.h"
 #include "process.h"
-#include "dispextern.h"
-#include "termchar.h"
+#include "disptab.h"
 #include "intervals.h"
 #include "blockinput.h"
-#include "termhooks.h"         /* For struct terminal.  */
-#include "font.h"
+#include "xwidget.h"
 
+#include <c-ctype.h>
 #include <float.h>
 #include <ftoastr.h>
 
+#ifdef WINDOWSNT
+# include <sys/socket.h> /* for F_DUPFD_CLOEXEC */
+#endif
+
+struct terminal;
+
 /* Avoid actual stack overflow in print.  */
 static ptrdiff_t print_depth;
 
@@ -194,6 +198,71 @@ print_unwind (Lisp_Object saved_text)
   memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text));
 }
 
+/* Print character CH to the stdio stream STREAM.  */
+
+static void
+printchar_to_stream (unsigned int ch, FILE *stream)
+{
+  Lisp_Object dv UNINIT;
+  ptrdiff_t i = 0, n = 1;
+  Lisp_Object coding_system = Vlocale_coding_system;
+  bool encode_p = false;
+
+  if (!NILP (Vcoding_system_for_write))
+    coding_system = Vcoding_system_for_write;
+  if (!NILP (coding_system))
+    encode_p = true;
+
+  if (CHAR_VALID_P (ch) && DISP_TABLE_P (Vstandard_display_table))
+    {
+      dv = DISP_CHAR_VECTOR (XCHAR_TABLE (Vstandard_display_table), ch);
+      if (VECTORP (dv))
+       {
+         n = ASIZE (dv);
+         goto next_char;
+       }
+    }
+
+  while (true)
+    {
+      if (ASCII_CHAR_P (ch))
+       {
+         putc (ch, stream);
+#ifdef WINDOWSNT
+         /* Send the output to a debugger (nothing happens if there
+            isn't one).  */
+         if (print_output_debug_flag && stream == stderr)
+           OutputDebugString ((char []) {ch, '\0'});
+#endif
+       }
+      else
+       {
+         unsigned char mbstr[MAX_MULTIBYTE_LENGTH];
+         int len = CHAR_STRING (ch, mbstr);
+         Lisp_Object encoded_ch =
+           make_multibyte_string ((char *) mbstr, 1, len);
+
+         if (encode_p)
+           encoded_ch = code_convert_string_norecord (encoded_ch,
+                                                      coding_system, true);
+         fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream);
+#ifdef WINDOWSNT
+         if (print_output_debug_flag && stream == stderr)
+           OutputDebugString (SSDATA (encoded_ch));
+#endif
+       }
+
+      i++;
+
+    next_char:
+      for (; i < n; i++)
+       if (CHARACTERP (AREF (dv, i)))
+         break;
+      if (! (i < n))
+       break;
+      ch = XFASTINT (AREF (dv, i));
+    }
+}
 
 /* Print character CH using method FUN.  FUN nil means print to
    print_buffer.  FUN t means print to echo area or stdout if
@@ -225,7 +294,10 @@ printchar (unsigned int ch, Lisp_Object fun)
       else if (noninteractive)
        {
          printchar_stdout_last = ch;
-         fwrite (str, 1, len, stdout);
+         if (DISP_TABLE_P (Vstandard_display_table))
+           printchar_to_stream (ch, stdout);
+         else
+           fwrite (str, 1, len, stdout);
          noninteractive_need_newline = 1;
        }
       else
@@ -266,7 +338,19 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
     }
   else if (noninteractive && EQ (printcharfun, Qt))
     {
-      fwrite (ptr, 1, size_byte, stdout);
+      if (DISP_TABLE_P (Vstandard_display_table))
+       {
+         int len;
+         for (ptrdiff_t i = 0; i < size_byte; i += len)
+           {
+             int ch = STRING_CHAR_AND_LENGTH ((const unsigned char *) ptr + i,
+                                              len);
+             printchar_to_stream (ch, stdout);
+           }
+       }
+      else
+       fwrite (ptr, 1, size_byte, stdout);
+
       noninteractive_need_newline = 1;
     }
   else if (EQ (printcharfun, Qt))
@@ -393,8 +477,6 @@ print_string (Lisp_Object string, Lisp_Object printcharfun)
       ptrdiff_t i;
       ptrdiff_t size = SCHARS (string);
       ptrdiff_t size_byte = SBYTES (string);
-      struct gcpro gcpro1;
-      GCPRO1 (string);
       if (size == size_byte)
        for (i = 0; i < size; i++)
          printchar (SREF (string, i), printcharfun);
@@ -408,7 +490,6 @@ print_string (Lisp_Object string, Lisp_Object printcharfun)
            printchar (ch, printcharfun);
            i += len;
          }
-      UNGCPRO;
     }
 }
 \f
@@ -667,17 +748,13 @@ If PRINTCHARFUN is omitted, the value of `standard-output' (which see)
 is used instead.  */)
   (Lisp_Object object, Lisp_Object printcharfun)
 {
-  struct gcpro gcpro1;
-
   if (NILP (printcharfun))
     printcharfun = Vstandard_output;
-  GCPRO1 (object);
   PRINTPREPARE;
   printchar ('\n', printcharfun);
   print (object, printcharfun, 1);
   printchar ('\n', printcharfun);
   PRINTFINISH;
-  UNGCPRO;
   return object;
 }
 
@@ -687,37 +764,8 @@ You can call print while debugging emacs, and pass it this function
 to make it write to the debugging output.  */)
   (Lisp_Object character)
 {
-  unsigned int ch;
-
   CHECK_NUMBER (character);
-  ch = XINT (character);
-  if (ASCII_CHAR_P (ch))
-    {
-      putc (ch, stderr);
-#ifdef WINDOWSNT
-      /* Send the output to a debugger (nothing happens if there isn't
-        one).  */
-      if (print_output_debug_flag)
-       {
-         char buf[2] = {(char) XINT (character), '\0'};
-         OutputDebugString (buf);
-       }
-#endif
-    }
-  else
-    {
-      unsigned char mbstr[MAX_MULTIBYTE_LENGTH];
-      ptrdiff_t len = CHAR_STRING (ch, mbstr);
-      Lisp_Object encoded_ch =
-       ENCODE_SYSTEM (make_multibyte_string ((char *) mbstr, 1, len));
-
-      fwrite (SSDATA (encoded_ch), SBYTES (encoded_ch), 1, stderr);
-#ifdef WINDOWSNT
-      if (print_output_debug_flag)
-       OutputDebugString (SSDATA (encoded_ch));
-#endif
-    }
-
+  printchar_to_stream (XINT (character), stderr);
   return character;
 }
 
@@ -731,15 +779,6 @@ debug_output_compilation_hack (bool x)
   print_output_debug_flag = x;
 }
 
-#if defined (GNU_LINUX)
-
-/* This functionality is not vitally important in general, so we rely on
-   non-portable ability to use stderr as lvalue.  */
-
-#define WITH_REDIRECT_DEBUGGING_OUTPUT 1
-
-static FILE *initial_stderr_stream = NULL;
-
 DEFUN ("redirect-debugging-output", Fredirect_debugging_output, Sredirect_debugging_output,
        1, 2,
        "FDebug output file: \nP",
@@ -749,30 +788,38 @@ Optional arg APPEND non-nil (interactively, with prefix arg) means
 append to existing target file.  */)
   (Lisp_Object file, Lisp_Object append)
 {
-  if (initial_stderr_stream != NULL)
-    {
-      block_input ();
-      fclose (stderr);
-      unblock_input ();
-    }
-  stderr = initial_stderr_stream;
-  initial_stderr_stream = NULL;
+  /* If equal to STDERR_FILENO, stderr has not been duplicated and is OK as-is.
+     Otherwise, this is a close-on-exec duplicate of the original stderr. */
+  static int stderr_dup = STDERR_FILENO;
+  int fd = stderr_dup;
 
-  if (STRINGP (file))
+  if (! NILP (file))
     {
       file = Fexpand_file_name (file, Qnil);
-      initial_stderr_stream = stderr;
-      stderr = emacs_fopen (SSDATA (file), NILP (append) ? "w" : "a");
-      if (stderr == NULL)
+
+      if (stderr_dup == STDERR_FILENO)
        {
-         stderr = initial_stderr_stream;
-         initial_stderr_stream = NULL;
-         report_file_error ("Cannot open debugging output stream", file);
+         int n = fcntl (STDERR_FILENO, F_DUPFD_CLOEXEC, STDERR_FILENO + 1);
+         if (n < 0)
+           report_file_error ("dup", file);
+         stderr_dup = n;
        }
+
+      fd = emacs_open (SSDATA (ENCODE_FILE (file)),
+                      (O_WRONLY | O_CREAT
+                       | (! NILP (append) ? O_APPEND : O_TRUNC)),
+                      0666);
+      if (fd < 0)
+       report_file_error ("Cannot open debugging output stream", file);
     }
+
+  fflush (stderr);
+  if (dup2 (fd, STDERR_FILENO) < 0)
+    report_file_error ("dup2", file);
+  if (fd != stderr_dup)
+    emacs_close (fd);
   return Qnil;
 }
-#endif /* GNU_LINUX */
 
 
 /* This is the interface for debugging printing.  */
@@ -793,9 +840,12 @@ safe_debug_print (Lisp_Object arg)
   if (valid > 0)
     debug_print (arg);
   else
-    fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n",
-            !valid ? "INVALID" : "SOME",
-            XLI (arg));
+    {
+      EMACS_UINT n = XLI (arg);
+      fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n",
+              !valid ? "INVALID" : "SOME",
+              n);
+    }
 }
 
 \f
@@ -808,7 +858,6 @@ error message is constructed.  */)
 {
   struct buffer *old = current_buffer;
   Lisp_Object value;
-  struct gcpro gcpro1;
 
   /* If OBJ is (error STRING), just return STRING.
      That is not only faster, it also avoids the need to allocate
@@ -824,10 +873,8 @@ error message is constructed.  */)
   set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
   value = Fbuffer_string ();
 
-  GCPRO1 (value);
   Ferase_buffer ();
   set_buffer_internal (old);
-  UNGCPRO;
 
   return value;
 }
@@ -842,7 +889,6 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context,
                     Lisp_Object caller)
 {
   Lisp_Object errname, errmsg, file_error, tail;
-  struct gcpro gcpro1;
 
   if (context != 0)
     write_string_1 (context, stream);
@@ -856,7 +902,7 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context,
       USE_SAFE_ALLOCA;
       char *name = SAFE_ALLOCA (cnamelen);
       memcpy (name, SDATA (cname), cnamelen);
-      message_dolog (name, cnamelen, 0, 0);
+      message_dolog (name, cnamelen, 0, STRING_MULTIBYTE (cname));
       message_dolog (": ", 2, 0, 0);
       SAFE_FREE ();
     }
@@ -881,7 +927,6 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context,
   /* Print an error message including the data items.  */
 
   tail = Fcdr_safe (data);
-  GCPRO1 (tail);
 
   /* For file-error, make error message by concatenating
      all the data items.  They are all strings.  */
@@ -894,7 +939,7 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context,
     if (!STRINGP (errmsg))
       write_string_1 ("peculiar error", stream);
     else if (SCHARS (errmsg))
-      Fprinc (errmsg, stream);
+      Fprinc (Fsubstitute_command_keys (errmsg), stream);
     else
       sep = NULL;
 
@@ -912,8 +957,6 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context,
          Fprin1 (obj, stream);
       }
   }
-
-  UNGCPRO;
 }
 
 
@@ -1382,16 +1425,13 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
        print_string (obj, printcharfun);
       else
        {
-         register ptrdiff_t i, i_byte;
-         struct gcpro gcpro1;
+         ptrdiff_t i, i_byte;
          ptrdiff_t size_byte;
-         /* 1 means we must ensure that the next character we output
+         /* True means we must ensure that the next character we output
             cannot be taken as part of a hex character escape.  */
-         bool need_nonhex = 0;
+         bool need_nonhex = false;
          bool multibyte = STRING_MULTIBYTE (obj);
 
-         GCPRO1 (obj);
-
          if (! EQ (Vprint_charset_text_property, Qt))
            obj = print_prune_string_charset (obj);
 
@@ -1411,60 +1451,46 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
 
              QUIT;
 
-             if (c == '\n' && print_escape_newlines)
-               print_c_string ("\\n", printcharfun);
-             else if (c == '\f' && print_escape_newlines)
-               print_c_string ("\\f", printcharfun);
-             else if (multibyte
-                      && (CHAR_BYTE8_P (c)
-                          || (! ASCII_CHAR_P (c) && print_escape_multibyte)))
+             if (multibyte
+                 ? (CHAR_BYTE8_P (c) && (c = CHAR_TO_BYTE8 (c), true))
+                 : (SINGLE_BYTE_CHAR_P (c) && ! ASCII_CHAR_P (c)
+                    && print_escape_nonascii))
                {
-                 /* When multibyte is disabled,
-                    print multibyte string chars using hex escapes.
-                    For a char code that could be in a unibyte string,
-                    when found in a multibyte string, always use a hex escape
-                    so it reads back as multibyte.  */
-                 char outbuf[50];
-                 int len;
-
-                 if (CHAR_BYTE8_P (c))
-                   len = sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c));
-                 else
-                   {
-                     len = sprintf (outbuf, "\\x%04x", c);
-                     need_nonhex = 1;
-                   }
-                 strout (outbuf, len, len, printcharfun);
-               }
-             else if (! multibyte
-                      && SINGLE_BYTE_CHAR_P (c) && ! ASCII_CHAR_P (c)
-                      && print_escape_nonascii)
-               {
-                 /* When printing in a multibyte buffer
-                    or when explicitly requested,
+                 /* When printing a raw 8-bit byte in a multibyte buffer, or
+                    (when requested) a non-ASCII character in a unibyte buffer,
                     print single-byte non-ASCII string chars
                     using octal escapes.  */
                  char outbuf[5];
-                 int len = sprintf (outbuf, "\\%03o", c);
+                 int len = sprintf (outbuf, "\\%03o", c + 0u);
                  strout (outbuf, len, len, printcharfun);
+                 need_nonhex = false;
+               }
+             else if (multibyte
+                      && ! ASCII_CHAR_P (c) && print_escape_multibyte)
+               {
+                 /* When requested, print multibyte chars using hex escapes.  */
+                 char outbuf[sizeof "\\x" + INT_STRLEN_BOUND (c)];
+                 int len = sprintf (outbuf, "\\x%04x", c + 0u);
+                 strout (outbuf, len, len, printcharfun);
+                 need_nonhex = true;
                }
              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'))
-                       print_c_string ("\\ ", printcharfun);
-                   }
-
-                 if (c == '\"' || c == '\\')
+                 if (need_nonhex && c_isxdigit (c))
+                   print_c_string ("\\ ", printcharfun);
+
+                 if (c == '\n' && print_escape_newlines
+                     ? (c = 'n', true)
+                     : c == '\f' && print_escape_newlines
+                     ? (c = 'f', true)
+                     : c == '\"' || c == '\\')
                    printchar ('\\', printcharfun);
+
                  printchar (c, printcharfun);
+                 need_nonhex = false;
                }
            }
          printchar ('\"', printcharfun);
@@ -1475,8 +1501,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
                                  0, print_interval, printcharfun);
              printchar (')', printcharfun);
            }
-
-         UNGCPRO;
        }
       break;
 
@@ -1554,33 +1578,32 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
          && print_depth > XINT (Vprint_level))
        print_c_string ("...", printcharfun);
       else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
-              && (EQ (XCAR (obj), Qquote)))
+              && EQ (XCAR (obj), Qquote))
        {
          printchar ('\'', printcharfun);
          print_object (XCAR (XCDR (obj)), printcharfun, escapeflag);
        }
       else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
-              && (EQ (XCAR (obj), Qfunction)))
+              && EQ (XCAR (obj), Qfunction))
        {
          print_c_string ("#'", printcharfun);
          print_object (XCAR (XCDR (obj)), printcharfun, escapeflag);
        }
       else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
-              && ((EQ (XCAR (obj), Qbackquote))))
+              && EQ (XCAR (obj), Qbackquote))
        {
-         print_object (XCAR (obj), printcharfun, 0);
+         printchar ('`', printcharfun);
          new_backquote_output++;
          print_object (XCAR (XCDR (obj)), printcharfun, escapeflag);
          new_backquote_output--;
        }
       else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
               && new_backquote_output
-              && ((EQ (XCAR (obj), Qbackquote)
-                   || EQ (XCAR (obj), Qcomma)
-                   || EQ (XCAR (obj), Qcomma_at)
-                   || EQ (XCAR (obj), Qcomma_dot))))
+              && (EQ (XCAR (obj), Qcomma)
+                  || EQ (XCAR (obj), Qcomma_at)
+                  || EQ (XCAR (obj), Qcomma_dot)))
        {
-         print_object (XCAR (obj), printcharfun, 0);
+         print_object (XCAR (obj), printcharfun, false);
          new_backquote_output--;
          print_object (XCAR (XCDR (obj)), printcharfun, escapeflag);
          new_backquote_output++;
@@ -1671,11 +1694,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
        {
          ptrdiff_t i;
          unsigned char c;
-         struct gcpro gcpro1;
          EMACS_INT size = bool_vector_size (obj);
          ptrdiff_t size_in_chars = bool_vector_bytes (size);
          ptrdiff_t real_size_in_chars = size_in_chars;
-         GCPRO1 (obj);
 
          int len = sprintf (buf, "#&%"pI"d\"", size);
          strout (buf, len, len, printcharfun);
@@ -1712,8 +1733,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
          if (size_in_chars < real_size_in_chars)
            print_c_string (" ...", printcharfun);
          printchar ('\"', printcharfun);
-
-         UNGCPRO;
        }
       else if (SUBRP (obj))
        {
@@ -1721,6 +1740,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
          print_c_string (XSUBR (obj)->symbol_name, printcharfun);
          printchar ('>', printcharfun);
        }
+      else if (XWIDGETP (obj) || XWIDGET_VIEW_P (obj))
+       {
+         print_c_string ("#<xwidget ", printcharfun);
+         printchar ('>', printcharfun);
+       }
       else if (WINDOWP (obj))
        {
          int len = sprintf (buf, "#<window %"pI"d",
@@ -1985,6 +2009,19 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
          printchar ('>', printcharfun);
           break;
 
+#ifdef HAVE_MODULES
+       case Lisp_Misc_User_Ptr:
+         {
+           print_c_string ("#<user-ptr ", printcharfun);
+           int i = sprintf (buf, "ptr=%p finalizer=%p",
+                            XUSER_PTR (obj)->p,
+                            XUSER_PTR (obj)->finalizer);
+           strout (buf, i, i, printcharfun);
+           printchar ('>', printcharfun);
+           break;
+         }
+#endif
+
         case Lisp_Misc_Finalizer:
           print_c_string ("#<finalizer", printcharfun);
           if (NILP (XFINALIZER (obj)->function))
@@ -2010,8 +2047,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
              {
                ptrdiff_t amount = v->data[1].integer;
 
-#if GC_MARK_STACK
-
                /* valid_lisp_object_p is reliable, so try to print up
                   to 8 saved objects.  This code is rarely used, so
                   it's OK that valid_lisp_object_p is slow.  */
@@ -2036,16 +2071,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
                  }
                if (i == limit && i < amount)
                  print_c_string (" ...", printcharfun);
-
-#else /* not GC_MARK_STACK */
-
-               /* There is no reliable way to determine whether the objects
-                  are initialized, so do not try to print them.  */
-
-               i = sprintf (buf, "with %"pD"d objects", amount);
-               strout (buf, i, i, printcharfun);
-
-#endif /* GC_MARK_STACK */
              }
            else
              {
@@ -2107,11 +2132,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
           Probably should just emacs_abort ().  */
        print_c_string ("#<EMACS BUG: INVALID DATATYPE ", printcharfun);
        if (MISCP (obj))
-         len = sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj));
+         len = sprintf (buf, "(MISC 0x%04x)", (unsigned) XMISCTYPE (obj));
        else if (VECTORLIKEP (obj))
-         len = sprintf (buf, "(PVEC 0x%08"pD"x)", ASIZE (obj));
+         len = sprintf (buf, "(PVEC 0x%08zx)", (size_t) ASIZE (obj));
        else
-         len = sprintf (buf, "(0x%02x)", (int) XTYPE (obj));
+         len = sprintf (buf, "(0x%02x)", (unsigned) XTYPE (obj));
        strout (buf, len, len, printcharfun);
        print_c_string ((" Save your buffers immediately"
                         " and please report this bug>"),
@@ -2184,7 +2209,6 @@ decimal point.  0 is not allowed with `e' or `g'.
 A value of nil means to use the shortest notation
 that represents the number without losing information.  */);
   Vfloat_output_format = Qnil;
-  DEFSYM (Qfloat_output_format, "float-output-format");
 
   DEFVAR_LISP ("print-length", Vprint_length,
               doc: /* Maximum length of list to print before abbreviating.
@@ -2217,7 +2241,7 @@ This affects only `prin1'.  */);
 
   DEFVAR_BOOL ("print-quoted", print_quoted,
               doc: /* Non-nil means print quoted forms with reader syntax.
-I.e., (quote foo) prints as 'foo, (function foo) as #'foo.  */);
+I.e., (quote foo) prints as \\='foo, (function foo) as #\\='foo.  */);
   print_quoted = 0;
 
   DEFVAR_LISP ("print-gensym", Vprint_gensym,
@@ -2284,9 +2308,7 @@ priorities.  */);
   defsubr (&Sprint);
   defsubr (&Sterpri);
   defsubr (&Swrite_char);
-#ifdef WITH_REDIRECT_DEBUGGING_OUTPUT
   defsubr (&Sredirect_debugging_output);
-#endif
 
   DEFSYM (Qprint_escape_newlines, "print-escape-newlines");
   DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte");