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