Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "tdef.h"
2
#include "fns.h"
3
#include "ext.h"
4
 
5
#ifdef STRICT
6
	/* not in ANSI or POSIX */
7
#undef  isascii
8
#define	isascii(a) ((a) >= 0 && (a) <= 127)
9
#endif
10
 
11
#define GETCH gettch
12
Tchar	gettch(void);
13
 
14
 
15
/*
16
 * troff7.c
17
 * 
18
 * text
19
 */
20
 
21
int	brflg;
22
 
23
void tbreak(void)
24
{
25
	int pad, k;
26
	Tchar *i, j;
27
	int resol;
28
	int un0 = un;
29
 
30
	trap = 0;
31
	if (nb)
32
		return;
33
	if (dip == d && numtabp[NL].val == -1) {
34
		newline(1);
35
		return;
36
	}
37
	if (!nc) {
38
		setnel();
39
		if (!wch)
40
			return;
41
		if (pendw)
42
			getword(1);
43
		movword();
44
	} else if (pendw && !brflg) {
45
		getword(1);
46
		movword();
47
	}
48
	*linep = dip->nls = 0;
49
	if (NROFF && dip == d)
50
		horiz(po);
51
	if (lnmod)
52
		donum();
53
	lastl = ne;
54
	if (brflg != 1) {
55
		totout = 0;
56
	} else if (ad) {
57
		if ((lastl = ll - un) < ne)
58
			lastl = ne;
59
	}
60
	if (admod && ad && (brflg != 2)) {
61
		lastl = ne;
62
		adsp = adrem = 0;
63
		if (admod == 1)
64
			un +=  quant(nel / 2, HOR);
65
		else if (admod == 2)
66
			un += nel;
67
	}
68
	totout++;
69
	brflg = 0;
70
	if (lastl + un > dip->maxl)
71
		dip->maxl = lastl + un;
72
	horiz(un);
73
	if (NROFF) {
74
		if (adrem % t.Adj)
75
			resol = t.Hor; 
76
		else 
77
			resol = t.Adj;
78
	} else
79
		resol = HOR;
80
 
81
	lastl = ne + (nwd-1) * adsp + adrem;
82
	for (i = line; nc > 0; ) {
83
		if ((cbits(j = *i++)) == ' ') {
84
			pad = 0;
85
			do {
86
				pad += width(j);
87
				nc--;
88
			} while ((cbits(j = *i++)) == ' ');
89
			i--;
90
			pad += adsp;
91
			--nwd;
92
			if (adrem) {
93
				if (adrem < 0) {
94
					pad -= resol;
95
					adrem += resol;
96
				} else if ((totout & 01) || adrem / resol >= nwd) {
97
					pad += resol;
98
					adrem -= resol;
99
				}
100
			}
101
			pchar((Tchar) WORDSP);
102
			horiz(pad);
103
		} else {
104
			pchar(j);
105
			nc--;
106
		}
107
	}
108
	if (ic) {
109
		if ((k = ll - un0 - lastl + ics) > 0)
110
			horiz(k);
111
		pchar(ic);
112
	}
113
	if (icf)
114
		icf++;
115
	else 
116
		ic = 0;
117
	ne = nwd = 0;
118
	un = in;
119
	setnel();
120
	newline(0);
121
	if (dip != d) {
122
		if (dip->dnl > dip->hnl)
123
			dip->hnl = dip->dnl;
124
	} else {
125
		if (numtabp[NL].val > dip->hnl)
126
			dip->hnl = numtabp[NL].val;
127
	}
128
	for (k = ls - 1; k > 0 && !trap; k--)
129
		newline(0);
130
	spread = 0;
131
}
132
 
133
void donum(void)
134
{
135
	int i, nw;
136
	int lnv = numtabp[LN].val;
137
 
138
	nrbits = nmbits;
139
	nw = width('1' | nrbits);
140
	if (nn) {
141
		nn--;
142
		goto d1;
143
	}
144
	if (lnv % ndf) {
145
		numtabp[LN].val++;
146
d1:
147
		un += nw * (nmwid + nms + ni);
148
		return;
149
	}
150
	i = 0;
151
	do {		/* count digits in numtabp[LN].val */
152
		i++;
153
	} while ((lnv /= 10) > 0);
154
	horiz(nw * (ni + max(nmwid-i, 0)));
155
	nform = 0;
156
	fnumb(numtabp[LN].val, pchar);
157
	un += nw * nms;
158
	numtabp[LN].val++;
159
}
160
 
161
 
