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