- now with a smarter assert

Fri, 02 May 2014 21:37:18 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Fri, 02 May 2014 21:37:18 +0300
changeset 125
85814c0918c5
parent 124
a7b769a0e537
child 126
c5858c0cd476

- now with a smarter assert

src/dataBuffer.cpp file | annotate | diff | comparison | revisions
src/expression.cpp file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/lexer.cpp file | annotate | diff | comparison | revisions
src/lexer.h file | annotate | diff | comparison | revisions
src/list.h file | annotate | diff | comparison | revisions
src/macros.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
src/string.h file | annotate | diff | comparison | revisions
--- a/src/dataBuffer.cpp	Fri May 02 20:37:27 2014 +0300
+++ b/src/dataBuffer.cpp	Fri May 02 21:37:18 2014 +0300
@@ -41,7 +41,8 @@
 //
 DataBuffer::~DataBuffer()
 {
-	assert (marks().isEmpty() && references().isEmpty());
+	ASSERT (marks().isEmpty());
+	ASSERT (references().isEmpty());
 	delete buffer();
 }
 
--- a/src/expression.cpp	Fri May 02 20:37:27 2014 +0300
+++ b/src/expression.cpp	Fri May 02 21:37:18 2014 +0300
@@ -390,7 +390,7 @@
 {
 	const OperatorInfo* info = &g_Operators[op->id()];
 	bool isconstexpr = true;
-	assert (values.size() == info->numoperands);
+	ASSERT_EQ (values.size(), info->numoperands)
 
 	for (ExpressionValue* val : values)
 	{
@@ -562,7 +562,7 @@
 			}
 
 			default:
-				assert (false);
+				error ("WTF bad expression with %1 operands", info->numoperands);
 		}
 
 		List<ExpressionValue*> values;
@@ -579,7 +579,8 @@
 		m_symbols.insert (lower, newvalue);
 	}
 
-	assert (m_symbols.size() == 1 && m_symbols.first()->type() == EXPRSYM_Value);
+	ASSERT_EQ (m_symbols.size(), 1)
+	ASSERT_EQ (m_symbols.first()->type(), EXPRSYM_Value)
 	ExpressionValue* val = static_cast<ExpressionValue*> (m_symbols.first());
 	return val;
 }
@@ -645,7 +646,6 @@
 
 		case TYPE_Void:
 		case TYPE_Unknown:
-			assert (false);
-			break;
+			error ("WTF: tried to convert bad expression value type %1 to buffer", m_valueType);
 	}
 }
--- a/src/format.h	Fri May 02 20:37:27 2014 +0300
+++ b/src/format.h	Fri May 02 21:37:18 2014 +0300
@@ -39,6 +39,7 @@
 	FormatArgument (char a) : m_text (a) {}
 	FormatArgument (int a) : m_text (String::fromNumber (a)) {}
 	FormatArgument (long a) : m_text (String::fromNumber (a)) {}
+	FormatArgument (size_t a) : m_text (String::fromNumber ((long) a)) {}
 	FormatArgument (const char* a) : m_text (a) {}
 
 	FormatArgument (void* a)
@@ -51,6 +52,9 @@
 		m_text.sprintf ("%p", a);
 	}
 
