diff --git a/c/Makefile b/c/Makefile index 49a744250..b695d07c8 100644 --- a/c/Makefile +++ b/c/Makefile @@ -102,6 +102,7 @@ lib/mlr_globals.c \ lib/string_builder.c \ input/stdio_byte_reader.c \ input/file_reader_mmap.c \ +input/line_readers.c \ containers/parse_trie.c \ experimental/getlines.c diff --git a/c/experimental/getlines.c b/c/experimental/getlines.c index c444613d0..03d020cd7 100644 --- a/c/experimental/getlines.c +++ b/c/experimental/getlines.c @@ -7,6 +7,7 @@ #include "input/lrec_readers.h" #include "lib/string_builder.h" #include "input/byte_readers.h" +#include "input/line_readers.h" #include "input/peek_file_reader.h" #include "containers/parse_trie.h" @@ -44,6 +45,29 @@ static int read_file_mlr_get_line(char* filename, int do_write) { return bc; } +// ================================================================ +static int read_file_mlr_getcdelim(char* filename, int do_write) { + FILE* fp = fopen_or_die(filename); + char irs = '\n'; + int bc = 0; + while (1) { + char* line = NULL; + size_t linecap = 0; + ssize_t linelen = mlr_getcdelim(&line, &linecap, irs, fp); + if (linelen < 0) { + break; + } + bc += linelen; + if (do_write) { + fputs(line, stdout); + fputc('\n', stdout); + } + free(line); + } + fclose(fp); + return bc; +} + // ================================================================ static char* read_line_fgetc(FILE* fp, char* irs, int irs_len) { char* line = mlr_malloc_or_die(FIXED_LINE_LEN); @@ -347,6 +371,7 @@ int main(int argc, char** argv) { int bc; for (int i = 0; i < nreps; i++) { + s = get_systime(); bc = read_file_mlr_get_line(filename, do_write); e = get_systime(); @@ -354,6 +379,13 @@ int main(int argc, char** argv) { printf("type=getdelim,t=%.6lf,n=%d\n", t, bc); fflush(stdout); + s = get_systime(); + bc = read_file_mlr_getcdelim(filename, do_write); + e = get_systime(); + t = e - s; + printf("type=mlr_getcdelim,t=%.6lf,n=%d\n", t, bc); + fflush(stdout); + s = get_systime(); bc = read_file_fgetc_fixed_len(filename, do_write); e = get_systime(); diff --git a/c/input/line_readers.c b/c/input/line_readers.c index eb04a5881..9841173b6 100644 --- a/c/input/line_readers.c +++ b/c/input/line_readers.c @@ -13,10 +13,10 @@ size_t mlr_getcdelim(char ** restrict ppline, size_t * restrict plinecap, int de size_t linecap = INITIAL_SIZE; char* pline = mlr_malloc_or_die(INITIAL_SIZE); char* p = pline; - int len = 0; + int eof = FALSE; while (TRUE) { - if (len >= linecap) { + if ((p-pline) >= linecap) { linecap = linecap << 1; // xxx mlr_realloc_or_die pline = realloc(pline, linecap); @@ -24,18 +24,27 @@ size_t mlr_getcdelim(char ** restrict ppline, size_t * restrict plinecap, int de } int c = getc_unlocked(fp); if (c == EOF) { + if (p == pline) + eof = TRUE; + *(p++) = 0; break; } else if (c == delimiter) { *(p++) = 0; + break; } else { *(p++) = c; } } - *ppline = pline; - *plinecap = linecap; - len = p - pline; - return len; + if (eof) { + free(pline); + *ppline = NULL; + return -1; + } else { + *ppline = pline; + *plinecap = linecap; + return p - pline; + } } size_t mlr_getsdelim(char ** restrict ppline, size_t * restrict plinecap, char* delimiter, FILE * restrict fp) {