10 |
|
|
11 |
#include "libbb.h" |
#include "libbb.h" |
12 |
|
|
13 |
/* Read up to (and including) TERMINATING_STRING from FILE and return it. |
static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string, int chop_off) |
|
* Return NULL on EOF. */ |
|
|
|
|
|
char *xmalloc_fgets_str(FILE *file, const char *terminating_string) |
|
14 |
{ |
{ |
15 |
char *linebuf = NULL; |
char *linebuf = NULL; |
16 |
const int term_length = strlen(terminating_string); |
const int term_length = strlen(terminating_string); |
22 |
while (1) { |
while (1) { |
23 |
ch = fgetc(file); |
ch = fgetc(file); |
24 |
if (ch == EOF) { |
if (ch == EOF) { |
25 |
free(linebuf); |
if (idx == 0) |
26 |
return NULL; |
return linebuf; /* NULL */ |
27 |
|
break; |
28 |
} |
} |
29 |
|
|
30 |
/* grow the line buffer as necessary */ |
if (idx >= linebufsz) { |
|
while (idx > linebufsz - 2) { |
|
31 |
linebufsz += 200; |
linebufsz += 200; |
32 |
linebuf = xrealloc(linebuf, linebufsz); |
linebuf = xrealloc(linebuf, linebufsz); |
33 |
} |
} |
37 |
|
|
38 |
/* Check for terminating string */ |
/* Check for terminating string */ |
39 |
end_string_offset = idx - term_length; |
end_string_offset = idx - term_length; |
40 |
if (end_string_offset > 0 |
if (end_string_offset >= 0 |
41 |
&& memcmp(&linebuf[end_string_offset], terminating_string, term_length) == 0 |
&& memcmp(&linebuf[end_string_offset], terminating_string, term_length) == 0 |
42 |
) { |
) { |
43 |
idx -= term_length; |
if (chop_off) |
44 |
|
idx -= term_length; |
45 |
break; |
break; |
46 |
} |
} |
47 |
} |
} |
48 |
|
/* Grow/shrink *first*, then store NUL */ |
49 |
linebuf = xrealloc(linebuf, idx + 1); |
linebuf = xrealloc(linebuf, idx + 1); |
50 |
linebuf[idx] = '\0'; |
linebuf[idx] = '\0'; |
51 |
return linebuf; |
return linebuf; |
52 |
} |
} |
53 |
|
|
54 |
|
/* Read up to TERMINATING_STRING from FILE and return it, |
55 |
|
* including terminating string. |
56 |
|
* Non-terminated string can be returned if EOF is reached. |
57 |
|
* Return NULL if EOF is reached immediately. */ |
58 |
|
char* FAST_FUNC xmalloc_fgets_str(FILE *file, const char *terminating_string) |
59 |
|
{ |
60 |
|
return xmalloc_fgets_internal(file, terminating_string, 0); |
61 |
|
} |
62 |
|
|
63 |
|
char* FAST_FUNC xmalloc_fgetline_str(FILE *file, const char *terminating_string) |
64 |
|
{ |
65 |
|
return xmalloc_fgets_internal(file, terminating_string, 1); |
66 |
|
} |