[git commit] istream: fix readin<traits, char, bool>

Bernhard Reutner-Fischer rep.dot.nop at gmail.com
Thu May 24 08:29:46 UTC 2012


commit: http://git.uclibc.org/uClibc++/commit/?id=b18de12d8c3cc1bb61b72816acae001c1310e314
branch: http://git.uclibc.org/uClibc++/commit/?id=refs/heads/master

add test for __istream_readin<traits, char, bool>

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
 ChangeLog                         |    1 +
 include/istream_helpers           |   34 ++++++++++-
 tests/iotest.cpp                  |   15 +++++
 tests/sstreamtest.cpp             |  110 +++++++++++++++++++++++++++++++++++++
 tests/testoutput/iotest.good      |   12 ++++
 tests/testoutput/sstreamtest.good |   34 +++++++++++
 6 files changed, 202 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b476e2c..4887d09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 0.2.4
+-   istream: fix readin<traits, char, bool>
 
 0.2.3
 -   eh: Add alloc/free for dependent exception
diff --git a/include/istream_helpers b/include/istream_helpers
index ddece1c..588df7f 100644
--- a/include/istream_helpers
+++ b/include/istream_helpers
@@ -103,12 +103,38 @@ namespace std{
 	public:
 		inline static void readin(basic_istream<char, traits >& stream, bool & var)
 		{
+			/* 22.4.2.1.2.4 */
 			basic_string<char, traits > temp;
 			temp = _readToken( stream);
-			if(temp == "true" || temp == "True" || temp == "TRUE" || temp == "1"){
-				var = true;
-			}else{
-				var = false;
+			if (stream.flags() & ios_base::boolalpha) {
+				if (temp == "true") // truename()
+					var = true;
+				else {
+					var = false;
+					if (temp != "false") // falsename()
+						stream.setstate(ios_base::failbit);
+				}
+			} else {
+				long int i = 0;
+				int ret;
+				if (stream.flags() & ios_base::dec) {
+					ret = sscanf(temp.c_str(), "%ld", &i );
+				} else {
+					if (stream.flags() & ios_base::oct) {
+						ret = sscanf(temp.c_str(), "%lo", (unsigned long int *)(&i));
+					} else if (stream.flags() & ios_base::hex) {
+						if (stream.flags() & ios_base::uppercase) {
+							ret = sscanf(temp.c_str(), "%lX", (unsigned long int *)(&i));
+						} else {
+							ret = sscanf(temp.c_str(), "%lx", (unsigned long int *)(&i));
+						}
+					} else {
+						ret = sscanf(temp.c_str(), "%li", &i);
+					}
+				}
+				if (ret != 1 || i >> 1)
+					stream.setstate(ios_base::failbit);
+				var = ret == 1 && bool(i);
 			}
 		}
 	};
diff --git a/tests/iotest.cpp b/tests/iotest.cpp
index 830c52d..0114c5c 100644
--- a/tests/iotest.cpp
+++ b/tests/iotest.cpp
@@ -80,6 +80,21 @@ int main(){
 	std::cout << "This is the number 200:" << 200.1 << std::endl;
 	std::cout << "This is the number 200:" << (short)200 << std::endl;
 	std::cout << "True: " << true << std::endl;
+	std::cout << "True: " << (bool)1 << std::endl;
+	std::cout << "not True: " << std::noboolalpha << "true" << "(the string), " << true << std::boolalpha << std::endl;
+	std::cout << "boolalpha set: " << (bool)(std::cout.flags() & std::ios_base::boolalpha) << std::endl;
+	std::cout << "not True: " << 1U << std::endl;
+	std::cout << "not True: " << -1L << std::endl;
+	std::cout << "not True: " << (1?1:0) << std::endl;
+	//std::cout << "not True: " << __builtin_constant_p(-1) << std::endl;
+	std::cout << "False: " << false << std::endl;
+	std::cout << "False: " << (bool)0 << std::endl;
+	std::cout << "not False: " << 0 << std::endl;
+	//std::cout << "not False: " << '\0' << std::endl;
+	//std::cout << "not False: " << L'\0' << std::endl;
+	std::cout << "not False: " << -0 << std::endl;
+	std::cout << "not False: " << -0U << std::endl;
+	std::cout << "not False: " << -0L << std::endl;
 	
 	float i = 0;
 	long double j = 0;
diff --git a/tests/sstreamtest.cpp b/tests/sstreamtest.cpp
index 26c9532..df3d521 100644
--- a/tests/sstreamtest.cpp
+++ b/tests/sstreamtest.cpp
@@ -76,5 +76,115 @@ int main(){
 
 	std::cout << o.str() << std::endl;
 
+	{
+	std::stringstream ss;
+	if (ss.flags() &~ (std::ios_base::skipws | std::ios_base::dec))
+		std::cout << "ERROR: stream constructor with invalid additional flags "
+			<< (ss.flags() &~ (std::ios_base::skipws | std::ios_base::dec))
+			<< " set" << std::endl;
+	}
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+	/* test __istream_readin<traits, char, bool>
+	   Check that we handle boolalpha correctly
+	 */
+	std::cout << "Checking __istream_readin<traits, char, bool>" << std::endl;
+	struct tests_s {
+		unsigned format;
+		std::string input;
+		std::string output;
+		bool b;
+		bool fail;
+	};
+	struct tests_s tests[] = {
+		{0, "true", "0", 0, 1},
+		{0, "True", "0", 0, 1},
+		{0, "TRUE", "0", 0, 1},
+		{0, "false", "0", 0, 1},
+		{0, "-1", "1", 1, 1},
+		{0, "0", "0", 0, 0},
+		{0, "1", "1", 1, 0},
+		{0, "2", "1", 1, 1},
+
+		{3, "true", "0", 0, 1},
+		{3, "True", "0", 0, 1},
+		{3, "TRUE", "0", 0, 1},
+		{3, "false", "1", 1, 1},
+		{3, "-0x1", "1", 1, 1},
+		{3, "0x0", "0", 0, 0},
+		{3, "0x1", "1", 1, 0},
+		{3, "0x2", "1", 1, 1},
+
+		{1, "true", "0", 0, 1},
+		{1, "True", "0", 0, 1},
+		{1, "TRUE", "0", 0, 1},
+		{1, "false", "0", 0, 1},
+		{1, "-1", "1", 1, 1},
+		{1, "0", "0", 0, 0},
+		{1, "1", "1", 1, 0},
+		{1, "2", "1", 1, 1},
+
+		{2, "true", "1", 1, 0},
+		{2, "True", "0", 0, 1},
+		{2, "TRUE", "0", 0, 1},
+		{2, "false", "0", 0, 0},
+		{2, "-1", "0", 0, 1},
+		{2, "0", "0", 0, 1},
+		{2, "1", "0", 0, 1},
+		{2, "2", "0", 0, 1},
+	};
+	for (unsigned int i = 0; i < ARRAY_SIZE(tests); i++) {
+		struct tests_s *test = tests + i;
+		std::string brief;
+		std::stringstream ss;
+		bool b;
+
+		if (test->format == 3) {
+				brief = "no manip., hex";
+				ss << std::hex;
+				if (!(ss.flags() & ss.hex))
+					std::cout << "FAILED to set hex via operator<<"
+						<< std::endl;
+		} else if (test->format == 2) {
+				brief = "boolalpha     ";
+				ss << std::boolalpha;
+				if (!(ss.flags() & ss.boolalpha))
+					std::cout << "FAILED to set boolalpha via operator<<"
+						<< std::endl;
+		} else if (test->format == 1) {
+				brief = "noboolalpha   ";
+				ss << std::noboolalpha;
+				if (ss.flags() & ss.boolalpha)
+					std::cout << "FAILED to unset boolalpha via operator<<"
+						<< std::endl;
+		} else {
+				brief = "no manipulator";
+		}
+		ss.str(test->input);
+		ss >> b;
+		std::ostringstream os;
+		os << b;
+		std::cout << brief << ": "
+			<< test->input << " >> bool == \"" << os.str() << "\""
+			<< " (expected " << test->output << ")"
+			<< ((os.str() == test->output && ss.fail() == test->fail)
+				? ", ok" : ", FAILED")
+			<< std::endl;
+		if (b != test->b)
+			std::cout
+				<< "WRONG intermediate result bool(" << int(b)
+				<< "), expected " << int(test->b)
+				<< " for input " << test->input
+				<< std::endl;
+		if (ss.fail() != test->fail)
+			std::cout
+				<< "WRONG failbit " << int(ss.fail())
+				<< ", expected " << int(test->fail)
+				<< " for input " << test->input
+				<< std::endl;
+	}
+	std::cout << std::endl;
 	return 0;
 }
diff --git a/tests/testoutput/iotest.good b/tests/testoutput/iotest.good
index d3e4469..2f1497d 100644
--- a/tests/testoutput/iotest.good
+++ b/tests/testoutput/iotest.good
@@ -3,6 +3,18 @@ Test string: Test string
 This is the number 200:200.100000
 This is the number 200:200
 True: true
+True: true
+not True: true(the string), 1
+boolalpha set: true
+not True: 1
+not True: -1
+not True: 1
+False: false
+False: false
+not False: 0
+not False: 0
+not False: 0
+not False: 0
 Pointer: 0xbc614e
 Please enter two floats:You entered: 14564.264648 98347.000000
 Checking ostream_iterator
diff --git a/tests/testoutput/sstreamtest.good b/tests/testoutput/sstreamtest.good
index 6b35e8b..ae45a5a 100644
--- a/tests/testoutput/sstreamtest.good
+++ b/tests/testoutput/sstreamtest.good
@@ -29,3 +29,37 @@ abcdefghiojklmnopqrstuvwxyz
 abcdefghiojklmnopqrstuvwxyz 
 Test string
 
+Checking __istream_readin<traits, char, bool>
+no manipulator: true >> bool == "0" (expected 0), ok
+no manipulator: True >> bool == "0" (expected 0), ok
+no manipulator: TRUE >> bool == "0" (expected 0), ok
+no manipulator: false >> bool == "0" (expected 0), ok
+no manipulator: -1 >> bool == "1" (expected 1), ok
+no manipulator: 0 >> bool == "0" (expected 0), ok
+no manipulator: 1 >> bool == "1" (expected 1), ok
+no manipulator: 2 >> bool == "1" (expected 1), ok
+no manip., hex: true >> bool == "0" (expected 0), ok
+no manip., hex: True >> bool == "0" (expected 0), ok
+no manip., hex: TRUE >> bool == "0" (expected 0), ok
+no manip., hex: false >> bool == "1" (expected 1), ok
+no manip., hex: -0x1 >> bool == "1" (expected 1), ok
+no manip., hex: 0x0 >> bool == "0" (expected 0), ok
+no manip., hex: 0x1 >> bool == "1" (expected 1), ok
+no manip., hex: 0x2 >> bool == "1" (expected 1), ok
+noboolalpha   : true >> bool == "0" (expected 0), ok
+noboolalpha   : True >> bool == "0" (expected 0), ok
+noboolalpha   : TRUE >> bool == "0" (expected 0), ok
+noboolalpha   : false >> bool == "0" (expected 0), ok
+noboolalpha   : -1 >> bool == "1" (expected 1), ok
+noboolalpha   : 0 >> bool == "0" (expected 0), ok
+noboolalpha   : 1 >> bool == "1" (expected 1), ok
+noboolalpha   : 2 >> bool == "1" (expected 1), ok
+boolalpha     : true >> bool == "1" (expected 1), ok
+boolalpha     : True >> bool == "0" (expected 0), ok
+boolalpha     : TRUE >> bool == "0" (expected 0), ok
+boolalpha     : false >> bool == "0" (expected 0), ok
+boolalpha     : -1 >> bool == "0" (expected 0), ok
+boolalpha     : 0 >> bool == "0" (expected 0), ok
+boolalpha     : 1 >> bool == "0" (expected 0), ok
+boolalpha     : 2 >> bool == "0" (expected 0), ok
+


More information about the uClibc-cvs mailing list