162
void text(void)
163
{
164
	Tchar i;
165
	static int spcnt;
166
 
167
	nflush++;
168
	numtabp[HP].val = 0;
169
	if ((dip == d) && (numtabp[NL].val == -1)) {
170
		newline(1); 
171
		return;
172
	}
173
	setnel();
174
	if (ce || !fi) {
175
		nofill();
176
		return;
177
	}
178
	if (pendw)
179
		goto t4;
180
	if (pendt)
181
		if (spcnt)
182
			goto t2; 
183
		else 
184
			goto t3;
185
	pendt++;
186
	if (spcnt)
187
		goto t2;
188
	while ((cbits(i = GETCH())) == ' ') {
189
		spcnt++;
190
		numtabp[HP].val += sps;
191
		widthp = sps;
192
	}
193
	if (nlflg) {
194
t1:
195
		nflush = pendt = ch = spcnt = 0;
196
		callsp();
197
		return;
198
	}
199
	ch = i;
200
	if (spcnt) {
201
t2:
202
		tbreak();
203
		if (nc || wch)
204
			goto rtn;
205
		un += spcnt * sps;
206
		spcnt = 0;
207
		setnel();
208
		if (trap)
209
			goto rtn;
210
		if (nlflg)
211
			goto t1;
212
	}
213
t3:
214
	if (spread)
215
		goto t5;
216
	if (pendw || !wch)
217
t4:
218
		if (getword(0))
219
			goto t6;
220
	if (!movword())
221
		goto t3;
222
t5:
223
	if (nlflg)
224
		pendt = 0;
225
	adsp = adrem = 0;
226
	if (ad) {
227
		if (nwd == 1)
228
			adsp = nel; 
229
		else 
230
			adsp = nel / (nwd - 1);
231
		adsp = (adsp / HOR) * HOR;
232
		adrem = nel - adsp*(nwd-1);
233
	}
234
	brflg = 1;
235
	tbreak();
236
	spread = 0;
237
	if (!trap)
238
		goto t3;
239
	if (!nlflg)
240
		goto rtn;
241
t6:
242
	pendt = 0;
243
	ckul();
244
rtn:
245
	nflush = 0;
246
}
247
 
248
 
249
void nofill(void)
250
{
251
	int j;
252
	Tchar i;
253
 
254
	if (!pendnf) {
255
		over = 0;
256
		tbreak();
257
		if (trap)
258
			goto rtn;
259
		if (nlflg) {
260
			ch = nflush = 0;
261
			callsp();
262
			return;
263
		}
264
		adsp = adrem = 0;
265
		nwd = 10000;
266
	}
267
	while ((j = (cbits(i = GETCH()))) != '\n') {
268
		if (j == ohc)
269
			continue;
270
		if (j == CONT) {
271
			pendnf++;
272
			nflush = 0;
273
			flushi();
274
			ckul();
275
			return;
276
		}
277
		j = width(i);
278
		widthp = j;
279
		numtabp[HP].val += j;
280
		storeline(i, j);
281
	}
282
	if (ce) {
283
		ce--;
284
		if ((i = quant(nel / 2, HOR)) > 0)
285
			un += i;
286
	}
287
	if (!nc)
288
		storeline((Tchar)FILLER, 0);
289
	brflg = 2;
290
	tbreak();
291
	ckul();
292
rtn:
293
	pendnf = nflush = 0;
294
}
295
 
296
 
297
void callsp(void)
298
{
299
	int i;
300
 
301
	if (flss)
302
		i = flss; 
303
	else 
304
		i = lss;
305
	flss = 0;
306
	casesp1(i);
307
}
308
 
309
 
310
void ckul(void)
311
{
312
	if (ul && (--ul == 0)) {
313
		cu = 0;
314
		font = sfont;
315
		mchbits();
316
	}
317
	if (it && --it == 0 && itmac)
318
		control(itmac, 0);
319
}
320
 
321
 
322
void storeline(Tchar c, int w)
323
{
324
	int diff;
325
 
326
	if (linep >= line + lnsize - 2) {
327
		lnsize += LNSIZE;
328
		diff = linep - line;
329
		if (( line = (Tchar *)realloc((char *)line, lnsize * sizeof(Tchar))) != NULL) {
330
			if (linep && diff)
331
				linep = line + diff;
332
		} else {
333
			if (over) {
334
				return;
335
			} else {
336
				flusho();
337
				ERROR "Line overflow." WARN;
338
				over++;
339
				*linep++ = LEFTHAND;
340
				w = width(LEFTHAND);
341
				nc++;
342
				c = '\n';
343
			}
344
		}
345
	}
346
	*linep++ = c;
347
	ne += w;
348
	nel -= w;
349
	nc++;
350
}
351
 
352
 
