2 ////////////////////////////////////////////////////////////////////////////////////////
4 // This file is part of Boost Statechart Viewer.
6 // Boost Statechart Viewer is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // Boost Statechart Viewer is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Boost Statechart Viewer. If not, see <http://www.gnu.org/licenses/>.
19 ////////////////////////////////////////////////////////////////////////////////////////
25 #include "stringoper.h"
31 list<string> transitions;
34 string outputFilename;
35 string name_of_machine;
36 string name_of_first_state;
40 int find_place(string model, int type)
44 for(unsigned i = 3;i<events.size()+3;i++)
46 if(model.compare(0,model.size(),table[i])==0) return i;
51 for(unsigned i = 1;i<states.size()+1;i++)
52 if(model.compare(0,model.size(),table[i*cols+2])==0) return i;
59 IO_operations( const string outputFile, const string FSM_name, const string firstState, const list<string> trans, const list<string> state, const list<string> ev )
61 outputFilename = outputFile;
62 name_of_machine = FSM_name;
63 name_of_first_state = firstState;
73 void setEvents(list<string> events)
75 this->events = events;
78 void setTransitions(list<string> transitions)
80 this->transitions = transitions;
83 void setStates(list<string> states)
85 this->states = states;
88 void setNameOfStateMachine(string name_of_FSM)
90 name_of_machine = name_of_FSM;
93 void setNameOfFirstState(string first_state)
95 name_of_first_state = first_state;
98 void setOutputFilename(string outputFilename)
100 this->outputFilename = outputFilename;
103 // outputfile writing methods
104 void write_states(ofstream& filestr) // write states
106 int pos1, pos2, cnt, subs;
108 string context, state, ctx, sState, str;
109 list<string> nstates = states;
110 context = name_of_machine;
112 table[1] = "Context";
114 for(list<string>::iterator i = nstates.begin();i!=nstates.end();i++) // write all states in the context of the automaton
117 cnt = count(state,',');
120 pos1 = state.find(",");
121 ctx = cut_namespaces(state.substr(pos1+1));
122 if(ctx.compare(0,context.length(),context)==0)
124 str = cut_namespaces(state.substr(0,pos1));
126 table[cols*nState+2] = str;
127 table[cols*nState+1] = context;
131 if(str.compare(0,str.length(),name_of_first_state)==0) table[cols*(nState-1)] = "*";
136 pos1 = state.find(",");
137 pos2 = state.rfind(",");
138 ctx = cut_namespaces(state.substr(pos1+1,pos2-pos1-1));
139 if(ctx.compare(0,context.length(),context)==0)
141 str = cut_namespaces(state.substr(0,pos1));
143 table[cols*nState+2] = str;
144 table[cols*nState+1] = context;
146 if(str.compare(0,str.length(),name_of_first_state)==0) table[cols*(nState-1)] = "*";
150 filestr<<name_of_first_state<<" [peripheries=2] ;\n";
152 while(!nstates.empty()) // substates ?
154 state = nstates.front();
155 filestr<<"subgraph cluster"<<subs<<" {\n";
156 pos1 = state.find(",");
157 pos2 = state.rfind(",");
158 context = cut_namespaces(state.substr(0,pos1));
159 filestr<<"label=\""<<context<<"\";\n";
160 sState = cut_namespaces(state.substr(pos2+1));
161 filestr<<sState<<" [peripheries=2] ;\n";
163 for(list<string>::iterator i = nstates.begin();i!=nstates.end();i++)
166 cnt = count(state,',');
169 pos1 = state.find(",");
170 ctx = cut_namespaces(state.substr(pos1+1));
171 if(ctx.compare(0,context.length(),context)==0)
173 str = cut_namespaces(state.substr(0,pos1));
175 table[cols*nState+2] = str;
176 table[cols*nState+1] = context;
180 if(str.compare(0,str.length(),sState)==0) table[cols*(nState-1)] = "*";
185 pos1 = state.find(",");
186 pos2 = state.rfind(",");
187 ctx = cut_namespaces(state.substr(pos1+1,pos2-pos1-1));
188 if(ctx.compare(0,context.length(),context)==0)
190 str = cut_namespaces(state.substr(0,pos1));
192 table[cols*nState+2] = str;
193 table[cols*nState+1] = context;
195 if(str.compare(0,str.length(),sState)==0) table[cols*(nState-1)] = "*";
205 void write_transitions(ofstream& filestr) // write transitions
208 string params, state, event, dest;
209 for(list<string>::iterator i = transitions.begin();i!=transitions.end();i++) // write all transitions
212 pos1 = params.find(",");
213 state = cut_namespaces(params.substr(0,pos1));
214 filestr<<state<<"->";
215 pos2 = params.rfind(",");
216 dest = cut_namespaces(params.substr(pos2+1));
218 event = cut_namespaces(params.substr(pos1+1,pos2-pos1-1));
219 filestr<<"[label=\""<<event<<"\"];\n";
220 table[find_place(state,2)*cols+find_place(event,1)]=dest;
225 void fill_table_with_events()
228 for(list<string>::iterator i = events.begin();i!=events.end();i++)
235 void save_to_file() // save state automaton to file
237 if(!name_of_first_state.empty())
239 ofstream filestr(outputFilename.c_str());
240 filestr<<"digraph "<< name_of_machine<< " {\n";
241 cols = events.size()+3;
242 rows = states.size()+1;
243 table = new string [cols*rows];
244 fill_table_with_events();
245 write_states(filestr);
246 write_transitions(filestr);
251 else cout<<"No state machine was found. So no output file was created.\n";
257 cout<<"\nTRANSITION TABLE\n";
258 unsigned * len = new unsigned[cols];
260 string line = "-|---|-";
261 for(unsigned i = 1; i<cols; i++)
264 for(unsigned j = 0;j<rows;j++)
266 if(len[i]<table[j*cols+i].length()) len[i] = table[j*cols+i].length();
268 for(unsigned k = 0; k<len[i]; k++)
275 for(unsigned i = 0; i<rows; i++)
278 for(unsigned j = 0;j<cols;j++)
281 cout<<left<<table[i*cols+j]<<" | ";
288 // method for printing statistics about state automaton
289 void print_stats() // print statistics
291 cout<<"\n"<<"Statistics: \n";
292 cout<<"Number of states: "<<states.size()<<"\n";
293 cout<<"Number of events: "<<events.size()<<"\n";
294 cout<<"Number of transitions: "<<transitions.size()<<"\n\n";