Add/update copyright notice in all source code files.
[mmh] / 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 }