|
From: <got...@us...> - 2009-04-22 21:29:13
|
Revision: 228
http://scstudio.svn.sourceforge.net/scstudio/?rev=228&view=rev
Author: gotthardp
Date: 2009-04-22 21:28:52 +0000 (Wed, 22 Apr 2009)
Log Message:
-----------
Initial implementation of dependency checks (feature request #2556693). Next step: add the actual dependency data.
Enhanced the Z.120 output to correctly print msc.h with ReferenceNodes.
Modified Paths:
--------------
trunk/CMakeLists.txt
trunk/src/check/boundedness/universal_boundedness_checker.cpp
trunk/src/check/boundedness/universal_boundedness_checker.h
trunk/src/check/liveness/deadlock_checker.cpp
trunk/src/check/liveness/deadlock_checker.h
trunk/src/check/liveness/livelock_checker.cpp
trunk/src/check/liveness/livelock_checker.h
trunk/src/check/order/acyclic_checker.cpp
trunk/src/check/order/acyclic_checker.h
trunk/src/check/order/fifo_checker.cpp
trunk/src/check/order/fifo_checker.h
trunk/src/check/race/race_checker.cpp
trunk/src/check/race/race_checker.h
trunk/src/check/structure/name_checker.cpp
trunk/src/check/structure/name_checker.h
trunk/src/data/Z120/z120.h
trunk/src/data/Z120/z120_save.cpp
trunk/src/data/checker.h
trunk/src/data/msc.h
trunk/src/view/visio/addon/dllmodule.rc
trunk/src/view/visio/addon/document.cpp
trunk/src/view/visio/addon/document.h
trunk/src/view/visio/scstudio.nsi
Modified: trunk/CMakeLists.txt
===================================================================
--- trunk/CMakeLists.txt 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/CMakeLists.txt 2009-04-22 21:28:52 UTC (rev 228)
@@ -13,6 +13,12 @@
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_INSTALL_PREFIX}/share/scripts)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE(TestBigEndian)
+TEST_BIG_ENDIAN(BIG_ENDIAN)
+IF(BIG_ENDIAN)
+ ADD_DEFINITIONS(-DHOST_IS_BIG_ENDIAN)
+ENDIF(BIG_ENDIAN)
+
FIND_PACKAGE(Boost REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
@@ -23,7 +29,7 @@
INCLUDE_DIRECTORIES(src)
INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/include)
-IF (WIN32)
+IF (WIN32)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH})
ENDIF(WIN32)
Modified: trunk/src/check/boundedness/universal_boundedness_checker.cpp
===================================================================
--- trunk/src/check/boundedness/universal_boundedness_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/boundedness/universal_boundedness_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -105,6 +105,14 @@
}
+Checker::PreconditionList UniversalBoundednessChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ result.push_back(CheckerPrecondition("Unique instance names", CP_RECOMMENDED));
+
+ return result;
+}
+
HMscPtr UniversalBoundednessChecker::create_counter_example(const MscElementPList& to_cycle, const MscElementPList& cycle)
{
HMscPtr p;
Modified: trunk/src/check/boundedness/universal_boundedness_checker.h
===================================================================
--- trunk/src/check/boundedness/universal_boundedness_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/boundedness/universal_boundedness_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -138,12 +138,14 @@
static const std::string vertex_number_attribute;
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
+ virtual std::string get_property_name() const
{ return "Universal Boundedness"; }
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
/**
* Checks whether hmsc satisfy universal boundedness property.
*/
Modified: trunk/src/check/liveness/deadlock_checker.cpp
===================================================================
--- trunk/src/check/liveness/deadlock_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/liveness/deadlock_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -123,6 +123,13 @@
}
}
+Checker::PreconditionList DeadlockChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ // no preconditions
+ return result;
+}
+
HMscPtr DeadlockChecker::create_counter_example(const MscElementPListList& path)
{
HMscPathDuplicator duplicator;
Modified: trunk/src/check/liveness/deadlock_checker.h
===================================================================
--- trunk/src/check/liveness/deadlock_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/liveness/deadlock_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -126,12 +126,14 @@
DeadlockChecker(){};
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
+ virtual std::string get_property_name() const
{ return "Deadlock"; }
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
/**
* Checks whether hmsc satisfy deadlock free property.
*/
Modified: trunk/src/check/liveness/livelock_checker.cpp
===================================================================
--- trunk/src/check/liveness/livelock_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/liveness/livelock_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -87,6 +87,13 @@
return reachable;
}
+Checker::PreconditionList LivelockChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ // no preconditions
+ return result;
+}
+
HMscPtr LivelockChecker::check(HMscPtr hmsc, ChannelMapperPtr chm)
{
HMscPtr p;
Modified: trunk/src/check/liveness/livelock_checker.h
===================================================================
--- trunk/src/check/liveness/livelock_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/liveness/livelock_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -108,12 +108,14 @@
LivelockChecker();
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
+ virtual std::string get_property_name() const
{ return "Livelock"; }
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
static LivelockCheckerPtr instance();
bool is_supported(ChannelMapperPtr chm);
Modified: trunk/src/check/order/acyclic_checker.cpp
===================================================================
--- trunk/src/check/order/acyclic_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/order/acyclic_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -21,6 +21,13 @@
AcyclicCheckerPtr AcyclicChecker::m_instance;
+Checker::PreconditionList AcyclicChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ // no preconditions
+ return result;
+}
+
BMscPtr AcyclicChecker::create_counter_example(BMscPtr& bmsc, const MscElementPList& path)
{
MscElement* last_event = path.back();
Modified: trunk/src/check/order/acyclic_checker.h
===================================================================
--- trunk/src/check/order/acyclic_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/order/acyclic_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -61,12 +61,14 @@
}
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
+ virtual std::string get_property_name() const
{ return "Acyclic"; }
-
+
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
/**
* Checks whether bmsc has acyclic events' dependecy
*/
Modified: trunk/src/check/order/fifo_checker.cpp
===================================================================
--- trunk/src/check/order/fifo_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/order/fifo_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -23,6 +23,13 @@
const std::string FifoChecker::channel_id_attribute = "fifo_channel_id";
FifoCheckerPtr FifoChecker::m_instance;
+Checker::PreconditionList FifoChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ // no preconditions
+ return result;
+}
+
BMscPtr FifoChecker::create_counter_example(BMscPtr& bmsc, Event* e_1, Event* e_2)
{
BMscDuplicator duplicator;
Modified: trunk/src/check/order/fifo_checker.h
===================================================================
--- trunk/src/check/order/fifo_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/order/fifo_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -65,12 +65,14 @@
public:
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
+ virtual std::string get_property_name() const
{ return "FIFO"; }
-
+
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
/**
* Name of channel id attribute
*/
Modified: trunk/src/check/race/race_checker.cpp
===================================================================
--- trunk/src/check/race/race_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/race/race_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -239,6 +239,13 @@
&m_visual_initiator,&m_causal_initiator,&m_instance_marker);
}
+Checker::PreconditionList RaceChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ // no preconditions
+ return result;
+}
+
BMscPtr RaceChecker::create_counter_example(Event* e1, Event* e2)
{
BMscDuplicator duplicator;
Modified: trunk/src/check/race/race_checker.h
===================================================================
--- trunk/src/check/race/race_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/race/race_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -222,12 +222,14 @@
RaceChecker();
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
+ virtual std::string get_property_name() const
{ return "Race Conditions"; }
-
+
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
BMscPtr check_bmsc(BMscPtr bmsc, ChannelMapperPtr mapper);
BMscPtr check(BMscPtr bmsc, ChannelMapperPtr mapper);
Modified: trunk/src/check/structure/name_checker.cpp
===================================================================
--- trunk/src/check/structure/name_checker.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/structure/name_checker.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -76,6 +76,13 @@
}
+Checker::PreconditionList NameChecker::get_preconditions(MscPtr msc) const
+{
+ Checker::PreconditionList result;
+ // no preconditions
+ return result;
+}
+
HMscPtr NameChecker::create_duplicate_counter_example(const MscElementPListList& path)
{
HMscPathDuplicator duplicator;
Modified: trunk/src/check/structure/name_checker.h
===================================================================
--- trunk/src/check/structure/name_checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/check/structure/name_checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -115,12 +115,14 @@
NameChecker(){};
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
// note: DLL in Windows cannot return pointers to static data
- virtual std::string get_description() const
- { return "Instance names"; }
+ virtual std::string get_property_name() const
+ { return "Unique instance names"; }
+ virtual PreconditionList get_preconditions(MscPtr msc) const;
+
/**
* Checks whether a given hmsc contains consistent set of instances.
*/
Modified: trunk/src/data/Z120/z120.h
===================================================================
--- trunk/src/data/Z120/z120.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/data/Z120/z120.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -45,6 +45,10 @@
virtual int save_msc(std::ostream& stream, const std::string &name, const std::vector<MscPtr>& msc);
protected:
+ int save_msc(std::ostream& stream, const MscPtr& msc);
+ // note: insertion to m_printing must not invalidate iterators
+ std::list<MscPtr> m_printing;
+
//! export a basic MSC drawing
int save_bmsc(std::ostream& stream, const BMscPtr& bmsc);
//! export a HMSC drawing
Modified: trunk/src/data/Z120/z120_save.cpp
===================================================================
--- trunk/src/data/Z120/z120_save.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/data/Z120/z120_save.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -29,26 +29,40 @@
int result = 0; // error count
stream << "mscdocument " << name << ";" << std::endl;
- for(std::vector<MscPtr>::const_iterator pos = msc.begin();
- pos != msc.end(); pos++)
+ std::set<std::string> printed;
+
+ // list of MSC to be printed
+ // new references may be added to m_printing by save_hmsc()
+ std::copy(msc.begin(), msc.end(), std::back_inserter(m_printing));
+
+ for(std::list<MscPtr>::const_iterator pos = m_printing.begin();
+ pos != m_printing.end(); pos++)
{
- BMscPtr bmsc = boost::dynamic_pointer_cast<BMsc>(*pos);
- HMscPtr hmsc = boost::dynamic_pointer_cast<HMsc>(*pos);
-
- if(bmsc != NULL)
- result += save_bmsc(stream, bmsc);
- else if(hmsc != NULL)
- result += save_hmsc(stream, hmsc);
- else
+ // if not already generated
+ if(printed.find((*pos)->get_label()) == printed.end())
{
- // unexpected pointer
- result++;
+ result += save_msc(stream, *pos);
+ printed.insert((*pos)->get_label());
}
}
+ m_printing.clear();
return 0;
}
+int Z120::save_msc(std::ostream& stream, const MscPtr& msc)
+{
+ BMscPtr bmsc = boost::dynamic_pointer_cast<BMsc>(msc);
+ HMscPtr hmsc = boost::dynamic_pointer_cast<HMsc>(msc);
+
+ if(bmsc != NULL)
+ return save_bmsc(stream, bmsc);
+ else if(hmsc != NULL)
+ return save_hmsc(stream, hmsc);
+ else
+ return 1; // unexpected pointer
+}
+
template <class Ptr>
class PtrIDMap
{
@@ -78,12 +92,33 @@
list.push_back(item);
}
+// for debugging purposes
+void print_element_attributes(std::ostream& stream, const MscElementPtr& element)
+{
+ stream << "/* ";
+
+ std::set<std::string> attributes = element->get_attribute_names();
+ stream << "[";
+ for(std::set<std::string>::const_iterator pos = attributes.begin();
+ pos != attributes.end(); pos++)
+ {
+ stream << *pos;
+ }
+ stream << "]";
+
+ stream << " */" << std::endl;
+}
+
void print_event(std::ostream& stream, PtrIDMap<MscMessagePtr>& message_id_map,
const EventPtr& event)
{
+ // print_element_attributes(stream, event);
+
CompleteMessagePtr complete_message = event->get_complete_message();
if(complete_message != NULL)
{
+ // print_element_attributes(stream, complete_message);
+
if(complete_message->get_send_event() == event)
stream << "out " << complete_message->get_label()
<< "," << message_id_map.get_id(complete_message)
@@ -97,6 +132,8 @@
IncompleteMessagePtr incomplete_message = event->get_incomplete_message();
if(incomplete_message != NULL)
{
+ // print_element_attributes(stream, incomplete_message);
+
if(incomplete_message->is_lost())
stream << "out " << incomplete_message->get_label()
<< "," << message_id_map.get_id(incomplete_message)
@@ -113,6 +150,7 @@
PtrIDMap<MscMessagePtr> message_id_map; // message instance identifiers
PtrIDMap<EventPtr> event_id_map; // event identifiers
+ // print_element_attributes(stream, bmsc);
stream << "msc " << bmsc->get_label() << ";" << std::endl;
// declare instances
@@ -126,12 +164,15 @@
for(InstancePtrList::const_iterator ipos = bmsc->get_instances().begin();
ipos != bmsc->get_instances().end(); ipos++)
{
+ // print_element_attributes(stream, *ipos);
stream << (*ipos)->get_label() << ": instance;" << std::endl;
// walk through event areas
for(EventAreaPtr area = (*ipos)->get_first();
area != NULL; area = area->get_next())
{
+ // print_element_attributes(stream, area);
+
StrictOrderAreaPtr strict_area = boost::dynamic_pointer_cast<StrictOrderArea>(area);
if(strict_area != NULL)
{
@@ -203,6 +244,7 @@
// nodes to be processed; this is to avoid recursion
std::list<HMscNodePtr> node_stack;
+ // print_element_attributes(stream, hmsc);
stream << "msc " << hmsc->get_label() << ";" << std::endl;
// initialize the stack with the start node
@@ -212,6 +254,8 @@
for(std::list<HMscNodePtr>::const_iterator npos = node_stack.begin();
npos != node_stack.end(); npos++)
{
+ // print_element_attributes(stream, *npos);
+
StartNodePtr start_node = boost::dynamic_pointer_cast<StartNode>(*npos);
if(start_node != NULL)
{
@@ -237,6 +281,7 @@
{
stream << "L" << node_id_map.get_id(*npos)
<< ": reference " << reference_node->get_msc()->get_label();
+ m_printing.push_back(reference_node->get_msc());
}
EndNodePtr end_node = boost::dynamic_pointer_cast<EndNode>(*npos);
@@ -252,6 +297,8 @@
for(NodeRelationPtrSet::const_iterator spos = predecessor_node->get_successors().begin();
spos != predecessor_node->get_successors().end(); spos++)
{
+ // print_element_attributes(stream, *spos);
+
SuccessorNode *successor = (*spos)->get_successor();
// is it a first item being printed?
Modified: trunk/src/data/checker.h
===================================================================
--- trunk/src/data/checker.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/data/checker.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -45,11 +45,35 @@
public:
/**
- * Human readable description of this check.
+ * Human readable name of the property being checked.
*/
- virtual std::string get_description() const = 0;
-
+ virtual std::string get_property_name() const = 0;
+
+ enum CheckerPriority
+ {
+ CP_REQUIRED, //! error if not satisfied
+ CP_RECOMMENDED, //! warning if not satisfied
+ CP_DISREGARDED //! may not be satisfied
+ };
+
+ struct CheckerPrecondition
+ {
+ CheckerPrecondition(const std::string& name, CheckerPriority prio)
+ : property_name(name), priority(prio)
+ { }
+
+ std::string property_name;
+ CheckerPriority priority;
+ };
+ //! List of properties that must be satisfied before executing the check.
+ typedef std::vector<CheckerPrecondition> PreconditionList;
+
/**
+ * Returns a list of preconditions for the check.
+ */
+ virtual PreconditionList get_preconditions(MscPtr msc) const = 0;
+
+ /**
* Removes no more needed attributes.
*
* Descendat of this class should remove attributes of MscElements that are no
Modified: trunk/src/data/msc.h
===================================================================
--- trunk/src/data/msc.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/data/msc.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -172,7 +172,6 @@
return (m_attributes.find(name)!=m_attributes.end());
}
-
/**
* \brief Returns dynamic attribute of MscElement.
*
@@ -274,7 +273,23 @@
m_attributes.erase(i);
}
}
-
+
+ /**
+ * \brief List all attributes of MscElement.
+ */
+ std::set<std::string> get_attribute_names()
+ {
+ std::set<std::string> result;
+
+ for(AttributePMap::const_iterator i = m_attributes.begin();
+ i != m_attributes.end(); i++)
+ {
+ result.insert(i->first);
+ }
+
+ return result;
+ }
+
bool get_marked() const
{
return m_marked;
Modified: trunk/src/view/visio/addon/dllmodule.rc
===================================================================
--- trunk/src/view/visio/addon/dllmodule.rc 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/view/visio/addon/dllmodule.rc 2009-04-22 21:28:52 UTC (rev 228)
@@ -72,8 +72,8 @@
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,9,0
- PRODUCTVERSION 0,2,9,0
+ FILEVERSION 0,2,10,0
+ PRODUCTVERSION 0,2,10,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x9L
@@ -90,13 +90,13 @@
BEGIN
VALUE "CompanyName", "Masaryk University Brno"
VALUE "FileDescription", "Microsoft Visio add-on for design and verification of Message Sequence Charts (MSC)."
- VALUE "FileVersion", "0.2.9"
+ VALUE "FileVersion", "0.2.10"
VALUE "InternalName", "scstudio.vsl"
VALUE "LegalCopyright", "(c) Petr Gotthard. All rights reserved."
VALUE "OriginalFilename", "scstudio.vsl"
VALUE "PrivateBuild", "$Revision$"
VALUE "ProductName", "Sequence Chart Studio"
- VALUE "ProductVersion", "0.2.9"
+ VALUE "ProductVersion", "0.2.10"
END
END
BLOCK "VarFileInfo"
Modified: trunk/src/view/visio/addon/document.cpp
===================================================================
--- trunk/src/view/visio/addon/document.cpp 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/view/visio/addon/document.cpp 2009-04-22 21:28:52 UTC (rev 228)
@@ -32,6 +32,9 @@
// Install WTL80 under e.g. "C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\"
#include <atldlgs.h>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/topological_sort.hpp>
+
CDocumentMonitor::CDocumentMonitor(CStudioAddon *addon,
Visio::IVApplicationPtr vsoApp, Visio::IVDocumentPtr vsoDocument)
{
@@ -353,6 +356,31 @@
vsoDocument->SetCustomMenus(vsoMenus);
}
+struct CheckExecutionStatus
+{
+ CheckExecutionStatus()
+ : executed(false), satisfied(false)
+ { }
+
+ bool executed;
+ bool satisfied;
+};
+typedef std::vector<CheckExecutionStatus> CheckExecutionStatusList;
+
+CheckerPtrList::const_iterator CDocumentMonitor::find_checker(const std::string& property_name) const
+{
+ nocase_comparator is_equal;
+
+ for(CheckerPtrList::const_iterator cpos = m_checkers.begin();
+ cpos != m_checkers.end(); cpos++)
+ {
+ if(is_equal((*cpos)->get_property_name(), property_name))
+ return cpos;
+ }
+
+ return m_checkers.end();
+}
+
VAORC CDocumentMonitor::OnMenuRun(Visio::IVApplicationPtr vsoApp)
{
// clear the verification report
@@ -362,73 +390,163 @@
Visio::IVPagePtr vsoPage = vsoApp->GetActivePage();
MscPtr msc = extractor.extract_msc(vsoPage);
- if(msc != NULL)
+ if(msc == NULL)
{
- BMscPtr bmsc = boost::dynamic_pointer_cast<BMsc>(msc);
- HMscPtr hmsc = boost::dynamic_pointer_cast<HMsc>(msc);
+ m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
+ << "Graphical error(s) in drawing. No properties verified.");
+ return VAORC_FAILURE;
+ }
- SRChannelMapperPtr srm = SRChannelMapper::instance();
+ CheckExecutionStatusList status;
+ // initialize status for each checker
+ status.insert(status.begin(), m_checkers.size(), CheckExecutionStatus());
- int satisfied_count = 0;
- int violated_count = 0;
+ typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
+ boost::property<boost::vertex_color_t, boost::default_color_type> > Graph;
+ Graph G(m_checkers.size());
- for(CheckerPtrList::const_iterator cpos = m_checkers.begin();
- cpos != m_checkers.end(); cpos++)
+ for(CheckerPtrList::const_iterator cpos = m_checkers.begin();
+ cpos != m_checkers.end(); cpos++)
+ {
+ size_t icheck = cpos - m_checkers.begin();
+
+ Checker::PreconditionList preconditions = (*cpos)->get_preconditions(msc);
+ // check the preconditions
+ for(Checker::PreconditionList::const_iterator ppos = preconditions.begin();
+ ppos != preconditions.end(); ppos++)
{
- BMscCheckerPtr bmsc_checker = boost::dynamic_pointer_cast<BMscChecker>(*cpos);
- HMscCheckerPtr hmsc_checker = boost::dynamic_pointer_cast<HMscChecker>(*cpos);
+ CheckerPtrList::const_iterator checker = find_checker(ppos->property_name);
+ if(checker != m_checkers.end())
+ {
+ size_t idep = checker - m_checkers.begin();
+ // add dependency to the graph
+ // if edge (u,v) appears in the graph, then v comes before u in the ordering
+ boost::add_edge(icheck, idep, G);
+ }
+ }
+ }
- if(bmsc_checker != NULL && bmsc != NULL)
+ typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef std::vector<Vertex> Container;
+ Container check_order;
+
+ try
+ {
+ // output iterator in reverse topological order
+ boost::topological_sort(G, std::back_inserter(check_order));
+ }
+ catch(boost::not_a_dag)
+ {
+ m_reportView->Print(RS_ERROR, stringize() << "internal error: broken dependencies");
+ return VAORC_FAILURE;
+ }
+
+ BMscPtr bmsc = boost::dynamic_pointer_cast<BMsc>(msc);
+ HMscPtr hmsc = boost::dynamic_pointer_cast<HMsc>(msc);
+
+ SRChannelMapperPtr srm = SRChannelMapper::instance();
+
+ int satisfied_count = 0;
+ int violated_count = 0;
+
+ for(Container::const_iterator cpos = check_order.begin();
+ cpos != check_order.end(); cpos++)
+ {
+ CheckerPtr msc_checker = m_checkers[*cpos];
+ bool all_preconditions = true;
+
+ Checker::PreconditionList preconditions = msc_checker->get_preconditions(msc);
+ // check the preconditions
+ for(Checker::PreconditionList::const_iterator ppos = preconditions.begin();
+ ppos != preconditions.end(); ppos++)
+ {
+ CheckerPtrList::const_iterator checker = find_checker(ppos->property_name);
+ if(checker != m_checkers.end())
{
- BMscPtr result = bmsc_checker->check(bmsc, srm);
- if(result != NULL)
+ size_t idep = checker - m_checkers.begin();
+
+ if((!status[idep].executed || !status[idep].satisfied)
+ && ppos->priority == Checker::CP_REQUIRED)
{
- m_reportView->Print(RS_ERROR, stringize() << vsoPage->Name << ": "
- << (*cpos)->get_description() << " violated.", result);
- violated_count++;
+ all_preconditions = false;
}
- else
- {
- m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
- << (*cpos)->get_description() << " satisfied.");
- satisfied_count++;
- }
}
+ else
+ {
+ if(ppos->priority == Checker::CP_REQUIRED)
+ all_preconditions = false;
- if(hmsc_checker != NULL && hmsc != NULL)
+ m_reportView->Print(RS_WARNING, stringize() << vsoPage->Name << ": "
+ << "skipping " << msc_checker->get_property_name()
+ << " due to unknown dependency: " << ppos->property_name);
+ }
+ }
+
+ if(!all_preconditions)
+ {
+ m_reportView->Print(RS_WARNING, stringize() << vsoPage->Name << ": "
+ << msc_checker->get_property_name() << " skipped.");
+ continue;
+ }
+
+ BMscCheckerPtr bmsc_checker = boost::dynamic_pointer_cast<BMscChecker>(msc_checker);
+ if(bmsc_checker != NULL && bmsc != NULL)
+ {
+ BMscPtr result = bmsc_checker->check(bmsc, srm);
+ status[*cpos].executed = true;
+
+ if(result != NULL)
{
- HMscPtr result = hmsc_checker->check(hmsc, srm);
- if(result != NULL)
- {
- m_reportView->Print(RS_ERROR, stringize() << vsoPage->Name << ": "
- << (*cpos)->get_description() << " violated.", result);
- violated_count++;
- }
- else
- {
- m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
- << (*cpos)->get_description() << " satisfied.");
- satisfied_count++;
- }
+ status[*cpos].satisfied = false;
+ violated_count++;
+
+ m_reportView->Print(RS_ERROR, stringize() << vsoPage->Name << ": "
+ << msc_checker->get_property_name() << " violated.", result);
}
+ else
+ {
+ status[*cpos].satisfied = true;
+ satisfied_count++;
- (*cpos)->cleanup_attributes();
+ m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
+ << msc_checker->get_property_name() << " satisfied.");
+ }
}
- if(satisfied_count == 0 && violated_count == 0)
+ HMscCheckerPtr hmsc_checker = boost::dynamic_pointer_cast<HMscChecker>(msc_checker);
+ if(hmsc_checker != NULL && hmsc != NULL)
{
- m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
- << "No verification algorithms applicable. No properties verified.");
+ HMscPtr result = hmsc_checker->check(hmsc, srm);
+ status[*cpos].executed = true;
+
+ if(result != NULL)
+ {
+ status[*cpos].satisfied = false;
+ violated_count++;
+
+ m_reportView->Print(RS_ERROR, stringize() << vsoPage->Name << ": "
+ << msc_checker->get_property_name() << " violated.", result);
+ }
+ else
+ {
+ status[*cpos].satisfied = true;
+ satisfied_count++;
+
+ m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
+ << msc_checker->get_property_name() << " satisfied.");
+ }
}
- return VAORC_SUCCESS;
+ msc_checker->cleanup_attributes();
}
- else
+
+ if(satisfied_count == 0 && violated_count == 0)
{
- m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
- << "Graphical error(s) in drawing. No properties verified.");
- return VAORC_FAILURE;
+ m_reportView->Print(RS_NOTICE, stringize() << vsoPage->Name << ": "
+ << "No verification algorithms applicable. No properties verified.");
}
+
+ return VAORC_SUCCESS;
}
std::wstring filter_to_wstring(const std::string& str)
Modified: trunk/src/view/visio/addon/document.h
===================================================================
--- trunk/src/view/visio/addon/document.h 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/view/visio/addon/document.h 2009-04-22 21:28:52 UTC (rev 228)
@@ -28,6 +28,9 @@
class CStudioAddon;
+typedef std::vector<CheckerPtr> CheckerPtrList;
+typedef std::vector<FormatterPtr> FormatterPtrList;
+
class CDocumentMonitor
{
public:
@@ -66,10 +69,10 @@
int LoadModulesFromRegistry(HKEY hKey);
std::vector<HINSTANCE> m_open_modules;
- typedef std::vector<FormatterPtr> FormatterPtrList;
FormatterPtrList m_formatters;
- typedef std::vector<CheckerPtr> CheckerPtrList;
+
CheckerPtrList m_checkers;
+ CheckerPtrList::const_iterator find_checker(const std::string& property_name) const;
CStudioAddon *m_addon;
Visio::IVApplicationPtr m_vsoApp;
Modified: trunk/src/view/visio/scstudio.nsi
===================================================================
--- trunk/src/view/visio/scstudio.nsi 2009-04-22 09:56:16 UTC (rev 227)
+++ trunk/src/view/visio/scstudio.nsi 2009-04-22 21:28:52 UTC (rev 228)
@@ -21,7 +21,7 @@
; -- General ---------------------------
-!define VERSION "0.2.9"
+!define VERSION "0.2.10"
Name "Sequence Chart Studio"
OutFile "scstudio-setup-${VERSION}.exe"
@@ -146,6 +146,7 @@
WriteRegStr HKCU '${RegModulesPath}' 'sc_boundedness' 'scboundedness.dll'
WriteRegStr HKCU '${RegModulesPath}' 'sc_liveness' 'scliveness.dll'
WriteRegStr HKCU '${RegModulesPath}' 'sc_order' 'scorder.dll'
+ WriteRegStr HKCU '${RegModulesPath}' 'sc_structure' 'scstructure.dll'
WriteRegStr HKCU '${RegModulesPath}' 'sc_race' 'scrace.dll'
WriteRegStr HKCU '${RegModulesPath}' 'sc_z120' 'scZ120.dll'
WriteRegStr HKCU '${RegModulesPath}' 'sc_engmann' 'scengmann.dll'
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|