86211cf64ffb587eb73714129b2f1f8223d1102a
[mmh] / sbr / cpydgst.c
1 /*
2 ** cpydgst.c -- copy from one fd to another in encapsulating mode
3 **           -- (do dashstuffing of input data).
4 **
5 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
6 ** COPYRIGHT file in the root directory of the nmh distribution for
7 ** complete copyright information.
8 */
9
10 #include <h/mh.h>
11
12 /*
13 ** We want to perform the substitution
14 **
15 **     \n(-.*)\n    -->    \n- \1\n
16 **
17 ** This is equivalent to the sed substitution
18 **
19 **     sed -e 's%^-%- -%' < ifile > ofile
20 **
21 **  but the routine below is faster than the pipe, fork, and exec.
22 */
23
24 #define S1 0
25 #define S2 1
26
27 #define output(c)  if (bp >= dp) {flush(); *bp++ = c;} else *bp++ = c
28 #define flush()  if ((j = bp - outbuf) && write(out, outbuf, j) != j) \
29                 adios(ofile, "error writing"); \
30         else \
31                 bp = outbuf
32
33
34 void
35 cpydgst(int in, int out, char *ifile, char *ofile)
36 {
37         register int i, j, state;
38         register char *cp, *ep;
39         register char *bp, *dp;
40         char buffer[BUFSIZ], outbuf[BUFSIZ];
41
42         dp = (bp = outbuf) + sizeof outbuf;
43         for (state = S1; (i = read(in, buffer, sizeof buffer)) > 0;)
44                 for (ep = (cp = buffer) + i; cp < ep; cp++) {
45                         if (*cp == '\0')
46                                 continue;
47                         switch (state) {
48                                 case S1:
49                                         if (*cp == '-') {
50                                                 output('-');
51                                                 output(' ');
52                                         }
53                                         state = S2;  /* fall */
54
55                                 case S2:
56                                         output(*cp);
57                                         if (*cp == '\n')
58                                                 state = S1;
59                                         break;
60                         }
61                 }
62
63         if (i == -1)
64                 adios(ifile, "error reading");
65         flush();
66 }