From a3275160b67d9ef74c6e1d157d9db96421abdd10 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 7 Sep 2014 20:51:17 +0200
Subject: [PATCH] fix segfault when reallocating vector optimize all Regexps

---
 alib2algo/src/regexp/RegExpOptimize.cpp | 27 ++++++++++++++++++++++++-
 alib2algo/src/regexp/RegExpOptimize.h   |  9 +++++++--
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/alib2algo/src/regexp/RegExpOptimize.cpp b/alib2algo/src/regexp/RegExpOptimize.cpp
index 03574a2935..9203ccb549 100644
--- a/alib2algo/src/regexp/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/RegExpOptimize.cpp
@@ -13,6 +13,29 @@
 
 namespace regexp {
 
+regexp::RegExp RegExpOptimize::optimize(const regexp::RegExp& regexp)
+{
+    regexp::RegExp * out = NULL;
+    regexp.getData().Accept((void*) &out, *this);
+    regexp::RegExp res( std::move( * out ) );
+    delete out;
+    return res;
+}
+
+void RegExpOptimize::Visit(void* userData, const regexp::FormalRegExp& regexp)
+{
+    regexp::RegExp * &ret = *(regexp::RegExp **) userData;
+
+    ret = new regexp::RegExp( this->optimize( regexp ) );
+}
+
+void RegExpOptimize::Visit(void* userData, const regexp::UnboundedRegExp& regexp)
+{
+    regexp::RegExp * &ret = *(regexp::RegExp **) userData;
+
+    ret = new regexp::RegExp( this->optimize( regexp ) );
+}
+
 FormalRegExp RegExpOptimize::optimize( FormalRegExp const & regexp )
 {
 	throw exception::AlibException("Unimplemented");
@@ -563,7 +586,9 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node )
 				{
 					optimized = optimizedIter = true;
 
+					size_t off = it - node->elements.begin();
 					node->elements.push_back( iter->clone( ) );
+					it = node->elements.begin() + off;
 
 					delete childConcat;
 					it = node->elements.erase( it );
@@ -1194,7 +1219,7 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & node )
 		// std::cout << RegExp( tmp ) << std::endl;
 
 		// copy the range <it;sth>, delete it and go back to the iter node
-	std::vector<UnboundedRegExpElement*> copyRange;
+		std::vector<UnboundedRegExpElement*> copyRange;
 		copyRange.insert( copyRange.end(), std::next( it ), c1Iter );
 		it = node->elements.erase( std::next( it ), c1Iter );
 		it = std::prev( it );
diff --git a/alib2algo/src/regexp/RegExpOptimize.h b/alib2algo/src/regexp/RegExpOptimize.h
index 8f6ff40ee2..56fe7ea06c 100644
--- a/alib2algo/src/regexp/RegExpOptimize.h
+++ b/alib2algo/src/regexp/RegExpOptimize.h
@@ -12,6 +12,8 @@
 #include <functional>
 #include <iterator>
 
+#include <regexp/RegExp.h>
+
 #include <regexp/unbounded/UnboundedRegExp.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
 
@@ -57,9 +59,11 @@ namespace regexp {
  *
  *  - X1 : -> : a* + \e = a*
  */
-class RegExpOptimize
+class RegExpOptimize : public regexp::VisitableRegExpBase::visitor_type
 {
 public:
+    regexp::RegExp optimize( const regexp::RegExp & regexp );
+
     regexp::UnboundedRegExp optimize( const regexp::UnboundedRegExp & regexp );
     void optimize( regexp::UnboundedRegExpElement & regexp );
 
@@ -74,7 +78,8 @@ private:
     regexp::UnboundedRegExpElement * optimize( regexp::UnboundedRegExpEpsilon const * const & node );
     regexp::UnboundedRegExpElement * optimize( regexp::UnboundedRegExpEmpty const * const & node );
 
-
+    void Visit(void*, const regexp::UnboundedRegExp& regexp);
+    void Visit(void*, const regexp::FormalRegExp& regexp);
 
 private:
     bool A1( regexp::UnboundedRegExpAlternation * const & node );
-- 
GitLab