From 69f4f9a6f40e2825c93fad4d3adf453c9b33d9bb Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 9 Aug 2008 17:16:40 +0000 Subject: optimize config_read() (by Timo Teras ) function old new delta bb_get_chunk_with_continuation - 176 +176 find_pair 169 187 +18 ... process_stdin 443 433 -10 config_read 549 456 -93 bb_get_chunk_from_file 139 7 -132 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 7/7 up/down: 215/-254) Total: -39 bytes --- libbb/get_line_from_file.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'libbb/get_line_from_file.c') diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c index 968d7572d..3cb46d240 100644 --- a/libbb/get_line_from_file.c +++ b/libbb/get_line_from_file.c @@ -9,18 +9,22 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -/* for getline() [GNUism] */ +/* for getline() [GNUism] #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif +*/ #include "libbb.h" /* This function reads an entire line from a text file, up to a newline * or NUL byte, inclusive. It returns a malloc'ed char * which * must be free'ed by the caller. If end is NULL '\n' isn't considered - * end of line. If end isn't NULL, length of the chunk read is stored in it. - * Return NULL if EOF/error */ -char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) + * end of line. If end isn't NULL, length of the chunk is stored in it. + * If lineno is not NULL, *lineno is incremented for each line, + * and also trailing '\' is recognized as line continuation. + * + * Returns NULL if EOF/error. */ +char* FAST_FUNC bb_get_chunk_with_continuation(FILE *file, int *end, int *lineno) { int ch; int idx = 0; @@ -30,12 +34,20 @@ char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) while ((ch = getc(file)) != EOF) { /* grow the line buffer as necessary */ if (idx >= linebufsz) { - linebufsz += 80; + linebufsz += 256; linebuf = xrealloc(linebuf, linebufsz); } linebuf[idx++] = (char) ch; - if (!ch || (end && ch == '\n')) + if (!ch) break; + if (end && ch == '\n') { + if (lineno == NULL) + break; + (*lineno)++; + if (idx < 2 || linebuf[idx-2] != '\\') + break; + idx -= 2; + } } if (end) *end = idx; @@ -52,6 +64,11 @@ char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) return linebuf; } +char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) +{ + return bb_get_chunk_with_continuation(file, end, NULL); +} + /* Get line, including trailing \n if any */ char* FAST_FUNC xmalloc_fgets(FILE *file) { @@ -72,7 +89,6 @@ char* FAST_FUNC xmalloc_fgetline(FILE *file) } #if 0 - /* GNUism getline() should be faster (not tested) than a loop with fgetc */ /* Get line, including trailing \n if any */ -- cgit v1.2.3