]> SALOME platform Git repositories - modules/yacs.git/blob - src/yacsloader/driver.cxx
Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / yacsloader / driver.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "yacsconfig.h"
20 #include "RuntimeSALOME.hxx"
21 #include "Proc.hxx"
22 #include "Logger.hxx"
23 #include "Exception.hxx"
24 #include "Executor.hxx"
25 #include "parsers.hxx"
26 #include "VisitorSaveState.hxx"
27 #include "VisitorSaveSalomeSchema.hxx"
28 #include "LoadState.hxx"
29 #include "Dispatcher.hxx"
30 #include "LinkInfo.hxx"
31
32 #ifdef SALOME_KERNEL
33 #include "SALOME_NamingService.hxx"
34 #include "SALOME_ModuleCatalog.hh"
35 #endif
36
37 #include <iostream>
38 #include <fstream>
39 #include <argp.h>
40
41 using YACS::YACSLoader;
42 using namespace YACS::ENGINE;
43 using namespace std;
44
45
46 // --- use of glibc argp interface for parsing unix-style arguments
47
48 const char *argp_program_version ="driver V0.1";
49 const char *argp_program_bug_address ="<nepal@nepal.edf.fr>";
50 static char doc[] ="driver -- a SALOME YACS graph executor";
51 static char args_doc[] = "graph.xml";
52
53 static struct argp_option options[] =
54   {
55     {"display",         'd', "level", 0,                   "Display dot files: 0=never to 3=very often"},
56     {"verbose",         'v', 0,       0,                   "Produce verbose output" },
57     {"stop-on-error",   's', 0,       0,                   "Stop on first error" },
58     {"dump-on-error",   'e', "file",  OPTION_ARG_OPTIONAL, "Stop on first error and dump state"},
59     {"dump-final",      'f', "file",  OPTION_ARG_OPTIONAL, "dump final state"},
60     {"load-state",      'l', "file",  0,                   "Load State from a previous partial execution"},
61     {"save-xml-schema", 'x', "file",  OPTION_ARG_OPTIONAL, "dump xml schema"},
62     { 0 }
63   };
64
65 struct arguments
66 {
67   char *args[1];
68   int display;
69   int verbose;
70   int stop;
71   char *dumpErrorFile;
72   char *finalDump;
73   char *xmlSchema;
74   char *loadState;
75 };
76
77 static error_t
78 parse_opt (int key, char *arg, struct argp_state *state)
79 {
80   // Get the input argument from argp_parse, which we
81   // know is a pointer to our arguments structure. 
82   struct arguments *myArgs = (arguments*)state->input;
83   
84   switch (key)
85     {
86     case 'd':
87       myArgs->display = atoi(arg);
88       break;
89     case 'v':
90       myArgs->verbose = 1;
91       break;
92     case 's':
93       myArgs->stop = 1;
94       break;
95     case 'e':
96       myArgs->stop = 1;
97       if (arg)
98         myArgs->dumpErrorFile = arg;
99       else
100         myArgs->dumpErrorFile = "dumpErrorState.xml";
101       break;
102     case 'f':
103       if (arg)
104         myArgs->finalDump = arg;
105       else
106         myArgs->finalDump = "finalDumpState.xml";
107       break;      
108     case 'l':
109       myArgs->loadState = arg;
110       break;
111     case 'x':
112       if (arg)
113         myArgs->xmlSchema = arg;
114       else
115         myArgs->xmlSchema = "saveSchema.xml";
116       break;      
117
118     case ARGP_KEY_ARG:
119       if (state->arg_num >=1) // Too many arguments.
120         argp_usage (state);
121       myArgs->args[state->arg_num] = arg;
122       break;
123       
124     case ARGP_KEY_END:
125       if (state->arg_num < 1) // Not enough arguments.
126         argp_usage (state);
127       break;
128      
129     default:
130       return ARGP_ERR_UNKNOWN;
131     }
132   return 0;
133 }
134
135 // Our argp parser.
136 static struct argp argp = { options, parse_opt, args_doc, doc };
137
138 void timer(std::string msg)
139 {
140   struct timeval tv;
141   gettimeofday(&tv,NULL);
142   long t=tv.tv_sec*1000+tv.tv_usec/1000;
143   static long t0=t;
144   gettimeofday(&tv,NULL);
145   std::cerr << msg << tv.tv_sec*1000+tv.tv_usec/1000-t0 << " ms" << std::endl;
146 }
147
148 main (int argc, char* argv[])
149 {
150   struct arguments myArgs;
151      
152   // Default values.
153   myArgs.display = 0;
154   myArgs.verbose = 0;
155   myArgs.stop = 0;
156   myArgs.dumpErrorFile= "";
157   myArgs.finalDump = "";
158   myArgs.loadState = "";
159   myArgs.xmlSchema = "";
160
161   // Parse our arguments; every option seen by parse_opt will be reflected in arguments.
162   argp_parse (&argp, argc, argv, 0, 0, &myArgs);
163     cerr << "graph = " << myArgs.args[0] 
164          << " options: display=" << myArgs.display 
165          << " verbose="<<myArgs.verbose
166          << " stop-on-error=" << myArgs.stop;
167   if (myArgs.stop)
168     cerr << " dumpErrorFile=" << myArgs.dumpErrorFile << endl;
169   else
170     cerr << endl;
171
172   timer("Starting ");
173   RuntimeSALOME::setRuntime();
174
175   // Try to load the session catalog if it exists
176   try
177     {
178       YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
179       CORBA::ORB_ptr orb = runTime->getOrb();
180       if (orb)
181         {
182           SALOME_NamingService namingService(orb);
183           CORBA::Object_var obj = namingService.Resolve("/Kernel/ModulCatalog");
184           SALOME_ModuleCatalog::ModuleCatalog_var aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
185           if (! CORBA::is_nil(aModuleCatalog))
186             {
187               CORBA::String_var anIOR = orb->object_to_string( aModuleCatalog );
188               YACS::ENGINE::Catalog* aCatalog = runTime->loadCatalog( "session", anIOR.in() );
189               runTime->addCatalog(aCatalog);
190             }
191         }
192     }
193   catch(ServiceUnreachable& e)
194     {
195       //Naming service unreachable don't add catalog
196     }
197
198   YACSLoader loader;
199   Executor executor;
200
201   try
202     {
203       timer("Elapsed time before load: ");
204       Proc* p=loader.load(myArgs.args[0]);
205       if(p==0)
206         {
207           std::cerr << "The imported file is probably not a YACS schema file" << std::endl;
208           return 1;
209         }
210       //Get the parser logger
211       Logger* logger=p->getLogger("parser");
212       //Print errors logged if any
213       if(!logger->isEmpty())
214         {
215           std::cerr << "The imported file has errors" << std::endl;
216           std::cerr << logger->getStr() << std::endl;
217         }
218       //Don't execute if there are errors
219       if(logger->hasErrors())
220         {
221           delete p;
222           Runtime* r=YACS::ENGINE::getRuntime();
223           Dispatcher* disp=Dispatcher::getDispatcher();
224           r->fini();
225           delete r;
226           delete disp;
227           return 1;
228         }
229       timer("Elapsed time after load: ");
230
231       if(!p->isValid())
232         {
233           std::string report=p->getErrorReport();
234           std::cerr << "The schema is not valid and can not be executed" << std::endl;
235           std::cerr << report << std::endl;
236           Runtime* r=YACS::ENGINE::getRuntime();
237           Dispatcher* disp=Dispatcher::getDispatcher();
238           r->fini();
239           delete r;
240           delete disp;
241           return 1;
242         }
243       timer("Elapsed time after validation: ");
244
245       // Check consistency
246       LinkInfo info(LinkInfo::ALL_DONT_STOP);
247       p->checkConsistency(info);
248       if(info.areWarningsOrErrors())
249         {
250           std::cerr << "The schema is not consistent and can not be executed" << std::endl;
251           std::cerr << info.getGlobalRepr() << std::endl;
252           Runtime* r=YACS::ENGINE::getRuntime();
253           Dispatcher* disp=Dispatcher::getDispatcher();
254           r->fini();
255           delete r;
256           delete disp;
257           return 1;
258         }
259       timer("Elapsed time after check consistency: ");
260
261       //execution
262       bool isXmlSchema = (strlen(myArgs.xmlSchema) != 0);
263       if (isXmlSchema)
264       {
265         YACS::ENGINE::VisitorSaveSalomeSchema vss(p);
266         vss.openFileSchema(myArgs.xmlSchema);
267         p->accept(&vss);
268         vss.closeFileSchema();
269       }
270
271       bool fromScratch = (strlen(myArgs.loadState) == 0);
272       if (!fromScratch)
273         {
274           p->init();
275           p->exUpdateState();
276           stateParser* rootParser = new stateParser();
277           stateLoader myStateLoader(rootParser, p);
278           myStateLoader.parse(myArgs.loadState);
279         }
280
281       if (myArgs.stop)
282         if (strlen(myArgs.dumpErrorFile) >0)
283           executor.setStopOnError(true, myArgs.dumpErrorFile);
284         else
285           executor.setStopOnError(false, myArgs.dumpErrorFile);
286
287       std::ofstream f("toto");
288       p->writeDot(f);
289       f.close();
290
291       cerr << "+++++++++++++++++++ start calculation +++++++++++++++++++" << endl;
292       executor.RunW(p,myArgs.display, fromScratch);
293       cerr << "+++++++++++++++++++  end calculation  +++++++++++++++++++" << endl;
294       cerr << "Proc state : " << p->getEffectiveState() << endl;
295       timer("Elapsed time after execution: ");
296
297       if(p->getEffectiveState() != YACS::DONE)
298         {
299           std::string report=p->getErrorReport();
300           std::cerr << "Execution has ended in error" << std::endl;
301           std::cerr << report << std::endl;
302         }
303
304       std::ofstream g("titi");
305       p->writeDot(g);
306       g.close();
307
308       bool isFinalDump = (strlen(myArgs.finalDump) != 0);
309       if (isFinalDump)
310         {
311           YACS::ENGINE::VisitorSaveState vst(p);
312           vst.openFileDump(myArgs.finalDump);
313           p->accept(&vst);
314           vst.closeFileDump();
315         }
316       delete p;
317       Runtime* r=YACS::ENGINE::getRuntime();
318       Dispatcher* disp=Dispatcher::getDispatcher();
319       r->fini();
320       delete r;
321       delete disp;
322       return 0;
323     }
324   catch (YACS::Exception& e)
325     {
326       cerr << "Caught a YACS exception" << endl;
327       cerr << e.what() << endl;
328       Runtime* r=YACS::ENGINE::getRuntime();
329       Dispatcher* disp=Dispatcher::getDispatcher();
330       r->fini();
331       delete r;
332       delete disp;
333       return 1;
334     }
335   catch (const std::ios_base::failure&)
336     {
337       cerr << "Caught an io failure exception" << endl;
338       return 1;
339     }
340   catch(CORBA::SystemException& ex) 
341     {
342       cerr << "Caught a CORBA::SystemException." ;
343       CORBA::Any tmp;
344       tmp <<= ex;
345       CORBA::TypeCode_var tc = tmp.type();
346       const char *p = tc->name();
347       if ( *p != '\0' ) 
348         cerr <<p;
349       else  
350         cerr  << tc->id();
351       cerr << endl;
352       return 1;
353     }
354   catch(omniORB::fatalException& fe) 
355     {
356       cerr << "Caught omniORB::fatalException:" << endl;
357       cerr << "  file: " << fe.file() << endl;
358       cerr << "  line: " << fe.line() << endl;
359       cerr << "  mesg: " << fe.errmsg() << endl;
360       return 1;
361     }
362   catch(...) 
363     {
364       cerr << "Caught unknown exception." << endl;
365       return 1;
366     }
367 }
368