diff options
| author | Kenichi Handa | 1999-07-26 11:56:28 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1999-07-26 11:56:28 +0000 |
| commit | 5232fa7b78a4a7bcce1c23b449d992ba7e34586e (patch) | |
| tree | 82e6f8a77e4dd2bbccb607def68ca9e2857ca5b5 /src | |
| parent | e5e6d6fbaf49a42731abdcfb7e777e20ab8e8c0c (diff) | |
| download | emacs-5232fa7b78a4a7bcce1c23b449d992ba7e34586e.tar.gz emacs-5232fa7b78a4a7bcce1c23b449d992ba7e34586e.zip | |
(ccl_driver) <CCL_Call>: Now CCL program ID to call may be
stored in the following CCL code. Adjusted for the change of
Vccl_program_table.
(resolve_symbol_ccl_program): Adjusted for the new style of
embedded symbols (SYMBOL . PROP) in CCL compiled code. Return Qt
is resolving failed.
(ccl_get_compiled_code): New function.
(setup_ccl_program): Function type changed from `void' to `int'.
Resolve symbols in CCL_PROG.
(Fccl_program_p): New function.
(Fccl_execute): Get compiled CCL code by just calling
setup_ccl_program.
(Fccl_execute_on_string): Likewise.
(Fregister_ccl_program): Adjusted for the change of
Vccl_program_table.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ccl.c | 340 |
1 files changed, 227 insertions, 113 deletions
| @@ -59,7 +59,11 @@ Lisp_Object Qcode_conversion_map_id; | |||
| 59 | is an index for Vccl_protram_table. */ | 59 | is an index for Vccl_protram_table. */ |
| 60 | Lisp_Object Qccl_program_idx; | 60 | Lisp_Object Qccl_program_idx; |
| 61 | 61 | ||
| 62 | /* Vector of CCL program names vs corresponding program data. */ | 62 | /* Table of registered CCL programs. Each element is a vector of |
| 63 | NAME, CCL_PROG, and RESOLVEDP where NAME (symbol) is the name of | ||
| 64 | the program, CCL_PROG (vector) is the compiled code of the program, | ||
| 65 | RESOLVEDP (t or nil) is the flag to tell if symbols in CCL_PROG is | ||
| 66 | already resolved to index numbers or not. */ | ||
| 63 | Lisp_Object Vccl_program_table; | 67 | Lisp_Object Vccl_program_table; |
| 64 | 68 | ||
| 65 | /* CCL (Code Conversion Language) is a simple language which has | 69 | /* CCL (Code Conversion Language) is a simple language which has |
| @@ -291,10 +295,15 @@ Lisp_Object Vccl_program_table; | |||
| 291 | */ | 295 | */ |
| 292 | 296 | ||
| 293 | #define CCL_Call 0x13 /* Call the CCL program whose ID is | 297 | #define CCL_Call 0x13 /* Call the CCL program whose ID is |
| 294 | (CC..C). | 298 | CC..C or cc..c. |
| 295 | 1:CCCCCCCCCCCCCCCCCCCC000XXXXX | 299 | 1:CCCCCCCCCCCCCCCCCCCCFFFXXXXX |
| 300 | [2:00000000cccccccccccccccccccc] | ||
| 296 | ------------------------------ | 301 | ------------------------------ |
| 297 | call (CC..C) | 302 | if (FFF) |
| 303 | call (cc..c) | ||
| 304 | IC++; | ||
| 305 | else | ||
| 306 | call (CC..C) | ||
| 298 | */ | 307 | */ |
| 299 | 308 | ||
| 300 | #define CCL_WriteConstString 0x14 /* Write a constant or a string: | 309 | #define CCL_WriteConstString 0x14 /* Write a constant or a string: |
| @@ -924,16 +933,27 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed) | |||
| 924 | op = field1 >> 6; | 933 | op = field1 >> 6; |
| 925 | goto ccl_set_expr; | 934 | goto ccl_set_expr; |
| 926 | 935 | ||
| 927 | case CCL_Call: /* CCCCCCCCCCCCCCCCCCCC000XXXXX */ | 936 | case CCL_Call: /* 1:CCCCCCCCCCCCCCCCCCCCFFFXXXXX */ |
| 928 | { | 937 | { |
| 929 | Lisp_Object slot; | 938 | Lisp_Object slot; |
| 939 | int prog_id; | ||
| 940 | |||
| 941 | /* If FFF is nonzero, the CCL program ID is in the | ||
| 942 | following code. */ | ||
| 943 | if (rrr) | ||
| 944 | { | ||
| 945 | prog_id = XINT (ccl_prog[ic]); | ||
| 946 | ic++; | ||
| 947 | } | ||
| 948 | else | ||
| 949 | prog_id = field1; | ||
| 930 | 950 | ||
| 931 | if (stack_idx >= 256 | 951 | if (stack_idx >= 256 |
| 932 | || field1 < 0 | 952 | || prog_id < 0 |
| 933 | || field1 >= XVECTOR (Vccl_program_table)->size | 953 | || prog_id >= XVECTOR (Vccl_program_table)->size |
| 934 | || (slot = XVECTOR (Vccl_program_table)->contents[field1], | 954 | || (slot = XVECTOR (Vccl_program_table)->contents[prog_id], |
| 935 | !CONSP (slot)) | 955 | !VECTORP (slot)) |
| 936 | || !VECTORP (XCONS (slot)->cdr)) | 956 | || !VECTORP (XVECTOR (slot)->contents[1])) |
| 937 | { | 957 | { |
| 938 | if (stack_idx > 0) | 958 | if (stack_idx > 0) |
| 939 | { | 959 | { |
| @@ -946,7 +966,7 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed) | |||
| 946 | ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; | 966 | ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; |
| 947 | ccl_prog_stack_struct[stack_idx].ic = ic; | 967 | ccl_prog_stack_struct[stack_idx].ic = ic; |
| 948 | stack_idx++; | 968 | stack_idx++; |
| 949 | ccl_prog = XVECTOR (XCONS (slot)->cdr)->contents; | 969 | ccl_prog = XVECTOR (XVECTOR (slot)->contents[1])->contents; |
| 950 | ic = CCL_HEADER_MAIN; | 970 | ic = CCL_HEADER_MAIN; |
| 951 | } | 971 | } |
| 952 | break; | 972 | break; |
| @@ -1619,20 +1639,141 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed) | |||
| 1619 | return (dst ? dst - destination : 0); | 1639 | return (dst ? dst - destination : 0); |
| 1620 | } | 1640 | } |
| 1621 | 1641 | ||
| 1642 | /* Resolve symbols in the specified CCL code (Lisp vector). This | ||
| 1643 | function converts symbols of code conversion maps and character | ||
| 1644 | translation tables embeded in the CCL code into their ID numbers. | ||
| 1645 | |||
| 1646 | The return value is a vector (CCL itself or a new vector in which | ||
| 1647 | all symbols are resolved), Qt if resolving of some symbol failed, | ||
| 1648 | or nil if CCL contains invalid data. */ | ||
| 1649 | |||
| 1650 | static Lisp_Object | ||
| 1651 | resolve_symbol_ccl_program (ccl) | ||
| 1652 | Lisp_Object ccl; | ||
| 1653 | { | ||
| 1654 | int i, veclen, unresolved = 0; | ||
| 1655 | Lisp_Object result, contents, val; | ||
| 1656 | |||
| 1657 | result = ccl; | ||
| 1658 | veclen = XVECTOR (result)->size; | ||
| 1659 | |||
| 1660 | for (i = 0; i < veclen; i++) | ||
| 1661 | { | ||
| 1662 | contents = XVECTOR (result)->contents[i]; | ||
| 1663 | if (INTEGERP (contents)) | ||
| 1664 | continue; | ||
| 1665 | else if (CONSP (contents) | ||
| 1666 | && SYMBOLP (XCONS (contents)->car) | ||
| 1667 | && SYMBOLP (XCONS (contents)->cdr)) | ||
| 1668 | { | ||
| 1669 | /* This is the new style for embedding symbols. The form is | ||
| 1670 | (SYMBOL . PROPERTY). (get SYMBOL PROPERTY) should give | ||
| 1671 | an index number. */ | ||
| 1672 | |||
| 1673 | if (EQ (result, ccl)) | ||
| 1674 | result = Fcopy_sequence (ccl); | ||
| 1675 | |||
| 1676 | val = Fget (XCONS (contents)->car, XCONS (contents)->cdr); | ||
| 1677 | if (NATNUMP (val)) | ||
| 1678 | XVECTOR (result)->contents[i] = val; | ||
| 1679 | else | ||
| 1680 | unresolved = 1; | ||
| 1681 | continue; | ||
| 1682 | } | ||
| 1683 | else if (SYMBOLP (contents)) | ||
| 1684 | { | ||
| 1685 | /* This is the old style for embedding symbols. This style | ||
| 1686 | may lead to a bug if, for instance, a translation table | ||
| 1687 | and a code conversion map have the same name. */ | ||
| 1688 | if (EQ (result, ccl)) | ||
| 1689 | result = Fcopy_sequence (ccl); | ||
| 1690 | |||
| 1691 | val = Fget (contents, Qtranslation_table_id); | ||
| 1692 | if (NATNUMP (val)) | ||
| 1693 | XVECTOR (result)->contents[i] = val; | ||
| 1694 | else | ||
| 1695 | { | ||
| 1696 | val = Fget (contents, Qcode_conversion_map_id); | ||
| 1697 | if (NATNUMP (val)) | ||
| 1698 | XVECTOR (result)->contents[i] = val; | ||
| 1699 | else | ||
| 1700 | { | ||
| 1701 | val = Fget (contents, Qccl_program_idx); | ||
| 1702 | if (NATNUMP (val)) | ||
| 1703 | XVECTOR (result)->contents[i] = val; | ||
| 1704 | else | ||
| 1705 | unresolved = 1; | ||
| 1706 | } | ||
| 1707 | } | ||
| 1708 | continue; | ||
| 1709 | } | ||
| 1710 | return Qnil; | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | return (unresolved ? Qt : result); | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | /* Return the compiled code (vector) of CCL program CCL_PROG. | ||
| 1717 | CCL_PROG is a name (symbol) of the program or already compiled | ||
| 1718 | code. If necessary, resolve symbols in the compiled code to index | ||
| 1719 | numbers. If we failed to get the compiled code or to resolve | ||
| 1720 | symbols, return Qnil. */ | ||
| 1721 | |||
| 1722 | static Lisp_Object | ||
| 1723 | ccl_get_compiled_code (ccl_prog) | ||
| 1724 | Lisp_Object ccl_prog; | ||
| 1725 | { | ||
| 1726 | Lisp_Object val, slot; | ||
| 1727 | |||
| 1728 | if (VECTORP (ccl_prog)) | ||
| 1729 | { | ||
| 1730 | val = resolve_symbol_ccl_program (ccl_prog); | ||
| 1731 | return (VECTORP (val) ? val : Qnil); | ||
| 1732 | } | ||
| 1733 | if (!SYMBOLP (ccl_prog)) | ||
| 1734 | return Qnil; | ||
| 1735 | |||
| 1736 | val = Fget (ccl_prog, Qccl_program_idx); | ||
| 1737 | if (! NATNUMP (val) | ||
| 1738 | || XINT (val) >= XVECTOR (Vccl_program_table)->size) | ||
| 1739 | return Qnil; | ||
| 1740 | slot = XVECTOR (Vccl_program_table)->contents[XINT (val)]; | ||
| 1741 | if (! VECTORP (slot) | ||
| 1742 | || XVECTOR (slot)->size != 3 | ||
| 1743 | || ! VECTORP (XVECTOR (slot)->contents[1])) | ||
| 1744 | return Qnil; | ||
| 1745 | if (NILP (XVECTOR (slot)->contents[2])) | ||
| 1746 | { | ||
| 1747 | val = resolve_symbol_ccl_program (XVECTOR (slot)->contents[1]); | ||
| 1748 | if (! VECTORP (val)) | ||
| 1749 | return Qnil; | ||
| 1750 | XVECTOR (slot)->contents[1] = val; | ||
| 1751 | XVECTOR (slot)->contents[2] = Qt; | ||
| 1752 | } | ||
| 1753 | return XVECTOR (slot)->contents[1]; | ||
| 1754 | } | ||
| 1755 | |||
| 1622 | /* Setup fields of the structure pointed by CCL appropriately for the | 1756 | /* Setup fields of the structure pointed by CCL appropriately for the |
| 1623 | execution of compiled CCL code in VEC (vector of integer). | 1757 | execution of CCL program CCL_PROG. CCL_PROG is the name (symbol) |
| 1624 | If VEC is nil, we skip setting ups based on VEC. */ | 1758 | of the CCL program or the already compiled code (vector). |
| 1625 | void | 1759 | Return 0 if we succeed this setup, else return -1. |
| 1626 | setup_ccl_program (ccl, vec) | 1760 | |
| 1761 | If CCL_PROG is nil, we just reset the structure pointed by CCL. */ | ||
| 1762 | int | ||
| 1763 | setup_ccl_program (ccl, ccl_prog) | ||
| 1627 | struct ccl_program *ccl; | 1764 | struct ccl_program *ccl; |
| 1628 | Lisp_Object vec; | 1765 | Lisp_Object ccl_prog; |
| 1629 | { | 1766 | { |
| 1630 | int i; | 1767 | int i; |
| 1631 | 1768 | ||
| 1632 | if (VECTORP (vec)) | 1769 | if (! NILP (ccl_prog)) |
| 1633 | { | 1770 | { |
| 1634 | struct Lisp_Vector *vp = XVECTOR (vec); | 1771 | struct Lisp_Vector *vp; |
| 1635 | 1772 | ||
| 1773 | ccl_prog = ccl_get_compiled_code (ccl_prog); | ||
| 1774 | if (! VECTORP (ccl_prog)) | ||
| 1775 | return -1; | ||
| 1776 | vp = XVECTOR (ccl_prog); | ||
| 1636 | ccl->size = vp->size; | 1777 | ccl->size = vp->size; |
| 1637 | ccl->prog = vp->contents; | 1778 | ccl->prog = vp->contents; |
| 1638 | ccl->eof_ic = XINT (vp->contents[CCL_HEADER_EOF]); | 1779 | ccl->eof_ic = XINT (vp->contents[CCL_HEADER_EOF]); |
| @@ -1645,64 +1786,38 @@ setup_ccl_program (ccl, vec) | |||
| 1645 | ccl->private_state = 0; | 1786 | ccl->private_state = 0; |
| 1646 | ccl->status = 0; | 1787 | ccl->status = 0; |
| 1647 | ccl->stack_idx = 0; | 1788 | ccl->stack_idx = 0; |
| 1789 | return 0; | ||
| 1648 | } | 1790 | } |
| 1649 | 1791 | ||
| 1650 | /* Resolve symbols in the specified CCL code (Lisp vector). This | 1792 | #ifdef emacs |
| 1651 | function converts symbols of code conversion maps and character | ||
| 1652 | translation tables embeded in the CCL code into their ID numbers. */ | ||
| 1653 | 1793 | ||
| 1654 | Lisp_Object | 1794 | DEFUN ("ccl-program-p", Fccl_program_p, Sccl_program_p, 1, 1, 0, |
| 1655 | resolve_symbol_ccl_program (ccl) | 1795 | "Return t if OBJECT is a CCL program name or a compiled CCL program code.") |
| 1656 | Lisp_Object ccl; | 1796 | (object) |
| 1797 | Lisp_Object object; | ||
| 1657 | { | 1798 | { |
| 1658 | int i, veclen; | 1799 | Lisp_Object val; |
| 1659 | Lisp_Object result, contents, prop; | ||
| 1660 | |||
| 1661 | result = ccl; | ||
| 1662 | veclen = XVECTOR (result)->size; | ||
| 1663 | 1800 | ||
| 1664 | /* Set CCL program's table ID */ | 1801 | if (VECTORP (object)) |
| 1665 | for (i = 0; i < veclen; i++) | ||
| 1666 | { | 1802 | { |
| 1667 | contents = XVECTOR (result)->contents[i]; | 1803 | val = resolve_symbol_ccl_program (object); |
| 1668 | if (SYMBOLP (contents)) | 1804 | return (VECTORP (val) ? Qt : Qnil); |
| 1669 | { | ||
| 1670 | if (EQ(result, ccl)) | ||
| 1671 | result = Fcopy_sequence (ccl); | ||
| 1672 | |||
| 1673 | prop = Fget (contents, Qtranslation_table_id); | ||
| 1674 | if (NUMBERP (prop)) | ||
| 1675 | { | ||
| 1676 | XVECTOR (result)->contents[i] = prop; | ||
| 1677 | continue; | ||
| 1678 | } | ||
| 1679 | prop = Fget (contents, Qcode_conversion_map_id); | ||
| 1680 | if (NUMBERP (prop)) | ||
| 1681 | { | ||
| 1682 | XVECTOR (result)->contents[i] = prop; | ||
| 1683 | continue; | ||
| 1684 | } | ||
| 1685 | prop = Fget (contents, Qccl_program_idx); | ||
| 1686 | if (NUMBERP (prop)) | ||
| 1687 | { | ||
| 1688 | XVECTOR (result)->contents[i] = prop; | ||
| 1689 | continue; | ||
| 1690 | } | ||
| 1691 | } | ||
| 1692 | } | 1805 | } |
| 1806 | if (!SYMBOLP (object)) | ||
| 1807 | return Qnil; | ||
| 1693 | 1808 | ||
| 1694 | return result; | 1809 | val = Fget (object, Qccl_program_idx); |
| 1810 | return ((! NATNUMP (val) | ||
| 1811 | || XINT (val) >= XVECTOR (Vccl_program_table)->size) | ||
| 1812 | ? Qnil : Qt); | ||
| 1695 | } | 1813 | } |
| 1696 | 1814 | ||
| 1697 | |||
| 1698 | #ifdef emacs | ||
| 1699 | |||
| 1700 | DEFUN ("ccl-execute", Fccl_execute, Sccl_execute, 2, 2, 0, | 1815 | DEFUN ("ccl-execute", Fccl_execute, Sccl_execute, 2, 2, 0, |
| 1701 | "Execute CCL-PROGRAM with registers initialized by REGISTERS.\n\ | 1816 | "Execute CCL-PROGRAM with registers initialized by REGISTERS.\n\ |
| 1702 | \n\ | 1817 | \n\ |
| 1703 | CCL-PROGRAM is a symbol registered by register-ccl-program,\n\ | 1818 | CCL-PROGRAM is a CCL program name (symbol)\n\ |
| 1704 | or a compiled code generated by `ccl-compile' (for backward compatibility,\n\ | 1819 | or a compiled code generated by `ccl-compile' (for backward compatibility,\n\ |
| 1705 | in this case, the execution is slower).\n\ | 1820 | in this case, the overhead of the execution is bigger than the former case).\n\ |
| 1706 | No I/O commands should appear in CCL-PROGRAM.\n\ | 1821 | No I/O commands should appear in CCL-PROGRAM.\n\ |
| 1707 | \n\ | 1822 | \n\ |
| 1708 | REGISTERS is a vector of [R0 R1 ... R7] where RN is an initial value\n\ | 1823 | REGISTERS is a vector of [R0 R1 ... R7] where RN is an initial value\n\ |
| @@ -1715,27 +1830,14 @@ As side effect, each element of REGISTERS holds the value of\n\ | |||
| 1715 | { | 1830 | { |
| 1716 | struct ccl_program ccl; | 1831 | struct ccl_program ccl; |
| 1717 | int i; | 1832 | int i; |
| 1718 | Lisp_Object ccl_id; | ||
| 1719 | 1833 | ||
| 1720 | if ((SYMBOLP (ccl_prog)) && | 1834 | if (setup_ccl_program (&ccl, ccl_prog) < 0) |
| 1721 | (!NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx)))) | 1835 | error ("Invalid CCL program"); |
| 1722 | { | ||
| 1723 | ccl_prog = XVECTOR (Vccl_program_table)->contents[XUINT (ccl_id)]; | ||
| 1724 | CHECK_LIST (ccl_prog, 0); | ||
| 1725 | ccl_prog = XCONS (ccl_prog)->cdr; | ||
| 1726 | CHECK_VECTOR (ccl_prog, 1); | ||
| 1727 | } | ||
| 1728 | else | ||
| 1729 | { | ||
| 1730 | CHECK_VECTOR (ccl_prog, 1); | ||
| 1731 | ccl_prog = resolve_symbol_ccl_program (ccl_prog); | ||
| 1732 | } | ||
| 1733 | 1836 | ||
| 1734 | CHECK_VECTOR (reg, 2); | 1837 | CHECK_VECTOR (reg, 1); |
| 1735 | if (XVECTOR (reg)->size != 8) | 1838 | if (XVECTOR (reg)->size != 8) |
| 1736 | error ("Invalid length of vector REGISTERS"); | 1839 | error ("Length of vector REGISTERS is not 9"); |
| 1737 | 1840 | ||
| 1738 | setup_ccl_program (&ccl, ccl_prog); | ||
| 1739 | for (i = 0; i < 8; i++) | 1841 | for (i = 0; i < 8; i++) |
| 1740 | ccl.reg[i] = (INTEGERP (XVECTOR (reg)->contents[i]) | 1842 | ccl.reg[i] = (INTEGERP (XVECTOR (reg)->contents[i]) |
| 1741 | ? XINT (XVECTOR (reg)->contents[i]) | 1843 | ? XINT (XVECTOR (reg)->contents[i]) |
| @@ -1783,30 +1885,18 @@ is a unibyte string. By default it is a multibyte string.") | |||
| 1783 | int i, produced; | 1885 | int i, produced; |
| 1784 | int outbufsize; | 1886 | int outbufsize; |
| 1785 | char *outbuf; | 1887 | char *outbuf; |
| 1786 | struct gcpro gcpro1, gcpro2, gcpro3; | 1888 | struct gcpro gcpro1, gcpro2; |
| 1787 | Lisp_Object ccl_id; | ||
| 1788 | 1889 | ||
| 1789 | if ((SYMBOLP (ccl_prog)) && | 1890 | if (setup_ccl_program (&ccl, ccl_prog) < 0) |
| 1790 | (!NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx)))) | 1891 | error ("Invalid CCL program"); |
| 1791 | { | ||
| 1792 | ccl_prog = XVECTOR (Vccl_program_table)->contents[XUINT (ccl_id)]; | ||
| 1793 | CHECK_LIST (ccl_prog, 0); | ||
| 1794 | ccl_prog = XCONS (ccl_prog)->cdr; | ||
| 1795 | CHECK_VECTOR (ccl_prog, 1); | ||
| 1796 | } | ||
| 1797 | else | ||
| 1798 | { | ||
| 1799 | CHECK_VECTOR (ccl_prog, 1); | ||
| 1800 | ccl_prog = resolve_symbol_ccl_program (ccl_prog); | ||
| 1801 | } | ||
| 1802 | 1892 | ||
| 1803 | CHECK_VECTOR (status, 1); | 1893 | CHECK_VECTOR (status, 1); |
| 1804 | if (XVECTOR (status)->size != 9) | 1894 | if (XVECTOR (status)->size != 9) |
| 1805 | error ("Invalid length of vector STATUS"); | 1895 | error ("Length of vector STATUS is not 9"); |
| 1806 | CHECK_STRING (str, 2); | 1896 | CHECK_STRING (str, 2); |
| 1807 | GCPRO3 (ccl_prog, status, str); | ||
| 1808 | 1897 | ||
| 1809 | setup_ccl_program (&ccl, ccl_prog); | 1898 | GCPRO2 (status, str); |
| 1899 | |||
| 1810 | for (i = 0; i < 8; i++) | 1900 | for (i = 0; i < 8; i++) |
| 1811 | { | 1901 | { |
| 1812 | if (NILP (XVECTOR (status)->contents[i])) | 1902 | if (NILP (XVECTOR (status)->contents[i])) |
| @@ -1848,50 +1938,73 @@ is a unibyte string. By default it is a multibyte string.") | |||
| 1848 | 1938 | ||
| 1849 | DEFUN ("register-ccl-program", Fregister_ccl_program, Sregister_ccl_program, | 1939 | DEFUN ("register-ccl-program", Fregister_ccl_program, Sregister_ccl_program, |
| 1850 | 2, 2, 0, | 1940 | 2, 2, 0, |
| 1851 | "Register CCL program PROGRAM of NAME in `ccl-program-table'.\n\ | 1941 | "Register CCL program CCL_PROG as NAME in `ccl-program-table'.\n\ |
| 1852 | PROGRAM should be a compiled code of CCL program, or nil.\n\ | 1942 | CCL_PROG should be a compiled CCL program (vector), or nil.\n\ |
| 1943 | If it is nil, just reserve NAME as a CCL program name.\n\ | ||
| 1853 | Return index number of the registered CCL program.") | 1944 | Return index number of the registered CCL program.") |
| 1854 | (name, ccl_prog) | 1945 | (name, ccl_prog) |
| 1855 | Lisp_Object name, ccl_prog; | 1946 | Lisp_Object name, ccl_prog; |
| 1856 | { | 1947 | { |
| 1857 | int len = XVECTOR (Vccl_program_table)->size; | 1948 | int len = XVECTOR (Vccl_program_table)->size; |
| 1858 | int i; | 1949 | int idx; |
| 1950 | Lisp_Object resolved; | ||
| 1859 | 1951 | ||
| 1860 | CHECK_SYMBOL (name, 0); | 1952 | CHECK_SYMBOL (name, 0); |
| 1953 | resolved = Qnil; | ||
| 1861 | if (!NILP (ccl_prog)) | 1954 | if (!NILP (ccl_prog)) |
| 1862 | { | 1955 | { |
| 1863 | CHECK_VECTOR (ccl_prog, 1); | 1956 | CHECK_VECTOR (ccl_prog, 1); |
| 1864 | ccl_prog = resolve_symbol_ccl_program (ccl_prog); | 1957 | resolved = resolve_symbol_ccl_program (ccl_prog); |
| 1958 | if (! NILP (resolved)) | ||
| 1959 | { | ||
| 1960 | ccl_prog = resolved; | ||
| 1961 | resolved = Qt; | ||
| 1962 | } | ||
| 1865 | } | 1963 | } |
| 1866 | 1964 | ||
| 1867 | for (i = 0; i < len; i++) | 1965 | for (idx = 0; idx < len; idx++) |
| 1868 | { | 1966 | { |
| 1869 | Lisp_Object slot = XVECTOR (Vccl_program_table)->contents[i]; | 1967 | Lisp_Object slot; |
| 1870 | 1968 | ||
| 1871 | if (!CONSP (slot)) | 1969 | slot = XVECTOR (Vccl_program_table)->contents[idx]; |
| 1970 | if (!VECTORP (slot)) | ||
| 1971 | /* This is the first unsed slot. Register NAME here. */ | ||
| 1872 | break; | 1972 | break; |
| 1873 | 1973 | ||
| 1874 | if (EQ (name, XCONS (slot)->car)) | 1974 | if (EQ (name, XVECTOR (slot)->contents[0])) |
| 1875 | { | 1975 | { |
| 1876 | XCONS (slot)->cdr = ccl_prog; | 1976 | /* Update this slot. */ |
| 1877 | return make_number (i); | 1977 | XVECTOR (slot)->contents[1] = ccl_prog; |
| 1978 | XVECTOR (slot)->contents[2] = resolved; | ||
| 1979 | return make_number (idx); | ||
| 1878 | } | 1980 | } |
| 1879 | } | 1981 | } |
| 1880 | 1982 | ||
| 1881 | if (i == len) | 1983 | if (idx == len) |
| 1882 | { | 1984 | { |
| 1883 | Lisp_Object new_table = Fmake_vector (make_number (len * 2), Qnil); | 1985 | /* Extend the table. */ |
| 1986 | Lisp_Object new_table; | ||
| 1884 | int j; | 1987 | int j; |
| 1885 | 1988 | ||
| 1989 | new_table = Fmake_vector (make_number (len * 2), Qnil); | ||
| 1886 | for (j = 0; j < len; j++) | 1990 | for (j = 0; j < len; j++) |
| 1887 | XVECTOR (new_table)->contents[j] | 1991 | XVECTOR (new_table)->contents[j] |
| 1888 | = XVECTOR (Vccl_program_table)->contents[j]; | 1992 | = XVECTOR (Vccl_program_table)->contents[j]; |
| 1889 | Vccl_program_table = new_table; | 1993 | Vccl_program_table = new_table; |
| 1890 | } | 1994 | } |
| 1891 | 1995 | ||
| 1892 | XVECTOR (Vccl_program_table)->contents[i] = Fcons (name, ccl_prog); | 1996 | { |
| 1893 | Fput (name, Qccl_program_idx, make_number (i)); | 1997 | Lisp_Object elt; |
| 1894 | return make_number (i); | 1998 | |
| 1999 | elt = Fmake_vector (make_number (3), Qnil); | ||
| 2000 | XVECTOR (elt)->contents[0] = name; | ||
| 2001 | XVECTOR (elt)->contents[1] = ccl_prog; | ||
| 2002 | XVECTOR (elt)->contents[2] = resolved; | ||
| 2003 | XVECTOR (Vccl_program_table)->contents[idx] = elt; | ||
| 2004 | } | ||
| 2005 | |||
| 2006 | Fput (name, Qccl_program_idx, make_number (idx)); | ||
| 2007 | return make_number (idx); | ||
| 1895 | } | 2008 | } |
| 1896 | 2009 | ||
| 1897 | /* Register code conversion map. | 2010 | /* Register code conversion map. |
| @@ -1989,6 +2102,7 @@ The code point in the font is set in CCL registers R1 and R2\n\ | |||
| 1989 | If the font is single-byte font, the register R2 is not used."); | 2102 | If the font is single-byte font, the register R2 is not used."); |
| 1990 | Vfont_ccl_encoder_alist = Qnil; | 2103 | Vfont_ccl_encoder_alist = Qnil; |
| 1991 | 2104 | ||
| 2105 | defsubr (&Sccl_program_p); | ||
| 1992 | defsubr (&Sccl_execute); | 2106 | defsubr (&Sccl_execute); |
| 1993 | defsubr (&Sccl_execute_on_string); | 2107 | defsubr (&Sccl_execute_on_string); |
| 1994 | defsubr (&Sregister_ccl_program); | 2108 | defsubr (&Sregister_ccl_program); |