Mercurial > emacs
comparison src/print.c @ 55498:2b06def87ce0
(print_preprocess): Use being_printed, loop_count and
halftail to detect overdeep nesting and cyclic cdr chains.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 10 May 2004 16:55:38 +0000 |
parents | a318c79b8463 |
children | dcb7d888bb38 |
comparison
equal
deleted
inserted
replaced
55497:85aa052b7bf2 | 55498:2b06def87ce0 |
---|---|
1278 print_preprocess (obj) | 1278 print_preprocess (obj) |
1279 Lisp_Object obj; | 1279 Lisp_Object obj; |
1280 { | 1280 { |
1281 int i; | 1281 int i; |
1282 EMACS_INT size; | 1282 EMACS_INT size; |
1283 int loop_count = 0; | |
1284 Lisp_Object halftail; | |
1285 | |
1286 /* Avoid infinite recursion for circular nested structure | |
1287 in the case where Vprint_circle is nil. */ | |
1288 if (NILP (Vprint_circle)) | |
1289 { | |
1290 for (i = 0; i < print_depth; i++) | |
1291 if (EQ (obj, being_printed[i])) | |
1292 return; | |
1293 being_printed[print_depth] = obj; | |
1294 } | |
1295 | |
1296 /* Give up if we go so deep that print_object will get an error. */ | |
1297 /* See similar code in print_object. */ | |
1298 if (print_depth >= PRINT_CIRCLE) | |
1299 return; | |
1300 | |
1301 print_depth++; | |
1302 halftail = obj; | |
1283 | 1303 |
1284 loop: | 1304 loop: |
1285 if (STRINGP (obj) || CONSP (obj) || VECTORP (obj) | 1305 if (STRINGP (obj) || CONSP (obj) || VECTORP (obj) |
1286 || COMPILEDP (obj) || CHAR_TABLE_P (obj) | 1306 || COMPILEDP (obj) || CHAR_TABLE_P (obj) |
1287 || (! NILP (Vprint_gensym) | 1307 || (! NILP (Vprint_gensym) |
1338 traverse_intervals_noorder (STRING_INTERVALS (obj), | 1358 traverse_intervals_noorder (STRING_INTERVALS (obj), |
1339 print_preprocess_string, Qnil); | 1359 print_preprocess_string, Qnil); |
1340 break; | 1360 break; |
1341 | 1361 |
1342 case Lisp_Cons: | 1362 case Lisp_Cons: |
1363 /* Use HALFTAIL and LOOP_COUNT to detect circular lists, | |
1364 just as in print_object. */ | |
1365 if (loop_count && EQ (obj, halftail)) | |
1366 break; | |
1343 print_preprocess (XCAR (obj)); | 1367 print_preprocess (XCAR (obj)); |
1344 obj = XCDR (obj); | 1368 obj = XCDR (obj); |
1369 loop_count++; | |
1370 if (!(loop_count & 1)) | |
1371 halftail = XCDR (halftail); | |
1345 goto loop; | 1372 goto loop; |
1346 | 1373 |
1347 case Lisp_Vectorlike: | 1374 case Lisp_Vectorlike: |
1348 size = XVECTOR (obj)->size; | 1375 size = XVECTOR (obj)->size; |
1349 if (size & PSEUDOVECTOR_FLAG) | 1376 if (size & PSEUDOVECTOR_FLAG) |
1354 | 1381 |
1355 default: | 1382 default: |
1356 break; | 1383 break; |
1357 } | 1384 } |
1358 } | 1385 } |
1386 print_depth--; | |
1359 } | 1387 } |
1360 | 1388 |
1361 static void | 1389 static void |
1362 print_preprocess_string (interval, arg) | 1390 print_preprocess_string (interval, arg) |
1363 INTERVAL interval; | 1391 INTERVAL interval; |
1424 } | 1452 } |
1425 } | 1453 } |
1426 | 1454 |
1427 print_depth++; | 1455 print_depth++; |
1428 | 1456 |
1457 /* See similar code in print_preprocess. */ | |
1429 if (print_depth > PRINT_CIRCLE) | 1458 if (print_depth > PRINT_CIRCLE) |
1430 error ("Apparently circular structure being printed"); | 1459 error ("Apparently circular structure being printed"); |
1431 #ifdef MAX_PRINT_CHARS | 1460 #ifdef MAX_PRINT_CHARS |
1432 if (max_print && print_chars > max_print) | 1461 if (max_print && print_chars > max_print) |
1433 { | 1462 { |