+ switch (XGCTYPE (obj))
+ {
+ case Lisp_String:
+ /* A string may have text properties, which can be circular. */
+ traverse_intervals_noorder (STRING_INTERVALS (obj),
+ print_preprocess_string, Qnil);
+ break;
+
+ case Lisp_Cons:
+ /* Use HALFTAIL and LOOP_COUNT to detect circular lists,
+ just as in print_object. */
+ if (loop_count && EQ (obj, halftail))
+ break;
+ print_preprocess (XCAR (obj));
+ obj = XCDR (obj);
+ loop_count++;
+ if (!(loop_count & 1))
+ halftail = XCDR (halftail);
+ goto loop;
+
+ case Lisp_Vectorlike:
+ size = XVECTOR (obj)->size;
+ if (size & PSEUDOVECTOR_FLAG)
+ size &= PSEUDOVECTOR_SIZE_MASK;
+ for (i = 0; i < size; i++)
+ print_preprocess (XVECTOR (obj)->contents[i]);
+ break;
+
+ default:
+ break;
+ }
+ }
+ print_depth--;
+}
+
+static void
+print_preprocess_string (interval, arg)
+ INTERVAL interval;
+ Lisp_Object arg;
+{
+ print_preprocess (interval->plist);
+}
+
+static void
+print_object (obj, printcharfun, escapeflag)
+ Lisp_Object obj;
+ register Lisp_Object printcharfun;
+ int escapeflag;
+{
+ char buf[40];
+
+ QUIT;
+
+ /* Detect circularities and truncate them. */
+ if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
+ || COMPILEDP (obj) || CHAR_TABLE_P (obj)
+ || (! NILP (Vprint_gensym)
+ && SYMBOLP (obj)
+ && !SYMBOL_INTERNED_P (obj)))
+ {
+ if (NILP (Vprint_circle) && NILP (Vprint_gensym))
+ {
+ /* Simple but incomplete way. */
+ int i;
+ for (i = 0; i < print_depth; i++)
+ if (EQ (obj, being_printed[i]))
+ {
+ sprintf (buf, "#%d", i);
+ strout (buf, -1, -1, printcharfun, 0);
+ return;
+ }
+ being_printed[print_depth] = obj;
+ }
+ else
+ {
+ /* With the print-circle feature. */
+ int i;
+ for (i = 0; i < print_number_index; i++)
+ if (EQ (PRINT_NUMBER_OBJECT (Vprint_number_table, i), obj))
+ {
+ if (NILP (PRINT_NUMBER_STATUS (Vprint_number_table, i)))
+ {
+ /* Add a prefix #n= if OBJ has not yet been printed;
+ that is, its status field is nil. */
+ sprintf (buf, "#%d=", i + 1);
+ strout (buf, -1, -1, printcharfun, 0);
+ /* OBJ is going to be printed. Set the status to t. */
+ PRINT_NUMBER_STATUS (Vprint_number_table, i) = Qt;
+ break;
+ }
+ else
+ {
+ /* Just print #n# if OBJ has already been printed. */
+ sprintf (buf, "#%d#", i + 1);
+ strout (buf, -1, -1, printcharfun, 0);
+ return;
+ }
+ }
+ }
+ }
+
+ print_depth++;
+
+ /* See similar code in print_preprocess. */