Index: uspace/lib/c/generic/stdio/scanf.c
===================================================================
--- uspace/lib/c/generic/stdio/scanf.c	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/c/generic/stdio/scanf.c	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -624,5 +624,5 @@
 	v = 0;
 	do {
-		digit = digit_value(c); // XXX
+		digit = digit_value(c);
 		if (digit >= base)
 			break;
@@ -1266,5 +1266,5 @@
 }
 
-int xxvfscanf(FILE *f, const char *fmt, va_list ap)
+int vfscanf(FILE *f, const char *fmt, va_list ap)
 {
 	const char *cp;
@@ -1323,5 +1323,5 @@
 }
 
-int xxfscanf(FILE *f, const char *fmt, ...)
+int fscanf(FILE *f, const char *fmt, ...)
 {
 	va_list args;
@@ -1329,5 +1329,5 @@
 
 	va_start(args, fmt);
-	rc = xxvfscanf(f, fmt, args);
+	rc = vfscanf(f, fmt, args);
 	va_end(args);
 
@@ -1335,10 +1335,10 @@
 }
 
-int xxvscanf(const char *fmt, va_list ap)
-{
-	return xxvfscanf(stdin, fmt, ap);
-}
-
-int xxscanf(const char *fmt, ...)
+int vscanf(const char *fmt, va_list ap)
+{
+	return vfscanf(stdin, fmt, ap);
+}
+
+int scanf(const char *fmt, ...)
 {
 	va_list args;
@@ -1346,5 +1346,5 @@
 
 	va_start(args, fmt);
-	rc = xxvscanf(fmt, args);
+	rc = vscanf(fmt, args);
 	va_end(args);
 
Index: uspace/lib/c/generic/stdio/sscanf.c
===================================================================
--- uspace/lib/c/generic/stdio/sscanf.c	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/c/generic/stdio/sscanf.c	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -40,13 +40,13 @@
 #include "../private/sstream.h"
 
-int xxvsscanf(const char *s, const char *fmt, va_list ap)
+int vsscanf(const char *s, const char *fmt, va_list ap)
 {
 	FILE f;
 
 	__sstream_init(s, &f);
-	return xxvfscanf(&f, fmt, ap);
+	return vfscanf(&f, fmt, ap);
 }
 
-int xxsscanf(const char *s, const char *fmt, ...)
+int sscanf(const char *s, const char *fmt, ...)
 {
 	va_list args;
@@ -54,5 +54,5 @@
 
 	va_start(args, fmt);
-	rc = xxvsscanf(s, fmt, args);
+	rc = vsscanf(s, fmt, args);
 	va_end(args);
 
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/c/include/stdio.h	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -101,10 +101,11 @@
 extern int vsnprintf(char *, size_t, const char *, va_list);
 
-extern int xxscanf(const char *, ...);
-extern int xxvscanf(const char *, va_list);
-extern int xxfscanf(FILE *, const char *, ...);
-extern int xxvfscanf(FILE *, const char *, va_list);
-extern int xxsscanf(const char *, const char *, ...);
-extern int xxvsscanf(const char *, const char *, va_list);
+/* Formatted input */
+extern int scanf(const char *, ...);
+extern int vscanf(const char *, va_list);
+extern int fscanf(FILE *, const char *, ...);
+extern int vfscanf(FILE *, const char *, va_list);
+extern int sscanf(const char *, const char *, ...);
+extern int vsscanf(const char *, const char *, va_list);
 
 /* File stream functions */
Index: uspace/lib/c/test/stdio/scanf.c
===================================================================
--- uspace/lib/c/test/stdio/scanf.c	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/c/test/stdio/scanf.c	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -55,5 +55,5 @@
 
 	/* Empty format string */
-	rc = xxsscanf("42", "");
+	rc = sscanf("42", "");
 	PCUT_ASSERT_INT_EQUALS(0, rc);
 }
@@ -65,5 +65,5 @@
 
 	/* Decimal integer */
-	rc = xxsscanf("42", "%d", &i);
+	rc = sscanf("42", "%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -76,5 +76,5 @@
 
 	/* Two integers */
-	rc = xxsscanf("42 43", "%d%d", &i, &j);
+	rc = sscanf("42 43", "%d%d", &i, &j);
 	PCUT_ASSERT_INT_EQUALS(2, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -88,5 +88,5 @@
 
 	/* Decimal signed char */
-	rc = xxsscanf("42", "%hhd", &sc);
+	rc = sscanf("42", "%hhd", &sc);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(sc == 42);
@@ -99,5 +99,5 @@
 
 	/* Decimal short */
-	rc = xxsscanf("42", "%hd", &si);
+	rc = sscanf("42", "%hd", &si);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(si == 42);
@@ -110,5 +110,5 @@
 
 	/* Decimal long */
-	rc = xxsscanf("42", "%ld", &li);
+	rc = sscanf("42", "%ld", &li);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(li == 42);
@@ -121,5 +121,5 @@
 
 	/* Decimal long long */
-	rc = xxsscanf("42", "%lld", &lli);
+	rc = sscanf("42", "%lld", &lli);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(lli == 42);
@@ -132,5 +132,5 @@
 
 	/* Decimal intmax_t */
-	rc = xxsscanf("42", "%jd", &imax);
+	rc = sscanf("42", "%jd", &imax);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(imax == 42);
@@ -143,5 +143,5 @@
 
 	/* Decimal size_t-sized */
-	rc = xxsscanf("42", "%zd", &szi);
+	rc = sscanf("42", "%zd", &szi);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(szi == 42);
@@ -154,5 +154,5 @@
 
 	/* Decimal ptrdiff_t-sized */
-	rc = xxsscanf("42", "%td", &pdi);
+	rc = sscanf("42", "%td", &pdi);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(pdi == 42);
@@ -165,5 +165,5 @@
 
 	/* Decimal integer followed by hexadecimal digit */
-	rc = xxsscanf("42a", "%d", &i);
+	rc = sscanf("42a", "%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -176,5 +176,5 @@
 
 	/* Decimal integer - detect no prefix */
-	rc = xxsscanf("42", "%i", &i);
+	rc = sscanf("42", "%i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -187,5 +187,5 @@
 
 	/* Prefixed octal integer followed by decimal digit */
-	rc = xxsscanf("019", "%i", &i);
+	rc = sscanf("019", "%i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 1);
@@ -198,5 +198,5 @@
 
 	/* Prefixed hexadecimal integer followed by other character */
-	rc = xxsscanf("0xag", "%i", &i);
+	rc = sscanf("0xag", "%i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 10);
@@ -209,5 +209,5 @@
 
 	/* Decimal integer with '+' sign */
-	rc = xxsscanf("+42", "%d", &i);
+	rc = sscanf("+42", "%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -220,5 +220,5 @@
 
 	/* Decimal integer with '-' sign */
-	rc = xxsscanf("-42", "%d", &i);
+	rc = sscanf("-42", "%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == -42);
@@ -231,5 +231,5 @@
 
 	/* Hexadecimal integer with prefix and '-' sign */
-	rc = xxsscanf("-0xa", "%i", &i);
+	rc = sscanf("-0xa", "%i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == -10);
@@ -242,5 +242,5 @@
 
 	/* Decimal unsigned integer */
-	rc = xxsscanf("42", "%u", &u);
+	rc = sscanf("42", "%u", &u);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(u == 42);
@@ -253,5 +253,5 @@
 
 	/* Decimal unsigned char */
-	rc = xxsscanf("42", "%hhu", &uc);
+	rc = sscanf("42", "%hhu", &uc);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(uc == 42);
@@ -264,5 +264,5 @@
 
 	/* Decimal unsigned short */
-	rc = xxsscanf("42", "%hu", &su);
+	rc = sscanf("42", "%hu", &su);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(su == 42);
@@ -275,5 +275,5 @@
 
 	/* Decimal unsigned long */
-	rc = xxsscanf("42", "%lu", &lu);
+	rc = sscanf("42", "%lu", &lu);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(lu == 42);
@@ -286,5 +286,5 @@
 
 	/* Decimal unsigned long long */
-	rc = xxsscanf("42", "%llu", &llu);
+	rc = sscanf("42", "%llu", &llu);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(llu == 42);
@@ -297,5 +297,5 @@
 
 	/* Decimal uintmax_t */
-	rc = xxsscanf("42", "%ju", &umax);
+	rc = sscanf("42", "%ju", &umax);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(umax == 42);
@@ -308,5 +308,5 @@
 
 	/* Decimal size_t */
-	rc = xxsscanf("42", "%zu", &szu);
+	rc = sscanf("42", "%zu", &szu);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(szu == 42);
@@ -319,5 +319,5 @@
 
 	/* Decimal ptrdiff_t-sized unsigned int*/
-	rc = xxsscanf("42", "%tu", &pdu);
+	rc = sscanf("42", "%tu", &pdu);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(pdu == 42);
@@ -330,5 +330,5 @@
 
 	/* Octal unsigned integer */
-	rc = xxsscanf("52", "%o", &u);
+	rc = sscanf("52", "%o", &u);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(u == 052);
@@ -341,5 +341,5 @@
 
 	/* Hexadecimal unsigned integer */
-	rc = xxsscanf("2a", "%x", &u);
+	rc = sscanf("2a", "%x", &u);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(u == 0x2a);
@@ -352,5 +352,5 @@
 
 	/* Hexadecimal unsigned integer unsing alternate specifier */
-	rc = xxsscanf("2a", "%X", &u);
+	rc = sscanf("2a", "%X", &u);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(u == 0x2a);
@@ -363,9 +363,21 @@
 
 	/* Uppercase hexadecimal unsigned integer */
-	rc = xxsscanf("2A", "%x", &u);
+	rc = sscanf("2A", "%x", &u);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(u == 0x2a);
 }
 
+PCUT_TEST(hex_not_match_0x)
+{
+	int rc;
+	unsigned u;
+
+	/* Make sure %x does not match 0x prefix */
+	rc = sscanf("0x1", "%x", &u);
+
+	PCUT_ASSERT_INT_EQUALS(1, rc);
+	PCUT_ASSERT_TRUE(u == 0);
+}
+
 PCUT_TEST(skipws)
 {
@@ -374,5 +386,5 @@
 
 	/* Skipping whitespace */
-	rc = xxsscanf(" \t\n42", "%d", &i);
+	rc = sscanf(" \t\n42", "%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -385,5 +397,5 @@
 
 	/* Percentile conversion */
-	rc = xxsscanf(" \t\n%42", "%%%d", &i);
+	rc = sscanf(" \t\n%42", "%%%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -396,5 +408,5 @@
 
 	/* Matching specific character */
-	rc = xxsscanf("x42", "x%d", &i);
+	rc = sscanf("x42", "x%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -407,5 +419,5 @@
 
 	/* Matching specific character should not skip whitespace */
-	rc = xxsscanf(" x42", "x%d", &i);
+	rc = sscanf(" x42", "x%d", &i);
 	PCUT_ASSERT_INT_EQUALS(0, rc);
 }
@@ -417,5 +429,5 @@
 
 	/* Skipping whitespace + match specific character */
-	rc = xxsscanf(" x42", "\t\nx%d", &i);
+	rc = sscanf(" x42", "\t\nx%d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -428,5 +440,5 @@
 
 	/* Decimal with limited, but sufficient width */
-	rc = xxsscanf("42", "%2d", &i);
+	rc = sscanf("42", "%2d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 42);
@@ -439,5 +451,5 @@
 
 	/* Decimal with limited, smaller width */
-	rc = xxsscanf("42", "%1d", &i);
+	rc = sscanf("42", "%1d", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 4);
@@ -450,5 +462,5 @@
 
 	/* Integer with hex prefix, format with limited, sufficient width */
-	rc = xxsscanf("0x1", "%3i", &i);
+	rc = sscanf("0x1", "%3i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 1);
@@ -461,5 +473,5 @@
 
 	/* Integer with hex prefix, format with limited, smaller width */
-	rc = xxsscanf("0x1", "%2i", &i);
+	rc = sscanf("0x1", "%2i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 0);
@@ -472,5 +484,5 @@
 
 	/* Integer with octal prefix, format with limited, sufficient width */
-	rc = xxsscanf("012", "%3i", &i);
+	rc = sscanf("012", "%3i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 012);
@@ -483,5 +495,5 @@
 
 	/* Integer with octal prefix, format with limited, smaller width */
-	rc = xxsscanf("012", "%2i", &i);
+	rc = sscanf("012", "%2i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 01);
@@ -494,5 +506,5 @@
 
 	/* Integer with octal prefix, format with width allowing just for 0 */
-	rc = xxsscanf("012", "%1i", &i);
+	rc = sscanf("012", "%1i", &i);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(i == 0);
@@ -505,7 +517,7 @@
 
 	/* Pointer */
-	rc = xxsscanf("0x12341234", "%p", &ptr);
-	PCUT_ASSERT_INT_EQUALS(1, rc);
-	PCUT_ASSERT_TRUE(ptr == (void *)0x12341234);
+	rc = sscanf("0xABCDEF88", "%p", &ptr);
+	PCUT_ASSERT_INT_EQUALS(1, rc);
+	PCUT_ASSERT_TRUE(ptr == (void *)0xABCDEF88);
 }
 
@@ -516,5 +528,5 @@
 
 	/* Single character */
-	rc = xxsscanf("x", "%c", &c);
+	rc = sscanf("x", "%c", &c);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(c == 'x');
@@ -527,5 +539,5 @@
 
 	/* Single whitespace character */
-	rc = xxsscanf("\t", "%c", &c);
+	rc = sscanf("\t", "%c", &c);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(c == '\t');
@@ -539,5 +551,5 @@
 	/* Multiple characters */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abc", "%3c", chars);
+	rc = sscanf("abc", "%3c", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -554,5 +566,5 @@
 	/* Fewer characters than requested */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abc", "%5c", chars);
+	rc = sscanf("abc", "%5c", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -569,5 +581,5 @@
 	/* Reading characters but no found */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("", "%5c", chars);
+	rc = sscanf("", "%5c", chars);
 	PCUT_ASSERT_INT_EQUALS(EOF, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'X');
@@ -580,5 +592,5 @@
 
 	/* Multiple characters with suppressed assignment */
-	rc = xxsscanf("abc", "%*3c%n", &n);
+	rc = sscanf("abc", "%*3c%n", &n);
 	PCUT_ASSERT_INT_EQUALS(0, rc);
 	PCUT_ASSERT_INT_EQUALS(3, n);
@@ -592,5 +604,5 @@
 	/* Multiple characters with memory allocation */
 	cp = NULL;
-	rc = xxsscanf("abc", "%m3c", &cp);
+	rc = sscanf("abc", "%m3c", &cp);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_NOT_NULL(cp);
@@ -608,5 +620,5 @@
 	/* String of non-whitespace characters, unlimited width */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf(" abc d", "%s", chars);
+	rc = sscanf(" abc d", "%s", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -624,5 +636,5 @@
 	/* String of non-whitespace characters, until the end */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf(" abc", "%s", chars);
+	rc = sscanf(" abc", "%s", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -640,5 +652,5 @@
 	/* String of non-whitespace characters, large enough width */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf(" abc d", "%5s", chars);
+	rc = sscanf(" abc d", "%5s", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -656,5 +668,5 @@
 	/* Want string of non-whitespace, but got only whitespace */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf(" ", "%s", chars);
+	rc = sscanf(" ", "%s", chars);
 	PCUT_ASSERT_INT_EQUALS(EOF, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'X');
@@ -668,5 +680,5 @@
 	/* String of non-whitespace characters, small width */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf(" abc", "%2s", chars);
+	rc = sscanf(" abc", "%2s", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -682,5 +694,5 @@
 
 	/* String of non-whitespace characters, assignment suppression */
-	rc = xxsscanf(" abc d", "%*s%n", &n);
+	rc = sscanf(" abc d", "%*s%n", &n);
 	PCUT_ASSERT_INT_EQUALS(0, rc);
 	PCUT_ASSERT_INT_EQUALS(4, n);
@@ -693,5 +705,5 @@
 
 	/* String of non-whitespace characters, memory allocation */
-	rc = xxsscanf(" abc d", "%ms", &cp);
+	rc = sscanf(" abc d", "%ms", &cp);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_NOT_NULL(cp);
@@ -711,5 +723,5 @@
 	/* Set conversion without width specified terminating before the end  */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abcd42", "%[abc]d%d", chars, &i);
+	rc = sscanf("abcd42", "%[abc]d%d", chars, &i);
 	PCUT_ASSERT_INT_EQUALS(2, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -728,5 +740,5 @@
 	/* Set conversion without width specified, until the end */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abc", "%[abc]", chars);
+	rc = sscanf("abc", "%[abc]", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -744,5 +756,5 @@
 	/* Set conversion with larger width */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abcd", "%5[abc]", chars);
+	rc = sscanf("abcd", "%5[abc]", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -760,5 +772,5 @@
 	/* Set conversion with smaller width */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abcd", "%3[abcd]", chars);
+	rc = sscanf("abcd", "%3[abcd]", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -776,5 +788,5 @@
 	/* Set conversion with negated scanset */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abcd", "%[^d]", chars);
+	rc = sscanf("abcd", "%[^d]", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -792,5 +804,5 @@
 	/* Set conversion with ']' in scanset */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("]bcd", "%[]bc]", chars);
+	rc = sscanf("]bcd", "%[]bc]", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == ']');
@@ -808,5 +820,5 @@
 	/* Set conversion with ']' in inverted scanset */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abc]", "%[^]def]", chars);
+	rc = sscanf("abc]", "%[^]def]", chars);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -823,5 +835,5 @@
 
 	/* Set conversion with assignment suppression */
-	rc = xxsscanf("abcd42", "%*[abc]%n", &n);
+	rc = sscanf("abcd42", "%*[abc]%n", &n);
 	PCUT_ASSERT_INT_EQUALS(0, rc);
 	PCUT_ASSERT_INT_EQUALS(3, n);
@@ -835,5 +847,5 @@
 	/* Set conversion with memory allocation */
 	cp = NULL;
-	rc = xxsscanf("abcd42", "%m[abcd]", &cp);
+	rc = sscanf("abcd42", "%m[abcd]", &cp);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_NOT_NULL(cp);
@@ -852,5 +864,5 @@
 
 	/* Decimal integer with suppressed assignment */
-	rc = xxsscanf("42", "%*d%n", &n);
+	rc = sscanf("42", "%*d%n", &n);
 	PCUT_ASSERT_INT_EQUALS(0, rc);
 	PCUT_ASSERT_INT_EQUALS(2, n);
@@ -865,5 +877,5 @@
 	/* Count of characters read */
 	memset(chars, 'X', chars_size);
-	rc = xxsscanf("abcd", "%3c%n", chars, &n);
+	rc = sscanf("abcd", "%3c%n", chars, &n);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(chars[0] == 'a');
@@ -880,5 +892,5 @@
 
 	/* Float with just integer part */
-	rc = xxsscanf("42", "%f", &f);
+	rc = sscanf("42", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 42.0);
@@ -891,5 +903,5 @@
 
 	/* Double with just integer part */
-	rc = xxsscanf("42", "%lf", &d);
+	rc = sscanf("42", "%lf", &d);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(d == 42.0);
@@ -902,5 +914,5 @@
 
 	/* Long double with just integer part */
-	rc = xxsscanf("42", "%Lf", &ld);
+	rc = sscanf("42", "%Lf", &ld);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(ld == 42.0);
@@ -913,5 +925,5 @@
 
 	/* Float with just hexadecimal integer part */
-	rc = xxsscanf("0x2a", "%f", &f);
+	rc = sscanf("0x2a", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 0x2a.0p0);
@@ -924,5 +936,5 @@
 
 	/* Float with sign and integer part */
-	rc = xxsscanf("-42", "%f", &f);
+	rc = sscanf("-42", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == -42.0);
@@ -935,5 +947,5 @@
 
 	/* Float with integer and fractional part */
-	rc = xxsscanf("4.2", "%f", &f);
+	rc = sscanf("4.2", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	/* 1/10 is not exactly representable in binary floating point */
@@ -948,5 +960,5 @@
 
 	/* Float with integer part and unsigned exponent */
-	rc = xxsscanf("42e1", "%f", &f);
+	rc = sscanf("42e1", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -959,5 +971,5 @@
 
 	/* Float with integer part and positive exponent */
-	rc = xxsscanf("42e+1", "%f", &f);
+	rc = sscanf("42e+1", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -970,5 +982,5 @@
 
 	/* Float with integer part and negative exponent */
-	rc = xxsscanf("42e-1", "%f", &f);
+	rc = sscanf("42e-1", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	/* 1/10 is not exactly representable in binary floating point */
@@ -983,5 +995,5 @@
 
 	/* Float with integer, fractional parts and unsigned exponent */
-	rc = xxsscanf("4.2e1", "%f", &f);
+	rc = sscanf("4.2e1", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 42.0);
@@ -994,5 +1006,5 @@
 
 	/* Hexadecimal float with integer and fractional part */
-	rc = xxsscanf("0x2.a", "%f", &f);
+	rc = sscanf("0x2.a", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 0x2.ap0);
@@ -1007,5 +1019,5 @@
 	 * Hexadecimal float with integer part and unsigned exponent
 	 */
-	rc = xxsscanf("0x2ap1", "%f", &f);
+	rc = sscanf("0x2ap1", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 0x2ap1);
@@ -1020,5 +1032,5 @@
 	 * Hexadecimal float with integer part and negative exponent
 	 */
-	rc = xxsscanf("0x2ap-1", "%f", &f);
+	rc = sscanf("0x2ap-1", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 0x2ap-1);
@@ -1034,5 +1046,5 @@
 	 * exponent
 	 */
-	rc = xxsscanf("0x2.ap4", "%f", &f);
+	rc = sscanf("0x2.ap4", "%f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 0x2.ap4);
@@ -1045,5 +1057,5 @@
 
 	/* Float with just integer part and limited width */
-	rc = xxsscanf("1234", "%3f", &f);
+	rc = sscanf("1234", "%3f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 123.0);
@@ -1056,5 +1068,5 @@
 
 	/* Float with integer, fractional part and limited width */
-	rc = xxsscanf("12.34", "%4f", &f);
+	rc = sscanf("12.34", "%4f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	/* 1/10 is not exactly representable in binary floating point */
@@ -1069,5 +1081,5 @@
 
 	/* Float with width only enough to cover an integral part */
-	rc = xxsscanf("12.34", "%3f", &f);
+	rc = sscanf("12.34", "%3f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 12.0);
@@ -1080,5 +1092,5 @@
 
 	/* Float with width too small to cover the exponent number */
-	rc = xxsscanf("12.34e+2", "%7f", &f);
+	rc = sscanf("12.34e+2", "%7f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	/* 1/10 is not exactly representable in binary floating point */
@@ -1093,5 +1105,5 @@
 
 	/* Float with width too small to cover the exponent sign and number */
-	rc = xxsscanf("12.34e+2", "%6f", &f);
+	rc = sscanf("12.34e+2", "%6f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	/* 1/10 is not exactly representable in binary floating point */
@@ -1106,5 +1118,5 @@
 
 	/* Float with width too small to cover the exponent part */
-	rc = xxsscanf("12.34e+2", "%5f", &f);
+	rc = sscanf("12.34e+2", "%5f", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	/* 1/10 is not exactly representable in binary floating point */
@@ -1119,5 +1131,5 @@
 
 	/* Float using alternate form 'F' */
-	rc = xxsscanf("42e1", "%F", &f);
+	rc = sscanf("42e1", "%F", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -1130,5 +1142,5 @@
 
 	/* Float using alternate form 'a' */
-	rc = xxsscanf("42e1", "%a", &f);
+	rc = sscanf("42e1", "%a", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -1141,5 +1153,5 @@
 
 	/* Float using alternate form 'e' */
-	rc = xxsscanf("42e1", "%e", &f);
+	rc = sscanf("42e1", "%e", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -1152,5 +1164,5 @@
 
 	/* Float using alternate form 'g' */
-	rc = xxsscanf("42e1", "%g", &f);
+	rc = sscanf("42e1", "%g", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -1163,5 +1175,5 @@
 
 	/* Float using alternate form 'A' */
-	rc = xxsscanf("42e1", "%A", &f);
+	rc = sscanf("42e1", "%A", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -1174,5 +1186,5 @@
 
 	/* Float using alternate form 'E' */
-	rc = xxsscanf("42e1", "%E", &f);
+	rc = sscanf("42e1", "%E", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
@@ -1185,5 +1197,5 @@
 
 	/* Float using alternate form 'G' */
-	rc = xxsscanf("42e1", "%G", &f);
+	rc = sscanf("42e1", "%G", &f);
 	PCUT_ASSERT_INT_EQUALS(1, rc);
 	PCUT_ASSERT_TRUE(f == 420.0);
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/posix/Makefile	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -70,5 +70,4 @@
 	src/signal.c \
 	src/stdio.c \
-	src/stdio/scanf.c \
 	src/stdlib.c \
 	src/stdlib/strtold.c \
Index: uspace/lib/posix/include/posix/stdio.h
===================================================================
--- uspace/lib/posix/include/posix/stdio.h	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/posix/include/posix/stdio.h	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -164,16 +164,4 @@
 extern int vsprintf(char *__restrict__ s, const char *__restrict__ format, va_list ap);
 
-/* Formatted Input */
-extern int fscanf(
-    FILE *__restrict__ stream, const char *__restrict__ format, ...);
-extern int vfscanf(
-    FILE *__restrict__ stream, const char *__restrict__ format, va_list arg);
-extern int scanf(const char *__restrict__ format, ...);
-extern int vscanf(const char *__restrict__ format, va_list arg);
-extern int sscanf(
-    const char *__restrict__ s, const char *__restrict__ format, ...);
-extern int vsscanf(
-    const char *__restrict__ s, const char *__restrict__ format, va_list arg);
-
 /* File Locking */
 extern void flockfile(FILE *file);
Index: uspace/lib/posix/src/stdio.c
===================================================================
--- uspace/lib/posix/src/stdio.c	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ uspace/lib/posix/src/stdio.c	(revision 5a6c28d195eff93f3ee378bd1f116b66a4c0fd9c)
@@ -351,63 +351,4 @@
 
 /**
- * Convert formatted input from the stream.
- *
- * @param stream Input stream.
- * @param format Format description.
- * @return The number of converted output items or EOF on failure.
- */
-int fscanf(FILE *restrict stream, const char *restrict format, ...)
-{
-	va_list list;
-	va_start(list, format);
-	int result = vfscanf(stream, format, list);
-	va_end(list);
-	return result;
-}
-
-/**
- * Convert formatted input from the standard input.
- *
- * @param format Format description.
- * @return The number of converted output items or EOF on failure.
- */
-int scanf(const char *restrict format, ...)
-{
-	va_list list;
-	va_start(list, format);
-	int result = vscanf(format, list);
-	va_end(list);
-	return result;
-}
-
-/**
- * Convert formatted input from the standard input.
- *
- * @param format Format description.
- * @param arg Output items.
- * @return The number of converted output items or EOF on failure.
- */
-int vscanf(const char *restrict format, va_list arg)
-{
-	return vfscanf(stdin, format, arg);
-}
-
-/**
- * Convert formatted input from the string.
- *
- * @param s Input string.
- * @param format Format description.
- * @return The number of converted output items or EOF on failure.
- */
-int sscanf(const char *restrict s, const char *restrict format, ...)
-{
-	va_list list;
-	va_start(list, format);
-	int result = vsscanf(s, format, list);
-	va_end(list);
-	return result;
-}
-
-/**
  * Acquire file stream for the thread.
  *
Index: uspace/lib/posix/src/stdio/scanf.c
===================================================================
--- uspace/lib/posix/src/stdio/scanf.c	(revision f47a905f54a600cbf89372fdb1682e03070399c3)
+++ 	(revision )
@@ -1,1307 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libposix
- * @{
- */
-/** @file Implementation of the scanf backend.
- */
-
-#include <assert.h>
-
-#include <errno.h>
-
-#include "posix/stdio.h"
-#include "posix/stdlib.h"
-#include "posix/stddef.h"
-#include "posix/string.h"
-#include "posix/ctype.h"
-#include "posix/sys/types.h"
-
-#include "../internal/common.h"
-#include "libc/malloc.h"
-#include "libc/stdbool.h"
-
-/** Unified data type for possible data sources for scanf. */
-typedef union __data_source {
-	FILE *stream; /**< Input file stream. */
-	const char *string; /**< Input string. */
-} _data_source;
-
-/** Internal state of the input provider. */
-enum {
-	/** Partly constructed but not yet functional. */
-	_PROV_CONSTRUCTED,
-	/** Ready to serve any request. */
-	_PROV_READY,
-	/** Cursor is temporarily lent to the external entity. No action is
-	 * possible until the cursor is returned.
-	 */
-	_PROV_CURSOR_LENT,
-};
-
-/** Universal abstraction over data input for scanf. */
-typedef struct __input_provider {
-	/** Source of data elements. */
-	_data_source source;
-	/** How many elements was already processed. */
-	int consumed;
-	/** How many elements was already fetched from the source. */
-	int fetched;
-	/** Elements are fetched from the source in batches (e.g. by getline())
-	 * to allow using strtol/strtod family even on streams.
-	 */
-	char *window;
-	/** Size of the current window. */
-	size_t window_size;
-	/** Points to the next element to be processed inside the current window. */
-	const char *cursor;
-	/** Internal state of the provider. */
-	int state;
-
-	/** Take control over data source. Finish initialization of the internal
-	 * structures (e.g. allocation of window).
-	 */
-	void (*capture)(struct __input_provider *);
-	/** Get a single element from the source and update the internal structures
-	 * accordingly (e.g. greedy update of the window). Return -1 if the
-	 * element cannot be obtained.
-	 */
-	int (*pop)(struct __input_provider *);
-	/** Undo the most recent not-undone pop operation. Might be necesarry to
-	 * flush current window and seek data source backwards. Return 0 if the
-	 * pop history is exhausted, non-zero on success.
-	 */
-	int (*undo)(struct __input_provider *);
-	/** Lend the cursor to the caller.  */
-	const char *(*borrow_cursor)(struct __input_provider *);
-	/** Take control over possibly incremented cursor and update the internal
-	 * structures if necessary.
-	 */
-	void (*return_cursor)(struct __input_provider *, const char *);
-	/** Release the control over the source. That is, synchronize any
-	 * fetched but non-consumed elements (e.g. by seeking) and destruct
-	 * internal structures (e.g. window deallocation).
-	 */
-	void (*release)(struct __input_provider *);
-} _input_provider;
-
-/** @see __input_provider */
-static void _capture_stream(_input_provider *self)
-{
-	assert(self->source.stream);
-	assert(self->state == _PROV_CONSTRUCTED);
-	/* Caller could already pre-allocated the window. */
-	assert((self->window == NULL && self->window_size == 0) ||
-	    (self->window && self->window_size > 0));
-
-	/* Initialize internal structures. */
-	self->consumed = 0;
-	ssize_t fetched = getline(
-	    &self->window, &self->window_size, self->source.stream);
-	if (fetched != -1) {
-		self->fetched = fetched;
-		self->cursor = self->window;
-	} else {
-		/* EOF encountered. */
-		self->fetched = 0;
-		self->cursor = NULL;
-	}
-	self->state = _PROV_READY;
-}
-
-/** @see __input_provider */
-static void _capture_string(_input_provider *self)
-{
-	assert(self->source.string);
-	assert(self->state == _PROV_CONSTRUCTED);
-
-	/* Initialize internal structures. */
-	self->consumed = 0;
-	self->fetched = strlen(self->source.string);
-	self->window = (char *) self->source.string;
-	self->window_size = self->fetched + 1;
-	self->cursor = self->window;
-	self->state = _PROV_READY;
-}
-
-/** @see __input_provider */
-static int _pop_stream(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-
-	if (self->cursor) {
-		int c = *self->cursor;
-		++self->consumed;
-		++self->cursor;
-		/* Do we need to fetch a new line from the source? */
-		if (*self->cursor == '\0') {
-			ssize_t fetched = getline(&self->window,
-			    &self->window_size, self->source.stream);
-			if (fetched != -1) {
-				self->fetched += fetched;
-				self->cursor = self->window;
-			} else {
-				/* EOF encountered. */
-				self->cursor = NULL;
-			}
-		}
-		return c;
-	} else {
-		/* Already at EOF. */
-		return -1;
-	}
-}
-
-/** @see __input_provider */
-static int _pop_string(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-
-	if (*self->cursor != '\0') {
-		int c = *self->cursor;
-		++self->consumed;
-		++self->cursor;
-		return c;
-	} else {
-		/* String depleted. */
-		return -1;
-	}
-}
-
-/** @see __input_provider */
-static int _undo_stream(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-
-	if (self->consumed == 0) {
-		/* Undo history exhausted. */
-		return 0;
-	}
-
-	if (!self->cursor || self->window == self->cursor) {
-		/*
-		 * Complex case. Either at EOF (cursor == NULL) or there is no more
-		 * place to retreat to inside the window. Seek the source backwards
-		 * and flush the window. Regarding the scanf, this could happend only
-		 * when matching unbounded string (%s) or unbounded scanset (%[) not
-		 * containing newline, while at the same time newline is the character
-		 * that breaks the matching process.
-		 */
-		int rc = fseek(self->source.stream, -1, SEEK_CUR);
-		if (rc == -1) {
-			/* Seek failed.  */
-			return 0;
-		}
-		ssize_t fetched = getline(&self->window,
-		    &self->window_size, self->source.stream);
-		if (fetched != -1) {
-			assert(fetched == 1);
-			self->fetched = self->consumed + 1;
-			self->cursor = self->window;
-		} else {
-			/* Stream is broken. */
-			return 0;
-		}
-	} else {
-		/* Simple case. Still inside window. */
-		--self->cursor;
-	}
-	--self->consumed;
-	return 1; /* Success. */
-}
-
-/** @see __input_provider */
-static int _undo_string(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-
-	if (self->consumed > 0) {
-		--self->consumed;
-		--self->cursor;
-	} else {
-		/* Undo history exhausted. */
-		return 0;
-	}
-	return 1; /* Success. */
-}
-
-/** @see __input_provider */
-static const char *_borrow_cursor_universal(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-
-	self->state = _PROV_CURSOR_LENT;
-	return self->cursor;
-}
-
-/** @see __input_provider */
-static void _return_cursor_stream(_input_provider *self, const char *cursor)
-{
-	assert(self->state == _PROV_CURSOR_LENT);
-
-	/* Check how much of the window did external entity consumed. */
-	self->consumed += cursor - self->cursor;
-	self->cursor = cursor;
-	if (*self->cursor == '\0') {
-		/* Window was completely consumed, fetch new data. */
-		ssize_t fetched = getline(&self->window,
-		    &self->window_size, self->source.stream);
-		if (fetched != -1) {
-			self->fetched += fetched;
-			self->cursor = self->window;
-		} else {
-			/* EOF encountered. */
-			self->cursor = NULL;
-		}
-	}
-	self->state = _PROV_READY;
-}
-
-/** @see __input_provider */
-static void _return_cursor_string(_input_provider *self, const char *cursor)
-{
-	assert(self->state == _PROV_CURSOR_LENT);
-
-	/* Check how much of the window did external entity consumed. */
-	self->consumed += cursor - self->cursor;
-	self->cursor = cursor;
-	self->state = _PROV_READY;
-}
-
-/** @see __input_provider */
-static void _release_stream(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-	assert(self->consumed >= self->fetched);
-
-	/*
-	 * Try to correct the difference between the stream position and what was
-	 * actually consumed. If it is not possible, continue anyway.
-	 */
-	fseek(self->source.stream, self->consumed - self->fetched, SEEK_CUR);
-
-	/* Destruct internal structures. */
-	self->fetched = 0;
-	self->cursor = NULL;
-	if (self->window) {
-		free(self->window);
-		self->window = NULL;
-	}
-	self->window_size = 0;
-	self->state = _PROV_CONSTRUCTED;
-}
-
-/** @see __input_provider */
-static void _release_string(_input_provider *self)
-{
-	assert(self->state == _PROV_READY);
-
-	/* Destruct internal structures. */
-	self->fetched = 0;
-	self->cursor = NULL;
-	self->window = NULL;
-	self->window_size = 0;
-	self->state = _PROV_CONSTRUCTED;
-}
-
-/** Length modifier values. */
-enum {
-	LMOD_NONE,
-	LMOD_hh,
-	LMOD_h,
-	LMOD_l,
-	LMOD_ll,
-	LMOD_j,
-	LMOD_z,
-	LMOD_t,
-	LMOD_L,
-	LMOD_p, /* Reserved for %p conversion. */
-};
-
-/**
- * Decides whether provided characters specify length modifier. If so, the
- * recognized modifier is stored through provider pointer.
- *
- * @param c Candidate on the length modifier.
- * @param _c Next character (might be NUL).
- * @param modifier Pointer to the modifier value.
- * @return Whether the modifier was recognized or not.
- */
-static inline int is_length_mod(int c, int _c, int *modifier)
-{
-	assert(modifier);
-
-	switch (c) {
-	case 'h':
-		/* Check whether the modifier was not already recognized. */
-		if (*modifier == LMOD_NONE) {
-			*modifier = _c == 'h' ? LMOD_hh : LMOD_h;
-		} else {
-			/* Format string is invalid. Notify the caller. */
-			*modifier = LMOD_NONE;
-		}
-		return 1;
-	case 'l':
-		if (*modifier == LMOD_NONE) {
-			*modifier = _c == 'l' ? LMOD_ll : LMOD_l;
-		} else {
-			*modifier = LMOD_NONE;
-		}
-		return 1;
-	case 'j':
-		*modifier = *modifier == LMOD_NONE ? LMOD_j : LMOD_NONE;
-		return 1;
-	case 'z':
-		*modifier = *modifier == LMOD_NONE ? LMOD_z : LMOD_NONE;
-		return 1;
-	case 't':
-		*modifier = *modifier == LMOD_NONE ? LMOD_t : LMOD_NONE;
-		return 1;
-	case 'L':
-		*modifier = *modifier == LMOD_NONE ? LMOD_L : LMOD_NONE;
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-/**
- * Decides whether provided character specifies integer conversion. If so, the
- * semantics of the conversion is stored through provided pointers..
- *
- * @param c Candidate on the integer conversion.
- * @param is_unsigned Pointer to store whether the conversion is signed or not.
- * @param base Pointer to store the base of the integer conversion.
- * @return Whether the conversion was recognized or not.
- */
-static inline int is_int_conv(int c, bool *is_unsigned, int *base)
-{
-	assert(is_unsigned && base);
-
-	switch (c) {
-	case 'd':
-		*is_unsigned = false;
-		*base = 10;
-		return 1;
-	case 'i':
-		*is_unsigned = false;
-		*base = 0;
-		return 1;
-	case 'o':
-		*is_unsigned = true;
-		*base = 8;
-		return 1;
-	case 'u':
-		*is_unsigned = true;
-		*base = 10;
-		return 1;
-	case 'p':
-		/*
-		 * According to POSIX, %p modifier is implementation defined but
-		 * must correspond to its printf counterpart.
-		 */
-	case 'x':
-	case 'X':
-		*is_unsigned = true;
-		*base = 16;
-		return 1;
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-/**
- * Decides whether provided character specifies conversion of the floating
- * point number.
- *
- * @param c Candidate on the floating point conversion.
- * @return Whether the conversion was recognized or not.
- */
-static inline int is_float_conv(int c)
-{
-	switch (c) {
-	case 'a':
-	case 'A':
-	case 'e':
-	case 'E':
-	case 'f':
-	case 'F':
-	case 'g':
-	case 'G':
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-/**
- * Decides whether provided character specifies conversion of the character
- * sequence.
- *
- * @param c Candidate on the character sequence conversion.
- * @param modifier Pointer to store length modifier for wide chars.
- * @return Whether the conversion was recognized or not.
- */
-static inline int is_seq_conv(int c, int *modifier)
-{
-	assert(modifier);
-
-	switch (c) {
-	case 'S':
-		*modifier = LMOD_l;
-		/* Fallthrough */
-	case 's':
-		return 1;
-	case 'C':
-		*modifier = LMOD_l;
-		/* Fallthrough */
-	case 'c':
-		return 1;
-	case '[':
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-/**
- * Backend for the whole family of scanf functions. Uses input provider
- * to abstract over differences between strings and streams. Should be
- * POSIX compliant (apart from the not supported stuff).
- *
- * NOT SUPPORTED: locale (see strtold), wide chars, numbered output arguments
- *
- * @param in Input provider.
- * @param fmt Format description.
- * @param arg Output arguments.
- * @return The number of converted output items or EOF on failure.
- */
-static inline int _internal_scanf(
-    _input_provider *in, const char *restrict fmt, va_list arg)
-{
-	int c = -1;
-	int converted_cnt = 0;
-	bool converting = false;
-	bool matching_failure = false;
-
-	bool assign_supress = false;
-	bool assign_alloc = false;
-	long width = -1;
-	int length_mod = LMOD_NONE;
-	bool int_conv_unsigned = false;
-	int int_conv_base = 0;
-
-	/*
-	 * Buffers allocated by scanf for optional 'm' specifier must be remembered
-	 * to deallocaate them in case of an error. Because each of those buffers
-	 * corresponds to one of the argument from va_list, there is an upper bound
-	 * on the number of those arguments. In case of C99, this uppper bound is
-	 * 127 arguments.
-	 */
-	char *buffers[127];
-	for (int i = 0; i < 127; ++i) {
-		buffers[i] = NULL;
-	}
-	int next_unused_buffer_idx = 0;
-
-	in->capture(in);
-
-	/*
-	 * Interpret format string. Control shall prematurely jump from the cycle
-	 * on input failure, matching failure or illegal format string. In order
-	 * to keep error reporting simple enough and to keep input consistent,
-	 * error condition shall be always manifested as jump from the cycle,
-	 * not function return. Format string pointer shall be updated specifically
-	 * for each sub-case (i.e. there shall be no loop-wide increment).
-	 */
-	while (*fmt) {
-
-		if (converting) {
-
-			/*
-			 * Processing inside conversion specifier. Either collect optional
-			 * parameters or execute the conversion. When the conversion
-			 * is successfully completed, increment conversion count and switch
-			 * back to normal mode.
-			 */
-			if (*fmt == '*') {
-				/* Assignment-supression (optional). */
-				if (assign_supress) {
-					/* Already set. Illegal format string. */
-					break;
-				}
-				assign_supress = true;
-				++fmt;
-			} else if (*fmt == 'm') {
-				/* Assignment-allocation (optional). */
-				if (assign_alloc) {
-					/* Already set. Illegal format string. */
-					break;
-				}
-				assign_alloc = true;
-				++fmt;
-			} else if (*fmt == '$') {
-				/* Reference to numbered output argument. */
-				// TODO
-				not_implemented();
-			} else if (isdigit(*fmt)) {
-				/* Maximum field length (optional). */
-				if (width != -1) {
-					/* Already set. Illegal format string. */
-					break;
-				}
-				char *fmt_new = NULL;
-				width = strtol(fmt, &fmt_new, 10);
-				if (width != 0) {
-					fmt = fmt_new;
-				} else {
-					/*
-					 * Since POSIX requires width to be non-zero, it is
-					 * sufficient to interpret zero width as error without
-					 * referring to errno.
-					 */
-					break;
-				}
-			} else if (is_length_mod(*fmt, *(fmt + 1), &length_mod)) {
-				/* Length modifier (optional). */
-				if (length_mod == LMOD_NONE) {
-					/*
-					 * Already set. Illegal format string. The actual detection
-					 * is carried out in the is_length_mod().
-					 */
-					break;
-				}
-				if (length_mod == LMOD_hh || length_mod == LMOD_ll) {
-					/* Modifier was two characters long. */
-					++fmt;
-				}
-				++fmt;
-			} else if (is_int_conv(*fmt, &int_conv_unsigned, &int_conv_base)) {
-				/* Integer conversion. */
-
-				/* Check sanity of optional parts of conversion specifier. */
-				if (assign_alloc || length_mod == LMOD_L) {
-					/* Illegal format string. */
-					break;
-				}
-
-				/*
-				 * Conversion of the integer with %p specifier needs special
-				 * handling, because it is not allowed to have arbitrary
-				 * length modifier.
-				 */
-				if (*fmt == 'p') {
-					if (length_mod == LMOD_NONE) {
-						length_mod = LMOD_p;
-					} else {
-						/* Already set. Illegal format string. */
-						break;
-					}
-				}
-
-				/*
-				 * First consume any white spaces, so we can borrow cursor
-				 * from the input provider. This way, the cursor will either
-				 * point to the non-white space while the input will be
-				 * prefetched up to the newline (which is suitable for strtol),
-				 * or the input will be at EOF.
-				 */
-				do {
-					c = in->pop(in);
-				} while (isspace(c));
-
-				/* After skipping the white spaces, can we actually continue? */
-				if (c == -1) {
-					/* Input failure. */
-					break;
-				} else {
-					/*
-					 * Everything is OK, just undo the last pop, so the cursor
-					 * can be borrowed.
-					 */
-					in->undo(in);
-				}
-
-				const char *cur_borrowed = NULL;
-				char *cur_duplicated = NULL;
-				const char *cur_limited = NULL;
-				const char *cur_updated = NULL;
-
-				/*
-				 * Borrow the cursor. Until it is returned to the provider
-				 * we cannot jump from the cycle, because it would leave
-				 * the input inconsistent.
-				 */
-				cur_borrowed = in->borrow_cursor(in);
-
-				/*
-				 * If the width is limited, the cursor horizont must be
-				 * decreased accordingly. Otherwise the strtol could read more
-				 * than allowed by width.
-				 */
-				if (width != -1) {
-					cur_duplicated = strndup(cur_borrowed, width);
-					cur_limited = cur_duplicated;
-				} else {
-					cur_limited = cur_borrowed;
-				}
-				cur_updated = cur_limited;
-
-				long long sres = 0;
-				unsigned long long ures = 0;
-				errno = 0; /* Reset errno to recognize error later. */
-				/* Try to convert the integer. */
-				if (int_conv_unsigned) {
-					ures = strtoull(cur_limited, (char **) &cur_updated, int_conv_base);
-				} else {
-					sres = strtoll(cur_limited, (char **) &cur_updated, int_conv_base);
-				}
-
-				/* Update the cursor so it can be returned to the provider. */
-				cur_borrowed += cur_updated - cur_limited;
-				if (cur_duplicated != NULL) {
-					/* Deallocate duplicated part of the cursor view. */
-					free(cur_duplicated);
-				}
-				cur_limited = NULL;
-				cur_updated = NULL;
-				cur_duplicated = NULL;
-				/*
-				 * Return the cursor to the provider. Input consistency is again
-				 * the job of the provider, so we can report errors from
-				 * now on.
-				 */
-				in->return_cursor(in, cur_borrowed);
-				cur_borrowed = NULL;
-
-				/* Check whether the conversion was successful. */
-				if (errno != EOK) {
-					matching_failure = true;
-					break;
-				}
-
-				/*
-				 * If not supressed, assign the converted integer into
-				 * the next output argument.
-				 */
-				if (!assign_supress) {
-					if (int_conv_unsigned) {
-						unsigned char *phh;
-						unsigned short *ph;
-						unsigned *pdef;
-						unsigned long *pl;
-						unsigned long long *pll;
-						uintmax_t *pj;
-						size_t *pz;
-						// XXX: What is unsigned counterpart of the ptrdiff_t?
-						size_t *pt;
-						void **pp;
-
-						switch (length_mod) {
-						case LMOD_hh:
-							phh = va_arg(arg, unsigned char *);
-							*phh = (unsigned char) ures;
-							break;
-						case LMOD_h:
-							ph = va_arg(arg, unsigned short *);
-							*ph = (unsigned short) ures;
-							break;
-						case LMOD_NONE:
-							pdef = va_arg(arg, unsigned *);
-							*pdef = (unsigned) ures;
-							break;
-						case LMOD_l:
-							pl = va_arg(arg, unsigned long *);
-							*pl = (unsigned long) ures;
-							break;
-						case LMOD_ll:
-							pll = va_arg(arg, unsigned long long *);
-							*pll = (unsigned long long) ures;
-							break;
-						case LMOD_j:
-							pj = va_arg(arg, uintmax_t *);
-							*pj = (uintmax_t) ures;
-							break;
-						case LMOD_z:
-							pz = va_arg(arg, size_t *);
-							*pz = (size_t) ures;
-							break;
-						case LMOD_t:
-							pt = va_arg(arg, size_t *);
-							*pt = (size_t) ures;
-							break;
-						case LMOD_p:
-							pp = va_arg(arg, void **);
-							*pp = (void *) (uintptr_t) ures;
-							break;
-						default:
-							assert(false);
-						}
-					} else {
-						signed char *phh;
-						short *ph;
-						int *pdef;
-						long *pl;
-						long long *pll;
-						intmax_t *pj;
-						ssize_t *pz;
-						ptrdiff_t *pt;
-
-						switch (length_mod) {
-						case LMOD_hh:
-							phh = va_arg(arg, signed char *);
-							*phh = (signed char) sres;
-							break;
-						case LMOD_h:
-							ph = va_arg(arg, short *);
-							*ph = (short) sres;
-							break;
-						case LMOD_NONE:
-							pdef = va_arg(arg, int *);
-							*pdef = (int) sres;
-							break;
-						case LMOD_l:
-							pl = va_arg(arg, long *);
-							*pl = (long) sres;
-							break;
-						case LMOD_ll:
-							pll = va_arg(arg, long long *);
-							*pll = (long long) sres;
-							break;
-						case LMOD_j:
-							pj = va_arg(arg, intmax_t *);
-							*pj = (intmax_t) sres;
-							break;
-						case LMOD_z:
-							pz = va_arg(arg, ssize_t *);
-							*pz = (ssize_t) sres;
-							break;
-						case LMOD_t:
-							pt = va_arg(arg, ptrdiff_t *);
-							*pt = (ptrdiff_t) sres;
-							break;
-						default:
-							assert(false);
-						}
-					}
-					++converted_cnt;
-				}
-
-				converting = false;
-				++fmt;
-			} else if (is_float_conv(*fmt)) {
-				/* Floating point number conversion. */
-
-				/* Check sanity of optional parts of conversion specifier. */
-				if (assign_alloc) {
-					/* Illegal format string. */
-					break;
-				}
-				if (length_mod != LMOD_NONE &&
-				    length_mod != LMOD_l &&
-				    length_mod != LMOD_L) {
-					/* Illegal format string. */
-					break;
-				}
-
-				/*
-				 * First consume any white spaces, so we can borrow cursor
-				 * from the input provider. This way, the cursor will either
-				 * point to the non-white space while the input will be
-				 * prefetched up to the newline (which is suitable for strtof),
-				 * or the input will be at EOF.
-				 */
-				do {
-					c = in->pop(in);
-				} while (isspace(c));
-
-				/* After skipping the white spaces, can we actually continue? */
-				if (c == -1) {
-					/* Input failure. */
-					break;
-				} else {
-					/*
-					 * Everything is OK, just undo the last pop, so the cursor
-					 * can be borrowed.
-					 */
-					in->undo(in);
-				}
-
-				const char *cur_borrowed = NULL;
-				const char *cur_limited = NULL;
-				char *cur_duplicated = NULL;
-				const char *cur_updated = NULL;
-
-				/*
-				 * Borrow the cursor. Until it is returned to the provider
-				 * we cannot jump from the cycle, because it would leave
-				 * the input inconsistent.
-				 */
-				cur_borrowed = in->borrow_cursor(in);
-
-				/*
-				 * If the width is limited, the cursor horizont must be
-				 * decreased accordingly. Otherwise the strtof could read more
-				 * than allowed by width.
-				 */
-				if (width != -1) {
-					cur_duplicated = strndup(cur_borrowed, width);
-					cur_limited = cur_duplicated;
-				} else {
-					cur_limited = cur_borrowed;
-				}
-				cur_updated = cur_limited;
-
-				float fres = 0.0;
-				double dres = 0.0;
-				long double ldres = 0.0;
-				errno = 0; /* Reset errno to recognize error later. */
-				/* Try to convert the floating point nubmer. */
-				switch (length_mod) {
-				case LMOD_NONE:
-					fres = strtof(cur_limited, (char **) &cur_updated);
-					break;
-				case LMOD_l:
-					dres = strtod(cur_limited, (char **) &cur_updated);
-					break;
-				case LMOD_L:
-					ldres = strtold(cur_limited, (char **) &cur_updated);
-					break;
-				default:
-					assert(false);
-				}
-
-				/* Update the cursor so it can be returned to the provider. */
-				cur_borrowed += cur_updated - cur_limited;
-				if (cur_duplicated != NULL) {
-					/* Deallocate duplicated part of the cursor view. */
-					free(cur_duplicated);
-				}
-				cur_limited = NULL;
-				cur_updated = NULL;
-				/*
-				 * Return the cursor to the provider. Input consistency is again
-				 * the job of the provider, so we can report errors from
-				 * now on.
-				 */
-				in->return_cursor(in, cur_borrowed);
-				cur_borrowed = NULL;
-
-				/* Check whether the conversion was successful. */
-				if (errno != EOK) {
-					matching_failure = true;
-					break;
-				}
-
-				/*
-				 * If nto supressed, assign the converted floating point number
-				 * into the next output argument.
-				 */
-				if (!assign_supress) {
-					float *pf;
-					double *pd;
-					long double *pld;
-					switch (length_mod) {
-					case LMOD_NONE:
-						pf = va_arg(arg, float *);
-						*pf = fres;
-						break;
-					case LMOD_l:
-						pd = va_arg(arg, double *);
-						*pd = dres;
-						break;
-					case LMOD_L:
-						pld = va_arg(arg, long double *);
-						*pld = ldres;
-						break;
-					default:
-						assert(false);
-					}
-					++converted_cnt;
-				}
-
-				converting = false;
-				++fmt;
-			} else if (is_seq_conv(*fmt, &length_mod)) {
-				/* Character sequence conversion. */
-
-				/* Check sanity of optional parts of conversion specifier. */
-				if (length_mod != LMOD_NONE &&
-				    length_mod != LMOD_l) {
-					/* Illegal format string. */
-					break;
-				}
-
-				if (length_mod == LMOD_l) {
-					/* Wide chars not supported. */
-					// TODO
-					not_implemented();
-				}
-
-				int term_size = 1; /* Size of the terminator (0 or 1)). */
-				if (*fmt == 'c') {
-					term_size = 0;
-					width = width == -1 ? 1 : width;
-				}
-
-				if (*fmt == 's') {
-					/* Skip white spaces. */
-					do {
-						c = in->pop(in);
-					} while (isspace(c));
-				} else {
-					/* Fetch a single character. */
-					c = in->pop(in);
-				}
-
-				/* Check whether there is still input to read. */
-				if (c == -1) {
-					/* Input failure. */
-					break;
-				}
-
-				/* Prepare scanset. */
-				char terminate_on[256];
-				for (int i = 0; i < 256; ++i) {
-					terminate_on[i] = 0;
-				}
-				if (*fmt == 'c') {
-					++fmt;
-				} else if (*fmt == 's') {
-					terminate_on[' '] = 1;
-					terminate_on['\n'] = 1;
-					terminate_on['\t'] = 1;
-					terminate_on['\f'] = 1;
-					terminate_on['\r'] = 1;
-					terminate_on['\v'] = 1;
-					++fmt;
-				} else {
-					assert(*fmt == '[');
-					bool not = false;
-					bool dash = false;
-					++fmt;
-					/* Check for negation. */
-					if (*fmt == '^') {
-						not = true;
-						++fmt;
-					}
-					/* Check for escape sequences. */
-					if (*fmt == '-' || *fmt == ']') {
-						terminate_on[(int) *fmt] = 1;
-						++fmt;
-					}
-					/* Check for ordinary characters and ranges. */
-					while (*fmt != '\0' && *fmt != ']') {
-						if (dash) {
-							for (char chr = *(fmt - 2); chr <= *fmt; ++chr) {
-								terminate_on[(int) chr] = 1;
-							}
-							dash = false;
-						} else if (*fmt == '-') {
-							dash = true;
-						} else {
-							terminate_on[(int) *fmt] = 1;
-						}
-						++fmt;
-					}
-					/* Check for escape sequence. */
-					if (dash == true) {
-						terminate_on['-'] = 1;
-					}
-					/* Check whether the specifier was correctly terminated.*/
-					if (*fmt == '\0') {
-						/* Illegal format string. */
-						break;
-					} else {
-						++fmt;
-					}
-					/* Inverse the scanset if necessary. */
-					if (not == false) {
-						for (int i = 0; i < 256; ++i) {
-							terminate_on[i] = terminate_on[i] ? 0 : 1;
-						}
-					}
-				}
-
-				char *buf = NULL;
-				size_t buf_size = 0;
-				char *cur = NULL;
-				size_t alloc_step = 80; /* Buffer size gain during reallocation. */
-				int my_buffer_idx = 0;
-
-				/*
-				 * Retrieve the buffer into which popped characters
-				 * will be stored.
-				 */
-				if (!assign_supress) {
-					if (assign_alloc) {
-						/* We must allocate our own buffer. */
-						buf_size =
-						    width == -1 ? alloc_step : (size_t) width + term_size;
-						buf = malloc(buf_size);
-						if (!buf) {
-							/* No memory. */
-							break;
-						}
-						my_buffer_idx = next_unused_buffer_idx;
-						++next_unused_buffer_idx;
-						buffers[my_buffer_idx] = buf;
-						cur = buf;
-					} else {
-						/* Caller provided its buffer. */
-						buf = va_arg(arg, char *);
-						cur = buf;
-						buf_size =
-						    width == -1 ? SIZE_MAX : (size_t) width + term_size;
-					}
-				}
-
-				/* Match the string. The next character is already popped. */
-				while ((width == -1 || width > 0) && c != -1 && !terminate_on[c]) {
-
-					/* Check whether the buffer is still sufficiently large. */
-					if (!assign_supress) {
-						/* Always reserve space for the null terminator. */
-						if (cur == buf + buf_size - term_size) {
-							/* Buffer size must be increased. */
-							buf = realloc(buf, buf_size + alloc_step);
-							if (buf) {
-								buffers[my_buffer_idx] = buf;
-								cur = buf + buf_size - term_size;
-								buf_size += alloc_step;
-							} else {
-								/*
-								 * Break just from this tight loop. Errno will
-								 * be checked after it.
-								 */
-								break;
-							}
-						}
-						/* Store the input character. */
-						*cur = c;
-					}
-
-					width = width == -1 ? -1 : width - 1;
-					++cur;
-					c = in->pop(in);
-				}
-				if (errno == ENOMEM) {
-					/* No memory. */
-					break;
-				}
-				if (c != -1) {
-					/* There is still more input, so undo the last pop. */
-					in->undo(in);
-				}
-
-				/* Check for failures. */
-				if (cur == buf) {
-					/*
-					 * Matching failure. Input failure was already checked
-					 * earlier.
-					 */
-					matching_failure = true;
-					if (!assign_supress && assign_alloc) {
-						/* Roll back. */
-						free(buf);
-						buffers[my_buffer_idx] = NULL;
-						--next_unused_buffer_idx;
-					}
-					break;
-				}
-
-				/* Store the terminator. */
-				if (!assign_supress && term_size > 0) {
-					/* Space for the terminator was reserved. */
-					*cur = '\0';
-				}
-
-				/* Store the result if not already stored. */
-				if (!assign_supress) {
-					if (assign_alloc) {
-						char **pbuf = va_arg(arg, char **);
-						*pbuf = buf;
-					}
-					++converted_cnt;
-				}
-
-				converting = false;
-				/* Format string pointer already incremented. */
-			} else if (*fmt == 'n') {
-				/* Report the number of consumed bytes so far. */
-
-				/* Sanity check. */
-				bool sane =
-				    width == -1 &&
-				    length_mod == LMOD_NONE &&
-				    assign_alloc == false &&
-				    assign_supress == false;
-
-				if (sane) {
-					int *pi = va_arg(arg, int *);
-					*pi = in->consumed;
-				} else {
-					/* Illegal format string. */
-					break;
-				}
-
-				/* This shall not be counted as conversion. */
-				converting = false;
-				++fmt;
-			} else {
-				/* Illegal format string. */
-				break;
-			}
-
-		} else {
-
-			/*
-			 * Processing outside conversion specifier. Either skip white
-			 * spaces or match characters one by one. If conversion specifier
-			 * is detected, switch to coversion mode.
-			 */
-			if (isspace(*fmt)) {
-				/* Skip white spaces in the format string. */
-				while (isspace(*fmt)) {
-					++fmt;
-				}
-				/* Skip white spaces in the input. */
-				do {
-					c = in->pop(in);
-				} while (isspace(c));
-				if (c != -1) {
-					/* Input is not at EOF, so undo the last pop operation. */
-					in->undo(in);
-				}
-			} else if (*fmt == '%' && *(fmt + 1) != '%') {
-				/* Conversion specifier detected. Switch modes. */
-				converting = true;
-				/* Reset the conversion context. */
-				assign_supress = false;
-				assign_alloc = false;
-				width = -1;
-				length_mod = LMOD_NONE;
-				int_conv_unsigned = false;
-				int_conv_base = 0;
-				++fmt;
-			} else {
-				/* One by one matching. */
-				if (*fmt == '%') {
-					/* Escape sequence detected. */
-					++fmt;
-					assert(*fmt == '%');
-				}
-				c = in->pop(in);
-				if (c == -1) {
-					/* Input failure. */
-					break;
-				} else if (c != *fmt) {
-					/* Matching failure. */
-					in->undo(in);
-					matching_failure = true;
-					break;
-				} else {
-					++fmt;
-				}
-			}
-
-		}
-
-	}
-
-	in->release(in);
-
-	/* This somewhat complicated return value decision is required by POSIX. */
-	int rc;
-	if (matching_failure) {
-		rc = converted_cnt;
-	} else {
-		if (errno == EOK) {
-			rc = converted_cnt > 0 ? converted_cnt : EOF;
-		} else {
-			rc = EOF;
-		}
-	}
-	if (rc == EOF) {
-		/*
-		 * Caller will not know how many arguments were successfully converted,
-		 * so the deallocation of buffers is our responsibility.
-		 */
-		for (int i = 0; i < next_unused_buffer_idx; ++i) {
-			free(buffers[i]);
-			buffers[i] = NULL;
-		}
-		next_unused_buffer_idx = 0;
-	}
-	return rc;
-}
-
-/**
- * Convert formatted input from the stream.
- *
- * @param stream Input stream.
- * @param format Format description.
- * @param arg Output items.
- * @return The number of converted output items or EOF on failure.
- */
-int vfscanf(
-    FILE *restrict stream, const char *restrict format, va_list arg)
-{
-	_input_provider provider = {
-		{ 0 }, 0, 0, NULL, 0, NULL, _PROV_CONSTRUCTED,
-		_capture_stream, _pop_stream, _undo_stream,
-		_borrow_cursor_universal, _return_cursor_stream, _release_stream
-	};
-	provider.source.stream = stream;
-	return _internal_scanf(&provider, format, arg);
-}
-
-/**
- * Convert formatted input from the string.
- *
- * @param s Input string.
- * @param format Format description.
- * @param arg Output items.
- * @return The number of converted output items or EOF on failure.
- */
-int vsscanf(
-    const char *restrict s, const char *restrict format, va_list arg)
-{
-	_input_provider provider = {
-		{ 0 }, 0, 0, NULL, 0, NULL, _PROV_CONSTRUCTED,
-		_capture_string, _pop_string, _undo_string,
-		_borrow_cursor_universal, _return_cursor_string, _release_string
-	};
-	provider.source.string = s;
-	return _internal_scanf(&provider, format, arg);
-}
-
-/** @}
- */
