1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmVTKWrapTclCommand.cxx,v $
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");
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);
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"))
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);
59 else if (*j
== "COMMANDS")
61 doing_sources
= false;
67 sources
.push_back(*j
);
71 m_Commands
.push_back(*j
);
76 // get the list of classes for this library
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());
90 sourceListValue
= def
;
91 sourceListValue
+= ";";
94 // Create the init file
95 std::string res
= m_LibraryName
;
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())
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(),
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";
127 cfile
.SetIsAnAbstractClass(false);
128 std::string newName
= m_LibraryName
;
130 this->CreateInitFile(res
);
131 cfile
.SetName(newName
.c_str(), m_Makefile
->GetCurrentOutputDirectory(),
133 m_Makefile
->AddSource(cfile
);
134 m_Makefile
->AddDefinition(m_SourceList
.c_str(), sourceListValue
.c_str());
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();
168 res
+= m_WrapClasses
[classNum
].GetSourceName() + ".cxx";
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();
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
)
215 std::string tempOutputFile
= outFileName
+ ".tmp";
216 FILE *fout
= fopen(tempOutputFile
.c_str(),"w");
219 cmSystemTools::Error("Failed to open TclInit file for ", tempOutputFile
.c_str());
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");
235 " typedef int (*vtkTclCommandType)(ClientData, Tcl_Interp *,int, char *[]);\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");
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",
270 fprintf(fout
,"\nextern \"C\" {int VTK_EXPORT %s_Init(Tcl_Interp *interp);}\n",
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",
290 if (!strcmp(kitName
,"Vtkcommontcl"))
293 " vtkTclInterpStruct *info = new vtkTclInterpStruct;\n");
295 " info->Number = 0; info->InDelete = 0; info->DebugOn = 0;\n");
299 " Tcl_InitHashTable(&info->InstanceLookup, TCL_STRING_KEYS);\n");
301 " Tcl_InitHashTable(&info->PointerLookup, TCL_STRING_KEYS);\n");
303 " Tcl_InitHashTable(&info->CommandLookup, TCL_STRING_KEYS);\n");
305 " Tcl_SetAssocData(interp,(char *) \"vtk\",NULL,(ClientData *)info);\n");
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());
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");
331 // copy the file if different
332 cmSystemTools::CopyFileIfDifferent(tempOutputFile
.c_str(),
333 outFileName
.c_str());
334 cmSystemTools::RemoveFile(tempOutputFile
.c_str());