BSD 3 development
[unix-history] / usr / src / cmd / ul.c
CommitLineData
77031d39
MH
1/*
2 *
3 * ul - General underline filter. Converts underlines by
4 * the standard backspacing method to the code used by the
5 * particular terminal to underline.
6 *
7 */
8#include <stdio.h>
9char buf[BUFSIZ];
10char isul[BUFSIZ];
11char termcap[1024];
12char ulbuf[BUFSIZ];
13char *stul, *endul, *chul;
14char *backspace;
15char *termtype;
16int outc();
17char *tgetstr();
18char *getenv();
19
20main(argc,argv) char **argv; {
21 register int i;
22 char *cp;
23 FILE *f;
24
25 /* Figure out kind of terminal and set up special strings. */
26 termtype = getenv("TERM");
27 if (termtype == NULL)
28 termtype = "dumb";
29 while (argc >= 2 && argv[1][0] == '-') {
30 switch(argv[1][1]) {
31 case 't':
32 case 'T': /* for nroff compatibility */
33 if (argv[1][2])
34 termtype = &argv[1][2];
35 else {
36 termtype = argv[2];
37 argc--;
38 argv++;
39 }
40 break;
41 default:
42 printf("Bad switch: %s\n",argv[1]);
43 exit(1);
44 }
45 }
46 switch(tgetent(termcap, termtype)) {
47 case 1: /* All is well */
48 /* Terminals that don't need any help. */
49 if (tgetflag("ul") || tgetflag("os"))
50 execv("/bin/cat",argv);
51 cp = ulbuf;
52 if ((backspace = tgetstr("bc",&cp)) == NULL)
53 backspace = "\b";
54 /*
55 * Handle terminals that have start underline/stop
56 * underline sequences, as well as those with
57 * underline char sequences (we assume the sequence
58 * moves the cursor forward one character).
59 * If we can't find underline sequences, we
60 * settle for standout sequences.
61 */
62 if ( (chul=tgetstr("uc",&cp)) == NULL)
63 chul = "";
64 if ( (stul=tgetstr("us",&cp)) == NULL &&
65 (!*chul) && (stul=tgetstr("so",&cp)) == NULL)
66 stul = "";
67 if ( (endul=tgetstr("ue",&cp)) == NULL &&
68 (!*chul) && (endul=tgetstr("se",&cp)) == NULL)
69 endul = "";
70 break;
71 default:/* error opening/reading termcap */
72 fprintf(stderr,"trouble reading termcap");
73 /* fall through to ... */
74 case 0: /* No such terminal type - assume dumb */
75 stul = endul = chul = "";
76 break;
77 }
78 if (argc < 2) filter(stdin);
79 else for (i=1; i<argc; i++) {
80 f = fopen(argv[i],"r");
81 if (f == NULL) {
82 printf("Can't open %s\n",argv[i]);
83 exit(1);
84 } else filter(f);
85 }
86 exit(0);
87}
88
89filter(f)
90FILE *f;
91{
92 register int p, n;
93 register char c;
94 int state;
95
96 n = 0;
97 for (;;) {
98 p = 0;
99 for (p=0; p<n; p++) {
100 buf[p] = '\0';
101 isul[p] = 0;
102 }
103 p = n = 0;
104
105 for (;;) {
106 c = getc(f);
107 if (c==EOF) break;
108 if (c=='\b') {
109 if (p > 0) {
110 p--;
111 }
112 } else if (c=='_' && isul[p]==0 && buf[p]) {
113 isul[p] = 1;
114 p++;
115 } else {
116 if (buf[p] == '_') {
117 isul[p] = 1;
118 }
119 buf[p] = c;
120 p++;
121 if (n < p) n = p;
122 }
123 if (c=='\n') break;
124 }
125
126 state = 0;
127 for (p=0; p<n; p++) {
128 if (isul[p] != state)
129 tputs(isul[p] ? stul : endul, 1, outc);
130 state = isul[p];
131 outc(buf[p]);
132 if (isul[p] && *chul) {
133 printf("%s",backspace);
134 tputs(chul, 1, outc);
135 }
136 }
137 if (c==EOF) break;
138 }
139}
140
141outc(c)
142char c;
143{
144 putchar(c);
145}