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