1 /* $Id: kinsoku.c,v 1.4 2001/02/18 17:07:26 amura Exp $ */
2 /*
3 * Kinsoku char handling routines.
4 * These are only used when KANJI is #defined.
5 *
6 * Coded by Shigeki Yoshida (shige@csk.CO.JP)
7 */
8
9 /*
10 * $Log: kinsoku.c,v $
11 * Revision 1.4 2001/02/18 17:07:26 amura
12 * append AUTOSAVE feature (but NOW not work)
13 *
14 * Revision 1.3 2001/02/11 15:40:25 amura
15 * some function are changed to static for speed/size
16 *
17 * Revision 1.2 2000/11/16 14:31:13 amura
18 * fix some typos which cause compile error when using
19 * strict ANSI-C compiler (ex ACK, gcc-1.x)
20 *
21 * Revision 1.1.1.1 2000/06/27 01:47:56 amura
22 * import to CVS
23 *
24 */
25 /* 90.01.29 Created by S.Yoshida */
26
27 #include "config.h" /* 90.12.20 by S.Yoshida */
28
29 #ifdef KINSOKU /* 90.01.29 by S.Yoshida */
30 #include "def.h"
31
32 #define MAXBOLKC 128 /* Maximum number of BOL (begin */
33 /* of line) KINSOKU chars. */
34 #define MAXEOLKC 64 /* Maximum number of EOL (end */
35 /* of line) KINSOKU chars. */
36
37 /* BOL KINSOKU char list (EUC). */
38 /* This table must be sorted. */
39 static unsigned short bolkchar[MAXBOLKC] = {
40 '!', '\'', ')', ',', '-', /* 5 */
41 '.', ':', ';', '?', ']', /* 10 */
42 '_', '}', '~', 0xa1a2, 0xa1a3, /* 15 */
43 0xa1a4, 0xa1a5, 0xa1a6, 0xa1a7, 0xa1a8, /* 20 */
44 0xa1a9, 0xa1aa, 0xa1ab, 0xa1ac, 0xa1ad, /* 25 */
45 0xa1ae, 0xa1af, 0xa1b0, 0xa1b1, 0xa1b2, /* 30 */
46 0xa1b3, 0xa1b4, 0xa1b5, 0xa1b6, 0xa1b7, /* 35 */
47 0xa1b8, 0xa1b9, 0xa1ba, 0xa1bb, 0xa1bc, /* 40 */
48 0xa1bd, 0xa1be, 0xa1bf, 0xa1c0, 0xa1c1, /* 45 */
49 0xa1c2, 0xa1c3, 0xa1c4, 0xa1c5, 0xa1c7, /* 50 */
50 0xa1c9, 0xa1cb, 0xa1cd, 0xa1cf, 0xa1d1, /* 55 */
51 0xa1d3, 0xa1d5, 0xa1d7, 0xa1d9, 0xa1db, /* 60 */
52 0xa1eb, 0xa1ec, 0xa1ed, 0xa1ee, 0xa4a1, /* 65 */
53 0xa4a3, 0xa4a5, 0xa4a7, 0xa4a9, 0xa4c3, /* 70 */
54 0xa4e3, 0xa4e5, 0xa4e7, 0xa4ee, 0xa5a1, /* 75 */
55 0xa5a3, 0xa5a5, 0xa5a7, 0xa5a9, 0xa5c3, /* 80 */
56 0xa5e3, 0xa5e5, 0xa5e7, 0xa5ee, 0xa5f5, /* 85 */
57 0xa5f6
58 };
59
60 /* EOL KINSOKU char list (EUC). */
61 /* This table must be sorted. */
62 static unsigned short eolkchar[MAXEOLKC] = {
63 '(', '[', '{', 0xa1c6, 0xa1c8, /* 5 */
64 0xa1ca, 0xa1cc, 0xa1ce, 0xa1d0, 0xa1d2, /* 10 */
65 0xa1d4, 0xa1d6, 0xa1d8, 0xa1da, 0xa1eb, /* 15 */
66 0xa1ec, 0xa1ed, 0xa1ee, 0xa1f7, 0xa1f8 /* 20 */
67 };
68
69 static int nbolkc = 86; /* Number of BOL KINSOKU chars. */
70 static int neolkc = 20; /* Number of EOL KINSOKU chars. */
71
72 /*
73 * FUNCTION: list-kinsoku-chars
74 * Display a list of kinsoku-bol-chars and kinsoku-eol-chars values
75 * in the *Kinsoku Chars* buffer.
76 */
77 /*ARGSUSED*/
kc_list_char(f,n)78 kc_list_char(f, n)
79 {
80 register unsigned short *p; /* KINSOKU char list pointer. */
81 register unsigned short *eop; /* End of KINSOKU char list. */
82 register char c;
83 register char *l; /* Display line buffer pointer. */
84 register char *eol; /* End of display line buffer. */
85 register BUFFER *bp;
86 register WINDOW *wp;
87 #define DISPLEN 64
88 char line[DISPLEN + 1]; /* Display line buffer. */
89
90 if ((bp = bfind("*Kinsoku Chars*", TRUE)) == NULL) return FALSE;
91 #ifdef AUTOSAVE /* 96.12.24 by M.Suzuki */
92 bp->b_flag &= ~(BFCHG | BFACHG); /* Blow away old. */
93 #else
94 bp->b_flag &= ~BFCHG; /* Blow away old. */
95 #endif /* AUTOSAVE */
96 if (bclear(bp) != TRUE) return FALSE;
97
98 strcpy(line, "kinsoku-bol-chars:"); /* BOL KINSOKU char list. */
99 if (addline(bp, line) == FALSE) return FALSE;
100 l = line;
101 *l++ = '\t'; /* List line start with TAB. */
102 eol = &line[DISPLEN];
103 p = bolkchar;
104 eop = &bolkchar[nbolkc];
105 while (p < eop) {
106 if (l >= eol) {
107 *l = '\0';
108 if (addline(bp, line) == FALSE) return FALSE;
109 l = line;
110 *l++ = '\t'; /* List line start with TAB. */
111 } else {
112 if ((c = (*p >> 8) & 0xff) != 0) {
113 *l++ = c;
114 }
115 c = *p++ & 0xff;
116 if (ISCTRL(c)) { /* This may be needless... */
117 *l++ = '^';
118 *l++ = CCHR(c);
119 } else {
120 *l++ = c;
121 }
122 }
123 }
124 if (l > line) { /* Not shown line exists. */
125 *l = '\0';
126 if (addline(bp, line) == FALSE) return FALSE;
127 }
128 line[0] = '\0';
129 if (addline(bp, line) == FALSE) return FALSE;
130
131 strcpy(line, "kinsoku-eol-chars:"); /* EOL KINSOKU char list. */
132 if (addline(bp, line) == FALSE) return FALSE;
133 l = line;
134 *l++ = '\t'; /* List line start with TAB. */
135 eol = &line[DISPLEN];
136 p = eolkchar;
137 eop = &eolkchar[neolkc];
138 while (p < eop) {
139 if (l >= eol) {
140 *l = '\0';
141 if (addline(bp, line) == FALSE) return FALSE;
142 l = line;
143 *l++ = '\t'; /* List line start with TAB. */
144 } else {
145 if ((c = (*p >> 8) & 0xff) != 0) {
146 *l++ = c;
147 }
148 c = *p++ & 0xff;
149 if (ISCTRL(c)) { /* This may be needless... */
150 *l++ = '^';
151 *l++ = CCHR(c);
152 } else {
153 *l++ = c;
154 }
155 }
156 }
157 if (l > line) { /* Not shown line exists. */
158 *l = '\0';
159 if (addline(bp, line) == FALSE) return FALSE;
160 }
161
162 if ((wp = popbuf(bp)) == NULL) return FALSE;
163 bp->b_dotp = lforw(bp->b_linep); /* put dot at beginning of buffer */
164 bp->b_doto = 0;
165 wp->w_dotp = bp->b_dotp; /* fix up if window already on screen */
166 wp->w_doto = bp->b_doto;
167 return TRUE;
168 }
169
170 /*
171 * FUNCTION: add-kinsoku-bol-chars
172 * Add some BOL (begin of line) KINSOKU chars to a BOL KINSOKU char list
173 * (kinsoku-bol-chars = bolkchar[]).
174 */
175 /*ARGSUSED*/
kc_add_bol(f,n)176 kc_add_bol(f, n)
177 {
178 register int s;
179 register short c;
180 register char *p;
181 char kchar[NFILEN];
182
183 if ((s = ereply("Kinsoku Chars : ", kchar, NFILEN)) != TRUE) {
184 return (s);
185 }
186
187 for (p = kchar; *p;) {
188 c = *p++ & 0xff;
189 if (ISKANJI(c)) {
190 c = (c << 8) | (*p++ & 0xff);
191 }
192 if (nbolkc < MAXBOLKC) {
193 if (kcinsert(bolkchar, c, nbolkc)) {
194 nbolkc++;
195 }
196 } else {
197 ewprintf("Too many kinsoku-bol-chars!");
198 return FALSE;
199 }
200 }
201 return TRUE;
202 }
203
204 /*
205 * FUNCTION: delete-kinsoku-bol-chars
206 * Delete some BOL (begin of line) KINSOKU chars from a BOL KINSOKU char list
207 * (kinsoku-bol-chars = bolkchar[]).
208 */
209 /*ARGSUSED*/
kc_del_bol(f,n)210 kc_del_bol(f, n)
211 {
212 register int s;
213 register short c;
214 register char *p;
215 char kchar[NFILEN];
216
217 if ((s = ereply("Kinsoku Chars : ", kchar, NFILEN)) != TRUE) {
218 return (s);
219 }
220
221 for (p = kchar; *p;) {
222 c = *p++ & 0xff;
223 if (ISKANJI(c)) {
224 c = (c << 8) | (*p++ & 0xff);
225 }
226 if (nbolkc > 0) {
227 if (kcdelete(bolkchar, c, nbolkc)) {
228 nbolkc--;
229 }
230 } else {
231 ewprintf("No kinsoku-bol-chars!");
232 return FALSE;
233 }
234 }
235 return TRUE;
236 }
237
238 /*
239 * FUNCTION: add-kinsoku-eol-chars
240 * Add some EOL (end of line) KINSOKU chars to a EOL KINSOKU char list
241 * (kinsoku-eol-chars = eolkchar[]).
242 */
243 /*ARGSUSED*/
kc_add_eol(f,n)244 kc_add_eol(f, n)
245 {
246 register int s;
247 register short c;
248 register char *p;
249 char kchar[NFILEN];
250
251 if ((s = ereply("Kinsoku Chars : ", kchar, NFILEN)) != TRUE) {
252 return (s);
253 }
254
255 for (p = kchar; *p;) {
256 c = *p++ & 0xff;
257 if (ISKANJI(c)) {
258 c = (c << 8) | (*p++ & 0xff);
259 }
260 if (neolkc < MAXEOLKC) {
261 if (kcinsert(eolkchar, c, neolkc)) {
262 neolkc++;
263 }
264 } else {
265 ewprintf("Too many kinsoku-eol-chars!");
266 return FALSE;
267 }
268 }
269 return TRUE;
270 }
271
272 /*
273 * FUNCTION: delete-kinsoku-eol-chars
274 * Delete some EOL (end of line) KINSOKU chars from a EOL KINSOKU char list
275 * (kinsoku-eol-chars = eolkchar[]).
276 */
277 /*ARGSUSED*/
kc_del_eol(f,n)278 kc_del_eol(f, n)
279 {
280 register int s;
281 register short c;
282 register char *p;
283 char kchar[NFILEN];
284
285 if ((s = ereply("Kinsoku Chars : ", kchar, NFILEN)) != TRUE) {
286 return (s);
287 }
288
289 for (p = kchar; *p;) {
290 c = *p++ & 0xff;
291 if (ISKANJI(c)) {
292 c = (c << 8) | (*p++ & 0xff);
293 }
294 if (neolkc > 0) {
295 if (kcdelete(eolkchar, c, neolkc)) {
296 neolkc--;
297 }
298 } else {
299 ewprintf("No kinsoku-eol-chars!");
300 return FALSE;
301 }
302 }
303 return TRUE;
304 }
305
306 /*
307 * Insert one KINSOKU char in a KINSOKU char list.
308 */
309 int
310 #ifdef SUPPORT_ANSI /* for strict compiler */
kcinsert(unsigned short * kclist,unsigned short kc,int nkc)311 kcinsert(unsigned short *kclist, unsigned short kc, int nkc)
312 #else
313 kcinsert(kclist, kc, nkc)
314 unsigned short *kclist; /* KINSOKU char list. */
315 unsigned short kc; /* Target KINSOKU char. */
316 int nkc; /* Current number of KINSOKU chars. */
317 #endif
318 {
319 unsigned short *p = kclist; /* Start of KINSOKU char list. */
320 unsigned short *eop = &kclist[nkc]; /* End of KINSOKU char list. */
321 unsigned short *pp;
322
323 for (; p < eop; p++) {
324 if (kc < *p) {
325 break;
326 } else if (kc == *p) { /* Already exist. */
327 return FALSE;
328 }
329 }
330 if (p < eop) {
331 pp = eop;
332 for (; pp > p; pp--) {
333 *pp = pp[-1];
334 }
335 }
336 *p = kc;
337 return TRUE;
338 }
339
340 /*
341 * Delete one KINSOKU char form a KINSOKU char list.
342 */
343 int
344 #ifdef SUPPORT_ANSI /* for strict compiler */
kcdelete(unsigned short * kclist,unsigned short kc,int nkc)345 kcdelete(unsigned short *kclist, unsigned short kc,int nkc)
346 #else
347 kcdelete(kclist, kc, nkc)
348 unsigned short *kclist; /* KINSOKU char list. */
349 unsigned short kc; /* Target KINSOKU char. */
350 int nkc; /* Current number of KINSOKU chars. */
351 #endif
352 {
353 unsigned short *p = kclist; /* Start of KINSOKU char list. */
354 unsigned short *eop = &kclist[nkc]; /* End of KINSOKU char list. */
355
356 for (; p < eop; p++) {
357 if (kc == *p) {
358 break;
359 }
360 }
361 if (p == eop) { /* Not exist that char. */
362 return FALSE;
363 }
364 for (; p < eop; p++) {
365 *p = p[1];
366 }
367 return TRUE;
368 }
369
370 /*
371 * Is this BOL (begin of line) KINSOKU char ?
372 * c1 must be KANJI 1st byte or 0 (when c2 is ASCII).
373 */
isbolkchar(c1,c2)374 isbolkchar(c1, c2)
375 int c1;
376 int c2;
377 {
378 register unsigned short c = ((c1 & 0xff) << 8) | (c2 & 0xff);
379 register unsigned short *p = &bolkchar[0];
380 register unsigned short *eop = &bolkchar[nbolkc];
381
382 if (c < *p || c > eop[-1]) {
383 return FALSE;
384 }
385 while (p < eop) {
386 if (c == *p++) {
387 return TRUE;
388 }
389 }
390 return FALSE;
391 }
392
393 /*
394 * Is this EOL (end of line) KINSOKU char ?
395 * c1 must be KANJI 1st byte or 0 (when c2 is ASCII).
396 */
iseolkchar(c1,c2)397 iseolkchar(c1, c2)
398 int c1;
399 int c2;
400 {
401 register unsigned short c = ((c1 & 0xff) << 8) | (c2 & 0xff);
402 register unsigned short *p = &eolkchar[0];
403 register unsigned short *eop = &eolkchar[neolkc];
404
405 if (c < *p || c > eop[-1]) {
406 return FALSE;
407 }
408 while (p < eop) {
409 if (c == *p++) {
410 return TRUE;
411 }
412 }
413 return FALSE;
414 }
415 #endif /* KINSOKU */
416