Mercurial > emacs
comparison src/ccl.c @ 25066:8b8e54912f5c
(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.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Mon, 26 Jul 1999 11:56:28 +0000 |
parents | 7b170d2184a4 |
children | 0a7261c1d487 |
comparison
equal
deleted
inserted
replaced
25065:6f92f7a071c9 | 25066:8b8e54912f5c |
---|---|
57 | 57 |
58 /* Symbols of ccl program have this property, a value of the property | 58 /* Symbols of ccl program have this property, a value of the property |
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 |
66 operations on one input buffer, one output buffer, and 7 registers. | 70 operations on one input buffer, one output buffer, and 7 registers. |
67 The syntax of CCL is described in `ccl.el'. Emacs Lisp function | 71 The syntax of CCL is described in `ccl.el'. Emacs Lisp function |
289 ------------------------------ | 293 ------------------------------ |
290 write (reg[RRR] OPERATION reg[Rrr]); | 294 write (reg[RRR] OPERATION reg[Rrr]); |
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 |
296 ------------------------------ | 300 [2:00000000cccccccccccccccccccc] |
297 call (CC..C) | 301 ------------------------------ |
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: |
301 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | 310 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX |
302 [2:0000STRIN[0]STRIN[1]STRIN[2]] | 311 [2:0000STRIN[0]STRIN[1]STRIN[2]] |
922 i = reg[RRR]; | 931 i = reg[RRR]; |
923 j = reg[Rrr]; | 932 j = reg[Rrr]; |
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 { |
940 ccl_prog = ccl_prog_stack_struct[0].ccl_prog; | 960 ccl_prog = ccl_prog_stack_struct[0].ccl_prog; |
941 ic = ccl_prog_stack_struct[0].ic; | 961 ic = ccl_prog_stack_struct[0].ic; |
944 } | 964 } |
945 | 965 |
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; |
953 | 973 |
954 case CCL_WriteConstString: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ | 974 case CCL_WriteConstString: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ |
1617 ccl->prog = ccl_prog; | 1637 ccl->prog = ccl_prog; |
1618 if (consumed) *consumed = src - source; | 1638 if (consumed) *consumed = src - source; |
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]); |
1639 ccl->buf_magnification = XINT (vp->contents[CCL_HEADER_BUF_MAG]); | 1780 ccl->buf_magnification = XINT (vp->contents[CCL_HEADER_BUF_MAG]); |
1640 } | 1781 } |
1643 ccl->reg[i] = 0; | 1784 ccl->reg[i] = 0; |
1644 ccl->last_block = 0; | 1785 ccl->last_block = 0; |
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 | 1793 |
1652 translation tables embeded in the CCL code into their ID numbers. */ | 1794 DEFUN ("ccl-program-p", Fccl_program_p, Sccl_program_p, 1, 1, 0, |
1653 | 1795 "Return t if OBJECT is a CCL program name or a compiled CCL program code.") |
1654 Lisp_Object | 1796 (object) |
1655 resolve_symbol_ccl_program (ccl) | 1797 Lisp_Object object; |
1656 Lisp_Object ccl; | |
1657 { | 1798 { |
1658 int i, veclen; | 1799 Lisp_Object val; |
1659 Lisp_Object result, contents, prop; | 1800 |
1660 | 1801 if (VECTORP (object)) |
1661 result = ccl; | |
1662 veclen = XVECTOR (result)->size; | |
1663 | |
1664 /* Set CCL program's table ID */ | |
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 } |
1693 | 1806 if (!SYMBOLP (object)) |
1694 return result; | 1807 return Qnil; |
1808 | |
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 | |
1697 | |
1698 #ifdef emacs | |
1699 | 1814 |
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\ |
1709 of Nth register.\n\ | 1824 of Nth register.\n\ |
1710 \n\ | 1825 \n\ |
1713 (ccl_prog, reg) | 1828 (ccl_prog, reg) |
1714 Lisp_Object ccl_prog, reg; | 1829 Lisp_Object ccl_prog, reg; |
1715 { | 1830 { |
1716 struct ccl_program ccl; | 1831 struct ccl_program ccl; |
1717 int i; | 1832 int i; |
1718 Lisp_Object ccl_id; | 1833 |
1719 | 1834 if (setup_ccl_program (&ccl, ccl_prog) < 0) |
1720 if ((SYMBOLP (ccl_prog)) && | 1835 error ("Invalid CCL program"); |
1721 (!NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx)))) | 1836 |
1722 { | 1837 CHECK_VECTOR (reg, 1); |
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 | |
1734 CHECK_VECTOR (reg, 2); | |
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]) |
1742 : 0); | 1844 : 0); |
1743 | 1845 |
1781 Lisp_Object val; | 1883 Lisp_Object val; |
1782 struct ccl_program ccl; | 1884 struct ccl_program ccl; |
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; | 1889 |
1788 | 1890 if (setup_ccl_program (&ccl, ccl_prog) < 0) |
1789 if ((SYMBOLP (ccl_prog)) && | 1891 error ("Invalid CCL program"); |
1790 (!NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx)))) | |
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); | 1897 |
1808 | 1898 GCPRO2 (status, str); |
1809 setup_ccl_program (&ccl, ccl_prog); | 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])) |
1813 XSETINT (XVECTOR (status)->contents[i], 0); | 1903 XSETINT (XVECTOR (status)->contents[i], 0); |
1814 if (INTEGERP (XVECTOR (status)->contents[i])) | 1904 if (INTEGERP (XVECTOR (status)->contents[i])) |
1846 return val; | 1936 return val; |
1847 } | 1937 } |
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); |
1865 } | 1958 if (! NILP (resolved)) |
1866 | |
1867 for (i = 0; i < len; i++) | |
1868 { | |
1869 Lisp_Object slot = XVECTOR (Vccl_program_table)->contents[i]; | |
1870 | |
1871 if (!CONSP (slot)) | |
1872 break; | |
1873 | |
1874 if (EQ (name, XCONS (slot)->car)) | |
1875 { | 1959 { |
1876 XCONS (slot)->cdr = ccl_prog; | 1960 ccl_prog = resolved; |
1877 return make_number (i); | 1961 resolved = Qt; |
1878 } | 1962 } |
1879 } | 1963 } |
1880 | 1964 |
1881 if (i == len) | 1965 for (idx = 0; idx < len; idx++) |
1882 { | 1966 { |
1883 Lisp_Object new_table = Fmake_vector (make_number (len * 2), Qnil); | 1967 Lisp_Object slot; |
1968 | |
1969 slot = XVECTOR (Vccl_program_table)->contents[idx]; | |
1970 if (!VECTORP (slot)) | |
1971 /* This is the first unsed slot. Register NAME here. */ | |
1972 break; | |
1973 | |
1974 if (EQ (name, XVECTOR (slot)->contents[0])) | |
1975 { | |
1976 /* Update this slot. */ | |
1977 XVECTOR (slot)->contents[1] = ccl_prog; | |
1978 XVECTOR (slot)->contents[2] = resolved; | |
1979 return make_number (idx); | |
1980 } | |
1981 } | |
1982 | |
1983 if (idx == len) | |
1984 { | |
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. |
1898 A code conversion map consists of numbers, Qt, Qnil, and Qlambda. | 2011 A code conversion map consists of numbers, Qt, Qnil, and Qlambda. |
1899 The first element is start code point. | 2012 The first element is start code point. |
1987 The code point in the font is set in CCL registers R1 and R2\n\ | 2100 The code point in the font is set in CCL registers R1 and R2\n\ |
1988 when the execution terminated.\n\ | 2101 when the execution terminated.\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); |
1995 defsubr (&Sregister_code_conversion_map); | 2109 defsubr (&Sregister_code_conversion_map); |
1996 } | 2110 } |