diff options
| author | Alan Mackenzie | 2017-02-12 10:59:03 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2017-02-12 10:59:03 +0000 |
| commit | f4d5b687150810129b7a1d5b006e31ccf82b691b (patch) | |
| tree | 4229b13800349032697daae3904dc3773e6b7a80 /src/fns.c | |
| parent | d5514332d4a6092673ce1f78fadcae0c57f7be64 (diff) | |
| parent | 148100d98319499f0ac6f57b8be08cbd14884a5c (diff) | |
| download | emacs-comment-cache.tar.gz emacs-comment-cache.zip | |
Merge branch 'master' into comment-cachecomment-cache
Diffstat (limited to 'src/fns.c')
| -rw-r--r-- | src/fns.c | 377 |
1 files changed, 157 insertions, 220 deletions
| @@ -34,6 +34,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 34 | #include "buffer.h" | 34 | #include "buffer.h" |
| 35 | #include "intervals.h" | 35 | #include "intervals.h" |
| 36 | #include "window.h" | 36 | #include "window.h" |
| 37 | #include "puresize.h" | ||
| 37 | 38 | ||
| 38 | static void sort_vector_copy (Lisp_Object, ptrdiff_t, | 39 | static void sort_vector_copy (Lisp_Object, ptrdiff_t, |
| 39 | Lisp_Object *restrict, Lisp_Object *restrict); | 40 | Lisp_Object *restrict, Lisp_Object *restrict); |
| @@ -83,18 +84,8 @@ See Info node `(elisp)Random Numbers' for more details. */) | |||
| 83 | return make_number (val); | 84 | return make_number (val); |
| 84 | } | 85 | } |
| 85 | 86 | ||
| 86 | /* Heuristic on how many iterations of a tight loop can be safely done | ||
| 87 | before it's time to do a QUIT. This must be a power of 2. */ | ||
| 88 | enum { QUIT_COUNT_HEURISTIC = 1 << 16 }; | ||
| 89 | |||
| 90 | /* Random data-structure functions. */ | 87 | /* Random data-structure functions. */ |
| 91 | 88 | ||
| 92 | static void | ||
| 93 | CHECK_LIST_END (Lisp_Object x, Lisp_Object y) | ||
| 94 | { | ||
| 95 | CHECK_TYPE (NILP (x), Qlistp, y); | ||
| 96 | } | ||
| 97 | |||
| 98 | DEFUN ("length", Flength, Slength, 1, 1, 0, | 89 | DEFUN ("length", Flength, Slength, 1, 1, 0, |
| 99 | doc: /* Return the length of vector, list or string SEQUENCE. | 90 | doc: /* Return the length of vector, list or string SEQUENCE. |
| 100 | A byte-code function object is also allowed. | 91 | A byte-code function object is also allowed. |
| @@ -126,7 +117,7 @@ To get the number of bytes, use `string-bytes'. */) | |||
| 126 | { | 117 | { |
| 127 | if (MOST_POSITIVE_FIXNUM < i) | 118 | if (MOST_POSITIVE_FIXNUM < i) |
| 128 | error ("List too long"); | 119 | error ("List too long"); |
| 129 | QUIT; | 120 | maybe_quit (); |
| 130 | } | 121 | } |
| 131 | sequence = XCDR (sequence); | 122 | sequence = XCDR (sequence); |
| 132 | } | 123 | } |
| @@ -172,7 +163,7 @@ which is at least the number of distinct elements. */) | |||
| 172 | halftail = XCDR (halftail); | 163 | halftail = XCDR (halftail); |
| 173 | if ((lolen & (QUIT_COUNT_HEURISTIC - 1)) == 0) | 164 | if ((lolen & (QUIT_COUNT_HEURISTIC - 1)) == 0) |
| 174 | { | 165 | { |
| 175 | QUIT; | 166 | maybe_quit (); |
| 176 | if (lolen == 0) | 167 | if (lolen == 0) |
| 177 | hilen += UINTMAX_MAX + 1.0; | 168 | hilen += UINTMAX_MAX + 1.0; |
| 178 | } | 169 | } |
| @@ -1202,17 +1193,12 @@ are shared, however. | |||
| 1202 | Elements of ALIST that are not conses are also shared. */) | 1193 | Elements of ALIST that are not conses are also shared. */) |
| 1203 | (Lisp_Object alist) | 1194 | (Lisp_Object alist) |
| 1204 | { | 1195 | { |
| 1205 | register Lisp_Object tem; | ||
| 1206 | |||
| 1207 | CHECK_LIST (alist); | ||
| 1208 | if (NILP (alist)) | 1196 | if (NILP (alist)) |
| 1209 | return alist; | 1197 | return alist; |
| 1210 | alist = concat (1, &alist, Lisp_Cons, 0); | 1198 | alist = concat (1, &alist, Lisp_Cons, false); |
| 1211 | for (tem = alist; CONSP (tem); tem = XCDR (tem)) | 1199 | for (Lisp_Object tem = alist; !NILP (tem); tem = XCDR (tem)) |
| 1212 | { | 1200 | { |
| 1213 | register Lisp_Object car; | 1201 | Lisp_Object car = XCAR (tem); |
| 1214 | car = XCAR (tem); | ||
| 1215 | |||
| 1216 | if (CONSP (car)) | 1202 | if (CONSP (car)) |
| 1217 | XSETCAR (tem, Fcons (XCAR (car), XCDR (car))); | 1203 | XSETCAR (tem, Fcons (XCAR (car), XCDR (car))); |
| 1218 | } | 1204 | } |
| @@ -1356,16 +1342,19 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0, | |||
| 1356 | doc: /* Take cdr N times on LIST, return the result. */) | 1342 | doc: /* Take cdr N times on LIST, return the result. */) |
| 1357 | (Lisp_Object n, Lisp_Object list) | 1343 | (Lisp_Object n, Lisp_Object list) |
| 1358 | { | 1344 | { |
| 1359 | EMACS_INT i, num; | ||
| 1360 | CHECK_NUMBER (n); | 1345 | CHECK_NUMBER (n); |
| 1361 | num = XINT (n); | 1346 | Lisp_Object tail = list; |
| 1362 | for (i = 0; i < num && !NILP (list); i++) | 1347 | for (EMACS_INT num = XINT (n); 0 < num; num--) |
| 1363 | { | 1348 | { |
| 1364 | QUIT; | 1349 | if (! CONSP (tail)) |
| 1365 | CHECK_LIST_CONS (list, list); | 1350 | { |
| 1366 | list = XCDR (list); | 1351 | CHECK_LIST_END (tail, list); |
| 1352 | return Qnil; | ||
| 1353 | } | ||
| 1354 | tail = XCDR (tail); | ||
| 1355 | rarely_quit (num); | ||
| 1367 | } | 1356 | } |
| 1368 | return list; | 1357 | return tail; |
| 1369 | } | 1358 | } |
| 1370 | 1359 | ||
| 1371 | DEFUN ("nth", Fnth, Snth, 2, 2, 0, | 1360 | DEFUN ("nth", Fnth, Snth, 2, 2, 0, |
| @@ -1392,66 +1381,55 @@ DEFUN ("elt", Felt, Selt, 2, 2, 0, | |||
| 1392 | DEFUN ("member", Fmember, Smember, 2, 2, 0, | 1381 | DEFUN ("member", Fmember, Smember, 2, 2, 0, |
| 1393 | doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `equal'. | 1382 | doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `equal'. |
| 1394 | The value is actually the tail of LIST whose car is ELT. */) | 1383 | The value is actually the tail of LIST whose car is ELT. */) |
| 1395 | (register Lisp_Object elt, Lisp_Object list) | 1384 | (Lisp_Object elt, Lisp_Object list) |
| 1396 | { | 1385 | { |
| 1397 | register Lisp_Object tail; | 1386 | unsigned short int quit_count = 0; |
| 1398 | for (tail = list; !NILP (tail); tail = XCDR (tail)) | 1387 | Lisp_Object tail; |
| 1388 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 1399 | { | 1389 | { |
| 1400 | register Lisp_Object tem; | 1390 | if (! NILP (Fequal (elt, XCAR (tail)))) |
| 1401 | CHECK_LIST_CONS (tail, list); | ||
| 1402 | tem = XCAR (tail); | ||
| 1403 | if (! NILP (Fequal (elt, tem))) | ||
| 1404 | return tail; | 1391 | return tail; |
| 1405 | QUIT; | 1392 | rarely_quit (++quit_count); |
| 1406 | } | 1393 | } |
| 1394 | CHECK_LIST_END (tail, list); | ||
| 1407 | return Qnil; | 1395 | return Qnil; |
| 1408 | } | 1396 | } |
| 1409 | 1397 | ||
| 1410 | DEFUN ("memq", Fmemq, Smemq, 2, 2, 0, | 1398 | DEFUN ("memq", Fmemq, Smemq, 2, 2, 0, |
| 1411 | doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `eq'. | 1399 | doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `eq'. |
| 1412 | The value is actually the tail of LIST whose car is ELT. */) | 1400 | The value is actually the tail of LIST whose car is ELT. */) |
| 1413 | (register Lisp_Object elt, Lisp_Object list) | 1401 | (Lisp_Object elt, Lisp_Object list) |
| 1414 | { | 1402 | { |
| 1415 | while (1) | 1403 | unsigned short int quit_count = 0; |
| 1404 | Lisp_Object tail; | ||
| 1405 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 1416 | { | 1406 | { |
| 1417 | if (!CONSP (list) || EQ (XCAR (list), elt)) | 1407 | if (EQ (XCAR (tail), elt)) |
| 1418 | break; | 1408 | return tail; |
| 1419 | 1409 | rarely_quit (++quit_count); | |
| 1420 | list = XCDR (list); | ||
| 1421 | if (!CONSP (list) || EQ (XCAR (list), elt)) | ||
| 1422 | break; | ||
| 1423 | |||
| 1424 | list = XCDR (list); | ||
| 1425 | if (!CONSP (list) || EQ (XCAR (list), elt)) | ||
| 1426 | break; | ||
| 1427 | |||
| 1428 | list = XCDR (list); | ||
| 1429 | QUIT; | ||
| 1430 | } | 1410 | } |
| 1431 | 1411 | CHECK_LIST_END (tail, list); | |
| 1432 | CHECK_LIST (list); | 1412 | return Qnil; |
| 1433 | return list; | ||
| 1434 | } | 1413 | } |
| 1435 | 1414 | ||
| 1436 | DEFUN ("memql", Fmemql, Smemql, 2, 2, 0, | 1415 | DEFUN ("memql", Fmemql, Smemql, 2, 2, 0, |
| 1437 | doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `eql'. | 1416 | doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `eql'. |
| 1438 | The value is actually the tail of LIST whose car is ELT. */) | 1417 | The value is actually the tail of LIST whose car is ELT. */) |
| 1439 | (register Lisp_Object elt, Lisp_Object list) | 1418 | (Lisp_Object elt, Lisp_Object list) |
| 1440 | { | 1419 | { |
| 1441 | register Lisp_Object tail; | ||
| 1442 | |||
| 1443 | if (!FLOATP (elt)) | 1420 | if (!FLOATP (elt)) |
| 1444 | return Fmemq (elt, list); | 1421 | return Fmemq (elt, list); |
| 1445 | 1422 | ||
| 1446 | for (tail = list; !NILP (tail); tail = XCDR (tail)) | 1423 | unsigned short int quit_count = 0; |
| 1424 | Lisp_Object tail; | ||
| 1425 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 1447 | { | 1426 | { |
| 1448 | register Lisp_Object tem; | 1427 | Lisp_Object tem = XCAR (tail); |
| 1449 | CHECK_LIST_CONS (tail, list); | ||
| 1450 | tem = XCAR (tail); | ||
| 1451 | if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) | 1428 | if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) |
| 1452 | return tail; | 1429 | return tail; |
| 1453 | QUIT; | 1430 | rarely_quit (++quit_count); |
| 1454 | } | 1431 | } |
| 1432 | CHECK_LIST_END (tail, list); | ||
| 1455 | return Qnil; | 1433 | return Qnil; |
| 1456 | } | 1434 | } |
| 1457 | 1435 | ||
| @@ -1461,44 +1439,28 @@ The value is actually the first element of LIST whose car is KEY. | |||
| 1461 | Elements of LIST that are not conses are ignored. */) | 1439 | Elements of LIST that are not conses are ignored. */) |
| 1462 | (Lisp_Object key, Lisp_Object list) | 1440 | (Lisp_Object key, Lisp_Object list) |
| 1463 | { | 1441 | { |
| 1464 | while (1) | 1442 | unsigned short int quit_count = 0; |
| 1443 | Lisp_Object tail; | ||
| 1444 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 1465 | { | 1445 | { |
| 1466 | if (!CONSP (list) | 1446 | if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key)) |
| 1467 | || (CONSP (XCAR (list)) | 1447 | return XCAR (tail); |
| 1468 | && EQ (XCAR (XCAR (list)), key))) | 1448 | rarely_quit (++quit_count); |
| 1469 | break; | ||
| 1470 | |||
| 1471 | list = XCDR (list); | ||
| 1472 | if (!CONSP (list) | ||
| 1473 | || (CONSP (XCAR (list)) | ||
| 1474 | && EQ (XCAR (XCAR (list)), key))) | ||
| 1475 | break; | ||
| 1476 | |||
| 1477 | list = XCDR (list); | ||
| 1478 | if (!CONSP (list) | ||
| 1479 | || (CONSP (XCAR (list)) | ||
| 1480 | && EQ (XCAR (XCAR (list)), key))) | ||
| 1481 | break; | ||
| 1482 | |||
| 1483 | list = XCDR (list); | ||
| 1484 | QUIT; | ||
| 1485 | } | 1449 | } |
| 1486 | 1450 | CHECK_LIST_END (tail, list); | |
| 1487 | return CAR (list); | 1451 | return Qnil; |
| 1488 | } | 1452 | } |
| 1489 | 1453 | ||
| 1490 | /* Like Fassq but never report an error and do not allow quits. | 1454 | /* Like Fassq but never report an error and do not allow quits. |
| 1491 | Use only on lists known never to be circular. */ | 1455 | Use only on objects known to be non-circular lists. */ |
| 1492 | 1456 | ||
| 1493 | Lisp_Object | 1457 | Lisp_Object |
| 1494 | assq_no_quit (Lisp_Object key, Lisp_Object list) | 1458 | assq_no_quit (Lisp_Object key, Lisp_Object list) |
| 1495 | { | 1459 | { |
| 1496 | while (CONSP (list) | 1460 | for (; ! NILP (list); list = XCDR (list)) |
| 1497 | && (!CONSP (XCAR (list)) | 1461 | if (CONSP (XCAR (list)) && EQ (XCAR (XCAR (list)), key)) |
| 1498 | || !EQ (XCAR (XCAR (list)), key))) | 1462 | return XCAR (list); |
| 1499 | list = XCDR (list); | 1463 | return Qnil; |
| 1500 | |||
| 1501 | return CAR_SAFE (list); | ||
| 1502 | } | 1464 | } |
| 1503 | 1465 | ||
| 1504 | DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0, | 1466 | DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0, |
| @@ -1506,81 +1468,51 @@ DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0, | |||
| 1506 | The value is actually the first element of LIST whose car equals KEY. */) | 1468 | The value is actually the first element of LIST whose car equals KEY. */) |
| 1507 | (Lisp_Object key, Lisp_Object list) | 1469 | (Lisp_Object key, Lisp_Object list) |
| 1508 | { | 1470 | { |
| 1509 | Lisp_Object car; | 1471 | unsigned short int quit_count = 0; |
| 1510 | 1472 | Lisp_Object tail; | |
| 1511 | while (1) | 1473 | for (tail = list; CONSP (tail); tail = XCDR (tail)) |
| 1512 | { | 1474 | { |
| 1513 | if (!CONSP (list) | 1475 | Lisp_Object car = XCAR (tail); |
| 1514 | || (CONSP (XCAR (list)) | 1476 | if (CONSP (car) |
| 1515 | && (car = XCAR (XCAR (list)), | 1477 | && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key)))) |
| 1516 | EQ (car, key) || !NILP (Fequal (car, key))))) | 1478 | return car; |
| 1517 | break; | 1479 | rarely_quit (++quit_count); |
| 1518 | |||
| 1519 | list = XCDR (list); | ||
| 1520 | if (!CONSP (list) | ||
| 1521 | || (CONSP (XCAR (list)) | ||
| 1522 | && (car = XCAR (XCAR (list)), | ||
| 1523 | EQ (car, key) || !NILP (Fequal (car, key))))) | ||
| 1524 | break; | ||
| 1525 | |||
| 1526 | list = XCDR (list); | ||
| 1527 | if (!CONSP (list) | ||
| 1528 | || (CONSP (XCAR (list)) | ||
| 1529 | && (car = XCAR (XCAR (list)), | ||
| 1530 | EQ (car, key) || !NILP (Fequal (car, key))))) | ||
| 1531 | break; | ||
| 1532 | |||
| 1533 | list = XCDR (list); | ||
| 1534 | QUIT; | ||
| 1535 | } | 1480 | } |
| 1536 | 1481 | CHECK_LIST_END (tail, list); | |
| 1537 | return CAR (list); | 1482 | return Qnil; |
| 1538 | } | 1483 | } |
| 1539 | 1484 | ||
| 1540 | /* Like Fassoc but never report an error and do not allow quits. | 1485 | /* Like Fassoc but never report an error and do not allow quits. |
| 1541 | Use only on lists known never to be circular. */ | 1486 | Use only on objects known to be non-circular lists. */ |
| 1542 | 1487 | ||
| 1543 | Lisp_Object | 1488 | Lisp_Object |
| 1544 | assoc_no_quit (Lisp_Object key, Lisp_Object list) | 1489 | assoc_no_quit (Lisp_Object key, Lisp_Object list) |
| 1545 | { | 1490 | { |
| 1546 | while (CONSP (list) | 1491 | for (; ! NILP (list); list = XCDR (list)) |
| 1547 | && (!CONSP (XCAR (list)) | 1492 | { |
| 1548 | || (!EQ (XCAR (XCAR (list)), key) | 1493 | Lisp_Object car = XCAR (list); |
| 1549 | && NILP (Fequal (XCAR (XCAR (list)), key))))) | 1494 | if (CONSP (car) |
| 1550 | list = XCDR (list); | 1495 | && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key)))) |
| 1551 | 1496 | return car; | |
| 1552 | return CONSP (list) ? XCAR (list) : Qnil; | 1497 | } |
| 1498 | return Qnil; | ||
| 1553 | } | 1499 | } |
| 1554 | 1500 | ||
| 1555 | DEFUN ("rassq", Frassq, Srassq, 2, 2, 0, | 1501 | DEFUN ("rassq", Frassq, Srassq, 2, 2, 0, |
| 1556 | doc: /* Return non-nil if KEY is `eq' to the cdr of an element of LIST. | 1502 | doc: /* Return non-nil if KEY is `eq' to the cdr of an element of LIST. |
| 1557 | The value is actually the first element of LIST whose cdr is KEY. */) | 1503 | The value is actually the first element of LIST whose cdr is KEY. */) |
| 1558 | (register Lisp_Object key, Lisp_Object list) | 1504 | (Lisp_Object key, Lisp_Object list) |
| 1559 | { | 1505 | { |
| 1560 | while (1) | 1506 | unsigned short int quit_count = 0; |
| 1507 | Lisp_Object tail; | ||
| 1508 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 1561 | { | 1509 | { |
| 1562 | if (!CONSP (list) | 1510 | if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key)) |
| 1563 | || (CONSP (XCAR (list)) | 1511 | return XCAR (tail); |
| 1564 | && EQ (XCDR (XCAR (list)), key))) | 1512 | rarely_quit (++quit_count); |
| 1565 | break; | ||
| 1566 | |||
| 1567 | list = XCDR (list); | ||
| 1568 | if (!CONSP (list) | ||
| 1569 | || (CONSP (XCAR (list)) | ||
| 1570 | && EQ (XCDR (XCAR (list)), key))) | ||
| 1571 | break; | ||
| 1572 | |||
| 1573 | list = XCDR (list); | ||
| 1574 | if (!CONSP (list) | ||
| 1575 | || (CONSP (XCAR (list)) | ||
| 1576 | && EQ (XCDR (XCAR (list)), key))) | ||
| 1577 | break; | ||
| 1578 | |||
| 1579 | list = XCDR (list); | ||
| 1580 | QUIT; | ||
| 1581 | } | 1513 | } |
| 1582 | 1514 | CHECK_LIST_END (tail, list); | |
| 1583 | return CAR (list); | 1515 | return Qnil; |
| 1584 | } | 1516 | } |
| 1585 | 1517 | ||
| 1586 | DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0, | 1518 | DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0, |
| @@ -1588,35 +1520,18 @@ DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0, | |||
| 1588 | The value is actually the first element of LIST whose cdr equals KEY. */) | 1520 | The value is actually the first element of LIST whose cdr equals KEY. */) |
| 1589 | (Lisp_Object key, Lisp_Object list) | 1521 | (Lisp_Object key, Lisp_Object list) |
| 1590 | { | 1522 | { |
| 1591 | Lisp_Object cdr; | 1523 | unsigned short int quit_count = 0; |
| 1592 | 1524 | Lisp_Object tail; | |
| 1593 | while (1) | 1525 | for (tail = list; CONSP (tail); tail = XCDR (tail)) |
| 1594 | { | 1526 | { |
| 1595 | if (!CONSP (list) | 1527 | Lisp_Object car = XCAR (tail); |
| 1596 | || (CONSP (XCAR (list)) | 1528 | if (CONSP (car) |
| 1597 | && (cdr = XCDR (XCAR (list)), | 1529 | && (EQ (XCDR (car), key) || !NILP (Fequal (XCDR (car), key)))) |
| 1598 | EQ (cdr, key) || !NILP (Fequal (cdr, key))))) | 1530 | return car; |
| 1599 | break; | 1531 | rarely_quit (++quit_count); |
| 1600 | |||
| 1601 | list = XCDR (list); | ||
| 1602 | if (!CONSP (list) | ||
| 1603 | || (CONSP (XCAR (list)) | ||
| 1604 | && (cdr = XCDR (XCAR (list)), | ||
| 1605 | EQ (cdr, key) || !NILP (Fequal (cdr, key))))) | ||
| 1606 | break; | ||
| 1607 | |||
| 1608 | list = XCDR (list); | ||
| 1609 | if (!CONSP (list) | ||
| 1610 | || (CONSP (XCAR (list)) | ||
| 1611 | && (cdr = XCDR (XCAR (list)), | ||
| 1612 | EQ (cdr, key) || !NILP (Fequal (cdr, key))))) | ||
| 1613 | break; | ||
| 1614 | |||
| 1615 | list = XCDR (list); | ||
| 1616 | QUIT; | ||
| 1617 | } | 1532 | } |
| 1618 | 1533 | CHECK_LIST_END (tail, list); | |
| 1619 | return CAR (list); | 1534 | return Qnil; |
| 1620 | } | 1535 | } |
| 1621 | 1536 | ||
| 1622 | DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0, | 1537 | DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0, |
| @@ -1647,6 +1562,7 @@ argument. */) | |||
| 1647 | else | 1562 | else |
| 1648 | prev = tail; | 1563 | prev = tail; |
| 1649 | } | 1564 | } |
| 1565 | CHECK_LIST_END (tail, list); | ||
| 1650 | return list; | 1566 | return list; |
| 1651 | } | 1567 | } |
| 1652 | 1568 | ||
| @@ -1754,12 +1670,11 @@ changing the value of a sequence `foo'. */) | |||
| 1754 | } | 1670 | } |
| 1755 | else | 1671 | else |
| 1756 | { | 1672 | { |
| 1673 | unsigned short int quit_count = 0; | ||
| 1757 | Lisp_Object tail, prev; | 1674 | Lisp_Object tail, prev; |
| 1758 | 1675 | ||
| 1759 | for (tail = seq, prev = Qnil; !NILP (tail); tail = XCDR (tail)) | 1676 | for (tail = seq, prev = Qnil; CONSP (tail); tail = XCDR (tail)) |
| 1760 | { | 1677 | { |
| 1761 | CHECK_LIST_CONS (tail, seq); | ||
| 1762 | |||
| 1763 | if (!NILP (Fequal (elt, XCAR (tail)))) | 1678 | if (!NILP (Fequal (elt, XCAR (tail)))) |
| 1764 | { | 1679 | { |
| 1765 | if (NILP (prev)) | 1680 | if (NILP (prev)) |
| @@ -1769,8 +1684,9 @@ changing the value of a sequence `foo'. */) | |||
| 1769 | } | 1684 | } |
| 1770 | else | 1685 | else |
| 1771 | prev = tail; | 1686 | prev = tail; |
| 1772 | QUIT; | 1687 | rarely_quit (++quit_count); |
| 1773 | } | 1688 | } |
| 1689 | CHECK_LIST_END (tail, seq); | ||
| 1774 | } | 1690 | } |
| 1775 | 1691 | ||
| 1776 | return seq; | 1692 | return seq; |
| @@ -1788,16 +1704,17 @@ This function may destructively modify SEQ to produce the value. */) | |||
| 1788 | return Freverse (seq); | 1704 | return Freverse (seq); |
| 1789 | else if (CONSP (seq)) | 1705 | else if (CONSP (seq)) |
| 1790 | { | 1706 | { |
| 1707 | unsigned short int quit_count = 0; | ||
| 1791 | Lisp_Object prev, tail, next; | 1708 | Lisp_Object prev, tail, next; |
| 1792 | 1709 | ||
| 1793 | for (prev = Qnil, tail = seq; !NILP (tail); tail = next) | 1710 | for (prev = Qnil, tail = seq; CONSP (tail); tail = next) |
| 1794 | { | 1711 | { |
| 1795 | QUIT; | ||
| 1796 | CHECK_LIST_CONS (tail, tail); | ||
| 1797 | next = XCDR (tail); | 1712 | next = XCDR (tail); |
| 1798 | Fsetcdr (tail, prev); | 1713 | Fsetcdr (tail, prev); |
| 1799 | prev = tail; | 1714 | prev = tail; |
| 1715 | rarely_quit (++quit_count); | ||
| 1800 | } | 1716 | } |
| 1717 | CHECK_LIST_END (tail, seq); | ||
| 1801 | seq = prev; | 1718 | seq = prev; |
| 1802 | } | 1719 | } |
| 1803 | else if (VECTORP (seq)) | 1720 | else if (VECTORP (seq)) |
| @@ -1838,10 +1755,11 @@ See also the function `nreverse', which is used more often. */) | |||
| 1838 | return Qnil; | 1755 | return Qnil; |
| 1839 | else if (CONSP (seq)) | 1756 | else if (CONSP (seq)) |
| 1840 | { | 1757 | { |
| 1758 | unsigned short int quit_count = 0; | ||
| 1841 | for (new = Qnil; CONSP (seq); seq = XCDR (seq)) | 1759 | for (new = Qnil; CONSP (seq); seq = XCDR (seq)) |
| 1842 | { | 1760 | { |
| 1843 | QUIT; | ||
| 1844 | new = Fcons (XCAR (seq), new); | 1761 | new = Fcons (XCAR (seq), new); |
| 1762 | rarely_quit (++quit_count); | ||
| 1845 | } | 1763 | } |
| 1846 | CHECK_LIST_END (seq, seq); | 1764 | CHECK_LIST_END (seq, seq); |
| 1847 | } | 1765 | } |
| @@ -2130,12 +2048,11 @@ If PROP is already a property on the list, its value is set to VAL, | |||
| 2130 | otherwise the new PROP VAL pair is added. The new plist is returned; | 2048 | otherwise the new PROP VAL pair is added. The new plist is returned; |
| 2131 | use `(setq x (plist-put x prop val))' to be sure to use the new value. | 2049 | use `(setq x (plist-put x prop val))' to be sure to use the new value. |
| 2132 | The PLIST is modified by side effects. */) | 2050 | The PLIST is modified by side effects. */) |
| 2133 | (Lisp_Object plist, register Lisp_Object prop, Lisp_Object val) | 2051 | (Lisp_Object plist, Lisp_Object prop, Lisp_Object val) |
| 2134 | { | 2052 | { |
| 2135 | register Lisp_Object tail, prev; | 2053 | unsigned short int quit_count = 0; |
| 2136 | Lisp_Object newcell; | 2054 | Lisp_Object prev = Qnil; |
| 2137 | prev = Qnil; | 2055 | for (Lisp_Object tail = plist; CONSP (tail) && CONSP (XCDR (tail)); |
| 2138 | for (tail = plist; CONSP (tail) && CONSP (XCDR (tail)); | ||
| 2139 | tail = XCDR (XCDR (tail))) | 2056 | tail = XCDR (XCDR (tail))) |
| 2140 | { | 2057 | { |
| 2141 | if (EQ (prop, XCAR (tail))) | 2058 | if (EQ (prop, XCAR (tail))) |
| @@ -2145,13 +2062,13 @@ The PLIST is modified by side effects. */) | |||
| 2145 | } | 2062 | } |
| 2146 | 2063 | ||
| 2147 | prev = tail; | 2064 | prev = tail; |
| 2148 | QUIT; | 2065 | rarely_quit (++quit_count); |
| 2149 | } | 2066 | } |
| 2150 | newcell = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev)))); | 2067 | Lisp_Object newcell |
| 2068 | = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev)))); | ||
| 2151 | if (NILP (prev)) | 2069 | if (NILP (prev)) |
| 2152 | return newcell; | 2070 | return newcell; |
| 2153 | else | 2071 | Fsetcdr (XCDR (prev), newcell); |
| 2154 | Fsetcdr (XCDR (prev), newcell); | ||
| 2155 | return plist; | 2072 | return plist; |
| 2156 | } | 2073 | } |
| 2157 | 2074 | ||
| @@ -2174,6 +2091,7 @@ corresponding to the given PROP, or nil if PROP is not | |||
| 2174 | one of the properties on the list. */) | 2091 | one of the properties on the list. */) |
| 2175 | (Lisp_Object plist, Lisp_Object prop) | 2092 | (Lisp_Object plist, Lisp_Object prop) |
| 2176 | { | 2093 | { |
| 2094 | unsigned short int quit_count = 0; | ||
| 2177 | Lisp_Object tail; | 2095 | Lisp_Object tail; |
| 2178 | 2096 | ||
| 2179 | for (tail = plist; | 2097 | for (tail = plist; |
| @@ -2182,8 +2100,7 @@ one of the properties on the list. */) | |||
| 2182 | { | 2100 | { |
| 2183 | if (! NILP (Fequal (prop, XCAR (tail)))) | 2101 | if (! NILP (Fequal (prop, XCAR (tail)))) |
| 2184 | return XCAR (XCDR (tail)); | 2102 | return XCAR (XCDR (tail)); |
| 2185 | 2103 | rarely_quit (++quit_count); | |
| 2186 | QUIT; | ||
| 2187 | } | 2104 | } |
| 2188 | 2105 | ||
| 2189 | CHECK_LIST_END (tail, prop); | 2106 | CHECK_LIST_END (tail, prop); |
| @@ -2199,12 +2116,11 @@ If PROP is already a property on the list, its value is set to VAL, | |||
| 2199 | otherwise the new PROP VAL pair is added. The new plist is returned; | 2116 | otherwise the new PROP VAL pair is added. The new plist is returned; |
| 2200 | use `(setq x (lax-plist-put x prop val))' to be sure to use the new value. | 2117 | use `(setq x (lax-plist-put x prop val))' to be sure to use the new value. |
| 2201 | The PLIST is modified by side effects. */) | 2118 | The PLIST is modified by side effects. */) |
| 2202 | (Lisp_Object plist, register Lisp_Object prop, Lisp_Object val) | 2119 | (Lisp_Object plist, Lisp_Object prop, Lisp_Object val) |
| 2203 | { | 2120 | { |
| 2204 | register Lisp_Object tail, prev; | 2121 | unsigned short int quit_count = 0; |
| 2205 | Lisp_Object newcell; | 2122 | Lisp_Object prev = Qnil; |
| 2206 | prev = Qnil; | 2123 | for (Lisp_Object tail = plist; CONSP (tail) && CONSP (XCDR (tail)); |
| 2207 | for (tail = plist; CONSP (tail) && CONSP (XCDR (tail)); | ||
| 2208 | tail = XCDR (XCDR (tail))) | 2124 | tail = XCDR (XCDR (tail))) |
| 2209 | { | 2125 | { |
| 2210 | if (! NILP (Fequal (prop, XCAR (tail)))) | 2126 | if (! NILP (Fequal (prop, XCAR (tail)))) |
| @@ -2214,13 +2130,12 @@ The PLIST is modified by side effects. */) | |||
| 2214 | } | 2130 | } |
| 2215 | 2131 | ||
| 2216 | prev = tail; | 2132 | prev = tail; |
| 2217 | QUIT; | 2133 | rarely_quit (++quit_count); |
| 2218 | } | 2134 | } |
| 2219 | newcell = list2 (prop, val); | 2135 | Lisp_Object newcell = list2 (prop, val); |
| 2220 | if (NILP (prev)) | 2136 | if (NILP (prev)) |
| 2221 | return newcell; | 2137 | return newcell; |
| 2222 | else | 2138 | Fsetcdr (XCDR (prev), newcell); |
| 2223 | Fsetcdr (XCDR (prev), newcell); | ||
| 2224 | return plist; | 2139 | return plist; |
| 2225 | } | 2140 | } |
| 2226 | 2141 | ||
| @@ -2293,8 +2208,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, | |||
| 2293 | } | 2208 | } |
| 2294 | } | 2209 | } |
| 2295 | 2210 | ||
| 2211 | unsigned short int quit_count = 0; | ||
| 2296 | tail_recurse: | 2212 | tail_recurse: |
| 2297 | QUIT; | 2213 | rarely_quit (++quit_count); |
| 2298 | if (EQ (o1, o2)) | 2214 | if (EQ (o1, o2)) |
| 2299 | return 1; | 2215 | return 1; |
| 2300 | if (XTYPE (o1) != XTYPE (o2)) | 2216 | if (XTYPE (o1) != XTYPE (o2)) |
| @@ -2483,14 +2399,12 @@ Only the last argument is not altered, and need not be a list. | |||
| 2483 | usage: (nconc &rest LISTS) */) | 2399 | usage: (nconc &rest LISTS) */) |
| 2484 | (ptrdiff_t nargs, Lisp_Object *args) | 2400 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2485 | { | 2401 | { |
| 2486 | ptrdiff_t argnum; | 2402 | unsigned short int quit_count = 0; |
| 2487 | register Lisp_Object tail, tem, val; | 2403 | Lisp_Object val = Qnil; |
| 2488 | |||
| 2489 | val = tail = Qnil; | ||
| 2490 | 2404 | ||
| 2491 | for (argnum = 0; argnum < nargs; argnum++) | 2405 | for (ptrdiff_t argnum = 0; argnum < nargs; argnum++) |
| 2492 | { | 2406 | { |
| 2493 | tem = args[argnum]; | 2407 | Lisp_Object tem = args[argnum]; |
| 2494 | if (NILP (tem)) continue; | 2408 | if (NILP (tem)) continue; |
| 2495 | 2409 | ||
| 2496 | if (NILP (val)) | 2410 | if (NILP (val)) |
| @@ -2498,14 +2412,16 @@ usage: (nconc &rest LISTS) */) | |||
| 2498 | 2412 | ||
| 2499 | if (argnum + 1 == nargs) break; | 2413 | if (argnum + 1 == nargs) break; |
| 2500 | 2414 | ||
| 2501 | CHECK_LIST_CONS (tem, tem); | 2415 | CHECK_CONS (tem); |
| 2502 | 2416 | ||
| 2503 | while (CONSP (tem)) | 2417 | Lisp_Object tail; |
| 2418 | do | ||
| 2504 | { | 2419 | { |
| 2505 | tail = tem; | 2420 | tail = tem; |
| 2506 | tem = XCDR (tail); | 2421 | tem = XCDR (tail); |
| 2507 | QUIT; | 2422 | rarely_quit (++quit_count); |
| 2508 | } | 2423 | } |
| 2424 | while (CONSP (tem)); | ||
| 2509 | 2425 | ||
| 2510 | tem = args[argnum + 1]; | 2426 | tem = args[argnum + 1]; |
| 2511 | Fsetcdr (tail, tem); | 2427 | Fsetcdr (tail, tem); |
| @@ -2927,11 +2843,12 @@ property and a property with the value nil. | |||
| 2927 | The value is actually the tail of PLIST whose car is PROP. */) | 2843 | The value is actually the tail of PLIST whose car is PROP. */) |
| 2928 | (Lisp_Object plist, Lisp_Object prop) | 2844 | (Lisp_Object plist, Lisp_Object prop) |
| 2929 | { | 2845 | { |
| 2846 | unsigned short int quit_count = 0; | ||
| 2930 | while (CONSP (plist) && !EQ (XCAR (plist), prop)) | 2847 | while (CONSP (plist) && !EQ (XCAR (plist), prop)) |
| 2931 | { | 2848 | { |
| 2932 | plist = XCDR (plist); | 2849 | plist = XCDR (plist); |
| 2933 | plist = CDR (plist); | 2850 | plist = CDR (plist); |
| 2934 | QUIT; | 2851 | rarely_quit (++quit_count); |
| 2935 | } | 2852 | } |
| 2936 | return plist; | 2853 | return plist; |
| 2937 | } | 2854 | } |
| @@ -3804,12 +3721,17 @@ allocate_hash_table (void) | |||
| 3804 | (table size) is >= REHASH_THRESHOLD. | 3721 | (table size) is >= REHASH_THRESHOLD. |
| 3805 | 3722 | ||
| 3806 | WEAK specifies the weakness of the table. If non-nil, it must be | 3723 | WEAK specifies the weakness of the table. If non-nil, it must be |
| 3807 | one of the symbols `key', `value', `key-or-value', or `key-and-value'. */ | 3724 | one of the symbols `key', `value', `key-or-value', or `key-and-value'. |
| 3725 | |||
| 3726 | If PURECOPY is non-nil, the table can be copied to pure storage via | ||
| 3727 | `purecopy' when Emacs is being dumped. Such tables can no longer be | ||
| 3728 | changed after purecopy. */ | ||
| 3808 | 3729 | ||
| 3809 | Lisp_Object | 3730 | Lisp_Object |
| 3810 | make_hash_table (struct hash_table_test test, | 3731 | make_hash_table (struct hash_table_test test, |
| 3811 | Lisp_Object size, Lisp_Object rehash_size, | 3732 | Lisp_Object size, Lisp_Object rehash_size, |
| 3812 | Lisp_Object rehash_threshold, Lisp_Object weak) | 3733 | Lisp_Object rehash_threshold, Lisp_Object weak, |
| 3734 | Lisp_Object pure) | ||
| 3813 | { | 3735 | { |
| 3814 | struct Lisp_Hash_Table *h; | 3736 | struct Lisp_Hash_Table *h; |
| 3815 | Lisp_Object table; | 3737 | Lisp_Object table; |
| @@ -3850,6 +3772,7 @@ make_hash_table (struct hash_table_test test, | |||
| 3850 | h->hash = Fmake_vector (size, Qnil); | 3772 | h->hash = Fmake_vector (size, Qnil); |
| 3851 | h->next = Fmake_vector (size, Qnil); | 3773 | h->next = Fmake_vector (size, Qnil); |
| 3852 | h->index = Fmake_vector (make_number (index_size), Qnil); | 3774 | h->index = Fmake_vector (make_number (index_size), Qnil); |
| 3775 | h->pure = pure; | ||
| 3853 | 3776 | ||
| 3854 | /* Set up the free list. */ | 3777 | /* Set up the free list. */ |
| 3855 | for (i = 0; i < sz - 1; ++i) | 3778 | for (i = 0; i < sz - 1; ++i) |
| @@ -4514,10 +4437,15 @@ key, value, one of key or value, or both key and value, depending on | |||
| 4514 | WEAK. WEAK t is equivalent to `key-and-value'. Default value of WEAK | 4437 | WEAK. WEAK t is equivalent to `key-and-value'. Default value of WEAK |
| 4515 | is nil. | 4438 | is nil. |
| 4516 | 4439 | ||
| 4440 | :purecopy PURECOPY -- If PURECOPY is non-nil, the table can be copied | ||
| 4441 | to pure storage when Emacs is being dumped, making the contents of the | ||
| 4442 | table read only. Any further changes to purified tables will result | ||
| 4443 | in an error. | ||
| 4444 | |||
| 4517 | usage: (make-hash-table &rest KEYWORD-ARGS) */) | 4445 | usage: (make-hash-table &rest KEYWORD-ARGS) */) |
| 4518 | (ptrdiff_t nargs, Lisp_Object *args) | 4446 | (ptrdiff_t nargs, Lisp_Object *args) |
| 4519 | { | 4447 | { |
| 4520 | Lisp_Object test, size, rehash_size, rehash_threshold, weak; | 4448 | Lisp_Object test, size, rehash_size, rehash_threshold, weak, pure; |
| 4521 | struct hash_table_test testdesc; | 4449 | struct hash_table_test testdesc; |
| 4522 | ptrdiff_t i; | 4450 | ptrdiff_t i; |
| 4523 | USE_SAFE_ALLOCA; | 4451 | USE_SAFE_ALLOCA; |
| @@ -4551,6 +4479,9 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */) | |||
| 4551 | testdesc.cmpfn = cmpfn_user_defined; | 4479 | testdesc.cmpfn = cmpfn_user_defined; |
| 4552 | } | 4480 | } |
| 4553 | 4481 | ||
| 4482 | /* See if there's a `:purecopy PURECOPY' argument. */ | ||
| 4483 | i = get_key_arg (QCpurecopy, nargs, args, used); | ||
| 4484 | pure = i ? args[i] : Qnil; | ||
| 4554 | /* See if there's a `:size SIZE' argument. */ | 4485 | /* See if there's a `:size SIZE' argument. */ |
| 4555 | i = get_key_arg (QCsize, nargs, args, used); | 4486 | i = get_key_arg (QCsize, nargs, args, used); |
| 4556 | size = i ? args[i] : Qnil; | 4487 | size = i ? args[i] : Qnil; |
| @@ -4592,7 +4523,8 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */) | |||
| 4592 | signal_error ("Invalid argument list", args[i]); | 4523 | signal_error ("Invalid argument list", args[i]); |
| 4593 | 4524 | ||
| 4594 | SAFE_FREE (); | 4525 | SAFE_FREE (); |
| 4595 | return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak); | 4526 | return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak, |
| 4527 | pure); | ||
| 4596 | } | 4528 | } |
| 4597 | 4529 | ||
| 4598 | 4530 | ||
| @@ -4671,7 +4603,9 @@ DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0, | |||
| 4671 | doc: /* Clear hash table TABLE and return it. */) | 4603 | doc: /* Clear hash table TABLE and return it. */) |
| 4672 | (Lisp_Object table) | 4604 | (Lisp_Object table) |
| 4673 | { | 4605 | { |
| 4674 | hash_clear (check_hash_table (table)); | 4606 | struct Lisp_Hash_Table *h = check_hash_table (table); |
| 4607 | CHECK_IMPURE (table, h); | ||
| 4608 | hash_clear (h); | ||
| 4675 | /* Be compatible with XEmacs. */ | 4609 | /* Be compatible with XEmacs. */ |
| 4676 | return table; | 4610 | return table; |
| 4677 | } | 4611 | } |
| @@ -4695,9 +4629,10 @@ VALUE. In any case, return VALUE. */) | |||
| 4695 | (Lisp_Object key, Lisp_Object value, Lisp_Object table) | 4629 | (Lisp_Object key, Lisp_Object value, Lisp_Object table) |
| 4696 | { | 4630 | { |
| 4697 | struct Lisp_Hash_Table *h = check_hash_table (table); | 4631 | struct Lisp_Hash_Table *h = check_hash_table (table); |
| 4632 | CHECK_IMPURE (table, h); | ||
| 4633 | |||
| 4698 | ptrdiff_t i; | 4634 | ptrdiff_t i; |
| 4699 | EMACS_UINT hash; | 4635 | EMACS_UINT hash; |
| 4700 | |||
| 4701 | i = hash_lookup (h, key, &hash); | 4636 | i = hash_lookup (h, key, &hash); |
| 4702 | if (i >= 0) | 4637 | if (i >= 0) |
| 4703 | set_hash_value_slot (h, i, value); | 4638 | set_hash_value_slot (h, i, value); |
| @@ -4713,6 +4648,7 @@ DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0, | |||
| 4713 | (Lisp_Object key, Lisp_Object table) | 4648 | (Lisp_Object key, Lisp_Object table) |
| 4714 | { | 4649 | { |
| 4715 | struct Lisp_Hash_Table *h = check_hash_table (table); | 4650 | struct Lisp_Hash_Table *h = check_hash_table (table); |
| 4651 | CHECK_IMPURE (table, h); | ||
| 4716 | hash_remove_from_table (h, key); | 4652 | hash_remove_from_table (h, key); |
| 4717 | return Qnil; | 4653 | return Qnil; |
| 4718 | } | 4654 | } |
| @@ -5083,6 +5019,7 @@ syms_of_fns (void) | |||
| 5083 | DEFSYM (Qequal, "equal"); | 5019 | DEFSYM (Qequal, "equal"); |
| 5084 | DEFSYM (QCtest, ":test"); | 5020 | DEFSYM (QCtest, ":test"); |
| 5085 | DEFSYM (QCsize, ":size"); | 5021 | DEFSYM (QCsize, ":size"); |
| 5022 | DEFSYM (QCpurecopy, ":purecopy"); | ||
| 5086 | DEFSYM (QCrehash_size, ":rehash-size"); | 5023 | DEFSYM (QCrehash_size, ":rehash-size"); |
| 5087 | DEFSYM (QCrehash_threshold, ":rehash-threshold"); | 5024 | DEFSYM (QCrehash_threshold, ":rehash-threshold"); |
| 5088 | DEFSYM (QCweakness, ":weakness"); | 5025 | DEFSYM (QCweakness, ":weakness"); |