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.
		
		
		
		
		
			
		
			
				
					
					
						
							350 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
	
	
							350 lines
						
					
					
						
							11 KiB
						
					
					
				| /* this is a CMake loadable command to wrap vtk objects into Python */
 | |
| 
 | |
| #include "cmCPluginAPI.h"
 | |
| #include <string.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| typedef struct 
 | |
| {
 | |
|   char *LibraryName;
 | |
|   int NumberWrapped;
 | |
|   void **SourceFiles;
 | |
|   char **HeaderFiles;
 | |
| } cmVTKWrapPythonData;
 | |
| 
 | |
| /* this roputine creates the init file */
 | |
| static void CreateInitFile(cmLoadedCommandInfo *info,
 | |
|                            void *mf, const char *kitName, 
 | |
|                            int numClasses, const char **classes) 
 | |
| {
 | |
|   /* we have to make sure that the name is the correct case */
 | |
|   int i;
 | |
|   char *tempOutputFile;  
 | |
|   char *outFileName = 
 | |
|     (char *)malloc(strlen(info->CAPI->GetCurrentOutputDirectory(mf)) + 
 | |
|                    strlen(kitName) + 10);
 | |
|   FILE *fout;
 | |
|   
 | |
|   sprintf(outFileName,"%s/%sInit.cxx",
 | |
|           info->CAPI->GetCurrentOutputDirectory(mf), kitName);
 | |
|   
 | |
|   tempOutputFile = (char *)malloc(strlen(outFileName) + 5);
 | |
|   sprintf(tempOutputFile,"%s.tmp",outFileName);
 | |
|   fout = fopen(tempOutputFile,"w");
 | |
|   if (!fout)
 | |
|     {
 | |
|     return;
 | |
|     }
 | |
|   
 | |
|   fprintf(fout,"// Generated by cmVTKWrapPythonCommand2 in VTK/CMake\n\n");
 | |
|   fprintf(fout,"#include \"vtkPython.h\"\n\n");
 | |
|   fprintf(fout,"#include \"vtkSystemIncludes.h\"\n");
 | |
|   fprintf(fout,"#include <string.h>\n");
 | |
|   fprintf(fout,"// Handle compiler warning messages, etc.\n"
 | |
|           "#if defined( _MSC_VER ) && !defined(VTK_DISPLAY_WIN32_WARNINGS)\n"
 | |
|           "#pragma warning ( disable : 4706 )\n"
 | |
|           "#endif // Windows Warnings \n\n");
 | |
|   
 | |
|   for (i = 0; i < numClasses; i++)
 | |
|     {
 | |
| #ifdef _WIN32
 | |
|     fprintf(fout,"extern  \"C\" {__declspec( dllexport) PyObject *PyVTKClass_%sNew(char *); }\n",classes[i]);
 | |
| #else
 | |
|     fprintf(fout,"extern  \"C\" {PyObject *PyVTKClass_%sNew(char *); }\n",classes[i]);
 | |
| #endif
 | |
|     }
 | |
|   
 | |
|   fprintf(fout,"\nstatic PyMethodDef Py%s_ClassMethods[] = {\n",
 | |
|           kitName);
 | |
|   fprintf(fout,"{NULL, NULL, 0, NULL}};\n\n");
 | |
|   
 | |
| #ifdef _WIN32
 | |
|   fprintf(fout,"extern  \"C\" {__declspec( dllexport) void init%s();}\n\n",kitName);
 | |
|   fprintf(fout,"void init%s()\n{\n",kitName);
 | |
| #else
 | |
|   fprintf(fout,"extern  \"C\" {void initlib%s();}\n\n",kitName);
 | |
|   fprintf(fout,"void initlib%s()\n{\n",kitName);
 | |
| #endif
 | |
|   
 | |
|   
 | |
|   /* module init function */
 | |
|   fprintf(fout,"  PyObject *m, *d, *c;\n\n");
 | |
| #ifdef _WIN32
 | |
|   fprintf(fout,"  static const char modulename[] = \"%s\";\n",kitName);
 | |
| #else
 | |
|   fprintf(fout,"  static const char modulename[] = \"lib%s\";\n",kitName);
 | |
| #endif
 | |
|   fprintf(fout,"  m = Py_InitModule((char*)modulename, Py%s_ClassMethods);\n",
 | |
|     kitName);
 | |
|   
 | |
|   fprintf(fout,"  d = PyModule_GetDict(m);\n");
 | |
|   fprintf(fout,"  if (!d) Py_FatalError((char*)\"can't get dictionary for module %s!\");\n\n",
 | |
|           kitName);
 | |
|   
 | |
|   for (i = 0; i < numClasses; i++)
 | |
|     {
 | |
|     fprintf(fout,"  if ((c = PyVTKClass_%sNew((char*)modulename)))\n",
 | |
|             classes[i]);
 | |
|     fprintf(fout,"    if (-1 == PyDict_SetItemString(d, (char*)\"%s\", c))\n",
 | |
|       classes[i]);
 | |
|     fprintf(fout,"      Py_FatalError((char*)\"can't add class %s to dictionary!\");\n\n",
 | |
|             classes[i]);
 | |
|     }
 | |
|   fprintf(fout,"}\n\n");
 | |
|   fclose(fout);
 | |
| 
 | |
|   /* copy the file if different */
 | |
|   info->CAPI->CopyFileIfDifferent(tempOutputFile, outFileName);
 | |
|   info->CAPI->RemoveFile(tempOutputFile);
 | |
| }
 | |
