Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

478 lines
15 KiB

/* this is a CMake loadable command to wrap vtk objects into Tcl */
#include "cmCPluginAPI.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
char *LibraryName;
int NumberWrapped;
void **SourceFiles;
char **HeaderFiles;
} cmVTKWrapTclData;
/* this roputine creates the init file */
static void CreateInitFile(cmLoadedCommandInfo *info,
void *mf, const char *libName,
int numConcrete, const char **concrete,
int numCommands, const char **commands)
{
/* we have to make sure that the name is the correct case */
char *kitName = info->CAPI->Capitalized(libName);
int i;
char *tempOutputFile;
char *outFileName =
(char *)malloc(strlen(info->CAPI->GetCurrentOutputDirectory(mf)) +
strlen(libName) + 10);
char **capcommands = (char **)malloc(numCommands*sizeof(char *));
FILE *fout;
sprintf(outFileName,"%s/%sInit.cxx",
info->CAPI->GetCurrentOutputDirectory(mf), libName);
tempOutputFile = (char *)malloc(strlen(outFileName) + 5);
sprintf(tempOutputFile,"%s.tmp",outFileName);
fout = fopen(tempOutputFile,"w");
if (!fout)
{
return;
}
/* capitalized commands just once */
for (i = 0; i < numCommands; i++)
{
capcommands[i] = info->CAPI->Capitalized(commands[i]);
}
fprintf(fout,"#include \"vtkTclUtil.h\"\n");
fprintf(fout,"#include \"vtkVersion.h\"\n");
fprintf(fout,"#define VTK_TCL_TO_STRING(x) VTK_TCL_TO_STRING0(x)\n");
fprintf(fout,"#define VTK_TCL_TO_STRING0(x) #x\n");
fprintf(fout,
"extern \"C\"\n"
"{\n"
"#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4) && (TCL_RELEASE_LEVEL >= TCL_FINAL_RELEASE)\n"
" typedef int (*vtkTclCommandType)(ClientData, Tcl_Interp *,int, CONST84 char *[]);\n"
"#else\n"
" typedef int (*vtkTclCommandType)(ClientData, Tcl_Interp *,int, char *[]);\n"
"#endif\n"
"}\n"
"\n");
for (i = 0; i < numConcrete; i++)
{
fprintf(fout,"int %sCommand(ClientData cd, Tcl_Interp *interp,\n int argc, char *argv[]);\n",concrete[i]);
fprintf(fout,"ClientData %sNewCommand();\n",concrete[i]);
}
if (!strcmp(kitName,"Vtkcommontcl"))
{
fprintf(fout,"int vtkCreateCommand(ClientData cd, Tcl_Interp *interp,\n"
" int argc, char *argv[]);\n");
fprintf(fout,"\nTcl_HashTable vtkInstanceLookup;\n");
fprintf(fout,"Tcl_HashTable vtkPointerLookup;\n");
fprintf(fout,"Tcl_HashTable vtkCommandLookup;\n");
}
else
{
fprintf(fout,"\nextern Tcl_HashTable vtkInstanceLookup;\n");
fprintf(fout,"extern Tcl_HashTable vtkPointerLookup;\n");
fprintf(fout,"extern Tcl_HashTable vtkCommandLookup;\n");
}
fprintf(fout,"extern void vtkTclDeleteObjectFromHash(void *);\n");
fprintf(fout,"extern void vtkTclListInstances(Tcl_Interp *interp, ClientData arg);\n");
for (i = 0; i < numCommands; i++)
{
fprintf(fout,
"\nextern \"C\" {int VTK_EXPORT %s_Init(Tcl_Interp *interp);}\n",
capcommands[i]);
}
fprintf(fout,
"\n\nextern \"C\" {int VTK_EXPORT %s_SafeInit(Tcl_Interp *interp);}\n",
kitName);
fprintf(fout,
"\nextern \"C\" {int VTK_EXPORT %s_Init(Tcl_Interp *interp);}\n",
kitName);
/* create an extern ref to the generic delete function */
fprintf(fout,"\nextern void vtkTclGenericDeleteObject(ClientData cd);\n");
if (!strcmp(kitName,"Vtkcommontcl"))
{
fprintf(fout,
"extern \"C\"\n{\nvoid vtkCommonDeleteAssocData(ClientData cd)\n");
fprintf(fout," {\n");
fprintf(fout," vtkTclInterpStruct *tis = static_cast<vtkTclInterpStruct*>(cd);\n");
fprintf(fout," delete tis;\n }\n}\n");
}
/* the main declaration */
fprintf(fout,
"\n\nint VTK_EXPORT %s_SafeInit(Tcl_Interp *interp)\n{\n",kitName);
fprintf(fout," return %s_Init(interp);\n}\n",kitName);
fprintf(fout,"\n\nint VTK_EXPORT %s_Init(Tcl_Interp *interp)\n{\n",
kitName);
if (!strcmp(kitName,"Vtkcommontcl"))
{
fprintf(fout,
" vtkTclInterpStruct *info = new vtkTclInterpStruct;\n");
fprintf(fout,
" info->Number = 0; info->InDelete = 0; info->DebugOn = 0; info->DeleteExistingObjectOnNew = 0;\n");
fprintf(fout,"\n");
fprintf(fout,"\n");
fprintf(fout,
" Tcl_InitHashTable(&info->InstanceLookup, TCL_STRING_KEYS);\n");
fprintf(fout,
" Tcl_InitHashTable(&info->PointerLookup, TCL_STRING_KEYS);\n");
fprintf(fout,
" Tcl_InitHashTable(&info->CommandLookup, TCL_STRING_KEYS);\n");
fprintf(fout,
" Tcl_SetAssocData(interp,(char *) \"vtk\",NULL,(ClientData *)info);\n");
fprintf(fout,
" Tcl_CreateExitHandler(vtkCommonDeleteAssocData,(ClientData *)info);\n");
/* create special vtkCommand command */
fprintf(fout," Tcl_CreateCommand(interp,(char *) \"vtkCommand\",\n"
" reinterpret_cast<vtkTclCommandType>(vtkCreateCommand),\n"
" (ClientData *)NULL, NULL);\n\n");
}
for (i = 0; i < numCommands; i++)
{
fprintf(fout," %s_Init(interp);\n", capcommands[i]);
}
fprintf(fout,"\n");
for (i = 0; i < numConcrete; i++)
{
fprintf(fout," vtkTclCreateNew(interp,(char *) \"%s\", %sNewCommand,\n",
concrete[i], concrete[i]);
fprintf(fout," %sCommand);\n",concrete[i]);
}
fprintf(fout," char pkgName[]=\"%s\";\n", libName);
fprintf(fout," char pkgVers[]=VTK_TCL_TO_STRING(VTK_MAJOR_VERSION)"
" \".\" "
"VTK_TCL_TO_STRING(VTK_MINOR_VERSION);\n");
fprintf(fout," Tcl_PkgProvide(interp, pkgName, pkgVers);\n");
fprintf(fout," return TCL_OK;\n}\n");
fclose(fout);
/* copy the file if different */
info->CAPI->CopyFileIfDifferent(tempOutputFile, outFileName);
info->CAPI->RemoveFile(tempOutputFile);
for ( i = 0; i < numCommands; i++ )
{
info->CAPI->Free(capcommands[i]);
}
free(capcommands);
free(tempOutputFile);
info->CAPI->Free(kitName);
free(outFileName);
}
/* do almost everything in the initial pass */
static int InitialPass(void *inf, void *mf, int argc, char *argv[])
{
cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
int i;
int newArgc;
char **newArgv;
int doing_sources = 1;
char **sources = 0;
char **commands = 0;
int numSources = 0;
int numCommands = 0;
int numConcrete = 0;
char **concrete = 0;
int numWrapped = 0;
cmVTKWrapTclData *cdata =
(cmVTKWrapTclData *)malloc(sizeof(cmVTKWrapTclData));
if(argc < 3 )
{
info->CAPI->SetError(info, "called with incorrect number of arguments");
return 0;
}
if (!strcmp(argv[1],"SOURCES"))
{
info->CAPI->ExpandSourceListArguments(mf, argc, argv, &newArgc,
&newArgv, 3);
}
else
{
info->CAPI->ExpandSourceListArguments(mf, argc, argv,
&newArgc, &newArgv, 2);
}
/* Now check and see if the value has been stored in the cache */
/* already, if so use that value and don't look for the program */
if(!info->CAPI->IsOn(mf,"VTK_WRAP_TCL"))
{
info->CAPI->FreeArguments(newArgc, newArgv);
return 1;
}
/* extract the sources and commands parameters */
sources = (char **)malloc(sizeof(char *)*newArgc);
commands = (char **)malloc(sizeof(char *)*newArgc);
concrete = (char **)malloc(sizeof(char *)*newArgc);
cdata->SourceFiles = (void **)malloc(sizeof(void *)*newArgc);
cdata->HeaderFiles = (char **)malloc(sizeof(char *)*newArgc);
for(i = 1; i < newArgc; ++i)
{
if(!strcmp(newArgv[i],"SOURCES"))
{
doing_sources = 1;
}
else if (!strcmp(newArgv[i],"COMMANDS"))
{
doing_sources = 0;
}
else
{
if(doing_sources)
{
sources[numSources] = newArgv[i];
numSources++;
}
else
{
commands[numCommands] = newArgv[i];
numCommands++;
}
}
}
/* get the list of classes for this library */
if (numSources)
{
/* what is the current source dir */
const char *cdir = info->CAPI->GetCurrentDirectory(mf);
int sourceListSize = 0;
char *sourceListValue = 0;
void *cfile = 0;
char *newName;
/* was the list already populated */
const char *def = info->CAPI->GetDefinition(mf, sources[0]);
/* Calculate size of source list. */
/* Start with list of source files. */
sourceListSize = info->CAPI->GetTotalArgumentSize(newArgc,newArgv);
/* Add enough to extend the name of each class. */
sourceListSize += numSources*strlen("Tcl.cxx");
/* Add enough to include the def and init file. */
sourceListSize += def?strlen(def):0;
sourceListSize += strlen(";Init.cxx");
/* Allocate and initialize the source list. */
sourceListValue = (char *)malloc(sourceListSize);
if (def)
{
sprintf(sourceListValue,"%s;%sInit.cxx",def,argv[0]);
}
else
{
sprintf(sourceListValue,"%sInit.cxx",argv[0]);
}
for(i = 1; i < numSources; ++i)
{
void *curr = info->CAPI->GetSource(mf,sources[i]);
/* if we should wrap the class */
if (!curr ||
!info->CAPI->SourceFileGetPropertyAsBool(curr,"WRAP_EXCLUDE"))
{
void *file = info->CAPI->CreateSourceFile();
char *srcName;
char *hname;
char *pathName;
srcName = info->CAPI->GetFilenameWithoutExtension(sources[i]);
pathName = info->CAPI->GetFilenamePath(sources[i]);
if (curr)
{
int abst = info->CAPI->SourceFileGetPropertyAsBool(curr,"ABSTRACT");
info->CAPI->SourceFileSetProperty(file,"ABSTRACT",
(abst ? "1" : "0"));
if (!abst)
{
concrete[numConcrete] = strdup(srcName);
numConcrete++;
}
}
else
{
concrete[numConcrete] = strdup(srcName);
numConcrete++;
}
newName = (char *)malloc(strlen(srcName)+4);
sprintf(newName,"%sTcl",srcName);
info->CAPI->SourceFileSetName2(file, newName,
info->CAPI->GetCurrentOutputDirectory(mf),
"cxx",0);
if (strlen(pathName) > 1)
{
hname = (char *)malloc(strlen(pathName) + strlen(srcName) + 4);
sprintf(hname,"%s/%s.h",pathName,srcName);
}
else
{
hname = (char *)malloc(strlen(cdir) + strlen(srcName) + 4);
sprintf(hname,"%s/%s.h",cdir,srcName);
}
/* add starting depends */
info->CAPI->SourceFileAddDepend(file,hname);
info->CAPI->AddSource(mf,file);
cdata->SourceFiles[numWrapped] = file;
cdata->HeaderFiles[numWrapped] = hname;
numWrapped++;
strcat(sourceListValue,";");
strcat(sourceListValue,newName);
strcat(sourceListValue,".cxx");
free(newName);
info->CAPI->Free(srcName);
info->CAPI->Free(pathName);
}
}
/* add the init file */
cfile = info->CAPI->CreateSourceFile();
info->CAPI->SourceFileSetProperty(cfile,"ABSTRACT","0");
newName = (char *)malloc(strlen(argv[0]) + 5);
sprintf(newName,"%sInit",argv[0]);
CreateInitFile(info,mf,argv[0],numConcrete,concrete,numCommands,commands);
info->CAPI->SourceFileSetName2(cfile, newName,
info->CAPI->GetCurrentOutputDirectory(mf),
"cxx",0);
free(newName);
info->CAPI->AddSource(mf,cfile);
info->CAPI->DestroySourceFile(cfile);
info->CAPI->AddDefinition(mf, sources[0], sourceListValue);
free(sourceListValue);
}
/* store key data in the CLientData for the final pass */
cdata->NumberWrapped = numWrapped;
cdata->LibraryName = strdup(argv[0]);
info->CAPI->SetClientData(info,cdata);
free(sources);
free(commands);
info->CAPI->FreeArguments(newArgc, newArgv);
for (i = 0; i < numConcrete; ++i)
{
free(concrete[i]);
}
free(concrete);
return 1;
}
static void FinalPass(void *inf, void *mf)
{
cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
/* get our client data from initial pass */
cmVTKWrapTclData *cdata =
(cmVTKWrapTclData *)info->CAPI->GetClientData(info);
/* first we add the rules for all the .h to Tcl.cxx files */
const char *wtcl = "${VTK_WRAP_TCL_EXE}";
const char *hints = info->CAPI->GetDefinition(mf,"VTK_WRAP_HINTS");
const char *args[4];
const char *depends[2];
int i;
int numDepends, numArgs;
const char *cdir = info->CAPI->GetCurrentDirectory(mf);
/* If the first pass terminated early, we have nothing to do. */
if(!cdata)
{
return;
}
/* wrap all the .h files */
depends[0] = wtcl;
numDepends = 1;
if (hints)
{
depends[1] = hints;
numDepends++;
}
for(i = 0; i < cdata->NumberWrapped; i++)
{
char *res;
const char *srcName = info->CAPI->SourceFileGetSourceName(cdata->SourceFiles[i]);
args[0] = cdata->HeaderFiles[i];
numArgs = 1;
if (hints)
{
args[1] = hints;
numArgs++;
}
args[numArgs] =
(info->CAPI->SourceFileGetPropertyAsBool(cdata->SourceFiles[i],"ABSTRACT") ?"0" :"1");
numArgs++;
res = (char *)malloc(strlen(info->CAPI->GetCurrentOutputDirectory(mf)) +
strlen(srcName) + 6);
sprintf(res,"%s/%s.cxx",info->CAPI->GetCurrentOutputDirectory(mf),srcName);
args[numArgs] = res;
numArgs++;
info->CAPI->AddCustomCommand(mf, args[0],
wtcl, numArgs, args, numDepends, depends,
1, &res, cdata->LibraryName);
free(res);
}
}
static void Destructor(void *inf)
{
int i;
cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
/* get our client data from initial pass */
cmVTKWrapTclData *cdata =
(cmVTKWrapTclData *)info->CAPI->GetClientData(info);
if (cdata)
{
for (i = 0; i < cdata->NumberWrapped; ++i)
{
info->CAPI->DestroySourceFile(cdata->SourceFiles[i]);
free(cdata->HeaderFiles[i]);
}
free(cdata->SourceFiles);
free(cdata->HeaderFiles);
free(cdata->LibraryName);
free(cdata);
}
}
static const char* GetTerseDocumentation()
{
return "Create Tcl Wrappers for VTK classes.";
}
static const char* GetFullDocumentation()
{
return
"VTK_WRAP_TCL(resultingLibraryName [SOURCES] SourceListName SourceLists ... [COMMANDS CommandName1 CommandName2 ...])";
}
void CM_PLUGIN_EXPORT VTK_WRAP_TCL2Init(cmLoadedCommandInfo *info)
{
info->InitialPass = InitialPass;
info->FinalPass = FinalPass;
info->Destructor = Destructor;
info->m_Inherited = 0;
info->GetTerseDocumentation = GetTerseDocumentation;
info->GetFullDocumentation = GetFullDocumentation;
info->Name = "VTK_WRAP_TCL2";
}