stdio: tests for ungetc, update and append modes
This commit is contained in:
parent
ab763cf712
commit
419fef4f1e
|
@ -31,6 +31,8 @@ extern ft_test ft_stdio_open;
|
|||
extern ft_test ft_stdio_simple_read;
|
||||
extern ft_test ft_stdio_simple_write;
|
||||
extern ft_test ft_stdio_line_buffering;
|
||||
extern ft_test ft_stdio_update_ungetc;
|
||||
extern ft_test ft_stdio_append;
|
||||
|
||||
/* stdlib */
|
||||
extern ft_test ft_stdlib_arith;
|
||||
|
|
|
@ -47,6 +47,8 @@ ft_list headers_libc[] = {
|
|||
&ft_stdio_simple_read,
|
||||
&ft_stdio_simple_write,
|
||||
&ft_stdio_line_buffering,
|
||||
&ft_stdio_update_ungetc,
|
||||
&ft_stdio_append,
|
||||
NULL,
|
||||
}},
|
||||
{ _("stdlib.h", "<stdlib.h>"), (ft_test*[]){
|
||||
|
|
|
@ -29,8 +29,8 @@ static void _stdio_open_switch(ft_test *t)
|
|||
/* Try to open it with <stdio.h> */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "r"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
if(!fp) return;
|
||||
|
||||
/* Change buffer settings a couple times */
|
||||
DO_E(rc, setvbuf(fp, NULL, _IONBF, 0), t, "%d");
|
||||
|
@ -46,15 +46,19 @@ static void _stdio_open_switch(ft_test *t)
|
|||
/* Reopen with different permissions */
|
||||
DO_E(fp, freopen("ft_stdio.txt", "w+", fp), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(fp, freopen("ft_stdio.txt", "rb+", fp), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(fp, freopen("ft_stdio.txt", "ab", fp), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(fp, freopen("ft_stdio.txt", "w", fp), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
|
||||
DO_E(rc, fclose(fp), t, "%d");
|
||||
|
@ -80,7 +84,7 @@ static char const *filler =
|
|||
"defined) is advanced by the number of characters successfully read. If an "
|
||||
"error occurs, the resulting value of the file position indicator for the "
|
||||
"stream is indeterminate. If a partial element is read, its value is "
|
||||
"indeterminate.\n"; /* length 591 */
|
||||
"indeterminate.\n"; /* ISO/IEC 9899:1999, 7.19.8.1§2 (length 591) */
|
||||
|
||||
static void _ft_stdio_simple_read_switch(ft_test *t)
|
||||
{
|
||||
|
@ -100,6 +104,7 @@ static void _ft_stdio_simple_read_switch(ft_test *t)
|
|||
/* Read it through a buffer of size 128 */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "r"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, setvbuf(fp, NULL, _IOFBF, 128), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
|
@ -264,6 +269,7 @@ static void _ft_stdio_simple_write_switch(ft_test *t)
|
|||
/* Open a new file */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "w"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, setvbuf(fp, NULL, _IOFBF, 128), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
|
@ -347,6 +353,7 @@ static void _ft_stdio_simple_write_switch(ft_test *t)
|
|||
/* Check the new file size */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "r"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
DO_E(rc, fseek(fp, 0, SEEK_END), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
DO_E(rc, ftell(fp), t, "%d");
|
||||
|
@ -373,6 +380,7 @@ static void _ft_stdio_line_buffering_switch(ft_test *t)
|
|||
/* Open a new line-buffered file */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "w"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, setvbuf(fp, NULL, _IOLBF, 128), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
|
@ -424,3 +432,241 @@ ft_test ft_stdio_line_buffering = {
|
|||
.name = "Writing with line buffering",
|
||||
.function = _ft_stdio_line_buffering,
|
||||
};
|
||||
|
||||
static void _ft_stdio_update_ungetc_switch(ft_test *t)
|
||||
{
|
||||
FILE *fp;
|
||||
int rc;
|
||||
char str[128];
|
||||
|
||||
/* Create a file in update mode with w+ */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "w+"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
/* Write some data, then re-read it, then re-write it */
|
||||
DO_E(rc, fwrite(filler, 1, 64, fp), t, "%d");
|
||||
ft_assert(t, rc == 64);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fseek(fp, 0, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fread(str, 1, 16, fp), t, "%d");
|
||||
ft_assert(t, rc == 16);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fread(str, 1, 48, fp), t, "%d");
|
||||
ft_assert(t, rc == 48);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, ftell(fp) == 64);
|
||||
DO_E(rc, fseek(fp, -16, SEEK_CUR), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
DO_E(rc, fwrite(str, 1, 48, fp), t, "%d");
|
||||
ft_assert(t, rc == 48);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fwrite(str, 1, 16, fp), t, "%d");
|
||||
ft_assert(t, rc == 16);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, ftell(fp) == 112);
|
||||
/* Re-read it and check it */
|
||||
rewind(fp);
|
||||
ft_log(t, "rewind(fp)\n");
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fread(str, 1, 112, fp), t, "%d");
|
||||
ft_assert(t, rc == 112);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, !memcmp(str, filler, 48));
|
||||
ft_assert(t, !memcmp(str+48, filler+16, 48));
|
||||
ft_assert(t, !memcmp(str+96, filler+16, 16));
|
||||
DO_E(rc, fclose(fp), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_log(t, "\n");
|
||||
|
||||
/* Reopen that file with r+ */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "r+"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
/* ungetc() some characters before position 0 */
|
||||
DO_E(rc, ungetc('#', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '#');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('!', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '!');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('$', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '$');
|
||||
ft_log_FILE(t, "", fp);
|
||||
/* Read them back along with some actual data */
|
||||
DO_E(rc, fread(str, 1, 51, fp), t, "%d");
|
||||
ft_assert(t, rc == 51);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, !memcmp(str, "$!#", 3) && !memcmp(str+3, filler, 48));
|
||||
/* Do it again after position 0 */
|
||||
DO_E(rc, ungetc('#', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '#');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('!', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '!');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('$', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '$');
|
||||
ft_log_FILE(t, "", fp);
|
||||
/* Read them back as well as the second segment */
|
||||
DO_E(rc, fread(str, 1, 51, fp), t, "%d");
|
||||
ft_assert(t, rc == 51);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, !memcmp(str, "$!#", 3) && !memcmp(str+3, filler+16, 48));
|
||||
/* Push some characters but discard them by rewind() */
|
||||
DO_E(rc, ungetc('#', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '#');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fseek(fp, 0, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fread(str, 1, 48, fp), t, "%d");
|
||||
ft_assert(t, rc == 48);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, !memcmp(str, filler, 48));
|
||||
/* Discard buffered data by a write (nonstandard but supported) */
|
||||
DO_E(rc, fwrite(filler, 1, 48, fp), t, "%d");
|
||||
ft_assert(t, rc == 48);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fclose(fp), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
|
||||
/* Try ungetc() like previousy but with a non-buffered stream */
|
||||
DO_E(fp, fopen("ft_stdio.txt", "r+"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, setvbuf(fp, NULL, _IONBF, 0), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fseek(fp, 0, SEEK_END), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
DO_E(rc, ftell(fp), t, "%d");
|
||||
ft_assert(t, rc == 112);
|
||||
DO_E(rc, fseek(fp, 0, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
/* ungetc() some characters before position 0 */
|
||||
DO_E(rc, ungetc('#', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '#');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('!', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '!');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('$', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '$');
|
||||
ft_log_FILE(t, "", fp);
|
||||
/* Read them back along with some actual data */
|
||||
DO_E(rc, fread(str, 1, 51, fp), t, "%d");
|
||||
ft_assert(t, rc == 51);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, !memcmp(str, "$!#", 3) && !memcmp(str+3, filler, 48));
|
||||
/* Do it again after position 0 */
|
||||
DO_E(rc, ungetc('#', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '#');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('!', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '!');
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ungetc('$', fp), t, "'%c'");
|
||||
ft_assert(t, rc == '$');
|
||||
ft_log_FILE(t, "", fp);
|
||||
/* Read them back as well as the second segment */
|
||||
DO_E(rc, fread(str, 1, 51, fp), t, "%d");
|
||||
ft_assert(t, rc == 51);
|
||||
ft_log_FILE(t, "", fp);
|
||||
ft_assert(t, !memcmp(str, "$!#", 3) && !memcmp(str+3, filler, 48));
|
||||
DO_E(rc, fclose(fp), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
}
|
||||
|
||||
static void _ft_stdio_update_ungetc(ft_test *t)
|
||||
{
|
||||
gint_world_switch(GINT_CALL(_ft_stdio_update_ungetc_switch,
|
||||
(void *)t));
|
||||
}
|
||||
|
||||
ft_test ft_stdio_update_ungetc = {
|
||||
.name = "Update modes and ungetc()",
|
||||
.function = _ft_stdio_update_ungetc,
|
||||
};
|
||||
|
||||
static void _ft_stdio_append_switch(ft_test *t)
|
||||
{
|
||||
FILE *fp;
|
||||
int rc;
|
||||
char str[40];
|
||||
|
||||
/* Remove the file if it exists */
|
||||
DO_E(rc, remove("ft_append.txt"), t, "%d");
|
||||
ft_assert(t, rc == 0 || (rc == -1 && errno == ENOENT));
|
||||
|
||||
/* Append some data with mode a */
|
||||
DO_E(fp, fopen("ft_append.txt", "a"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fwrite("Line #1\n", 1, 8, fp), t, "%d");
|
||||
ft_assert(t, rc == 8);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fseek(fp, 0, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_assert(t, ftell(fp) == 0);
|
||||
DO_E(rc, fwrite("Line #2\n", 1, 8, fp), t, "%d");
|
||||
ft_assert(t, rc == 8);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ftell(fp), t, "%d");
|
||||
ft_assert(t, rc == 16);
|
||||
DO_E(rc, fclose(fp), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
|
||||
/* Append more with a+ */
|
||||
DO_E(fp, fopen("ft_append.txt", "a+"), t, "%p");
|
||||
ft_assert(t, fp != NULL);
|
||||
if(fp == NULL) return;
|
||||
DO_E(rc, fseek(fp, 0, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_assert(t, ftell(fp) == 0);
|
||||
DO_E(rc, fread(str, 1, 8, fp), t, "%d");
|
||||
ft_assert(t, rc == 8);
|
||||
ft_assert(t, ftell(fp) == 8);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fwrite(str, 1, 8, fp), t, "%d");
|
||||
ft_assert(t, rc == 8);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ftell(fp), t, "%d");
|
||||
ft_assert(t, rc == 24);
|
||||
DO_E(rc, fseek(fp, 8, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
DO_E(rc, fread(str, 1, 16, fp), t, "%d");
|
||||
ft_assert(t, rc == 16);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, fseek(fp, -8, SEEK_END), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
ft_assert(t, ftell(fp) == 16);
|
||||
DO_E(rc, fwrite(str, 1, 16, fp), t, "%d");
|
||||
ft_assert(t, rc == 16);
|
||||
ft_log_FILE(t, "", fp);
|
||||
DO_E(rc, ftell(fp), t, "%d");
|
||||
ft_assert(t, rc == 40);
|
||||
DO_E(rc, fseek(fp, 0, SEEK_SET), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
DO_E(rc, fread(str, 1, 40, fp), t, "%d");
|
||||
ft_assert(t, rc == 40);
|
||||
ft_assert(t, !memcmp(str,
|
||||
"Line #1\nLine #2\nLine #1\nLine #2\nLine #1\n", 40));
|
||||
DO_E(rc, fclose(fp), t, "%d");
|
||||
ft_assert(t, rc == 0);
|
||||
}
|
||||
|
||||
static void _ft_stdio_append(ft_test *t)
|
||||
{
|
||||
gint_world_switch(GINT_CALL(_ft_stdio_append_switch, (void *)t));
|
||||
}
|
||||
|
||||
ft_test ft_stdio_append = {
|
||||
.name = "Append modes",
|
||||
.function = _ft_stdio_append,
|
||||
};
|
||||
|
|
|
@ -25,8 +25,8 @@ static inline void ft_log_FILE(ft_test *t, char const *prefix, FILE *fp)
|
|||
fp->bufmode == _IOLBF ? "_IOLBF" :
|
||||
fp->bufmode == _IOFBF ? "_IOFBF" : "_???");
|
||||
|
||||
if(fp->bufmode != _IONBF) {
|
||||
ft_log(t, " %p/%d", fp->buf, fp->bufsize);
|
||||
if(fp->buf) {
|
||||
ft_log(t, " %s%d", fp->buf ? "" : "NULL/", fp->bufsize);
|
||||
|
||||
if(fp->bufpos == 0)
|
||||
ft_log(t, " EMPTY");
|
||||
|
@ -34,6 +34,9 @@ static inline void ft_log_FILE(ft_test *t, char const *prefix, FILE *fp)
|
|||
ft_log(t, " READ %d/%d", fp->bufpos, fp->bufread);
|
||||
else if(fp->bufdir == __FILE_BUF_WRITE)
|
||||
ft_log(t, " WRITE %d", fp->bufpos);
|
||||
|
||||
if(fp->bufungetc > 0)
|
||||
ft_log(t, " UNGETC %d", fp->bufungetc);
|
||||
}
|
||||
|
||||
ft_log(t, "}\n");
|
||||
|
|
Loading…
Reference in New Issue