Sync up with egg-980404.
[elisp/egg.git] / egg-com.el
1 ;;; egg-com.el --- Communication Routines in Egg Input
2 ;;;                   Method Architecture
3
4 ;; Copyright (C) 1997, 1998 Mule Project, Powered by Electrotechnical
5 ;; Laboratory, JAPAN.
6 ;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
7
8 ;; Author: Hisashi Miyashita <himi@bird.scphys.kyoto-u.ac.jp>
9 ;;         NIIBE Yutaka <gniibe@mri.co.jp>
10 ;;         KATAYAMA Yoshio <kate@pfu.co.jp>  ; Korean, Chinese support.
11 ;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
12
13 ;; This file is part of EGG.
14
15 ;; EGG is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; any later version.
19
20 ;; EGG is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 ;; GNU General Public License for more details.
24
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
27 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 ;; Boston, MA 02111-1307, USA.
29
30 ;;; Commentary:
31
32 ;;; Code:
33
34 (defvar egg-fixed-euc 'fixed-euc-jp)
35 (make-variable-buffer-local 'egg-fixed-euc)
36
37 (defvar egg-mb-euc 'euc-japan)
38 (make-variable-buffer-local 'egg-mb-euc)
39
40 (eval-and-compile
41 (define-ccl-program ccl-decode-fixed-euc-jp
42   `(2
43     ((r2 = ,(charset-id 'japanese-jisx0208))
44      (r3 = ,(charset-id 'japanese-jisx0212))
45      (r4 = ,(charset-id 'katakana-jisx0201))
46      (read r0)
47      (loop
48       (read r1)
49       (if (r0 < ?\x80)
50           ((r0 = r1)
51            (if (r1 < ?\x80)
52                (write-read-repeat r0))
53            (write r4)
54            (write-read-repeat r0))
55         ((if (r1 > ?\x80)
56              ((write r2 r0)
57               (r0 = r1)
58               (write-read-repeat r0))
59            ((write r3 r0)
60             (r0 = (r1 | ?\x80))
61             (write-read-repeat r0)))))))))
62
63 (define-ccl-program ccl-encode-fixed-euc
64   `(2
65     ((read r0)
66      (loop
67 ;      (if (r0 < ?\x20)
68 ;         (write-read-repeat r0))
69       (if (r0 == ,(charset-id 'latin-jisx0201))                 ; Unify
70           ((read r0)
71            (r0 &= ?\x7f)))
72       (if (r0 < ?\x80)
73           ((write 0)
74            (write-read-repeat r0)))
75       (r6 = (r0 == ,(charset-id 'japanese-jisx0208)))
76       (r6 |= (r0 == ,(charset-id 'japanese-jisx0208-1978)))
77       (r6 |= (r0 == ,(charset-id 'chinese-gb2312)))
78       (r6 |= (r0 == ,(charset-id 'korean-ksc5601)))
79       (if r6                                                      ;G1
80           ((read r0)
81            (write r0)
82            (read r0)
83            (write-read-repeat r0)))
84       (r6 = (r0 == ,(charset-id 'katakana-jisx0201)))
85       (r6 |= (r0 == ,(charset-id 'chinese-sisheng)))
86       (if r6                                                      ;G2
87           ((read r0)
88            (write 0)
89            (write-read-repeat r0)))
90       (if (r0 == ,(charset-id 'japanese-jisx0212))                ;G3
91           ((read r0)
92            (write r0)
93            (read r0)
94            (r0 &= ?\x7f)
95            (write-read-repeat r0)))
96       (read r0)
97       (repeat)))))
98 )
99
100 (make-coding-system 'fixed-euc-jp 4 ?W "Coding System for fixed EUC Japanese"
101                     (cons ccl-decode-fixed-euc-jp ccl-encode-fixed-euc))
102
103 ;; Korean
104
105 (eval-and-compile
106 (define-ccl-program ccl-decode-fixed-euc-kr
107   `(2
108     ((r2 = ,(charset-id 'korean-ksc5601))
109      (read r0)
110      (loop
111       (read r1)
112       (if (r0 < ?\x80)
113           (r0 = r1 & ?\x7f)
114         ((write r2 r0)
115          (r0 = r1 | ?\x80)))
116       (write-read-repeat r0)))))
117
118 (define-ccl-program ccl-encode-fixed-euc-kr
119   `(2
120     ((read r0)
121      (loop
122 ;      (if (r0 < ?\x20)
123 ;         (write-read-repeat r0))
124       (if (r0 < ?\x80)
125           ((write 0)
126            (write-read-repeat r0)))
127       (if (r0 == ,(charset-id 'korean-ksc5601))
128           ((read r0)
129            (r0 |= ?\x80)
130            (write r0)
131            (read r0)
132            (r0 |= ?\x80)
133            (write-read-repeat r0)))
134       (read r0)
135       (repeat)))))
136 )
137
138 (make-coding-system 'fixed-euc-kr 4 ?W "Coding System for fixed EUC Korean"
139                     (cons ccl-decode-fixed-euc-kr ccl-encode-fixed-euc-kr))
140
141 ;; Chinese
142 (defvar egg-zhuyin nil)
143
144 (defconst yincode-pinyin-shengmu
145   '((""  . 0)  ("B" . 1)  ("C"  . 2)  ("Ch" . 3)  ("D" . 4)
146     ("F" . 5)  ("G" . 6)  ("H"  . 7)  ("J"  . 8)  ("K" . 9)
147     ("L" . 10) ("M" . 11) ("N"  . 12) ("P"  . 13) ("Q" . 14)
148     ("R" . 15) ("S" . 16) ("Sh" . 17) ("T"  . 18) ("W" . 19)
149     ("X" . 20) ("Y" . 21) ("Z"  . 22) ("Zh" . 23)))
150
151 (defconst yincode-pinyin-yunmu
152   '(("\e(0@\e(B"      0 0) ("\e(0@\e(B"      0 1) ("\e(0@\e(B"      0 3) ("\e(0@\e(B"      0 5) ("\e(0@\e(B"      0 7)
153     ("a\e(0@\e(B"     1 0) ("\e(0!@\e(B"     1 1) ("\e(0"@\e(B"     1 3) ("\e(0#@\e(B"     1 5) ("\e(0$@\e(B"     1 7)
154     ("ai\e(0@\e(B"    2 0) ("\e(0!\e(Bi\e(0@\e(B"    2 1) ("\e(0"\e(Bi\e(0@\e(B"    2 3) ("\e(0#\e(Bi\e(0@\e(B"    2 5) ("\e(0$\e(Bi\e(0@\e(B"    2 7)
155     ("an\e(0@\e(B"    3 0) ("\e(0!\e(Bn\e(0@\e(B"    3 1) ("\e(0"\e(Bn\e(0@\e(B"    3 3) ("\e(0#\e(Bn\e(0@\e(B"    3 5) ("\e(0$\e(Bn\e(0@\e(B"    3 7)
156     ("ang\e(0@\e(B"   4 0) ("\e(0!\e(Bng\e(0@\e(B"   4 1) ("\e(0"\e(Bng\e(0@\e(B"   4 3) ("\e(0#\e(Bng\e(0@\e(B"   4 5) ("\e(0$\e(Bng\e(0@\e(B"   4 7)
157     ("ao\e(0@\e(B"    5 0) ("\e(0!\e(Bo\e(0@\e(B"    5 1) ("\e(0"\e(Bo\e(0@\e(B"    5 3) ("\e(0#\e(Bo\e(0@\e(B"    5 5) ("\e(0$\e(Bo\e(0@\e(B"    5 7)
158     ("e\e(0@\e(B"     6 0) ("\e(0%@\e(B"     6 1) ("\e(0&@\e(B"     6 3) ("\e(0'@\e(B"     6 5) ("\e(0(@\e(B"     6 7)
159     ("ei\e(0@\e(B"    7 0) ("\e(0%\e(Bi\e(0@\e(B"    7 1) ("\e(0&\e(Bi\e(0@\e(B"    7 3) ("\e(0'\e(Bi\e(0@\e(B"    7 5) ("\e(0(\e(Bi\e(0@\e(B"    7 7)
160     ("en\e(0@\e(B"    8 0) ("\e(0%\e(Bn\e(0@\e(B"    8 1) ("\e(0&\e(Bn\e(0@\e(B"    8 3) ("\e(0'\e(Bn\e(0@\e(B"    8 5) ("\e(0(\e(Bn\e(0@\e(B"    8 7)
161     ("eng\e(0@\e(B"   9 0) ("\e(0%\e(Bng\e(0@\e(B"   9 1) ("\e(0&\e(Bng\e(0@\e(B"   9 3) ("\e(0'\e(Bng\e(0@\e(B"   9 5) ("\e(0(\e(Bng\e(0@\e(B"   9 7)
162     ("er\e(0@\e(B"   10 0) ("\e(0%\e(Br\e(0@\e(B"   10 1) ("\e(0&\e(Br\e(0@\e(B"   10 3) ("\e(0'\e(Br\e(0@\e(B"   10 5) ("\e(0(\e(Br\e(0@\e(B"   10 7)
163     ("i\e(0@\e(B"    11 0) ("\e(0)@\e(B"    11 1) ("\e(0*@\e(B"    11 3) ("\e(0+@\e(B"    11 5) ("\e(0,@\e(B"    11 7)
164     ("ia\e(0@\e(B"   12 0) ("i\e(0!@\e(B"   12 1) ("i\e(0"@\e(B"   12 3) ("i\e(0#@\e(B"   12 5) ("i\e(0$@\e(B"   12 7)
165     ("ian\e(0@\e(B"  13 0) ("i\e(0!\e(Bn\e(0@\e(B"  13 1) ("i\e(0"\e(Bn\e(0@\e(B"  13 3) ("i\e(0#\e(Bn\e(0@\e(B"  13 5) ("i\e(0$\e(Bn\e(0@\e(B"  13 7)
166     ("iang\e(0@\e(B" 14 0) ("i\e(0!\e(Bng\e(0@\e(B" 14 1) ("i\e(0"\e(Bng\e(0@\e(B" 14 3) ("i\e(0#\e(Bng\e(0@\e(B" 14 5) ("i\e(0$\e(Bng\e(0@\e(B" 14 7)
167     ("iao\e(0@\e(B"  15 0) ("i\e(0!\e(Bo\e(0@\e(B"  15 1) ("i\e(0"\e(Bo\e(0@\e(B"  15 3) ("i\e(0#\e(Bo\e(0@\e(B"  15 5) ("i\e(0$\e(Bo\e(0@\e(B"  15 7)
168     ("ie\e(0@\e(B"   16 0) ("i\e(0%@\e(B"   16 1) ("i\e(0&@\e(B"   16 3) ("i\e(0'@\e(B"   16 5) ("i\e(0(@\e(B"   16 7)
169     ("in\e(0@\e(B"   17 0) ("\e(0)\e(Bn\e(0@\e(B"   17 1) ("\e(0*\e(Bn\e(0@\e(B"   17 3) ("\e(0+\e(Bn\e(0@\e(B"   17 5) ("\e(0,\e(Bn\e(0@\e(B"   17 7)
170     ("ing\e(0@\e(B"  18 0) ("\e(0)\e(Bng\e(0@\e(B"  18 1) ("\e(0*\e(Bng\e(0@\e(B"  18 3) ("\e(0+\e(Bng\e(0@\e(B"  18 5) ("\e(0,\e(Bng\e(0@\e(B"  18 7)
171     ("iong\e(0@\e(B" 19 0) ("i\e(0-\e(Bng\e(0@\e(B" 19 1) ("i\e(0.\e(Bng\e(0@\e(B" 19 3) ("i\e(0/\e(Bng\e(0@\e(B" 19 5) ("i\e(00\e(Bng\e(0@\e(B" 19 7)
172     ("iu\e(0@\e(B"   20 0) ("i\e(01@\e(B"   20 1) ("i\e(02@\e(B"   20 3) ("i\e(03@\e(B"   20 5) ("i\e(04@\e(B"   20 7)
173     ("m\e(0@\e(B"    21 0) ("m\e(0@\e(B"    21 1) ("m\e(0@\e(B"    21 3) ("m\e(0@\e(B"    21 5) ("m\e(0@\e(B"    21 7)
174     ("n\e(0@\e(B"    22 0) ("n\e(0@\e(B"    22 1) ("\e(0=@\e(B"    22 3) ("\e(0>@\e(B"    22 5) ("\e(0?@\e(B"    22 7)
175     ("ng\e(0@\e(B"   23 0) ("ng\e(0@\e(B"   23 1) ("ng\e(0@\e(B"   23 3) ("ng\e(0@\e(B"   23 5) ("ng\e(0@\e(B"   23 7)
176     ("o\e(0@\e(B"    24 0) ("\e(0-@\e(B"    24 1) ("\e(0.@\e(B"    24 3) ("\e(0/@\e(B"    24 5) ("\e(00@\e(B"    24 7)
177     ("ong\e(0@\e(B"  25 0) ("\e(0-\e(Bng\e(0@\e(B"  25 1) ("\e(0.\e(Bng\e(0@\e(B"  25 3) ("\e(0/\e(Bng\e(0@\e(B"  25 5) ("\e(00\e(Bng\e(0@\e(B"  25 7)
178     ("ou\e(0@\e(B"   26 0) ("\e(0-\e(Bu\e(0@\e(B"   26 1) ("\e(0.\e(Bu\e(0@\e(B"   26 3) ("\e(0/\e(Bu\e(0@\e(B"   26 5) ("\e(00\e(Bu\e(0@\e(B"   26 7)
179     ("u\e(0@\e(B"    27 0) ("\e(01@\e(B"    27 1) ("\e(02@\e(B"    27 3) ("\e(03@\e(B"    27 5) ("\e(04@\e(B"    27 7)
180     ("ua\e(0@\e(B"   28 0) ("u\e(0!@\e(B"   28 1) ("u\e(0"@\e(B"   28 3) ("u\e(0#@\e(B"   28 5) ("u\e(0$@\e(B"   28 7)
181     ("uai\e(0@\e(B"  29 0) ("u\e(0!\e(Bi\e(0@\e(B"  29 1) ("u\e(0"\e(Bi\e(0@\e(B"  29 3) ("u\e(0#\e(Bi\e(0@\e(B"  29 5) ("u\e(0$\e(Bi\e(0@\e(B"  29 7)
182     ("uan\e(0@\e(B"  30 0) ("u\e(0!\e(Bn\e(0@\e(B"  30 1) ("u\e(0"\e(Bn\e(0@\e(B"  30 3) ("u\e(0#\e(Bn\e(0@\e(B"  30 5) ("u\e(0$\e(Bn\e(0@\e(B"  30 7)
183     ("uang\e(0@\e(B" 31 0) ("u\e(0!\e(Bng\e(0@\e(B" 31 1) ("u\e(0"\e(Bng\e(0@\e(B" 31 3) ("u\e(0#\e(Bng\e(0@\e(B" 31 5) ("u\e(0$\e(Bng\e(0@\e(B" 31 7)
184     ("ue\e(0@\e(B"   32 0) ("u\e(0%@\e(B"   32 1) ("u\e(0&@\e(B"   32 3) ("u\e(0'@\e(B"   32 5) ("u\e(0(@\e(B"   32 7)
185     ("ui\e(0@\e(B"   33 0) ("u\e(0)@\e(B"   33 1) ("u\e(0*@\e(B"   33 3) ("u\e(0+@\e(B"   33 5) ("u\e(0,@\e(B"   33 7)
186     ("un\e(0@\e(B"   34 0) ("\e(01\e(Bn\e(0@\e(B"   34 1) ("\e(02\e(Bn\e(0@\e(B"   34 3) ("\e(03\e(Bn\e(0@\e(B"   34 5) ("\e(04\e(Bn\e(0@\e(B"   34 7)
187     ("uo\e(0@\e(B"   35 0) ("u\e(0-@\e(B"   35 1) ("u\e(0.@\e(B"   35 3) ("u\e(0/@\e(B"   35 5) ("u\e(00@\e(B"   35 7)
188     ("\e(09@\e(B"    36 0) ("\e(05@\e(B"    36 1) ("\e(06@\e(B"    36 3) ("\e(07@\e(B"    36 5) ("\e(08@\e(B"    36 7)
189     ("\e(09\e(Be\e(0@\e(B"   37 0) ("\e(09%@\e(B"   37 1) ("\e(09&@\e(B"   37 3) ("\e(09'@\e(B"   37 5) ("\e(09(@\e(B"   37 7)
190     ("0\e(0@\e(B"    38 0) ("1\e(0@\e(B"    38 1) ("2\e(0@\e(B"    38 3) ("3\e(0@\e(B"    38 5) ("4\e(0@\e(B"    38 7)))
191
192 (defconst yincode-pinyin-table
193   [
194    0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
195    0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1
196    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
197    0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
198    0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
199    0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
200    0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
201    0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
202    0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
203    0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
204    0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1
205    0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
206    0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 1 1 1 1
207    0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
208    0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
209    0 0 0 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 0 0 1
210    0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
211    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 0 1
212    0 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
213    0 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1
214    0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
215    0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 1 0 0 0 1
216    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
217    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
218    ])
219
220 (defconst yincode-zhuyin-shengmu
221   '((""  .  0) ("\e(0E\e(B" .  1) ("\e(0X\e(B" .  2) ("\e(0T\e(B" .  3) ("\e(0I\e(B" .  4)
222     ("\e(0H\e(B" .  5) ("\e(0M\e(B" .  6) ("\e(0O\e(B" .  7) ("\e(0P\e(B" .  8) ("\e(0N\e(B" .  9)
223     ("\e(0L\e(B" . 10) ("\e(0G\e(B" . 11) ("\e(0K\e(B" . 12) ("\e(0F\e(B" . 13) ("\e(0Q\e(B" . 14)
224     ("\e(0V\e(B" . 15) ("\e(0Y\e(B" . 16) ("\e(0U\e(B" . 17) ("\e(0J\e(B" . 18) ("\e(0h\e(B" . 19)
225     ("\e(0R\e(B" . 20) ("\e(0g\e(B" . 21) ("\e(0W\e(B" . 22) ("\e(0S\e(B" . 23)))
226
227 (defconst yincode-zhuyin-yunmu
228   '(("\e(0@\e(B"    0 0) ("\e(0A\e(B"    0 1) ("\e(0B\e(B"    0 3) ("\e(0C\e(B"    0 5) ("\e(0D\e(B"    0 7) ; i
229     ("\e(0Z@\e(B"   1 0) ("\e(0ZA\e(B"   1 1) ("\e(0ZB\e(B"   1 3) ("\e(0ZC\e(B"   1 5) ("\e(0ZD\e(B"   1 7) ; a
230     ("\e(0^@\e(B"   2 0) ("\e(0^A\e(B"   2 1) ("\e(0^B\e(B"   2 3) ("\e(0^C\e(B"   2 5) ("\e(0^D\e(B"   2 7) ; ai
231     ("\e(0b@\e(B"   3 0) ("\e(0bA\e(B"   3 1) ("\e(0bB\e(B"   3 3) ("\e(0bC\e(B"   3 5) ("\e(0bD\e(B"   3 7) ; an
232     ("\e(0d@\e(B"   4 0) ("\e(0dA\e(B"   4 1) ("\e(0dB\e(B"   4 3) ("\e(0dC\e(B"   4 5) ("\e(0dD\e(B"   4 7) ; ang
233     ("\e(0`@\e(B"   5 0) ("\e(0`A\e(B"   5 1) ("\e(0`B\e(B"   5 3) ("\e(0`C\e(B"   5 5) ("\e(0`D\e(B"   5 7) ; ao
234     ("\e(0\@\e(B"   6 0) ("\e(0\A\e(B"   6 1) ("\e(0\B\e(B"   6 3) ("\e(0\C\e(B"   6 5) ("\e(0\D\e(B"   6 7) ; e
235     ("\e(0_@\e(B"   7 0) ("\e(0_A\e(B"   7 1) ("\e(0_B\e(B"   7 3) ("\e(0_C\e(B"   7 5) ("\e(0_D\e(B"   7 7) ; ei
236     ("\e(0c@\e(B"   8 0) ("\e(0cA\e(B"   8 1) ("\e(0cB\e(B"   8 3) ("\e(0cC\e(B"   8 5) ("\e(0cD\e(B"   8 7) ; en
237     ("\e(0e@\e(B"   9 0) ("\e(0eA\e(B"   9 1) ("\e(0eB\e(B"   9 3) ("\e(0eC\e(B"   9 5) ("\e(0eD\e(B"   9 7) ; eng
238     ("\e(0f@\e(B"  10 0) ("\e(0fA\e(B"  10 1) ("\e(0fB\e(B"  10 3) ("\e(0fC\e(B"  10 5) ("\e(0fD\e(B"  10 7) ; er
239     ("\e(0g@\e(B"  11 0) ("\e(0gA\e(B"  11 1) ("\e(0gB\e(B"  11 3) ("\e(0gC\e(B"  11 5) ("\e(0gD\e(B"  11 7) ; i
240     ("\e(0gZ@\e(B" 12 0) ("\e(0gZA\e(B" 12 1) ("\e(0gZB\e(B" 12 3) ("\e(0gZC\e(B" 12 5) ("\e(0gZD\e(B" 12 7) ; ia
241     ("\e(0gb@\e(B" 13 0) ("\e(0gbA\e(B" 13 1) ("\e(0gbB\e(B" 13 3) ("\e(0gbC\e(B" 13 5) ("\e(0gbD\e(B" 13 7) ; ian
242     ("\e(0gd@\e(B" 14 0) ("\e(0gdA\e(B" 14 1) ("\e(0gdB\e(B" 14 3) ("\e(0gdC\e(B" 14 5) ("\e(0gdD\e(B" 14 7) ; iang
243     ("\e(0g`@\e(B" 15 0) ("\e(0g`A\e(B" 15 1) ("\e(0g`B\e(B" 15 3) ("\e(0g`C\e(B" 15 5) ("\e(0g`D\e(B" 15 7) ; iao
244     ("\e(0g]@\e(B" 16 0) ("\e(0g]A\e(B" 16 1) ("\e(0g]B\e(B" 16 3) ("\e(0g]C\e(B" 16 5) ("\e(0g]D\e(B" 16 7) ; ie
245     ("\e(0gc@\e(B" 17 0) ("\e(0gcA\e(B" 17 1) ("\e(0gcB\e(B" 17 3) ("\e(0gcC\e(B" 17 5) ("\e(0gcD\e(B" 17 7) ; in
246     ("\e(0ge@\e(B" 18 0) ("\e(0geA\e(B" 18 1) ("\e(0geB\e(B" 18 3) ("\e(0geC\e(B" 18 5) ("\e(0geD\e(B" 18 7) ; ing
247     ("\e(0ie@\e(B" 19 0) ("\e(0ieA\e(B" 19 1) ("\e(0ieB\e(B" 19 3) ("\e(0ieC\e(B" 19 5) ("\e(0ieD\e(B" 19 7) ; iong
248     ("\e(0ga@\e(B" 20 0) ("\e(0gaA\e(B" 20 1) ("\e(0gaB\e(B" 20 3) ("\e(0gaC\e(B" 20 5) ("\e(0gaD\e(B" 20 7) ; iu
249     ("\e(0G@\e(B"  21 0) ("\e(0GA\e(B"  21 1) ("\e(0GB\e(B"  21 3) ("\e(0GC\e(B"  21 5) ("\e(0GD\e(B"  21 7) ; m
250     ("\e(0K@\e(B"  22 0) ("\e(0KA\e(B"  22 1) ("\e(0KB\e(B"  22 3) ("\e(0KC\e(B"  22 5) ("\e(0KD\e(B"  22 7) ; n
251     ("@\e(0@\e(B"  23 0) ("@\e(0A\e(B"  23 1) ("@\e(0B\e(B"  23 3) ("@\e(0C\e(B"  23 5) ("@\e(0D\e(B"  23 7) ; ng
252     ("\e(0[@\e(B"  24 0) ("\e(0[A\e(B"  24 1) ("\e(0[B\e(B"  24 3) ("\e(0[C\e(B"  24 5) ("\e(0[D\e(B"  24 7) ; o
253     ("\e(0he@\e(B" 25 0) ("\e(0heA\e(B" 25 1) ("\e(0heB\e(B" 25 3) ("\e(0heC\e(B" 25 5) ("\e(0heD\e(B" 25 7) ; ong
254     ("\e(0a@\e(B"  26 0) ("\e(0aA\e(B"  26 1) ("\e(0aB\e(B"  26 3) ("\e(0aC\e(B"  26 5) ("\e(0aD\e(B"  26 7) ; ou
255     ("\e(0h@\e(B"  27 0) ("\e(0hA\e(B"  27 1) ("\e(0hB\e(B"  27 3) ("\e(0hC\e(B"  27 5) ("\e(0hD\e(B"  27 7) ; u
256     ("\e(0hZ@\e(B" 28 0) ("\e(0hZA\e(B" 28 1) ("\e(0hZB\e(B" 28 3) ("\e(0hZC\e(B" 28 5) ("\e(0hZD\e(B" 28 7) ; ua
257     ("\e(0h^@\e(B" 29 0) ("\e(0h^A\e(B" 29 1) ("\e(0h^B\e(B" 29 3) ("\e(0h^C\e(B" 29 5) ("\e(0h^D\e(B" 29 7) ; uai
258     ("\e(0hb@\e(B" 30 0) ("\e(0hbA\e(B" 30 1) ("\e(0hbB\e(B" 30 3) ("\e(0hbC\e(B" 30 5) ("\e(0hbD\e(B" 30 7) ; uan
259     ("\e(0hd@\e(B" 31 0) ("\e(0hdA\e(B" 31 1) ("\e(0hdB\e(B" 31 3) ("\e(0hdC\e(B" 31 5) ("\e(0hdD\e(B" 31 7) ; uang
260     ("\e(0i]@\e(B" 37 0) ("\e(0i]A\e(B" 37 1) ("\e(0i]B\e(B" 37 3) ("\e(0i]C\e(B" 37 5) ("\e(0i]D\e(B" 37 7) ; ue
261     ("\e(0h_@\e(B" 33 0) ("\e(0h_A\e(B" 33 1) ("\e(0h_B\e(B" 33 3) ("\e(0h_C\e(B" 33 5) ("\e(0h_D\e(B" 33 7) ; ui
262     ("\e(0hc@\e(B" 34 0) ("\e(0hcA\e(B" 34 1) ("\e(0hcB\e(B" 34 3) ("\e(0hcC\e(B" 34 5) ("\e(0hcD\e(B" 34 7) ; un
263     ("\e(0h[@\e(B" 35 0) ("\e(0h[A\e(B" 35 1) ("\e(0h[B\e(B" 35 3) ("\e(0h[C\e(B" 35 5) ("\e(0h[D\e(B" 35 7) ; uo
264     ("\e(0i@\e(B"  36 0) ("\e(0iA\e(B"  36 1) ("\e(0iB\e(B"  36 3) ("\e(0iC\e(B"  36 5) ("\e(0iD\e(B"  36 7) ; \e(09\e(B
265     ("\e(0i]@\e(B" 37 0) ("\e(0i]A\e(B" 37 1) ("\e(0i]B\e(B" 37 3) ("\e(0i]C\e(B" 37 5) ("\e(0i]D\e(B" 37 7) ; \e(09\e(Be
266     ("0\e(0@\e(B"  38 0) ("1\e(0A\e(B"  38 1) ("2\e(0B\e(B"  38 3) ("3\e(0C\e(B"  38 5) ("4\e(0D\e(B"  38 7) ; undefined
267     ("\e(0ib@\e(B" 39 0) ("\e(0ibA\e(B" 39 1) ("\e(0ibB\e(B" 39 3) ("\e(0ibC\e(B" 39 5) ("\e(0ibD\e(B" 39 7) ; \e(09\e(Ban
268     ("\e(0ic@\e(B" 40 0) ("\e(0icA\e(B" 40 1) ("\e(0icB\e(B" 40 3) ("\e(0icC\e(B" 40 5) ("\e(0icD\e(B" 40 7) ; \e(09\e(Bn
269     ))
270
271 (defconst yincode-zhuyin-table
272   [
273    ;; empty ShengMu
274    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
275    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x9586 ?\x0000 ?\x9592 ?\x9599
276    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x0000
277    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x959b ?\x95a0 ?\x0000 ?\x959e
278    ?\x95a2
279    ;; ShengMu B
280    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
281    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
282    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000
283    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
284    ?\x0000
285    ;; ShengMu C
286    ?\x828b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
287    ?\x0000 ?\x0280 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
288    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
289    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
290    ?\x0000
291    ;; ShengMu Ch
292    ?\x838b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
293    ?\x0000 ?\x0380 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
294    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
295    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
296    ?\x0000
297    ;; ShengMu D
298    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
299    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000
300    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
301    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
302    ?\x0000
303    ;; ShengMu F
304    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
305    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
306    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
307    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
308    ?\x0000
309    ;; ShengMu G
310    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
311    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
312    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
313    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
314    ?\x0000
315    ;; ShengMu H
316    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
317    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
318    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
319    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
320    ?\x0000
321    ;; ShengMu J
322    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
323    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
324    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x08a4 ?\x0000 ?\x0000
325    ?\x08a7 ?\x0000 ?\x08a5 ?\x0000 ?\x08a8 ?\x0000 ?\x889b ?\x88a0 ?\x8000 ?\x889e
326    ?\x88a2
327    ;; ShengMu K
328    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
329    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
330    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
331    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
332    ?\x0000
333    ;; ShengMu L
334    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000
335    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
336    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
337    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
338    ?\x0000
339    ;; ShengMu M
340    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
341    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
342    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
343    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
344    ?\x0000
345    ;; ShengMu N
346    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
347    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
348    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
349    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
350    ?\x0000
351    ;; ShengMu P
352    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
353    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
354    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
355    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
356    ?\x0000 
357    ;; ShengMu Q
358    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
359    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
360    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0ea4 ?\x0000 ?\x0000
361    ?\x0ea7 ?\x0000 ?\x0ea5 ?\x0000 ?\x0ea8 ?\x0000 ?\x8e9b ?\x8ea0 ?\x8000 ?\x8e9e
362    ?\x8ea2
363    ;; ShengMu R
364    ?\x8f8b ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
365    ?\x0000 ?\x0f80 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
366    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
367    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
368    ?\x0000
369    ;; ShengMu S
370    ?\x908b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
371    ?\x0000 ?\x1080 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
372    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
373    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
374    ?\x0000
375    ;; ShengMu Sh
376    ?\x918b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
377    ?\x0000 ?\x1180 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
378    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
379    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
380    ?\x0000
381    ;; ShengMu T
382    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000
383    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000
384    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
385    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
386    ?\x0000
387    ;; ShengMu W
388    ?\x939b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
389    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
390    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x1380 ?\x0000 ?\x0000
391    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
392    ?\x0000
393    ;; ShengMu X
394    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
395    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
396    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x14a4 ?\x0000 ?\x0000
397    ?\x14a7 ?\x0000 ?\x14a5 ?\x0000 ?\x14a8 ?\x0000 ?\x949b ?\x94a0 ?\x8000 ?\x949e
398    ?\x94a2
399    ;; ShengMu Y 
400    ?\x958b ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0090 ?\x0000 ?\x9591 ?\x9592
401    ?\x0000 ?\x1580 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x1588 ?\x1589 ?\x0000
402    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0093 ?\x8000 ?\x00a4 ?\x0000 ?\x0000
403    ?\x00a7 ?\x0000 ?\x00a5 ?\x0000 ?\x00a8 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
404    ?\x0000
405    ;; ShengMu Z
406    ?\x968b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
407    ?\x0000 ?\x1680 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
408    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
409    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
410    ?\x0000
411    ;; ShengMu Zh 
412    ?\x978b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
413    ?\x0000 ?\x1780 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
414    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
415    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
416    ?\x0000
417    ])
418
419 (defun egg-chinese-syllable (str &optional start)
420   (if start
421       (setq str (substring str start)))
422   (or (car (egg-pinyin-syllable str))
423       (car (egg-zhuyin-syllable str))))
424
425 (defsubst egg-make-fixed-euc-china-code (s y)
426   (concat (list
427            (+ (* 2 (nth 1 y)) (logand (nth 2 y) 1) 32)
428            (+ (* 4 (if (= s 0) 20 s)) (lsh (nth 2 y) -1) 156))))
429
430 (defun egg-pinyin-syllable (str)
431   (let (s y end)
432     (if (string-match "^[A-Za-z\e(0!\e(B-\e(0?\e(B]+\e(0@\e(B" str)
433         (progn
434           (setq end (match-end 0))
435           (cond
436            ((setq s (cdr (assoc (substring str 0 2) yincode-pinyin-shengmu)))
437             (setq y (substring str 2 end)))
438            ((setq s (cdr (assoc (substring str 0 1) yincode-pinyin-shengmu)))
439             (setq y (substring str 1 end)))
440            (t
441             (setq s 0 y (substring str 0 end))))
442           (if (and (setq y (assoc y yincode-pinyin-yunmu))
443                    (= (aref yincode-pinyin-table (+ (* 39 s) (nth 1 y))) 1))
444               (cons end (egg-make-fixed-euc-china-code s y)))))))
445
446 (defun egg-zhuyin-syllable (str)
447   (let (end s y c z (zhuyin-len (charset-bytes 'chinese-sisheng)))
448     (if (string-match "^[\e(0E\e(B-\e(0i\e(B@0-4]+[\e(0@ABCD\e(B]" str)
449         (progn
450           (setq end (match-end 0)
451                 c (substring str 0 zhuyin-len)
452                 s (cdr (assoc c yincode-zhuyin-shengmu))
453                 y (assoc (substring str zhuyin-len end) yincode-zhuyin-yunmu))
454           (if (null (and s y))
455               (setq s 0
456                     y (assoc (substring str 0 end) yincode-zhuyin-yunmu)))
457           (if (and y
458                    (setq z (aref yincode-zhuyin-table (+ (* 41 s) (nth 1 y))))
459                    (/= (logand z ?\x8000) 0))
460               (if (/= (logand z ?\x80) 0)
461                   (cons end (egg-make-fixed-euc-china-code
462                              (logand (lsh z -8) ?\x7f)
463                              (list nil (logand z ?\x7f) (nth 2 y))))
464                 (cons end (egg-make-fixed-euc-china-code s y))))))))
465
466 (defun encode-fixed-euc-china-region (beg end type)
467   "Encode the text in the region to EUC-CN/TW."
468   (let (s syl c cset (maxlen (max (length "Zhu\e(0!\e(Bng\e(0@\e(B") (length "\e(0ShdA\e(B"))))
469     (save-excursion
470       (save-restriction
471         (narrow-to-region beg end)
472         (goto-char (point-min))
473         (while (< (point) (point-max))
474           (setq s (buffer-substring (point) 
475                                     (min (+ (point) maxlen) (point-max))))
476           (cond
477            ((setq syl (egg-pinyin-syllable s))
478             (delete-region (point) (+ (point) (car syl)))
479             (insert (cdr syl)))
480            ((setq syl (egg-zhuyin-syllable s))
481             (delete-region (point) (+ (point) (car syl)))
482             (insert (cdr syl)))
483            (t
484             (setq c (split-char (following-char))
485                   cset (car c))
486             (cond
487              ((or (and (eq cset 'chinese-gb2312) (eq type 'cn))
488                   (and (eq cset 'chinese-cns11643-1) (eq type 'tw)))
489               (delete-char 1)
490               (insert (+ (nth 1 c) 128) (+ (nth 2 c) 128)))
491              ((and (eq cset 'chinese-cns11643-2) (eq type 'tw))
492               (delete-char 1)
493               (insert (+ (nth 1 c) 128) (nth 2 c)))
494              ((eq cset 'chinese-sisheng)
495               (delete-char 1)
496               (insert 0 (+ (nth 1 c) 128)))
497              (t
498               (delete-region (point) (1+ (point)))
499               (insert 0 (nth 1 c)))))))
500         (- (point-max) (point-min))))))
501
502 (defun pre-write-encode-fixed-euc-china (from to type)
503   (let ((buf (current-buffer))
504         (work (get-buffer-create " *pre-write-encoding-work*")))
505     (set-buffer work)
506     (erase-buffer)
507     (if (stringp from)
508         (insert from)
509       (insert-buffer-substring buf from to))
510     (encode-fixed-euc-china-region 1 (point-max) type)
511     nil))
512
513 (defun pre-write-encode-euc-cn (from to)
514   (pre-write-encode-fixed-euc-china from to 'cn))
515
516 (defun pre-write-encode-euc-tw (from to)
517   (pre-write-encode-fixed-euc-china from to 'tw))
518
519 (defun decode-fixed-euc-china-region (beg end type)
520   "Decode EUC-CN/TW encoded text in the region.
521 Return the length of resulting text."
522   (interactive "r")
523   (prog1
524       (let (c0 c1 s y ss)
525         (save-restriction
526           (narrow-to-region beg end)
527           (goto-char (point-min))
528           (while (< (point) (point-max))
529             (setq c1 (buffer-substring (point) (+ (point) 2))
530                   c0 (aref c1 0)
531                   c1 (aref c1 1))
532             (delete-region (point) (+ (point) 2))
533             (cond
534              ((eq c0 0)
535               (if (> c1 ?\xa0)
536                   (insert leading-code-private-11
537                           (charset-id 'chinese-sisheng)
538                           c1)
539                 (insert c1)))
540              ((>= c0 ?\x80)
541               (cond
542                ((eq type 'cn)
543                 (insert (charset-id 'chinese-gb2312) c0 (logior c1 ?\x80)))
544                ((>= c0 ?\x80)
545                 (insert (charset-id 'chinese-cns11643-1) c0 c1))
546                (t
547                 (insert (charset-id 'chinese-cns11643-2) c0 (+ c1 ?\x80)))))
548              (t
549               (setq c1 (logand c1 ?\x7f))
550               (setq s (- (lsh c1 -2) 7)  ;;(+ (lsh (- c1 32) -2) 1)
551                     y (- (lsh c0 -1) 16) ;;(lsh (- c0 32) -1)
552                     ss (+ (logand c0 1) (logand c1 3)))
553               (if egg-zhuyin
554                   (progn
555                     (setq c0 (aref yincode-zhuyin-table (+ (* 41 s) y)))
556                     (if (eq (logand c0 ?\x8080) ?\x80)
557                         (setq s (lsh c0 -8)
558                               y (logand c0 ?\x7f)))
559                     (if (and (eq s 20)
560                              (eq (aref yincode-pinyin-table (+ (* 39 s) y)) 0))
561                         (setq s 0))
562                     (insert (car (nth s yincode-zhuyin-shengmu))
563                             (car (nth (+ (* 5 y) ss) yincode-zhuyin-yunmu))))
564                 (if (and (eq s 20)
565                          (eq (aref yincode-pinyin-table (+ (* 39 s) y)) 0))
566                     (setq s 0))
567                 (insert (car (nth s yincode-pinyin-shengmu))
568                         (car (nth (+ (* 5 y) ss) yincode-pinyin-yunmu)))))))
569           (- (point-max) (point-min))))
570     (if (looking-at "\0\0") (forward-char 2))))
571
572 (defun post-read-decode-fixed-euc-china (len type)
573   (let ((pos (point))
574         (buffer-modified-p (buffer-modified-p)))
575     (prog1
576         (decode-fixed-euc-china-region pos (+ pos len) type)
577       (set-buffer-modified-p buffer-modified-p))))
578
579 (defun post-read-decode-euc-cn (len)
580   (post-read-decode-fixed-euc-china len 'cn))
581
582 (defun post-read-decode-euc-tw (len)
583   (post-read-decode-fixed-euc-china len 'tw))
584
585 (make-coding-system 'fixed-euc-cn 5 ?W "Coding System for fixed EUC Chinese-gb2312")
586 (put 'fixed-euc-cn 'pre-write-conversion 'pre-write-encode-euc-cn)
587 (put 'fixed-euc-cn 'post-read-conversion 'post-read-decode-euc-cn)
588
589 (make-coding-system 'fixed-euc-tw 5 ?W "Coding System for fixed EUC Chinese-cns11643")
590 (put 'fixed-euc-tw 'pre-write-conversion 'pre-write-encode-euc-tw)
591 (put 'fixed-euc-tw 'post-read-conversion 'post-read-decode-euc-tw)
592 \f
593 (defsubst comm-format-u32c (uint32c)
594   (let ((h0 (car uint32c))
595         (h1 (cdr uint32c)))
596     (let ((b0 (logand (lsh h0 -8) 255))
597           (b1 (logand h0 255))
598           (b2 (logand (lsh h1 -8) 255))
599           (b3 (logand h1 255)))
600       (insert-char b0 1)
601       (insert-char b1 1)
602       (insert-char b2 1)
603       (insert-char b3 1))))
604
605 (defsubst comm-format-u32 (uint32)
606   (let ((b0 (logand (lsh uint32 -24) 255))
607         (b1 (logand (lsh uint32 -16) 255))
608         (b2 (logand (lsh uint32 -8) 255))
609         (b3 (logand uint32 255)))
610     (insert-char b0 1)
611     (insert-char b1 1)
612     (insert-char b2 1)
613     (insert-char b3 1)))
614
615 (defsubst comm-format-i32 (int32)
616   (let ((b0 (logand (ash int32 -24) 255))
617         (b1 (logand (ash int32 -16) 255))
618         (b2 (logand (ash int32 -8) 255))
619         (b3 (logand int32 255)))
620     (insert-char b0 1)
621     (insert-char b1 1)
622     (insert-char b2 1)
623     (insert-char b3 1)))
624
625 (defsubst comm-format-u16 (uint16)
626   (let ((b0 (logand (lsh uint16 -8) 255))
627         (b1 (logand uint16 255)))
628     (insert-char b0 1)
629     (insert-char b1 1)))
630
631 (defsubst comm-format-u8 (uint8)
632   (let ((b0 (logand uint8 255)))
633     (insert-char b0 1)))
634
635 ;;; XXX should support other code conversion
636 (defsubst comm-format-u16-string (s)
637   (let ((euc-string (encode-coding-string s egg-fixed-euc)))
638     (insert euc-string)
639     (insert-char 0 1)
640     (insert-char 0 1)))
641
642 ;;; XXX should support other code conversion
643 (defsubst comm-format-mb-string (s)
644   (let ((euc-string (encode-coding-string s egg-mb-euc)))
645     (insert euc-string)
646     (insert-char 0 1)))
647
648 (defsubst comm-format-u8-string (s)
649   (insert s)
650   (insert-char 0 1))
651
652 (defsubst comm-format-u8-vector (s)
653   (insert (concat s)))
654
655 (defsubst comm-format-bytes (s)
656   (insert s)
657   (insert-char 255 1))
658
659 (defmacro comm-format (format &rest args)
660   "Format a string out of a control-list and arguments into the buffer.
661 u means unsigned 32-bit in big endian.
662 i means unsigned 32-bit in big endian.
663 w means unsigned 16-bit in big endian.
664 b means unsigned  8-bit.
665 S means 16-bit(big endian) wide-character string (0x0000 terminated).
666 E means multibyte string (0x00 terminated).
667 s means 8-bit string (0x00 terminated).
668 v means 8-bit vector."
669   (let ((p args) result arg f)
670     (while format
671       (setq arg (car p))
672       (setq f (car format))
673       (setq result
674             (append result
675                     (list
676                      (cond ((eq f 'U) (list 'comm-format-u32c arg))
677                            ((eq f 'u) (list 'comm-format-u32 arg))
678                            ((eq f 'i) (list 'comm-format-i32 arg))
679                            ((eq f 'v) (list 'comm-format-u8-vector arg))
680                            ((eq f 'w) (list 'comm-format-u16 arg))
681                            ((eq f 'b) (list 'comm-format-u8 arg))
682                            ((eq f 'S) (list 'comm-format-u16-string arg))
683                            ((eq f 'E) (list 'comm-format-mb-string arg))
684                            ((eq f 's) (list 'comm-format-u8-string arg))
685                            ((eq f 'B) (list 'comm-format-bytes arg))))))
686       (setq p (cdr p))
687       (setq format (cdr format)))
688     (cons
689      'progn
690      result)))
691 \f
692 (if (not (fboundp 'string-as-multibyte))
693     (defsubst string-as-multibyte (str)
694       str))
695
696 ;; Do not move the point, leave it where it was.
697 (defun comm-accept-process-output (proc)
698   (let ((p (point)))
699     (accept-process-output proc)
700     (goto-char p)))
701
702 ;; Assume PROC is bound to the process of current buffer
703 (defsubst comm-following-char-or-wait (proc)
704   (if (eobp)
705       (let ((p (point)))
706         (while (= p (point-max))
707           (accept-process-output proc))
708         (goto-char p)))
709   (following-char))
710
711 (defun comm-following+forward-char (proc)
712   (prog1
713       (comm-following-char-or-wait proc)
714     (forward-char 1)))
715
716 (defsubst comm-unpack-u32c (proc uint32c)
717   (let (h0 h1)
718     (setq h0
719          (+
720           (lsh (comm-following+forward-char proc) 8)
721           (comm-following+forward-char proc)))
722     (setq h1
723          (+
724           (lsh (comm-following+forward-char proc) 8)
725           (comm-following+forward-char proc)))
726     (set uint32c (cons h0 h1))))
727
728 (defsubst comm-unpack-u32 (proc uint32)
729   (set uint32
730        (+
731         (lsh (comm-following+forward-char proc) 24)
732         (lsh (comm-following+forward-char proc) 16)
733         (lsh (comm-following+forward-char proc) 8)
734         (comm-following+forward-char proc))))
735
736 (defsubst comm-unpack-u16 (proc uint16)
737   (set uint16
738        (+
739         (lsh (comm-following+forward-char proc) 8)
740         (comm-following+forward-char proc))))
741
742 (defsubst comm-unpack-u8 (proc uint8)
743   (set uint8
744        (comm-following+forward-char proc)))
745
746 ;;; XXX should support other conversion (euc-kr, cns)
747 (defsubst comm-unpack-u16-string (proc s)
748   (let ((start (point)))
749     (while (not (search-forward "\0\0" nil t))
750       (comm-accept-process-output proc))
751     (set s (string-as-multibyte
752             (buffer-substring start
753                               (+ start
754                                  (decode-coding-region start (- (point) 2)
755                                                        egg-fixed-euc)))))))
756
757 ;;; XXX should support other conversion (euc-kr, cns)
758 (defsubst comm-unpack-mb-string (proc s)
759   (let ((start (point)))
760     (while (not (search-forward "\0" nil t))
761       (comm-accept-process-output proc))
762     (set s (string-as-multibyte
763             (buffer-substring start
764                               (+ start
765                                  (decode-coding-region start (- (point) 1)
766                                                        egg-mb-euc)))))))
767
768 (defsubst comm-unpack-u8-string (proc s)
769   (let ((start (point)))
770     (while (not (search-forward "\0" nil 1))
771       (comm-accept-process-output proc))
772     (set s (buffer-substring start (1- (point))))))
773
774 (defsubst comm-unpack-bytes (proc s)
775   (let ((start (point)))
776     (while (not (search-forward "\377" nil 1))
777       (comm-accept-process-output proc))
778     (set s (buffer-substring start (1- (point))))))
779
780 (defmacro comm-unpack (format &rest args)
781   "Unpack a string out of a control-string and set arguments.
782 u means unsigned 32-bit in big endian.
783 w means unsigned 16-bit in big endian.
784 b means unsigned  8-bit.
785 S means 16-bit(big endian) string (0x0000 terminated).
786 E means multibyte string (0x00 terminated).
787 s means 8-bit string (0x00 terminated).
788 "
789   (let ((p args) result arg f)
790     (while format
791       (setq arg (car p))
792       (setq f (car format))
793       (setq result
794             (append result
795                     (list
796                      (cond ((eq f 'U) (list 'comm-unpack-u32c
797                                             'proc (list 'quote arg)))
798                            ((eq f 'u) (list 'comm-unpack-u32
799                                             'proc (list 'quote arg)))
800                            ((eq f 'w) (list 'comm-unpack-u16
801                                             'proc (list 'quote arg)))
802                            ((eq f 'b) (list 'comm-unpack-u8
803                                             'proc (list 'quote arg)))
804                            ((eq f 'S) (list 'comm-unpack-u16-string
805                                             'proc (list 'quote arg)))
806                            ((eq f 'E) (list 'comm-unpack-mb-string
807                                             'proc (list 'quote arg)))
808                            ((eq f 's) (list 'comm-unpack-u8-string
809                                             'proc (list 'quote arg)))
810                            ((eq f 'B) (list 'comm-unpack-u8-string
811                                             'proc (list 'quote arg)))))))
812       (setq p (cdr p))
813       (setq format (cdr format)))
814     (cons
815      'progn
816      result)))
817 \f
818 (defmacro comm-call-with-proc (proc vlist send-expr &rest receive-exprs)
819   (list
820    'let vlist
821    (append
822     `(save-excursion
823        (set-buffer (process-buffer proc))
824        (erase-buffer)
825        ,send-expr
826        (process-send-region proc (point-min) (point-max))
827        (goto-char (prog1 (point) (accept-process-output proc))))
828     receive-exprs)))
829
830 (defmacro comm-call-with-proc-1 (proc vlist send-expr &rest receive-exprs)
831   (list
832    'let vlist
833    (append
834     `(progn
835        (erase-buffer)
836        ,send-expr
837        (process-send-region proc (point-min) (point-max))
838        (goto-char (prog1 (point) (accept-process-output proc))))
839     receive-exprs)))
840
841 (provide 'egg-com)
842 ;;; egg-com.el ends here.