Get GNU GMP test suite fully passing

- Fix stdio fmemopen() buffer behaviors
- Fix scanf() to return EOF when appropriate
- Prefer fseek/ftell names over fseeko/ftello
- Ensure locale field is always set in the TIB
- Fix recent regression in vfprintf() return count
- Make %n directive in scanf() have standard behavior
This commit is contained in:
Justine Tunney 2023-08-21 09:00:40 -07:00
parent 755ae64e73
commit 63a1636e1f
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
20 changed files with 228 additions and 51 deletions

View file

@ -18,6 +18,7 @@
*/
#include "libc/calls/calls.h"
#include "libc/mem/gc.h"
#include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
@ -28,7 +29,7 @@
TEST(fgetln, test) {
FILE *f;
f = fmemopen(_gc(strdup(kHyperion)), kHyperionSize, "r+");
f = fmemopen(gc(strdup(kHyperion)), kHyperionSize, "r+");
EXPECT_STREQ("The fall of Hyperion - a Dream\n", fgetln(f, 0));
EXPECT_STREQ("John Keats\n", fgetln(f, 0));
EXPECT_STREQ("\n", fgetln(f, 0));
@ -81,7 +82,7 @@ TEST(fgetln, testReadingFromStdin_doesntLeakMemory) {
}
BENCH(fgetln, bench) {
FILE *f = fmemopen(_gc(strdup(kHyperion)), kHyperionSize, "r+");
FILE *f = fmemopen(gc(strdup(kHyperion)), kHyperionSize, "r+");
EZBENCH2("fgetln", donothing, fgetln(f, 0));
EZBENCH2("xgetline", donothing, free(xgetline(f)));
fclose(f);

View file

@ -16,7 +16,12 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/stdio/temp.h"
#include "libc/testlib/testlib.h"
TEST(fmemopen, testWriteRewindRead) {
@ -30,10 +35,43 @@ TEST(fmemopen, testWriteRewindRead) {
fclose(f);
}
/* TEST(fmemopen, testWriteRead_readsNothingButNotEof) { */
/* char c; */
/* FILE *f; */
/* f = fmemopen(NULL, BUFSIZ, "w+"); */
/* EXPECT_EQ(1, fwrite("c", 1, 1, f)); */
/* EXPECT_EQ(0, fread(&c, 1, 1, f)); */
/* } */
TEST(fmemopen_fprintf, test) {
FILE *f = fmemopen(NULL, BUFSIZ, "w+");
EXPECT_EQ(1, fprintf(f, "%ld", 0L));
rewind(f);
char buf[8] = {0};
EXPECT_EQ(1, fread(&buf, 1, 8, f));
EXPECT_STREQ("0", buf);
fclose(f);
}
TEST(fmemopen, seekEofRead) {
FILE *f = fmemopen("x", 1, "r+");
ASSERT_SYS(EINVAL, -1, fseek(f, -1, SEEK_SET));
ASSERT_SYS(EINVAL, -1, fseek(f, +1, SEEK_END));
ASSERT_EQ(0, fseek(f, 0, SEEK_END));
ASSERT_FALSE(feof(f));
ASSERT_EQ(-1, fgetc(f));
ASSERT_TRUE(feof(f));
fclose(f);
}
TEST(tmpfile_fprintf, test) {
FILE *f = tmpfile();
EXPECT_EQ(1, fprintf(f, "%ld", 0L));
rewind(f);
char buf[8] = {0};
EXPECT_EQ(1, fread(&buf, 1, 8, f));
EXPECT_STREQ("0", buf);
fclose(f);
}
TEST(fmemopen, small) {
FILE *f = fmemopen(gc(malloc(1)), 1, "w+");
EXPECT_EQ(3, fprintf(f, "%ld", 123L));
rewind(f);
char buf[8] = {0};
EXPECT_EQ(1, fread(&buf, 1, 8, f));
EXPECT_STREQ("1", buf);
fclose(f);
}

View file

@ -17,8 +17,8 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/mem/mem.h"
#include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"

View file

@ -42,7 +42,6 @@ TEST(sscanf, testMultiple) {
TEST(sscanf, testDecimal) {
EXPECT_EQ(123, sscanf1("123", "%d"));
EXPECT_EQ(123, sscanf1("123", "%n"));
EXPECT_EQ(123, sscanf1("123", "%u"));
EXPECT_EQ((uint32_t)-123, sscanf1("-123", "%d"));
}
@ -258,3 +257,30 @@ TEST(sscanf, test0) {
ASSERT_EQ(sscanf("0", "%b", &v), 1);
ASSERT_EQ(v, 0);
}
TEST(sscanf, n) {
int x, y;
EXPECT_EQ(1, sscanf("7 2 3 4", "%d%n", &x, &y));
EXPECT_EQ(7, x);
EXPECT_EQ(1, y);
}
TEST(sscanf, eofForNoMatching) {
int y = 666;
char x[8] = "hi";
EXPECT_EQ(-1, sscanf(" ", "%s%n", &x, &y));
EXPECT_STREQ("hi", x);
EXPECT_EQ(666, y);
}
TEST(sscanf, eofConditions) {
int x = 666;
EXPECT_EQ(-1, sscanf("", "%d", &x));
EXPECT_EQ(666, x);
EXPECT_EQ(-1, sscanf(" ", "%d", &x));
EXPECT_EQ(666, x);
EXPECT_EQ(-1, sscanf("123", "%*d%d", &x));
EXPECT_EQ(666, x);
EXPECT_EQ(-1, sscanf("123", "%*d%n", &x));
EXPECT_EQ(666, x);
}