FIX: stupid pb fixed (close to being medieval'ed by The Ken)
[cmake.git] / Source / cmVTKWrapTclCommand.cxx
blobae18f2c3a267e6bc58687c8767525ad2978d6a10
1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmVTKWrapTclCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2002-07-26 13:54:47 $
7 Version: $Revision: 1.29 $
9 Copyright (c) 2002 Insight Consortium. All rights reserved.
10 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmVTKWrapTclCommand.h"
19 // cmVTKWrapTclCommand
20 bool cmVTKWrapTclCommand::InitialPass(std::vector<std::string> const& argsIn)
22 if(argsIn.size() < 3 )
24 this->SetError("called with incorrect number of arguments");
25 return false;
27 std::vector<std::string> args;
29 // keep the library name
30 m_LibraryName = argsIn[0];
32 if (argsIn[1] == std::string("SOURCES"))
34 m_Makefile->ExpandSourceListArguments(argsIn, args, 3);
36 else
38 m_Makefile->ExpandSourceListArguments(argsIn, args, 2);
41 // Now check and see if the value has been stored in the cache
42 // already, if so use that value and don't look for the program
43 if(!m_Makefile->IsOn("VTK_WRAP_TCL"))
45 return true;
48 // extract the sources and commands parameters
49 std::vector<std::string> sources;
50 bool doing_sources = true;
52 for(std::vector<std::string>::const_iterator j = (args.begin() + 1);
53 j != args.end(); ++j)
55 if(*j == "SOURCES")
57 doing_sources = true;
59 else if (*j == "COMMANDS")
61 doing_sources = false;
63 else
65 if(doing_sources)
67 sources.push_back(*j);
69 else
71 m_Commands.push_back(*j);
76 // get the list of classes for this library
77 if (sources.size())
79 // what is the current source dir
80 std::string cdir = m_Makefile->GetCurrentDirectory();
82 // get the resulting source list name
83 m_SourceList = sources[0];
84 std::string sourceListValue;
86 // was the list already populated
87 const char *def = m_Makefile->GetDefinition(m_SourceList.c_str());
88 if (def)
90 sourceListValue = def;
91 sourceListValue += ";";
94 // Create the init file
95 std::string res = m_LibraryName;
96 res += "Init.cxx";
97 sourceListValue += res;
99 for(std::vector<std::string>::iterator j = (sources.begin() + 1);
100 j != sources.end(); ++j)
102 cmSourceFile *curr = m_Makefile->GetSource(j->c_str());
104 // if we should wrap the class
105 if (!curr || !curr->GetWrapExclude())
107 cmSourceFile file;
108 if (curr)
110 file.SetIsAnAbstractClass(curr->IsAnAbstractClass());
112 std::string srcName = cmSystemTools::GetFilenameWithoutExtension(*j);
113 std::string newName = srcName + "Tcl";
114 std::string hname = cdir + "/" + srcName + ".h";
115 file.SetName(newName.c_str(), m_Makefile->GetCurrentOutputDirectory(),
116 "cxx",false);
117 m_WrapHeaders.push_back(hname);
118 // add starting depends
119 file.GetDepends().push_back(hname);
120 m_WrapClasses.push_back(file);
121 sourceListValue += ";";
122 sourceListValue += newName + ".cxx";
125 // add the init file
126 cmSourceFile cfile;
127 cfile.SetIsAnAbstractClass(false);
128 std::string newName = m_LibraryName;
129 newName += "Init";
130 this->CreateInitFile(res);
131 cfile.SetName(newName.c_str(), m_Makefile->GetCurrentOutputDirectory(),
132 "cxx",false);
133 m_Makefile->AddSource(cfile);
134 m_Makefile->AddDefinition(m_SourceList.c_str(), sourceListValue.c_str());
137 return true;
140 void cmVTKWrapTclCommand::FinalPass()
142 // first we add the rules for all the .h to Tcl.cxx files
143 size_t lastClass = m_WrapClasses.size();
144 std::vector<std::string> depends;
145 std::string wtcl = "${VTK_WRAP_TCL_EXE}";
146 std::string hints = "${VTK_WRAP_HINTS}";
148 m_Makefile->ExpandVariablesInString(hints);
150 // wrap all the .h files
151 depends.push_back(wtcl);
152 if (strcmp("${VTK_WRAP_HINTS}",hints.c_str()))
154 depends.push_back(hints);
156 for(size_t classNum = 0; classNum < lastClass; classNum++)
158 m_Makefile->AddSource(m_WrapClasses[classNum]);
159 std::vector<std::string> args;
160 args.push_back(m_WrapHeaders[classNum]);
161 if (strcmp("${VTK_WRAP_HINTS}",hints.c_str()))
163 args.push_back(hints);
165 args.push_back((m_WrapClasses[classNum].IsAnAbstractClass() ? "0" : "1"));
166 std::string res = m_Makefile->GetCurrentOutputDirectory();
167 res += "/";
168 res += m_WrapClasses[classNum].GetSourceName() + ".cxx";
169 args.push_back(res);
171 m_Makefile->AddCustomCommand(m_WrapHeaders[classNum].c_str(),
172 wtcl.c_str(), args, depends,
173 res.c_str(), m_LibraryName.c_str());
177 bool cmVTKWrapTclCommand::CreateInitFile(std::string& res)
179 /* we have to make sure that the name is the correct case */
180 std::string kitName = cmSystemTools::Capitalized(m_LibraryName);
182 std::vector<std::string> classes;
183 size_t lastClass = m_WrapHeaders.size();
184 size_t classNum;
185 for(classNum = 0; classNum < lastClass; classNum++)
187 if (!m_WrapClasses[classNum].IsAnAbstractClass())
189 std::string cls = m_WrapHeaders[classNum];
190 cls = cls.substr(0,cls.size()-2);
191 std::string::size_type pos = cls.rfind('/');
192 if(pos != std::string::npos)
194 cls = cls.substr(pos+1);
196 classes.push_back(cls);
200 // open the init file
201 std::string outFileName =
202 m_Makefile->GetCurrentOutputDirectory();
203 outFileName += "/" + res;
205 return this->WriteInit(kitName.c_str(), outFileName, classes);
209 /* warning this code is also in getclasses.cxx under pcmaker */
210 bool cmVTKWrapTclCommand::WriteInit(const char *kitName,
211 std::string& outFileName,
212 std::vector<std::string>& classes)
214 unsigned int i;
215 std::string tempOutputFile = outFileName + ".tmp";
216 FILE *fout = fopen(tempOutputFile.c_str(),"w");
217 if (!fout)
219 cmSystemTools::Error("Failed to open TclInit file for ", tempOutputFile.c_str());
220 return false;
223 // capitalized commands just once
224 std::vector<std::string> capcommands;
225 for (i = 0; i < m_Commands.size(); i++)
227 capcommands.push_back(cmSystemTools::Capitalized(m_Commands[i]));
230 fprintf(fout,"#include \"vtkTclUtil.h\"\n");
232 fprintf(fout,
233 "extern \"C\"\n"
234 "{\n"
235 " typedef int (*vtkTclCommandType)(ClientData, Tcl_Interp *,int, char *[]);\n"
236 "}\n"
237 "\n");
239 for (i = 0; i < classes.size(); i++)
241 fprintf(fout,"int %sCommand(ClientData cd, Tcl_Interp *interp,\n int argc, char *argv[]);\n",classes[i].c_str());
242 fprintf(fout,"ClientData %sNewCommand();\n",classes[i].c_str());
245 if (!strcmp(kitName,"Vtkcommontcl"))
247 fprintf(fout,"int vtkCommand(ClientData cd, Tcl_Interp *interp,\n"
248 " int argc, char *argv[]);\n");
249 fprintf(fout,"\nTcl_HashTable vtkInstanceLookup;\n");
250 fprintf(fout,"Tcl_HashTable vtkPointerLookup;\n");
251 fprintf(fout,"Tcl_HashTable vtkCommandLookup;\n");
253 else
255 fprintf(fout,"\nextern Tcl_HashTable vtkInstanceLookup;\n");
256 fprintf(fout,"extern Tcl_HashTable vtkPointerLookup;\n");
257 fprintf(fout,"extern Tcl_HashTable vtkCommandLookup;\n");
259 fprintf(fout,"extern void vtkTclDeleteObjectFromHash(void *);\n");
260 fprintf(fout,"extern void vtkTclListInstances(Tcl_Interp *interp, ClientData arg);\n");
262 for (i = 0; i < m_Commands.size(); i++)
264 fprintf(fout,"\nextern \"C\" {int VTK_EXPORT %s_Init(Tcl_Interp *interp);}\n",
265 capcommands[i].c_str());
268 fprintf(fout,"\n\nextern \"C\" {int VTK_EXPORT %s_SafeInit(Tcl_Interp *interp);}\n",
269 kitName);
270 fprintf(fout,"\nextern \"C\" {int VTK_EXPORT %s_Init(Tcl_Interp *interp);}\n",
271 kitName);
273 /* create an extern ref to the generic delete function */
274 fprintf(fout,"\nextern void vtkTclGenericDeleteObject(ClientData cd);\n");
276 if (!strcmp(kitName,"Vtkcommontcl"))
278 fprintf(fout,"extern \"C\"\n{\nvoid vtkCommonDeleteAssocData(ClientData cd)\n");
279 fprintf(fout," {\n");
280 fprintf(fout," vtkTclInterpStruct *tis = static_cast<vtkTclInterpStruct*>(cd);\n");
281 fprintf(fout," delete tis;\n }\n}\n");
284 /* the main declaration */
285 fprintf(fout,"\n\nint VTK_EXPORT %s_SafeInit(Tcl_Interp *interp)\n{\n",kitName);
286 fprintf(fout," return %s_Init(interp);\n}\n",kitName);
288 fprintf(fout,"\n\nint VTK_EXPORT %s_Init(Tcl_Interp *interp)\n{\n",
289 kitName);
290 if (!strcmp(kitName,"Vtkcommontcl"))
292 fprintf(fout,
293 " vtkTclInterpStruct *info = new vtkTclInterpStruct;\n");
294 fprintf(fout,
295 " info->Number = 0; info->InDelete = 0; info->DebugOn = 0;\n");
296 fprintf(fout,"\n");
297 fprintf(fout,"\n");
298 fprintf(fout,
299 " Tcl_InitHashTable(&info->InstanceLookup, TCL_STRING_KEYS);\n");
300 fprintf(fout,
301 " Tcl_InitHashTable(&info->PointerLookup, TCL_STRING_KEYS);\n");
302 fprintf(fout,
303 " Tcl_InitHashTable(&info->CommandLookup, TCL_STRING_KEYS);\n");
304 fprintf(fout,
305 " Tcl_SetAssocData(interp,(char *) \"vtk\",NULL,(ClientData *)info);\n");
306 fprintf(fout,
307 " Tcl_CreateExitHandler(vtkCommonDeleteAssocData,(ClientData *)info);\n");
309 /* create special vtkCommand command */
310 fprintf(fout," Tcl_CreateCommand(interp,(char *) \"vtkCommand\",\n"
311 " reinterpret_cast<vtkTclCommandType>(vtkCommand),\n"
312 " (ClientData *)NULL, NULL);\n\n");
315 for (i = 0; i < m_Commands.size(); i++)
317 fprintf(fout," %s_Init(interp);\n", capcommands[i].c_str());
319 fprintf(fout,"\n");
321 for (i = 0; i < classes.size(); i++)
323 fprintf(fout," vtkTclCreateNew(interp,(char *) \"%s\", %sNewCommand,\n",
324 classes[i].c_str(), classes[i].c_str());
325 fprintf(fout," %sCommand);\n",classes[i].c_str());
328 fprintf(fout," return TCL_OK;\n}\n");
329 fclose(fout);
331 // copy the file if different
332 cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
333 outFileName.c_str());
334 cmSystemTools::RemoveFile(tempOutputFile.c_str());
336 return true;