Mercurial > hg > xemacs-beta
comparison src/data.c @ 5866:5ea790936de9
Automated merge with file:///Sources/xemacs-21.5-checked-out
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 16 Mar 2015 00:11:30 +0000 |
parents | 750fab17b299 |
children | e0f1dfaa821e |
comparison
equal
deleted
inserted
replaced
5863:15041705c196 | 5866:5ea790936de9 |
---|---|
29 #include "buffer.h" | 29 #include "buffer.h" |
30 #include "bytecode.h" | 30 #include "bytecode.h" |
31 #include "gc.h" | 31 #include "gc.h" |
32 #include "syssignal.h" | 32 #include "syssignal.h" |
33 #include "sysfloat.h" | 33 #include "sysfloat.h" |
34 #include "syntax.h" | |
34 | 35 |
35 Lisp_Object Qnil, Qt, Qlambda, Qunbound; | 36 Lisp_Object Qnil, Qt, Qlambda, Qunbound; |
36 Lisp_Object Qerror_conditions, Qerror_message; | 37 Lisp_Object Qerror_conditions, Qerror_message; |
37 Lisp_Object Qerror, Qquit, Qsyntax_error, Qinvalid_read_syntax; | 38 Lisp_Object Qerror, Qquit, Qsyntax_error, Qinvalid_read_syntax; |
38 Lisp_Object Qlist_formation_error, Qstructure_formation_error; | 39 Lisp_Object Qlist_formation_error, Qstructure_formation_error; |
63 Lisp_Object Qnumberp, Qnumber_char_or_marker_p; | 64 Lisp_Object Qnumberp, Qnumber_char_or_marker_p; |
64 Lisp_Object Qbit_vectorp, Qbitp, Qcdr; | 65 Lisp_Object Qbit_vectorp, Qbitp, Qcdr; |
65 | 66 |
66 Lisp_Object Qerror_lacks_explanatory_string; | 67 Lisp_Object Qerror_lacks_explanatory_string; |
67 Lisp_Object Qfloatp; | 68 Lisp_Object Qfloatp; |
69 Lisp_Object Q_junk_allowed, Q_radix, Q_radix_table; | |
70 | |
71 Lisp_Object Vdigit_fixnum_map, Vfixnum_to_char_map; | |
68 | 72 |
69 Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum; | 73 Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum; |
70 | 74 |
71 #ifdef DEBUG_XEMACS | 75 #ifdef DEBUG_XEMACS |
72 | 76 |
1430 } | 1434 } |
1431 return make_fixnum (negative * v); | 1435 return make_fixnum (negative * v); |
1432 } | 1436 } |
1433 #endif /* HAVE_BIGNUM */ | 1437 #endif /* HAVE_BIGNUM */ |
1434 } | 1438 } |
1439 | |
1440 static int | |
1441 find_highest_value (struct chartab_range * range, Lisp_Object UNUSED (table), | |
1442 Lisp_Object val, void *extra_arg) | |
1443 { | |
1444 Lisp_Object *highest_pointer = (Lisp_Object *) extra_arg; | |
1445 Lisp_Object max_seen = *highest_pointer; | |
1446 | |
1447 CHECK_FIXNUM (val); | |
1448 if (range->type != CHARTAB_RANGE_CHAR) | |
1449 { | |
1450 invalid_argument ("Not an appropriate char table range", Qunbound); | |
1451 } | |
1452 | |
1453 if (XFIXNUM (max_seen) < XFIXNUM (val)) | |
1454 { | |
1455 *highest_pointer = val; | |
1456 } | |
1457 | |
1458 return 0; | |
1459 } | |
1460 | |
1461 static int | |
1462 fill_ichar_array (struct chartab_range *range, Lisp_Object UNUSED (table), | |
1463 Lisp_Object val, void *extra_arg) | |
1464 { | |
1465 Ichar *cctable = (Ichar *) extra_arg; | |
1466 EMACS_INT valint = XFIXNUM (val); | |
1467 | |
1468 /* Save the value if it hasn't been seen yet. */ | |
1469 if (-1 == cctable[valint]) | |
1470 { | |
1471 cctable[valint] = range->ch; | |
1472 } | |
1473 else | |
1474 { | |
1475 /* Otherwise, save it if the existing value is not uppercase, and this | |
1476 one is. Use the standard case table rather than any buffer-specific | |
1477 one because a) this can be called early before current_buffer is | |
1478 available and b) it's better to have these independent of particular | |
1479 buffer case tables. */ | |
1480 if (current_buffer != NULL && UPCASE (0, range->ch) == range->ch | |
1481 && UPCASE (0, cctable[valint]) != cctable[valint]) | |
1482 { | |
1483 cctable[valint] = range->ch; | |
1484 } | |
1485 /* Maybe our own case infrastructure is not available yet. Use the C | |
1486 library's. */ | |
1487 else if (isupper (range->ch) && !isupper (cctable[valint])) | |
1488 { | |
1489 cctable[valint] = range->ch; | |
1490 } | |
1491 /* Otherwise, save it if this character has a numerically lower value | |
1492 (preferring ASCII over fullwidth Chinese and so on). */ | |
1493 else if (range->ch < cctable[valint]) | |
1494 { | |
1495 cctable[valint] = range->ch; | |
1496 } | |
1497 } | |
1498 | |
1499 return 0; | |
1500 } | |
1501 | |
1502 static Lisp_Object | |
1503 build_fixnum_to_char_map (Lisp_Object radix_table) | |
1504 { | |
1505 Lisp_Object highest_value, result; | |
1506 struct chartab_range ctr = { CHARTAB_RANGE_ALL, 0, Qnil, 0 }; | |
1507 Ichar *cctable; | |
1508 EMACS_INT ii, cclen; | |
1509 Ibyte *data; | |
1510 | |
1511 /* What's the greatest fixnum value seen? In passing, check all the char | |
1512 table values are fixnums. */ | |
1513 CHECK_FIXNUM (XCHAR_TABLE (radix_table)->default_); | |
1514 highest_value = XFIXNUM (XCHAR_TABLE (radix_table)->default_); | |
1515 map_char_table (radix_table, &ctr, find_highest_value, &highest_value); | |
1516 cclen = XFIXNUM (highest_value) + 1; | |
1517 | |
1518 cctable = malloc (sizeof (Ichar) * cclen); | |
1519 if (cctable == NULL) | |
1520 { | |
1521 out_of_memory ("Could not allocate data for `digit-char'", Qunbound); | |
1522 } | |
1523 | |
1524 for (ii = 0; ii < cclen; ++ii) | |
1525 { | |
1526 cctable[ii] = (Ichar) -1; | |
1527 } | |
1528 | |
1529 map_char_table (radix_table, &ctr, fill_ichar_array, cctable); | |
1530 | |
1531 for (ii = 0; ii < cclen; ++ii) | |
1532 { | |
1533 if (cctable[ii] < 0) | |
1534 { | |
1535 free (cctable); | |
1536 invalid_argument ("No digit specified for weight", make_fixnum (ii)); | |
1537 } | |
1538 } | |
1539 | |
1540 result = Fmake_string (make_fixnum (cclen * MAX_ICHAR_LEN), make_char (0)); | |
1541 | |
1542 data = XSTRING_DATA (result); | |
1543 for (ii = 0; ii < cclen; ii++) | |
1544 { | |
1545 set_itext_ichar (data + (MAX_ICHAR_LEN * ii), cctable[ii]); | |
1546 } | |
1547 | |
1548 init_string_ascii_begin (result); | |
1549 bump_string_modiff (result); | |
1550 sledgehammer_check_ascii_begin (result); | |
1551 | |
1552 free (cctable); | |
1553 | |
1554 return result; | |
1555 } | |
1556 | |
1557 DEFUN ("set-digit-fixnum-map", Fset_digit_fixnum_map, 1, 1, 0, /* | |
1558 Set the value of `digit-fixnum-map', which see. | |
1559 | |
1560 Also check that RADIX-TABLE is well-formed from the perspective of | |
1561 `parse-integer' and `digit-char-p', and create an internal inverse mapping | |
1562 for `digit-char', so that all three functions behave consistently. | |
1563 | |
1564 RADIX-TABLE itself is not saved, a read-only copy of it is made and returned. | |
1565 */ | |
1566 (radix_table)) | |
1567 { | |
1568 Lisp_Object ftctable = Qnil; | |
1569 | |
1570 CHECK_CHAR_TABLE (radix_table); | |
1571 | |
1572 /* Create a table for `digit-char', checking the consistency of | |
1573 radix_table while doing so. */ | |
1574 ftctable = build_fixnum_to_char_map (radix_table); | |
1575 | |
1576 Vdigit_fixnum_map = Fcopy_char_table (radix_table); | |
1577 LISP_READONLY (Vdigit_fixnum_map) = 1; | |
1578 Vfixnum_to_char_map = ftctable; | |
1579 | |
1580 return Vdigit_fixnum_map; | |
1581 } | |
1582 | |
1583 DEFUN ("digit-char-p", Fdigit_char_p, 1, 3, 0, /* | |
1584 Return non-nil if CHARACTER represents a digit in base RADIX. | |
1585 | |
1586 RADIX defaults to ten. The actual non-nil value returned is the integer | |
1587 value of the character in base RADIX. | |
1588 | |
1589 RADIX-TABLE, if non-nil, is a character table describing characters' numeric | |
1590 values. See `parse-integer' and `digit-fixnum-map'. | |
1591 */ | |
1592 (character, radix, radix_table)) | |
1593 { | |
1594 Lisp_Object got = Qnil; | |
1595 EMACS_INT radixing, val; | |
1596 Ichar cc; | |
1597 | |
1598 CHECK_CHAR (character); | |
1599 cc = XCHAR (character); | |
1600 | |
1601 if (!NILP (radix)) | |
1602 { | |
1603 check_integer_range (radix, Qzero, | |
1604 NILP (radix_table) ? | |
1605 /* If we are using the default radix table, the | |
1606 maximum possible value for the radix is | |
1607 available to us now. */ | |
1608 make_fixnum | |
1609 (XSTRING_LENGTH (Vfixnum_to_char_map) | |
1610 / MAX_ICHAR_LEN) | |
1611 /* Otherwise, calculating that is expensive. Check | |
1612 at least that the radix is not a bignum, the | |
1613 maximum count of characters available will not | |
1614 exceed the size of a fixnum. */ | |
1615 : make_fixnum (MOST_POSITIVE_FIXNUM)); | |
1616 radixing = XFIXNUM (radix); | |
1617 } | |
1618 else | |
1619 { | |
1620 radixing = 10; | |
1621 } | |
1622 | |
1623 if (NILP (radix_table)) | |
1624 { | |
1625 radix_table = Vdigit_fixnum_map; | |
1626 } | |
1627 | |
1628 got = get_char_table (cc, radix_table); | |
1629 CHECK_FIXNUM (got); | |
1630 val = XFIXNUM (got); | |
1631 | |
1632 if (val < 0 || val >= radixing) | |
1633 { | |
1634 return Qnil; | |
1635 } | |
1636 | |
1637 return make_fixnum (val); | |
1638 } | |
1639 | |
1640 DEFUN ("digit-char", Fdigit_char, 1, 3, 0, /* | |
1641 Return a character representing the integer WEIGHT in base RADIX. | |
1642 | |
1643 RADIX defaults to ten. If no such character exists, return nil. `digit-char' | |
1644 prefers an upper case character if available. RADIX must be a non-negative | |
1645 integer of value less than the maximum value in RADIX-TABLE. | |
1646 | |
1647 RADIX-TABLE, if non-nil, is a character table describing characters' numeric | |
1648 values. It defaults to the value of `digit-fixnum-map'; see the documentation | |
1649 for that variable and for `parse-integer'. This is not specified by Common | |
1650 Lisp, and using a value other than the default in `digit-char' is expensive, | |
1651 since the inverse map needs to be calculated. | |
1652 */ | |
1653 (weight, radix, radix_table)) | |
1654 { | |
1655 EMACS_INT radixing = 10, weighting; | |
1656 Lisp_Object fixnum_to_char_table = Qnil; | |
1657 Ichar cc; | |
1658 | |
1659 CHECK_NATNUM (weight); | |
1660 | |
1661 if (!NILP (radix_table) && !EQ (radix_table, Vdigit_fixnum_map)) | |
1662 { | |
1663 CHECK_CHAR_TABLE (radix_table); | |
1664 /* The result of this isn't GCPROd, but the rest of this function | |
1665 won't GC and continue. */ | |
1666 fixnum_to_char_table = build_fixnum_to_char_map (radix_table); | |
1667 } | |
1668 else | |
1669 { | |
1670 fixnum_to_char_table = Vfixnum_to_char_map; | |
1671 } | |
1672 | |
1673 if (!NILP (radix)) | |
1674 { | |
1675 check_integer_range (radix, Qzero, | |
1676 make_fixnum (XSTRING_LENGTH (fixnum_to_char_table) | |
1677 / MAX_ICHAR_LEN)); | |
1678 radixing = XFIXNUM (radix); | |
1679 } | |
1680 | |
1681 /* If weight is in its canonical form (and there's no reason to think it | |
1682 isn't), Vfixnum_to_char_map can't be long enough to handle | |
1683 this. */ | |
1684 if (BIGNUMP (weight)) | |
1685 { | |
1686 return Qnil; | |
1687 } | |
1688 | |
1689 weighting = XFIXNUM (weight); | |
1690 | |
1691 if (weighting < radixing) | |
1692 { | |
1693 cc = itext_ichar (XSTRING_DATA (fixnum_to_char_table) | |
1694 + MAX_ICHAR_LEN * weighting); | |
1695 return make_char (cc); | |
1696 } | |
1697 | |
1698 return Qnil; | |
1699 } | |
1700 | |
1701 Lisp_Object | |
1702 parse_integer (const Ibyte *buf, Ibyte **buf_end_out, Bytecount len, | |
1703 EMACS_INT base, Boolint junk_allowed, Lisp_Object radix_table) | |
1704 { | |
1705 const Ibyte *lim = buf + len, *p = buf; | |
1706 EMACS_UINT num = 0, onum = (EMACS_UINT) -1; | |
1707 EMACS_UINT fixnum_limit = MOST_POSITIVE_FIXNUM; | |
1708 EMACS_INT cint = 0; | |
1709 Boolint negativland = 0; | |
1710 Ichar c = -1; | |
1711 Lisp_Object result = Qnil, got = Qnil; | |
1712 | |
1713 if (NILP (radix_table)) | |
1714 { | |
1715 radix_table = Vdigit_fixnum_map; | |
1716 } | |
1717 | |
1718 /* This function ignores the current buffer's syntax table. | |
1719 Respecting it will probably introduce more bugs than it fixes. */ | |
1720 update_mirror_syntax_if_dirty (XCHAR_TABLE (Vstandard_syntax_table)-> | |
1721 mirror_table); | |
1722 | |
1723 /* Ignore leading whitespace, if that leading whitespace has no | |
1724 numeric value. */ | |
1725 while (p < lim) | |
1726 { | |
1727 c = itext_ichar (p); | |
1728 if (!(((got = get_char_table (c, radix_table), FIXNUMP (got)) | |
1729 && ((cint = XFIXNUM (got), cint < 0) || cint >= base)) | |
1730 && (SYNTAX (XCHAR_TABLE (Vstandard_syntax_table)->mirror_table, | |
1731 c) == Swhitespace))) | |
1732 { | |
1733 break; | |
1734 } | |
1735 | |
1736 INC_IBYTEPTR (p); | |
1737 } | |
1738 | |
1739 /* Drop sign information if appropriate. */ | |
1740 if (c == '-') | |
1741 { | |
1742 negativland = 1; | |
1743 fixnum_limit = - MOST_NEGATIVE_FIXNUM; | |
1744 INC_IBYTEPTR (p); | |
1745 } | |
1746 else if (c == '+') | |
1747 { | |
1748 got = get_char_table (c, radix_table); | |
1749 cint = FIXNUMP (got) ? XFIXNUM (got) : -1; | |
1750 /* If ?+ has no integer weight, drop it. */ | |
1751 if (cint < 0 || cint >= base) | |
1752 { | |
1753 INC_IBYTEPTR (p); | |
1754 } | |
1755 } | |
1756 | |
1757 while (p < lim) | |
1758 { | |
1759 c = itext_ichar (p); | |
1760 | |
1761 got = get_char_table (c, radix_table); | |
1762 if (!FIXNUMP (got)) | |
1763 { | |
1764 goto loser; | |
1765 } | |
1766 | |
1767 cint = XFIXNUM (got); | |
1768 | |
1769 if (cint < 0 || cint >= base) | |
1770 { | |
1771 goto loser; | |
1772 } | |
1773 | |
1774 onum = num; | |
1775 num *= base; | |
1776 if (num > fixnum_limit) | |
1777 { | |
1778 goto overflow; | |
1779 } | |
1780 | |
1781 num += cint; | |
1782 if (num > fixnum_limit) | |
1783 { | |
1784 goto overflow; | |
1785 } | |
1786 | |
1787 INC_IBYTEPTR (p); | |
1788 } | |
1789 | |
1790 if (onum == (EMACS_UINT) -1) | |
1791 { | |
1792 /* No digits seen, we may need to error. */ | |
1793 goto loser; | |
1794 } | |
1795 | |
1796 if (negativland) | |
1797 { | |
1798 result = make_fixnum (- (EMACS_INT) num); | |
1799 } | |
1800 else | |
1801 { | |
1802 result = make_fixnum (num); | |
1803 } | |
1804 | |
1805 *buf_end_out = (Ibyte *) p; | |
1806 return result; | |
1807 | |
1808 overflow: | |
1809 #ifndef HAVE_BIGNUM | |
1810 return Fsignal (Qinvalid_argument, | |
1811 list3 (build_msg_string ("Integer constant overflow"), | |
1812 make_string (buf, len), make_fixnum (base))); | |
1813 | |
1814 #else /* HAVE_BIGNUM */ | |
1815 result = make_bignum_emacs_uint (onum); | |
1816 | |
1817 bignum_set_emacs_int (scratch_bignum, base); | |
1818 bignum_set_emacs_int (scratch_bignum2, cint); | |
1819 bignum_mul (XBIGNUM_DATA (result), XBIGNUM_DATA (result), scratch_bignum); | |
1820 bignum_add (XBIGNUM_DATA (result), XBIGNUM_DATA (result), scratch_bignum2); | |
1821 INC_IBYTEPTR (p); | |
1822 | |
1823 assert (!bignum_fits_emacs_int_p (XBIGNUM_DATA (result)) | |
1824 || (fixnum_limit | |
1825 < (EMACS_UINT) bignum_to_emacs_int (XBIGNUM_DATA (result)))); | |
1826 | |
1827 while (p < lim) | |
1828 { | |
1829 c = itext_ichar (p); | |
1830 | |
1831 got = get_char_table (c, radix_table); | |
1832 if (!FIXNUMP (got)) | |
1833 { | |
1834 goto loser; | |
1835 } | |
1836 | |
1837 cint = XFIXNUM (got); | |
1838 if (cint < 0 || cint >= base) | |
1839 { | |
1840 goto loser; | |
1841 } | |
1842 | |
1843 bignum_set_emacs_int (scratch_bignum2, cint); | |
1844 bignum_mul (XBIGNUM_DATA (result), XBIGNUM_DATA (result), | |
1845 scratch_bignum); | |
1846 bignum_add (XBIGNUM_DATA (result), XBIGNUM_DATA (result), | |
1847 scratch_bignum2); | |
1848 | |
1849 INC_IBYTEPTR (p); | |
1850 } | |
1851 | |
1852 if (negativland) | |
1853 { | |
1854 bignum_set_long (scratch_bignum, -1L); | |
1855 bignum_mul (XBIGNUM_DATA (result), XBIGNUM_DATA (result), | |
1856 scratch_bignum); | |
1857 } | |
1858 | |
1859 *buf_end_out = (Ibyte *) p; | |
1860 return result; | |
1861 #endif /* HAVE_BIGNUM */ | |
1862 loser: | |
1863 | |
1864 if (p < lim && !junk_allowed) | |
1865 { | |
1866 /* JUNK-ALLOWED is zero. If we have stopped parsing because we | |
1867 encountered whitespace, then we need to check that the rest if the | |
1868 string is whitespace and whitespace alone if we are not to error. | |
1869 | |
1870 Perhaps surprisingly, if JUNK-ALLOWED is zero, the parse is regarded | |
1871 as including the trailing whitespace, so the second value returned is | |
1872 always the length of the string. */ | |
1873 while (p < lim) | |
1874 { | |
1875 c = itext_ichar (p); | |
1876 if (!(SYNTAX (XCHAR_TABLE (Vstandard_syntax_table)->mirror_table, c) | |
1877 == Swhitespace)) | |
1878 { | |
1879 break; | |
1880 } | |
1881 | |
1882 INC_IBYTEPTR (p); | |
1883 } | |
1884 } | |
1885 | |
1886 *buf_end_out = (Ibyte *) p; | |
1887 | |
1888 if (junk_allowed || (p == lim && onum != (EMACS_UINT) -1)) | |
1889 { | |
1890 | |
1891 #ifdef HAVE_BIGNUM | |
1892 if (!NILP (result)) | |
1893 { | |
1894 /* Bignum terminated by whitespace or by non-digit. */ | |
1895 return Fcanonicalize_number (result); | |
1896 } | |
1897 #endif | |
1898 | |
1899 if (onum == (EMACS_UINT) -1) | |
1900 { | |
1901 /* No integer digits seen, but junk allowed, so no indication to | |
1902 error. Return nil. */ | |
1903 return Qnil; | |
1904 } | |
1905 | |
1906 if (negativland) | |
1907 { | |
1908 assert ((- (EMACS_INT) num) >= MOST_NEGATIVE_FIXNUM); | |
1909 result = make_fixnum (- (EMACS_INT) num); | |
1910 } | |
1911 else | |
1912 { | |
1913 assert ((EMACS_INT) num <= MOST_POSITIVE_FIXNUM); | |
1914 result = make_fixnum (num); | |
1915 } | |
1916 | |
1917 return result; | |
1918 } | |
1919 | |
1920 return Fsignal (Qinvalid_argument, | |
1921 list3 (build_msg_string ("Invalid integer syntax"), | |
1922 make_string (buf, len), make_fixnum (base))); | |
1923 } | |
1924 | |
1925 DEFUN ("parse-integer", Fparse_integer, 1, MANY, 0, /* | |
1926 Parse and return the integer represented by STRING using RADIX. | |
1927 | |
1928 START and END are bounding index designators, as used in `remove*'. START | |
1929 defaults to 0 and END defaults to nil, meaning the end of STRING. | |
1930 | |
1931 If JUNK-ALLOWED is nil, error if STRING does not consist in its entirety of | |
1932 the representation of an integer, with or without surrounding whitespace | |
1933 characters. | |
1934 | |
1935 If RADIX-TABLE is non-nil, it is a char table mapping from characters to | |
1936 fixnums used with RADIX. Otherwise, `digit-fixnum-map' provides the | |
1937 correspondence to use. | |
1938 | |
1939 RADIX must always be a non-negative fixnum. RADIX-TABLE constrains its | |
1940 possible values further, and the maximum RADIX available is always the largest | |
1941 positive value available RADIX-TABLE. | |
1942 | |
1943 arguments: (STRING &key (START 0) end (RADIX 10) junk-allowed radix-table) | |
1944 */ | |
1945 (int nargs, Lisp_Object *args)) | |
1946 { | |
1947 Lisp_Object string = args[0], result; | |
1948 Charcount starting = 0, ending = MOST_POSITIVE_FIXNUM + 1, ii = 0; | |
1949 Bytecount byte_len; | |
1950 Ibyte *startp, *cursor, *end_read, *limit, *saved_start; | |
1951 EMACS_INT radixing; | |
1952 | |
1953 PARSE_KEYWORDS (Fparse_integer, nargs, args, 5, | |
1954 (start, end, radix, junk_allowed, radix_table), | |
1955 (start = Qzero, radix = make_fixnum (10))); | |
1956 | |
1957 CHECK_STRING (string); | |
1958 CHECK_NATNUM (start); | |
1959 starting = BIGNUMP (start) ? 1 + MOST_POSITIVE_FIXNUM : XFIXNUM (start); | |
1960 if (!NILP (end)) | |
1961 { | |
1962 CHECK_NATNUM (end); | |
1963 ending = BIGNUMP (end) ? 1 + MOST_POSITIVE_FIXNUM : XFIXNUM (end); | |
1964 } | |
1965 | |
1966 if (!NILP (radix_table)) | |
1967 { | |
1968 CHECK_CHAR_TABLE (radix_table); | |
1969 } | |
1970 else | |
1971 { | |
1972 radix_table = Vdigit_fixnum_map; | |
1973 } | |
1974 | |
1975 check_integer_range (radix, Qzero, | |
1976 EQ (radix_table, Vdigit_fixnum_map) ? | |
1977 make_fixnum (XSTRING_LENGTH (Vfixnum_to_char_map) | |
1978 / MAX_ICHAR_LEN) | |
1979 /* Non-default radix table; calculating the upper limit | |
1980 is is expensive. Check at least that the radix is | |
1981 not a bignum, the maximum count of characters | |
1982 available in our XEmacs will not exceed the size of | |
1983 a fixnum. */ | |
1984 : make_fixnum (MOST_POSITIVE_FIXNUM)); | |
1985 radixing = XFIXNUM (radix); | |
1986 | |
1987 startp = cursor = saved_start = XSTRING_DATA (string); | |
1988 byte_len = XSTRING_LENGTH (string); | |
1989 limit = startp + byte_len; | |
1990 | |
1991 while (cursor < limit && ii < ending) | |
1992 { | |
1993 INC_IBYTEPTR (cursor); | |
1994 if (ii < starting) | |
1995 { | |
1996 startp = cursor; | |
1997 } | |
1998 ii++; | |
1999 } | |
2000 | |
2001 if (ii < starting || (ii < ending && !NILP (end))) | |
2002 { | |
2003 check_sequence_range (string, start, end, Flength (string)); | |
2004 } | |
2005 | |
2006 result = parse_integer (startp, &end_read, cursor - startp, radixing, | |
2007 !NILP (junk_allowed), radix_table); | |
2008 | |
2009 /* This code hasn't been written to handle relocating string data. */ | |
2010 assert (saved_start == XSTRING_DATA (string)); | |
2011 | |
2012 return values2 (result, make_fixnum (string_index_byte_to_char | |
2013 (string, end_read - saved_start))); | |
2014 } | |
1435 | 2015 |
1436 | |
1437 DEFUN ("+", Fplus, 0, MANY, 0, /* | 2016 DEFUN ("+", Fplus, 0, MANY, 0, /* |
1438 Return sum of any number of arguments. | 2017 Return sum of any number of arguments. |
1439 The arguments should all be numbers, characters or markers. | 2018 The arguments should all be numbers, characters or markers. |
1440 | 2019 |
1441 arguments: (&rest ARGS) | 2020 arguments: (&rest ARGS) |
3536 DEFSYMBOL (Qnumber_char_or_marker_p); | 4115 DEFSYMBOL (Qnumber_char_or_marker_p); |
3537 DEFSYMBOL (Qcdr); | 4116 DEFSYMBOL (Qcdr); |
3538 DEFSYMBOL (Qerror_lacks_explanatory_string); | 4117 DEFSYMBOL (Qerror_lacks_explanatory_string); |
3539 DEFSYMBOL_MULTIWORD_PREDICATE (Qweak_listp); | 4118 DEFSYMBOL_MULTIWORD_PREDICATE (Qweak_listp); |
3540 DEFSYMBOL (Qfloatp); | 4119 DEFSYMBOL (Qfloatp); |
4120 | |
4121 DEFKEYWORD (Q_radix); | |
4122 DEFKEYWORD (Q_junk_allowed); | |
4123 DEFKEYWORD (Q_radix_table); | |
3541 | 4124 |
3542 DEFSUBR (Fwrong_type_argument); | 4125 DEFSUBR (Fwrong_type_argument); |
3543 | 4126 |
3544 #ifdef HAVE_RATIO | 4127 #ifdef HAVE_RATIO |
3545 DEFSUBR (Fdiv); | 4128 DEFSUBR (Fdiv); |
3593 DEFSUBR (Faref); | 4176 DEFSUBR (Faref); |
3594 DEFSUBR (Faset); | 4177 DEFSUBR (Faset); |
3595 | 4178 |
3596 DEFSUBR (Fnumber_to_string); | 4179 DEFSUBR (Fnumber_to_string); |
3597 DEFSUBR (Fstring_to_number); | 4180 DEFSUBR (Fstring_to_number); |
4181 DEFSUBR (Fset_digit_fixnum_map); | |
4182 DEFSUBR (Fdigit_char_p); | |
4183 DEFSUBR (Fdigit_char); | |
4184 DEFSUBR (Fparse_integer); | |
3598 DEFSUBR (Feqlsign); | 4185 DEFSUBR (Feqlsign); |
3599 DEFSUBR (Flss); | 4186 DEFSUBR (Flss); |
3600 DEFSUBR (Fgtr); | 4187 DEFSUBR (Fgtr); |
3601 DEFSUBR (Fleq); | 4188 DEFSUBR (Fleq); |
3602 DEFSUBR (Fgeq); | 4189 DEFSUBR (Fgeq); |
3657 DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /* | 4244 DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /* |
3658 The fixnum closest in value to positive infinity. | 4245 The fixnum closest in value to positive infinity. |
3659 */); | 4246 */); |
3660 Vmost_positive_fixnum = MOST_POSITIVE_FIXNUM; | 4247 Vmost_positive_fixnum = MOST_POSITIVE_FIXNUM; |
3661 | 4248 |
4249 DEFVAR_CONST_LISP ("digit-fixnum-map", &Vdigit_fixnum_map /* | |
4250 Table used to determine a character's numeric value when parsing. | |
4251 | |
4252 This is a character table with fixnum values. A value of -1 indicates this | |
4253 character does not have an assigned numeric value. See `parse-integer', | |
4254 `digit-char-p', and `digit-char'. | |
4255 */); | |
4256 Vdigit_fixnum_map = Fmake_char_table (Qgeneric); | |
4257 set_char_table_default (Vdigit_fixnum_map, make_fixnum (-1)); | |
4258 { | |
4259 int ii = 0; | |
4260 | |
4261 for (ii = 0; ii < 10; ++ii) | |
4262 { | |
4263 XCHAR_TABLE (Vdigit_fixnum_map)->ascii['0' + ii] = make_fixnum(ii); | |
4264 } | |
4265 | |
4266 for (ii = 10; ii < 36; ++ii) | |
4267 { | |
4268 XCHAR_TABLE (Vdigit_fixnum_map)->ascii['a' + (ii - 10)] | |
4269 = make_fixnum(ii); | |
4270 XCHAR_TABLE (Vdigit_fixnum_map)->ascii['A' + (ii - 10)] | |
4271 = make_fixnum(ii); | |
4272 } | |
4273 } | |
4274 { | |
4275 Ascbyte *fixnum_tab = alloca_ascbytes (36 * MAX_ICHAR_LEN), *ptr; | |
4276 int ii; | |
4277 Ichar cc; | |
4278 memset ((void *)fixnum_tab, 0, 36 * MAX_ICHAR_LEN); | |
4279 | |
4280 /* The whole point of fixnum_to_character_table is access as an array, | |
4281 avoid O(N) issues by giving every character MAX_ICHAR_LEN of | |
4282 bytes. */ | |
4283 for (ii = 0, ptr = fixnum_tab; ii < 36; ++ii, ptr += MAX_ICHAR_LEN) | |
4284 { | |
4285 cc = ii < 10 ? '0' + ii : 'A' + (ii - 10); | |
4286 set_itext_ichar ((Ibyte *) ptr, cc); | |
4287 } | |
4288 | |
4289 /* Sigh, we can't call build_fixnum_to_char_map() on Vdigit_fixnum_map, | |
4290 this is too early in the boot sequence to map across a char table. Do | |
4291 it by hand. */ | |
4292 Vfixnum_to_char_map = build_ascstring (fixnum_tab); | |
4293 staticpro (&Vfixnum_to_char_map); | |
4294 } | |
4295 | |
3662 #ifdef DEBUG_XEMACS | 4296 #ifdef DEBUG_XEMACS |
3663 DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /* | 4297 DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /* |
3664 If non-zero, note when your code may be suffering from char-int confoundance. | 4298 If non-zero, note when your code may be suffering from char-int confoundance. |
3665 That is to say, if XEmacs encounters a usage of `eq', `memq', `equal', | 4299 That is to say, if XEmacs encounters a usage of `eq', `memq', `equal', |
3666 etc. where an int and a char with the same value are being compared, | 4300 etc. where an int and a char with the same value are being compared, |