xref: /minix3/minix/commands/cawf/bsfilt.c (revision b80da2a01d0bb632707b7b4e974aa32eaebbcc6f)
1 /*
2  *	bsfilt.c - a colcrt-like processor for cawf(1)
3  */
4 
5 /*
6  *	Copyright (c) 1991 Purdue University Research Foundation,
7  *	West Lafayette, Indiana 47907.  All rights reserved.
8  *
9  *	Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
10  *	University Computing Center.  Not derived from licensed software;
11  *	derived from awf(1) by Henry Spencer of the University of Toronto.
12  *
13  *	Permission is granted to anyone to use this software for any
14  *	purpose on any computer system, and to alter it and redistribute
15  *	it freely, subject to the following restrictions:
16  *
17  *	1. The author is not responsible for any consequences of use of
18  *	   this software, even if they arise from flaws in it.
19  *
20  *	2. The origin of this software must not be misrepresented, either
21  *	   by explicit claim or by omission.  Credits must appear in the
22  *	   documentation.
23  *
24  *	3. Altered versions must be plainly marked as such, and must not
25  *	   be misrepresented as being the original software.  Credits must
26  *	   appear in the documentation.
27  *
28  *	4. This notice may not be removed or altered.
29  */
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 
34 #ifdef UNIX
35 # ifdef USG
36 #include <string.h>
37 # else	/* not USG */
38 #include <strings.h>
39 # endif	/* USG */
40 #else	/* not UNIX */
41 #include <string.h>
42 #endif	/* UNIX */
43 
44 #include <sys/types.h>
45 
46 
47 #define MAXLL	2048			/* ridiculous maximum line length */
48 
49 int Dash = 1;				/* underline with dashes */
50 int Dp = 0;				/* dash pending */
51 int Lc = 0;				/* line count */
52 char *Pname;				/* program name */
53 unsigned char Ulb[MAXLL];		/* underline buffer */
54 int Ulx = 0;				/* underline buffer index */
55 
56 void Putchar(int ch);
57 
58 int main(int argc, char *argv[]) {
59 	int ax = 1;			/* argument index */
60 	unsigned char c;		/* character buffer */
61 	FILE *fs;			/* file stream */
62 	int nf = 0;			/* number of files processed */
63 	unsigned char pc;		/* previous character */
64 	int under = 0;                  /* underline */
65 /*
66  * Save program name.
67  */
68 	if ((Pname = strrchr(argv[0], '/')) != NULL)
69 		Pname++;
70 	else if ((Pname = strrchr(argv[0], '\\')) != NULL)
71 		Pname++;
72 	else
73 		Pname = argv[0];
74 /*
75  * Process options.
76  */
77 	if (argc > 1 && argv[1][0] == '-') {
78 		switch (argv[1][1]) {
79 	/*
80 	 * "-U" - underline with dashes.
81 	 */
82 		case 'U':
83 			Dash = 0;
84 			under = 1;
85 			break;
86 	/*
87 	 * "-" - do no  underlining at all.
88 	 */
89 		case '\0':
90 			Dash = under = 0;
91 			break;
92 		default:
93 			(void) fprintf(stderr,
94 				"%s usage: [-] [-U] [file]\n", Pname);
95 			exit(1);
96 		}
97 		ax++;
98 	}
99 /*
100  * Process files.  Read standard input if no files names.
101  */
102 
103 	while (ax < argc || nf == 0) {
104 		if (ax >= argc)
105 			fs = stdin;
106 		else {
107 #ifdef	UNIX
108 			if ((fs = fopen(argv[ax], "r")) == NULL)
109 #else
110 			if ((fs = fopen(argv[ax], "rt")) == NULL)
111 #endif
112 			{
113 				(void) fprintf(stderr, "%s: can't open %s\n",
114 					Pname, argv[ax]);
115 				exit(1);
116 			}
117 			ax++;
118 		}
119 		nf++;
120 	/*
121 	 * Read input a character at a time.
122 	 */
123 		for (pc = '\0';;) {
124 			c = (unsigned char)fgetc(fs);
125 			if (feof(fs))
126 				break;
127 			switch(c) {
128 
129 			case '\n':
130 				if (pc)
131 					Putchar((int)pc);
132 				Putchar('\n');
133 				pc = '\0';
134 				break;
135 
136 			case '\b':
137 				if (pc == '_') {
138 					if (under) {
139 						putchar(pc);
140 						putchar('\b');
141 					} else if (Dash)
142 						Dp = 1;
143 				}
144 				pc = '\0';
145 				break;
146 
147 			default:
148 				if (pc)
149 					Putchar((int)pc);
150 				pc = c;
151 			}
152 		}
153 		if (pc) {
154 			Putchar((int)pc);
155 			Putchar((int)'\n');
156 		}
157 	}
158 	exit(0);
159 }
160 
161 
162 /*
163  * Putchar(ch) - put a character with possible underlining
164  */
165 
166 void Putchar(int ch) {
167 	int i;					/* temporary index */
168 
169 	if ((unsigned char)ch == '\n') {
170 /*
171  * Handle end of line.
172  */
173 		putchar('\n');
174 		if (Ulx) {
175 			while (Ulx && Ulb[Ulx-1] == ' ')
176 				Ulx--;
177 			if (Ulx) {
178 				for (i = 0; i < Ulx; i++)
179 					putchar(Ulb[i]);
180 				putchar('\n');
181 			}
182 		}
183 		Dp = Ulx = 0;
184 		Lc++;
185 		return;
186 	}
187 /*
188  * Put "normal" character.
189  */
190 	putchar((unsigned char)ch);
191 	if (Dash) {
192 
193 	/*
194 	 * Handle dash-type underlining.
195 	 */
196 		if (Ulx >= MAXLL) {
197 			(void) fprintf(stderr,
198 				"%s: underline for line %d > %d characters\n",
199 				Pname, Lc, MAXLL);
200 			exit(1);
201 		}
202 		Ulb[Ulx++] = Dp ? '-' : ' ';
203 		Dp = 0;
204 	}
205 }
206