+	FormatArgument (std::nullptr_t) :
+		m_text (FormatArgument ((void*) 0).text()) {}
+
 	template<class T> FormatArgument (const List<T>& list)
 	{
 		if (list.isEmpty())
@@ -148,7 +152,7 @@
 {
 	std::vector<String> args;
 	expandFormatArguments (args, raw_args...);
-	assert (args.size() == sizeof... (raw_args));
+	ASSERT_EQ (args.size(), sizeof... (raw_args))
 	return formatArgs (fmtstr, args);
 }
 
@@ -205,9 +209,9 @@
 // caught in main() which prints the error to stderr and then exits.
 //
 template<typename... argtypes>
-void error (const String& fmtstr, const argtypes&... args)
+void error (const char* fmtstr, const argtypes&... args)
 {
-	error (format (fmtstr, args...));
+	error (format (String (fmtstr), args...));
 }
 
 //
--- a/src/lexer.cpp	Fri May 02 20:37:27 2014 +0300
+++ b/src/lexer.cpp	Fri May 02 21:37:18 2014 +0300
@@ -36,7 +36,7 @@
 //
 Lexer::Lexer()
 {
-	assert (gMainLexer == null);
+	ASSERT_EQ (gMainLexer, null);
 	gMainLexer = this;
 }
 
--- a/src/lexer.h	Fri May 02 20:37:27 2014 +0300
+++ b/src/lexer.h	Fri May 02 21:37:18 2014 +0300
@@ -73,7 +73,7 @@
 
 	inline TokenInfo* token() const
 	{
-		assert (hasValidToken() == true);
+		ASSERT (hasValidToken());
 		return &(*m_tokenPosition);
 	}
 
--- a/src/list.h	Fri May 02 20:37:27 2014 +0300
+++ b/src/list.h	Fri May 02 21:37:18 2014 +0300
@@ -29,7 +29,7 @@
 #ifndef BOTC_LIST_H
 #define BOTC_LIST_H
 
-#include <cassert>
+#include "macros.h"
 #include <algorithm>
 #include <deque>
 #include <initializer_list>
@@ -155,7 +155,7 @@
 template<typename T>
 void List<T>::removeAt (int pos)
 {
-	assert (pos < size());
+	ASSERT_LT (pos, size());
 	_deque.erase (_deque.begin() + pos);
 }
 
@@ -241,14 +241,14 @@
 template<typename T>
 inline T& List<T>::operator[] (int n)
 {
-	assert (n < size());
+	ASSERT_LT (n, size());
 	return _deque[n];
 }
 
 template<typename T>
 inline const T& List<T>::operator[] (int n) const
 {
-	assert (n < size());
+	ASSERT_LT (n, size());
 	return _deque[n];
 }
 
@@ -293,7 +293,9 @@
 template<typename T>
 List<T> List<T>::splice (int a, int b) const
 {
-	assert (a >= 0 && b >= 0 && a < size() && b < size() && a <= b);
+	ASSERT_RANGE (a, 0, size() - 1)
+	ASSERT_RANGE (b, 0, size() - 1)
+	ASSERT_LT_EQ (a, b)
 	List<T> result;
 
 	for (int i = a; i <= b; ++i)
--- a/src/macros.h	Fri May 02 20:37:27 2014 +0300
+++ b/src/macros.h	Fri May 02 21:37:18 2014 +0300
@@ -26,7 +26,8 @@
 	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#pragma once
+#ifndef BOTC_MACROS_H
+#define BOTC_MACROS_H
 
 #if !defined (__cplusplus) || __cplusplus < 201103L
 # error botc requires a C++11-compliant compiler to be built
@@ -43,7 +44,7 @@
 
 // On Windows, files are case-insensitive
 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
-#define FILE_CASEINSENSITIVE
+# define FILE_CASEINSENSITIVE
 #endif
 
 #define named_enum enum
@@ -55,4 +56,21 @@
 # define __attribute__(X)
 #endif
 
-#define deprecated __attribute__ ((deprecated))
\ No newline at end of file
+#define deprecated __attribute__ ((deprecated))
+
+template<typename... argtypes>
+void error (const char* fmtstr, const argtypes&... args);
+
+#define BOTC_GENERIC_ASSERT(A,B,OP,COMPLAINT) ((A OP B) ? (void) 0 : \
+	error ("assertion failed at " __FILE__ ":%1: " #A " (%2) " COMPLAINT " " #B " (%3)", __LINE__, A, B));
+
+#define ASSERT_EQ(A,B) BOTC_GENERIC_ASSERT (A, B, ==, "does not equal")
+#define ASSERT_NE(A,B) BOTC_GENERIC_ASSERT (A, B, !=, "is no different from")
+#define ASSERT_LT(A,B) BOTC_GENERIC_ASSERT (A, B, <, "is not less than")
+#define ASSERT_GT(A,B) BOTC_GENERIC_ASSERT (A, B, >, "is not greater than")
+#define ASSERT_LT_EQ(A,B) BOTC_GENERIC_ASSERT (A, B, <=, "is not at most")
+#define ASSERT_GT_EQ(A,B) BOTC_GENERIC_ASSERT (A, B, >=, "is not at least")
+#define ASSERT_RANGE(A,MIN,MAX) { ASSERT_LT_EQ(A, MAX); ASSERT_GT_EQ(A, MIN); }
+#define ASSERT(A) ASSERT_EQ (A, true)
+
+#endif // BOTC_MACROS_H
--- a/src/parser.cpp	Fri May 02 20:37:27 2014 +0300
+++ b/src/parser.cpp	Fri May 02 21:37:18 2014 +0300
@@ -854,7 +854,7 @@
 	// Return value
 	m_lexer->mustGetAnyOf ({TK_Int,TK_Void,TK_Bool,TK_Str});
 	comm->returnvalue = getTypeByName (m_lexer->token()->text); // TODO
-	assert (comm->returnvalue != -1);
+	ASSERT_NE (comm->returnvalue, -1);
 
 	// Number
 	m_lexer->mustGetNext (TK_Number);
@@ -877,7 +877,8 @@
 		CommandArgument arg;
 		m_lexer->mustGetAnyOf ({TK_Int,TK_Bool,TK_Str});
 		DataType type = getTypeByName (m_lexer->token()->text); // TODO
-		assert (type != -1 && type != TYPE_Void);
+		ASSERT_NE (type, -1)
+		ASSERT_NE (type, TYPE_Void)
 		arg.type = type;
 
 		m_lexer->mustGetNext (TK_Symbol);
@@ -1066,7 +1067,7 @@
 		default: break;
 	}
 
-	assert (false);
+	error ("WTF bad operator token %1", m_lexer->describeToken (m_lexer->token()));
 	return (AssignmentOperator) 0;
 }
 
--- a/src/string.h	Fri May 02 20:37:27 2014 +0300
+++ b/src/string.h	Fri May 02 21:37:18 2014 +0300
@@ -324,15 +324,17 @@
 			return stdString();
 		}
 
-		// =============================================================================
-		//
-		// Difference between indices @a and @b. @b can be -1, in which
-		// case it will be length() - 1.
-		//
-		inline int indexDifference (int a, int b)
+		void modifyIndex (int& a)
 		{
-			assert (b == -1 || b >= a);
-			return (b != -1 ? b - a : length() - 1 - a);
+			if (a < 0)
+				a = length() - a;
+		}
+
+		int indexDifference (int a, int b)
+		{
+			modifyIndex (a);
+			modifyIndex (b);
+			return b - a;
 		}
 
 	private:

mercurial