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