353
void newline(int a)
354
{
355
	int i, j, nlss;
356
	int opn;
357
 
358
	nlss = 0;
359
	if (a)
360
		goto nl1;
361
	if (dip != d) {
362
		j = lss;
363
		pchar1((Tchar)FLSS);
364
		if (flss)
365
			lss = flss;
366
		i = lss + dip->blss;
367
		dip->dnl += i;
368
		pchar1((Tchar)i);
369
		pchar1((Tchar)'\n');
370
		lss = j;
371
		dip->blss = flss = 0;
372
		if (dip->alss) {
373
			pchar1((Tchar)FLSS);
374
			pchar1((Tchar)dip->alss);
375
			pchar1((Tchar)'\n');
376
			dip->dnl += dip->alss;
377
			dip->alss = 0;
378
		}
379
		if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap && dip->dimac)
380
			if (control(dip->dimac, 0)) {
381
				trap++; 
382
				dip->ditf++;
383
			}
384
		return;
385
	}
386
	j = lss;
387
	if (flss)
388
		lss = flss;
389
	nlss = dip->alss + dip->blss + lss;
390
	numtabp[NL].val += nlss;
391
	if (TROFF && ascii) {
392
		dip->alss = dip->blss = 0;
393
	}
394
	pchar1((Tchar)'\n');
395
	flss = 0;
396
	lss = j;
397
	if (numtabp[NL].val < pl)
398
		goto nl2;
399
nl1:
400
	ejf = dip->hnl = numtabp[NL].val = 0;
401
	ejl = frame;
402
	if (donef) {
403
		if ((!nc && !wch) || ndone)
404
			done1(0);
405
		ndone++;
406
		donef = 0;
407
		if (frame == stk)
408
			nflush++;
409
	}
410
	opn = numtabp[PN].val;
411
	numtabp[PN].val++;
412
	if (npnflg) {
413
		numtabp[PN].val = npn;
414
		npn = npnflg = 0;
415
	}
416
nlpn:
417
	if (numtabp[PN].val == pfrom) {
418
		print++;
419
		pfrom = -1;
420
	} else if (opn == pto) {
421
		print = 0;
422
		opn = -1;
423
		chkpn();
424
		goto nlpn;
425
	}
426
	if (print)
427
		ptpage(numtabp[PN].val);	/* supposedly in a clean state so can pause */
428
	if (stop && print) {
429
		dpn++;
430
		if (dpn >= stop) {
431
			dpn = 0;
432
			ptpause();
433
		}
434
	}
435
nl2:
436
	trap = 0;
437
	if (numtabp[NL].val == 0) {
438
		if ((j = findn(0)) != NTRAP)
439
			trap = control(mlist[j], 0);
440
	} else if ((i = findt(numtabp[NL].val - nlss)) <= nlss) {
441
		if ((j = findn1(numtabp[NL].val - nlss + i)) == NTRAP) {
442
			flusho();
443
			ERROR "Trap botch." WARN;
444
			done2(-5);
445
		}
446
		trap = control(mlist[j], 0);
447
	}
448
}
449
 
450
 
451
findn1(int a)
452
{
453
	int i, j;
454
 
455
	for (i = 0; i < NTRAP; i++) {
456
		if (mlist[i]) {
457
			if ((j = nlist[i]) < 0)
458
				j += pl;
459
			if (j == a)
460
				break;
461
		}
462
	}
463
	return(i);
464
}
465
 
466
 
467
void chkpn(void)
468
{
469
	pto = *(pnp++);
470
	pfrom = pto>=0 ? pto : -pto;
471
	if (pto == -INT_MAX) {
472
		flusho();
473
		done1(0);
474
	}
475
	if (pto < 0) {
476
		pto = -pto;
477
		print++;
478
		pfrom = 0;
479
	}
480
}
481
 
482
 
483
findt(int a)
484
{
485
	int i, j, k;
486
 
487
	k = INT_MAX;
488
	if (dip != d) {
489
		if (dip->dimac && (i = dip->ditrap - a) > 0)
490
			k = i;
491
		return(k);
492
	}
493
	for (i = 0; i < NTRAP; i++) {
494
		if (mlist[i]) {
495
			if ((j = nlist[i]) < 0)
496
				j += pl;
497
			if ((j -= a) <= 0)
498
				continue;
499
			if (j < k)
500
				k = j;
501
		}
502
	}
503
	i = pl - a;
504
	if (k > i)
505
		k = i;
506
	return(k);
507
}
508
 
509
 
510
findt1(void)
511
{
512
	int i;
513
 
514
	if (dip != d)
515
		i = dip->dnl;
516
	else 
517
		i = numtabp[NL].val;
518
	return(findt(i));
519
}
520
 
