]> rtime.felk.cvut.cz Git - boost-statechart-viewer.git/commitdiff
Add creation of the transition table. Now the program can show the state machine...
authorpetr000 <silhavik.p@gmail.com>
Sat, 30 Apr 2011 14:36:45 +0000 (16:36 +0200)
committerpetr000 <silhavik.p@gmail.com>
Sat, 30 Apr 2011 14:36:45 +0000 (16:36 +0200)
src/iooper.h
src/visualizer.cpp

index acd72c79eb01fd182aba7331d2ff39b68bd00418..6a28b4142ec0a41b1965ed8405df22becbe3e255 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <fstream>
 #include <list>
+#include <string>
 
 #include "stringoper.h"
 
@@ -33,6 +34,25 @@ class IO_operations
        string outputFilename;
        string name_of_machine;
        string name_of_first_state;
+       string *table;
+       int nState;
+       int cols, rows;
+       int find_place(string model, int type)
+       {
+               if(type == 1)
+               {
+                       for(unsigned i = 3;i<events.size()+3;i++)
+                       {
+                               if(model.compare(0,model.size(),table[i])==0) return i;
+                       }
+               }
+               else 
+               {
+                       for(unsigned i = 1;i<states.size()+1;i++)
+                       if(model.compare(0,model.size(),table[i*cols+2])==0) return i;
+               }
+               return -1;
+       }
        public:
        IO_operations() {}
        
@@ -45,7 +65,10 @@ class IO_operations
                states = state;
                events = ev;
        }
-
+       ~IO_operations()
+       {
+               delete table;
+       }
        // set methods
        void setEvents(list<string> events)
        {
@@ -81,9 +104,13 @@ class IO_operations
        void write_states(ofstream& filestr) // write states
        {
                int pos1, pos2, cnt, subs;
-               string context, state, ctx;
+               nState = 1;
+               string context, state, ctx, sState, str;
                list<string> nstates = states;
                context = name_of_machine;
+               table[0] = "S";
+               table[1] = "Context";
+               table[2] = "State";
                for(list<string>::iterator i = nstates.begin();i!=nstates.end();i++) // write all states in the context of the automaton
                {
                        state = *i;
@@ -94,9 +121,14 @@ class IO_operations
                                ctx = cut_namespaces(state.substr(pos1+1));
                                if(ctx.compare(0,context.length(),context)==0)
                                {
-                                       filestr<<cut_namespaces(state.substr(0,pos1))<<";\n";
+                                       str = cut_namespaces(state.substr(0,pos1));
+                                       filestr<<str<<";\n";
+                                       table[cols*nState+2] = str;
+                                       table[cols*nState+1] = context;
+                                       nState+=1;
                                        nstates.erase(i);
                                        i--;
+                                       if(str.compare(0,str.length(),name_of_first_state)==0) table[cols*(nState-1)] = "*";
                                }
                        }
                        if(cnt==2)
@@ -106,10 +138,16 @@ class IO_operations
                                ctx = cut_namespaces(state.substr(pos1+1,pos2-pos1-1));
                                if(ctx.compare(0,context.length(),context)==0)
                                {                               
-                                       filestr<<cut_namespaces(state.substr(0,pos1))<<";\n";
+                                       str = cut_namespaces(state.substr(0,pos1));
+                                       filestr<<str<<";\n";
+                                       table[cols*nState+2] = str;
+                                       table[cols*nState+1] = context;                 
+                                       nState+=1;
+                                       if(str.compare(0,str.length(),name_of_first_state)==0) table[cols*(nState-1)] = "*";
                                }
                        }
                }
+               filestr<<name_of_first_state<<" [peripheries=2] ;\n";
                subs = 0;
                while(!nstates.empty()) // substates ?
                {
@@ -119,9 +157,9 @@ class IO_operations
                        pos2 = state.rfind(",");
                        context = cut_namespaces(state.substr(0,pos1));
                        filestr<<"label=\""<<context<<"\";\n";
-                       filestr<<cut_namespaces(state.substr(pos2+1))<<" [peripheries=2] ;\n";  
+                       sState = cut_namespaces(state.substr(pos2+1));
+                       filestr<<sState<<" [peripheries=2] ;\n";        
                        nstates.pop_front();    
-                       //std::cout<<states.size();     
                        for(list<string>::iterator i = nstates.begin();i!=nstates.end();i++)
                        {
                                state = *i;
@@ -132,9 +170,14 @@ class IO_operations
                                        ctx = cut_namespaces(state.substr(pos1+1));
                                        if(ctx.compare(0,context.length(),context)==0)
                                        {
-                                               filestr<<cut_namespaces(state.substr(0,pos1))<<";\n";
+                                               str = cut_namespaces(state.substr(0,pos1));
+                                               filestr<<str<<";\n";
+                                               table[cols*nState+2] = str;
+                                               table[cols*nState+1] = context;
+                                               nState+=1;
                                                nstates.erase(i);
                                                i--;
+                                               if(str.compare(0,str.length(),sState)==0) table[cols*(nState-1)] = "*";
                                        }
                                }
                                if(cnt==2)
@@ -142,7 +185,15 @@ class IO_operations
                                        pos1 = state.find(",");
                                        pos2 = state.rfind(",");
                                        ctx = cut_namespaces(state.substr(pos1+1,pos2-pos1-1));
-                                       if(ctx.compare(0,context.length(),context)==0) filestr<<cut_namespaces(state.substr(0,pos1))<<";\n";
+                                       if(ctx.compare(0,context.length(),context)==0) 
+                                       {
+                                               str = cut_namespaces(state.substr(0,pos1));
+                                               filestr<<str<<";\n";
+                                               table[cols*nState+2] = str;
+                                               table[cols*nState+1] = context;
+                                               nState+=1;
+                                               if(str.compare(0,str.length(),sState)==0) table[cols*(nState-1)] = "*";
+                                       }
                                }
                        }
                        filestr<<"}\n";
