]> diplodocus.org Git - nmh/blob - sbr/vfgets.c
37d1d90c88a199d8484be071cbdfe23fab665315
[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 "error.h"
10 #include <h/utils.h>
11
12 #define QUOTE '\\'
13
14
15 int
16 vfgets (FILE *in, char **bp)
17 {
18 int toggle;
19 char *cp, *dp, *ep, *fp;
20 static int len = 0;
21 static char *pp = NULL;
22
23 if (pp == NULL)
24 pp = mh_xmalloc ((size_t) (len = BUFSIZ));
25
26 for (ep = (cp = pp) + len - 1;;) {
27 if (fgets (cp, ep - cp + 1, in) == NULL) {
28 if (cp != pp) {
29 *bp = pp;
30 return 0;
31 }
32 return ferror(in) && !feof(in) ? -1 : 1;
33 }
34
35 if ((dp = cp + strlen (cp) - 2) < cp || *dp != QUOTE) {
36 wrong_guess:
37 if (cp > ++dp)
38 die("vfgets() botch -- you lose big");
39 if (*dp == '\n') {
40 *bp = pp;
41 return 0;
42 }
43 cp = ++dp;
44 } else {
45 for (fp = dp - 1, toggle = 0; fp >= cp; fp--) {
46 if (*fp != QUOTE)
47 break;
48 toggle = !toggle;
49 }
50 if (toggle)
51 goto wrong_guess;
52
53 if (*++dp == '\n') {
54 *--dp = 0;
55 cp = dp;
56 } else {
57 cp = ++dp;
58 }
59 }
60
61 if (cp >= ep) {
62 int curlen = cp - pp;
63
64 dp = mh_xrealloc (pp, (size_t) (len += BUFSIZ));
65 cp = dp + curlen;
66 ep = (pp = dp) + len - 1;
67 }
68 }
69 }