521
 
522
void eject(Stack *a)
523
{
524
	int savlss;
525
 
526
	if (dip != d)
527
		return;
528
	ejf++;
529
	if (a)
530
		ejl = a;
531
	else 
532
		ejl = frame;
533
	if (trap)
534
		return;
535
e1:
536
	savlss = lss;
537
	lss = findt(numtabp[NL].val);
538
	newline(0);
539
	lss = savlss;
540
	if (numtabp[NL].val && !trap)
541
		goto e1;
542
}
543
 
544
 
545
movword(void)
546
{
547
	int w;
548
	Tchar i, *wp;
549
	int savwch, hys;
550
 
551
	over = 0;
552
	wp = wordp;
553
	if (!nwd) {
554
		while (cbits(*wp++) == ' ') {
555
			wch--;
556
			wne -= sps;
557
		}
558
		wp--;
559
	}
560
	if (wne > nel && !hyoff && hyf && (!nwd || nel > 3 * sps) &&
561
	   (!(hyf & 02) || (findt1() > lss)))
562
		hyphen(wp);
563
	savwch = wch;
564
	hyp = hyptr;
565
	nhyp = 0;
566
	while (*hyp && *hyp <= wp)
567
		hyp++;
568
	while (wch) {
569
		if (hyoff != 1 && *hyp == wp) {
570
			hyp++;
571
			if (!wdstart || (wp > wdstart + 1 && wp < wdend &&
572
			   (!(hyf & 04) || wp < wdend - 1) &&		/* 04 => last 2 */
573
			   (!(hyf & 010) || wp > wdstart + 2))) {	/* 010 => 1st 2 */
574
				nhyp++;
575
				storeline((Tchar)IMP, 0);
576
			}
577
		}
578
		i = *wp++;
579
		w = width(i);
580
		wne -= w;
581
		wch--;
582
		storeline(i, w);
583
	}
584
	if (nel >= 0) {
585
		nwd++;
586
		return(0);	/* line didn't fill up */
587
	}
588
	if (TROFF)
589
		xbits((Tchar)HYPHEN, 1);
590
	hys = width((Tchar)HYPHEN);
591
m1:
592
	if (!nhyp) {
593
		if (!nwd)
594
			goto m3;
595
		if (wch == savwch)
596
			goto m4;
597
	}
598
	if (*--linep != IMP)
599
		goto m5;
600
	if (!(--nhyp))
601
		if (!nwd)
602
			goto m2;
603
	if (nel < hys) {
604
		nc--;
605
		goto m1;
606
	}
607
m2:
608
	if ((i = cbits(*(linep - 1))) != '-' && i != EMDASH) {
609
		*linep = (*(linep - 1) & SFMASK) | HYPHEN;
610
		w = width(*linep);
611
		nel -= w;
612
		ne += w;
613
		linep++;
614
	}
615
m3:
616
	nwd++;
617
m4:
618
	wordp = wp;
619
	return(1);	/* line filled up */
620
m5:
621
	nc--;
622
	w = width(*linep);
623
	ne -= w;
624
	nel += w;
625
	wne += w;
626
	wch++;
627
	wp--;
628
	goto m1;
629
}
630
 
631
 
632
void horiz(int i)
633
{
634
	vflag = 0;
635
	if (i)
636
		pchar(makem(i));
637
}
638
 
639
 
640
void setnel(void)
641
{
642
	if (!nc) {
643
		linep = line;
644
		if (un1 >= 0) {
645
			un = un1;
646
			un1 = -1;
647
		}
648
		nel = ll - un;
649
		ne = adsp = adrem = 0;
650
	}
651
}
652
 
653
 
