diff --git a/include/ft/all-tests.h b/include/ft/all-tests.h index 158c344..fada5cf 100644 --- a/include/ft/all-tests.h +++ b/include/ft/all-tests.h @@ -37,6 +37,7 @@ extern ft_test ft_stdio_fdopen; extern ft_test ft_stdio_write_chars; extern ft_test ft_stdio_read_chars; extern ft_test ft_stdio_stdstreams; +extern ft_test ft_stdio_getdelim; /* stdlib */ extern ft_test ft_stdlib_arith; diff --git a/src/main.c b/src/main.c index ee6398e..c0a4c38 100644 --- a/src/main.c +++ b/src/main.c @@ -56,6 +56,7 @@ ft_list headers_libc[] = { &ft_stdio_write_chars, &ft_stdio_read_chars, &ft_stdio_stdstreams, + &ft_stdio_getdelim, NULL, }}, { _("stdlib.h", ""), (ft_test*[]){ diff --git a/src/stdio/files.c b/src/stdio/files.c index 20ac6c0..6c52a98 100644 --- a/src/stdio/files.c +++ b/src/stdio/files.c @@ -1058,3 +1058,84 @@ ft_test ft_stdio_stdstreams = { .name = "stdin, stdout, and stderr", .function = _ft_stdio_stdstreams, }; + +static void _ft_stdio_getdelim_switch(ft_test *t) +{ + FILE *fp; + int rc; + size_t n=0; + ssize_t result; + char *lineptr = NULL; + + /* Create an initial file with some filler */ + DO_E(fp, fopen("ft_getdelim.txt", "w"), t, "%p"); + ft_assert(t, fp != NULL); + if(fp == NULL) return; + DO_E(rc, fputs("Line #1\nLine #2\n\nAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ\nLine #3", fp), t, "%d"); + ft_assert(t, rc >= 0); + DO_E(rc, fclose(fp), t, "%d"); + ft_assert(t, rc == 0); + + /* Read it with getline() and getdelim() */ + DO_E(fp, fopen("ft_getdelim.txt", "r"), t, "%p"); + ft_assert(t, fp != NULL); + if(fp == NULL) return; + DO_E(rc, setvbuf(fp, NULL, _IOFBF, 14), t, "%d"); + ft_assert(t, rc == 0); + ft_log_FILE(t, "", fp); + /* also test automatic alloc if lineptr=NULL */ + DO_E(result, getline(&lineptr, &n, fp), t, "%ld"); + ft_assert(t, result == 8); + ft_log_FILE(t, "", fp); + ft_log(t, "lineptr = '%s'\n", lineptr); + ft_assert(t, !strcmp(lineptr, "Line #1\n")); + DO_E(result, getdelim(&lineptr, &n, ' ', fp), t, "%ld"); + ft_assert(t, result == 5); + ft_log_FILE(t, "", fp); + ft_log(t, "lineptr = '%s'\n", lineptr); + ft_assert(t, !strcmp(lineptr, "Line ")); + DO_E(result, getline(&lineptr, &n, fp), t, "%ld"); + ft_assert(t, result == 3); + ft_log_FILE(t, "", fp); + ft_assert(t, !strcmp(lineptr, "#2\n")); + /* Test getline with 0 char line */ + DO_E(result, getline(&lineptr, &n, fp), t, "%ld"); + ft_assert(t, result == 1); + ft_log_FILE(t, "", fp); + ft_log(t, "lineptr = '%s'\n", lineptr); + ft_assert(t, !strcmp(lineptr, "\n")); + /* Test getline with long line */ + DO_E(result, getline(&lineptr, &n, fp), t, "%ld"); + ft_assert(t, result == 105); + ft_log_FILE(t, "", fp); + ft_log(t, "lineptr = '%s'\n", lineptr); + ft_log(t, "n = '%u'\n", n); + ft_assert(t, !strcmp(lineptr, "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ\n")); + /* test that we don't get -1 in case delim iss last symbol in file */ + DO_E(result, getdelim(&lineptr, &n, '3', fp), t, "%ld"); + ft_assert(t, result == 7); + ft_log_FILE(t, "", fp); + ft_log(t, "lineptr = '%s'\n", lineptr); + ft_log(t, "n = '%u'\n", n); + ft_assert(t, !strcmp(lineptr, "Line #3")); + ft_log(t, "Reading to EOF with getdelim(delim not in file)...\n"); + rewind(fp); + ft_log(t, "rewind(fp)\n"); + DO_E(result, getdelim(&lineptr, &n, '5', fp), t, "%ld"); + ft_assert(t, result == -1); + ft_log(t, "lineptr = '%s'\n", lineptr); + ft_assert(t, !strcmp(lineptr, "Line #1\nLine #2\n\nAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ\nLine #3")); + DO_E(rc, fclose(fp), t, "%d"); + ft_assert(t, rc == 0); + +} + +static void _ft_stdio_getdelim(ft_test *t) +{ + gint_world_switch(GINT_CALL(_ft_stdio_getdelim_switch, (void *)t)); +} + +ft_test ft_stdio_getdelim = { + .name = "delimited string input", + .function = _ft_stdio_getdelim, +};