]> code.delx.au - gnu-emacs/blobdiff - src/print.c
* doc/lispref/modes.texi (Defining Minor Modes): Use C-backspace, not C-delete.
[gnu-emacs] / src / print.c
index 90b46496eff4971de2bfb6d39dd45ef740c6cb86..ccbf8d8c0c789ae3451d0954960a9acc9d80dbeb 100644 (file)
@@ -1,7 +1,7 @@
 /* Lisp object printing and output streams.
    Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997,
                  1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -21,6 +21,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "buffer.h"
 #include "character.h"
@@ -400,7 +401,7 @@ strout (ptr, size, size_byte, printcharfun, multibyte)
          int len;
          for (i = 0; i < size_byte; i += len)
            {
-             int ch = STRING_CHAR_AND_LENGTH (ptr + i, size_byte - i, len);
+             int ch = STRING_CHAR_AND_LENGTH (ptr + i, len);
              insert_char (ch);
            }
        }
@@ -426,7 +427,7 @@ strout (ptr, size, size_byte, printcharfun, multibyte)
                 corresponding character code before handing it to
                 PRINTCHAR.  */
              int len;
-             int ch = STRING_CHAR_AND_LENGTH (ptr + i, size_byte - i, len);
+             int ch = STRING_CHAR_AND_LENGTH (ptr + i, len);
              PRINTCHAR (ch);
              i += len;
            }
@@ -518,8 +519,7 @@ print_string (string, printcharfun)
            /* Here, we must convert each multi-byte form to the
               corresponding character code before handing it to PRINTCHAR.  */
            int len;
-           int ch = STRING_CHAR_AND_LENGTH (SDATA (string) + i,
-                                            size_byte - i, len);
+           int ch = STRING_CHAR_AND_LENGTH (SDATA (string) + i, len);
            PRINTCHAR (ch);
            i += len;
          }
@@ -1341,6 +1341,7 @@ print_preprocess (obj)
  loop:
   if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
       || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj)
+      || HASH_TABLE_P (obj)
       || (! NILP (Vprint_gensym)
          && SYMBOLP (obj)
          && !SYMBOL_INTERNED_P (obj)))
@@ -1415,6 +1416,13 @@ print_preprocess (obj)
            size &= PSEUDOVECTOR_SIZE_MASK;
          for (i = 0; i < size; i++)
            print_preprocess (XVECTOR (obj)->contents[i]);
+         if (HASH_TABLE_P (obj))
+           { /* For hash tables, the key_and_value slot is past
+               `size' because it needs to be marked specially in case
+               the table is weak.  */
+             struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
+             print_preprocess (h->key_and_value);
+           }
          break;
 
        default:
@@ -1536,6 +1544,7 @@ print_object (obj, printcharfun, escapeflag)
   /* Detect circularities and truncate them.  */
   if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
       || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj)
+      || HASH_TABLE_P (obj)
       || (! NILP (Vprint_gensym)
          && SYMBOLP (obj)
          && !SYMBOL_INTERNED_P (obj)))
@@ -1585,7 +1594,7 @@ print_object (obj, printcharfun, escapeflag)
 
   switch (XTYPE (obj))
     {
-    case Lisp_Int:
+    case_Lisp_Int:
       if (sizeof (int) == sizeof (EMACS_INT))
        sprintf (buf, "%d", (int) XINT (obj));
       else if (sizeof (long) == sizeof (EMACS_INT))
@@ -1642,8 +1651,7 @@ print_object (obj, printcharfun, escapeflag)
 
              if (multibyte)
                {
-                 c = STRING_CHAR_AND_LENGTH (str + i_byte,
-                                             size_byte - i_byte, len);
+                 c = STRING_CHAR_AND_LENGTH (str + i_byte, len);
                  i_byte += len;
                }
              else
@@ -1751,7 +1759,7 @@ print_object (obj, printcharfun, escapeflag)
          {
            while (p != end && ((*p >= '0' && *p <= '9')
                                /* Needed for \2e10.  */
-                               || *p == 'e'))
+                               || *p == 'e' || *p == 'E'))
              p++;
            confusing = (end == p);
          }
