1 /* cntrl.c */
2 /*****************************************************************************
3 					�ԣ�������У���������أԣ�
4 
5 							�����楳���ɽ�����
6 *****************************************************************************/
7 
8 #include "xtr.h"
9 
10 #define SameSeq(a, b) 	((a)->rpllen == (b)->rpllen && \
11 						 !memcmp((a)->rpl, (b)->rpl, (a)->rpllen))
12 
13 #define SameGrp(a, b)	((a)->grp == (b)->grp)
14 #define SameGrp1(a, b)	(SameGrp((a), (b)) && \
15 							((a)->grp || (a)->cmode == (b)->cmode))
16 #define SameGrpS(a, b) 	(SameGrp((a), (b)) && \
17 							((a)->grp || (a)->cmode == (b)->cmode && \
18 											SameSeq((a), (b))))
19 
20 #define FreeCntrl1(obj)	(XFree((voidstar)(obj)->fnd), XFree((voidstar)(obj)->rpl), XFree((voidstar)(obj)))
21 
22 
23 static int
MemberSameGrp(def_t * obj,def_t * clist)24 MemberSameGrp(def_t *obj, def_t *clist)
25 /* obj ��Ʊ�����롼�פ����Ǥ� clist �ˤ��뤫 */
26 {
27 	if (obj != NULL) {
28 		for (; clist != NULL; clist = clist->prev) {
29 			if (SameGrpS(obj, clist))
30 				return TRUE;
31 		}
32 	}
33 	return FALSE;
34 }
35 
36 static int
MemberCntrl(def_t * obj,def_t * clist)37 MemberCntrl(def_t *obj, def_t *clist)
38 /* obj �� clist �����Ǥ� */
39 {
40 	if (obj != NULL) {
41 		for (; clist != NULL; clist = clist->prev) {
42 			if (obj == clist)
43 				return TRUE;
44 		}
45 	}
46 	return FALSE;
47 }
48 
49 static void
FreeCntrl(def_t * cntrl)50 FreeCntrl(def_t *cntrl)
51 /* ���楳���ɥꥹ�� cntrl �������� */
52 {
53 	def_t *pprev;
54 
55 	while (cntrl) {
56 		pprev = cntrl->prev;
57 		FreeCntrl1(cntrl);
58 		cntrl = pprev;
59 	}
60 }
61 
62 /**************************************************************************/
63 
64 void
ResetCntrl(def_t ** cntrlp)65 ResetCntrl(def_t **cntrlp)
66 /* ���楳���ɥꥹ�� *cntrlp �������ƶ��ˤ��� */
67 {
68 	assert(cntrlp != NULL);
69 
70 	FreeCntrl(*cntrlp);
71 	*cntrlp = NULL;
72 }
73 
74 def_t *
DupCntrl1(def_t * org)75 DupCntrl1(def_t *org)
76 {
77 	if (org == NULL) {
78 		return NULL;
79 	} else {
80 		def_t *cntrl = (def_t *)XMalloc(sizeof(def_t));
81 #if 0
82 		cntrl->fnd = DupStrN(org->fnd, org->fndlen);
83 		cntrl->fndlen = org->fndlen;
84 #else
85 		cntrl->fnd = NULL;
86 		cntrl->fndlen = 0;
87 #endif
88 		cntrl->rpl = DupStrN(org->rpl, org->rpllen);
89 		cntrl->rpllen = org->rpllen;
90 		cntrl->mode = org->mode;
91 		cntrl->cmode = org->cmode;
92 		cntrl->grp = org->grp;
93 		cntrl->prev = NULL;
94 		return cntrl;
95 	}
96 }
97 
98 def_t *
DupCntrl(def_t * org)99 DupCntrl(def_t *org)
100 {
101 	if (org == NULL) {
102 		return NULL;
103 	} else {
104 		def_t *cntrl = DupCntrl1(org);
105 		cntrl->prev = DupCntrl(org->prev);
106 		return cntrl;
107 	}
108 }
109 
110 
111 /**************************************************************************/
112 
113 def_t *
AddCntrl(def_t * org,def_t * add)114 AddCntrl(def_t *org, def_t *add)
115 {
116 	assert(add != NULL);
117 
118 	if (org != NULL && SameGrp(org, add) && SameSeq(org, add)) {
119 		return org;
120 	} else {
121 		def_t *cntrl = DupCntrl1(add);
122 		cntrl->prev = org;
123 		return cntrl;
124 	}
125 }
126 
127 static def_t *
RemCntrlSub(def_t * org,def_t * rem)128 RemCntrlSub(def_t *org, def_t *rem)
129 {
130 	assert(rem != NULL);
131 
132 	if (org == NULL)
133 		return NULL;
134 	else if (SameGrpS(org, rem))
135 		return org->prev;
136 	else
137 		return AddCntrl(RemCntrlSub(org->prev, rem), org);
138 }
139 
140 def_t *
RemCntrl(def_t * org,def_t * rem)141 RemCntrl(def_t *org, def_t *rem)
142 /* ���楳���ɥꥹ�� org ���� rem �ޤ��ϡ�
143    rem ��Ʊ�����롼�פ����楳���ɤ��ļ�������
144    ���楳���ɥꥹ�Ȥ��֤��������˲�Ū�� */
145 {
146 	assert(rem != NULL);
147 
148 	if (MemberSameGrp(rem, org))
149 		return RemCntrlSub(org, rem);
150 	else
151 		return org;
152 }
153 
154 
155 /**************************************************************************/
156 
157 int
RemFCntrl(def_t ** cntrlp,def_t * rem)158 RemFCntrl(def_t **cntrlp, def_t *rem)
159 /* ���楳���ɥꥹ�� *cntrlp ���� rem �ޤ��ϡ�*/
160 /* rem ��Ʊ�����롼�פ����楳���ɤ��ļ����� */
161 /* ���������� 1 ���Ǥʤ��ä��� 0 ���֤� */
162 {
163 	def_t **cp = cntrlp;
164 	def_t *p = *cntrlp;
165 
166 	assert(cntrlp != NULL);
167 	assert(rem != NULL);
168 
169 	while (p) {
170 		if (SameGrpS(p, rem)) {
171 			/* ���Ĥ��ä��� */
172 			*cp = p->prev;
173 			FreeCntrl1(p);
174 			return 1;
175 		}
176 		cp = &(p->prev);
177 		p = *cp;
178 	}
179 	return 0;
180 }
181 
182 
183 /**************************************************************************/
184 
185 /* SGR���������ʤ鿿���֤� */
186 #define IsSGRseq(seq, len)	\
187 	(seq[0] == '\033' && seq[1] == '[' && seq[len-1] == 'm')
188 
189 static int
WasSGRseq(void)190 WasSGRseq(void)
191 /* ľ����PC98��SGR���������Ǥ��뤫��Ĵ�٤� */
192 {
193 	uchar *p = cbufp;
194 	if (--p <= cbuf || *p != 'm')
195 		return 0;				/* �Ǹ��ʸ���� 'm' �Ǥʤ��ʤ鵶 */
196 
197 	while (--p > cbuf)			/* ����鸫�Ƥ��� */
198 		if (*p == '[')
199 			return 1;			/* '[' �����ä��鿿 */
200 		else if (*p < 0x30 || *p > 0x3b)
201 			return 0;			/* ������ ';' �ʳ�������е� */
202 	return 0;
203 }
204 
205 static void
ExtractCntrl1(def_t * cntrl)206 ExtractCntrl1(def_t *cntrl)
207 /* ��Ĥ����楳���ɤ����Ƥ���Ф� */
208 {
209 	uchar *rpl = cntrl->rpl;
210 	int	   len = cntrl->rpllen;
211 
212 	if (cntrl->mode & R_EVAL) {
213 		/* ʸ����ɾ�����꤬����� */
214 		marg_t	*margv0 = margv;
215 		int		margc0 = margc;
216 		margv = NULL;
217 		margc = 0;
218 		rpl = AEvalStringN(&len, rpl, len);					/* %-�Ѵ� */
219 		margc = margc0;
220 		margv = margv0;
221 	}
222 	if (cbufp - len >= cbuf && memcmp(rpl, cbufp - len, len)==0) {
223 		/* ľ���Υ����ɤ�Ʊ�����Ƥʤ��ά */
224 		;
225 	} else {
226 		/* @@ ���ν����Ǥ��Խ�ʬ */
227 		if (sgr98mode && IsSGRseq(rpl, len) && WasSGRseq()) {
228 			/* �⤷��PC98 SGR mode �ǡ����Τ�ľ�������楳���ɤ�
229 			   SGR �����������ä��顢���Ĥ� SGR seq ��Ϣ�뤹�� */
230 			/* �㡧 "\x1b[7m" + "\x1b[32m" �� "\x1b[7;32m" */
231 			*(cbufp - 1) = ';';		/* ���� SGR seq �� "m" �� ";" ���Ѥ��� */
232 			rpl += 2;				/* ��� "\x1b[" �����Ф� */
233 			len -= 2;
234 		}
235 		memcpy(cbufp, rpl, len);
236 		cbufp += len;
237 		if (cbufp > cbuf + CBUFSIZE)
238 			FError("Code buffer over");
239 	}
240 	if (cntrl->mode & R_EVAL)
241 		XFree((voidstar)rpl);
242 }
243 
244 
245 static void
ExtractCntrl2(def_t * cntrls,int grp)246 ExtractCntrl2(def_t *cntrls, int grp)
247 /* ���楳���ɥꥹ�� cntrls �����Ƥ���Ф��ƥХåե� cbufp ���Ÿ������ */
248 /* 0 �ʳ��� grp ��Ϳ�����Ƥ����顢���� grp �Ȱ��פ����ΤΤ߼��Ф� */
249 /* ���楳���ɤ�Ĺ����ʬ�������ݥ��� cbufp ��ʤ�� */
250 {
251 	if (cntrls == NULL)
252 		return;
253 	else {
254 		ExtractCntrl2(cntrls->prev, grp);	/* �ޤ��������Ρ����Ǥ���� */
255 		if (!grp || grp == cntrls->grp) {
256 			/* ���롼�׻���̵����̵���ˤ����롼�פ����פ���� */
257 			ExtractCntrl1(cntrls);
258 		}
259 	}
260 }
261 
262 
263 int
ExtractCntrl(def_t * cntrls,int grp)264 ExtractCntrl(def_t *cntrls, int grp)
265 /* ���楳���ɥꥹ�� cntrls �����Ƥ���Ф��ƥХåե� cbuf[] ���Ÿ������ */
266 /* 0 �ʳ��� grp ��Ϳ�����Ƥ����顢���� grp �Ȱ��פ����ΤΤ߼��Ф� */
267 /* Ĺ�����֤� */
268 {
269 	cbufp = cbuf;
270 	ExtractCntrl2(cntrls, grp);
271 	*cbufp = 0;
272 	return clength = cbufp - cbuf;
273 }
274 
275 
276 int
ExtractResetCntrl(def_t * cntrls,def_t * rescntrls)277 ExtractResetCntrl(def_t *cntrls, def_t *rescntrls)
278 /* ���ߤ�ʸ�����������楳���ɥꥹ�Ȥ� cntrls��
279    ʸ��������������楳���ɥꥹ�Ȥ� rescntrls �Ȥ��ơ�
280    ���ߤ�ʸ��������������Τ�ɬ�פ����楳���ɤΤߤ� cbuf[] ��Ÿ������ */
281 {
282 	cbufp = cbuf;
283 	for ( ; cntrls; cntrls = cntrls->prev)
284 		ExtractCntrl2(rescntrls, cntrls->grp);
285 
286 	*cbufp = 0;
287 	return clength = cbufp - cbuf;
288 }
289 
290 
291 static void
ExtractReputCntrl2(def_t * cntrls,def_t * rescntrls,def_t * rescntrl)292 ExtractReputCntrl2(def_t *cntrls,def_t *rescntrls,def_t *rescntrl)
293 {
294 	assert(rescntrl != NULL);
295 
296 	if (cntrls == NULL)
297 		return;
298 
299 	ExtractReputCntrl2(cntrls->prev, rescntrls, rescntrl); /* ���Τ���˽��� */
300 	for ( ; rescntrls ; rescntrls = rescntrls->prev) {
301 		if (SameGrp1(cntrls, rescntrls) && SameSeq(rescntrls, rescntrl)) {
302 			/* ���롼�פ����פ���ʸ����������Υ����ɡ�rescntrls �����ǡˤ�
303 			   ���˽��Ϥ���ʸ����������Υ����� rescntrl �ȥ��������Ƥ�
304 			   Ʊ��Ǥ������楳���ɤ� cntrls �����ǤȤ���¸�ߤ����
305 			   �������Ф� */
306 			ExtractCntrl1(cntrls);
307 		}
308 	}
309 }
310 
311 
312 int
ExtractReputCntrl(def_t * rescntrl)313 ExtractReputCntrl(def_t *rescntrl)
314 /* rescntrl ����Ϥ������Ȥǰ��˲������Ƥ��ޤä�ʸ��������
315    �����������楳���ɤ�Ȥ���� */
316 {
317 	assert(rescntrl != NULL);
318 
319 	cbufp = cbuf;
320 
321 	if (c_attr)
322 		ExtractReputCntrl2(c_attr, c_areset, rescntrl);
323 	if (c_wide)
324 		ExtractReputCntrl2(c_wide, c_wreset, rescntrl);
325 	if (c_vexpand)
326 		ExtractReputCntrl2(c_vexpand, c_vreset, rescntrl);
327 	if (c_qexpand)
328 		ExtractReputCntrl2(c_qexpand, c_qreset, rescntrl);
329 	if (c_half)
330 		ExtractReputCntrl2(c_half, c_hreset, rescntrl);
331 	if (c_font)
332 		ExtractReputCntrl2(c_font, c_freset, rescntrl);
333 
334 	*cbufp = 0;
335 	return clength = cbufp - cbuf;
336 }
337 
338 static void InitCntrlPosVects ARGS((void));
339 
340 void
ResetCntrlLists(void)341 ResetCntrlLists(void)
342 {
343 	ResetCntrl(&c_reset);
344 	ResetCntrl(&c_terminate);
345 	ResetCntrl(&c_newline);
346 	ResetCntrl(&c_newpage);
347 	ResetCntrl(&c_reset2);
348 	ResetCntrl(&c_areset);
349 	ResetCntrl(&c_vreset);
350 	ResetCntrl(&c_qreset);
351 	ResetCntrl(&c_wreset);
352 	ResetCntrl(&c_hreset);
353 	ResetCntrl(&c_freset);
354 	ResetCntrl(&c_kicode);
355 	ResetCntrl(&c_kocode);
356 	ResetCntrl(&c_hicode);
357 	ResetCntrl(&c_hocode);
358 	ResetCntrl(&c_attr);
359 	ResetCntrl(&c_wide);
360 	ResetCntrl(&c_vexpand);
361 	ResetCntrl(&c_qexpand);
362 	ResetCntrl(&c_half);
363 	ResetCntrl(&c_font);
364 	ResetCntrl(&c_pagefont);
365 	ResetCntrl(&c_pagekicode);
366 	ResetCntrl(&c_pagekocode);
367 
368 	InitCntrlPosVects();
369 }
370 
371 
372 /**************************************************************************/
373 
374 
375 /* ���楳���������߰��ֵ����٥��������� */
376 typedef struct cpos {
377 	ushort		x;		/* ���楳���������߰��� */
378 	struct def	*cntrl;		/* ���楳���ɥꥹ�� */
379 } cpos_t;
380 
381 /* ���楳���������߰��ֵ����٥��� */
382 static cpos_t cposv_a[CPOSVSIZE];
383 static cpos_t cposv_w[CPOSVSIZE];
384 static cpos_t cposv_v[CPOSVSIZE];
385 static cpos_t cposv_q[CPOSVSIZE];
386 static cpos_t cposv_h[CPOSVSIZE];
387 static cpos_t cposv_f[CPOSVSIZE];
388 static int cposc_a = 0;
389 static int cposc_w = 0;
390 static int cposc_v = 0;
391 static int cposc_q = 0;
392 static int cposc_h = 0;
393 static int cposc_f = 0;
394 
395 static def_t *c_a = NULL;
396 static def_t *c_w = NULL;
397 static def_t *c_v = NULL;
398 static def_t *c_q = NULL;
399 static def_t *c_h = NULL;
400 static def_t *c_f = NULL;
401 
402 static def_t *
CntrlWrapSub(int cposc,cpos_t * cposv)403 CntrlWrapSub(int cposc, cpos_t *cposv)
404 {
405 	while (cposc > 0 && (int)cposv[cposc].x > x)
406 		cposc--;
407 
408 	return cposv[cposc].cntrl;
409 }
410 
411 void
CntrlWrapBefor(void)412 CntrlWrapBefor(void)
413 /* ���������楳���ɤΥ�ɥ�å������� */
414 /* ��ɥ�åפ����������楳���ɤޤǼ��Ԥ������Ƥ�����
415    ʸ�������������֤��Υ����ɤ����ξ��֤��᤹ */
416 {
417 	c_a = c_attr;
418 	c_w = c_wide;
419 	c_v = c_vexpand;
420 	c_q = c_qexpand;
421 	c_h = c_half;
422 	c_f = c_font;
423 	c_attr = CntrlWrapSub(cposc_a, cposv_a);
424 	c_wide = CntrlWrapSub(cposc_w, cposv_w);
425 	c_vexpand = CntrlWrapSub(cposc_v, cposv_v);
426 	c_qexpand = CntrlWrapSub(cposc_q, cposv_q);
427 	c_half = CntrlWrapSub(cposc_h, cposv_h);
428 	c_font = CntrlWrapSub(cposc_f, cposv_f);
429 }
430 
431 void
CntrlWrapAfter(void)432 CntrlWrapAfter(void)
433 /* ���������楳���ɤΥ�ɥ�å׸���� */
434 {
435 	c_attr 	= c_a;
436 	c_wide 	= c_w;
437 	c_vexpand = c_v;
438 	c_qexpand = c_q;
439 	c_half 	= c_h;
440 	c_font 	= c_f;
441 	c_a = NULL;
442 	c_w = NULL;
443 	c_v = NULL;
444 	c_q = NULL;
445 	c_h = NULL;
446 	c_f = NULL;
447 	SetCntrlPosVects();
448 }
449 
450 
451 
452 static void
FreeCntrlPosv(int cposc,cpos_t * cposv,def_t * c1,def_t * c2)453 FreeCntrlPosv(int cposc, cpos_t *cposv, def_t *c1, def_t *c2)
454 {
455 	def_t *p;
456 	def_t *pprev;
457 	int i, j;
458 
459 	for (i = cposc; i >= 0; i--) {
460 		p = cposv[i].cntrl;
461 		cposv[i].x = 0;
462 		cposv[i].cntrl = NULL;
463 
464 		while (p) {
465 			if (MemberCntrl(p, c2) || (c1 != c2 && MemberCntrl(p, c1)))
466 				goto next;
467 
468 			for (j = i - 1; j >= 0; j--) {
469 				if (MemberCntrl(p, cposv[j].cntrl))
470 					goto next;
471 			}
472 			pprev = p->prev;
473 			FreeCntrl1(p);
474 			p = pprev;
475 		}
476 	next:;
477 	}
478 }
479 
480 
481 static void
InitCntrlPosVects(void)482 InitCntrlPosVects(void)
483 {
484 	cposc_a = cposc_w = cposc_v = cposc_q = cposc_h = cposc_f = 0;
485 	cposv_a[0].x = 0;
486 	cposv_a[0].cntrl = c_attr;
487 	cposv_w[0].x = 0;
488 	cposv_w[0].cntrl = c_wide;
489 	cposv_v[0].x = 0;
490 	cposv_v[0].cntrl = c_vexpand;
491 	cposv_q[0].x = 0;
492 	cposv_q[0].cntrl = c_qexpand;
493 	cposv_h[0].x = 0;
494 	cposv_h[0].cntrl = c_half;
495 	cposv_f[0].x = 0;
496 	cposv_f[0].cntrl = c_font;
497 }
498 
499 
500 void
ResCntrlPosVects(void)501 ResCntrlPosVects(void)
502 {
503 	FreeCntrlPosv(cposc_a, cposv_a, c_attr, c_a);
504 	FreeCntrlPosv(cposc_w, cposv_w, c_wide, c_w);
505 	FreeCntrlPosv(cposc_v, cposv_v, c_vexpand, c_v);
506 	FreeCntrlPosv(cposc_q, cposv_q, c_qexpand, c_q);
507 	FreeCntrlPosv(cposc_h, cposv_h, c_half, c_h);
508 	FreeCntrlPosv(cposc_f, cposv_f, c_font, c_f);
509 
510 	InitCntrlPosVects();
511 }
512 
513 void
SetCntrlPosVects(void)514 SetCntrlPosVects(void)
515 {
516 	if (cposv_a[cposc_a].cntrl != c_attr && ++cposc_a < CPOSVSIZE) {
517 		cposv_a[cposc_a].x = x;
518 		cposv_a[cposc_a].cntrl = c_attr;
519 	}
520 	if (cposv_w[cposc_w].cntrl != c_wide && ++cposc_w < CPOSVSIZE) {
521 		cposv_w[cposc_w].x = x;
522 		cposv_w[cposc_w].cntrl = c_wide;
523 	}
524 	if (cposv_v[cposc_v].cntrl != c_vexpand && ++cposc_v < CPOSVSIZE) {
525 		cposv_v[cposc_v].x = x;
526 		cposv_v[cposc_v].cntrl = c_vexpand;
527 	}
528 	if (cposv_q[cposc_q].cntrl != c_qexpand && ++cposc_q < CPOSVSIZE) {
529 		cposv_q[cposc_q].x = x;
530 		cposv_q[cposc_q].cntrl = c_qexpand;
531 	}
532 	if (cposv_h[cposc_h].cntrl != c_half && ++cposc_h < CPOSVSIZE) {
533 		cposv_h[cposc_h].x = x;
534 		cposv_h[cposc_h].cntrl = c_half;
535 	}
536 	if (cposv_f[cposc_f].cntrl != c_font && ++cposc_f < CPOSVSIZE) {
537 		cposv_f[cposc_f].x = x;
538 		cposv_f[cposc_f].cntrl = c_font;
539 	}
540 }
541 
542 /*
543  * Local variables:
544  * mode: c
545  * c-indent-level: 4
546  * c-continued-statement-offset: 4
547  * c-brace-offset: -4
548  * c-argdecl-indent: 4
549  * c-label-offset: -4
550  * tab-width: 4
551  * tab-stop-list: (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80)
552  * End:
553  */
554