3BSD/usr/src/cmd/ul.c

Compare this file to the similar file:
Show the results in this format:

/*
 *
 * ul - General underline filter. Converts underlines by
 * the standard backspacing method to the code used by the
 * particular terminal to underline.
 *
 */
#include <stdio.h>
char buf[BUFSIZ];
char isul[BUFSIZ];
char termcap[1024];
char ulbuf[BUFSIZ];
char *stul, *endul, *chul;
char *backspace;
char *termtype;
int outc();
char *tgetstr();
char *getenv();

main(argc,argv) char **argv; {
	register int i;
	char *cp;
	FILE *f;

	/* Figure out kind of terminal and set up special strings. */
	termtype = getenv("TERM");
	if (termtype == NULL)
		termtype = "dumb";
	while (argc >= 2 && argv[1][0] == '-') {
		switch(argv[1][1]) {
		case 't':
		case 'T': /* for nroff compatibility */
			if (argv[1][2])
				termtype = &argv[1][2];
			else {
				termtype = argv[2];
				argc--;
				argv++;
			}
			break;
		default:
			printf("Bad switch: %s\n",argv[1]);
			exit(1);
		}
	}
	switch(tgetent(termcap, termtype)) {
		case 1:	/* All is well */
			/* Terminals that don't need any help. */
			if (tgetflag("ul") || tgetflag("os"))
				execv("/bin/cat",argv);
			cp = ulbuf;
			if ((backspace = tgetstr("bc",&cp)) == NULL)
				backspace = "\b";
			/*
			 * Handle terminals that have start underline/stop
			 * underline sequences, as well as those with
			 * underline char sequences (we assume the sequence
			 * moves the cursor forward one character).
			 * If we can't find underline sequences, we
			 * settle for standout sequences.
			 */
			if (	(chul=tgetstr("uc",&cp)) == NULL)
					chul = "";
			if (	(stul=tgetstr("us",&cp)) == NULL &&
				(!*chul) && (stul=tgetstr("so",&cp)) == NULL)
					stul = "";
			if (	(endul=tgetstr("ue",&cp)) == NULL &&
				(!*chul) && (endul=tgetstr("se",&cp)) == NULL)
					endul = "";
			break;
		default:/* error opening/reading termcap */
			fprintf(stderr,"trouble reading termcap");
			/* fall through to ... */
		case 0:	/* No such terminal type - assume dumb */
			stul = endul = chul = "";
			break;
	}
	if (argc < 2) filter(stdin);
	else for (i=1; i<argc; i++) {
		f = fopen(argv[i],"r");
		if (f == NULL) {
			printf("Can't open %s\n",argv[i]);
			exit(1);
		} else filter(f);
	}
	exit(0);
}

filter(f)
FILE *f;
{
	register int p, n;
	register char c;
	int state;

	n = 0;
	for (;;) {
		p = 0;
		for (p=0; p<n; p++) {
			buf[p] = '\0';
			isul[p] = 0;
		}
		p = n = 0;

		for (;;) {
			c = getc(f);
			if (c==EOF) break;
			if (c=='\b') {
				if (p > 0) {
					p--;
				}
			} else if (c=='_' && isul[p]==0 && buf[p]) {
				isul[p] = 1;
				p++;
			} else {
				if (buf[p] == '_') {
					isul[p] = 1;
				}
				buf[p] = c;
				p++;
				if (n < p) n = p;
			}
			if (c=='\n') break;
		}

		state = 0;
		for (p=0; p<n; p++) {
			if (isul[p] != state)
				tputs(isul[p] ? stul : endul, 1, outc);
			state = isul[p];
			outc(buf[p]);
			if (isul[p] && *chul) {
				printf("%s",backspace);
				tputs(chul, 1, outc);
			}
		}
		if (c==EOF) break;
	}
}

outc(c)
char c;
{
	putchar(c);
}