654
getword(int x)
655
{
656
	int j, k;
657
	Tchar i, *wp;
658
	int noword;
659
	int obits;
660
 
661
	j = noword = 0;
662
	if (x)
663
		if (pendw) {
664
			*pendw = 0;
665
			goto rtn;
666
		}
667
	if (wordp = pendw)
668
		goto g1;
669
	hyp = hyptr;
670
	wordp = word;
671
	over = wne = wch = 0;
672
	hyoff = 0;
673
	obits = chbits;
674
	while (1) {	/* picks up 1st char of word */
675
		j = cbits(i = GETCH());
676
		if (j == '\n') {
677
			wne = wch = 0;
678
			noword = 1;
679
			goto rtn;
680
		}
681
		if (j == ohc) {
682
			hyoff = 1;	/* 1 => don't hyphenate */
683
			continue;
684
		}
685
		if (j == ' ') {
686
			numtabp[HP].val += sps;
687
			widthp = sps;
688
			storeword(i, sps);
689
			continue;
690
		}
691
		break;
692
	}
693
	storeword(' ' | obits, sps);
694
	if (spflg) {
695
		storeword(' ' | obits, sps);
696
		spflg = 0;
697
	}
698
g0:
699
	if (j == CONT) {
700
		pendw = wordp;
701
		nflush = 0;
702
		flushi();
703
		return(1);
704
	}
705
	if (hyoff != 1) {
706
		if (j == ohc) {
707
			hyoff = 2;
708
			*hyp++ = wordp;
709
			if (hyp > hyptr + NHYP - 1)
710
				hyp = hyptr + NHYP - 1;
711
			goto g1;
712
		}
713
		if (((j == '-' || j == EMDASH)) && !(i & ZBIT))	/* zbit avoids \X */
714
			if (wordp > word + 1) {
715
				hyoff = 2;
716
				*hyp++ = wordp + 1;
717
				if (hyp > hyptr + NHYP - 1)
718
					hyp = hyptr + NHYP - 1;
719
			}
720
	}
721
	j = width(i);
722
	numtabp[HP].val += j;
723
	storeword(i, j);
724
g1:
725
	j = cbits(i = GETCH());
726
	if (j != ' ') {
727
		static char *sentchar = ".?!";	/* sentence terminators */
728
		if (j != '\n')
729
			goto g0;
730
		wp = wordp-1;	/* handle extra space at end of sentence */
731
		while (wp >= word) {
732
			j = cbits(*wp--);
733
			if (j=='"' || j=='\'' || j==')' || j==']' || j=='*' || j==DAGGER)
734
				continue;
735
			for (k = 0; sentchar[k]; k++)
736
				if (j == sentchar[k]) {
737
					spflg++;
738
					break;
739
				}
740
			break;
741
		}
742
	}
743
	*wordp = 0;
744
	numtabp[HP].val += sps;
745
rtn:
746
	for (wp = word; *wp; wp++) {
747
		if (ismot(j))
748
			break;	/* drechsler */
749
		j = cbits(*wp);
750
		if (j == ' ')
751
			continue;
752
		if (!(isascii(j) && isdigit(j)) && j != '-')
753
			break;
754
	}
755
	if (*wp == 0)	/* all numbers, so don't hyphenate */
756
		hyoff = 1;
757
	wdstart = 0;
758
	wordp = word;
759
	pendw = 0;
760
	*hyp++ = 0;
761
	setnel();
762
	return(noword);
763
}
764
 
765
 
766
void storeword(Tchar c, int w)
767
{
768
	Tchar *savp;
769
	int i;
770
 
771
	if (wordp >= word + wdsize - 2) {
772
		wdsize += WDSIZE;
773
		savp = word;
774
		if (( word = (Tchar *)realloc((char *)word, wdsize * sizeof(Tchar))) != NULL) {
775
			if (wordp)
776
				wordp = word + (wordp - savp);
777
			if (pendw)
778
				pendw = word + (pendw - savp);
779
			if (wdstart)
780
				wdstart = word + (wdstart - savp);
781
			if (wdend)
782
				wdend = word + (wdend - savp);
783
			for (i = 0; i < NHYP; i++)
784
				if (hyptr[i])
785
					hyptr[i] = word + (hyptr[i] - savp);
786
		} else {
787
			if (over) {
788
				return;
789
			} else {
790
				flusho();
791
				ERROR "Word overflow." WARN;
792
				over++;
793
				c = LEFTHAND;
794
				w = width(LEFTHAND);
795
			}
796
		}
797
	}
798
	widthp = w;
799
	wne += w;
800
	*wordp++ = c;
801
	wch++;
802
}
803
 
804
 
805
Tchar gettch(void)
806
{
807
	extern int c_isalnum;
808
	Tchar i;
809
	int j;
810
 
811
	if (TROFF)
812
		return getch();
813
 
814
	i = getch();
815
	j = cbits(i);
816
	if (ismot(i) || fbits(i) != ulfont)
817
		return(i);
818
	if (cu) {
819
		if (trtab[j] == ' ') {
820
			setcbits(i, '_');
821
			setfbits(i, FT);	/* default */
822
		}
823
		return(i);
824
	}
825
	/* should test here for characters that ought to be underlined */
826
	/* in the old nroff, that was the 200 bit on the width! */
827
	/* for now, just do letters, digits and certain special chars */
828
	if (j <= 127) {
829
		if (!isalnum(j))
830
			setfbits(i, FT);
831
	} else {
832
		if (j < c_isalnum)
833
			setfbits(i, FT);
834
	}
835
	return(i);
836
}