@@ -1968,12 +1976,7 @@ print_object (obj, printcharfun, escapeflag)
            {
              QUIT;
              c = XBOOL_VECTOR (obj)->data[i];
-             if (! ASCII_BYTE_P (c))
-               {
-                 sprintf (buf, "\\%03o", c);
-                 strout (buf, -1, -1, printcharfun, 0);
-               }
-             else if (c == '\n' && print_escape_newlines)
+             if (c == '\n' && print_escape_newlines)
                {
                  PRINTCHAR ('\\');
                  PRINTCHAR ('n');
@@ -2036,6 +2039,8 @@ print_object (obj, printcharfun, escapeflag)
       else if (HASH_TABLE_P (obj))
        {
          struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
+         int i, real_size, size;
+#if 0
          strout ("#<hash-table", -1, -1, printcharfun, 0);
          if (SYMBOLP (h->test))
            {
@@ -2052,6 +2057,65 @@ print_object (obj, printcharfun, escapeflag)
          sprintf (buf, " 0x%lx", (unsigned long) h);
          strout (buf, -1, -1, printcharfun, 0);
          PRINTCHAR ('>');
+#endif
+         /* Implement a readable output, e.g.:
+           #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
+         /* Always print the size. */
+         sprintf (buf, "#s(hash-table size %ld",
+                  (long) XVECTOR (h->next)->size);
+         strout (buf, -1, -1, printcharfun, 0);
+
+         if (!NILP (h->test))
+           {
+             strout (" test ", -1, -1, printcharfun, 0);
+             print_object (h->test, printcharfun, 0);
+           }
+
+         if (!NILP (h->weak))
+           {
+             strout (" weakness ", -1, -1, printcharfun, 0);
+             print_object (h->weak, printcharfun, 0);
+           }
+
+         if (!NILP (h->rehash_size))
+           {
+             strout (" rehash-size ", -1, -1, printcharfun, 0);
+             print_object (h->rehash_size, printcharfun, 0);
+           }
+
+         if (!NILP (h->rehash_threshold))
+           {
+             strout (" rehash-threshold ", -1, -1, printcharfun, 0);
+             print_object (h->rehash_threshold, printcharfun, 0);
+           }
+
+         strout (" data ", -1, -1, printcharfun, 0);
+
+         /* Print the data here as a plist. */
+         real_size = HASH_TABLE_SIZE (h);
+         size = real_size;
+
+         /* Don't print more elements than the specified maximum.  */
+         if (NATNUMP (Vprint_length)
+             && XFASTINT (Vprint_length) < size)
+           size = XFASTINT (Vprint_length);
+         
+         PRINTCHAR ('(');
+         for (i = 0; i < size; i++)
+           if (!NILP (HASH_HASH (h, i)))
+             {
+               if (i) PRINTCHAR (' ');
+               print_object (HASH_KEY (h, i), printcharfun, 1);
+               PRINTCHAR (' ');
+               print_object (HASH_VALUE (h, i), printcharfun, 1);
+             }
+
+         if (size < real_size)
+           strout (" ...", 4, 4, printcharfun, 0);
+
+         PRINTCHAR (')');
+         PRINTCHAR (')');
+
        }
       else if (BUFFERP (obj))
        {
@@ -2121,6 +2185,13 @@ print_object (obj, printcharfun, escapeflag)
              /* We print a char-table as if it were a vector,
                 lumping the parent and default slots in with the
                 character slots.  But we add #^ as a prefix.  */
+
+             /* Make each lowest sub_char_table start a new line.
+                Otherwise we'll make a line extremely long, which
+                results in slow redisplay.  */
+             if (SUB_CHAR_TABLE_P (obj)
+                 && XINT (XSUB_CHAR_TABLE (obj)->depth) == 3)
+               PRINTCHAR ('\n');
              PRINTCHAR ('#');
              PRINTCHAR ('^');
              if (SUB_CHAR_TABLE_P (obj))
@@ -2319,7 +2390,7 @@ print_interval (interval, printcharfun)
 void
 syms_of_print ()
 {
-  Qtemp_buffer_setup_hook = intern ("temp-buffer-setup-hook");
+  Qtemp_buffer_setup_hook = intern_c_string ("temp-buffer-setup-hook");
   staticpro (&Qtemp_buffer_setup_hook);
 
   DEFVAR_LISP ("standard-output", &Vstandard_output,
@@ -2329,7 +2400,7 @@ It may also be a buffer (output is inserted before point)
 or a marker (output is inserted and the marker is advanced)
 or the symbol t (output appears in the echo area).  */);
   Vstandard_output = Qt;
-  Qstandard_output = intern ("standard-output");
+  Qstandard_output = intern_c_string ("standard-output");
   staticpro (&Qstandard_output);
 
   DEFVAR_LISP ("float-output-format", &Vfloat_output_format,
@@ -2349,7 +2420,7 @@ 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;
-  Qfloat_output_format = intern ("float-output-format");
+  Qfloat_output_format = intern_c_string ("float-output-format");
   staticpro (&Qfloat_output_format);
 
   DEFVAR_LISP ("print-length", &Vprint_length,
@@ -2455,16 +2526,16 @@ priorities.  */);
   defsubr (&Sredirect_debugging_output);
 #endif
 
-  Qexternal_debugging_output = intern ("external-debugging-output");
+  Qexternal_debugging_output = intern_c_string ("external-debugging-output");
   staticpro (&Qexternal_debugging_output);
 
-  Qprint_escape_newlines = intern ("print-escape-newlines");
+  Qprint_escape_newlines = intern_c_string ("print-escape-newlines");
   staticpro (&Qprint_escape_newlines);
 
-  Qprint_escape_multibyte = intern ("print-escape-multibyte");
+  Qprint_escape_multibyte = intern_c_string ("print-escape-multibyte");
   staticpro (&Qprint_escape_multibyte);
 
-  Qprint_escape_nonascii = intern ("print-escape-nonascii");
+  Qprint_escape_nonascii = intern_c_string ("print-escape-nonascii");
   staticpro (&Qprint_escape_nonascii);
 
   print_prune_charset_plist = Qnil;