diff options
-rw-r--r-- | include/libbb.h | 6 | ||||
-rw-r--r-- | libbb/get_line_from_file.c | 70 |
2 files changed, 75 insertions, 1 deletions
diff --git a/include/libbb.h b/include/libbb.h index 671584b43..2bd614c71 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -607,6 +607,8 @@ extern void xopen_xwrite_close(const char* file, const char *str) FAST_FUNC; | |||
607 | 607 | ||
608 | /* Reads and prints to stdout till eof, then closes FILE. Exits on error: */ | 608 | /* Reads and prints to stdout till eof, then closes FILE. Exits on error: */ |
609 | extern void xprint_and_close_file(FILE *file) FAST_FUNC; | 609 | extern void xprint_and_close_file(FILE *file) FAST_FUNC; |
610 | |||
611 | extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC; | ||
610 | /* Reads up to (and including) TERMINATING_STRING: */ | 612 | /* Reads up to (and including) TERMINATING_STRING: */ |
611 | extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC; | 613 | extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC; |
612 | /* Chops off TERMINATING_STRING from the end: */ | 614 | /* Chops off TERMINATING_STRING from the end: */ |
@@ -615,7 +617,9 @@ extern char *xmalloc_fgetline_str(FILE *file, const char *terminating_string) FA | |||
615 | extern char *xmalloc_fgets(FILE *file) FAST_FUNC; | 617 | extern char *xmalloc_fgets(FILE *file) FAST_FUNC; |
616 | /* Chops off '\n' from the end, unlike fgets: */ | 618 | /* Chops off '\n' from the end, unlike fgets: */ |
617 | extern char *xmalloc_fgetline(FILE *file) FAST_FUNC; | 619 | extern char *xmalloc_fgetline(FILE *file) FAST_FUNC; |
618 | extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC; | 620 | /* Same, but doesn't try to conserve space (may have some slack after the end) */ |
621 | extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC; | ||
622 | |||
619 | extern void die_if_ferror(FILE *file, const char *msg) FAST_FUNC; | 623 | extern void die_if_ferror(FILE *file, const char *msg) FAST_FUNC; |
620 | extern void die_if_ferror_stdout(void) FAST_FUNC; | 624 | extern void die_if_ferror_stdout(void) FAST_FUNC; |
621 | extern void xfflush_stdout(void) FAST_FUNC; | 625 | extern void xfflush_stdout(void) FAST_FUNC; |
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c index 3a76f49a0..7b65ced8d 100644 --- a/libbb/get_line_from_file.c +++ b/libbb/get_line_from_file.c | |||
@@ -67,3 +67,73 @@ char* FAST_FUNC xmalloc_fgetline(FILE *file) | |||
67 | 67 | ||
68 | return c; | 68 | return c; |
69 | } | 69 | } |
70 | |||
71 | /* Faster routines (~twice as fast). +170 bytes. Unused as of 2008-07. | ||
72 | * | ||
73 | * NB: they stop at NUL byte too. | ||
74 | * Performance is important here. Think "grep 50gigabyte_file"... | ||
75 | * Iironically, grep can't use it because of NUL issue. | ||
76 | * We sorely need C lib to provide fgets which reports size! | ||
77 | */ | ||
78 | |||
79 | static char* xmalloc_fgets_internal(FILE *file, int *sizep) | ||
80 | { | ||
81 | int len; | ||
82 | int idx = 0; | ||
83 | char *linebuf = NULL; | ||
84 | |||
85 | while (1) { | ||
86 | char *r; | ||
87 | |||
88 | linebuf = xrealloc(linebuf, idx + 0x100); | ||
89 | r = fgets(&linebuf[idx], 0x100, file); | ||
90 | if (!r) { | ||
91 | /* need to terminate in case this is error | ||
92 | * (EOF puts NUL itself) */ | ||
93 | linebuf[idx] = '\0'; | ||
94 | break; | ||
95 | } | ||
96 | /* stupid. fgets knows the len, it should report it somehow */ | ||
97 | len = strlen(&linebuf[idx]); | ||
98 | idx += len; | ||
99 | if (len != 0xff || linebuf[idx - 1] == '\n') | ||
100 | break; | ||
101 | } | ||
102 | *sizep = idx; | ||
103 | if (idx) { | ||
104 | /* xrealloc(linebuf, idx + 1) is up to caller */ | ||
105 | return linebuf; | ||
106 | } | ||
107 | free(linebuf); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | /* Get line, remove trailing \n */ | ||
112 | char* FAST_FUNC xmalloc_fgetline_fast(FILE *file) | ||
113 | { | ||
114 | int sz; | ||
115 | char *r = xmalloc_fgets_internal(file, &sz); | ||
116 | if (r && r[sz - 1] == '\n') | ||
117 | r[--sz] = '\0'; | ||
118 | return r; /* not xrealloc(r, sz + 1)! */ | ||
119 | } | ||
120 | |||
121 | #if 0 | ||
122 | char* FAST_FUNC xmalloc_fgets(FILE *file) | ||
123 | { | ||
124 | int sz; | ||
125 | return xmalloc_fgets_internal(file, &sz); | ||
126 | } | ||
127 | |||
128 | /* Get line, remove trailing \n */ | ||
129 | char* FAST_FUNC xmalloc_fgetline(FILE *file) | ||
130 | { | ||
131 | int sz; | ||
132 | char *r = xmalloc_fgets_internal(file, &sz); | ||
133 | if (!r) | ||
134 | return r; | ||
135 | if (r[sz - 1] == '\n') | ||
136 | r[--sz] = '\0'; | ||
137 | return xrealloc(r, sz + 1); | ||
138 | } | ||
139 | #endif | ||