@@ -154,42 +205,93 @@ class IO_operations
        void write_transitions(ofstream& filestr) // write transitions
        {
                int pos1, pos2;
-               string state;
+               string params, state, event, dest;
                for(list<string>::iterator i = transitions.begin();i!=transitions.end();i++) // write all transitions
                {
-                       state = *i;
-                       pos1 = state.find(",");
-                       filestr<<cut_namespaces(state.substr(0,pos1))<<"->";
-                       pos2 = state.rfind(",");
-                       filestr<<cut_namespaces(state.substr(pos2+1));
-                       filestr<<"[label=\""<<cut_namespaces(state.substr(pos1+1,pos2-pos1-1))<<"\"];\n";
+                       params = *i;
+                       pos1 = params.find(",");
+                       state = cut_namespaces(params.substr(0,pos1));
+                       filestr<<state<<"->";
+                       pos2 = params.rfind(",");
+                       dest = cut_namespaces(params.substr(pos2+1));
+                       filestr<<dest;
+                       event = cut_namespaces(params.substr(pos1+1,pos2-pos1-1));
+                       filestr<<"[label=\""<<event<<"\"];\n";
+                       table[find_place(state,2)*cols+find_place(event,1)]=dest;
                }               
                return;
        }
 
+       void fill_table_with_events()
+       {
+               int j = 3;
+               for(list<string>::iterator i = events.begin();i!=events.end();i++)
+               {
+                       table[j] = *i;
+                       j++;
+               }
+       }
+
        void save_to_file() // save state automaton to file
        {
                if(!name_of_first_state.empty())        
                {       
                        ofstream filestr(outputFilename.c_str());
                        filestr<<"digraph "<< name_of_machine<< " {\n";
-                       filestr<<name_of_first_state<<" [peripheries=2] ;\n";
+                       cols = events.size()+3;
+                       rows = states.size()+1;
+                       table = new string [cols*rows];
+                       fill_table_with_events();                       
                        write_states(filestr);
                        write_transitions(filestr);
                        filestr<<"}";           
                        filestr.close();
+                       print_table();
                }
                else cout<<"No state machine was found. So no output file was created.\n";
                return;
        }
-               
+
+       void print_table()
+       {
+               cout<<"\nTRANSITION TABLE\n";
+               unsigned * len = new unsigned[cols];
+               len[0] = 1;
+               string line = "-|---|-";
+               for(unsigned i = 1; i<cols; i++)
+               {
+                       len[i] = 0;
+                       for(unsigned j = 0;j<rows;j++)
+                       {
+                               if(len[i]<table[j*cols+i].length()) len[i] = table[j*cols+i].length();
+                       }
+                       for(unsigned k = 0; k<len[i]; k++)
+                       {
+                               line.append("-");
+                       }
+                       line.append("-|-");
+               }
+               cout<<line<<"\n";
+               for(unsigned i = 0; i<rows; i++)
+               {
+                       cout<<" | ";            
+                       for(unsigned j = 0;j<cols;j++)
+                       {
+                               cout.width(len[j]);
+                               cout<<left<<table[i*cols+j]<<" | ";
+                       }
+                       cout<<"\n";
+                       cout<<line<<"\n";
+               }
+               delete len;
+       }
        // method for printing statistics about state automaton
        void print_stats() // print statistics
        {
                cout<<"\n"<<"Statistics: \n";
                cout<<"Number of states: "<<states.size()<<"\n";
                cout<<"Number of events: "<<events.size()<<"\n";
-               cout<<"Number of transitions: "<<transitions.size()<<"\n";
+               cout<<"Number of transitions: "<<transitions.size()<<"\n\n";
                return;
        }
 
index 3d3b964af1a509c2881c4db117098e3c75be13b9..b24fccac2fa360fef83b35ff88f2af846fe25d1c 100644 (file)
@@ -156,7 +156,6 @@ class FindStates : public ASTConsumer
                        loc = decl->getLocation();
                        if(loc.isValid())
                        {
-                               //cout<<decl->getKind()<<"ss\n";
                                if(decl->getKind()==35)
                                {                                       
                                        method_decl(decl);
@@ -222,7 +221,7 @@ class FindStates : public ASTConsumer
                line = get_line_of_code(x.str());
                output = "";
                int pos;
-               const NamedDecl *namedDecl = dyn_cast<NamedDecl>(decl);         
+               const NamedDecl *namedDecl = dyn_cast<NamedDecl>(decl);
                if(is_derived(line))
                {
                        const CXXRecordDecl *cRecDecl = dyn_cast<CXXRecordDecl>(decl);
@@ -456,7 +455,7 @@ int main(int argc, char **argv)
        mdc->BeginSourceFile(lang, &pp);//start using diagnostic
        ParseAST(pp, &c, ctx, false, false);
        mdc->EndSourceFile(); //end using diagnostic
-       IO_operations *io = new IO_operations(outputFilename, c.getStateMachine(), c.getNameOfFirstState(), c.getTransitions(), c.getStates(), c.getEvents());  
+       IO_operations *io = new IO_operations(outputFilename, c.getStateMachine(), c.getNameOfFirstState(), c.getTransitions(), c.getStates(), c.getEvents());
        io->save_to_file();
        io->print_stats();
        mdc->print_stats();