Line data Source code
1 : /*******************************************************************************
2 : * *
3 : * Cosmos:(C)oncept et (O)utils (S)tatistique pour les (Mo)deles *
4 : * (S)tochastiques *
5 : * *
6 : * Copyright (C) 2009-2012 LSV & LACL *
7 : * Authors: Paolo Ballarini Benoît Barbot & Hilal Djafri *
8 : * Website: http://www.lsv.ens-cachan.fr/Software/cosmos *
9 : * *
10 : * This program is free software; you can redistribute it and/or modify *
11 : * it under the terms of the GNU General Public License as published by *
12 : * the Free Software Foundation; either version 3 of the License, or *
13 : * (at your option) any later version. *
14 : * *
15 : * This program is distributed in the hope that it will be useful, *
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 : * GNU General Public License for more details. *
19 : * *
20 : * You should have received a copy of the GNU General Public License along *
21 : * with this program; if not, write to the Free Software Foundation, Inc., *
22 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
23 : *******************************************************************************
24 : */
25 :
26 : /**
27 : *
28 : *
29 : * \author Benoît Barbot
30 : */
31 :
32 : #include <unistd.h>
33 : #include <sys/stat.h>
34 : #include <stdlib.h>
35 : #include <cstdlib>
36 : #include <err.h>
37 : #include <errno.h>
38 : #include <math.h>
39 :
40 : #include <fstream>
41 : #include <iostream>
42 : #include <string>
43 : #include <sstream>
44 : #include <iomanip>
45 :
46 : #include "SimpleSerializer.hpp"
47 : #include "server.hpp"
48 : #include "parameters.hpp"
49 : #include "Generator.hpp"
50 : #include "GspnParser/unfolder.hpp"
51 : #include "GspnParser/Gspn-Grml-Output.hpp"
52 : #include "GspnParser/Gspn-Writer-Color.hpp"
53 :
54 : /**
55 : * A function to manipulate call to system
56 : * The result of the call to cmd is read from its standart
57 : * ouput and put in a string.
58 : */
59 : std::string systemStringResult(const char* cmd);
60 :
61 : /**
62 : * Clean the temporary directory
63 : */
64 : void cleanTmp(void);
65 :
66 : void exec_or_die(std::string cmd, std::string error_message);
67 :
68 : using namespace std;
69 :
70 32 : string systemStringResult(const char* cmd) {
71 32 : FILE* pipe = popen(cmd, "r");
72 32 : if (!pipe) return "";
73 : char buffer[128];
74 64 : string result;
75 160 : while(!feof(pipe)) {
76 64 : if(fgets(buffer, 128, pipe) != NULL)
77 32 : result += buffer;
78 : }
79 32 : pclose(pipe);
80 32 : return result;
81 : }
82 :
83 :
84 : /**
85 : * The global parameter structure
86 : */
87 35 : parameters P;
88 :
89 67 : void cleanTmp(void){
90 67 : if(P.tmpStatus & TS_DESTROY){
91 126 : string cmd;
92 63 : cmd = "rm -rf " + P.tmpPath;
93 63 : if(system(cmd.c_str()) !=0)warnx("Fail to clean temporary file");
94 : }
95 67 : }
96 :
97 0 : void exec_or_die(std::string cmd, std::string error_message){
98 0 : if( system(cmd.c_str()) != 0) {
99 0 : cerr << error_message << endl;
100 0 : exit(EXIT_FAILURE);
101 : }
102 0 : }
103 :
104 : /**
105 : * Main function
106 : * Build the simulator and launch it.
107 : */
108 35 : int main(int argc, char** argv) {
109 :
110 : //Start the timer for build time.
111 35 : auto startbuild = chrono::steady_clock::now();
112 :
113 : // Fill the P structure from the command line
114 35 : P.parseCommandLine(argc,argv);
115 :
116 34 : if (P.verbose>0){
117 34 : if(P.isTTY && !P.guiGreatSpnMode){
118 0 : cout << "\033(0";
119 0 : cout << setw(P.terminalWidth/2-14) << "\x6c";
120 0 : cout.fill('\x71');
121 0 : cout << setw(28) << "\x6b" << endl;
122 0 : cout.fill(' ');
123 0 : cout << setw(P.terminalWidth/2-14) << "\x78";
124 0 : cout << "\033(B" << " Cosmos " << "\033(0";
125 0 : cout << "\x78" << endl;
126 0 : cout << setw(P.terminalWidth/2-14) << "\x6d";
127 0 : cout.fill('\x71');
128 0 : cout << setw(28) << "\x6a" << endl;
129 0 : cout.fill(' ');
130 0 : cout << "\033(B";
131 : }else {
132 34 : cout.fill('#');
133 34 : cout << setw(P.terminalWidth) << "#" << endl;
134 34 : cout << setw(P.terminalWidth/2+14) << " Cosmos ";
135 34 : cout << setw(P.terminalWidth-(P.terminalWidth/2 +14)) << "#" << endl;
136 34 : cout << setw(P.terminalWidth) << "#" << endl;
137 34 : cout.fill(' ');
138 : }
139 : }
140 34 : if(P.verbose>1){
141 34 : cout << "Actions: " << ((P.tmpStatus& TS_GEN) ? "Generate " : "");
142 34 : cout << ((P.tmpStatus& TS_BUILD) ? " Build " : "");
143 34 : cout << ((P.tmpStatus& TS_RUN) ? " Run " : "");
144 34 : cout << ((P.tmpStatus& TS_DESTROY) ? " Clean " : "") << endl;
145 : }
146 : //assert(cout<< "Cosmos compile in DEBUG mode!"<<endl);
147 :
148 : //If tmpStatus require it generate random tmp directory
149 34 : if (P.tmpStatus & TS_DESTROY) {
150 64 : string newtmp = systemStringResult("mktemp -d tmpCosmos-XXXXXX");
151 32 : if(!newtmp.empty())P.tmpPath=newtmp.substr(0,newtmp.length()-1);
152 : }
153 :
154 : //If the tmp directory do not exist faill.
155 34 : if(mkdir(P.tmpPath.c_str(), 0777) != 0){
156 33 : if(errno != EEXIST){
157 0 : err(EXIT_FAILURE,"Fail to build temporary directory:%s",P.tmpPath.c_str());
158 : }
159 : }
160 34 : if(P.verbose>2)cout << "Temporary directory set to:" << P.tmpPath << endl;
161 34 : atexit(cleanTmp);
162 :
163 : // create and open a character archive for output
164 : {
165 68 : std::ofstream ofs(P.tmpPath + "/parameters.txt");
166 34 : Serializer oa(ofs);
167 34 : P.serialize(oa);
168 : }
169 :
170 :
171 34 : if(P.generateLHA==SamplingLoop && P.dataPDFCDF.empty())
172 0 : P.dataPDFCDF = P.tmpPath+"/defaultOutput.dat";
173 :
174 34 : if(P.verbose>2)cout << "Binary directory path set to:" << P.Path << endl;
175 :
176 : //Parse models and generate code
177 34 : if((P.tmpStatus & TS_GEN) && (P.modelType == GSPN )){
178 : //Parse and generate the gspn and lha.
179 67 : shared_ptr<GspnType> pGSPN = ParseGSPN();
180 :
181 34 : if ( !pGSPN ) {
182 0 : cout << "Fail to parse the GSPN." << endl;
183 0 : return(EXIT_FAILURE);
184 : }
185 :
186 : // Unfold and export the model if required
187 34 : if (!P.unfold.empty()) {
188 2 : unfolder unfold(*pGSPN);
189 2 : ofstream unfoldfile(P.unfold, ios::out | ios::trunc);
190 1 : unfold.export_grml(unfoldfile);
191 1 : return EXIT_SUCCESS;
192 : }
193 :
194 : // Export the model in GrML if required
195 33 : if (!P.outputModel.empty()) {
196 : using namespace xml_output;
197 0 : GspnGrmlOutput outspn(*pGSPN);
198 0 : ofstream outfile(P.outputModel, ios::out | ios::trunc);
199 0 : outfile << outspn;
200 0 : return EXIT_SUCCESS;
201 : }
202 :
203 : // Check that the model is not empty and generate the code
204 33 : if (pGSPN->pl > 0 && pGSPN->tr > 0) {
205 66 : Gspn_Writer_Color writer(*pGSPN, P);
206 33 : writer.writeFile();
207 33 : writer.writeDotFile(P.tmpPath + "/templatePetriNet.dot");
208 : } else {
209 0 : cout << "Empty model for the GSPN: abort" << endl;
210 0 : return EXIT_FAILURE;
211 : }
212 :
213 :
214 33 : if(P.MaxRuns == 0 && P.lightSimulator){
215 0 : auto cmd = "cp "+P.Path+"../src/LightSimulator/*.* "+P.tmpPath;
216 0 : if(P.verbose>=3)cout << cmd << endl;
217 0 : exec_or_die(cmd, "Fail to copy files");
218 0 : cmd = "cd "+P.tmpPath+"; ./build.sh";
219 0 : if(P.verbose>=3)cout << cmd << endl;
220 0 : exec_or_die(cmd, "Fail to copy files");
221 0 : return EXIT_SUCCESS;
222 : }
223 :
224 : //Parse the LHA
225 33 : if(!P.lightSimulator)
226 33 : if ( ! ParseLHA(*pGSPN)) {
227 0 : cout << "Fail to build the LHA." << endl;;
228 0 : return(EXIT_FAILURE);
229 : }
230 :
231 : // Generate Main
232 66 : generateMain();
233 : } else {
234 :
235 0 : if ( ! ParseLHA()) {
236 0 : cout << "Fail to build the LHA. Try to go on anyway" << endl;;
237 : }
238 : }
239 :
240 33 : if(P.modelType == External){
241 0 : auto cmd = "cp "+P.PathGspn +" "+P.tmpPath+"/main.cpp";
242 0 : if(P.verbose>=3)cout << cmd << endl;
243 0 : exec_or_die(cmd, "Fail to copy files");
244 : }
245 :
246 : //Compile the simulator
247 33 : if(P.tmpStatus & TS_BUILD){
248 31 : if ( !build()) {
249 0 : cout << "Fail to Compile the model.";
250 0 : return(EXIT_FAILURE);
251 : }
252 : }
253 :
254 : //stop the timer for building, display the time if required.
255 33 : auto endtime = chrono::steady_clock::now();
256 33 : chrono::duration<double> buildtime= endtime-startbuild;
257 33 : if(P.verbose>0)cout<<"Time for building the simulator:\t"<< buildtime.count() << "s"<< endl;
258 33 : if(P.guiGreatSpnMode)cout << "#{GUI}# RESULT STAT build_time " << buildtime.count() << endl;
259 :
260 : // Run
261 33 : if(P.tmpStatus & TS_RUN){
262 31 : launchServer(P);
263 : }
264 :
265 33 : cleanTmp();
266 33 : return (EXIT_SUCCESS);
267 105 : }
|