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