145 lines
5.5 KiB
C
145 lines
5.5 KiB
C
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
│ │
|
|
│ This program is free software; you can redistribute it and/or modify │
|
|
│ it under the terms of the GNU General Public License as published by │
|
|
│ the Free Software Foundation; version 2 of the License. │
|
|
│ │
|
|
│ This program is distributed in the hope that it will be useful, but │
|
|
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
|
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
|
│ General Public License for more details. │
|
|
│ │
|
|
│ You should have received a copy of the GNU General Public License │
|
|
│ along with this program; if not, write to the Free Software │
|
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
|
│ 02110-1301 USA │
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
#include "libc/bits/bits.h"
|
|
#include "libc/errno.h"
|
|
#include "libc/fmt/fmt.h"
|
|
#include "libc/limits.h"
|
|
#include "libc/mem/mem.h"
|
|
#include "libc/testlib/testlib.h"
|
|
|
|
#define sscanf1(STR, FMT) \
|
|
({ \
|
|
errno = 0; \
|
|
intmax_t x = 0; \
|
|
EXPECT_EQ(1, sscanf(STR, FMT, &x)); \
|
|
x; \
|
|
})
|
|
|
|
TEST(sscanf, testMultiple) {
|
|
int a, b, c;
|
|
ASSERT_EQ(3, sscanf("123 123 123", "%d %x %o", &a, &b, &c));
|
|
EXPECT_EQ(123, a);
|
|
EXPECT_EQ(0x123, b);
|
|
EXPECT_EQ(0123, c);
|
|
}
|
|
|
|
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"));
|
|
}
|
|
|
|
TEST(sscanf, testHex) {
|
|
EXPECT_EQ(0x123, sscanf1("123", "%x"));
|
|
EXPECT_EQ(0x123, sscanf1("0x123", "%x"));
|
|
EXPECT_EQ(0x123, sscanf1("0123", "%x"));
|
|
EXPECT_EQ(INTMAX_MAX,
|
|
sscanf1("170141183460469231731687303715884105727", "%jd"));
|
|
EXPECT_EQ(INTMAX_MIN,
|
|
sscanf1("-170141183460469231731687303715884105728", "%jd"));
|
|
EXPECT_EQ(UINTMAX_MAX, sscanf1("0xffffffffffffffffffffffffffffffff", "%jx"));
|
|
}
|
|
|
|
TEST(sscanf, testOctal) {
|
|
EXPECT_EQ(0123, sscanf1("123", "%o"));
|
|
EXPECT_EQ(0123, sscanf1("0123", "%o"));
|
|
}
|
|
|
|
TEST(sscanf, testNonDirectiveCharacterMatching) {
|
|
EXPECT_EQ(0, sscanf("", ""));
|
|
EXPECT_EQ(0, sscanf("%", "%%"));
|
|
}
|
|
|
|
TEST(sscanf, testCharacter) {
|
|
char c = 0;
|
|
EXPECT_EQ(1, sscanf("a", "%c", &c));
|
|
EXPECT_EQ('a', c);
|
|
}
|
|
|
|
TEST(sscanf, testStringBuffer) {
|
|
char s1[32], s2[32];
|
|
ASSERT_EQ(2, sscanf("abc xyz", "%s %s", s1, s2));
|
|
EXPECT_STREQ("abc", &s1[0]);
|
|
EXPECT_STREQ("xyz", &s2[0]);
|
|
}
|
|
|
|
TEST(sscanf, testStringBuffer_gothicUtf8ToUtf8_roundTrips) {
|
|
char s1[64], s2[64];
|
|
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63s %63s", s1, s2));
|
|
EXPECT_STREQ("𐌰𐌱𐌲𐌳", s1);
|
|
EXPECT_STREQ("𐌴𐌵𐌶𐌷", s2);
|
|
}
|
|
|
|
TEST(sscanf, testStringBuffer_gothicUtf8ToUtf16) {
|
|
char16_t s1[64], s2[64];
|
|
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63hs %63hs", s1, s2));
|
|
EXPECT_STREQ(u"𐌰𐌱𐌲𐌳", s1);
|
|
EXPECT_STREQ(u"𐌴𐌵𐌶𐌷", s2);
|
|
}
|
|
|
|
TEST(sscanf, testStringBuffer_gothicUtf8ToUtf32) {
|
|
wchar_t s1[64], s2[64];
|
|
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63ls %63ls", s1, s2));
|
|
EXPECT_STREQ(L"𐌰𐌱𐌲𐌳", s1);
|
|
EXPECT_STREQ(L"𐌴𐌵𐌶𐌷", s2);
|
|
}
|
|
|
|
TEST(sscanf, testStringBuffer_allocatingBehavior) {
|
|
char *s1, *s2;
|
|
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%ms %ms", &s1, &s2));
|
|
EXPECT_STREQ("𐌰𐌱𐌲𐌳", s1);
|
|
EXPECT_STREQ("𐌴𐌵𐌶𐌷", s2);
|
|
free(s1);
|
|
free(s2);
|
|
}
|
|
|
|
TEST(sscanf, testPracticalBusinessApplication) {
|
|
unsigned start, stop;
|
|
char width;
|
|
ASSERT_EQ(1, sscanf("0BF3..", "%x", &start));
|
|
EXPECT_EQ(0x0BF3, start);
|
|
ASSERT_EQ(3, sscanf("0BF3..0BF8;N # So [6] TAMIL DAY SIGN",
|
|
"%x..%x;%c", &start, &stop, &width));
|
|
EXPECT_EQ(0x0BF3, start);
|
|
EXPECT_EQ(0x0BF8, stop);
|
|
EXPECT_EQ('N', width);
|
|
}
|
|
|
|
TEST(sscanf, socketListenUri) {
|
|
char proto[4];
|
|
unsigned char ip4[4];
|
|
uint16_t port;
|
|
ASSERT_EQ(6, sscanf("tcp:127.0.0.1:31337", "%3s:%hhu.%hhu.%hhu.%hhu:%hu",
|
|
proto, &ip4[0], &ip4[1], &ip4[2], &ip4[3], &port));
|
|
ASSERT_STREQ("tcp", proto);
|
|
ASSERT_EQ(127, ip4[0]);
|
|
ASSERT_EQ(0, ip4[1]);
|
|
ASSERT_EQ(0, ip4[2]);
|
|
ASSERT_EQ(1, ip4[3]);
|
|
ASSERT_EQ(31337, port);
|
|
}
|
|
|
|
TEST(sscanf, testDiscard_notIncludedInCount) {
|
|
char buf[8];
|
|
ASSERT_EQ(1, sscanf("hello there", "%*s %8s", buf));
|
|
EXPECT_STREQ("there", buf);
|
|
}
|