Introduction
Introduction Statistics Contact Development Disclaimer Help
n1.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
n1.c (20331B)
---
1 /*
2 * n1.c
3 *
4 * consume options, initialization, main loop,
5 * input routines, escape function calling
6 */
7
8 #include <u.h>
9 #include "tdef.h"
10 #include "fns.h"
11 #include "ext.h"
12 #include "dwbinit.h"
13
14 #include <setjmp.h>
15 #include <time.h>
16
17 char *Version = "March 11, 1994";
18
19 #ifndef DWBVERSION
20 #define DWBVERSION "???"
21 #endif
22
23 char *DWBfontdir = FONTDIR;
24 char *DWBntermdir = NTERMDIR;
25 char *DWBalthyphens = ALTHYPHENS;
26 char *DWBhomedir = "";
27
28 dwbinit dwbpaths[] = {
29 &DWBfontdir, NULL, 0,
30 &DWBntermdir, NULL, 0,
31 &DWBalthyphens, NULL, 0,
32 &DWBhomedir, NULL, 0,
33 NULL, nextf, NS,
34 NULL, NULL, 0
35 };
36
37 int TROFF = 1; /* assume we started in troff... */
38
39 jmp_buf sjbuf;
40 Offset ipl[NSO];
41
42 static FILE *ifile;
43 static FILE *ifl[NSO]; /* open input file pointers …
44 char cfname[NSO+1][NS] = { "stdin" }; /* file name stack …
45 int cfline[NSO]; /* input line count stack */
46 char *progname; /* program name (troff or nroff) */
47
48 int trace = 0; /* tracing mode: default off */
49 int trace1 = 0;
50
51 int
52 main(int argc, char *argv[])
53 {
54 char *p;
55 int j;
56 Tchar i;
57 char buf[100];
58
59 ifile = stdin; /* gcc */
60 ptid = stdout;
61
62 buf[0] = '\0'; /* make sure it's empty (silly 3b2…
63 progname = argv[0];
64 if ((p = strrchr(progname, '/')) == NULL)
65 p = progname;
66 else
67 p++;
68 DWBinit(progname, dwbpaths);
69 if (strcmp(p, "nroff") == 0)
70 TROFF = 0;
71 #ifdef UNICODE
72 alphabet = 128; /* unicode for plan 9 */
73 #endif /*UNICODE*/
74 mnspace();
75 nnspace();
76 mrehash();
77 nrehash();
78 numtabp[NL].val = -1;
79
80 while (--argc > 0 && (++argv)[0][0] == '-')
81 switch (argv[0][1]) {
82
83 case 'N': /* ought to be used first... */
84 TROFF = 0;
85 break;
86 case 'd':
87 fprintf(stderr, "troff/nroff version %s\n", Vers…
88 break;
89 case 'F': /* switch font tables from default */
90 if (argv[0][2] != '\0') {
91 strcpy(termtab, &argv[0][2]);
92 strcpy(fontdir, &argv[0][2]);
93 } else {
94 argv++; argc--;
95 strcpy(termtab, argv[0]);
96 strcpy(fontdir, argv[0]);
97 }
98 break;
99 case 0:
100 goto start;
101 case 'i':
102 stdi++;
103 break;
104 case 'n':
105 npn = atoi(&argv[0][2]);
106 break;
107 case 'u': /* set emboldening amount */
108 bdtab[3] = atoi(&argv[0][2]);
109 if (bdtab[3] < 0 || bdtab[3] > 50)
110 bdtab[3] = 0;
111 break;
112 case 's':
113 if (!(stop = atoi(&argv[0][2])))
114 stop++;
115 break;
116 case 'r':
117 sprintf(buf + strlen(buf), ".nr %c %s\n",
118 argv[0][2], &argv[0][3]);
119 /* not yet cpushback(buf);*/
120 /* dotnr(&argv[0][2], &argv[0][3]); */
121 break;
122 case 'm':
123 if (mflg++ >= NMF) {
124 ERROR "Too many macro packages: %s", arg…
125 break;
126 }
127 strcpy(mfiles[nmfi], nextf);
128 strcat(mfiles[nmfi++], &argv[0][2]);
129 break;
130 case 'o':
131 getpn(&argv[0][2]);
132 break;
133 case 'T':
134 strcpy(devname, &argv[0][2]);
135 dotT++;
136 break;
137 case 'a':
138 ascii = 1;
139 break;
140 case 'h':
141 hflg++;
142 break;
143 case 'e':
144 eqflg++;
145 break;
146 case 'q':
147 quiet++;
148 save_tty();
149 break;
150 case 'V':
151 fprintf(stdout, "%croff: DWB %s\n",
152 TROFF ? 't' : 'n', DWBVERSION);
153 exit(0);
154 case 't':
155 if (argv[0][2] != '\0')
156 trace = trace1 = argv[0][2];
157 break; /* for the sake of compati…
158 default:
159 ERROR "unknown option %s", argv[0] WARN;
160 done(02);
161 }
162
163 start:
164 /*
165 * cpushback maintains a LIFO, so push pack the -r arguments
166 * in reverse order to maintain a FIFO in case someone did -rC1 …
167 */
168 if (buf[0]) {
169 char *p = buf;
170 while(*p++)
171 ;
172 while(p > buf) {
173 while(strncmp(p, ".nr", 3) != 0)
174 p--;
175 cpushback(p);
176 *p-- = '\0';
177 }
178 }
179 argp = argv;
180 rargc = argc;
181 nmfi = 0;
182 init2();
183 setjmp(sjbuf);
184 loop:
185 copyf = lgf = nb = nflush = nlflg = 0;
186 if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl && dip ==…
187 nflush++;
188 trap = 0;
189 eject((Stack *)0);
190 goto loop;
191 }
192 i = getch();
193 if (pendt)
194 goto Lt;
195 if ((j = cbits(i)) == XPAR) {
196 copyf++;
197 tflg++;
198 while (cbits(i) != '\n')
199 pchar(i = getch());
200 tflg = 0;
201 copyf--;
202 goto loop;
203 }
204 if (j == cc || j == c2) {
205 if (j == c2)
206 nb++;
207 copyf++;
208 while ((j = cbits(i = getch())) == ' ' || j == '\t')
209 ;
210 ch = i;
211 copyf--;
212 control(getrq(), 1);
213 flushi();
214 goto loop;
215 }
216 Lt:
217 ch = i;
218 text();
219 if (nlflg)
220 numtabp[HP].val = 0;
221 goto loop;
222 }
223
224
225
226 void init2(void)
227 {
228 int i;
229 char buf[100];
230
231 for (i = NTRTAB; --i; )
232 trtab[i] = i;
233 trtab[UNPAD] = ' ';
234 iflg = 0;
235 obufp = obuf;
236 if (TROFF)
237 t_ptinit();
238 else
239 n_ptinit();
240 mchbits();
241 cvtime();
242 numtabp[PID].val = getpid();
243 numtabp[HP].val = init = 0;
244 numtabp[NL].val = -1;
245 nfo = 0;
246 copyf = raw = 0;
247 sprintf(buf, ".ds .T %s\n", devname);
248 cpushback(buf);
249 sprintf(buf, ".ds .P %s\n", DWBhomedir);
250 cpushback(buf);
251 numtabp[CD].val = -1; /* compensation */
252 nx = mflg;
253 frame = stk = (Stack *)setbrk(STACKSIZE);
254 dip = &d[0];
255 nxf = frame + 1;
256 for (i = 1; i < NEV; i++) /* propagate the environment */
257 envcopy(&env[i], &env[0]);
258 for (i = 0; i < NEV; i++) {
259 if ((env[i]._word._bufp = (Tchar *)calloc(WDSIZE, sizeof…
260 ERROR "not enough room for word buffers" WARN;
261 done2(1);
262 }
263 env[i]._word._size = WDSIZE;
264 if ((env[i]._line._bufp = (Tchar *)calloc(LNSIZE, sizeof…
265 ERROR "not enough room for line buffers" WARN;
266 done2(1);
267 }
268 env[i]._line._size = LNSIZE;
269 }
270 if ((oline = (Tchar *)calloc(OLNSIZE, sizeof(Tchar))) == NULL) {
271 ERROR "not enough room for line buffers" WARN;
272 done2(1);
273 }
274 olinep = oline;
275 olnsize = OLNSIZE;
276 blockinit();
277 }
278
279 void cvtime(void)
280 {
281 time_t tt;
282 struct tm *ltime;
283
284 time(&tt);
285 ltime = localtime(&tt);
286 numtabp[YR].val = ltime->tm_year % 100;
287 numtabp[YR].fmt = 2;
288 numtabp[MO].val = ltime->tm_mon + 1; /* troff uses 1..12 …
289 numtabp[DY].val = ltime->tm_mday;
290 numtabp[DW].val = ltime->tm_wday + 1; /* troff uses 1..7 …
291 }
292
293
294
295 char errbuf[200];
296
297 void errprint(void) /* error message printer */
298 {
299 int savecd = numtabp[CD].val;
300
301 if (!nlflg)
302 numtabp[CD].val++;
303
304 fprintf(stderr, "%s: ", progname);
305 fputs(errbuf, stderr);
306 if (cfname[ifi][0])
307 fprintf(stderr, "; %s:%d", cfname[ifi], numtabp[CD].val);
308 fputs("\n", stderr);
309 if (cfname[ifi][0])
310 stackdump();
311 numtabp[CD].val = savecd;
312 }
313
314
315 int control(int a, int b)
316 {
317 int j, k;
318 extern Contab *contabp;
319
320 numerr.type = RQERR;
321 numerr.req = a;
322 if (a == 0 || (j = findmn(a)) == -1)
323 return(0);
324 if (contabp[j].f == 0) {
325 if (trace & TRMAC)
326 fprintf(stderr, "invoke macro %s\n", unpair(a));
327 if (dip != d)
328 for (k = dilev; k; k--)
329 if (d[k].curd == a) {
330 ERROR "diversion %s invokes itse…
331 unpair(a…
332 edone(0100);
333 }
334 nxf->nargs = 0;
335 if (b)
336 collect();
337 flushi();
338 return pushi(contabp[j].mx, a); /* BUG??? all tha…
339 }
340 if (b) {
341 if (trace & TRREQ)
342 fprintf(stderr, "invoke request %s\n", unpair(a)…
343 (*contabp[j].f)();
344 }
345 return(0);
346 }
347
348 void casept(void)
349 {
350 int i;
351
352 noscale++;
353 if (skip())
354 i = trace1;
355 else {
356 i = max(inumb(&trace), 0);
357 if (nonumb)
358 i = trace1;
359 }
360 trace1 = trace;
361 trace = i;
362 noscale = 0;
363 }
364
365
366 int getrq(void)
367 {
368 int i, j;
369
370 if ((i = getach()) == 0 || (j = getach()) == 0)
371 goto rtn;
372 i = PAIR(i, j);
373 rtn:
374 return(i);
375 }
376
377 /*
378 * table encodes some special characters, to speed up tests
379 * in getch, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
380 */
381
382 char gchtab[NCHARS] = {
383 000,004,000,000,010,000,000,000, /* fc, ldr */
384 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
385 000,000,000,000,000,000,000,000,
386 000,001,000,001,000,000,000,000, /* FLSS, ESC */
387 000,000,000,000,000,000,000,000,
388 000,000,000,000,000,000,000,000,
389 000,000,000,000,000,000,000,000,
390 000,000,000,000,000,000,000,000,
391 000,000,000,000,000,000,000,000,
392 000,000,000,000,000,000,000,000,
393 000,000,000,000,000,000,000,000,
394 000,000,000,000,000,000,000,000,
395 000,000,000,000,000,000,001,000, /* f */
396 000,000,000,000,000,000,000,000,
397 000,000,000,000,000,000,000,000,
398 000,000,000,000,000,000,000,000
399 };
400
401 int realcbits(Tchar c) /* return character bits, or MOTCH if moti…
402 {
403 if (ismot(c))
404 return MOTCH;
405 else
406 return c & 0xFFFF;
407 }
408
409 Tchar getch(void)
410 {
411 int k;
412 Tchar i, j;
413
414 g0:
415 if (ch) {
416 i = ch;
417 if (cbits(i) == '\n')
418 nlflg++;
419 ch = 0;
420 return(i);
421 }
422
423 if (nlflg)
424 return('\n');
425 i = getch0();
426 if (ismot(i))
427 return(i);
428 k = cbits(i);
429 if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0) …
430 return(i);
431 if (k != ESC) {
432 if (k == '\n') {
433 nlflg++;
434 if (ip == 0)
435 numtabp[CD].val++; /* line number */
436 return(k);
437 }
438 if (k == FLSS) {
439 copyf++;
440 raw++;
441 i = getch0();
442 if (!fi)
443 flss = i;
444 copyf--;
445 raw--;
446 goto g0;
447 }
448 if (k == RPT) {
449 setrpt();
450 goto g0;
451 }
452 if (!copyf) {
453 if (k == 'f' && lg && !lgf) {
454 i = getlg(i);
455 return(i);
456 }
457 if (k == fc || k == tabch || k == ldrch) {
458 if ((i = setfield(k)) == 0)
459 goto g0;
460 else
461 return(i);
462 }
463 if (k == '\b') {
464 i = makem(-width(' ' | chbits));
465 return(i);
466 }
467 }
468 return(i);
469 }
470
471 k = cbits(j = getch0());
472 if (ismot(j))
473 return(j);
474
475 switch (k) {
476 case 'n': /* number register */
477 setn();
478 goto g0;
479 case '$': /* argument indicator */
480 seta();
481 goto g0;
482 case '*': /* string indicator */
483 setstr();
484 goto g0;
485 case '{': /* LEFT */
486 i = LEFT;
487 goto gx;
488 case '}': /* RIGHT */
489 i = RIGHT;
490 goto gx;
491 case '"': /* comment */
492 while (cbits(i = getch0()) != '\n')
493 ;
494 if (ip == 0)
495 numtabp[CD].val++; /* line number */
496 nlflg++;
497 return(i);
498
499 /* experiment: put it here instead of copy mode */
500 case '(': /* special char name \(xx */
501 case 'C': /* \C'...' */
502 if ((i = setch(k)) == 0)
503 goto g0;
504 goto gx;
505
506 case ESC: /* double backslash */
507 i = eschar;
508 goto gx;
509 case 'e': /* printable version of current eschar */
510 i = PRESC;
511 goto gx;
512 case '\n': /* concealed newline */
513 numtabp[CD].val++;
514 goto g0;
515 case ' ': /* unpaddable space */
516 i = UNPAD;
517 goto gx;
518 case '\'': /* \(aa */
519 i = ACUTE;
520 goto gx;
521 case '`': /* \(ga */
522 i = GRAVE;
523 goto gx;
524 case '_': /* \(ul */
525 i = UNDERLINE;
526 goto gx;
527 case '-': /* current font minus */
528 i = MINUS;
529 goto gx;
530 case '&': /* filler */
531 i = FILLER;
532 goto gx;
533 case 'c': /* to be continued */
534 i = CONT;
535 goto gx;
536 case '!': /* transparent indicator */
537 i = XPAR;
538 goto gx;
539 case 't': /* tab */
540 i = '\t';
541 return(i);
542 case 'a': /* leader (SOH) */
543 /* old: *pbp++ = LEADER; goto g0; */
544 i = LEADER;
545 return i;
546 case '%': /* ohc */
547 i = OHC;
548 return(i);
549 case 'g': /* return format of a number register */
550 setaf(); /* should this really be in copy mode???…
551 goto g0;
552 case '.': /* . */
553 i = '.';
554 gx:
555 setsfbits(i, sfbits(j));
556 return(i);
557 }
558 if (copyf) {
559 *pbp++ = j;
560 return(eschar);
561 }
562 switch (k) {
563
564 case 'f': /* font indicator */
565 setfont(0);
566 goto g0;
567 case 's': /* size indicator */
568 setps();
569 goto g0;
570 case 'v': /* vert mot */
571 numerr.type = numerr.escarg = 0; numerr.esc = k;
572 if (i = vmot()) {
573 return(i);
574 }
575 goto g0;
576 case 'h': /* horiz mot */
577 numerr.type = numerr.escarg = 0; numerr.esc = k;
578 if (i = hmot())
579 return(i);
580 goto g0;
581 case '|': /* narrow space */
582 if (NROFF)
583 goto g0;
584 return(makem((int)(EM)/6));
585 case '^': /* half narrow space */
586 if (NROFF)
587 goto g0;
588 return(makem((int)(EM)/12));
589 case 'w': /* width function */
590 setwd();
591 goto g0;
592 case 'p': /* spread */
593 spread++;
594 goto g0;
595 case 'N': /* absolute character number */
596 numerr.type = numerr.escarg = 0; numerr.esc = k;
597 if ((i = setabs()) == 0)
598 goto g0;
599 return i;
600 case 'H': /* character height */
601 numerr.type = numerr.escarg = 0; numerr.esc = k;
602 return(setht());
603 case 'S': /* slant */
604 numerr.type = numerr.escarg = 0; numerr.esc = k;
605 return(setslant());
606 case 'z': /* zero with char */
607 return(setz());
608 case 'l': /* hor line */
609 numerr.type = numerr.escarg = 0; numerr.esc = k;
610 setline();
611 goto g0;
612 case 'L': /* vert line */
613 numerr.type = numerr.escarg = 0; numerr.esc = k;
614 setvline();
615 goto g0;
616 case 'D': /* drawing function */
617 numerr.type = numerr.escarg = 0; numerr.esc = k;
618 setdraw();
619 goto g0;
620 case 'X': /* \X'...' for copy through */
621 setxon();
622 goto g0;
623 case 'b': /* bracket */
624 setbra();
625 goto g0;
626 case 'o': /* overstrike */
627 setov();
628 goto g0;
629 case 'k': /* mark hor place */
630 if ((k = findr(getsn())) != -1) {
631 numtabp[k].val = numtabp[HP].val;
632 }
633 goto g0;
634 case '0': /* number space */
635 return(makem(width('0' | chbits)));
636 case 'x': /* extra line space */
637 numerr.type = numerr.escarg = 0; numerr.esc = k;
638 if (i = xlss())
639 return(i);
640 goto g0;
641 case 'u': /* half em up */
642 case 'r': /* full em up */
643 case 'd': /* half em down */
644 return(sethl(k));
645 default:
646 return(j);
647 }
648 /* NOTREACHED */
649 }
650
651 void setxon(void) /* \X'...' for copy through */
652 {
653 Tchar xbuf[NC];
654 Tchar *i;
655 Tchar c;
656 int delim, k;
657
658 if (ismot(c = getch()))
659 return;
660 delim = cbits(c);
661 i = xbuf;
662 *i++ = XON | chbits;
663 while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbu…
664 if (k == ' ')
665 setcbits(c, WORDSP);
666 *i++ = c | ZBIT;
667 }
668 *i++ = XOFF | chbits;
669 *i = 0;
670 pushback(xbuf);
671 }
672
673
674 char ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, …
675
676 Tchar getch0(void)
677 {
678 Tchar i;
679
680 again:
681 if (pbp > lastpbp)
682 i = *--pbp;
683 else if (ip) {
684 /* i = rbf(); */
685 i = rbf0(ip);
686 if (i == 0)
687 i = rbf();
688 else {
689 ++ip;
690 if (pastend(ip)) {
691 --ip;
692 rbf();
693 }
694 }
695 } else {
696 if (donef || ndone)
697 done(0);
698 if (nx || 1) { /* BUG: was ibufp >= eibuf, so EOF…
699 if (nfo < 0)
700 ERROR "in getch0, nfo = %d", nfo WARN;
701 if (nfo == 0) {
702 g0:
703 if (nextfile()) {
704 if (ip)
705 goto again;
706 }
707 }
708 nx = 0;
709 #ifdef UNICODE
710 if (MB_CUR_MAX > 1)
711 i = get1ch(ifile);
712 else
713 #endif /*UNICODE*/
714 i = getc(ifile);
715 if (i == EOF)
716 goto g0;
717 if (ip)
718 goto again;
719 }
720 /*g2: */
721 if (i >= 040) /* zapped: && i < 0…
722 goto g4;
723 i = ifilt[i];
724 }
725 if (cbits(i) == IMP && !raw)
726 goto again;
727 if (i == 0 && !init && !raw) { /* zapped: || i =…
728 goto again;
729 }
730 g4:
731 if (ismot(i))
732 return i;
733 if (copyf == 0 && sfbits(i) == 0)
734 i |= chbits;
735 if (cbits(i) == eschar && !raw)
736 setcbits(i, ESC);
737 return(i);
738 }
739
740
741 #ifdef UNICODE
742 Tchar get1ch(FILE *fp) /* get one "character" from input, figure …
743 {
744 wchar_t wc;
745 char buf[100], *p;
746 int i, n, c;
747
748 for (i = 0, p = buf; i < MB_CUR_MAX; i++) {
749 if ((c = getc(fp)) == EOF)
750 return c;
751 *p++ = c;
752 if ((n = mbtowc(&wc, buf, p-buf)) >= 0)
753 break;
754 }
755
756 if (n == 1) /* real ascii, presumably */
757 return wc;
758 if (n == 0)
759 return p[-1]; /* illegal, but what else to do? */
760 if (c == EOF)
761 return EOF;
762 *p = 0;
763 return chadd(buf, MBchar, Install); /* add name even if h…
764 }
765 #endif /*UNICODE*/
766
767 void pushback(Tchar *b)
768 {
769 Tchar *ob = b;
770
771 while (*b++)
772 ;
773 b--;
774 while (b > ob && pbp < &pbbuf[NC-3])
775 *pbp++ = *--b;
776 if (pbp >= &pbbuf[NC-3]) {
777 ERROR "pushback overflow" WARN;
778 done(2);
779 }
780 }
781
782 void cpushback(char *b)
783 {
784 char *ob = b;
785
786 while (*b++)
787 ;
788 b--;
789 while (b > ob && pbp < &pbbuf[NC-3])
790 *pbp++ = *--b;
791 if (pbp >= &pbbuf[NC-3]) {
792 ERROR "cpushback overflow" WARN;
793 done(2);
794 }
795 }
796
797 int nextfile(void)
798 {
799 char *p;
800
801 n0:
802 if (ifile != stdin)
803 fclose(ifile);
804 if (ifi > 0 && !nx) {
805 if (popf())
806 goto n0; /* popf error */
807 return(1); /* popf ok */
808 }
809 if (nx || nmfi < mflg) {
810 p = mfiles[nmfi++];
811 if (*p != 0)
812 goto n1;
813 }
814 if (rargc-- <= 0) {
815 if ((nfo -= mflg) && !stdi) {
816 done(0);
817 }
818 nfo++;
819 numtabp[CD].val = stdi = mflg = 0;
820 ifile = stdin;
821 strcpy(cfname[ifi], "stdin");
822 return(0);
823 }
824 p = (argp++)[0];
825 if (rargc >= 0)
826 cfname[ifi][0] = 0;
827 n1:
828 numtabp[CD].val = 0;
829 if (p[0] == '-' && p[1] == 0) {
830 ifile = stdin;
831 strcpy(cfname[ifi], "stdin");
832 } else if ((ifile = fopen(unsharp(p), "r")) == NULL) {
833 ERROR "cannot open file %s", p WARN;
834 nfo -= mflg;
835 done(02);
836 } else
837 strcpy(cfname[ifi],p);
838 nfo++;
839 return(0);
840 }
841
842 int
843 popf(void)
844 {
845 --ifi;
846 if (ifi < 0) {
847 ERROR "popf went negative" WARN;
848 return 1;
849 }
850 numtabp[CD].val = cfline[ifi]; /* restore line counter */
851 ip = ipl[ifi]; /* input pointer */
852 ifile = ifl[ifi]; /* input FILE * */
853 return(0);
854 }
855
856
857 void flushi(void)
858 {
859 if (nflush)
860 return;
861 ch = 0;
862 copyf++;
863 while (!nlflg) {
864 if (donef && frame == stk)
865 break;
866 getch();
867 }
868 copyf--;
869 }
870
871 /*
872 * return 16-bit, ascii/alphabetic character, ignore chars with more bit…
873 * (internal names), spaces and special cookies (below 040).
874 * Leave STX ETX ENQ ACK and BELL in to maintain compatibility with v7 t…
875 */
876 int
877 getach(void)
878 {
879 Tchar i;
880 int j;
881
882 lgf++;
883 j = cbits(i = getch());
884 if (ismot(i)
885 || j > SHORTMASK
886 || (j <= 040 && j != 002 /*STX*/
887 && j != 003 /*ETX*/
888 && j != 005 /*ENQ*/
889 && j != 006 /*ACK*/
890 && j != 007)) { /*BELL*/
891 ch = i;
892 j = 0;
893 }
894 lgf--;
895 return j;
896 }
897
898
899 void casenx(void)
900 {
901 lgf++;
902 skip();
903 getname();
904 nx++;
905 if (nmfi > 0)
906 nmfi--;
907 strcpy(mfiles[nmfi], nextf);
908 nextfile();
909 nlflg++;
910 ip = 0;
911 pendt = 0;
912 frame = stk;
913 nxf = frame + 1;
914 }
915
916 int
917 getname(void)
918 {
919 int j, k;
920
921 lgf++;
922 for (k = 0; k < NS - 1; k++) {
923 j = getach();
924 if (!j)
925 break;
926 nextf[k] = j;
927 }
928 nextf[k] = 0;
929 lgf--;
930 return(nextf[0]);
931 }
932
933
934 void caseso(void)
935 {
936 FILE *fp = 0;
937
938 lgf++;
939 nextf[0] = 0;
940 if (skip() || !getname() || (fp = fopen(unsharp(nextf), "r")) ==…
941 ERROR "can't open file %s", nextf WARN;
942 done(02);
943 }
944 strcpy(cfname[ifi+1], nextf);
945 cfline[ifi] = numtabp[CD].val; /*hold line counte…
946 numtabp[CD].val = 0;
947 flushi();
948 ifl[ifi] = ifile;
949 ifile = fp;
950 ipl[ifi] = ip;
951 ip = 0;
952 nx++;
953 nflush++;
954 ifi++;
955 }
956
957 void caself(void) /* set line number and file */
958 {
959 int n;
960
961 if (skip())
962 return;
963 n = atoi0();
964 if (!nonumb)
965 cfline[ifi] = numtabp[CD].val = n - 1;
966 if (!skip())
967 if (getname()) { /* eats '\n' ? */
968 strcpy(cfname[ifi], nextf);
969 if (!nonumb)
970 numtabp[CD].val--;
971 }
972 }
973
974 void cpout(FILE *fin, char *token)
975 {
976 int n;
977 char buf[1024];
978
979 if (token) { /* BUG: There should be no NULL bytes in inp…
980 char *newl = buf;
981 while ((fgets(buf, sizeof buf, fin)) != NULL) {
982 if (newl) {
983 numtabp[CD].val++; /* line number */
984 if (strcmp(token, buf) == 0)
985 return;
986 }
987 newl = strchr(buf, '\n');
988 fputs(buf, ptid);
989 }
990 } else {
991 while ((n = fread(buf, sizeof *buf, sizeof buf, fin)) > …
992 fwrite(buf, n, 1, ptid);
993 fclose(fin);
994 }
995 }
996
997 void casecf(void)
998 { /* copy file without change */
999 FILE *fd;
1000 char *eof, *p;
1001 extern int hpos, esc, po;
1002
1003 /* this may not make much sense in nroff... */
1004
1005 lgf++;
1006 nextf[0] = 0;
1007 if (!skip() && getname()) {
1008 if (strncmp("<<", nextf, 2) != 0) {
1009 if ((fd = fopen(unsharp(nextf), "r")) == NULL) {
1010 ERROR "can't open file %s", nextf WARN;
1011 done(02);
1012 }
1013 eof = (char *) NULL;
1014 } else { /* current file */
1015 if (pbp > lastpbp || ip) {
1016 ERROR "casecf: not reading from file" WA…
1017 done(02);
1018 }
1019 eof = &nextf[2];
1020 if (!*eof) {
1021 ERROR "casecf: missing end of input toke…
1022 done(02);
1023 }
1024 p = eof;
1025 while(*++p)
1026 ;
1027 *p++ = '\n';
1028 *p = 0;
1029 fd = ifile;
1030 }
1031 } else {
1032 ERROR "casecf: no argument" WARN;
1033 lgf--;
1034 return;
1035 }
1036 lgf--;
1037
1038 /* make it into a clean state, be sure that everything is out */
1039 tbreak();
1040 hpos = po;
1041 esc = 0;
1042 ptesc(); /* to left margin */
1043 esc = un;
1044 ptesc();
1045 ptlead();
1046 ptps();
1047 ptfont();
1048 flusho();
1049 cpout(fd, eof);
1050 ptps();
1051 ptfont();
1052 }
1053
1054 void getline(char *s, int n) /* get rest of input line into s */
1055 {
1056 int i;
1057
1058 lgf++;
1059 copyf++;
1060 skip();
1061 for (i = 0; i < n-1; i++)
1062 if ((s[i] = cbits(getch())) == '\n' || s[i] == RIGHT)
1063 break;
1064 s[i] = 0;
1065 copyf--;
1066 lgf--;
1067 }
1068
1069 void casesy(void) /* call system */
1070 {
1071 char sybuf[NTM];
1072
1073 getline(sybuf, NTM);
1074 system(sybuf);
1075 }
1076
1077
1078 void getpn(char *a)
1079 {
1080 int n, neg;
1081
1082 if (*a == 0)
1083 return;
1084 neg = 0;
1085 for ( ; *a; a++)
1086 switch (*a) {
1087 case '+':
1088 case ',':
1089 continue;
1090 case '-':
1091 neg = 1;
1092 continue;
1093 default:
1094 n = 0;
1095 if (isdigit((uchar)*a)) {
1096 do
1097 n = 10 * n + *a++ - '0';
1098 while (isdigit((uchar)*a));
1099 a--;
1100 } else
1101 n = 9999;
1102 *pnp++ = neg ? -n : n;
1103 neg = 0;
1104 if (pnp >= &pnlist[NPN-2]) {
1105 ERROR "too many page numbers" WARN;
1106 done3(-3);
1107 }
1108 }
1109 if (neg)
1110 *pnp++ = -9999;
1111 *pnp = -INT_MAX;
1112 print = 0;
1113 pnp = pnlist;
1114 if (*pnp != -INT_MAX)
1115 chkpn();
1116 }
1117
1118
1119 void setrpt(void)
1120 {
1121 Tchar i, j;
1122
1123 copyf++;
1124 raw++;
1125 i = getch0();
1126 copyf--;
1127 raw--;
1128 if ((long) i < 0 || cbits(j = getch0()) == RPT)
1129 return;
1130 while (i > 0 && pbp < &pbbuf[NC-3]) {
1131 i--;
1132 *pbp++ = j;
1133 }
1134 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.