]> diplodocus.org Git - nmh/blob - sbr/vfgets.c
Just reworded the bit about '%s' being safe not to quote (it's only safe not to
[nmh] / sbr / vfgets.c
1
2 /*
3 * vfgets.c -- virtual fgets
4 *
5 * $Id$
6 */
7
8 #include <h/mh.h>
9
10 #define QUOTE '\\'
11
12
13 int
14 vfgets (FILE *in, char **bp)
15 {
16 int toggle;
17 char *cp, *dp, *ep, *fp;
18 static int len = 0;
19 static char *pp = NULL;
20
21 if (pp == NULL)
22 if (!(pp = malloc ((size_t) (len = BUFSIZ))))
23 adios (NULL, "unable to allocate string storage");
24
25 for (ep = (cp = pp) + len - 1;;) {
26 if (fgets (cp, ep - cp + 1, in) == NULL) {
27 if (cp != pp) {
28 *bp = pp;
29 return 0;
30 }
31 return (ferror (in) && !feof (in) ? -1 : 1);
32 }
33
34 if ((dp = cp + strlen (cp) - 2) < cp || *dp != QUOTE) {
35 wrong_guess:
36 if (cp > ++dp)
37 adios (NULL, "vfgets() botch -- you lose big");
38 if (*dp == '\n') {
39 *bp = pp;
40 return 0;
41 } else {
42 cp = ++dp;
43 }
44 } else {
45 for (fp = dp - 1, toggle = 0; fp >= cp; fp--) {
46 if (*fp != QUOTE)
47 break;
48 else
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 if (!(dp = realloc (pp, (size_t) (len += BUFSIZ)))) {
66 adios (NULL, "unable to allocate string storage");
67 } else {
68 cp = dp + curlen;
69 ep = (pp = dp) + len - 1;
70 }
71 }
72 }
73 }