diff options
| author | Gerd Moellmann | 2000-07-27 15:44:20 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-07-27 15:44:20 +0000 |
| commit | e517f19dd4e3896a7ba60fc5f330b7499891282b (patch) | |
| tree | f12b2d5f679e05b89198098bb631978893c5d2f9 /src | |
| parent | b3275b47475e2933ace754706dc2020a41a3aca1 (diff) | |
| download | emacs-e517f19dd4e3896a7ba60fc5f330b7499891282b.tar.gz emacs-e517f19dd4e3896a7ba60fc5f330b7499891282b.zip | |
(Fdelete): Make it work on vectors and strings in addition to lists.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fns.c | 137 |
1 files changed, 113 insertions, 24 deletions
| @@ -1593,39 +1593,128 @@ to be sure of changing the value of `foo'.") | |||
| 1593 | } | 1593 | } |
| 1594 | 1594 | ||
| 1595 | DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0, | 1595 | DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0, |
| 1596 | "Delete by side effect any occurrences of ELT as a member of LIST.\n\ | 1596 | "Delete by side effect any occurrences of ELT as a member of SEQ.\n\ |
| 1597 | The modified LIST is returned. Comparison is done with `equal'.\n\ | 1597 | SEQ must be a list, a vector, or a string.\n\ |
| 1598 | If the first member of LIST is ELT, deleting it is not a side effect;\n\ | 1598 | The modified SEQ is returned. Comparison is done with `equal'.\n\ |
| 1599 | it is simply using a different list.\n\ | 1599 | If SEQ is not a list, or the first member of SEQ is ELT, deleting it\n\ |
| 1600 | is not a side effect; it is simply using a different sequence.\n\ | ||
| 1600 | Therefore, write `(setq foo (delete element foo))'\n\ | 1601 | Therefore, write `(setq foo (delete element foo))'\n\ |
| 1601 | to be sure of changing the value of `foo'.") | 1602 | to be sure of changing the value of `foo'.") |
| 1602 | (elt, list) | 1603 | (elt, seq) |
| 1603 | register Lisp_Object elt; | 1604 | Lisp_Object elt, seq; |
| 1604 | Lisp_Object list; | ||
| 1605 | { | 1605 | { |
| 1606 | register Lisp_Object tail, prev; | 1606 | if (VECTORP (seq)) |
| 1607 | register Lisp_Object tem; | 1607 | { |
| 1608 | EMACS_INT i, n, size; | ||
| 1608 | 1609 | ||
| 1609 | tail = list; | 1610 | for (i = n = 0; i < ASIZE (seq); ++i) |
| 1610 | prev = Qnil; | 1611 | if (NILP (Fequal (AREF (seq, i), elt))) |
| 1611 | while (!NILP (tail)) | 1612 | ++n; |
| 1613 | |||
| 1614 | if (n != ASIZE (seq)) | ||
| 1615 | { | ||
| 1616 | struct Lisp_Vector *p = allocate_vectorlike (n); | ||
| 1617 | |||
| 1618 | for (i = n = 0; i < ASIZE (seq); ++i) | ||
| 1619 | if (NILP (Fequal (AREF (seq, i), elt))) | ||
| 1620 | p->contents[n++] = AREF (seq, i); | ||
| 1621 | |||
| 1622 | p->size = n; | ||
| 1623 | XSETVECTOR (seq, p); | ||
| 1624 | } | ||
| 1625 | } | ||
| 1626 | else if (STRINGP (seq)) | ||
| 1612 | { | 1627 | { |
| 1613 | if (! CONSP (tail)) | 1628 | EMACS_INT i, ibyte, nchars, nbytes, cbytes; |
| 1614 | wrong_type_argument (Qlistp, list); | 1629 | int c; |
| 1615 | tem = XCAR (tail); | 1630 | |
| 1616 | if (! NILP (Fequal (elt, tem))) | 1631 | for (i = nchars = nbytes = ibyte = 0; |
| 1632 | i < XSTRING (seq)->size; | ||
| 1633 | ++i, ibyte += cbytes) | ||
| 1617 | { | 1634 | { |
| 1618 | if (NILP (prev)) | 1635 | if (STRING_MULTIBYTE (seq)) |
| 1619 | list = XCDR (tail); | 1636 | { |
| 1637 | c = STRING_CHAR (&XSTRING (seq)->data[ibyte], | ||
| 1638 | STRING_BYTES (XSTRING (seq)) - ibyte); | ||
| 1639 | cbytes = CHAR_BYTES (c); | ||
| 1640 | } | ||
| 1620 | else | 1641 | else |
| 1621 | Fsetcdr (prev, XCDR (tail)); | 1642 | { |
| 1643 | c = XSTRING (seq)->data[i]; | ||
| 1644 | cbytes = 1; | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | if (!INTEGERP (elt) || c != XINT (elt)) | ||
| 1648 | { | ||
| 1649 | ++nchars; | ||
| 1650 | nbytes += cbytes; | ||
| 1651 | } | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | if (nchars != XSTRING (seq)->size) | ||
| 1655 | { | ||
| 1656 | Lisp_Object tem; | ||
| 1657 | |||
| 1658 | tem = make_uninit_multibyte_string (nchars, nbytes); | ||
| 1659 | if (!STRING_MULTIBYTE (seq)) | ||
| 1660 | SET_STRING_BYTES (XSTRING (tem), -1); | ||
| 1661 | |||
| 1662 | for (i = nchars = nbytes = ibyte = 0; | ||
| 1663 | i < XSTRING (seq)->size; | ||
| 1664 | ++i, ibyte += cbytes) | ||
| 1665 | { | ||
| 1666 | if (STRING_MULTIBYTE (seq)) | ||
| 1667 | { | ||
| 1668 | c = STRING_CHAR (&XSTRING (seq)->data[ibyte], | ||
| 1669 | STRING_BYTES (XSTRING (seq)) - ibyte); | ||
| 1670 | cbytes = CHAR_BYTES (c); | ||
| 1671 | } | ||
| 1672 | else | ||
| 1673 | { | ||
| 1674 | c = XSTRING (seq)->data[i]; | ||
| 1675 | cbytes = 1; | ||
| 1676 | } | ||
| 1677 | |||
| 1678 | if (!INTEGERP (elt) || c != XINT (elt)) | ||
| 1679 | { | ||
| 1680 | unsigned char *from = &XSTRING (seq)->data[ibyte]; | ||
| 1681 | unsigned char *to = &XSTRING (tem)->data[nbytes]; | ||
| 1682 | EMACS_INT n; | ||
| 1683 | |||
| 1684 | ++nchars; | ||
| 1685 | nbytes += cbytes; | ||
| 1686 | |||
| 1687 | for (n = cbytes; n--; ) | ||
| 1688 | *to++ = *from++; | ||
| 1689 | } | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | seq = tem; | ||
| 1622 | } | 1693 | } |
| 1623 | else | ||
| 1624 | prev = tail; | ||
| 1625 | tail = XCDR (tail); | ||
| 1626 | QUIT; | ||
| 1627 | } | 1694 | } |
| 1628 | return list; | 1695 | else |
| 1696 | { | ||
| 1697 | Lisp_Object tail, prev; | ||
| 1698 | |||
| 1699 | for (tail = seq, prev = Qnil; !NILP (tail); tail = XCDR (tail)) | ||
| 1700 | { | ||
| 1701 | if (!CONSP (tail)) | ||
| 1702 | wrong_type_argument (Qlistp, seq); | ||
| 1703 | |||
| 1704 | if (!NILP (Fequal (elt, XCAR (tail)))) | ||
| 1705 | { | ||
| 1706 | if (NILP (prev)) | ||
| 1707 | seq = XCDR (tail); | ||
| 1708 | else | ||
| 1709 | Fsetcdr (prev, XCDR (tail)); | ||
| 1710 | } | ||
| 1711 | else | ||
| 1712 | prev = tail; | ||
| 1713 | QUIT; | ||
| 1714 | } | ||
| 1715 | } | ||
| 1716 | |||
| 1717 | return seq; | ||
| 1629 | } | 1718 | } |
| 1630 | 1719 | ||
| 1631 | DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0, | 1720 | DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0, |