0030579: Draw Harness, Draw_Interpretor - catch exceptions other than Standard_Failure
[occt.git] / src / Draw / Draw_PloadCommands.cxx
1 // Created on: 2003-10-09
2 // Created by: Mikhail KUZMITCHEV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <TCollection_AsciiString.hxx>
17 #include <OSD_Path.hxx>
18 #include <OSD_Directory.hxx>
19 #include <OSD_File.hxx>
20 #include <OSD_Environment.hxx>
21 #include <OSD_SharedLibrary.hxx>
22 #include <Resource_Manager.hxx>
23 #include <Draw_Interpretor.hxx>
24 #include <Draw_MapOfAsciiString.hxx>
25 #include <Draw.hxx>
26
27 static Handle(Resource_Manager) myResources;
28
29 //=======================================================================
30 //function : FindPluginFile
31 //purpose  : Searches for the existence of the plugin file according to its name thePluginName:
32 //           - if thePluginName is empty then it defaults to DrawPlugin
33 //           - the search directory is defined according to the variable
34 //             CSF_<filename>Defaults (if it is omitted then it defaults to
35 //             $CASROOT/src/DrawResources)
36 //           - finally existence of the file is verified in the search directory
37 //           - if the file exists but corresponding variable (CSF_...) has not been
38 //             explicitly set, it is forced to (for further reuse by Resource_Manager)
39 //           Returns True if the file exists, otherwise - False.
40 //=======================================================================
41
42 #define FAILSTR "Failed to load plugin: "
43      
44 //static Standard_Boolean FindPluginFile (TCollection_AsciiString& thePluginName)
45 static Standard_Boolean FindPluginFile (TCollection_AsciiString& thePluginName, TCollection_AsciiString& aPluginDir)
46 {
47   Standard_Boolean aResult = Standard_True;
48   
49   // check if the file name has been specified and use default value if not
50   if (thePluginName.IsEmpty()) {
51     thePluginName += "DrawPlugin";
52 #ifdef OCCT_DEBUG
53     cout << "Plugin file name has not been specified. Defaults to " << thePluginName.ToCString() << endl;
54 #endif
55   }
56
57   //TCollection_AsciiString aPluginDir; // the search directory
58   Standard_Boolean aDirFound = Standard_True, aToSetCSFVariable = Standard_False;
59   
60   // the order of search : by CSF_<PluginFileName>Defaults and then by CASROOT
61   TCollection_AsciiString aCSFVariable = TCollection_AsciiString ("CSF_") + thePluginName + "Defaults";
62   aPluginDir = getenv (aCSFVariable.ToCString());
63
64   if (aPluginDir.IsEmpty()) {
65     // now try by CASROOT
66     aPluginDir = getenv("CASROOT");
67
68     if ( !aPluginDir.IsEmpty() ) {
69       aPluginDir +="/src/DrawResources" ;
70       aToSetCSFVariable = Standard_True; //CSF variable to be set later
71     } else {
72       aResult = aDirFound = Standard_False;
73       cout << FAILSTR "Neither " << aCSFVariable.ToCString() << ", nor CASROOT variables have been set" << endl;
74     }
75   }
76   
77   if (aDirFound) {
78     // search directory name has been constructed, now check whether it and the file exist
79     
80     TCollection_AsciiString aPluginFileName = aPluginDir + "/" + thePluginName;
81     OSD_File PluginFile ( aPluginFileName );
82     if ( PluginFile.Exists() ) {
83       if (aToSetCSFVariable) {
84         OSD_Environment aCSFVarEnv ( aCSFVariable, aPluginDir );
85         aCSFVarEnv.Build();
86 #ifdef OCCT_DEBUG
87         cout << "Variable " << aCSFVariable.ToCString() << " has not been explicitly defined. Set to " << aPluginDir.ToCString() << endl;
88 #endif
89         if ( aCSFVarEnv.Failed() ) {
90           aResult = Standard_False;
91           cout << FAILSTR "Failed to initialize " << aCSFVariable.ToCString() << " with " << aPluginDir.ToCString() << endl;
92         }
93       }
94     } else {
95       aResult = Standard_False;
96       cout << FAILSTR "File " << aPluginFileName.ToCString() << " not found" << endl;
97     }
98   }
99   
100   return aResult;
101 }
102
103 //=======================================================================
104 //function : Parse
105 //purpose  : Parse the input keys to atomic keys (<key> --> <akey>[<akey> ..])
106 //=======================================================================
107
108 static void Parse (Draw_MapOfAsciiString& theMap)
109 {
110   Draw_MapOfAsciiString aMap, aMap2;
111   Standard_Integer j, k;
112   Standard_Integer aMapExtent, aMap2Extent;
113   aMapExtent = theMap.Extent();
114   for(j = 1; j <= aMapExtent; j++) {
115     if (!myResources.IsNull()) {
116       const TCollection_AsciiString& aKey = theMap.FindKey(j);
117       TCollection_AsciiString aResource = aKey;
118       if(myResources->Find(aResource.ToCString())) {
119 #ifdef OCCT_DEBUG
120         cout << "Parse Value ==> " << myResources->Value(aResource.ToCString()) << endl;
121 #endif
122         TCollection_AsciiString aValue(myResources->Value(aResource.ToCString()));
123         // parse aValue string
124         Standard_Integer i=1;
125         for(;;) {
126           TCollection_AsciiString aCurKey = aValue.Token(" \t,", i++);
127 #ifdef OCCT_DEBUG
128           cout << "Parse aCurKey = " << aCurKey.ToCString() << endl;
129 #endif
130           if(aCurKey.IsEmpty()) break;
131           if(!myResources->Find(aCurKey.ToCString())) {
132             // It is toolkit
133             aMap.Add(aResource);
134           }
135           else
136             aMap2.Add(aCurKey);
137         }
138       } else
139         cout <<"Pload : Resource = " << aResource << " is not found" << endl;
140       if(!aMap2.IsEmpty())
141         Parse(aMap2);
142       //
143       aMap2Extent = aMap2.Extent();
144       for(k = 1; k <= aMap2Extent; k++) {
145         aMap.Add(aMap2.FindKey(k));
146       }
147
148     }
149   }
150
151   theMap.Assign(aMap);
152 }
153
154 //=======================================================================
155 //function : Pload
156 //purpose  : 
157 //=======================================================================
158
159 static Standard_Integer Pload (Draw_Interpretor& di,
160                                Standard_Integer  n,
161                                const char**      argv)
162 {
163   char adef[] = "-";
164   TCollection_AsciiString aPluginFileName("");
165   TCollection_AsciiString aPluginDir(""), aPluginDir2("");
166   Standard_Integer aStart = 0;
167   Standard_Integer aFinish = n - 1;
168
169   if (n == 1) {
170     // Load DEFAULT key
171     aStart = 0;
172   } else {
173     if(argv[1][0] == adef[0]) {
174       aPluginFileName = argv[1];
175       aPluginFileName.Remove(1,1);
176       if (n == 2) {
177         // Load DEFAULT key from aPluginFileName file
178         aStart = 0;
179         aFinish = n - 2;
180       } else {
181         aStart = 2;
182       }
183     } else {
184       aStart = 1;
185     }
186   }
187
188   //if ( !FindPluginFile (aPluginFileName) ) {
189   if ( !FindPluginFile (aPluginFileName, aPluginDir) ) {
190     return 1;
191   } 
192
193   Draw_MapOfAsciiString aMap;
194   TCollection_AsciiString aDEFAULT("DEFAULT");
195   //for(Standard_Integer i = aStart; i < n; i++) 
196   for(Standard_Integer i = aStart; i <= aFinish; i++) 
197     if (i == 0) {
198       // Load DEFAULT key
199       aMap.Add(aDEFAULT);
200     } else {
201       TCollection_AsciiString aTK(argv[i]);
202       aMap.Add(aTK);
203     }
204   
205   //myResources = new Resource_Manager(aPluginFileName.ToCString());
206   myResources = new Resource_Manager(aPluginFileName.ToCString(), aPluginDir, aPluginDir2, Standard_False);
207
208   Parse(aMap);
209   Standard_Integer j;
210   Standard_Integer aMapExtent;
211   aMapExtent = aMap.Extent();
212   for(j = 1; j <= aMapExtent; j++) {
213     const TCollection_AsciiString& aKey = aMap.FindKey(j);
214     TCollection_AsciiString aResource = aKey;
215 #ifdef OCCT_DEBUG
216       cout << "aResource = " << aResource << endl;
217 #endif
218     if(myResources->Find(aResource.ToCString())) {
219       const TCollection_AsciiString& aValue = myResources->Value(aResource.ToCString()); 
220 #ifdef OCCT_DEBUG
221       cout << "Value ==> " << aValue << endl;
222 #endif
223         
224       //Draw::Load(di, aKey, aPluginFileName);
225       Draw::Load(di, aKey, aPluginFileName, aPluginDir, aPluginDir2, Standard_False);
226
227       // Load TclScript
228       TCollection_AsciiString aCSFVariable ("CSF_DrawPluginTclDir");
229       TCollection_AsciiString aTclScriptDir;
230       aTclScriptDir = getenv (aCSFVariable.ToCString());
231       TCollection_AsciiString aTclScriptFileName;
232       TCollection_AsciiString aTclScriptFileNameDefaults;
233       aTclScriptFileName = aTclScriptDir + "/" + aValue + ".tcl";
234       aTclScriptFileNameDefaults = aPluginDir + "/" + aValue + ".tcl";
235       OSD_File aTclScriptFile ( aTclScriptFileName );
236       OSD_File aTclScriptFileDefaults ( aTclScriptFileNameDefaults );
237       if (!aTclScriptDir.IsEmpty() && aTclScriptFile.Exists()) {
238 #ifdef OCCT_DEBUG
239         cout << "Load " << aTclScriptFileName << " TclScript" << endl;
240 #endif
241         di.EvalFile( aTclScriptFileName.ToCString() );
242       } else if (!aPluginDir.IsEmpty() && aTclScriptFileDefaults.Exists()) {
243 #ifdef OCCT_DEBUG
244         cout << "Load " << aTclScriptFileNameDefaults << " TclScript" << endl;
245 #endif
246         di.EvalFile( aTclScriptFileNameDefaults.ToCString() );
247       }
248   
249     } else 
250       cout <<"Pload : Resource = " << aResource << " is not found" << endl;
251   }
252   return 0;
253 }
254
255 //=======================================================================
256 //function : dtryload
257 //purpose  : 
258 //=======================================================================
259
260 static Standard_Integer dtryload (Draw_Interpretor& di, Standard_Integer n, const char** argv)
261 {
262   if (n != 2)
263   {
264     cout << "Error: specify path to library to be loaded" << endl;
265     return 1;
266   }
267
268   OSD_SharedLibrary aLib(argv[1]);
269   if (aLib.DlOpen(OSD_RTLD_NOW))
270   {
271     di << "Loading " << argv[1] << " successful";
272     aLib.DlClose();
273   }
274   else 
275   {
276     di << "Loading " << argv[1] << " failed: " << aLib.DlError();
277   }
278   return 0;
279 }
280
281 //=======================================================================
282 //function : PloadCommands
283 //purpose  : 
284 //=======================================================================
285
286 void Draw::PloadCommands(Draw_Interpretor& theCommands)
287 {
288   static Standard_Boolean Done = Standard_False;
289   if (Done) return;
290   Done = Standard_True;
291
292   const char* g = "Draw Plugin";
293   
294   theCommands.Add("pload" , "pload [-PluginFilename] [[Key1] [Key2] ...]: Loads Draw plugins " ,
295                   __FILE__, Pload, g);
296   theCommands.Add("dtryload" , "dtryload path : load and unload specified dynamic loaded library" ,
297                   __FILE__, dtryload, g);
298 }