1 /*
2 * cconv.c -- $BF~NOJ8;zJQ49%i%$%V%i%j(B (for X11)
3 * ver 10.8
4 */
5
6 /*
7 * Copyright (C) 1988 Software Research Associates, Inc.
8 *
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation for any purpose and without fee is hereby granted, provided
11 * that the above copyright notice appear in all copies and that both that
12 * copyright notice and this permission notice appear in supporting
13 * documentation, and that the name of Software Research Associates not be
14 * used in advertising or publicity pertaining to distribution of the
15 * software without specific, written prior permission. Software Research
16 * Associates makes no representations about the suitability of this software
17 * for any purpose. It is provided "as is" without express or implied
18 * warranty.
19 *
20 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan
21 * ishisone@sra.co.jp
22 */
23
24 /*
25 * $B35MW(B
26 *
27 * $BF~NOJ8;zJQ49$O!"$+$J4A;zJQ49$NA0CJ3,$G$"$j!"$=$NL\E*$O%-!<%\!<%I$+$i(B
28 * $BF~NO$5$l$?%-!<%3!<%I$r2r<a$9$k$3$H$G$"$k!#(B
29 * $B=>$C$F!"Bg$-$/J,$1$k$H<!$N(B2$B$D$N5!G=$r;}$D$3$H$K$J$k!#(B
30 *
31 * 1. $B%m!<%^;z$+$JJQ49$J$IF~NO$5$l$?J8;z$rJL$NJ8;z$KJQ$($k5!G=(B
32 * 2. $B%-!<$NF~NO$K$h$j!"$+$J4A;zJQ49$G;H$o$l$k!VJQ49!W!"!V3NDj!W$J$I$N(B
33 * $B3F<o5!G=$r8F$S=P$95!G=(B
34 *
35 * $B$3$N(B cconv $B%i%$%V%i%j$O(B X Window version 11 $B$N$b$H$G;H$o$l$k$3$H$r(B
36 * $BA[Dj$7$F$$$k!#(B
37 */
38
39 /*
40 * $B%a%b(B
41 *
42 * version 6.0 88/06/05
43 * $B$@$$$?$$$G$-$?(B
44 * version 6.1 88/06/06
45 * $B%3%a%s%HF~$l(B
46 * version 6.2 88/06/07
47 * $B$3$l$@$1F~$l$l$P%^%K%e%"%k=q$+$J$/$F$bBg>fIW$@$m$&(B
48 * version 6.4 88/09/05
49 * $B2CF#;a(B@$BEl9)Bg$N0U8+$K$h$j(B redo $B5!G=$rF~$l$k(B
50 * $B$D$$$G$K(B static function $B$N@k8@$r$D$1$k(B
51 * $B$$$/$D$+$N4X?t$r(B external $B$+$i(B static $B$KJQ$($k(B
52 * version 6.5 88/09/07
53 * function $B$,J#?t=q$1$k$h$&$K$7$?(B
54 * $B$=$N$?$a%G!<%?9=B$$rJQ99$9$k(B
55 * version 6.6 88/10/07
56 * $B$J$s$H(B readRuleFile() $B$G%*!<%W%s$7$?%U%!%$%k$r(B
57 * $BJD$8$k$N$rK:$l$F$$$?(B -- $B$"!<$O$:$+$7$$(B
58 * $B=>$C$F(B wterm $B$G2?2s$b(B KanjiConvert $B$N(B on/off $B$r7+$jJV$9$H(B
59 * $B=i4|2=$K<:GT$9$k(B
60 * version 6.7 88/12/19
61 * wstrlen() $B$O$3$N%i%$%V%i%j$GDj5A$9$k$Y$-$b$N$G$O$J$$$N$G30$9(B
62 * version 6.8 89/07/21
63 * $B1F;3;a(B@$B>>2<EE4o$+$i%-!<%3!<%II=5-$,$&$^$/F0$+$J$$$H$NO"Mm$r<u$1$k(B
64 * getKey() $B$G(B XKEY $BI=5-$N>l9g!"(B#0x$B#1#6?J?t(B $B$NFI$_$H$j$K%P%0$,(B
65 * $B$"$k$3$H$,H=L@(B
66 * version 7.0 89/08/16
67 * jclib $B$N(B Wnn version4 $BBP1~$K$h$j!"JQ49%P%C%U%!$,J#?t;}$F$k$h$&$K(B
68 * $B$J$C$?(B
69 * $B$=$l$K9g$o$;$F!"(Bcconv $B$b%P%C%U%!$,J#?t;}$F$k$h$&$K$7$J$1$l$P(B
70 * $B$J$i$J$$(B
71 * $B7k6IH>J,0J>e=q$-49$($F$7$^$C$?$h$&$@(B
72 * version 7.1 89/08/17
73 * $B%P%0%U%#%C%/%9(B
74 * $B%b!<%IJQ99DLCNMQ$N%3!<%k%P%C%/$rDI2C$9$k(B
75 * version 7.2 89/08/23
76 * $B%U%!%s%/%7%g%s%F!<%V%k$O!"$d$O$j(B ccParseRule() $B$G$O$J$/!"(B
77 * ccCreateBuf() $B$G;XDj$9$k$Y$-$b$N$J$N$G!"$=$N$h$&$KJQ99$9$k(B
78 * version 7.3 89/08/25
79 * lint $B$G7Y9p$,=P$J$$$h$&$K=$@5(B
80 * dumpAllRules() $B$G$A$c$s$HJQ49%k!<%k$,%@%s%W$5$l$k$h$&$K=$@5(B
81 * version 7.4 89/08/26
82 * ccParseRule() $B$G!"JQ49Dj5A%U%!%$%k$,A0$HF1$8$G$"$l$P(B
83 * $B%k!<%k$r6&MQ$9$k$h$&$KJQ99(B
84 * ccParseRule/ccFreeRule $B$G$N(B memory leak $B$N=$@5(B
85 * version 7.5 89/09/26
86 * $BJQ49Dj5A%U%!%$%k$G(B include $B$,;H$($k$h$&$K=$@5(B
87 * version 7.6 89/09/27
88 * include $B$N@bL@$r=q$/$N$rK:$l$F$$$?$N$G$=$l$rDI2C(B
89 * version 7.7 89/10/26
90 * getKey() $B$G(B #$B?t;z(B $B7?$NI=5-$r$7$?;~$K$^$@%P%0$,$"$C$?$N$G=$@5(B
91 * $B$=$b$=$b$3$NJ}<0$NI=5-$G$O%^%9%/$,;XDj$G$-$J$$$H$$$&:,K\E*$J(B
92 * $BLdBj$,$"$k$,!"$^$"$3$l$O$$$$$3$H$K$7$F!#(B
93 * version 8.0 89/10/27
94 * R4 contrib $B8~$1$N(B Release $B$K$"$?$C$F%P!<%8%g%sHV9f$r=$@5(B
95 * version 8.1 89/12/25
96 * include $B%U%!%$%k$,$J$+$C$?;~$K%3%"%@%s%W$9$k%P%0$r=$@5(B
97 * version 8.2 90/02/15
98 * X11R4 keyboard group support $BDI2C(B
99 * version 8.3 90/02/16
100 * keyboard group support $B$N7k2L!"Nc$($P(B
101 * "" shift-Right "" foo
102 * "" Right "" bar
103 * $B$H$$$&%k!<%k$,$"$C$?;~!"(Bshift-Right $B$r2!$7$?$K$b$+$+$o$i$:(B
104 * $B$7$?$N%k!<%k$K%^%C%A$7$F$7$^$&$H$$$&%P%0$r=$@5(B
105 * $BDj5A%U%!%$%k(B (include $B%U%!%$%k$b4^$`(B) $B$N%5!<%A%Q%9$H$7$F(B
106 * $B4D6-JQ?t(B CC_DEF_PATH $B$r;H$&$h$&$K=$@5(B
107 * version 8.4 90/04/17
108 * keyboard group support $B$N%3!<%I$N%1%"%l%9%_%9$r=$@5(B
109 * $BJQ?tL>(B ks1 $B$H(B ks2 $B$r4V0c$($?(B
110 * version 8.5 90/05/31
111 * keyboard group support $B$NIT6q9g$r=$@5(B
112 * $BL1ED;a(B@$B%"%9%F%C%/$+$i$N%l%]!<%H(B
113 * version 8.6 91/03/20
114 * $B$I$N%k!<%k$K$b%^%C%A$7$J$+$C$?;~$K$O%G%U%)%k%H%"%/%7%g%s$,8F$P$l$k$,!"(B
115 * $B$3$N=hM}$G(B
116 * + $B0z?t$,4V0c$C$F$$$?(B
117 * + XLookupString() $B$N%j%?!<%s%P%j%e!<$,(B 0 $B$N$H$-(B ($B$D$^$j(B
118 * $B%-!<%$%Y%s%H$KBP1~$9$kJ8;zNs$,$J$+$C$?;~(B) $B$K%G%U%)%k%H(B
119 * $B%"%/%7%g%s$,8F$P$l$J$+$C$?(B
120 * $B$H$$$&LdBj$r=$@5(B
121 * $B%G%U%)%k%H%"%/%7%g%s$,(B NULL $B$N;~!"$I$N%k!<%k$K$b%^%C%A$7$J$1$l$P(B
122 * ccConvchar() $B$,(B -1 $B$rJV$9$h$&$K=$@5(B
123 * version 8.7 91/03/25
124 * $BA0$N%P!<%8%g%s$N=$@5$K$h$j!"C1$K%7%U%H%-!<$d%3%s%H%m!<%k%-!<$r(B
125 * $B2!$7$?$@$1$G%G%U%)%k%H%"%/%7%g%s$,8F$P$l$k$h$&$K$J$C$?$,!"$3$l$O(B
126 * $B%f!<%6$N4|BT$9$kF0:n$G$O$J$$$h$&$J5$$,$9$k$N$G!"(BXLookupString() $B$N(B
127 * $B%j%?!<%s%P%j%e!<$,(B 0 $B$N;~$K$O%G%U%)%k%H%"%/%7%g%s$r8F$P$J$$$h$&$K(B
128 * $B:F=$@5(B
129 * $B$^$?!"%G%U%)%k%H%"%/%7%g%s$,(B NULL $B$G$+$D%k!<%k$K%^%C%A$7$J$$;~$K(B
130 * ccConvchar() $B$,(B -1 $B$rJV$9$h$&$K$7$?$,!"%G%U%)%k%H%"%/%7%g%s$NCM$K(B
131 * $B$h$C$F%j%?!<%s%P%j%e!<$,JQ$o$k$N$OJQ$@$7!"(B-1 $B$rJV$9$N$O%(%i!<$,(B
132 * $B5/$3$C$?$_$?$$$J$N$G!"7k6I%G%U%)%k%H%"%/%7%g%s$,(B NULL $B$G$"$k$+(B
133 * $B$I$&$+$K4X$o$i$:%^%C%A$7$?;~$O(B 1$B!"%^%C%A$7$J$$;~$O(B 0 $B$rJV$9(B
134 * $B$h$&$K=$@5(B
135 * $B$3$NJQ99$K$h$j(B ccConvchar() $B$N%j%?!<%s%P%j%e!<$,(B 0 $B$+$I$&$+%A%'%C%/(B
136 * $B$7$F$$$?%"%W%j%1!<%7%g%s$OF0$+$J$/$J$k$,!":#$^$G(B ccConvchar() $B$N(B
137 * $B%j%?!<%s%P%j%e!<$ODj5A$7$F$$$J$+$C$?$N$G$3$l$O$=$N%"%W%j%1!<%7%g%s$N(B
138 * $B@UG$(B
139 * version 9.0 91/08/15
140 * $BJ8;z$N%G!<%?7?$H$7$F:#$^$G$:$C$H(B wchar_t $B$r;H$C$F$$$?$,!"(Bwchar_t $B$N(B
141 * $BDj5A$,5!<o$K$h$C$F0[$J$k$?$a!"(Bwchar $B$H$$$&7?$KJQ99$9$k!#K\Ev$O(B
142 * Wnn $B$N<!4|%P!<%8%g%s$K9g$o$;$?$$$N$G8e$G:F$SJQ99$9$k2DG=@-$,$"$k(B
143 * version 9.1 91/09/18
144 * Files $B9=B$BN$N(B index $B$H$$$&L>A0$N%U%#!<%k%I$,!"(BSystemV $B7O$N%^%7%s(B
145 * $B$@$H(B strchr $B$KJQ$o$C$F$7$^$&$N$G(B findex $B$H$$$&L>A0$KJQ99(B
146 * version 9.2 91/09/23
147 * DEBUG $B$,Dj5A$5$l$F$$$k$HJQ49%k!<%k$,%@%s%W$5$l$F$7$^$&$N$O(B kinput2
148 * $B$G;HMQ$9$k>l9g:$$k$N$G!"(BDEBUG $B$r(B DEBUG_CCONV $B$KJQ99(B
149 * version 10.0 91/10/01
150 * R5 contrib $B8~$1$N%j%j!<%9$K$"$?$C$F%P!<%8%g%sHV9f$r=$@5(B
151 * version 10.1 92/06/05
152 * Display $B9=B$BN$N(B mode_switch $B$r;2>H$7$F$$$?$,!"(BDisplay $B9=B$BN$O(B
153 * $BK\Mh(B opaque $B$G$"$j!"Cf$N%a%s%P!<$rD>@\%"%/%;%9$9$k$N$O$^$:$$$N$G(B
154 * mode_switch $B$NCM$r<+J,$G7W;;$9$k$h$&$KJQ99(B
155 * version 10.2 94/04/21
156 * $B4X?t(B eproc $B$O(B varargs.h/stdarg.h $B$r;H$o$:$K=q$+$l$F$$$?$,!"(B
157 * $B0\?"@-$KLdBj$,$"$k(B (int $B$H(B long $B$N%5%$%:$,0[$J$k%^%7%s$J$I(B)
158 * $B$N$G=$@5(B
159 * version 10.3 97/09/17
160 * $B$J$f$?$5$s(B@$BElBg$K$h$k5!G=3HD%%Q%C%A(B ($B%U%!%s%/%7%g%s%G%#%9%Q%C%A%c$N(B
161 * $BJV$jCM$G;D$j$N4X?t$N<B9T$r%9%-%C%W$G$-$k(B) $B$N<h$j9~$_(B
162 * version 10.4 97/11/20
163 * $BF1$8%U%!%$%k$KBP$7$F(B fclose $B$rJ#?t2s8F$s$G$$$F!"(Blibc $B$N<BAu$K(B
164 * $B$h$C$F$O%3%"%@%s%W$9$k$H$$$&%P%0$r=$@5!#$D$$$G$KDj5A%U%!%$%k$N(B
165 * $BFI$_9~$_ESCf$G%(%i!<$K$J$C$?;~$K%/%m!<%:$7K:$l$F$$$?$N$G9g$o$;$F(B
166 * $B=$@5!#(B
167 * version 10.5 98/12/28
168 * $B$J$f$?$5$s(B@$BElBg$K$h$k$5$i$J$k5!G=3HD%%Q%C%A(B ($B<+F03NDj5!G=(B) $B$N<h$j9~$_(B
169 * version 10.6 99/01/07
170 * $B%=!<%9$N4A;z%3!<%I$r(B SJIS $B$+$i(B EUC $B$KJQ49!#$?$@$7$3$l$OFbIt$N(B
171 * $B4IM}>e$NOC$G!"G[I[MQ%=!<%9$O85!9(B JIS $B%3!<%I$K$J$C$F$$$k!#(B
172 * version 10.7 99/04/02
173 * $B=i4|2=;~$N%(%i!<%A%'%C%/$N6/2=!"$H$$$&$+%P%0=$@5!#JQ49%k!<%kDj5A(B
174 * $B%U%!%$%k$K%k!<%k$,Dj5A$5$l$F$$$J$+$C$?>l9g(B ($B$D$^$j4V0c$C$FA4A3(B
175 * $BJL$N%U%!%$%k$rFI$_9~$s$G$7$^$C$?>l9g(B) $B$K%(%i!<$K$9$k!#(B
176 * version 10.8 99/05/07
177 * $B<+F03NDj5!G=$,!"JQ49%k!<%kDj5A%U%!%$%k$G$N;XDj$K4X$o$i$:(B
178 * $B>o$K%*%s$K$J$C$F$7$^$&$H$$$&%P%0$r=$@5!#(B
179 */
180
181 /*
182 * $B;HMQK!(B
183 *
184 * $B;HMQK!$O3d9g4JC1$G$"$k!#:G=i$KJQ49%k!<%kDj5A%U%!%$%k$rFI$_9~$`$?$a$K(B
185 * ccParseRule() $B$r%3!<%k$9$k!#(B
186 * $B<!$KJQ49%P%C%U%!$r:n$k$?$a$K(B ccCreateBuf() $B$r8F$S!"%P%C%U%!$r:n$k!#(B
187 * $B$3$N;~$K!";HMQ$9$k%k!<%k$d<o!9$N%3!<%k%P%C%/4X?t$r;XDj$9$k!#(B
188 * $BJQ49%k!<%k$HJQ49%P%C%U%!$OJ#?t;}$D$3$H$,$G$-$k!#(B
189 * $B$^$?!"A0$N%P!<%8%g%s$H$N8_49@-$N$?$a$K!"JQ49%k!<%k$NFI$_9~$_$H(B
190 * $BJQ49%P%C%U%!$N:n@.$rF1;~$K9T$J$&!"(BccInit() $B$H$$$&4X?t$bMQ0U$5$l$F$$$k!#(B
191 *
192 * $B$"$H$O%-!<%W%l%9$N%$%Y%s%H$,Mh$?$i(B ccConvchar() $B$r8F$V$@$1$G$"$k!#(B
193 * $B$3$N%U%!%s%/%7%g%s$,JQ49$r9T$J$$!"E,Ev$J%3!<%k%P%C%/%k!<%A%s$r8F$V!#(B
194 *
195 * $B8e$OI,MW$K1~$8$FMQ0U$5$l$F$$$k$=$NB>$N%U%!%s%/%7%g%s$r8F$Y$P$h$$!#(B
196 */
197
198 /*
199 * $BJQ49$N;EAH$_(B
200 *
201 * $B$3$NF~NOJ8;zJQ49$N;EAH$_$rM}2r$9$k$?$a$N%-!<%o!<%I$O<!$N(B3$B$D$G$"$k!#(B
202 * $B!&%b!<%I(B
203 * $B!&JQ49%k!<%k(B
204 * $B!&%3%s%F%-%9%H(B
205 *
206 * $B!&%b!<%I(B
207 * $BF~NOJ8;zJQ49$K$O!V%b!<%I!W$,$"$k!#$3$l$ONc$($P!"(B
208 * $B!V%m!<%^;z2>L>JQ49$r$7$F$+$J$rF~NO$9$k%b!<%I!W$H$+(B
209 * $B!V%"%k%U%!%Y%C%H$rF~NO$9$k%b!<%I!W$H$$$C$?$b$N$G$"$k!#(B
210 * $B%b!<%I$4$H$K0[$J$kJQ49%k!<%k$,@_Dj$G$-$k!#EvA3%b!<%I$N@ZBX$($b(B
211 * $BJQ49%k!<%k$H$7$F5-=R$G$-$k!#(B
212 *
213 * $B!&JQ49%k!<%k(B
214 * $BJQ49%k!<%k$O(B4$B$D$N9`L\$+$i9=@.$5$l$k!#(B
215 * $BF~NO%-!<(B
216 * $B%3%s%F%-%9%HJ8;zNs(B
217 * $BJQ497k2LJ8;zNs(B
218 * $B%U%!%s%/%7%g%s(B
219 * $B$3$N$&$A!"F~NO%-!<$H%3%s%F%-%9%HJ8;zNs$,%k!<%k$N%^%C%A%s%0$K;H$o$l$k!#(B
220 *
221 * $BF~NO%-!<$O%-!<%3!<%I$r;XDj$9$k$b$N$G!"(BX $B$N%-!<%$%Y%s%H%3!<%I$G(B
222 * $B;XDj$9$kJ}K!$H!"$=$l$r(B XLookupString $B$7$?7k2L$N%-%c%i%/%?%3!<%I$G(B
223 * $B;XDj$9$kJ}K!$H$N(B2$BDL$j$,$"$k!#(B
224 *
225 * $B%3%s%F%-%9%HJ8;zNs$O!"$=$l$^$G$K$I$N$h$&$JJ8;z$,F~NO$5$l$?$+$r(B
226 * $B;XDj$9$k$b$N$G$"$k!#(B
227 *
228 * $BJQ497k2LJ8;zNs$O$=$NL>$NDL$j!"JQ497k2L$N;XDj$G!"%^%C%A$7$?(B
229 * $B%3%s%F%-%9%H$,$3$NJQ497k2L$KCV$-$+$o$k!#(B
230 *
231 * $B%U%!%s%/%7%g%s$O%k!<%k$,%^%C%A$7$?$H$-$K<B9T$5$l$k%U%!%s%/%7%g%s(B
232 * ("$BJQ49(B" $B$H$+(B "$B3NDj(B" $B$H$+(B) $B$N;XDj$G$"$k!#%U%!%s%/%7%g%s$OJ#?t(B
233 * $B;XDj$9$k$3$H$b$G$-$k!#(B
234 *
235 * $BNc$r$"$2$k$H!"(B
236 * $B!V(B"ky" $B$HF~$C$F$$$k$H$3$m$G(B 'a' $B$H$$$&%-!<$,2!$5$l$?$i(B
237 * "$B$-$c$C(B!" $B$HJQ49$7!"%Y%k$rLD$i$9!W(B
238 * $B$H$$$&%k!<%k(B ($B$"$s$^$j0UL#$J$$$1$I(B) $B$G!"(B
239 * 'a' $B$,F~NO%-!<!"(B
240 * "ky" $B$,%3%s%F%-%9%H!"(B
241 * "$B$-$c$C(B!" $B$,JQ497k2L!"(B
242 * <$B%Y%k$rLD$i$9(B> $B$,%U%!%s%/%7%g%s(B
243 * $B$H$$$&$3$H$K$J$k!#(B
244 *
245 * $B!&%3%s%F%-%9%H(B
246 * $B0J>e$N$h$&$K!"%3%s%F%-%9%H$H$$$&$N$O$=$l$^$G$K$I$N$h$&$JJ8;z$,(B
247 * $BF~NO$5$l$F$$$J$1$l$P$J$i$J$$$+$r;XDj$9$k$b$N$G$"$k!#(B
248 * $B$=$l$HF1;~$K$=$NJ8;z$rJQ497k2L$HCV$-JQ$($k$3$H$r;XDj$9$k$b$N(B
249 * $B$G$b$"$k!#(B
250 *
251 * $B%3%s%F%-%9%H$O6uJ8;zNs$G$b$h$$!#$=$N$H$-$K$O$=$l$^$G$K$I$N$h$&$J(B
252 * $BJ8;z$,F~NO$5$l$?$+$K$+$+$o$i$:!"%^%C%A%s%0$,5/$3$k!#(B
253 *
254 * $B%3%s%F%-%9%H$OH>3Q$N>l9gBgJ8;z>.J8;z$r6hJL$7$J$$!#(B
255 * $B$I$A$i$K$b%^%C%A$9$k!#$?$@$7!"(Bcasesensitive $B$r;XDj$9$k$3$H$G(B
256 * $BBgJ8;z>.J8;z$r6hJL$9$k$h$&$K$9$k$3$H$b$G$-$k!#(B
257 *
258 * autofix $B$r;XDj$9$k$H!"%3%s%F%-%9%H$,$J$$>uBV$G%3%s%F%-%9%H$KJ8(B
259 * $B;z$,DI2C$5$l$kD>A0$K<+F03NDj%U%!%s%/%7%g%s$,8F$P$l$k!#(B
260 *
261 * $B!&JQ49$N<B:](B
262 * $B$5$F!"$I$N$h$&$K$7$FJQ49$,9T$J$o$l$k$N$+$r4JC1$K=q$$$F$_$k!#(B
263 *
264 * $B%-!<%W%l%9%$%Y%s%H$r0z?t$K$7$F(B ccConvchar() $B$,8F$P$l$k!#(B
265 * $B$9$k$H!"$^$:$O%$%Y%s%H%3!<%I$G%+%l%s%H%b!<%I$GDj5A$5$l$F$$$k(B
266 * $BJQ49%k!<%k$NCf$+$i%^%C%A$9$k$b$N$rC5$9!#C5:w$O%k!<%k$N5-=R=g$K(B
267 * $B9T$J$o$l!":G=i$K%^%C%A$7$?$b$N$,A*$P$l$k!#(B
268 * $B$b$7%^%C%A$9$k%k!<%k$,$J$1$l$P!":#EY$O%$%Y%s%H%3!<%I$r(B
269 * XLookupString() $B$GJQ49$7$?%-%c%i%/%?%3!<%I$G!"%^%C%A$9$k$b$N$rC5$9!#(B
270 *
271 * $B$=$l$G$b%^%C%A$9$k%k!<%k$,8+$D$+$i$J$+$C$?$H$-$K$O!"%G%U%)%k%H(B
272 * $B%"%/%7%g%s$N%3!<%k%P%C%/%k!<%A%s$,8F$P$l$k!#(B
273 *
274 * $B%^%C%A$9$k%k!<%k$,8+$D$+$l$P!"JQ497k2LJ8;zNs$X$NCV$-49$($r9T$J$&!#(B
275 * $B$D$^$j!"$^$:%k!<%k$K5-=R$5$l$F$$$k%3%s%F%-%9%HJ8;zNs$NJ8;z?tJ,$@$1(B
276 * 1$BJ8;z:o=|MQ$N%3!<%k%P%C%/%k!<%A%s$,8F$P$l!"$=$N8eJQ497k2LJ8;zNs$,(B
277 * 1$BJ8;zF~NOMQ$N%3!<%k%P%C%/%k!<%A%s$r8F$s$GF~NO$5$l$k!#$=$N:]$K(B
278 * $B%3%s%F%-%9%H$,6u$G$"$C$?>l9g$O!"<+F03NDjMQ$N%3!<%k%P%C%/%k!<%A%s$,(B
279 * $B8F$P$l$k!#(B
280 * $B$=$N%k!<%k$K%U%!%s%/%7%g%s$,;XDj$5$l$F$$$l$P%G%#%9%Q%C%AMQ$N(B
281 * $B%3!<%k%P%C%/%k!<%A%s$,8F$S=P$5$l$k!#(B
282 *
283 * $B%U%!%s%/%7%g%s$,B>$N%b!<%I$X$N@ZBX$($@$C$?>l9g$K$O>/$7J#;($G$"$k!#(B
284 * $B$=$N$H$-$K$O!"$^$:(B EXITMODE $B$H$$$&5?;w%-!<$r0z?t$K$7$F(B ccConvchar()
285 * $B$,8F$P$l$k!#$3$l$O$"$k%b!<%I$+$iH4$1$k:]$K2?$+=hM}$r$7$?$$!"(B
286 * $B$H$$$&$H$-$N$?$a$K$"$k!#$=$N8e%+%l%s%H%b!<%I$r?7$7$$%b!<%I$K$7$F!"(B
287 * $B:#EY$O(B ENTERMODE $B$H$$$&5?;w%-!<$r0z?t$K$7$F(B ccConvchar $B$,8F$P$l$k!#(B
288 * $B$3$l$K$h$C$F$"$k%b!<%I$KF~$C$?$H$-$N=hM}$r$9$k$3$H$,$G$-$k!#(B
289 * $B$=$N8e!"%3%s%F%-%9%H$,%/%j%"$5$l!":G8e$K!"%b!<%IJQ99DLCNMQ$N(B
290 * $B%3!<%k%P%C%/4X?t$,;XDj$5$l$F$$$l$P$=$l$,8F$P$l$k!#(B
291 */
292
293 /*
294 * ccdef $B%U%!%$%k$N=q$-J}(B
295 *
296 * $BF~NOJ8;zJQ49Dj5A%U%!%$%k(B (ccdef $B%U%!%$%k$H>JN,$9$k(B) $B$N=q$-J}$r4JC1$K5-$9!#(B
297 *
298 * ccdef $B%U%!%$%k$O<!$N(B3$B$D$N%Q!<%H$+$i9=@.$5$l$k!#(B
299 * $B$3$l$i$O$3$N=g$KJB$s$G$$$J$1$l$P$J$i$J$$!#(B
300 *
301 * <$B%b!<%I@k8@(B>
302 * <$B=i4|%b!<%I@k8@(B>
303 * <$B3F%b!<%I$NJQ49%k!<%k5-=R(B>
304 *
305 * <$B%b!<%I@k8@(B> $B$O;HMQ$9$k%b!<%IL>$r@k8@$9$k$b$N$G!"%U%)!<%^%C%H$O<!$NDL$j!#(B
306 * defmode Mode1 Mode2 Mode3...
307 * $B;HMQ$9$k%b!<%I$O$9$Y$F$3$3$G@k8@$7$F$*$+$J$/$F$O$J$i$J$$!#(B
308 *
309 * <$B=i4|%b!<%I@k8@(B> $B$O(B cconv $B$,=i4|2=$5$l$?$H$-$N%b!<%I$r;XDj$9$k$b$N$G$"$k!#(B
310 * $B%U%)!<%^%C%H$O<!$NDL$j!#(B
311 * initialmode Mode3
312 *
313 *
314 * <$B3F%b!<%I$NJQ49%k!<%k5-=R(B> $B$,<B:]$NJQ49%k!<%k$r5-=R$9$kItJ,$G$"$k!#(B
315 * 1$B$D$N%b!<%I$KBP$9$k5-=R7A<0$O<!$NDL$j!#(B
316 *
317 * mode <$B%b!<%IL>(B> "<$B%W%m%s%W%H(B>" [fallthrough <$B%b!<%IL>(B>]
318 * "<$B%3%s%F%-%9%H(B>" <$B%-!<(B> "<$BJQ497k2L(B>" [<$B%U%!%s%/%7%g%s(B>...]
319 * :
320 * :
321 * endmode
322 *
323 * <$B%b!<%IL>(B> $B$O(B <$B%b!<%I@k8@(B> $B$G@k8@$7$?%b!<%IL>$G$"$k!#(B
324 *
325 * <$B%W%m%s%W%H(B> $B$O%b!<%I$rI=$9J8;zNs$G$"$k!#$3$l$O%+%l%s%H%b!<%I$rI=<($9$k(B
326 * $B:]$K;HMQ$5$l$k$b$N$G!"4A;z$G$b$h$$!#D9$5$O<+M3$G$"$k$,!"M>$jD9$$$H(B
327 * $B$9$Y$FI=<($5$l$k$+$I$&$+5?Ld$G$"$k!#(B
328 * $B$=$N8e$N!"(B[ ] $B$K$/$k$^$l$?ItJ,$O>JN,2DG=$J$3$H$r<($9!#(B
329 * $B$b$7$"$l$P!"$3$N%b!<%I$G%^%C%A$9$k%k!<%k$,$J$+$C$?$H$-$K$O(B fallthrough $B$G(B
330 * $B;XDj$5$l$k%b!<%I$N%k!<%k$,0z$-B3$$$FC5$5$l$k!#(B
331 *
332 * mode $B$H(B endmode $B$K$O$5$^$l$?ItJ,$,8D!9$NJQ49%k!<%k$G$"$k!#(B
333 * <$B%3%s%F%-%9%H(B> $B$,%3%s%F%-%9%HJ8;zNs$G$"$k!#$3$3$G$O(B '^' $B$H(B '\' $B$,FC<l(B
334 * $B%-%c%i%/%?$H$7$F;HMQ$G$-$k!#(B"^C" $B$H=q$1$P$=$l$O(B $B%3%s%H%m!<%k(B-C $B$rI=$9!#(B
335 * $B%P%C%/%9%i%C%7%e(B '\' $B$O<!$NJ8;z$NFC<lJ8;z$H$7$F$N0UL#$r$J$/$9!#(B
336 * '^' $B<+?H$r;H$$$?$1$l$P(B "\^" $B$H%(%9%1!<%W$9$k!#F1MM$K(B '\' $B<+?H$r;H$$$?$1$l$P(B
337 * "\\" $B$H=E$M$l$P$h$$!#(B
338 *
339 * <$B%-!<(B> $B$OF~NO$5$l$?%-!<$G!"(BX $B$N%-!<%$%Y%s%H!"%-%c%i%/%?%3!<%I!"(B
340 * $B%a%?%-%c%i%/%?!"5?;w%-!<$N$$$:$l$+$G;XDj$9$k!#(B
341 *
342 * X $B$N%-!<%$%Y%s%H$O!"4pK\E*$K!"(B
343 * $B%b%G%#%U%!%$%"(B-Keysym$BL>(B
344 * $B$GI=$9!#Nc$($P!"(B
345 * Tab
346 * control-a
347 * shift-control-space
348 * $B$J$I$G$"$k!#(B
349 *
350 * $B%-%c%i%/%?%3!<%I$r=q$/$K$O!"%7%s%0%k%/%)!<%H$r;HMQ$9$k!#Nc$($P(B
351 * 'a'
352 * '^['
353 * '\''
354 * $B$J$I$G$"$k!#$o$+$k$H;W$&$,!"(B2$BHVL\$O(B ESCAPE$B!"(B3$BHVL\$O%7%s%0%k%/%)!<%H(B
355 * $B$=$N$b$N$r<($9!#(B
356 *
357 * $B%a%?%-%c%i%/%?$O<!$N(B10$B<oN`$,;HMQ$G$-$k!#(B
358 * $B%-!<%$%Y%s%H$G$b%-%c%i%/%?%3!<%I$G$b%^%C%A$9$k$b$N(B
359 * @any - $B2?$K$G$b%^%C%A$9$k(B
360 * $B%-!<%$%Y%s%H$K%^%C%A$9$k$b$N(B
361 * @raw - $B%-!<%$%Y%s%H$J$i2?$K$G$b%^%C%A(B
362 * @func - $B%U%!%s%/%7%g%s%-!<$K%^%C%A(B
363 * @cursor - $B%+!<%=%k%-!<$K%^%C%A(B
364 * @keypad - $B%F%s%-!<%Q%C%I$N%-!<$K%^%C%A(B
365 * @modifier - $B%b%G%#%U%!%$%"(B (shift, control $B$J$I(B) $B$K%^%C%A(B
366 * @non-ascii - $B%-!<%$%Y%s%H$N$&$A!"(BXLookupString() $B$N7k2L$,(B
367 * $BD9$5(B0$B!"$D$^$jBP1~$9$k%"%9%-!<J8;z$,$J$$$b$N$K%^%C%A(B
368 * $B%-%c%i%/%?%3!<%I$K%^%C%A$9$k$b$N(B
369 * @ascii - $B%-%c%i%/%?%3!<%I$J$i2?$K$G$b%^%C%A(B
370 * @printable - $B0u;z2DG=J8;z(B (0x20 $B!e(B c $B!e(B 0x7e) $B$K%^%C%A(B
371 * @control - $B%3%s%H%m!<%kJ8;z(B (0x00 $B!e(B c $B!e(B 0x1f) $B$K%^%C%A(B
372 *
373 * $B5?;w%-!<$OK\Ev$N%-!<F~NO$G$O$J$$!#$3$l$K$O(B2$B<oN`$"$k!#(B
374 * ENTERMODE - $B$"$k%b!<%I$KF~$C$?$H$-$K2>A[E*$KF~NO$5$l$k%-!<(B
375 * EXITMODE - $B$"$k%b!<%I$+$iH4$1$k$H$-$K2>A[E*$KF~NO$5$l$k%-!<(B
376 *
377 * <$BJQ497k2L(B> $B$OJQ497k2L$r;XDj$9$k!#$3$3$G$O(B '&'$B!"(B'/'$B!"(B'^'$B!"(B'\' $B$N(B4$B<oN`$N(B
378 * $BFC<lJ8;z$,;HMQ$G$-$k!#(B'^' $B$H(B '\' $B$K$D$$$F$O(B <$B%3%s%F%-%9%H(B> $B$HF1$8$G$"$k!#(B
379 * '&' $B$O(B $B%^%C%A$7$?(B <$B%-!<(B> $B$HCV$-49$($i$l$k!#(B<$B%-!<(B> $B$,%$%Y%s%H$N>l9g$K$O(B
380 * $B$=$N%$%Y%s%H$r(B XLookupString() $B$7$?7k2L$NJ8;zNs$GCV$-49$o$k!#(B
381 * '/' $B$,=P$F$/$k$H!"$=$3$G%3%s%F%-%9%H$O%/%j%"$5$l$k!#(B
382 *
383 * <$B%U%!%s%/%7%g%s(B> $B$O$J$/$F$b$h$$!#$"$l$PJQ49$N8e!"%U%!%s%/%7%g%s$,(B
384 * $B<B9T$5$l$k!#%U%!%s%/%7%g%s$rJ#?t;XDj$9$k$3$H$b$G$-!"$=$N>l9g$K$O(B
385 * $B;XDj$5$l$?=g=x$G<B9T$5$l$k!#%U%!%s%/%7%g%s$N6h@Z$j$O6uGrJ8;z$G$"$k!#(B
386 * func1 func2 func3
387 * $B$N$h$&$K;XDj$9$k!#(B
388 * $B%U%!%s%/%7%g%s$H$7$F%+%l%s%H%b!<%I$NJQ99$r;XDj$9$k$3$H$b$G$-$k!#(B
389 * goto <$B%b!<%IL>(B>
390 * $B$G%+%l%s%H%b!<%I$,JQ$o$k!#$3$N%b!<%IL>$H$7$F(B "PREV" $B$,;HMQ$G$-$k!#(B
391 * $B$3$l$O0l$DA0$N%b!<%I$rI=$9!#(B
392 * $B$^$?!":FJQ49$r;XDj$9$k$3$H$b$G$-$k!#(B<$B%U%!%s%/%7%g%s(B>$B$H$7$F(B
393 * redo
394 * $B$H=q$/$H!"$b$&0lEY%^%C%A$9$k%k!<%k$r:G=i$+$iC5$7$K$$$/!#$?$@$7$=$NA0$K(B
395 * <$B%3%s%F%-%9%H(B> $B$,(B <$BJQ497k2L(B> $B$KCV$-49$($i$l$F$$$k$3$H$KCm0U!#$3$N5!G=$r(B
396 * $B;H$&;~$K$OL58B%k!<%W$K4Y$i$J$$$h$&$KCm0U$7$F%k!<%k$r=q$+$J$1$l$P$J$i$J$$!#(B
397 * $B0l1~0BA4:v$H$7$F(B redo $B$,(B MAXREDO (=20) $B2s8F$P$l$k$H<:GT$9$k$h$&$K(B
398 * $B$J$C$F$$$k!#(B
399 * $BCm0U(B: goto $B$H(B redo $B$N$"$H$K;XDj$5$l$?%U%!%s%/%7%g%s$O<B9T$5$l$J$$!#(B
400 * $B$D$^$j!"(B
401 * func1 goto XX func2
402 * $B$@$H!":G=i$K(B func1 $B$,<B9T$5$l!"<!$K%+%l%s%H%b!<%I$,(B XX $B$KJQ99$5$l$k$,(B
403 * func2 $B$O<B9T$5$l$J$$!#(B
404 * $B$^$?!"<!$KF~NO$7$?%-!<$K%b%G%#%U%!%$%d$rDI2C$9$k$3$H$b$G$-$k!#(B<$B%U%!(B
405 * $B%s%/%7%g%s(B>$B$H$7$F!"(B
406 * add-modifier-shift
407 * add-modifier-control
408 * add-modifier-lock
409 * add-modifier-mod1
410 * add-modifier-mod2
411 * add-modifier-mod3
412 * add-modifier-mod4
413 * add-modifier-mod5
414 * $B$r=q$/$H<!$KF~NO$7$?%-!<$K%b%G%#%U%!%$%d$rDI2C$9$k!#Nc$($P!"(B
415 * "" '^[' "" add-modifier-mod1
416 * "" mod1-i "" shrink-s
417 * $B$H=q$$$F$*$/$H!"(Bmod1-i $B$HF~NO$7$F$b!"(B^[ i $B$HF~NO$7$F$b(B shrink-s $B$,(B
418 * $B<B9T$5$l$k!#(B
419 *
420 * $B:G8e$K=EMW$JCm0U$r0l$D!#(Bccdef $B%U%!%$%k$O(B EUC $B%3!<%I$G=q$+$l$F$$$J$1$l$P(B
421 * $B$J$i$J$$!#(B
422 *
423 * $B$J$*!"=q$-K:$l$?$,(B '#' $B$G;O$^$k9T$O%3%a%s%H9T$G$"$k!#(B
424 *
425 * $B$^$?!"B>$N%U%!%$%k$r(B include $BJ8$r;H$C$F%$%s%/%k!<%I$9$k$3$H$,$G$-$k!#(B
426 * $B=q<0$O(B
427 * include $B%U%!%$%kL>(B
428 * $B$G$"$k!#%U%!%$%kL>Cf$K6uGrJ8;z$,4^$^$l$k;~$K$O(B ' $B$+(B " $B$G0O$a$P$h$$!#(B
429 * $B%U%!%$%kL>$,AjBP%Q%9L>$N;~$K$O$^$:%+%l%s%H%G%#%l%/%H%j$,C5$5$l!"$J$1$l$P(B
430 * $B4D6-JQ?t(B CC_DEF_PATH $B$,Dj5A$5$l$F$$$l$P$=$l$K;XDj$5$l$?%G%#%l%/%H%j(B
431 * (':' $B$G6h@Z$C$FJ#?t;XDj$9$k$3$H$,$G$-$k(B) $B$N2<$,C5$5$l!"$=$l$G$b$J$1$l$P(B
432 * CCDEFPATH (/usr/lib/X11/ccdef/) $B$N2<$,C5$5$l$k!#(B
433 */
434
435 /*
436 * $B%$%s%?!<%U%'%$%9!&%U%!%s%/%7%g%s(B
437 *
438 * - $BJQ49%k!<%kFI$_9~$_(B -
439 *
440 * ccRule ccParseRule(char *deffile, void (*errprint)())
441 * $BF~NOJ8;zJQ49%U%!%$%k$rFI$_9~$`!#(B
442 * deffile $B$G;XDj$5$l$k%U%!%$%k$+$iJQ49%k!<%k$rFI$_9~$`!#$b$7$b(B
443 * deffile $B$,(B NULL $B$N;~$O!"4D6-JQ?t(B CC_DEF $B$NCM$,;HMQ$5$l$k!#(B
444 * deffile $B$,AjBP%Q%9L>$N;~$K$O$^$:%+%l%s%H%G%#%l%/%H%j$N2<$,C5$5$l!"(B
445 * $B$J$1$l$P!"4D6-JQ?t(B CC_DEF_PATH $B$G;XDj$5$l$?%G%#%l%/%H%j$N2<$,(B
446 * $BC5$5$l$k!#(BCC_DEF_PATH $B$K$O4D6-JQ?t(B PATH $B$J$I$HF1$8$/J#?t$N(B
447 * $B%G%#%l%/%H%j$r(B ':' $B$G6h@Z$C$F;XDj$9$k$3$H$,$G$-$k!#(B
448 * $B$J$1$l$P(B CCDEFPATH (/usr/lib/X11/ccdef) $B$N2<$,C5$5$l$k!#(B
449 * $BF1$8JQ49%U%!%$%k$KBP$7$FJ#?t2s(B ccParseRule() $B$r9T$J$C$F$b!"(B
450 * $B<B:]$KFI$_9~$^$l$k$N$O:G=i$N0l2s$@$1$G$"$k!#(B
451 * errprint $B$O%(%i!<I=<(MQ$N%U%!%s%/%7%g%s$G$"$k$,!"(B NULL $B$N>l9g$K$O(B
452 * stderr $B$X(B fprintf() $B$r;HMQ$7$F=PNO$5$l$k!#(B
453 * $B@.8y;~$K$OJQ49%k!<%k$r!"<:GT;~$K$O(B NULL $B$rJV$9!#(B
454 *
455 * void ccFreeRule(ccRule rule)
456 * $B;HMQ$7$J$/$J$C$?JQ49%k!<%k$G;H$o$l$F$$$?NN0h$r2rJ|$9$k!#(B
457 *
458 *
459 * - $BJQ49%P%C%U%!:n@.(B -
460 *
461 * ccBuf ccCreateBuf(ccRule rule, int contextsize,
462 * char *functable[], int functablesize,
463 * void (*default_action)(), void (*insert_char)(),
464 * void (*delete_char)(), int (*function_dispatch)(),
465 * void (*mode_notify)(), void (*auto_fix)(),
466 * caddr_t client_data);
467 * $BJQ49%P%C%U%!$r:n$j!"$=$l$rJV$9!#(B
468 * rule $B$G!"$I$NJQ49%k!<%k$r;HMQ$9$k$+;XDj$9$k!#(B
469 * contextsize $B$K$O%3%s%F%-%9%H$r2?J8;zJ];}$9$k$+$r;XDj$9$k!#(B
470 * $B$h$[$IFC<l$J%k!<%k$,$J$$8B$j!"IaDL$O?tJ8;z$GB-$j$k$O$:$G$"$k!#(B
471 * functable $B$O%U%!%s%/%7%g%sL>$N0lMwI=!"(Bfunctablesize $B$O$=$N%5%$%:(B
472 * $B$G$"$k!#(B
473 * default_action $B$O!"F~NO$5$l$?%-!<$,$I$N%k!<%k$K$b%^%C%A$7$J$+$C$?(B
474 * $B$H$-$K8F$P$l$k%U%!%s%/%7%g%s$G$"$k!#(BNULL $B$r;XDj$9$k$H!"%^%C%A(B
475 * $B$7$J$+$C$?$H$-$K$O2?$b5/$3$i$J$$!#(B
476 * insert_char, delete_char $B$O$=$l$>$l(B 1$BJ8;zA^F~(B / 1$BJ8;z:o=|MQ$N(B
477 * $B%U%!%s%/%7%g%s$G$"$k!#(B
478 * function_dispatch $B$K$O%U%!%s%/%7%g%s%3!<%k$N$?$a$N%G%#%9%Q%C%A(B
479 * $B%k!<%A%s$r;XDj$9$k!#%G%#%9%Q%C%A4X?t$,(B True $B$rJV$;$P<!$N%U%!%s%/%7%g(B
480 * $B%s$r8F$V$,!"(BFalse $B$rJV$;$P(B goto $B$N$h$&$KB3$/4X?t$OL5;k$9$k!#(B
481 * auto_fix $B$O!"<+F03NDj$N$?$a$N%k!<%A%s$r;XDj$9$k!#(BNULL $B$r;XDj$9$k$H(B
482 * $B<+F03NDj$O$5$l$J$$!#(B
483 * mode_notify $B$O!"%b!<%I$,JQ$o$C$?;~$K8F$S=P$5$l$k%U%!%s%/%7%g%s$G$"$k!#(B
484 * $B%3!<%k%P%C%/$NI,MW$,$J$$$H$-$O(B NULL $B$r;XDj$7$F$*$1$P$h$$!#(B
485 * client_data $B$O!"%3!<%k%P%C%/;~$K0z?t$H$7$FEO$5$l$k%G!<%?$G$"$k!#(B
486 * $B@.8y;~$K$O%P%C%U%!$r!"%(%i!<$N;~$K$O(B NULL $B$,JV$5$l$k!#(B
487 *
488 *
489 * void ccDestroyBuf(ccBuf buf)
490 * $B;HMQ$7$J$/$J$C$?JQ49%P%C%U%!$G;H$o$l$F$$$?NN0h$r2rJ|$9$k!#(B
491 *
492 *
493 * - $BJQ49(B -
494 *
495 * int ccConvchar(ccBuf buf, XKeyPressedEvent *event)
496 * X11 $B$N%-!<%\!<%I$N%W%l%9%$%Y%s%H$r<u$1<h$j!"JQ49$r9T$J$&!#(B
497 * $B9T$J$C$?7k2L!"J8;z$NA^F~!&:o=|$O(B ccCreateBuf() $B$G;XDj$5$l$?(B
498 * insert_char, delete_char $B$,8F$S=P$5$l!"%U%!%s%/%7%g%s$K$D$$$F$O(B
499 * $BF1$8$/(B ccCreateBuf() $B$G;XDj$5$l$k(B function_dispatch $B$,%G%#%9%Q%C%A$N(B
500 * $B$?$a$K8F$P$l$k!#(B
501 * $B$I$N%k!<%k$K$b%^%C%A$7$J$1$l$P!"(Bdefault_action $B$,8F$P$l$k!#(B
502 * $B$I$N%k!<%k$K$b%^%C%A$7$J$+$C$?;~$K$O(B 0$B!"%^%C%A$7$?;~$K$O(B 1 $B$,(B
503 * $BJV$5$l$k!#(B
504 *
505 *
506 * - $B%+%l%s%H%b!<%I(B -
507 *
508 * int ccGetMode(ccBuf buf)
509 * $B%+%l%s%H%b!<%IHV9f$,JV$5$l$k!#(B
510 *
511 * wchar *ccGetModePrompt(ccBuf buf)
512 * $B%+%l%s%H%b!<%IL>$,(B EUC$B%W%m%;%9%3!<%I$GJV$5$l$k!#(B
513 *
514 *
515 * - $B%P%C%U%!$N;HMQ$7$F$$$k%k!<%k(B -
516 *
517 * ccRule ccGetRule(ccBuf buf)
518 * $B;XDj$5$l$?JQ49%P%C%U%!$,;HMQ$7$F$$$kJQ49%k!<%k$rJV$9!#(B
519 *
520 *
521 * - $B%3%s%F%-%9%H(B -
522 *
523 * $B%3%s%F%-%9%H$X$NJ8;z$NDI2C$d:o=|$O!"%k!<%k$K%^%C%A$7$?$H$-$K$O(B
524 * $B<+F0E*$K9T$J$o$l$k!#$^$?!"%+%l%s%H%b!<%I$NJQ99$K$H$b$J$C$F(B
525 * $B%3%s%F%-%9%H$O<+F0E*$K%/%j%"$5$l$k!#(B
526 * $B=>$C$FIaDL$O%f!<%6$,$3$l$i$N%U%!%s%/%7%g%s$r8F$VI,MW$O$J$$!#(B
527 * $B$?$@$7!"%^%C%A$7$J$+$C$?J8;z$r(B default_action $B$,A^F~$9$k$H$+!"(B
528 * $B%P%C%/%9%Z!<%9$N=hM}$r9T$J$&!"$J$I$N>l9g$K$O%f!<%6$,(B explicit $B$K(B
529 * $B8F$VI,MW$,$"$k!#(B
530 *
531 * void ccContextAppend(ccBuf buf, int c)
532 * $B%3%s%F%-%9%H$N:G8e$KJ8;z(B c (EUC $B%W%m%;%9%3!<%I(B)$B$rIU$12C$($k!#(B
533 *
534 * void ccContextDelete(ccBuf buf)
535 * $B%3%s%F%-%9%H$N:G8e$N(B1$BJ8;z$r:o=|$9$k!#(B
536 *
537 * void ccContextClear(ccBuf buf)
538 * $B%3%s%F%-%9%H$r%/%j%"$9$k!#(B
539 *
540 * void ccContextSet(ccBuf buf, wchar *cstr)
541 * $B%3%s%F%-%9%HJ8;zNs$r%;%C%H$9$k!#J8;zNs$O(B null $B%?!<%_%M!<%H$5$l$?(B
542 * EUC $B%W%m%;%9%3!<%I$G$J$1$l$P$J$i$J$$!#(B
543 * $BJ8;zNs$ND9$5$,(B ccCreateBuf() $B$G;XDj$5$l$?(B contextsize $B$h$j(B
544 * $BD9$$$H$-$K$O!":G8e$N(B contextsize $BJ8;z$,%;%C%H$5$l$k!#(B
545 *
546 * void ccContextGet(ccBuf buf, wchar *cstr)
547 * $B8=:_$N%3%s%F%-%9%HJ8;zNs$rJV$9!#J8;zNs$O(B null $B%?!<%_%M!<%H$5$l$?(B
548 * EUC $B%W%m%;%9%3!<%I$G$"$k!#(B
549 */
550
551 /*
552 * $B%3!<%k%P%C%/%U%!%s%/%7%g%s$H$=$N0z?t(B
553 *
554 * $B%G%#%9%Q%C%A%U%!%s%/%7%g%s(B:
555 * function_dispatch(int func, unsigned char *str, int nbytes,
556 * caddr_t client_data)
557 * $B%^%C%A$7$?%k!<%k$K%U%!%s%/%7%g%s$,=q$+$l$F$$$?$H$-$K(B
558 * $B8F$S=P$5$l$k!#(B
559 * $B0z?t(B func $B$O!"%U%!%s%/%7%g%sHV9f$G$"$k!#$3$l$O(B
560 * ccParseRule() $B$N0z?t$H$7$FEO$5$l$?!"(Bfunctable[] $B$N(B
561 * $B%$%s%G%C%/%9$G$"$k!#(Bstr, nbytes $B$O$3$N(B
562 * $B%U%!%s%/%7%g%s$r0z$-5/$3$7$?%-!<$NI=$9J8;zNs!#(B
563 * client_data $B$O(B ccCreateBuf() $B$N;~$K;XDj$5$l$?%G!<%?$G$"$k!#(B
564 *
565 * $B%G%U%)%k%H%"%/%7%g%sMQ%U%!%s%/%7%g%s(B:
566 * default_action(unsigned char *str, int nbytes, caddr_t client_data)
567 * $B2!$5$l$?%-!<$KBP$7$F%^%C%A$9$k%k!<%k$,$J$+$C$?$H$-$K(B
568 * $B8F$S=P$5$l$k!#(B
569 * str, nbytes $B$O%-!<$NI=$9J8;zNs!#(B
570 * client_data $B$O(B ccCreateBuf() $B$N;~$K;XDj$5$l$?%G!<%?!#(B
571 *
572 * $BJ8;zA^F~%U%!%s%/%7%g%s(B:
573 * insert_char(wchar c, caddr_t client_data)
574 * $BJQ497k2L$NJ8;z$r%"%W%j%1!<%7%g%s$KEO$9$N$K;HMQ$5$l$k!#(B
575 * c $B$O(B EUC $B%W%m%;%9%3!<%I$G$"$k!#$3$N%U%!%s%/%7%g%s$O(B
576 * 1$BJ8;z$4$H$K8F$P$l$k!#(B
577 * client_data $B$O(B ccCreateBuf() $B$N;~$K;XDj$5$l$?%G!<%?!#(B
578 *
579 * $BJ8;z:o=|%U%!%s%/%7%g%s(B:
580 * delete_char(caddr_t client_data)
581 * $BJQ497k2L$K$7$?$,$C$F:o=|$9$kJ8;z$,$"$l$P$=$NJ8;z?tJ,(B
582 * $B$3$N%U%!%s%/%7%g%s$,8F$P$l$k!#(B
583 * client_data $B$O(B ccCreateBuf() $B$N;~$K;XDj$5$l$?%G!<%?!#(B
584 *
585 * $B<+F03NDj%U%!%s%/%7%g%s(B:
586 * auto_fix(caddr_t client_data)
587 * $B%3%s%F%-%9%H$,$J$$>uBV$G%3%s%F%-%9%H$KJ8;z$,DI2C$5$l$k(B
588 * $BD>A0$K8F$P$l$k!#(B
589 * client_data $B$O(B ccCreateBuf() $B$N;~$K;XDj$5$l$?%G!<%?!#(B
590 *
591 * $B%b!<%IJQ99%U%!%s%/%7%g%s(B:
592 * mode_notify(int newmode, int oldmode, caddr_t client_data)
593 * $B%+%l%s%H%b!<%I$,JQ99$5$l$?;~$K$3$N%U%!%s%/%7%g%s$,(B
594 * $B8F$P$l$k!#(Bnewmode $B$,?7$7$$%+%l%s%H%b!<%I!"(Boldmode $B$,(B
595 * $BA0$N%+%l%s%H%b!<%IHV9f$G$"$k!#(B
596 *
597 * $B%(%i!<I=<(%U%!%s%/%7%g%s(B:
598 * error_handler(char *errstr)
599 * ccParseRule() $BCf$G!"%(%i!<$,H/@8$7$?;~$K8F$S=P$5$l$k!#(B
600 */
601
602 #ifndef lint
603 static char *rcsid = "$Id: cconv.c,v 10.10 1999/08/09 03:17:57 ishisone Exp $";
604 #endif
605
606 #include <stdio.h>
607 #include <stdlib.h>
608 #include <X11/Xlib.h>
609 #include <X11/keysym.h>
610 #include <X11/Xutil.h>
611 #include <X11/Xos.h>
612 #include "cconv.h"
613
614 #define uchar unsigned char
615 #define ushort unsigned short
616 #define ulong unsigned long
617
618 #define Malloc(size) malloc((unsigned int)(size))
619 #define Realloc(p, size) realloc((char *)(p), (unsigned int)(size))
620 #define Free(p) { if (p) (void)free((char *)(p)); }
621
622 #define Strcmp(s1, s2) strcmp((char *)(s1), (char *)(s2))
623 #define Strncmp(s1, s2, n) strncmp((char *)(s1), (char *)(s2), n)
624 #define Strcpy(s1, s2) strcpy((char *)(s1), (char *)(s2))
625 #define Strcat(s1, s2) strcat((char *)(s1), (char *)(s2))
626 #define Strlen(s) strlen((char *)(s))
627
628 #define EPROC2(efunc, format, a) { \
629 char tmp[1024]; \
630 (void)sprintf(tmp, format, a); \
631 eproc(efunc, tmp); }
632
633 /* $B%-!<%3!<%I$N%(%s%3!<%IJ}K!(B */
634 #define RAWKEY (1L<<31)
635 #define PSEUDO (1L<<30)
636 #define METAC (1L<<29)
637 #define META_ASCII 1 /* any ascii character (not useful) */
638 #define META_CONTROL 2 /* any control character */
639 #define META_RAW 3 /* any key event (not useful) */
640 #define META_ANY 4 /* anything (character or event) */
641 #define META_FUNC 5 /* any function key event */
642 #define META_CURSOR 6 /* any cursor key event */
643 #define META_KEYPAD 7 /* any keypad key event */
644 #define META_MODIFIER 8 /* any modifier key event */
645 #define META_PRINTABLE 9 /* any printable character */
646 #define META_NONASCII 10 /* key event that has no ascii interpretation */
647
648 /* pseudo key code */
649 #define ENTERMODE (ulong)(PSEUDO|1)
650 #define EXITMODE (ulong)(PSEUDO|2)
651
652 /* function code */
653 #define ENDFUNC 0xffff
654 #define MODECHANGE 0x8000
655 #define REDO 0x7fff
656 #define PREVMODE (MODECHANGE|0x1000)
657 #define FUNC_MODIFIER_SHIFT 0x7ff0
658 #define FUNC_MODIFIER_CONTROL 0x7ff1
659 #define FUNC_MODIFIER_LOCK 0x7ff2
660 #define FUNC_MODIFIER_MOD1 0x7ff3
661 #define FUNC_MODIFIER_MOD2 0x7ff4
662 #define FUNC_MODIFIER_MOD3 0x7ff5
663 #define FUNC_MODIFIER_MOD4 0x7ff6
664 #define FUNC_MODIFIER_MOD5 0x7ff7
665 #define FUNC_MODIFIER_start FUNC_MODIFIER_SHIFT
666 #define FUNC_MODIFIER_end FUNC_MODIFIER_MOD5
667
668 #define MAXREDO 20
669
670 /* key encoding */
671 #define ccEncodeKey(ev) ((ulong)XLookupKeysym(ev, 0) | (ulong)RAWKEY)
672 #define ccEncodeMask(ev) ((int)((ev)->state & 0xff))
673
674 #define ccEncodeChar(c) ((ulong)(c))
675
676 #define MATCHED_CHAR 0x8080 /* $B$3$l$O(B EUC $B$H$7$F$O(B illegal $B$J%3!<%I$J$N$G(B
677 * $BFCJL$JL\E*$KMQ$$$k(B */
678 #define CCLEAR_CHAR 0x8081 /* $B>e$KF1$8(B */
679
680 #define CANONIC(c) (((c) >= 'A' && (c) <= 'Z') ? c += ('a' - 'A') : c)
681
682 /* $B%G!<%?9=B$(B */
683 /* $BJQ49%k!<%k(B */
684 typedef struct convdesc {
685 ulong key; /* $BF~NO%-!<(B */
686 ushort mask; /* modifier mask (of X KeyEvent) */
687 ushort context; /* context$BJ8;zNs(B ($B5U=g$K3JG<$5$l$k(B) */
688 ushort result; /* $BJQ497k2LJ8;zNs(B */
689 ushort function; /* function $B%Y%/%?$N%$%s%G%C%/%9(B */
690
691 struct convdesc *next;
692 } ConvDesc;
693
694 /* $B%b!<%I$4$H$N%F!<%V%k(B */
695 typedef struct modetable {
696 char name[1024]; /* $B%b!<%IL>(B */
697 int nrule; /* $B%k!<%k$N?t(B */
698 struct convdesc *cd_head; /* $B%k!<%k(B */
699 wchar *prompt; /* $B%W%m%s%W%HJ8;zNs(B */
700
701 int mt_index;
702 struct modetable *fallthrough;
703 struct modetable *next;
704 } ModeTable;
705
706 /* ccParseRule() $B$GFbItI=8=$KJQ49$5$l$?%k!<%k(B */
707 typedef struct _ccRule {
708 char *rulefile; /* $BDj5A%U%!%$%kL>(B */
709 ccRule next; /* $B%k!<%k%j%9%H$N<!$NMWAG(B */
710 int refcnt; /* $B;2>H?t(B */
711 int nmode; /* $B%b!<%I$N?t(B */
712 struct modetable *initialmode; /* $B=i4|%b!<%I(B */
713 struct modetable *modes; /* $B%b!<%I%F!<%V%k(B */
714 wchar *strbuf; /* $B%9%H%j%s%0%P%C%U%!(B */
715 ushort *funcbuf; /* $B%U%!%s%/%7%g%s%P%C%U%!(B */
716 int nfunc; /* $B%U%!%s%/%7%g%s$N?t(B */
717 char *funcnamebuf; /* $B%U%!%s%/%7%g%sL>$N%P%C%U%!(B */
718 void (*errorfunc)(); /* $B%(%i!<%3!<%k%P%C%/(B */
719 int casesensitive; /* $BBgJ8;z>.J8;z$r6hJL$9$k$+$I$&$+(B */
720 int autofix; /* $B<+F03NDj$r$9$k$+$I$&$+(B */
721 } ccRuleRec;
722
723 static ccRule ccrules; /* $BJQ49%k!<%k$N%j%9%H(B */
724
725 /* ccCreateBuf() $B$G:n$i$l$kJQ49%P%C%U%!(B */
726 typedef struct _ccBuf {
727 ccRule rule; /* $BJQ49%k!<%k(B */
728 short *functbl;
729 void (*defaultaction)(); /* callback functions */
730 void (*insertchar)();
731 void (*deletechar)();
732 int (*executefunction)(); /* True $B$rJV$;$P=>Mh$I$*$j<!$N%U%!%s%/(B
733 $B%7%g%s$r8F$V$,!"(BFalse $B$rJV$;$P!"(B
734 goto $B$N$h$&$K<!$N4X?t$OL5;k$9$k(B */
735 void (*autofix)();
736 void (*modenotify)();
737 caddr_t client_data;
738 struct modetable *currentmode; /* $B8=:_$N%b!<%I(B */
739 struct modetable *previousmode; /* $B0l$DA0$N%b!<%I(B */
740 wchar *context;
741 wchar *contextend;
742 int contextsize;
743 unsigned int modifier; /* $B<!$NF~NO%-!<$r%b%G%#%U%!%$%d$D$-$K$9$k(B */
744 } ccBufRec;
745
746 #define STRSIZE 200
747 #define MORESTRSIZE 100
748 typedef struct {
749 wchar *strbuf;
750 wchar *strend;
751 wchar *strp;
752 } _strbufRec;
753
754 #define FUNCSIZE 20
755 #define MOREFUNCSIZE 20
756 typedef struct {
757 ushort *funcbuf; /* $B%U%!%s%/%7%g%s%Y%/%?(B */
758 ushort *funcend;
759 ushort *funcp;
760 } _funcbufRec;
761
762 #define MAXFUNC 1024 /* $B%U%!%s%/%7%g%s$N<oN`$N>e8B(B */
763 #define FUNCNAMESIZE 100
764 #define MOREFUNCNAMESIZE 50
765 typedef struct {
766 int nfunc;
767 ushort funcnames[MAXFUNC];
768 char *funcnamebuf;
769 char *funcnameend;
770 char *funcnamep;
771 int funcsize;
772 } _funcnameRec;
773
774 /* $BDj5A%U%!%$%k(B (for include directive) */
775 #define MAXINC 10
776 typedef struct {
777 int findex;
778 FILE *fp[MAXINC];
779 } Files;
780
781 #ifdef __STDC__
782 static int wstrlen(wchar *);
783 static wchar *wrev(wchar *);
784 static void eproc(void (*)(), char *);
785 static wchar *promptsave(wchar *);
786 static int parseLine(uchar *, uchar **, int);
787 static FILE *openfile(char *);
788 static int doinclude(uchar *, Files *, void (*)());
789 static uchar *get_line(uchar *, int, Files *, void (*)());
790 static int readRuleFile(ccRule, char *);
791 static int registMode(ccRule, int, uchar **);
792 static int newMode(ccRule, Files *, _strbufRec *, _funcbufRec *,
793 _funcnameRec *, int, uchar **);
794 static int getDesc(ccRule, uchar *, _funcbufRec *, _funcnameRec *,
795 ulong *, int *, wchar *, wchar *, int *);
796 static struct modetable *getMode(ccRule, uchar *);
797 static uchar *getQuote(uchar *, wchar *, int);
798 static int getKey(uchar *, ulong *, int *);
799 static int getmask(uchar *);
800 static char *strinc(char *, char *);
801 static ulong getcode(uchar *);
802 static int getFunc(ccRule, _funcbufRec *, _funcnameRec *, int, uchar **);
803 static ccRule findRule(char *);
804 static void addRule(ccRule);
805 static void deleteRule(ccRule);
806 static int wstrsave(_strbufRec *, wchar *);
807 static int wstralloc(_strbufRec *, int);
808 static void wstradjust(_strbufRec *);
809 static int funcalloc(_funcbufRec *, int);
810 static void funcadjust(_funcbufRec *);
811 static int funcsearch(_funcnameRec *, char *);
812 static void funcnameadjust(_funcnameRec *);
813 static int convchar(ccBuf, ulong, int, char *, int);
814 static int cconvert(ccBuf, struct modetable *, ulong, int, int *, char *, int);
815 static int metamatch(ulong, ulong, int);
816 static int contextMatch(ccBuf, wchar *);
817 static void substStr(ccBuf, wchar *, wchar *, char *, int);
818 #else
819 static int wstrlen();
820 static wchar *wrev();
821 static void eproc();
822 static wchar *promptsave();
823 static int parseLine();
824 static int readRuleFile();
825 static int registMode();
826 static int newMode();
827 static int getDesc();
828 static int getMode();
829 static uchar *getQuote();
830 static int getKey();
831 static int getmask();
832 static char *strinc();
833 static ulong getcode();
834 static int getFunc();
835 static int wstrsave();
836 static int wstralloc();
837 static void wstradjust();
838 static int funcalloc();
839 static void funcadjust();
840 static int funcsearch();
841 static void funcnameadjust();
842 static int convchar();
843 static int cconvert();
844 static int metamatch();
845 static int contextMatch();
846 static void substStr();
847 #endif
848
849 /*
850 * Private Functions
851 */
852
wstrlen(str)853 static int wstrlen(str)
854 wchar *str;
855 {
856 int len = 0;
857
858 while (*str++)
859 len++;
860 return len;
861 }
862
wrev(s)863 static wchar *wrev(s)
864 wchar *s;
865 {
866 wchar *str = s;
867 wchar *end = str;
868 int c;
869
870 while (*end++)
871 ;
872 end -= 2;
873 while (str < end) {
874 c = *str;
875 *str++ = *end;
876 *end-- = c;
877 }
878 return s;
879 }
880
881 static void eproc(efunc, msg)
882 void (*efunc)();
883 char *msg;
884 {
885 if (efunc == NULL) {
886 /* stderr $B$K%W%j%s%H(B */
887 (void)fprintf(stderr, "%s\n", msg);
888 } else {
889 /* $B%(%i!<%O%s%I%i$r8F$V(B */
890 (*efunc)(msg);
891 }
892 }
893
promptsave(str)894 static wchar *promptsave(str)
895 wchar *str;
896 {
897 int len = (wstrlen(str) + 1) * sizeof(wchar);
898 wchar *p = (wchar *)Malloc(len);
899
900 if (p != NULL) {
901 wchar *q = p;
902 while (*q++ = *str++)
903 ;
904 }
905 return p;
906 }
907
parseLine(line,argv,argvsize)908 static int parseLine(line, argv, argvsize)
909 uchar *line;
910 uchar **argv;
911 int argvsize;
912 {
913 int c, qc;
914 int argc;
915 int state;
916 #define IN_WORD 1 /* $B%o!<%I$NCf(B */
917 #define IN_QUOTE 2 /* $B%o!<%I$NCf$G$5$i$K%/%)!<%H$NCf(B */
918
919 qc = 0; /* not necessary, but for lint */
920 argc = 0;
921 state = 0; /* $B%o!<%I$N30(B */
922 while (c = *line) {
923 /* $B%/%)!<%H$5$l$F$$$J$$6uGrJ8;z$O!"%o!<%I$r=*$i$;$k(B */
924 if (state != IN_QUOTE && (c == ' ' || c == '\t' || c == '\n')) {
925 /* NULL $B%?!<%_%M!<%H$5$;$k(B */
926 *line++ = '\0';
927 state = 0;
928 continue;
929 }
930 /* $B%o!<%I$N30$N6uGr0J30$NJ8;z$O!"%o!<%I$N;O$^$j$K$J$k(B */
931 if (state == 0) {
932 if (argc >= argvsize)
933 return argc;
934 argv[argc++] = line;
935 state = IN_WORD;
936 }
937 /* $B%P%C%/%9%i%C%7%e$O!"<!$NJ8;z$r%9%-%C%W$5$;$k(B */
938 if (c == '\\') {
939 /* $B$H$O$$$C$F$b<!$,(B Nul $BJ8;z$J$iOC$OJL(B */
940 if (*++line == '\0') {
941 *--line = '\0';
942 break;
943 }
944 } else if (state == IN_QUOTE) {
945 /* $B%/%)!<%H$O;O$^$j$HF1$8J8;z$G=*$k(B */
946 if (c == qc)
947 state = IN_WORD;
948 } else if (c == '\'' || c == '"') {
949 /* $B%/%)!<%H$N30$K%/%)!<%HJ8;z$,$"$l$P%/%)!<%H$N;O$^$j(B */
950 state = IN_QUOTE;
951 qc = c;
952 }
953 line++;
954 }
955
956 /* $B:G8e$N%/%)!<%H$,JD$8$F$$$J$$$+$b$7$l$J$$(B */
957 return state != IN_QUOTE ? argc : argc - 1;
958 }
959
960 /* openfile -- $BDj5A%U%!%$%k$r%*!<%W%s$9$k(B */
openfile(file)961 static FILE *openfile(file)
962 char *file;
963 {
964 FILE *fp;
965 char filename[1024];
966 FILE *fopen();
967 char *getenv();
968
969 if ((fp = fopen(file, "r")) == NULL && *file != '/') {
970 char *p, *q;
971 /* $B4D6-JQ?t(B CC_DEF_PATH $B$,$"$l$P$=$N%Q%9$N2<$r(B
972 * $B%5!<%A$9$k(B
973 */
974 if ((p = getenv("CC_DEF_PATH")) != NULL) {
975 while (*p != '\0') {
976 q = filename;
977 while (*p != '\0' && *p != ':')
978 *q++ = *p++;
979 if (*p == ':') p++;
980 if (q == filename) continue;
981 *q++ = '/';
982 *q = '\0';
983 (void)Strcat(filename, file);
984 if ((fp = fopen(filename, "r")) != NULL)
985 return fp;
986 }
987 }
988 /* $B%G%U%)%k%H$N%5!<%A%Q%9(B CCDEFPATH(/usr/lib/X11/ccdef) $B$N(B
989 * $B2<$r%5!<%A$9$k(B
990 */
991 (void)Strcpy(filename, CCDEFPATH);
992 (void)Strcat(filename, file);
993 fp = fopen(filename, "r");
994 }
995 return fp;
996 }
997
998 /* doinclude -- include $B9T$N=hM}$r$9$k(B */
doinclude(line,files,efunc)999 static int doinclude(line, files, efunc)
1000 uchar *line;
1001 Files *files;
1002 void (*efunc)();
1003 {
1004 int argc;
1005 uchar *argv[2];
1006 char *name;
1007
1008 argc = parseLine(line, argv, 2);
1009 if (files->findex > MAXINC - 2) {
1010 eproc(efunc, "include nesting too deep");
1011 return -1;
1012 }
1013 if (argc < 2) {
1014 eproc(efunc, "missing include filename");
1015 return -1;
1016 }
1017 name = (char *)argv[1];
1018 if (*name == '\'' || *name == '"') {
1019 name++;
1020 name[strlen(name) - 1] = '\0';
1021 }
1022 if ((files->fp[++files->findex] = openfile(name)) == NULL) {
1023 EPROC2(efunc, "can't open %s", name);
1024 --files->findex;
1025 return -1;
1026 }
1027 return 0;
1028 }
1029
1030 /* get_line -- 1$B9TFI$_9~$`(B ($B$=$N:](B include $B$N=hM}$r9T$J$&(B) */
get_line(line,linesize,files,efunc)1031 static uchar *get_line(line, linesize, files, efunc)
1032 uchar *line;
1033 int linesize;
1034 Files *files;
1035 void (*efunc)();
1036 {
1037 redo:
1038 if (fgets((char *)line, linesize, files->fp[files->findex])) {
1039 register uchar *p = line;
1040 while (*p == ' ' || *p == '\t')
1041 p++;
1042 if (!Strncmp(p, "include", 7)) {
1043 if (doinclude(p, files, efunc) < 0) {
1044 return NULL;
1045 } else {
1046 goto redo;
1047 }
1048 }
1049 return line;
1050 }
1051 (void)fclose(files->fp[files->findex]);
1052 files->findex--;
1053
1054 if (files->findex >= 0) {
1055 goto redo;
1056 }
1057
1058 return NULL;
1059 }
1060
1061 /* readRuleFile -- $BJQ49%k!<%kDj5A%U%!%$%k$rFI$_9~$`(B */
readRuleFile(rule,file)1062 static int readRuleFile(rule, file)
1063 ccRule rule;
1064 char *file;
1065 {
1066 FILE *fp;
1067 int moderegistered;
1068 uchar line[256], tmp[256];
1069 uchar *argv[20];
1070 int argc;
1071 _strbufRec strrec;
1072 _funcbufRec funcrec;
1073 _funcnameRec fnrec;
1074 Files files;
1075 void (*efunc)() = rule->errorfunc;
1076 int err = 0;
1077
1078 if ((fp = openfile(file)) == NULL) {
1079 EPROC2(efunc, "can't open file %s", file);
1080 return -1;
1081 }
1082 files.findex = 0;
1083 files.fp[0] = fp;
1084
1085 moderegistered = 0;
1086
1087 strrec.strbuf = NULL;
1088 funcrec.funcbuf = NULL;
1089 fnrec.nfunc = 0;
1090 fnrec.funcnamebuf = NULL;
1091
1092 rule->nmode = 0;
1093 rule->initialmode = NULL;
1094
1095 while (get_line(line, sizeof(line), &files, efunc)) {
1096 (void)Strcpy(tmp, line);
1097 if ((argc = parseLine(tmp, argv, 20)) == 0)
1098 continue;
1099
1100 /* '#' $B$G;O$^$k9T$O%3%a%s%H(B */
1101 if (*line == '\0' || *line == '\n' || *line == '#') {
1102 continue;
1103 } else if (!moderegistered && argc > 1 &&
1104 !Strcmp(argv[0], "defmode")) {
1105 /* $B%b!<%IDj5A9T(B */
1106 if (registMode(rule, argc, argv) < 0) {
1107 err++;
1108 break;
1109 }
1110 moderegistered++;
1111 } else if (!Strcmp(argv[0], "mode") && argc > 2) {
1112 /* $B$"$k%b!<%I$KBP$9$kJQ49Dj5A(B */
1113 if (!moderegistered) {
1114 eproc(efunc, "'mode' before 'defmode'");
1115 err++;
1116 break;
1117 }
1118 if (newMode(rule, &files, &strrec, &funcrec, &fnrec,
1119 argc, argv) < 0) {
1120 err++;
1121 break;
1122 }
1123 } else if (!Strcmp(argv[0], "initialmode") &&
1124 argc > 1) {
1125 if (!moderegistered) {
1126 eproc(efunc, "'initialmode' before 'defmode'");
1127 err++;
1128 break;
1129 }
1130 rule->initialmode = getMode(rule, argv[1]);
1131 } else if (!Strcmp(argv[0], "casesensitive")) {
1132 rule->casesensitive = True;
1133 } else if (!Strcmp(argv[0], "caseinsensitive")) {
1134 rule->casesensitive = False;
1135 } else if (!Strcmp(argv[0], "autofix")) {
1136 rule->autofix = True;
1137 } else if (!Strcmp(argv[0], "noautofix")) {
1138 rule->autofix = False;
1139 } else {
1140 EPROC2(efunc, "syntax error - %s", line);
1141 }
1142 }
1143
1144 /* Close all opened files. */
1145 while (files.findex >= 0) {
1146 (void)fclose(files.fp[files.findex--]);
1147 }
1148
1149 if (err) {
1150 return -1;
1151 }
1152 if (rule->nmode == 0) {
1153 eproc(efunc, "no modes defined");
1154 return -1;
1155 }
1156 if (!moderegistered) {
1157 eproc(efunc, "'defmode' required");
1158 return -1;
1159 }
1160 if (rule->initialmode < 0) {
1161 eproc(efunc, "'initialmode' required");
1162 return -1;
1163 }
1164
1165 wstradjust(&strrec);
1166 funcadjust(&funcrec);
1167 funcnameadjust(&fnrec);
1168
1169 rule->strbuf = strrec.strbuf;
1170 rule->funcbuf = funcrec.funcbuf;
1171 rule->funcnamebuf = fnrec.funcnamebuf;
1172 rule->nfunc = fnrec.nfunc;
1173 #ifdef DEBUG_CCONV
1174 dumpAllRules(rule);
1175 #endif
1176
1177 return 0;
1178 }
1179
registMode(rule,ac,av)1180 static int registMode(rule, ac, av)
1181 ccRule rule;
1182 int ac;
1183 uchar **av;
1184 {
1185 int nmode;
1186 int i;
1187 struct modetable *mtp;
1188 struct modetable *mt_head;
1189
1190 ac--, av++;
1191
1192 nmode = ac;
1193 if ((mt_head = malloc(sizeof(struct modetable))) == NULL) {
1194 eproc(rule->errorfunc, "can't alloc memory");
1195 return -1;
1196 }
1197 memset(mt_head, 0, sizeof(struct modetable));
1198 mt_head->mt_index = -1;
1199 mtp = mt_head;
1200
1201 for (i = 0; i < nmode; i++) {
1202 if ((mtp->next = malloc(sizeof(struct modetable))) == NULL) {
1203 eproc(rule->errorfunc, "can't alloc memory");
1204 return -1;
1205 }
1206 memset(mtp->next, 0, sizeof(struct modetable));
1207 mtp->next->mt_index = mtp->mt_index + 1;
1208 mtp = mtp->next;
1209
1210 strncpy(mtp->name, av[i], sizeof(mtp->name) -1);
1211 mtp->name[sizeof(mtp->name) - 1] = '\0';
1212
1213 mtp->nrule = 0;
1214 mtp->cd_head = NULL;
1215 mtp->prompt = NULL;
1216 mtp->fallthrough = NULL;
1217 }
1218
1219 rule->modes = mt_head->next;
1220 rule->nmode = nmode;
1221 free(mt_head);
1222 return 0;
1223 }
1224
1225 /* newMode -- $B$"$k%b!<%I$K$D$$$F$N%k!<%k$rFI$_9~$`(B */
newMode(rule,files,srec,frec,fnrec,ac,av)1226 static int newMode(rule, files, srec, frec, fnrec, ac, av)
1227 ccRule rule;
1228 Files *files;
1229 _strbufRec *srec;
1230 _funcbufRec *frec;
1231 _funcnameRec *fnrec;
1232 int ac;
1233 uchar **av;
1234 {
1235 uchar line[256];
1236 int mode;
1237 ulong inkey;
1238 int modmask;
1239 wchar prompt[30], context[100], result[100];
1240 int func;
1241 int ndesc = 0;
1242 struct modetable *mtp;
1243 struct convdesc *cdp;
1244 struct convdesc *cd_head;
1245 void (*efunc)() = rule->errorfunc;
1246
1247 /* $B%U%)!<%^%C%H$O(B
1248 * "mode <$B%b!<%IL>(B> <"$B%W%m%s%W%HJ8;zNs(B"> [fallthrough <$B%b!<%IL>(B>]
1249 */
1250 /* $B%b!<%I$N%A%'%C%/(B */
1251 if ((mtp = getMode(rule, av[1])) == NULL) {
1252 EPROC2(efunc, "illegal modename: %s", av[1]);
1253 return -1; /* No Such Mode */
1254 }
1255
1256 if (getQuote(av[2], prompt, 0) == NULL) {
1257 EPROC2(efunc, "illegal prompt: %s", av[2]);
1258 return -1;
1259 }
1260
1261 mtp->prompt = promptsave(prompt);
1262 mtp->nrule = 0;
1263
1264 if (ac > 4 && !Strcmp(av[3], "fallthrough")) {
1265 mtp->fallthrough = getMode(rule, av[4]);
1266 } else {
1267 mtp->fallthrough = NULL;
1268 }
1269
1270 if ((cd_head = malloc(sizeof(struct convdesc))) == NULL) {
1271 return -1;
1272 }
1273 memset(cd_head, 0, sizeof(struct convdesc));
1274 cdp = cd_head;
1275
1276 /* $B%k!<%k$rFI$s$G%9%H%"$9$k(B */
1277 while (get_line(line, sizeof(line), files, efunc)) {
1278 /* '#' $B$G;O$^$k9T$O%3%a%s%H(B */
1279 if (*line == '\0' || *line == '\n' || *line == '#')
1280 continue;
1281 if (!Strncmp(line, "endmode", 6))
1282 break;
1283 if (getDesc(rule, line, frec, fnrec, &inkey, &modmask,
1284 context, result, &func)) {
1285 if ((cdp->next = malloc(sizeof(struct convdesc))) == NULL) {
1286 return -1;
1287 }
1288 memset(cdp->next, 0, sizeof(struct convdesc));
1289 cdp = cdp->next;
1290
1291 /* $B%k!<%k$N%9%H%"(B */
1292 cdp->key = inkey;
1293 cdp->mask = modmask;
1294 cdp->context = *context ? wstrsave(srec, wrev(context)) : 0;
1295 cdp->result = *result ? wstrsave(srec, result) : 0;
1296 cdp->function = func;
1297 ndesc++;
1298 } else
1299 EPROC2(efunc, "illegal description - %s", line);
1300 }
1301
1302 /* $B%k!<%k$,#1$D$b$J$1$l$P%(%i!<$K$9$Y$-$@$m$&(B */
1303 /* $B$H;W$C$?$,Nc$($P(B ASCII $B%b!<%I$N$H$-$K$O%k!<%k$,#1$D$b$J$$$3$H$,(B
1304 * $B$"$j$&$k(B
1305 */
1306
1307 mtp->nrule = ndesc;
1308
1309 /* cd_head is always empty. cd_head->next is the head. */
1310 mtp->cd_head = cd_head->next;
1311 free(cd_head);
1312
1313 return 0;
1314 }
1315
getDesc(rule,line,frec,fnrec,keyp,maskp,context,result,funcp)1316 static int getDesc(rule, line, frec, fnrec, keyp, maskp, context, result, funcp)
1317 ccRule rule;
1318 uchar *line;
1319 _funcbufRec *frec;
1320 _funcnameRec *fnrec;
1321 ulong *keyp;
1322 int *maskp;
1323 wchar *context;
1324 wchar *result;
1325 int *funcp;
1326 {
1327 uchar tmp[256];
1328 uchar *av[20];
1329 int ac;
1330 void (*efunc)() = rule->errorfunc;
1331
1332 /* valid description format is:
1333 "context" key "result" [function...]
1334 */
1335
1336 (void)Strcpy(tmp, line);
1337 ac = parseLine(tmp, av, 20);
1338 if (ac < 3) {
1339 EPROC2(efunc, "syntax error - %s", line);
1340 return 0;
1341 }
1342
1343 /* context $B$NFI$_9~$_(B */
1344 if (getQuote(av[0], context, 0) == NULL)
1345 return 0;
1346
1347 /* $B%-!<%3!<%I$rFI$_9~$s$G(B */
1348 if (getKey(av[1], keyp, maskp) < 0) {
1349 EPROC2(efunc, "no such key (%s)", av[1]);
1350 return 0;
1351 }
1352
1353 /* result $B$rFI$_9~$s$G(B */
1354 if (getQuote(av[2], result, 1) == NULL)
1355 return 0;
1356
1357 /* $B%U%!%s%/%7%g%s$N5-=R$,$"$l$P$=$l$rFI$_9~$`(B */
1358 /* $B$b$7AjEv$9$k%U%!%s%/%7%g%s$,$J$/$F$b%(%i!<$K$7$J$$(B */
1359 if (ac > 3) {
1360 *funcp = getFunc(rule, frec, fnrec, ac - 3, &av[3]);
1361 } else {
1362 *funcp = 0;
1363 }
1364
1365 return 1;
1366 }
1367
getMode(rule,str)1368 static struct modetable *getMode(rule, str)
1369 ccRule rule;
1370 uchar *str;
1371 {
1372 struct modetable *mtp = rule->modes;
1373
1374 while (mtp) {
1375 if (!Strcmp(str, mtp->name)) {
1376 return mtp;
1377 }
1378 mtp = mtp->next;
1379 }
1380
1381 EPROC2(rule->errorfunc, "undefined mode %s", str);
1382 return NULL;
1383 }
1384
1385 /* getQuote -- $B%/%)!<%F!<%7%g%s5-9f$G0O$^$l$?J8;zNs$rFI$s$G(B wchar $B$K$9$k(B */
getQuote(line,str,metaf)1386 static uchar *getQuote(line, str, metaf)
1387 uchar *line;
1388 wchar *str;
1389 int metaf; /* '&' $B$H(B '/' $B$r%a%?!&%-%c%i%/%?$H$9$k$+$I$&$+(B */
1390 {
1391 int c;
1392 int quote; /* quote flag */
1393 int qc = *line++; /* quote character */
1394 #define SS2 0x8e
1395 #define SS3 0x8f
1396
1397 if (qc != '\'' && qc != '"')
1398 return((uchar *)NULL);
1399
1400 quote = 0;
1401 while ((c = *line++) && c != qc) {
1402 if (c == '\\' && !quote) {
1403 quote = 1;
1404 continue;
1405 }
1406
1407 if (c == '^' && !quote) {
1408 if (c = *line++)
1409 *str++ = c - '@';
1410 else
1411 break;
1412 } else if (metaf && c == '&' && !quote)
1413 *str++ = MATCHED_CHAR;
1414 else if (metaf && c == '/' && !quote)
1415 *str++ = CCLEAR_CHAR;
1416 else if (c < 0x80)
1417 *str++ = c;
1418 else if (c == SS2)
1419 *str++ = *line++ | 0x80;
1420 else if (c == SS3) {
1421 c = *line++;
1422 *str++ = (c << 8) | (*line++ & 0x7f) | 0x8000;
1423 } else {
1424 *str++ = (c << 8) | *line++ | 0x8080;
1425 }
1426 }
1427 *str = 0;
1428
1429 return((c == qc) ? line : (uchar *)NULL);
1430 }
1431
1432 /* getKey -- $B%-!<%3!<%I$rFI$`(B */
getKey(line,keyp,maskp)1433 static int getKey(line, keyp, maskp)
1434 uchar *line;
1435 ulong *keyp;
1436 int *maskp;
1437 {
1438 /*
1439 * $B%-!<%3!<%I$N5-=RK!$O#2DL$j(B
1440 * 1. ASCII $BI=5-(B
1441 * 'a'
1442 * '^H'
1443 * '\033'
1444 * '\xff'
1445 *
1446 * 2. XKEY $BI=5-(B
1447 * #124
1448 * #0132
1449 * #0x58
1450 * shift-A
1451 * shift-control-meta-HENKAN
1452 *
1453 * pseudo code
1454 * ENTERMODE
1455 * EXITMODE
1456 *
1457 * wild character
1458 * @ascii
1459 * @control
1460 * @raw
1461 * @any
1462 */
1463
1464 int key = 0;
1465
1466 *maskp = 0;
1467
1468 if (*line == '\'') { /* $B%7%s%0%k%/%)!<%H$G;O$^$k$N$G(B ASCII $BI=5-(B */
1469 if (*++line == '\\') {
1470 /* '\'' $B$N>l9g(B($B%7%s%0%k%/%)!<%H<+?H(B)$B!"(B
1471 * '\\' $B$N>l9g(B($B%P%C%/%9%i%C%7%e(B)
1472 * '\033' $B$N$h$&$J#8?JI=5-$N>l9g$H(B
1473 * '\x27' $B$N$h$&$J#1#6?JI=5-$N>l9g$,$"$k(B
1474 */
1475 if (*++line == '\'') /* '\'' */
1476 key = '\'';
1477 else if (*line == '\\') /* '\\' */
1478 key = '\\';
1479 else if (*line == 'x') /* hexadecimal */
1480 (void)sscanf((char *)++line, "%x", &key);
1481 else /* octal */
1482 (void)sscanf((char *)line, "%o", &key);
1483 key &= 0xff;
1484 } else if (*line == '^') {
1485 /* '^' ($B%+%l%C%H<+?H(B) $B$^$?$O%3%s%H%m!<%k%3!<%I(B */
1486 if (*++line == '\'')
1487 key = '^';
1488 else
1489 key = *line - '@';
1490 } else {
1491 key = *line;
1492 }
1493 *keyp = key;
1494 } else if (*line == '#') { /* event code */
1495 if (*++line == '0') { /* octal or hexadecimal */
1496 if (*(line + 1) == 'x') /* hexadecimal */
1497 (void)sscanf((char *)line + 2, "%x", &key);
1498 else /* octal */
1499 (void)sscanf((char *)line, "%o", &key);
1500 } else {
1501 key = atoi((char *)line);
1502 }
1503 *keyp = (ulong)key | (ulong)RAWKEY;
1504 } else if (!Strcmp(line, "ENTERMODE")) {
1505 *keyp = ENTERMODE;
1506 } else if (!Strcmp(line, "EXITMODE")) {
1507 *keyp = EXITMODE;
1508 } else if (*line == '@') {
1509 /* $B%o%$%k%I!&%-%c%i%/%?(B */
1510 line++;
1511 if (!Strcmp(line, "ascii"))
1512 key = META_ASCII;
1513 else if (!Strcmp(line, "printable"))
1514 key = META_PRINTABLE;
1515 else if (!Strcmp(line, "control"))
1516 key = META_CONTROL;
1517 else if (!Strcmp(line, "raw"))
1518 key = META_RAW;
1519 else if (!Strcmp(line, "any"))
1520 key = META_ANY;
1521 else if (!Strcmp(line, "func"))
1522 key = META_FUNC;
1523 else if (!Strcmp(line, "cursor"))
1524 key = META_CURSOR;
1525 else if (!Strcmp(line, "keypad"))
1526 key = META_KEYPAD;
1527 else if (!Strcmp(line, "modifier"))
1528 key = META_MODIFIER;
1529 else if (!Strcmp(line, "non-ascii"))
1530 key = META_NONASCII;
1531 else
1532 return -1;
1533 *keyp = (ulong)key | (ulong)METAC;
1534 } else {
1535 if ((key = getcode(line)) == 0)
1536 return -1;
1537 *keyp = (ulong)key | (ulong)RAWKEY;
1538 *maskp = getmask(line);
1539 }
1540 return 0;
1541 }
1542
1543 /* getmask -- $B%b%G%#%U%!%$%"!&%^%9%/$rJV$9(B */
getmask(s)1544 static int getmask(s)
1545 uchar *s;
1546 {
1547 int mask = 0;
1548 char buf[256];
1549 uchar *p;
1550
1551 if ((p = (uchar *)rindex((char *)s, '-')) == NULL)
1552 return 0;
1553 (void)strncpy(buf, (char *)s, p - s);
1554 buf[p - s] = '\0';
1555
1556 if (strinc(buf, "shift"))
1557 mask |= ShiftMask;
1558 if (strinc(buf, "control"))
1559 mask |= ControlMask;
1560 if (strinc(buf, "lock"))
1561 mask |= LockMask;
1562 if (strinc(buf, "mod1"))
1563 mask |= Mod1Mask;
1564 if (strinc(buf, "mod2"))
1565 mask |= Mod2Mask;
1566 if (strinc(buf, "mod3"))
1567 mask |= Mod3Mask;
1568 if (strinc(buf, "mod4"))
1569 mask |= Mod4Mask;
1570 if (strinc(buf, "mod5"))
1571 mask |= Mod5Mask;
1572 return mask;
1573 }
1574
strinc(s,k)1575 static char *strinc(s, k)
1576 char *s;
1577 char *k;
1578 {
1579 register int len = Strlen(k);
1580
1581 while (s = index(s, *k))
1582 if (!Strncmp(s, k, len))
1583 return s;
1584 else
1585 s++;
1586 return NULL;
1587 }
1588
1589
1590 /* getcode -- KeySym $B$rJV$9(B */
getcode(s)1591 static ulong getcode(s)
1592 uchar *s;
1593 {
1594 register uchar *t;
1595 KeySym keysym;
1596 KeySym XStringToKeysym();
1597
1598 if ((t = (uchar *)rindex((char *)s, '-')) == NULL)
1599 t = s;
1600 else
1601 t++;
1602 keysym = XStringToKeysym((char *)t);
1603 if (keysym == NoSymbol)
1604 return (ulong)0;
1605 else
1606 return (ulong)keysym;
1607 }
1608
getFunc(rule,frec,fnrec,n,args)1609 static int getFunc(rule, frec, fnrec, n, args)
1610 ccRule rule;
1611 _funcbufRec *frec;
1612 _funcnameRec *fnrec;
1613 int n;
1614 uchar **args;
1615 {
1616 int i, j;
1617 uchar *func;
1618 uchar *arg;
1619 ushort *fp;
1620 int findex;
1621 void (*efunc)() = rule->errorfunc;
1622 struct modetable *mtp;
1623
1624 findex = funcalloc(frec, n + 1);
1625 fp = frec->funcbuf + findex;
1626
1627 j = 0;
1628 while (n > 0) {
1629 func = *args++;
1630 if (!Strcmp(func, "goto")) {
1631 /* $B%b!<%I$NJQ99(B */
1632 if (n < 2)
1633 break; /* $B%b!<%IL>$,=q$$$F$J$$(B */
1634 arg = *args++;
1635 --n;
1636 if (!Strcmp(arg, "PREV")) {
1637 fp[j++] = PREVMODE;
1638 break;
1639 }
1640 if ((mtp = getMode(rule, arg)) == NULL) {
1641 break;
1642 }
1643 fp[j++] = MODECHANGE | mtp->mt_index;
1644 break;
1645 } else if (!Strcmp(func, "redo")) {
1646 fp[j++] = REDO;
1647 break;
1648 } else if (!Strncmp(func, "add-modifier-",
1649 sizeof("add-modifier-") - 1)) {
1650 /* $B<!$NF~NO%-!<$r%b%G%#%U%!%$%d$D$-$K$9$k(B */
1651 char *mod = func + sizeof("add-modifier-") - 1;
1652 if (!Strcmp(mod, "shift" )) fp[j++] = FUNC_MODIFIER_SHIFT;
1653 else if (!Strcmp(mod, "control")) fp[j++] = FUNC_MODIFIER_CONTROL;
1654 else if (!Strcmp(mod, "lock" )) fp[j++] = FUNC_MODIFIER_LOCK;
1655 else if (!Strcmp(mod, "mod1" )) fp[j++] = FUNC_MODIFIER_MOD1;
1656 else if (!Strcmp(mod, "mod2" )) fp[j++] = FUNC_MODIFIER_MOD2;
1657 else if (!Strcmp(mod, "mod3" )) fp[j++] = FUNC_MODIFIER_MOD3;
1658 else if (!Strcmp(mod, "mod4" )) fp[j++] = FUNC_MODIFIER_MOD4;
1659 else if (!Strcmp(mod, "mod5" )) fp[j++] = FUNC_MODIFIER_MOD5;
1660 break;
1661 } else {
1662 /* $B%U%!%s%/%7%g%sI=$N8!:w(B */
1663 int fnum;
1664 if ((fnum = funcsearch(fnrec, (char *)func)) < 0) {
1665 EPROC2(efunc, "too many functions (> %d)", MAXFUNC);
1666 } else {
1667 fp[j++] = fnum;
1668 }
1669 }
1670 --n;
1671 }
1672 fp[j++] = ENDFUNC;
1673 frec->funcp = fp + j; /* kludge */
1674 return findex;
1675 }
1676
1677 static ccRule
findRule(rulefile)1678 findRule(rulefile)
1679 char *rulefile;
1680 {
1681 ccRule rule = ccrules;
1682
1683 while (rule) {
1684 if (rule->rulefile && !strcmp(rulefile, rule->rulefile)) {
1685 return rule;
1686 }
1687 rule = rule->next;
1688 }
1689 return NULL;
1690 }
1691
1692 static void
addRule(rule)1693 addRule(rule)
1694 ccRule rule;
1695 {
1696 rule->refcnt = 1;
1697 rule->next = ccrules;
1698 ccrules = rule;
1699 }
1700
1701 static void
deleteRule(rule)1702 deleteRule(rule)
1703 ccRule rule;
1704 {
1705 ccRule rp = ccrules;
1706 ccRule rp0 = NULL;
1707
1708 while (rp) {
1709 if (rule == rp) {
1710 if (rp0 == NULL) {
1711 ccrules = rp->next;
1712 } else {
1713 rp0->next = rp->next;
1714 }
1715 return;
1716 }
1717 rp0 = rp;
1718 rp = rp->next;
1719 }
1720 }
1721
wstrsave(srec,str)1722 static int wstrsave(srec, str)
1723 _strbufRec *srec;
1724 wchar *str;
1725 {
1726 int len = wstrlen(str);
1727 int pos;
1728 wchar *p;
1729
1730 pos = wstralloc(srec, len + 1);
1731 if (pos > 0) {
1732 p = srec->strbuf + pos;
1733 while (len-- > 0) {
1734 *p++ = *str++;
1735 }
1736 *p = 0;
1737 }
1738 return pos;
1739 }
1740
1741 /* $B%P%C%U%!%"%m%1!<%H%U%!%s%/%7%g%s(B */
1742
wstralloc(srec,len)1743 static int wstralloc(srec, len)
1744 _strbufRec *srec;
1745 int len;
1746 {
1747 int ret;
1748
1749 if (srec->strbuf == NULL) {
1750 /* allocate srec->strbuf */
1751 srec->strbuf = (wchar *)Malloc(STRSIZE * sizeof(wchar));
1752 if (srec->strbuf == NULL)
1753 return 0;
1754 srec->strend = srec->strbuf + STRSIZE;
1755 srec->strp = srec->strbuf;
1756 *srec->strp++ = 0; /* dummy */
1757 }
1758 if (srec->strp + len > srec->strend) {
1759 /* allocate more memory */
1760 int size = (srec->strp + len) - srec->strend;
1761 int offset = srec->strp - srec->strbuf;
1762 wchar *wp;
1763
1764 if (size < MORESTRSIZE)
1765 size = MORESTRSIZE;
1766 size += srec->strend - srec->strbuf;
1767 wp = (wchar *)Realloc(srec->strbuf, size * sizeof(wchar));
1768 if (wp == NULL)
1769 return 0;
1770 srec->strp = wp + offset;
1771 srec->strbuf = wp;
1772 srec->strend = wp + size;
1773 }
1774
1775 ret = srec->strp - srec->strbuf;
1776 srec->strp += len;
1777
1778 return ret;
1779 }
1780
wstradjust(srec)1781 static void wstradjust(srec)
1782 _strbufRec *srec;
1783 {
1784 int size = srec->strp - srec->strbuf;
1785 wchar *wp;
1786
1787 if (size == 0) return;
1788 wp = (wchar *)Realloc(srec->strbuf, size * sizeof(wchar));
1789 if (wp != NULL) {
1790 srec->strbuf = wp;
1791 srec->strp = srec->strend = wp + size;
1792 }
1793 }
1794
funcalloc(frec,n)1795 static int funcalloc(frec, n)
1796 _funcbufRec *frec;
1797 int n;
1798 {
1799 int ret;
1800
1801 if (frec->funcbuf == NULL) {
1802 /* allocate funcbuf */
1803 frec->funcbuf = (ushort *)Malloc(FUNCSIZE * sizeof(ushort));
1804 if (frec->funcbuf == NULL)
1805 return 0;
1806 frec->funcend = frec->funcbuf + FUNCSIZE;
1807 frec->funcp = frec->funcbuf;
1808 *(frec->funcp)++ = ENDFUNC; /* dummy */
1809 }
1810 if (frec->funcp + n > frec->funcend) {
1811 /* allocate more memory */
1812 int size = (frec->funcp + n) - frec->funcend;
1813 int offset = frec->funcp - frec->funcbuf;
1814 ushort *up;
1815
1816 if (size < MOREFUNCSIZE)
1817 size = MOREFUNCSIZE;
1818 size += frec->funcend - frec->funcbuf;
1819 up = (ushort *)Realloc(frec->funcbuf, size * sizeof(ushort));
1820 if (up == NULL)
1821 return 0;
1822 frec->funcp = up + offset;
1823 frec->funcbuf = up;
1824 frec->funcend = up + size;
1825 }
1826
1827 ret = frec->funcp - frec->funcbuf;
1828 frec->funcp += n;
1829
1830 return ret;
1831 }
1832
funcadjust(frec)1833 static void funcadjust(frec)
1834 _funcbufRec *frec;
1835 {
1836 int size = frec->funcp - frec->funcbuf;
1837 ushort *fp;
1838
1839 if (size == 0) return;
1840 fp = (ushort *)Realloc(frec->funcbuf, size * sizeof(ushort));
1841 if (fp != NULL) {
1842 frec->funcbuf = fp;
1843 frec->funcp = frec->funcend = fp + size;
1844 }
1845 }
1846
funcsearch(fnrec,funcname)1847 static int funcsearch(fnrec, funcname)
1848 _funcnameRec *fnrec;
1849 char *funcname;
1850 {
1851 int nfunc = fnrec->nfunc;
1852 ushort *fnames = fnrec->funcnames;
1853 char *fnbuf = fnrec->funcnamebuf;
1854 int i;
1855 int len;
1856
1857 for (i = 0; i < nfunc; i++) {
1858 if (!strcmp(funcname, fnbuf + *fnames++))
1859 return i;
1860 }
1861
1862 if (nfunc >= MAXFUNC)
1863 return -1;
1864
1865 len = strlen(funcname) + 1;
1866
1867 /* add new function */
1868 if (fnrec->funcnamebuf == NULL) {
1869 /* allocate funcnamebuf */
1870 if ((fnrec->funcnamebuf = Malloc(FUNCNAMESIZE)) == NULL)
1871 return -1;
1872 fnrec->funcnameend = fnrec->funcnamebuf + FUNCNAMESIZE;
1873 fnrec->funcnamep = fnrec->funcnamebuf;
1874 }
1875 if (fnrec->funcnamep + len > fnrec->funcnameend) {
1876 /* allocate more memory */
1877 int size = (fnrec->funcnamep + len) - fnrec->funcnameend;
1878 int offset = fnrec->funcnamep - fnrec->funcnamebuf;
1879 char *cp;
1880
1881 if (size < MOREFUNCNAMESIZE)
1882 size = MOREFUNCNAMESIZE;
1883 size += fnrec->funcnameend - fnrec->funcnamebuf;
1884 if ((cp = Realloc(fnrec->funcnamebuf, size)) == NULL)
1885 return 0;
1886 fnrec->funcnamep = cp + offset;
1887 fnrec->funcnamebuf = cp;
1888 fnrec->funcnameend = cp + size;
1889 }
1890
1891 (void)strcpy(fnrec->funcnamep, funcname);
1892 fnrec->funcnames[nfunc] = fnrec->funcnamep - fnrec->funcnamebuf;
1893 fnrec->funcnamep += len;
1894
1895 return fnrec->nfunc++;
1896 }
1897
funcnameadjust(fnrec)1898 static void funcnameadjust(fnrec)
1899 _funcnameRec *fnrec;
1900 {
1901 int size = fnrec->funcnamep - fnrec->funcnamebuf;
1902 char *cp;
1903
1904 if (size == 0) return;
1905 if (cp = Realloc(fnrec->funcnamebuf, size)) {
1906 fnrec->funcnamebuf = cp;
1907 fnrec->funcnamep = fnrec->funcnameend = cp + size;
1908 }
1909 }
1910
convchar(buf,key,mask,str,len)1911 static int convchar(buf, key, mask, str, len)
1912 ccBuf buf;
1913 ulong key; /* keysym (RAWKEY) or ascii code */
1914 int mask; /* modifier mask */
1915 char *str; /* ascii interpretation */
1916 int len; /* length of str */
1917 {
1918 int r;
1919 int func;
1920 int redocount = 0;
1921 ushort *fp;
1922 ccRule rule = buf->rule;
1923
1924 redo:
1925 /* $B$^$:$O8=:_$N%b!<%I$N%k!<%k$GJQ49$7$F$_$k(B */
1926 r = cconvert(buf, buf->currentmode, key, mask, &func, str, len);
1927 if (r < 0) {
1928 /* $B%^%C%A$9$k%k!<%k$,8+$D$+$i$J$+$C$?$N$G(B
1929 * fallthrough $B$G;XDj$5$l$k%b!<%I$N%k!<%k$rC5$9(B
1930 */
1931 struct modetable *tmpmode = buf->currentmode->fallthrough;
1932
1933 while (tmpmode != NULL) {
1934 r = cconvert(buf, tmpmode, key, mask, &func, str, len);
1935 if (r >= 0) /* $B%^%C%A$7$?(B */
1936 break;
1937 tmpmode = tmpmode->fallthrough;
1938 }
1939 }
1940
1941 if (r < 0)
1942 return -1; /* $B$I$l$K$b%^%C%A$7$J$+$C$?(B */
1943
1944 if (func == 0)
1945 return 0; /* $B2?$b$7$J$$(B */
1946
1947 fp = rule->funcbuf + func;
1948 while ((func = *fp++) != ENDFUNC) {
1949 if (func == REDO) {
1950 if (redocount++ > MAXREDO)
1951 return -1; /* $B$?$V$sL58B%k!<%W(B */
1952 else
1953 goto redo; /* redo -- $B$b$&0lEY(B */
1954 } else if (func & MODECHANGE) { /* $B%+%l%s%H%b!<%I$NJQ99(B */
1955 struct modetable *tmpmode = buf->currentmode;
1956
1957 /* pseudo-key $B$NF~NO(B */
1958 (void)convchar(buf, EXITMODE, 0, (char *)NULL, 0);
1959
1960 if (func == PREVMODE) {
1961 buf->currentmode = buf->previousmode;
1962 } else {
1963 int index = func & ~MODECHANGE;
1964 struct modetable *mtp;
1965 for (mtp = rule->modes; mtp && mtp->mt_index != index; mtp = mtp->next)
1966 ;
1967 if (mtp) {
1968 buf->currentmode = mtp;
1969 } else {
1970 return -1;
1971 }
1972 }
1973 buf->previousmode = tmpmode;
1974
1975 /* pseudo-key $B$NF~NO(B */
1976 (void)convchar(buf, ENTERMODE, 0, (char *)NULL, 0);
1977
1978 /* $B%b!<%I$,JQ$o$C$?;~$K$O%3%s%F%-%9%H$r%/%j%"$9$k(B */
1979 ccContextClear(buf);
1980
1981 /* $B%b!<%IJQ99%3!<%k%P%C%/$,$"$l$P8F$S=P$9(B */
1982 if (buf->modenotify) {
1983 (*buf->modenotify)(buf->currentmode,
1984 buf->previousmode,
1985 buf->client_data);
1986 }
1987 break;
1988 } else if (FUNC_MODIFIER_start <= func &&
1989 func <= FUNC_MODIFIER_end) {
1990 /* $B<!$NF~NO%-!<$r%b%G%#%U%!%$%d$D$-$K$9$k(B */
1991 switch (func) {
1992 case FUNC_MODIFIER_SHIFT: buf->modifier |= ShiftMask; break;
1993 case FUNC_MODIFIER_CONTROL: buf->modifier |= ControlMask; break;
1994 case FUNC_MODIFIER_LOCK: buf->modifier |= LockMask; break;
1995 case FUNC_MODIFIER_MOD1: buf->modifier |= Mod1Mask; break;
1996 case FUNC_MODIFIER_MOD2: buf->modifier |= Mod2Mask; break;
1997 case FUNC_MODIFIER_MOD3: buf->modifier |= Mod3Mask; break;
1998 case FUNC_MODIFIER_MOD4: buf->modifier |= Mod4Mask; break;
1999 case FUNC_MODIFIER_MOD5: buf->modifier |= Mod5Mask; break;
2000 }
2001 } else {
2002 int truefunc = buf->functbl[func];
2003 /* $B%G%#%9%Q%C%A!&%k!<%A%s$r8F$V(B */
2004 if (truefunc >= 0) {
2005 if (!(*buf->executefunction)(truefunc, str, len,
2006 buf->client_data))
2007 break;
2008 }
2009 }
2010 }
2011 return 0;
2012 }
2013
cconvert(buf,mode,inkey,mask,func,str,len)2014 static int cconvert(buf, mode, inkey, mask, func, str, len)
2015 ccBuf buf;
2016 struct modetable *mode; /* current mode */
2017 ulong inkey; /* input key (raw/mapped) */
2018 int mask;
2019 int *func; /* function */
2020 char *str;
2021 int len;
2022 {
2023 ccRule rule = buf->rule;
2024 struct convdesc *cdp;
2025 ulong key;
2026 int n;
2027 struct modetable *mtp = mode;
2028
2029 if (mtp == NULL)
2030 return -1; /* No Such Mode */
2031
2032 if (mtp->nrule <= 0)
2033 return -1; /* No Rules */
2034
2035 for (cdp = mtp->cd_head; cdp; cdp = cdp->next) {
2036 key = cdp->key;
2037 if (key & (ulong)METAC) {
2038 /* $B%o%$%k%I%+!<%IJ8;z$N%^%C%A%s%0(B */
2039 if (!metamatch(key, inkey, len == 0))
2040 continue;
2041 } else if (key & (ulong)RAWKEY && mask != cdp->mask) {
2042 continue;
2043 } else if (key != inkey) {
2044 continue;
2045 }
2046
2047 /* $B%-!<$,%^%C%A$7$?(B */
2048 if (contextMatch(buf, rule->strbuf + cdp->context)) {
2049 substStr(buf, rule->strbuf + cdp->context,
2050 rule->strbuf + cdp->result, str, len);
2051 *func = cdp->function;
2052 return 0;
2053 }
2054 }
2055
2056 return -1; /* No Match */
2057 }
2058
metamatch(rkey,inkey,nonascii)2059 static int metamatch(rkey, inkey, nonascii)
2060 ulong rkey;
2061 ulong inkey;
2062 int nonascii;
2063 {
2064 int type = (int)(rkey & 0xff);
2065
2066 switch (type) {
2067 case META_ASCII:
2068 return !(inkey & (ulong)(RAWKEY|PSEUDO));
2069 case META_PRINTABLE:
2070 return (0x20 <= inkey && inkey < 0x7f);
2071 case META_CONTROL:
2072 return inkey < 0x20;
2073 case META_RAW:
2074 return inkey & (ulong)RAWKEY;
2075 case META_ANY:
2076 return 1;
2077 case META_FUNC:
2078 return (inkey & (ulong)RAWKEY) && IsFunctionKey(inkey & 0xffff);
2079 case META_CURSOR:
2080 return (inkey & (ulong)RAWKEY) && IsCursorKey(inkey & 0xffff);
2081 case META_KEYPAD:
2082 return (inkey & (ulong)RAWKEY) && IsKeypadKey(inkey & 0xffff);
2083 case META_MODIFIER:
2084 return (inkey & (ulong)RAWKEY) && IsModifierKey(inkey & 0xffff);
2085 case META_NONASCII:
2086 return (inkey & (ulong)RAWKEY) && nonascii;
2087 default:
2088 return 0;
2089 }
2090 /* NOTREACHED */
2091 }
2092
contextMatch(buf,context)2093 static int contextMatch(buf, context)
2094 ccBuf buf;
2095 wchar *context;
2096 {
2097 wchar *c0 = buf->contextend;
2098 wchar *c1 = buf->context;
2099 int cs = buf->rule->casesensitive;
2100
2101 if (context == 0 || *context == 0)
2102 return 1; /* $BL5>r7o%^%C%A(B */
2103 if (c0 - c1 < wstrlen(context)) /* $BD9$5$N%A%'%C%/(B */
2104 return 0; /* matching fail */
2105 c0--;
2106 while (*context) {
2107 if ((!cs && CANONIC(*c0) == CANONIC(*context)) ||
2108 (cs && *c0 == *context))
2109 c0--, context++;
2110 else
2111 return 0; /* fail */
2112 }
2113 return 1;
2114 }
2115
substStr(buf,context,result,str,len)2116 static void substStr(buf, context, result, str, len)
2117 ccBuf buf;
2118 wchar *context;
2119 wchar *result;
2120 char *str;
2121 int len;
2122 {
2123 register int c;
2124 int nbytes;
2125 uchar *bufp;
2126
2127 /* $B%3%s%F%-%9%H$NJ,$r>C$9(B */
2128 while (*context++) {
2129 ccContextDelete(buf);
2130 (*buf->deletechar)(buf->client_data);
2131 }
2132
2133 while (c = *result++) {
2134 if (c == MATCHED_CHAR) {
2135 nbytes = len;
2136 bufp = (uchar *)str;
2137 while (nbytes-- > 0) {
2138 c = *bufp++;
2139 /* bufp $B$NCf?H$O(B ASCII $B$+(B $B%+%J$J$N$G(B
2140 * EUC $B%W%m%;%9%3!<%I$X$NJQ49$r$o$6$o$6(B
2141 * $B$d$kI,MW$O$J$$(B
2142 */
2143 ccContextAppend(buf, c);
2144 (*buf->insertchar)(c, buf->client_data);
2145 }
2146 continue;
2147 } else if (c == CCLEAR_CHAR) {
2148 /* $B%3%s%F%-%9%H$r%/%j%"$9$k(B */
2149 ccContextClear(buf);
2150 continue;
2151 }
2152 ccContextAppend(buf, c);
2153 (*buf->insertchar)(c, buf->client_data);
2154 }
2155 }
2156
2157 /* getModeSwitchMask -- mode-switch $B$N%b%G%#%U%!%$%"%^%9%/$rD4$Y$k(B */
getModeSwitchMask(dpy)2158 int getModeSwitchMask(dpy)
2159 Display *dpy;
2160 {
2161 KeyCode modeswkey;
2162 struct modesw {
2163 Display *dpy;
2164 int mode_switch;
2165 struct modesw *next;
2166 } *msp;
2167 static struct modesw *modeswlist;
2168
2169 for (msp = modeswlist; msp != NULL; msp = msp->next) {
2170 if (dpy == msp->dpy) return msp->mode_switch;
2171 }
2172 msp = (struct modesw *)Malloc(sizeof(struct modesw));
2173 msp->dpy = dpy;
2174 msp->next = modeswlist;
2175 modeswlist = msp;
2176
2177 msp->mode_switch = 0;
2178
2179 if ((modeswkey = XKeysymToKeycode(dpy, XK_Mode_switch)) != 0) {
2180 XModifierKeymap *map = XGetModifierMapping(dpy);
2181 int keypermod = map->max_keypermod;
2182 int modbit;
2183 int i;
2184
2185 for (modbit = 3; modbit < 8; modbit++) {
2186 for (i = 0; i < keypermod; i++) {
2187 if (map->modifiermap[keypermod * modbit + i] == modeswkey) {
2188 msp->mode_switch = 1 << modbit;
2189 goto found;
2190 }
2191 }
2192 }
2193 found:
2194 XFreeModifiermap(map);
2195 }
2196
2197 return msp->mode_switch;
2198 }
2199
2200 /*
2201 * Public Functions
2202 */
2203
2204 /* ccParseRule -- $BJQ49Dj5A%U%!%$%k$rFI$_9~$`(B */
ccParseRule(deffile,errprint)2205 ccRule ccParseRule(deffile, errprint)
2206 char *deffile; /* $BF~NOJ8;zJQ49Dj5A%U%!%$%k(B */
2207 void (*errprint)(); /* $B%(%i!<%a%C%;!<%8I=<(MQ%3!<%k%P%C%/(B */
2208 {
2209 ccRule rule;
2210 extern char *getenv();
2211
2212 /* $BJQ49Dj5A%U%!%$%k$NFI$_9~$_(B */
2213 if (deffile == NULL) {
2214 /* $B4D6-JQ?t(B CC_DEF $B$rD4$Y$k(B */
2215 if ((deffile = getenv("CC_DEF")) == NULL) {
2216 return (ccRule)NULL;
2217 }
2218 }
2219
2220 if (rule = findRule(deffile)) {
2221 /* same rule found */
2222 rule->refcnt++;
2223 return rule;
2224 }
2225
2226 /* ccRuleRec $B$N%"%m%1!<%H(B */
2227 if ((rule = (ccRule)Malloc(sizeof(ccRuleRec))) == NULL) {
2228 return (ccRule)NULL;
2229 }
2230
2231 rule->errorfunc = errprint;
2232 rule->rulefile = Malloc(Strlen(deffile) + 1);
2233 if (rule->rulefile) {
2234 (void)Strcpy(rule->rulefile, deffile);
2235 }
2236 rule->casesensitive = False;
2237 rule->autofix = False;
2238
2239 if (readRuleFile(rule, deffile) < 0) {
2240 Free(rule);
2241 return (ccRule)NULL;
2242 }
2243
2244 addRule(rule);
2245
2246 return rule;
2247 }
2248
2249 /* ccCreateBuf -- $BJQ49%P%C%U%!$r:n$k(B */
ccCreateBuf(rule,csize,functable,nfunc,def_action,insert,delete,execute,autofix,modenotify,data)2250 ccBuf ccCreateBuf(rule, csize, functable, nfunc,
2251 def_action, insert, delete, execute, autofix, modenotify,
2252 data)
2253 ccRule rule; /* $B;HMQ$9$kF~NOJ8;zJQ49%k!<%k(B */
2254 int csize; /* context size ($BJ8;z?t(B) */
2255 char *functable[]; /* $B%U%!%s%/%7%g%s!&%F!<%V%k(B */
2256 int nfunc; /* functable $B$N%(%s%H%j?t(B */
2257 void (*def_action)(); /* $B%G%U%)%k%H!&%"%/%7%g%s!&%3!<%k%P%C%/(B */
2258 void (*insert)(); /* $BJ8;zF~NO%3!<%k%P%C%/(B */
2259 void (*delete)(); /* $BJ8;z:o=|%3!<%k%P%C%/(B */
2260 int (*execute)(); /* $B%U%!%s%/%7%g%s<B9T%3!<%k%P%C%/(B */
2261 void (*autofix)(); /* $B<+F03NDj%3!<%k%P%C%/(B */
2262 void (*modenotify)(); /* $B%b!<%IJQ99DLCN%3!<%k%P%C%/(B */
2263 caddr_t data; /* callback $B%G!<%?(B */
2264 {
2265 ccBuf buf;
2266 char *funcnamep;
2267 short *functblp;
2268 int i, j;
2269
2270 /* ccBuf $B$N%"%m%1!<%H(B */
2271 if ((buf = (ccBuf)Malloc(sizeof(ccBufRec))) == NULL) {
2272 return (ccBuf)NULL;
2273 }
2274
2275 buf->rule = rule;
2276
2277 /* context $B%P%C%U%!$N%"%m%1!<%H(B */
2278 if (csize <= 0) csize = 1;
2279 buf->context = (wchar *)Malloc(csize * sizeof(wchar));
2280 if (buf->context == NULL) {
2281 Free(buf);
2282 return (ccBuf)NULL;
2283 }
2284 buf->contextend = buf->context;
2285 buf->contextsize = csize;
2286
2287 /* function $B%3%s%P!<%H%F!<%V%k$N%"%m%1!<%H(B */
2288 buf->functbl = (short *)Malloc(rule->nfunc * sizeof(short));
2289 if (buf->functbl == NULL) {
2290 Free(buf->context);
2291 Free(buf);
2292 return (ccBuf)NULL;
2293 }
2294 /* ccRule $B$KF~$C$F$$$k%U%!%s%/%7%g%sI=$H!"0z?t$GM?$($i$l$?(B
2295 * $B%U%!%s%/%7%g%sI=$+$i!"(BccRule $BFbIt$N%U%!%s%/%7%g%sHV9f$H(B
2296 * $B:#M?$($i$l$?%U%!%s%/%7%g%sHV9f$H$NBP1~I=$r:n$k(B
2297 */
2298 funcnamep = rule->funcnamebuf;
2299 functblp = buf->functbl;
2300 for (i = rule->nfunc, functblp = buf->functbl; i > 0; i--, functblp++) {
2301 for (j = 0; j < nfunc; j++) {
2302 if (!strcmp(functable[j], funcnamep)) {
2303 *functblp = j;
2304 break;
2305 }
2306 }
2307 if (j >= nfunc) *functblp = -1;
2308
2309 while (*funcnamep++)
2310 ;
2311 }
2312
2313 buf->defaultaction = def_action;
2314 buf->insertchar = insert;
2315 buf->deletechar = delete;
2316 buf->executefunction = execute;
2317 buf->modenotify = modenotify;
2318 buf->autofix = autofix;
2319 buf->client_data = data;
2320
2321 /* $B%+%l%s%H%b!<%I$N@_Dj(B */
2322 buf->previousmode = buf->currentmode = rule->initialmode;
2323 buf->modifier = 0;
2324
2325 return buf;
2326 }
2327
2328 /* ccFreeRule -- $B%k!<%k$r<N$F$k(B */
ccFreeRule(rule)2329 void ccFreeRule(rule)
2330 ccRule rule;
2331 {
2332 struct modetable *mtp = rule->modes;
2333 int i;
2334
2335 if (rule == NULL) return;
2336 if (--rule->refcnt > 0) return;
2337
2338 deleteRule(rule);
2339
2340 /* XXX */
2341 Free(mtp->cd_head);
2342 Free(mtp->prompt);
2343
2344 Free(rule->rulefile);
2345 /* XXX */
2346 Free(rule->modes);
2347 Free(rule->strbuf);
2348 Free(rule->funcbuf);
2349 Free(rule->funcnamebuf);
2350 Free(rule);
2351 }
2352
2353 /* ccDestroyBuf -- $BJQ49%P%C%U%!$r<N$F$k(B */
ccDestroyBuf(buf)2354 void ccDestroyBuf(buf)
2355 ccBuf buf;
2356 {
2357 if (buf == NULL) return;
2358 Free(buf->context);
2359 Free(buf->functbl);
2360 Free(buf);
2361 }
2362
2363 /* ccConvchar -- $BJQ49MQ%U%!%s%/%7%g%s(B */
ccConvchar(buf,event)2364 int ccConvchar(buf, event)
2365 ccBuf buf;
2366 XKeyPressedEvent *event; /* $B%-!<%$%Y%s%H(B */
2367 {
2368 int r;
2369 char str[256];
2370 char *p;
2371 int nbytes;
2372 int n;
2373 KeySym ks1, ks2;
2374 int mask;
2375
2376 /* $B$H$j$"$($:(B LookupString $B$7$F$*$/(B */
2377 nbytes = XLookupString(event, str, sizeof(str), &ks2, 0);
2378
2379 /* $BF~NO%-!<$r%b%G%#%U%!%$%d$D$-$K$9$k(B */
2380 if (buf->modifier) {
2381 if (!IsModifierKey(ks2)) {
2382 event->state |= buf->modifier;
2383 buf->modifier = 0;
2384 nbytes = XLookupString(event, str, sizeof(str), &ks2, 0);
2385 }
2386 }
2387
2388 /* $B$^$:$O%$%Y%s%H%3!<%I$GJQ49$7$F$_$k(B */
2389 r = -1;
2390 mask = ccEncodeMask(event);
2391
2392 /* $B$^$:$O%b%G%#%U%!%$%"$r0l:]9MN8$7$J$$(B KeySym $B$r(B
2393 * $B%3!<%I$H$7$FJQ49$7$F$_$k(B
2394 */
2395 ks1 = (ulong)XLookupKeysym(event, 0);
2396 if (ks1 != NoSymbol) {
2397 r = convchar(buf, (ulong)ks1 | (ulong)RAWKEY,
2398 mask, str, nbytes);
2399 }
2400
2401 /* $B>e$,%^%C%A$7$J$1$l$P!"(BShift, Lock, ModeSwitch $B$r(B
2402 * $B9MN8$7$?(B KeySym ($B$D$^$j(B XLookupString() $B$,JV$9(B KeySym) $B$,(B
2403 * NoSymbol $B$G$J$1$l$P$=$N%3!<%I$GJQ49$7$F$_$k(B
2404 */
2405 if (r < 0 && ks2 != NoSymbol) {
2406 int msw = getModeSwitchMask(event->display);
2407
2408 if (mask & (ShiftMask | LockMask | msw)) {
2409 mask &= ~(ShiftMask | LockMask | msw);
2410 r = convchar(buf, (ulong)ks2 | (ulong)RAWKEY,
2411 mask, str, nbytes);
2412 }
2413 }
2414
2415 if (r < 0) {
2416 int match = 0;
2417
2418 if (nbytes == 0) return 0;
2419
2420 /* ASCII $BI=5-$GJQ49$7$F$_$k(B */
2421 p = str;
2422 n = nbytes;
2423 while (n-- > 0) {
2424 r = convchar(buf, ccEncodeChar(*p), 0, p, 1);
2425 if (r >= 0) match = 1;
2426 p++;
2427 }
2428 if (!match) {
2429 /* default action $B$N%U%!%s%/%7%g%s$r$h$V(B */
2430 if (buf->defaultaction != NULL) {
2431 (void)(*buf->defaultaction)(str, nbytes, buf->client_data);
2432 }
2433 return 0;
2434 }
2435 }
2436 return 1;
2437 }
2438
2439 /* ccGetMode -- $B8=:_$N%b!<%IHV9f$rJV$9(B */
ccGetMode(buf)2440 int ccGetMode(buf)
2441 ccBuf buf;
2442 {
2443 return buf->currentmode->mt_index;
2444 }
2445
2446 /* ccGetModePrompt -- $B8=:_$N%b!<%I$N%W%m%s%W%HJ8;zNs$rJV$9(B */
ccGetModePrompt(buf)2447 wchar *ccGetModePrompt(buf)
2448 ccBuf buf;
2449 {
2450 return buf->currentmode->prompt;
2451 }
2452
2453 /* ccGetRule -- $BJQ49%P%C%U%!$G;H$o$l$F$$$kJQ49%k!<%k$rJV$9(B */
ccGetRule(buf)2454 ccRule ccGetRule(buf)
2455 ccBuf buf;
2456 {
2457 return buf->rule;
2458 }
2459
2460 /* ccContextAppend -- $B%3%s%F%-%9%H$K(B1$BJ8;z2C$($k(B */
ccContextAppend(buf,c)2461 void ccContextAppend(buf, c)
2462 ccBuf buf;
2463 int c;
2464 {
2465 wchar *p;
2466
2467 /* $B<+F03NDj(B */
2468 if (buf->context == buf->contextend &&
2469 buf->rule->autofix && buf->autofix) {
2470 buf->autofix(buf->client_data);
2471 }
2472
2473 /* $B%3%s%F%-%9%HJ8;zNs$KA^F~(B */
2474 if (buf->contextend - buf->context < buf->contextsize) {
2475 *buf->contextend++ = c;
2476 } else {
2477 /* $B%3%s%F%-%9%HJ8;zNs$,0lGU$J$N$G(B
2478 * $B@hF,$N#1J8;z$r<N$F$F$D$a$k(B
2479 */
2480 p = buf->context + 1;
2481 while (p < buf->contextend) {
2482 *(p - 1) = *p;
2483 p++;
2484 }
2485 /* $B$"$$$?=j$KA^F~(B */
2486 *--p = c;
2487 }
2488 }
2489
2490 /* ccContextDelete -- $B%3%s%F%-%9%H$r(B1$BJ8;z:o=|$9$k(B */
ccContextDelete(buf)2491 void ccContextDelete(buf)
2492 ccBuf buf;
2493 {
2494 if (buf->contextend > buf->context)
2495 buf->contextend--;
2496 }
2497
2498 /* ccContextClear -- $B%3%s%F%-%9%H$r%/%j%"$9$k(B */
ccContextClear(buf)2499 void ccContextClear(buf)
2500 ccBuf buf;
2501 {
2502 /* $B%b!<%I$,JQ$o$C$?;~$K$O<+F0E*$K%/%j%"$5$l$k$,$=$l0J30$K(B
2503 * $B8=:_$N%3%s%F%-%9%H$r6/@)E*$K%/%j%"$7$?$$>l9g$KMQ$$$k(B
2504 */
2505 buf->contextend = buf->context;
2506 }
2507
2508 /* ccContextSet -- $B%3%s%F%-%9%H$r%;%C%H$9$k(B */
ccContextSet(buf,cstr)2509 void ccContextSet(buf, cstr)
2510 ccBuf buf;
2511 wchar *cstr;
2512 {
2513 int len = wstrlen(cstr);
2514 wchar *p = buf->context;
2515
2516 if (len > buf->contextsize) {
2517 cstr += len - buf->contextsize;
2518 len = buf->contextsize;
2519 }
2520 while (len-- > 0) {
2521 *p++ = *cstr++;
2522 }
2523 }
2524
2525 /* ccContextGet -- $B8=:_$N%3%s%F%-%9%H$rJV$9(B */
ccContextGet(buf,cstr)2526 void ccContextGet(buf, cstr)
2527 ccBuf buf;
2528 wchar *cstr;
2529 {
2530 register wchar *wp = buf->context;
2531
2532 while (wp < buf->contextend)
2533 *cstr++ = *wp++;
2534 *cstr = 0;
2535 }
2536
2537
2538 /*
2539 * Obsolete Functions
2540 */
2541
2542 /* ccInit -- $BJQ49%k!<%k$rFI$_9~$s$G%P%C%U%!$r:n$k(B */
ccInit(deffile,contextsize,defactfunc,insertfunc,deletefunc,dofunc,errprint,functable,functablesize)2543 ccBuf ccInit(deffile, contextsize, defactfunc, insertfunc, deletefunc, dofunc,
2544 errprint, functable, functablesize)
2545 char *deffile;
2546 int contextsize;
2547 void (*defactfunc)();
2548 void (*insertfunc)();
2549 void (*deletefunc)();
2550 int (*dofunc)();
2551 void (*errprint)();
2552 char *functable[];
2553 int functablesize;
2554 {
2555 ccRule rule;
2556
2557 if ((rule = ccParseRule(deffile, errprint)) == NULL) {
2558 return (ccBuf)NULL;
2559 }
2560
2561 return ccCreateBuf(rule, contextsize, functable, functablesize,
2562 defactfunc, insertfunc, deletefunc, dofunc,
2563 (void (*)())NULL, (void (*)())NULL, (caddr_t)NULL);
2564 }
2565
2566 /* ccTerminate -- $BF~NOJ8;zJQ49$r=*N;$9$k(B */
ccTerminate(buf)2567 void ccTerminate(buf)
2568 ccBuf buf;
2569 {
2570 ccFreeRule(buf->rule);
2571 ccDestroyBuf(buf);
2572 }
2573
2574 #ifdef DEBUG_CCONV
2575 /*
2576 * Debug Functions
2577 */
2578
putws(s)2579 static void putws(s)
2580 wchar *s;
2581 {
2582 unsigned char line[256];
2583
2584 (void)convJWStoSJIS(s, line);
2585 fputs(line, stdout);
2586 }
2587
puteuc(s)2588 static void puteuc(s)
2589 uchar *s;
2590 {
2591 wchar tmp[256];
2592
2593 (void)convEUCtoJWS(s, tmp);
2594 putws(tmp);
2595 }
2596
dumpRules(rule,mode)2597 void dumpRules(rule, mode)
2598 ccRule rule;
2599 struct modetable *mode;
2600 {
2601 int nkey;
2602 struct modetable *mtp;
2603 struct convdesc *cdp;
2604 wchar *strbuf = rule->strbuf;
2605 ushort *funcbuf = rule->funcbuf;
2606 char **funcnames;
2607 wchar *p, *q;
2608 wchar restmp[256];
2609 ushort *funcp;
2610 int i, j;
2611
2612 funcnames = (char **)__builtin_alloca(rule->nfunc * sizeof(char *));
2613 {
2614 char *cp, **fnp;
2615 cp = rule->funcnamebuf;
2616 fnp = funcnames;
2617 for (i = 0; i < rule->nfunc; i++) {
2618 *fnp++ = cp;
2619 while (*cp++)
2620 ;
2621 }
2622 }
2623
2624 if (mode == NULL) {
2625 printf("No such mode\n");
2626 return;
2627 }
2628 mtp = rule->modes;
2629
2630 printf("mode: %s (%d) prompt: ", mtp->name, mtp->mt_index);
2631 putws(mtp->prompt);
2632 if (mtp->fallthrough != NULL) {
2633 printf(" fallthrough: %s", mtp->fallthrough->name);
2634 }
2635 putchar('\n');
2636
2637 for (cdp = mtp->cd_head; cdp; cdp = cdp->next) {
2638 printf("rule: \"");
2639 putws(strbuf + cdp->context);
2640 printf("\"\t");
2641 if (cdp->key & RAWKEY) {
2642 ulong key = cdp->key & ~RAWKEY;
2643 int mask = cdp->mask;
2644 char *keysymname;
2645 if (mask & ShiftMask) printf("shift-");
2646 if (mask & ControlMask) printf("control-");
2647 if (mask & LockMask) printf("lock-");
2648 if (mask & Mod1Mask) printf("mod1-");
2649 if (mask & Mod2Mask) printf("mod2-");
2650 if (mask & Mod3Mask) printf("mod3-");
2651 if (mask & Mod4Mask) printf("mod4-");
2652 if (mask & Mod5Mask) printf("mod5-");
2653 keysymname = XKeysymToString((KeySym)key);
2654 printf(keysymname ? keysymname : "<illegal keysym>");
2655 } else if (cdp->key & METAC) {
2656 switch (cdp->key & ~METAC) {
2657 case META_ASCII: printf("@ascii"); break;
2658 case META_CONTROL: printf("@control"); break;
2659 case META_RAW: printf("@raw"); break;
2660 case META_ANY: printf("@any"); break;
2661 case META_FUNC: printf("@func"); break;
2662 case META_CURSOR: printf("@cursor"); break;
2663 case META_KEYPAD: printf("@keypad"); break;
2664 case META_MODIFIER: printf("@modifier"); break;
2665 case META_NONASCII: printf("@non-ascii"); break;
2666 case META_PRINTABLE: printf("@printable"); break;
2667 default: printf("<illegal meta>");
2668 }
2669 } else if (cdp->key & PSEUDO) {
2670 switch (cdp->key) {
2671 case ENTERMODE: printf("ENTERMODE"); break;
2672 case EXITMODE: printf("EXITMODE"); break;
2673 default: printf("<illegal pseudo>");
2674 }
2675 } else {
2676 putchar('\'');
2677 if (cdp->key >= 0x80) {
2678 printf("\\x%x", cdp->key);
2679 } else if (cdp->key < 0x20) {
2680 putchar('^');
2681 putchar(cdp->key + '@');
2682 } else if (cdp->key == 0x7f) {
2683 printf("^?");
2684 } else {
2685 putchar(cdp->key);
2686 }
2687 putchar('\'');
2688 }
2689 printf("\t\"");
2690 p = restmp;
2691 q = strbuf + cdp->result;
2692 while (*q) {
2693 if (*q == MATCHED_CHAR) {
2694 *p++ = '&';
2695 } else if (*q == CCLEAR_CHAR) {
2696 *p++ = '/';
2697 } else {
2698 *p++ = *q;
2699 }
2700 q++;
2701 }
2702 *p = 0;
2703 putws(restmp);
2704 printf("\"\t");
2705 funcp = funcbuf + cdp->function;
2706 while (*funcp != ENDFUNC) {
2707 if (*funcp == REDO) {
2708 printf("redo ");
2709 } else if (*funcp == PREVMODE) {
2710 printf("goto prev ");
2711 } else if (*funcp & MODECHANGE) {
2712 int gotomode = *funcp & ~MODECHANGE;
2713 if (gotomode < 0 || gotomode >= rule->nmode) {
2714 printf("<illegal goto>");
2715 } else {
2716 printf("goto %s ",
2717 rule->modes[gotomode].name);
2718 }
2719 } else {
2720 if (*funcp >= rule->nfunc) {
2721 printf("<illegal function> ");
2722 } else {
2723 printf("%s ", funcnames[*funcp]);
2724 }
2725 }
2726 funcp++;
2727 }
2728 putchar('\n');
2729 cdp++;
2730 }
2731 putchar('\n');
2732 }
2733
dumpAllRules(rule)2734 void dumpAllRules(rule)
2735 ccRule rule;
2736 {
2737 int i;
2738 struct modetable *mtp;
2739
2740 printf("** RULE DUMP **\n");
2741 printf("number of modes: %d initialmode: %s (%d)\n\n",
2742 rule->nmode,
2743 rule->initialmode->name,
2744 rule->initialmode->mt_index);
2745 for (mtp = rule->modes; mtp; mtp = mtp->next) {
2746 dumpRules(rule, mtp);
2747 }
2748 fflush(stdout);
2749 }
2750 #endif
2751