in comp.lang.c i read:
i elided most of the code -- sometimes this is a mistake, though i hope not
-- only the bits with nits remain.
char *rfg(FILE * f, int l) {
int makes some sense, but i happen to prefer size_t as there is no meaning
in a negative length or offset in this code.
char *rfg(FILE * f, size_t l) {
also, this is now a very short name to have with external linkage. i would
probably change to internal linkage, or rename it rfgets_r -- heh, perhaps
both.
nothing wrong with it, but again as you cannot have a negative string
length i tend to prefer a size_t.
size_t x;
if(b[x - 1] != '\n' && (p = rfg(f, l + x))) {
what if the first byte fgets returns is a null byte? better check for zero
length just in case.
also, what if rfg returns a null pointer (malloc failed)? do you really
want to just chuck the last part of the line away and make believe it ends
at the current block?
sometimes losing as little data as possible is important, in which case
your code with a length check added would be fine:
if(0 < x && b[x - 1] != '\n' && (p = rfg(f, l + x))) {
but i think it's usually better to back propagate the malloc failure:
if(0 < x && b[x - 1] != '\n') {
if (0 == (p = rfg(f, l + x))) return 0;
p = (char *) malloc(l + x + 1) + l;
strcpy(p, b);
what if the malloc fails? (the cast just to do the arithmetic is ugly
enough to want a change, even though it is valid -- as long as malloc
doesn't fail.)
if (0 == (p = malloc(l + x + 1))) return 0;
p += l;
strcpy(p, b);