1 #ifndef lint
2 /*
3 static char sccsid[]="@(#)n10.c 1.2 (CWI) 86/08/15";
4 */
5 static char sccsid[] = "@(#)n10.c 1.3 (Berkeley) 07/27/93";
6 #endif
7
8 /*
9 n10.c
10
11 Device interfaces
12 */
13
14 #include "tdef.h"
15 #include "ext.h"
16 #include "tw.h"
17 #include <sgtty.h>
18 #include <ctype.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21
22 struct t t; /* terminal characteristics */
23
24 int dtab;
25 int plotmode;
26 int esct;
27
28 char xchname[4 * (NROFFCHARS-128)]; /* hy, em, etc. */
29 short xchtab[NROFFCHARS-128]; /* indexes into chname[] */
30 char *codestr;
31 char *chname = xchname;
32 short *chtab = xchtab;
33
34
35 int Inch;
36 int Hor;
37 int Vert;
38 int nfonts = 4; /* R, I, B, S */
39
40 /* these characters are used as various signals or values
41 /* in miscellaneous places.
42 /* values are set in specnames in t10.c
43 */
44
45 int c_hyphen;
46 int c_emdash;
47 int c_rule;
48 int c_minus;
49 int c_fi;
50 int c_fl;
51 int c_ff;
52 int c_ffi;
53 int c_ffl;
54 int c_acute;
55 int c_grave;
56 int c_under;
57 int c_rooten;
58 int c_boxrule;
59 int c_lefthand;
60 int c_dagger;
61 int c_isalnum;
62
ptinit()63 ptinit()
64 {
65 register int i, j;
66 register char *p, *cp, *q;
67 int nread, fd;
68 extern char *skipstr(), *getstr(), *getint();
69 struct stat stbuf;
70 char check[50];
71
72 strcat(termtab, devname);
73 if ((fd = open(termtab, 0)) < 0) {
74 errprint("cannot open %s", termtab);
75 exit(-1);
76 }
77
78 fstat(fd, &stbuf);
79 codestr = malloc((int) stbuf.st_size);
80
81 nread = read(fd, codestr, (int) stbuf.st_size);
82 close(fd);
83
84 p = codestr;
85 p = skipstr(p); /* skip over type, could check */
86 p = skipstr(p); p = getint(p, &t.bset);
87 p = skipstr(p); p = getint(p, &t.breset);
88 p = skipstr(p); p = getint(p, &t.Hor);
89 p = skipstr(p); p = getint(p, &t.Vert);
90 p = skipstr(p); p = getint(p, &t.Newline);
91 p = skipstr(p); p = getint(p, &t.Char);
92 p = skipstr(p); p = getint(p, &t.Em);
93 p = skipstr(p); p = getint(p, &t.Halfline);
94 p = skipstr(p); p = getint(p, &t.Adj);
95 p = skipstr(p); p = getstr(p, t.twinit = p);
96 p = skipstr(p); p = getstr(p, t.twrest = p);
97 p = skipstr(p); p = getstr(p, t.twnl = p);
98 p = skipstr(p); p = getstr(p, t.hlr = p);
99 p = skipstr(p); p = getstr(p, t.hlf = p);
100 p = skipstr(p); p = getstr(p, t.flr = p);
101 p = skipstr(p); p = getstr(p, t.bdon = p);
102 p = skipstr(p); p = getstr(p, t.bdoff = p);
103 p = skipstr(p); p = getstr(p, t.iton = p);
104 p = skipstr(p); p = getstr(p, t.itoff = p);
105 p = skipstr(p); p = getstr(p, t.ploton = p);
106 p = skipstr(p); p = getstr(p, t.plotoff = p);
107 p = skipstr(p); p = getstr(p, t.up = p);
108 p = skipstr(p); p = getstr(p, t.down = p);
109 p = skipstr(p); p = getstr(p, t.right = p);
110 p = skipstr(p); p = getstr(p, t.left = p);
111 p = skipstr(p); p = getstr(p, t.eject = p);
112
113 getstr(p, check);
114 if (strcmp(check, "charset") != 0) {
115 errprint("device table apparently curdled");
116 exit(1);
117 }
118
119 for (i = 0; i < 128; i++)
120 t.width[i] = 1; /* default ascii widths */
121
122 i = 0;
123 /* this ought to be a pointer array and in place in codestr */
124 cp = chname + 1; /* bug if starts at 0, in setch */
125 while (p < codestr + nread) {
126 while (*p == ' ' || *p == '\t' || *p == '\n')
127 p++;
128 chtab[i] = cp - chname; /* index, not pointer */
129 *cp++ = *p++; /* 2-char names */
130 *cp++ = *p++;
131 *cp++ = '\0';
132 while (*p == ' ' || *p == '\t')
133 p++;
134 t.width[i+128] = *p++ - '0';
135 while (*p == ' ' || *p == '\t')
136 p++;
137 t.codetab[i] = p;
138 p = getstr(p, p); /* compress string */
139 p++;
140 i++;
141 }
142
143 sps = EM;
144 ics = EM * 2;
145 dtab = 8 * t.Em;
146 for (i = 0; i < 16; i++)
147 tabtab[i] = dtab * (i + 1);
148 pl = 11 * INCH;
149 po = PO;
150 spacesz = SS;
151 lss = lss1 = VS;
152 ll = ll1 = lt = lt1 = LL;
153 smnt = nfonts = 5; /* R I B BI S */
154 specnames(); /* install names like "hyphen", etc. */
155 if (eqflg)
156 t.Adj = t.Hor;
157 }
158
skipstr(s)159 char *skipstr(s) /* skip over leading space plus string */
160 char *s;
161 {
162 while (*s == ' ' || *s == '\t' || *s == '\n')
163 s++;
164 while (*s != ' ' && *s != '\t' && *s != '\n')
165 if (*s++ == '\\')
166 s++;
167 return s;
168 }
169
getstr(s,t)170 char *getstr(s, t) /* find next string in s, copy to t */
171 char *s, *t;
172 {
173 int quote = 0;
174
175 while (*s == ' ' || *s == '\t' || *s == '\n')
176 s++;
177 if (*s == '"') {
178 s++;
179 quote = 1;
180 }
181 for (;;) {
182 if (quote && *s == '"') {
183 s++;
184 break;
185 }
186 if (!quote && (*s == ' ' || *s == '\t' || *s == '\n'))
187 break;
188 if (*s != '\\')
189 *t++ = *s++;
190 else {
191 s++; /* skip \\ */
192 if (isdigit(s[0]) && isdigit(s[1]) && isdigit(s[2])) {
193 *t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s[2]-'0';
194 s += 2;
195 } else if (isdigit(s[0])) {
196 *t++ = *s - '0';
197 } else if (*s == 'b') {
198 *t++ = '\b';
199 } else if (*s == 'n') {
200 *t++ = '\n';
201 } else if (*s == 'r') {
202 *t++ = '\r';
203 } else if (*s == 't') {
204 *t++ = '\t';
205 } else {
206 *t++ = *s;
207 }
208 s++;
209 }
210 }
211 *t = '\0';
212 return s;
213 }
214
getint(s,pn)215 char *getint(s, pn) /* find integer at s */
216 char *s;
217 int *pn;
218 {
219 while (*s == ' ' || *s == '\t' || *s == '\n')
220 s++;
221 *pn = 0;
222 while (isdigit(*s))
223 *pn = 10 * *pn + *s++ - '0';
224 return s;
225 }
226
specnames()227 specnames()
228 {
229 static struct {
230 int *n;
231 char *v;
232 } spnames[] = {
233 &c_hyphen, "hy",
234 &c_emdash, "em",
235 &c_rule, "ru",
236 &c_minus, "\\-",
237 &c_fi, "fi",
238 &c_fl, "fl",
239 &c_ff, "ff",
240 &c_ffi, "Fi",
241 &c_ffl, "Fl",
242 &c_acute, "aa",
243 &c_grave, "ga",
244 &c_under, "ul",
245 &c_rooten, "rn",
246 &c_boxrule, "br",
247 &c_lefthand, "lh",
248 &c_isalnum, "__",
249 0, 0
250 };
251 int i;
252
253 for (i = 0; spnames[i].n; i++)
254 *spnames[i].n = findch(spnames[i].v);
255 if (c_isalnum == 0)
256 c_isalnum = NROFFCHARS;
257 }
258
259
findch(s)260 findch(s) /* find char s in chname */
261 register char *s;
262 {
263 register int i;
264
265 for (i = 0; chtab[i] != 0; i++)
266 if (strcmp(s, &chname[chtab[i]]) == 0)
267 return(i + 128);
268 return(0);
269 }
270
twdone()271 twdone()
272 {
273 int waitf;
274
275 oputs(t.twrest);
276 flusho();
277 if (pipeflg) {
278 close(fileno(ptid));
279 wait(&waitf);
280 }
281 if (ttysave != -1) {
282 ttys.sg_flags = ttysave;
283 stty(1, &ttys);
284 }
285 }
286
287
ptout(i)288 ptout(i)
289 tchar i;
290 {
291 *olinep++ = i;
292 if (olinep >= &oline[LNSIZE])
293 olinep--;
294 if (cbits(i) != '\n')
295 return;
296 olinep--;
297 lead += dip->blss + lss - t.Newline;
298 dip->blss = 0;
299 esct = esc = 0;
300 if (olinep > oline) {
301 move();
302 ptout1();
303 oputs(t.twnl);
304 } else {
305 lead += t.Newline;
306 move();
307 }
308 lead += dip->alss;
309 dip->alss = 0;
310 olinep = oline;
311 }
312
313
ptout1()314 ptout1()
315 {
316 register k;
317 register char *codep;
318 extern char *plot();
319 int w, j, phyw;
320 tchar * q, i;
321 static int oxfont = FT; /* start off in roman */
322
323 for (q = oline; q < olinep; q++) {
324 i = *q;
325 if (ismot(i)) {
326 j = absmot(i);
327 if (isnmot(i))
328 j = -j;
329 if (isvmot(i))
330 lead += j;
331 else
332 esc += j;
333 continue;
334 }
335 if ((k = cbits(i)) <= 040) {
336 switch (k) {
337 case ' ': /*space*/
338 esc += t.Char;
339 break;
340 case '\033':
341 case '\007':
342 case '\016':
343 case '\017':
344 oput(k);
345 break;
346 }
347 continue;
348 }
349 phyw = w = t.Char * t.width[k];
350 if (iszbit(i))
351 w = 0;
352 if (esc || lead)
353 move();
354 esct += w;
355 xfont = fbits(i);
356 if (xfont != oxfont) {
357 switch (oxfont) {
358 case ULFONT: oputs(t.itoff); break;
359 case BDFONT: oputs(t.bdoff); break;
360 case BIFONT: oputs(t.itoff); oputs(t.bdoff); break;
361 }
362 switch (xfont) {
363 case ULFONT:
364 if (*t.iton & 0377) oputs(t.iton); break;
365 case BDFONT:
366 if (*t.bdon & 0377) oputs(t.bdon); break;
367 case BIFONT:
368 if (*t.bdon & 0377) oputs(t.bdon);
369 if (*t.iton & 0377) oputs(t.iton);
370 break;
371 }
372 oxfont = xfont;
373 }
374 if ((xfont == ULFONT || xfont == BIFONT) && !(*t.iton & 0377)) {
375 for (j = w / t.Char; j > 0; j--)
376 oput('_');
377 for (j = w / t.Char; j > 0; j--)
378 oput('\b');
379 }
380 if (!(*t.bdon & 0377) && ((j = bdtab[xfont]) || xfont == BDFONT || xfont == BIFONT))
381 j++;
382 else
383 j = 1; /* number of overstrikes for bold */
384 if (k < 128) { /* ordinary ascii */
385 oput(k);
386 while (--j > 0) {
387 oput('\b');
388 oput(k);
389 }
390 } else {
391 int oj = j;
392 codep = t.codetab[k-128];
393 while (*codep != 0) {
394 if (*codep & 0200) {
395 codep = plot(codep);
396 oput(' ');
397 } else {
398 if (*codep == '%') /* escape */
399 codep++;
400 oput(*codep);
401 if (*codep != '\b')
402 for (j = oj; --j > 0; ) {
403 oput('\b');
404 oput(*codep);
405 }
406 codep++;
407 }
408 }
409 }
410 if (!w)
411 for (j = phyw / t.Char; j > 0; j--)
412 oput('\b');
413 }
414 }
415
416
plot(x)417 char *plot(x)
418 char *x;
419 {
420 register int i;
421 register char *j, *k;
422
423 oputs(t.ploton);
424 k = x;
425 if ((*k & 0377) == 0200)
426 k++;
427 for (; *k; k++) {
428 if (*k == '%') { /* quote char within plot mode */
429 oput(*++k);
430 } else if (*k & 0200) {
431 if (*k & 0100) {
432 if (*k & 040)
433 j = t.up;
434 else
435 j = t.down;
436 } else {
437 if (*k & 040)
438 j = t.left;
439 else
440 j = t.right;
441 }
442 if ((i = *k & 037) == 0) { /* 2nd 0200 turns it off */
443 ++k;
444 break;
445 }
446 while (i--)
447 oputs(j);
448 } else
449 oput(*k);
450 }
451 oputs(t.plotoff);
452 return(k);
453 }
454
455
move()456 move()
457 {
458 register k;
459 register char *i, *j;
460 char *p, *q;
461 int iesct, dt;
462
463 iesct = esct;
464 if (esct += esc)
465 i = "\0";
466 else
467 i = "\n\0";
468 j = t.hlf;
469 p = t.right;
470 q = t.down;
471 if (lead) {
472 if (lead < 0) {
473 lead = -lead;
474 i = t.flr;
475 /* if(!esct)i = t.flr; else i = "\0";*/
476 j = t.hlr;
477 q = t.up;
478 }
479 if (*i & 0377) {
480 k = lead / t.Newline;
481 lead = lead % t.Newline;
482 while (k--)
483 oputs(i);
484 }
485 if (*j & 0377) {
486 k = lead / t.Halfline;
487 lead = lead % t.Halfline;
488 while (k--)
489 oputs(j);
490 } else { /* no half-line forward, not at line begining */
491 k = lead / t.Newline;
492 lead = lead % t.Newline;
493 if (k > 0)
494 esc = esct;
495 i = "\n";
496 while (k--)
497 oputs(i);
498 }
499 }
500 if (esc) {
501 if (esc < 0) {
502 esc = -esc;
503 j = "\b";
504 p = t.left;
505 } else {
506 j = " ";
507 if (hflg)
508 while ((dt = dtab - (iesct % dtab)) <= esc) {
509 if (dt % t.Em)
510 break;
511 oput(TAB);
512 esc -= dt;
513 iesct += dt;
514 }
515 }
516 k = esc / t.Em;
517 esc = esc % t.Em;
518 while (k--)
519 oputs(j);
520 }
521 if ((*t.ploton & 0377) && (esc || lead)) {
522 oputs(t.ploton);
523 esc /= t.Hor;
524 lead /= t.Vert;
525 while (esc--)
526 oputs(p);
527 while (lead--)
528 oputs(q);
529 oputs(t.plotoff);
530 }
531 esc = lead = 0;
532 }
533
534
ptlead()535 ptlead()
536 {
537 move();
538 }
539
540
dostop()541 dostop()
542 {
543 char junk;
544
545 flusho();
546 read(2, &junk, 1);
547 }
548
549
newpage()550 newpage(){;}
pttrailer()551 pttrailer(){;}
552