#include #include #include #include #include #include #include #include struct format_test_cases { const char *format; const char *data; int expected_int; enum { T_INT, T_UINT, T_CHAR, T_NONE, } type; int ret; } formats[] = { {"%i", "0x420", 0x420, T_INT, 1}, {"%i", "0420", 0420, T_INT, 1}, {"%i", "420", 420, T_INT, 1}, {"%i", "-420", -420, T_INT, 1}, {"%d", "-12345", -12345, T_INT, 1}, {"%u", "69", 69, T_UINT, 1}, {"%u", "0420", 420, T_UINT, 1}, {"%o", "0420", 0420, T_UINT, 1}, {"%x", "0xCB7", 0xCB7, T_UINT, 1}, #ifndef USE_HOST_LIBC {"%b", "0b1011", 0b1011, T_UINT, 1}, {"%b", "0B1011", 0b1011, T_UINT, 1}, #endif {"%%", "%", 0, T_NONE, 0}, {"%c", " I am not a fan of this solution.", ' ', T_CHAR, 1}, {" %c", " CBT (capybara therapy)", 'C', T_CHAR, 1}, {"%d %d %d", " 111111 I<3Managarm 1234", 111111, T_UINT, 1}, {"%c %d", "C", 'C', T_CHAR, 1} }; #pragma GCC diagnostic ignored "-Wformat-security" static void test_matrix() { for(size_t i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) { struct format_test_cases *f = &formats[i]; int ret = -1; int data_int; unsigned int data_uint; char data_char; switch(f->type) { case T_INT: { ret = sscanf(f->data, f->format, &data_int); assert(data_int == f->expected_int); break; } case T_UINT: { ret = sscanf(f->data, f->format, &data_uint); assert(data_uint == (unsigned int) f->expected_int); break; } case T_CHAR: { ret = sscanf(f->data, f->format, &data_char); assert(data_char == (unsigned char) f->expected_int); break; } case T_NONE: { ret = sscanf(f->data, f->format); break; } } assert(ret == f->ret); } } int main() { { int x = 0; char buf[] = "12345"; sscanf(buf, "%d", &x); assert(x == 12345); } { char c; int n1; int n2; char buf[] = "z$ 7 5 440";; int count = sscanf(buf, "%*c%c %d %*d %d", &c, &n1, &n2); assert(count == 3); assert(c == '$'); assert(n1 == 7); assert(n2 == 440); } { // From dsda-doom char buf[] = "process_priority 0\n"; char def[80], strparm[128]; memset(def, '!', 80); memset(strparm, '!', 128); sscanf(buf, "%s %[^\n]\n", def, strparm); assert(!strcmp(def, "process_priority")); assert(!strcmp(strparm, "0")); } { char buf[] = "fffff100"; unsigned long y = 0; sscanf(buf, "%lx", &y); assert(y == 0xfffff100); } #if !defined(__i386__) && !defined(__m68k__) { char buf[] = "fffffffff100"; unsigned long y = 0; sscanf(buf, "%lx", &y); assert(y == 0xfffffffff100); } #endif { char buf[] = "410dc000"; unsigned long y = 0; sscanf(buf, "%lx", &y); assert(y == 0x410dc000); } { // From webkitgtk char buf[] = "MemTotal: 16299664 kB\n"; char token[51] = {0}; size_t amount = 0; int ret = sscanf(buf, "%50s%zukB", token, &amount); assert(ret == 2); assert(!strcmp(token, "MemTotal:")); assert(amount == 16299664); } { char buf[] = "SIGINT"; int sig; int ret = sscanf(buf, "%d", &sig); assert(!ret); } { char buf[50]; int ret = sscanf("", "%s", buf); assert(ret == EOF); } { char *str = NULL; int ret = sscanf("Managarm", "%ms", &str); assert(ret == 1); assert(str != NULL); assert(!strcmp(str, "Managarm")); free(str); } test_matrix(); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-zero-length" assert(sscanf("", "") == 0); #pragma GCC diagnostic pop assert(sscanf("", "a") == EOF); assert(sscanf(" \t\na", " a") == 0); assert(sscanf("a%", "a%%") == 0); assert(sscanf("ab", "abcd") == EOF); assert(sscanf("abab", "abcd") == 0); char char_value[8]; wchar_t wchar_value[8]; assert(sscanf("a", "%c", char_value) == 1); assert(char_value[0] == 'a'); assert(sscanf("a", "%lc", wchar_value) == 1); assert(wchar_value[0] == L'a'); assert(sscanf("hello", "%s", char_value) == 1); assert(strcmp(char_value, "hello") == 0); assert(sscanf("", "%s", char_value) == EOF); assert(sscanf(" ", "%s", char_value) == EOF); assert(sscanf(" a", "%sb", char_value) == 1); assert(sscanf("hello", "%ls", wchar_value) == 1); assert(wcscmp(wchar_value, L"hello") == 0); assert(sscanf("abcd", "%[ac]bcd", char_value) == 1); assert(strcmp(char_value, "a") == 0); assert(sscanf("abcd", "%l[ac]bcd", wchar_value) == 1); assert(wcscmp(wchar_value, L"a") == 0); assert(sscanf("aacd", "%[ac]bcd", char_value) == 1); assert(strcmp(char_value, "aac") == 0); assert(sscanf("aacd", "%[ac]bcd", char_value) == 1); assert(strcmp(char_value, "aac") == 0); assert(sscanf("]", "%[]]", char_value) == 1); assert(strcmp(char_value, "]") == 0); assert(sscanf("]", "%[^]]", char_value) == 0); assert(sscanf("abcd", "%[^ac]bcd", char_value) == 0); assert(sscanf("aacd", "%[^ac]bcd", char_value) == 0); assert(sscanf("aacd", "%[^ac]bcd", char_value) == 0); assert(sscanf("ddd", "%[^ac]bcd", char_value) == 1); assert(strcmp(char_value, "ddd") == 0); assert(sscanf("abcd", "%[0-9]", char_value) == 0); assert(sscanf("2a", "%[0-9]", char_value) == 1); assert(strcmp(char_value, "2") == 0); unsigned char uchar_value; signed char schar_value; unsigned short ushort_value; short short_value; unsigned int uint_value; int int_value; unsigned long ulong_value; long long_value; unsigned long long ulonglong_value; long long longlong_value; uintmax_t uintmax_value; intmax_t intmax_value; size_t size_value; ptrdiff_t ptrdiff_value; assert(sscanf("1234abc", "%d", &int_value) == 1); assert(int_value == 1234); assert(sscanf("123", "%hhd", &schar_value) == 1); assert(schar_value == 123); assert(sscanf("1234", "%hd", &short_value) == 1); assert(short_value == 1234); assert(sscanf("1234", "%ld", &long_value) == 1); assert(long_value == 1234); assert(sscanf("1234", "%lld", &longlong_value) == 1); assert(longlong_value == 1234); assert(sscanf("1234", "%jd", &intmax_value) == 1); assert(intmax_value == 1234); assert(sscanf("1234", "%zd", &size_value) == 1); assert(size_value == 1234); assert(sscanf("1234", "%td", &ptrdiff_value) == 1); assert(ptrdiff_value == 1234); assert(sscanf(" 1235abc", "%d", &int_value) == 1); assert(int_value == 1235); assert(sscanf("+1234abc", "%d", &int_value) == 1); assert(int_value == 1234); assert(sscanf("-1234abc", "%d", &int_value) == 1); assert(int_value == -1234); assert(sscanf("-abc", "%d", &int_value) == 0); assert(sscanf("-", "%d", &int_value) == 0); assert(sscanf("1234abc", "%i", &int_value) == 1); assert(int_value == 1234); assert(sscanf("123", "%hhi", &schar_value) == 1); assert(schar_value == 123); assert(sscanf("1234", "%hi", &short_value) == 1); assert(short_value == 1234); assert(sscanf("1234", "%li", &long_value) == 1); assert(long_value == 1234); assert(sscanf("1234", "%lli", &longlong_value) == 1); assert(longlong_value == 1234); assert(sscanf("1234", "%ji", &intmax_value) == 1); assert(intmax_value == 1234); assert(sscanf("1234", "%zi", &size_value) == 1); assert(size_value == 1234); assert(sscanf("1234", "%ti", &ptrdiff_value) == 1); assert(ptrdiff_value == 1234); assert(sscanf(" 1235abc", "%i", &int_value) == 1); assert(int_value == 1235); assert(sscanf("+1234abc", "%i", &int_value) == 1); assert(int_value == 1234); assert(sscanf("-1234abc", "%i", &int_value) == 1); assert(int_value == -1234); assert(sscanf("-abc", "%i", &int_value) == 0); assert(sscanf(" 0b1011", "%i", &int_value) == 1); assert(int_value == 0b1011); assert(sscanf(" 0B1010", "%i", &int_value) == 1); assert(int_value == 0b1010); assert(sscanf(" +0b1011", "%i", &int_value) == 1); assert(int_value == 0b1011); assert(sscanf(" -0b1111", "%i", &int_value) == 1); assert(int_value == -0b1111); assert(sscanf(" 01234", "%i", &int_value) == 1); assert(int_value == 01234); assert(sscanf(" +01234", "%i", &int_value) == 1); assert(int_value == 01234); assert(sscanf(" -01234", "%i", &int_value) == 1); assert(int_value == -01234); assert(sscanf(" 0xab12", "%i", &int_value) == 1); assert(int_value == 0xAB12); assert(sscanf(" 0xAB12", "%i", &int_value) == 1); assert(int_value == 0xAB12); assert(sscanf(" 0Xab12", "%i", &int_value) == 1); assert(int_value == 0xAB12); assert(sscanf(" +0xab12", "%i", &int_value) == 1); assert(int_value == 0xAB12); assert(sscanf(" -0xab12", "%i", &int_value) == 1); assert(int_value == -0xAB12); assert(sscanf("1234abc", "%u", &uint_value) == 1); assert(uint_value == 1234); assert(sscanf("123", "%hhu", &uchar_value) == 1); assert(uchar_value == 123); assert(sscanf("1234", "%hu", &ushort_value) == 1); assert(ushort_value == 1234); assert(sscanf("1234", "%lu", &ulong_value) == 1); assert(ulong_value == 1234); assert(sscanf("1234", "%llu", &ulonglong_value) == 1); assert(ulonglong_value == 1234); assert(sscanf("1234", "%ju", &uintmax_value) == 1); assert(uintmax_value == 1234); assert(sscanf("1234", "%zu", &size_value) == 1); assert(size_value == 1234); assert(sscanf("1234", "%tu", &ptrdiff_value) == 1); assert(ptrdiff_value == 1234); assert(sscanf(" 1235abc", "%u", &int_value) == 1); assert(int_value == 1235); assert(sscanf("+1234abc", "%u", &int_value) == 1); assert(int_value == 1234); assert(sscanf("-1234abc", "%u", &int_value) == 1); assert(int_value == -1234); assert(sscanf("-abc", "%d", &int_value) == 0); assert(sscanf(" 12345", "%o", &int_value) == 1); assert(int_value == 012345); assert(sscanf("12", "%hho", &uchar_value) == 1); assert(uchar_value == 012); assert(sscanf("1234", "%ho", &ushort_value) == 1); assert(ushort_value == 01234); assert(sscanf("1234", "%lo", &ulong_value) == 1); assert(ulong_value == 01234); assert(sscanf("1234", "%llo", &ulonglong_value) == 1); assert(ulonglong_value == 01234); assert(sscanf("1234", "%jo", &uintmax_value) == 1); assert(uintmax_value == 01234); assert(sscanf("1234", "%zo", &size_value) == 1); assert(size_value == 01234); assert(sscanf("1234", "%to", &ptrdiff_value) == 1); assert(ptrdiff_value == 01234); assert(sscanf(" 01234", "%o", &int_value) == 1); assert(int_value == 01234); assert(sscanf(" +01234", "%o", &int_value) == 1); assert(int_value == 01234); assert(sscanf(" -01234", "%o", &int_value) == 1); assert(int_value == -01234); assert(sscanf(" 1234ab", "%x", &int_value) == 1); assert(int_value == 0x1234AB); assert(sscanf("12", "%hhx", &uchar_value) == 1); assert(uchar_value == 0x12); assert(sscanf("1234", "%hx", &ushort_value) == 1); assert(ushort_value == 0x1234); assert(sscanf("1234", "%lx", &ulong_value) == 1); assert(ulong_value == 0x1234); assert(sscanf("1234", "%llx", &ulonglong_value) == 1); assert(ulonglong_value == 0x1234); assert(sscanf("1234", "%jx", &uintmax_value) == 1); assert(uintmax_value == 0x1234); assert(sscanf("1234", "%zx", &size_value) == 1); assert(size_value == 0x1234); assert(sscanf("1234", "%tx", &ptrdiff_value) == 1); assert(ptrdiff_value == 0x1234); assert(sscanf(" 1234ABC", "%x", &int_value) == 1); assert(int_value == 0x1234ABC); assert(sscanf(" 1234ab", "%X", &int_value) == 1); assert(int_value == 0x1234AB); assert(sscanf(" 0x1234", "%x", &int_value) == 1); assert(int_value == 0x1234); assert(sscanf(" 0x1234A", "%x", &int_value) == 1); assert(int_value == 0x1234A); assert(sscanf(" 0X1234AB", "%x", &int_value) == 1); assert(int_value == 0x1234AB); assert(sscanf(" +0x1234", "%x", &int_value) == 1); assert(int_value == 0x1234); assert(sscanf(" -0x1234", "%x", &int_value) == 1); assert(int_value == -0x1234); assert(sscanf("abc", "abc%n", &int_value) == 0); assert(int_value == 3); assert(sscanf("1234", "1234%hhn", &uchar_value) == 0); assert(uchar_value == 4); assert(sscanf("1234", "1234%hn", &ushort_value) == 0); assert(ushort_value == 4); assert(sscanf("1234", "1234%ln", &ulong_value) == 0); assert(ulong_value == 4); assert(sscanf("1234", "1234%lln", &ulonglong_value) == 0); assert(ulonglong_value == 4); assert(sscanf("1234", "1234%jn", &uintmax_value) == 0); assert(uintmax_value == 4); assert(sscanf("1234", "1234%zn", &size_value) == 0); assert(size_value == 4); assert(sscanf("1234", "1234%tn", &ptrdiff_value) == 0); assert(ptrdiff_value == 4); assert(sscanf("abcd", "ab%nc%c", &int_value, char_value) == 1); assert(int_value == 2); assert(char_value[0] == 'd'); float float_value; double double_value; long double long_double_value; (void)float_value; (void)double_value; (void)long_double_value; /*assert(sscanf("1.123", "%a", &float_value) == 1); assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01); assert(sscanf("1.123", "%la", &double_value) == 1); assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01); assert(sscanf("1.123", "%La", &long_double_value) == 1); assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01); assert(sscanf("1.1234", "%A", &float_value) == 1); assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01); assert(sscanf("1.123", "%e", &float_value) == 1); assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01); assert(sscanf("1.123", "%le", &double_value) == 1); assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01); assert(sscanf("1.123", "%Le", &long_double_value) == 1); assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01); assert(sscanf("1.1234", "%E", &float_value) == 1); assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01); assert(sscanf("1.123", "%f", &float_value) == 1); assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01); assert(sscanf("1.123", "%lf", &double_value) == 1); assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01); assert(sscanf("1.123", "%Lf", &long_double_value) == 1); assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01); assert(sscanf("1.1234", "%F", &float_value) == 1); assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01); assert(sscanf("1.123", "%g", &float_value) == 1); assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01); assert(sscanf("1.123", "%lg", &double_value) == 1); assert(double_value >= 1.123 - 0.01 && double_value <= 1.123 + 0.01); assert(sscanf("1.123", "%Lg", &long_double_value) == 1); assert(long_double_value >= 1.123L - 0.01 && long_double_value <= 1.123L + 0.01); assert(sscanf("1.1234", "%G", &float_value) == 1); assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01); assert(sscanf("+1.1234", "%f", &float_value) == 1); assert(float_value >= 1.1234f - 0.01 && float_value <= 1.1234f + 0.01); assert(sscanf("-1.1234", "%f", &float_value) == 1); assert(float_value >= -1.1234f - 0.01 && float_value <= -1.1234f + 0.01); assert(sscanf("1.1234e3", "%f", &float_value) == 1); assert(float_value >= 1.1234E3f - 0.01 && float_value <= 1.1234E3f + 0.01); assert(sscanf("1.1234E3", "%f", &float_value) == 1); assert(float_value >= 1.1234E3f - 0.01 && float_value <= 1.1234E3f + 0.01); assert(sscanf("0x1234", "%f", &float_value) == 1); assert(float_value >= 0x1234P0f - 0.01 && float_value <= 0x1234P0f + 0.01); assert(sscanf("0X1234", "%f", &float_value) == 1); assert(float_value >= 0x1234P0f - 0.01 && float_value <= 0x1234P0f + 0.01); assert(sscanf("0x1.1234", "%f", &float_value) == 1); assert(float_value >= 0x1.1234P0 - 0.01 && float_value <= 0x1.1234P0 + 0.01); assert(sscanf("0x1.abcdP3", "%f", &float_value) == 1); assert(float_value >= 0x1.ABCDP3 - 0.01 && float_value <= 0x1.ABCDP3 + 0.01); assert(sscanf("0x1.abcdP+3", "%f", &float_value) == 1); assert(float_value >= 0x1.ABCDP3 - 0.01 && float_value <= 0x1.ABCDP3 + 0.01); assert(sscanf("0x1.abcdP-3", "%f", &float_value) == 1); assert(float_value >= 0x1.ABCDP-3 - 0.01 && float_value <= 0x1.ABCDP-3 + 0.01); assert(sscanf("0x1.AbCdP-3", "%f", &float_value) == 1); assert(float_value >= 0x1.ABCDP-3 - 0.01 && float_value <= 0x1.ABCDP-3 + 0.01); assert(sscanf("inf", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("InF", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("+inf", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("-inf", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("INF", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("infinity", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("INFINITY", "%f", &float_value) == 1); assert(isinf(float_value)); assert(sscanf("nan", "%f", &float_value) == 1); assert(isnan(float_value)); assert(sscanf("NaN", "%f", &float_value) == 1); assert(isnan(float_value)); assert(sscanf("+nan", "%f", &float_value) == 1); assert(isnan(float_value)); assert(sscanf("-nan", "%f", &float_value) == 1); assert(isnan(float_value)); assert(sscanf("0xhello", "%f", &float_value) == 0); assert(sscanf("0x1hello", "%f", &float_value) == 1); assert(float_value >= 0x1P0f - 0.01 && float_value <= 0x1P0f + 0.01); assert(sscanf("ab1.1234", "%f", &float_value) == 0); assert(sscanf(" 1.123", "%f", &float_value) == 1); assert(float_value >= 1.123f - 0.01 && float_value <= 1.123f + 0.01);*/ void* ptr; assert(sscanf("hello", "%p", &ptr) == 0); #if UINTPTR_MAX == UINT64_MAX assert(sscanf("0xabcdef12abcdef12", "%p", &ptr) == 1); assert(ptr == (void*)0xabcdef12abcdef12); #else assert(sscanf("0xabcdef12", "%p", &ptr) == 1); assert(ptr == (void*)0xabcdef12); #endif assert(sscanf("a", "%*c") == 0); char_value[2] = 'q'; assert(sscanf("abcd", "%2c", char_value) == 1); assert(char_value[2] == 'q'); char_value[2] = 0; assert(strcmp(char_value, "ab") == 0); assert(sscanf("cdef", "%2s", char_value) == 1); assert(strcmp(char_value, "cd") == 0); assert(sscanf("c def", "%2s", char_value) == 1); assert(strcmp(char_value, "c") == 0); assert(sscanf("aacd", "%2[ac]", char_value) == 1); assert(strcmp(char_value, "aa") == 0); return 0; }