Read one line from input, up to and including the next newline * character. Returns a pointer to the heap-allocated string, or a * null pointer if no characters were read. * 5.0: redone to use nethack's alloc() rather than libc's malloc() * and realloc(). */
| 1594 | * and realloc(). |
| 1595 | */ |
| 1596 | static char * |
| 1597 | fgetline(FILE *fd) |
| 1598 | { |
| 1599 | static const int inc = (BUFSZ / 2) + 16; /* fgets() wants signed int */ |
| 1600 | unsigned len = (unsigned) inc, newlen; /* alloc() wants unsigned int */ |
| 1601 | char *c = (char *) alloc(len), *cprime, *ret; |
| 1602 | |
| 1603 | *c = '\0'; |
| 1604 | for (;;) { |
| 1605 | ret = fgets(c + len - inc, inc, fd); |
| 1606 | if (!ret) { |
| 1607 | /* don't just assume ret==Null indicates an error; last line |
| 1608 | might lack terminating newline; if previous fgets() read it, |
| 1609 | instead of returning we would have expanded the buffer and |
| 1610 | tried for more, then got Null due to end of file having |
| 1611 | already been reached */ |
| 1612 | if (feof(fd) && *c && strlen(c) < len) { |
| 1613 | Strcat(c, "\n"); /* append missing newline */ |
| 1614 | } else { |
| 1615 | free((genericptr_t) c), c = NULL; |
| 1616 | } |
| 1617 | break; /* either with or without added newline, we're done */ |
| 1618 | } else if (strchr(c, '\n')) { |
| 1619 | /* normal case: we have a full line */ |
| 1620 | break; |
| 1621 | } |
| 1622 | /* didn't fit in c[0..len-1]; expand buffer and read some more |
| 1623 | [this was much simpler (and possibly slightly more efficient) |
| 1624 | with realloc() but less safe because return values from malloc() |
| 1625 | and realloc() were not being checked for Null, and efficiency is |
| 1626 | a red herring because growing the buffer will be extremely rare] */ |
| 1627 | newlen = len + (unsigned) inc; |
| 1628 | cprime = (char *) alloc(newlen); |
| 1629 | (void) memcpy(cprime, c, len); |
| 1630 | free((genericptr_t) c); |
| 1631 | c = cprime; |
| 1632 | *(c + len) = '\0'; |
| 1633 | len = newlen; |
| 1634 | } |
| 1635 | |
| 1636 | filter_nonascii(c); |
| 1637 | return c; |
| 1638 | } |
| 1639 | |
| 1640 | static void |
| 1641 | filter_nonascii(char *line) |
no test coverage detected