| 
 | |
| /* 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 numClasses = 0;
 | |
|   char **classes = 0;
 | |
|   int numWrapped = 0;
 | |
|   cmVTKWrapPythonData *cdata = 
 | |
|     (cmVTKWrapPythonData *)malloc(sizeof(cmVTKWrapPythonData));
 | |
|   const char *cdir = info->CAPI->GetCurrentDirectory(mf);
 | |
|   const char *def = 0;
 | |
|   int sourceListSize = 0;
 | |
|   char *sourceListValue = 0;
 | |
|   char *newName;
 | |
|   void *cfile = 0;
 | |
| 
 | |
|   if(argc < 3 )
 | |
|     {
 | |
|     info->CAPI->SetError(info, "called with incorrect number of arguments");
 | |
|     return 0;
 | |
|     }
 | |
|   
 | |
|   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_PYTHON"))
 | |
|     {
 | |
|     info->CAPI->FreeArguments(newArgc, newArgv);
 | |
|     return 1;
 | |
|     }
 | |
| 
 | |
|   /* keep the library name */
 | |
|   classes = (char **)malloc(sizeof(char *)*newArgc);
 | |
|   cdata->LibraryName = strdup(newArgv[0]);
 | |
|   cdata->SourceFiles = (void **)malloc(sizeof(void *)*newArgc);
 | |
|   cdata->HeaderFiles = (char **)malloc(sizeof(char *)*newArgc);
 | |
| 
 | |
|   /* was the list already populated */
 | |
|   def = info->CAPI->GetDefinition(mf, newArgv[1]);
 | |
| 
 | |
|   /* 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 += newArgc*strlen("Python.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,newArgv[0]);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       /* Don't include the Init.cxx file in the library on OSX */
 | |
|       /* It is linked into a MODULE separate from the rest of the dylib */
 | |
| #if defined(__APPLE__)
 | |
|     sprintf(sourceListValue,"");
 | |
| #else
 | |
|     sprintf(sourceListValue,"%sInit.cxx",newArgv[0]);
 | |
| #endif
 | |
|     }
 | |
| 
 | |
|   /* get the classes for this lib */
 | |
|   for(i = 2; i < newArgc; ++i)
 | |
|     {   
 | |
|     void *curr = info->CAPI->GetSource(mf,newArgv[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(newArgv[i]);
 | |
|       pathName = info->CAPI->GetFilenamePath(newArgv[i]);
 | |
|       if (curr)
 | |
|         {
 | |
|         int abst = info->CAPI->SourceFileGetPropertyAsBool(curr,"ABSTRACT");
 | |
|         info->CAPI->SourceFileSetProperty(file,"ABSTRACT",
 | |
|                                           (abst ? "1" : "0"));
 | |
|         }
 | |
|       classes[numClasses] = strdup(srcName);
 | |
|       numClasses++;
 | |
|       newName = (char *)malloc(strlen(srcName)+7);
 | |
|       sprintf(newName,"%sPython",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++;
 | |
|       if(sourceListValue[0])
 | |
|         {
 | |
|         /* This is not the first value, add a separator. */
 | |
|         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(newArgv[0]) + 5);
 | |
|   sprintf(newName,"%sInit",newArgv[0]);
 | |
|   CreateInitFile(info,mf,newArgv[0],numClasses,classes);
 | |
|   info->CAPI->SourceFileSetName2(cfile, newName, 
 | |
|                                  info->CAPI->GetCurrentOutputDirectory(mf),
 | |
|                                  "cxx",0);
 | |
|   free(newName);
 | |
|   info->CAPI->AddSource(mf,cfile);
 | |
| 
 | |
|   cdata->NumberWrapped = numWrapped;
 | |
|   info->CAPI->SetClientData(info,cdata);
 | |
| 
 | |
|   info->CAPI->AddDefinition(mf, newArgv[1], sourceListValue);
 | |
|   info->CAPI->FreeArguments(newArgc, newArgv);
 | |
|   free(sourceListValue);
 | |
|   return 1;
 | |
| }
 | |
|   
 | |
|   
 | |
| static void FinalPass(void *inf, void *mf) 
 | |
| {
 | |
|   cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
 | |
|   /* get our client data from initial pass */
 | |
|   cmVTKWrapPythonData *cdata = 
 | |
|     (cmVTKWrapPythonData *)info->CAPI->GetClientData(info);
 | |
|   
 | |
|   /* first we add the rules for all the .h to Python.cxx files */
 | |
|   const char *wpython = "${VTK_WRAP_PYTHON_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] = wpython;
 | |
|   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],
 | |
|                        wpython, 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 */
 | |
|   cmVTKWrapPythonData *cdata = 
 | |
|     (cmVTKWrapPythonData *)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 Python Wrappers.";
 | |
| }
 | |
| 
 | |
| static const char* GetFullDocumentation()
 | |
| {
 | |
|   return
 | |
|     "VTK_WRAP_PYTHON(resultingLibraryName SourceListName SourceLists ...)";
 | |
| }
 | |
| 
 | |
| void CM_PLUGIN_EXPORT VTK_WRAP_PYTHON2Init(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_PYTHON2";
 | |
| }
 | |
| 
 |