Factor trim format function out
[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 <sysexits.h>
11 #include <unistd.h>
12 #include <h/mh.h>
13
14 /*
15 ** We want to perform the substitution
16 **
17 **     \n(-.*)\n    -->    \n- \1\n
18 **
19 ** This is equivalent to the sed substitution
20 **
21 **     sed -e 's%^-%- -%' < ifile > ofile
22 **
23 **  but the routine below is faster than the pipe, fork, and exec.
24 */
25
26 #define S1 0
27 #define S2 1
28
29 #define output(c)  if (bp >= dp) {flush(); *bp++ = c;} else *bp++ = c
30 #define flush()  if ((j = bp - outbuf) && write(out, outbuf, j) != j) \
31                 adios(EX_IOERR, ofile, "error writing"); \
32         else \
33                 bp = outbuf
34
35
36 void
37 cpydgst(int in, int out, char *ifile, char *ofile)
38 {
39         int i, j, state;
40         char *cp, *ep;
41         char *bp, *dp;
42         char buffer[BUFSIZ], outbuf[BUFSIZ];
43
44         dp = (bp = outbuf) + sizeof outbuf;
45         for (state = S1; (i = read(in, buffer, sizeof buffer)) > 0;)
46                 for (ep = (cp = buffer) + i; cp < ep; cp++) {
47                         if (*cp == '\0')
48                                 continue;
49                         switch (state) {
50                         case S1:
51                                 if (*cp == '-') {
52                                         output('-');
53                                         output(' ');
54                                 }
55                                 state = S2;  /* fall */
56
57                         case S2:
58                                 output(*cp);
59                                 if (*cp == '\n')
60                                         state = S1;
61                                 break;
62                         }
63                 }
64
65         if (i == -1)
66                 adios(EX_IOERR, ifile, "error reading");
67         flush();
68 }