]> diplodocus.org Git - nmh/blob - sbr/vfgets.c
sendsbr.c: Move interface to own file.
[nmh] / sbr / vfgets.c
1 /* vfgets.c -- virtual fgets
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include "h/mh.h"
9 #include "vfgets.h"
10 #include "error.h"
11 #include "h/utils.h"
12
13 #define QUOTE '\\'
14
15
16 int
17 vfgets (FILE *in, char **bp)
18 {
19 int toggle;
20 char *cp, *dp, *ep, *fp;
21 static int len = 0;
22 static char *pp = NULL;
23
24 if (pp == NULL)
25 pp = mh_xmalloc ((size_t) (len = BUFSIZ));
26
27 for (ep = (cp = pp) + len - 1;;) {
28 if (fgets (cp, ep - cp + 1, in) == NULL) {
29 if (cp != pp) {
30 *bp = pp;
31 return 0;
32 }
33 return ferror(in) && !feof(in) ? -1 : 1;
34 }
35
36 if ((dp = cp + strlen (cp) - 2) < cp || *dp != QUOTE) {
37 wrong_guess:
38 if (cp > ++dp)
39 die("vfgets() botch -- you lose big");
40 if (*dp == '\n') {
41 *bp = pp;
42 return 0;
43 }
44 cp = ++dp;
45 } else {
46 for (fp = dp - 1, toggle = 0; fp >= cp; fp--) {
47 if (*fp != QUOTE)
48 break;
49 toggle = !toggle;
50 }
51 if (toggle)
52 goto wrong_guess;
53
54 if (*++dp == '\n') {
55 *--dp = 0;
56 cp = dp;
57 } else {
58 cp = ++dp;
59 }
60 }
61
62 if (cp >= ep) {
63 int curlen = cp - pp;
64
65 dp = mh_xrealloc (pp, (size_t) (len += BUFSIZ));
66 cp = dp + curlen;
67 ep = (pp = dp) + len - 1;
68 }
69 }
70 }