aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h6
-rw-r--r--libbb/get_line_from_file.c70
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: */
609extern void xprint_and_close_file(FILE *file) FAST_FUNC; 609extern void xprint_and_close_file(FILE *file) FAST_FUNC;
610
611extern 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: */
611extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC; 613extern 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
615extern char *xmalloc_fgets(FILE *file) FAST_FUNC; 617extern 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: */
617extern char *xmalloc_fgetline(FILE *file) FAST_FUNC; 619extern char *xmalloc_fgetline(FILE *file) FAST_FUNC;
618extern 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) */
621extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC;
622
619extern void die_if_ferror(FILE *file, const char *msg) FAST_FUNC; 623extern void die_if_ferror(FILE *file, const char *msg) FAST_FUNC;
620extern void die_if_ferror_stdout(void) FAST_FUNC; 624extern void die_if_ferror_stdout(void) FAST_FUNC;
621extern void xfflush_stdout(void) FAST_FUNC; 625extern 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
79static 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 */
112char* 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
122char* 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 */
129char* 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