0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[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     std::cout << "Plugin file name has not been specified. Defaults to " << thePluginName.ToCString() << std::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 = OSD_Environment (aCSFVariable).Value();
63   if (aPluginDir.IsEmpty())
64   {
65     aPluginDir = OSD_Environment ("DRAWHOME").Value();
66     if (!aPluginDir.IsEmpty())
67     {
68       aToSetCSFVariable = Standard_True; //CSF variable to be set later
69     }
70     else
71     {
72       // now try by CASROOT
73       aPluginDir = OSD_Environment ("CASROOT").Value();
74       if (!aPluginDir.IsEmpty())
75       {
76         aPluginDir += "/src/DrawResources";
77         aToSetCSFVariable = Standard_True; //CSF variable to be set later
78       }
79       else
80       {
81         aResult = aDirFound = Standard_False;
82         std::cout << FAILSTR "Neither " << aCSFVariable << ", nor CASROOT variables have been set\n";
83       }
84     }
85   }
86   
87   if (aDirFound) {
88     // search directory name has been constructed, now check whether it and the file exist
89     
90     TCollection_AsciiString aPluginFileName = aPluginDir + "/" + thePluginName;
91     OSD_File PluginFile ( aPluginFileName );
92     if ( PluginFile.Exists() ) {
93       if (aToSetCSFVariable) {
94         OSD_Environment aCSFVarEnv ( aCSFVariable, aPluginDir );
95         aCSFVarEnv.Build();
96 #ifdef OCCT_DEBUG
97         std::cout << "Variable " << aCSFVariable.ToCString() << " has not been explicitly defined. Set to " << aPluginDir.ToCString() << std::endl;
98 #endif
99         if ( aCSFVarEnv.Failed() ) {
100           aResult = Standard_False;
101           std::cout << FAILSTR "Failed to initialize " << aCSFVariable.ToCString() << " with " << aPluginDir.ToCString() << std::endl;
102         }
103       }
104     } else {
105       aResult = Standard_False;
106       std::cout << FAILSTR "File " << aPluginFileName.ToCString() << " not found" << std::endl;
107     }
108   }
109   
110   return aResult;
111 }
112
113 //=======================================================================
114 //function : Parse
115 //purpose  : Parse the input keys to atomic keys (<key> --> <akey>[<akey> ..])
116 //=======================================================================
117
118 static void Parse (Draw_MapOfAsciiString& theMap)
119 {
120   Draw_MapOfAsciiString aMap, aMap2;
121   Standard_Integer j, k;
122   Standard_Integer aMapExtent, aMap2Extent;
123   aMapExtent = theMap.Extent();
124   for(j = 1; j <= aMapExtent; j++) {
125     if (!myResources.IsNull()) {
126       const TCollection_AsciiString& aKey = theMap.FindKey(j);
127       TCollection_AsciiString aResource = aKey;
128       if(myResources->Find(aResource.ToCString())) {
129 #ifdef OCCT_DEBUG
130         std::cout << "Parse Value ==> " << myResources->Value(aResource.ToCString()) << std::endl;
131 #endif
132         TCollection_AsciiString aValue(myResources->Value(aResource.ToCString()));
133         // parse aValue string
134         Standard_Integer i=1;
135         for(;;) {
136           TCollection_AsciiString aCurKey = aValue.Token(" \t,", i++);
137 #ifdef OCCT_DEBUG
138           std::cout << "Parse aCurKey = " << aCurKey.ToCString() << std::endl;
139 #endif
140           if(aCurKey.IsEmpty()) break;
141           if(!myResources->Find(aCurKey.ToCString())) {
142             // It is toolkit
143             aMap.Add(aResource);
144           }
145           else
146             aMap2.Add(aCurKey);
147         }
148       } else
149         std::cout <<"Pload : Resource = " << aResource << " is not found" << std::endl;
150       if(!aMap2.IsEmpty())
151         Parse(aMap2);
152       //
153       aMap2Extent = aMap2.Extent();
154       for(k = 1; k <= aMap2Extent; k++) {
155         aMap.Add(aMap2.FindKey(k));
156       }
157
158     }
159   }
160
161   theMap.Assign(aMap);
162 }
163
164 //=======================================================================
165 //function : Pload
166 //purpose  : 
167 //=======================================================================
168
169 static Standard_Integer Pload (Draw_Interpretor& di,
170                                Standard_Integer  n,
171                                const char**      argv)
172 {
173   char adef[] = "-";
174   TCollection_AsciiString aPluginFileName("");
175   TCollection_AsciiString aPluginDir(""), aPluginDir2("");
176   Standard_Integer aStart = 0;
177   Standard_Integer aFinish = n - 1;
178
179   if (n == 1) {
180     // Load DEFAULT key
181     aStart = 0;
182   } else {
183     if(argv[1][0] == adef[0]) {
184       aPluginFileName = argv[1];
185       aPluginFileName.Remove(1,1);
186       if (n == 2) {
187         // Load DEFAULT key from aPluginFileName file
188         aStart = 0;
189         aFinish = n - 2;
190       } else {
191         aStart = 2;
192       }
193     } else {
194       aStart = 1;
195     }
196   }
197
198   //if ( !FindPluginFile (aPluginFileName) ) {
199   if ( !FindPluginFile (aPluginFileName, aPluginDir) ) {
200     return 1;
201   } 
202
203   Draw_MapOfAsciiString aMap;
204   TCollection_AsciiString aDEFAULT("DEFAULT");
205   //for(Standard_Integer i = aStart; i < n; i++) 
206   for(Standard_Integer i = aStart; i <= aFinish; i++) 
207     if (i == 0) {
208       // Load DEFAULT key
209       aMap.Add(aDEFAULT);
210     } else {
211       TCollection_AsciiString aTK(argv[i]);
212       aMap.Add(aTK);
213     }
214   
215   //myResources = new Resource_Manager(aPluginFileName.ToCString());
216   myResources = new Resource_Manager(aPluginFileName.ToCString(), aPluginDir, aPluginDir2, Standard_False);
217
218   Parse(aMap);
219   Standard_Integer j;
220   Standard_Integer aMapExtent;
221   aMapExtent = aMap.Extent();
222   for(j = 1; j <= aMapExtent; j++) {
223     const TCollection_AsciiString& aKey = aMap.FindKey(j);
224     TCollection_AsciiString aResource = aKey;
225 #ifdef OCCT_DEBUG
226       std::cout << "aResource = " << aResource << std::endl;
227 #endif
228     if(myResources->Find(aResource.ToCString())) {
229       const TCollection_AsciiString& aValue = myResources->Value(aResource.ToCString()); 
230 #ifdef OCCT_DEBUG
231       std::cout << "Value ==> " << aValue << std::endl;
232 #endif
233         
234       //Draw::Load(di, aKey, aPluginFileName);
235       Draw::Load(di, aKey, aPluginFileName, aPluginDir, aPluginDir2, Standard_False);
236
237       // Load TclScript
238       TCollection_AsciiString aCSFVariable ("CSF_DrawPluginTclDir");
239       TCollection_AsciiString aTclScriptDir;
240       aTclScriptDir = getenv (aCSFVariable.ToCString());
241       TCollection_AsciiString aTclScriptFileName;
242       TCollection_AsciiString aTclScriptFileNameDefaults;
243       aTclScriptFileName = aTclScriptDir + "/" + aValue + ".tcl";
244       aTclScriptFileNameDefaults = aPluginDir + "/" + aValue + ".tcl";
245       OSD_File aTclScriptFile ( aTclScriptFileName );
246       OSD_File aTclScriptFileDefaults ( aTclScriptFileNameDefaults );
247       if (!aTclScriptDir.IsEmpty() && aTclScriptFile.Exists()) {
248 #ifdef OCCT_DEBUG
249         std::cout << "Load " << aTclScriptFileName << " TclScript" << std::endl;
250 #endif
251         di.EvalFile( aTclScriptFileName.ToCString() );
252       } else if (!aPluginDir.IsEmpty() && aTclScriptFileDefaults.Exists()) {
253 #ifdef OCCT_DEBUG
254         std::cout << "Load " << aTclScriptFileNameDefaults << " TclScript" << std::endl;
255 #endif
256         di.EvalFile( aTclScriptFileNameDefaults.ToCString() );
257       }
258   
259     } else 
260       std::cout <<"Pload : Resource = " << aResource << " is not found" << std::endl;
261   }
262   return 0;
263 }
264
265 //=======================================================================
266 //function : dtryload
267 //purpose  : 
268 //=======================================================================
269
270 static Standard_Integer dtryload (Draw_Interpretor& di, Standard_Integer n, const char** argv)
271 {
272   if (n != 2)
273   {
274     std::cout << "Error: specify path to library to be loaded" << std::endl;
275     return 1;
276   }
277
278   OSD_SharedLibrary aLib(argv[1]);
279   if (aLib.DlOpen(OSD_RTLD_NOW))
280   {
281     di << "Loading " << argv[1] << " successful";
282     aLib.DlClose();
283   }
284   else 
285   {
286     di << "Loading " << argv[1] << " failed: " << aLib.DlError();
287   }
288   return 0;
289 }
290
291 //=======================================================================
292 //function : PloadCommands
293 //purpose  : 
294 //=======================================================================
295
296 void Draw::PloadCommands(Draw_Interpretor& theCommands)
297 {
298   static Standard_Boolean Done = Standard_False;
299   if (Done) return;
300   Done = Standard_True;
301
302   const char* g = "Draw Plugin";
303   
304   theCommands.Add("pload" , "pload [-PluginFilename] [[Key1] [Key2] ...]: Loads Draw plugins " ,
305                   __FILE__, Pload, g);
306   theCommands.Add("dtryload" , "dtryload path : load and unload specified dynamic loaded library" ,
307                   __FILE__, dtryload, g);
308 }