xref: /minix/minix/commands/prep/prep.c (revision 7f5f010b)
1 /* prep - prepare file for statistics 	Author: Andy Tanenbaum */
2 
3 #include <ctype.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 
7 #define TROFF_CHAR	'.'	/* troff commands begin with this char */
8 #define EOL		'\n'	/* end of line char */
9 #define APOSTROPHE	047	/* single quote */
10 #define BACKSLASH       '\\'	/* troff code */
11 
12 int lfread;			/* set when last char read was lf */
13 int lfwritten = 1;		/* set when last char written was lf */
14 
15 int main(int argc, char **argv);
16 void skipline(void);
17 int backslash(void);
18 void usage(void);
19 
20 int main(argc, argv)
21 int argc;
22 char *argv[];
23 {
24 
25   int c;
26 
27   if (argc > 2) usage();
28   if (argc == 2) {
29 	if (freopen(argv[1], "r", stdin) == NULL) {
30 		printf("prep: cannot open %s\n", argv[1]);
31 		exit(1);
32 	}
33   }
34   while ((c = getchar()) != EOF) {
35 	/* Lines beginning with "." are troff commands -- skip them. */
36 	if (lfread && c == TROFF_CHAR) {
37 		skipline();
38 		continue;
39 	}
40 	while (c == BACKSLASH) c = backslash();	/* eat troff stuff */
41 
42 	if (isupper(c)) {
43 		putchar(tolower(c));
44 		lfwritten = 0;
45 		lfread = 0;
46 		continue;
47 	}
48 	if (islower(c)) {
49 		putchar(c);
50 		lfwritten = 0;
51 		lfread = 0;
52 		continue;
53 	}
54 	if (c == APOSTROPHE) {
55 		putchar(c);
56 		lfwritten = 0;
57 		lfread = 0;
58 		continue;
59 	}
60 	lfread = (c == EOL ? 1 : 0);
61 	if (lfwritten) continue;
62 	putchar(EOL);
63 	lfwritten = 1;
64   }
65   return(0);
66 }
67 
68 
69 void skipline()
70 {
71   char c;
72 
73   while ((c = getchar()) != EOL);
74 }
75 
76 
77 int backslash()
78 {
79 /* A backslash has been seen.  Eat troff stuff. */
80 
81   int c, c1, c2;
82 
83   c = getchar();
84   switch (c) {
85       case 'f':
86 	c = getchar();
87 	c = getchar();
88 	return(c);
89 
90       case 's':			/* \s7  or \s14 */
91 	c = getchar();
92 	c = getchar();
93 	if (isdigit(c)) c = getchar();
94 	return(c);
95 
96       case 'n':			/* \na or \n(xx  */
97 	c = getchar();
98 	if (c == '(') {
99 		c = getchar();
100 		c = getchar();
101 	}
102 	c = getchar();
103 	return(c);
104 
105       case '*':			/* / * (XX */
106 	c = getchar();
107 	if (c == '(') {
108 		c = getchar();
109 		c = getchar();
110 		c = getchar();
111 		return(c);
112 	}
113 
114       case '(':			/* troff 4-character escape sequence */
115 	c1 = getchar();
116 	c2 = getchar();
117 	if (c1 == 'e' && c2 == 'm') return(' ');
118 	if (c1 == 'e' && c2 == 'n') return(' ');
119 	c = getchar();
120 	return(c);
121 
122       case '%':			/* soft hyphen: \% */
123 	c = getchar();
124 	return(c);
125 
126       default:
127 	return(c);
128 
129   }
130 }
131 
132 void usage()
133 {
134   printf("Usage: prep [file]\n");
135   exit(1);
136 }
137