ftell_ungetc.c
1 /* Thanks to the originator of Feedback FB8165838 / Radar 66131999 for 2 * writing the original version of this test! 3 */ 4 5 #include <darwintest.h> 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <stdio.h> 11 12 T_DECL(ftell_ungetc, "Test interactions of ftell and ungetc") 13 { 14 FILE *fp = stdin; 15 fp = fopen("assets/ftell_ungetc.txt", "rb"); 16 T_QUIET; T_ASSERT_NE(fp, (FILE*)NULL, "Open the file"); 17 18 /* Test ftell without having done any reads/writes */ 19 T_ASSERT_EQ(ftell(fp), 0L, "ftell without having done any reads/writes"); 20 21 /* Read one character */ 22 T_ASSERT_EQ(fgetc(fp), '/', "Read one charatcter"); 23 24 /* Check ftell again after one read */ 25 T_ASSERT_EQ(ftell(fp), 1L, "ftell after one read"); 26 27 /* Push back one character */ 28 T_ASSERT_EQ(ungetc('/', fp), '/', "push back one character"); 29 30 /* Check ftell again after pushing back one char */ 31 T_ASSERT_EQ(ftell(fp), 0L, "ftell after pushing back one char"); 32 33 /* Read it again */ 34 T_ASSERT_EQ(fgetc(fp), '/', "read pushed back character again"); 35 T_ASSERT_EQ(ftell(fp), 1L, "ftell after reading again"); 36 37 /* Seek and test ftell again */ 38 T_ASSERT_EQ(fseek(fp, 2, SEEK_SET), 0, "seek"); 39 T_ASSERT_EQ(ftell(fp), 2L, "ftell after seeking"); 40 41 /* Push back invalid char (EOF) */ 42 T_ASSERT_EQ(ungetc(EOF, fp), EOF, "push back invalid char"); 43 T_ASSERT_EQ(ftell(fp), 2L, "ftell after pushing invalid char, pos should not have changed"); 44 45 /* Read, push back different char, read again 46 * and check ftell. 47 * 48 * Cppreference: 49 * A successful call to ungetc on a text stream modifies 50 * the stream position indicator in unspecified manner but 51 * guarantees that after all pushed-back characters are 52 * retrieved with a read operation, the stream position 53 * indicator is equal to its value before ungetc. 54 */ 55 T_ASSERT_EQ(fgetc(fp), '-', "read another character"); 56 T_ASSERT_EQ(ftell(fp), 3L, "ftell after read"); 57 T_ASSERT_EQ(ungetc('A', fp), 'A', "push back a different character"); 58 T_ASSERT_EQ(fgetc(fp), 'A', "read back the different character"); 59 T_ASSERT_EQ(ftell(fp), 3L, "ftell after pushback and read back"); 60 61 /* Push back a non-read character and test ftell. 62 * 63 * According to POSIX: 64 * The file-position indicator is decremented by each 65 * successful call to ungetc(); 66 * 67 * Cppreference: 68 * A successful call to ungetc on a binary stream decrements 69 * the stream position indicator by one 70 */ 71 T_ASSERT_EQ(fgetc(fp), '+', "read another character"); 72 T_ASSERT_EQ(ungetc('A', fp), 'A', "push back a different character"); 73 T_EXPECTFAIL; T_ASSERT_EQ(ftell(fp), 3L, "ftell after pushback - EXPECTED FAIL rdar://66131999"); 74 }