/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkWrapPython.c,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkPython.h" #include #include #include #include #include "vtkParse.h" #include "vtkConfigure.h" int numberOfWrappedFunctions = 0; FunctionInfo *wrappedFunctions[1000]; extern FunctionInfo *currentFunction; static int class_has_new = 0; /* when the cpp file doesn't have enough info use the hint file */ void use_hints(FILE *fp) { int i; switch (currentFunction->ReturnType % 0x1000) { case 0x301: fprintf(fp," return Py_BuildValue((char*)\""); for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"f"); fprintf(fp,"\""); for (i = 0; i < currentFunction->HintSize; i++) { fprintf(fp,",temp%i[%d]",MAX_ARGS,i); } fprintf(fp,");\n"); break; case 0x307: fprintf(fp," return Py_BuildValue((char*)\""); for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"d"); fprintf(fp,"\""); for (i = 0; i < currentFunction->HintSize; i++) { fprintf(fp,",temp%i[%d]",MAX_ARGS,i); } fprintf(fp,");\n"); break; case 0x304: case 0x30D: fprintf(fp," return Py_BuildValue((char*)\""); for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"i"); fprintf(fp,"\""); for (i = 0; i < currentFunction->HintSize; i++) { fprintf(fp,",temp%i[%d]",MAX_ARGS,i); } fprintf(fp,");\n"); break; case 0x30A: fprintf(fp," return Py_BuildValue((char*)\""); #ifdef VTK_USE_64BIT_IDS #ifdef PY_LONG_LONG for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"L"); #else for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"l"); #endif #else for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"i"); #endif fprintf(fp,"\""); for (i = 0; i < currentFunction->HintSize; i++) { fprintf(fp,",temp%i[%d]",MAX_ARGS,i); } fprintf(fp,");\n"); break; case 0x30B: case 0x30C: fprintf(fp," return Py_BuildValue((char*)\""); #ifdef PY_LONG_LONG for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"L"); #else for (i = 0; i < currentFunction->HintSize; i++) fprintf(fp,"l"); #endif fprintf(fp,"\""); for (i = 0; i < currentFunction->HintSize; i++) { fprintf(fp,",temp%i[%d]",MAX_ARGS,i); } fprintf(fp,");\n"); break; case 0x305: case 0x306: case 0x313: case 0x314: case 0x31A: case 0x31B: case 0x31C: case 0x315: case 0x316: break; } return; } void output_temp(FILE *fp, int i, int aType, char *Id, int aCount) { /* handle VAR FUNCTIONS */ if (aType == 0x5000) { fprintf(fp," PyObject *temp%i;\n",i); return; } if (((aType % 0x10) == 0x2)&&(!((aType % 0x1000)/0x100))) { return; } /* for const * return types prototype with const */ if ((i == MAX_ARGS)&&(aType % 0x2000 >= 0x1000)) { fprintf(fp," const "); } else { fprintf(fp," "); } if ((aType % 0x100)/0x10 == 0x1) { fprintf(fp,"unsigned "); } switch (aType % 0x10) { case 0x1: fprintf(fp,"float "); break; case 0x7: fprintf(fp,"double "); break; case 0x4: fprintf(fp,"int "); break; case 0x5: fprintf(fp,"short "); break; case 0x6: fprintf(fp,"long "); break; case 0x2: fprintf(fp,"void "); break; case 0x3: fprintf(fp,"char "); break; case 0x9: fprintf(fp,"%s ",Id); break; case 0xA: fprintf(fp,"vtkIdType "); break; case 0xB: fprintf(fp,"long long "); break; case 0xC: fprintf(fp,"__int64 "); break; case 0xD: fprintf(fp,"signed char "); break; case 0x8: return; } switch ((aType % 0x1000)/0x100) { case 0x1: fprintf(fp, " *"); break; /* act " &" */ case 0x2: fprintf(fp, "&&"); break; case 0x3: if ((i == MAX_ARGS)||(aType % 0x10 == 0x9)||(aType % 0x1000 == 0x303) ||(aType % 0x1000 == 0x302)) { fprintf(fp, " *"); } break; case 0x4: fprintf(fp, "&*"); break; case 0x5: fprintf(fp, "*&"); break; case 0x7: fprintf(fp, "**"); break; default: fprintf(fp," "); break; } fprintf(fp,"temp%i",i); /* handle arrays */ if ((aType % 0x1000/0x100 == 0x3)&& (i != MAX_ARGS)&&(aType % 0x10 != 0x9)&&(aType % 0x1000 != 0x303) &&(aType % 0x1000 != 0x302)) { fprintf(fp,"[%i]",aCount); } fprintf(fp,";\n"); if (aType % 0x1000 == 0x302 && i != MAX_ARGS) { fprintf(fp," int size%d;\n",i); } if ((i != MAX_ARGS) && ((aType % 0x1000 == 0x309)||(aType % 0x1000 == 0x109))) { fprintf(fp," PyObject *tempH%d;\n",i); } } void do_return(FILE *fp) { /* ignore void */ if (((currentFunction->ReturnType % 0x10) == 0x2)&& (!((currentFunction->ReturnType % 0x1000)/0x100))) { fprintf(fp," Py_INCREF(Py_None);\n"); fprintf(fp," return Py_None;\n"); return; } switch (currentFunction->ReturnType % 0x1000) { case 0x303: fprintf(fp," if (temp%i == NULL) {\n",MAX_ARGS); fprintf(fp," Py_INCREF(Py_None);\n"); fprintf(fp," return Py_None;\n }\n"); fprintf(fp," else {\n"); fprintf(fp," return PyString_FromString(temp%i);\n }\n",MAX_ARGS); break; case 0x109: case 0x309: { fprintf(fp," return vtkPythonGetObjectFromPointer((vtkObjectBase *)temp%i);\n", MAX_ARGS); break; } /* handle functions returning vectors */ /* this is done by looking them up in a hint file */ case 0x301: case 0x307: case 0x30A: case 0x30B: case 0x30C: case 0x30D: case 0x304: case 0x305: case 0x306: use_hints(fp); break; case 0x302: { fprintf(fp," if (temp%i == NULL)\n {\n",MAX_ARGS); fprintf(fp," Py_INCREF(Py_None);\n"); fprintf(fp," return Py_None;\n }\n"); fprintf(fp," else\n {\n"); fprintf(fp," return PyString_FromString(vtkPythonManglePointer(temp%i,\"void_p\"));\n }\n", MAX_ARGS); break; } case 0x1: case 0x7: { fprintf(fp," return PyFloat_FromDouble(temp%i);\n", MAX_ARGS); break; } case 0x13: case 0x14: case 0x15: case 0x4: case 0x5: case 0x6: case 0xD: { fprintf(fp," return PyInt_FromLong(temp%i);\n", MAX_ARGS); break; } case 0x16: { #if (PY_VERSION_HEX >= 0x02020000) fprintf(fp," return PyLong_FromUnsignedLong(temp%i);\n", MAX_ARGS); #else fprintf(fp," return PyInt_FromLong((long)temp%i);\n", MAX_ARGS); #endif break; } #if defined(VTK_USE_64BIT_IDS) && defined(PY_LONG_LONG) && (VTK_SIZEOF_LONG != VTK_SIZEOF_ID_TYPE) case 0xA: { fprintf(fp," return PyLong_FromLongLong(temp%i);\n", MAX_ARGS); break; } case 0x1A: { fprintf(fp," return PyLong_FromUnsignedLongLong(temp%i);\n", MAX_ARGS); break; } #else case 0xA: { fprintf(fp," return PyInt_FromLong((long)temp%i);\n", MAX_ARGS); break; } case 0x1A: { #if (PY_VERSION_HEX >= 0x02020000) fprintf(fp," return PyLong_FromUnsignedLong((unsigned long)temp%i);\n", MAX_ARGS); #else fprintf(fp," return PyInt_FromLong((long)temp%i);\n", MAX_ARGS); #endif break; } #endif #if defined(VTK_SIZEOF_LONG_LONG) # if defined(PY_LONG_LONG) && (VTK_SIZEOF_LONG != VTK_SIZEOF_LONG_LONG) case 0xB: { fprintf(fp," return PyLong_FromLongLong(temp%i);\n", MAX_ARGS); break; } case 0x1B: { fprintf(fp," return PyLong_FromUnsignedLongLong(temp%i);\n", MAX_ARGS); break; } # else case 0xB: { fprintf(fp," return PyLong_FromLong(temp%i);\n", MAX_ARGS); break; } case 0x1B: { fprintf(fp," return PyLong_FromUnsignedLong(temp%i);\n", MAX_ARGS); break; } # endif #endif #if defined(VTK_SIZEOF___INT64) # if defined(PY_LONG_LONG) && (VTK_SIZEOF_LONG != VTK_SIZEOF___INT64) case 0xC: { fprintf(fp," return PyLong_FromLongLong(temp%i);\n", MAX_ARGS); break; } case 0x1C: { fprintf(fp," return PyLong_FromUnsignedLongLong(temp%i);\n", MAX_ARGS); break; } # else case 0xC: { fprintf(fp," return PyLong_FromLong(temp%i);\n", MAX_ARGS); break; } case 0x1C: { fprintf(fp," return PyLong_FromUnsignedLong(temp%i);\n", MAX_ARGS); break; } # endif #endif case 0x3: { fprintf(fp," return PyString_FromStringAndSize((char *)&temp%i,1);\n", MAX_ARGS); break; } } } char *get_format_string() { static char result[1024]; int currPos = 0; int argtype; int i, j; if (currentFunction->ArgTypes[0] == 0x5000) { result[currPos] = 'O'; currPos++; result[currPos] = '\0'; return result; } for (i = 0; i < currentFunction->NumberOfArguments; i++) { argtype = currentFunction->ArgTypes[i] % 0x1000; switch (argtype) { case 0x301: result[currPos] = '('; currPos++; for (j = 0; j < currentFunction->ArgCounts[i]; j++) { result[currPos] = 'f'; currPos++; } result[currPos] = ')'; currPos++; break; case 0x307: result[currPos] = '('; currPos++; for (j = 0; j < currentFunction->ArgCounts[i]; j++) { result[currPos] = 'd'; currPos++; } result[currPos] = ')'; currPos++; break; case 0x304: result[currPos] = '('; currPos++; for (j = 0; j < currentFunction->ArgCounts[i]; j++) { result[currPos] = 'i'; currPos++; } result[currPos] = ')'; currPos++; break; case 0x30A: result[currPos] = '('; currPos++; for (j = 0; j < currentFunction->ArgCounts[i]; j++) { #ifdef VTK_USE_64BIT_IDS #ifdef PY_LONG_LONG result[currPos] = 'L'; currPos++; #else result[currPos] = 'l'; currPos++; #endif #else result[currPos] = 'i'; currPos++; #endif } result[currPos] = ')'; currPos++; break; case 0x30B: case 0x30C: result[currPos] = '('; currPos++; for (j = 0; j < currentFunction->ArgCounts[i]; j++) { #ifdef PY_LONG_LONG result[currPos] = 'L'; currPos++; #else result[currPos] = 'l'; currPos++; #endif } result[currPos] = ')'; currPos++; break; case 0x109: case 0x309: result[currPos] = 'O'; currPos++; break; case 0x303: result[currPos] = 'z'; currPos++; break; case 0x302: result[currPos] = 's'; currPos++; result[currPos] = '#'; currPos++; break; case 0x1: result[currPos] = 'f'; currPos++; break; case 0x7: result[currPos] = 'd'; currPos++; break; case 0x14: case 0x4: result[currPos] = 'i'; currPos++; break; case 0x15: case 0x5: result[currPos] = 'h'; currPos++; break; case 0x16: case 0x6: result[currPos] = 'l'; currPos++; break; case 0x1A: case 0xA: #ifdef VTK_USE_64BIT_IDS #ifdef PY_LONG_LONG result[currPos] = 'L'; currPos++; break; #else result[currPos] = 'l'; currPos++; break; #endif #else result[currPos] = 'i'; currPos++; break; #endif #ifdef PY_LONG_LONG case 0xB: case 0xC: result[currPos] = 'L'; currPos++; break; #else case 0xB: case 0xC: result[currPos] = 'l'; currPos++; break; #endif case 0xD: result[currPos] = 'i'; currPos++; break; case 0x3: result[currPos] = 'c'; currPos++; break; case 0x13: result[currPos] = 'b'; currPos++; break; } } result[currPos] = '\0'; return result; } static void add_to_sig(char *sig, char *add, int *i) { strcpy(&sig[*i],add); *i += (int)strlen(add); } void get_python_signature() { static char result[1024]; int currPos = 0; int argtype; int i, j; /* print out the name of the method */ add_to_sig(result,"V.",&currPos); add_to_sig(result,currentFunction->Name,&currPos); /* print the arg list */ add_to_sig(result,"(",&currPos); for (i = 0; i < currentFunction->NumberOfArguments; i++) { if (currentFunction->ArgTypes[i] == 0x5000) { add_to_sig(result,"function",&currPos); } argtype = currentFunction->ArgTypes[i] % 0x1000; if (i != 0) { add_to_sig(result,", ",&currPos); } switch (argtype) { case 0x301: case 0x307: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->ArgCounts[i]; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } add_to_sig(result,"float",&currPos); } add_to_sig(result,")",&currPos); break; case 0x304: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->ArgCounts[i]; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } add_to_sig(result,"int",&currPos); } add_to_sig(result,")",&currPos); break; case 0x30A: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->ArgCounts[i]; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } #if defined(VTK_USE_64BIT_IDS) && (VTK_SIZEOF_LONG != VTK_SIZEOF_ID_TYPE) add_to_sig(result,"long",&currPos); #else add_to_sig(result,"int",&currPos); #endif } add_to_sig(result,")",&currPos); break; case 0x30B: case 0x30C: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->ArgCounts[i]; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } add_to_sig(result,"long",&currPos); } add_to_sig(result,")",&currPos); break; case 0x109: case 0x309: add_to_sig(result,currentFunction->ArgClasses[i],&currPos); break; case 0x302: case 0x303: add_to_sig(result,"string",&currPos); break; case 0x1: case 0x7: add_to_sig(result,"float",&currPos); break; case 0xD: case 0xA: case 0x1B: case 0xB: case 0x1C: case 0xC: case 0x14: case 0x4: case 0x15: case 0x5: case 0x16: case 0x6: add_to_sig(result,"int",&currPos); break; case 0x3: add_to_sig(result,"char",&currPos); break; case 0x13: add_to_sig(result,"int",&currPos); break; } } add_to_sig(result,")",&currPos); /* if this is a void method, we are finished */ /* otherwise, print "->" and the return type */ if ((!((currentFunction->ReturnType % 0x10) == 0x2)) || ((currentFunction->ReturnType % 0x1000)/0x100)) { add_to_sig(result," -> ",&currPos); switch (currentFunction->ReturnType % 0x1000) { case 0x302: case 0x303: add_to_sig(result,"string",&currPos); break; case 0x109: case 0x309: add_to_sig(result,currentFunction->ReturnClass,&currPos); break; case 0x301: case 0x307: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->HintSize; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } add_to_sig(result,"float",&currPos); } add_to_sig(result,")",&currPos); break; case 0x304: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->HintSize; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } add_to_sig(result,"int",&currPos); } add_to_sig(result,")",&currPos); break; case 0x30A: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->HintSize; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } #if defined(VTK_USE_64BIT_IDS) && (VTK_SIZEOF_LONG != VTK_SIZEOF_ID_TYPE) add_to_sig(result,"long",&currPos); #else add_to_sig(result,"int",&currPos); #endif } add_to_sig(result,")",&currPos); break; case 0x30B: case 0x30C: add_to_sig(result,"(",&currPos); for (j = 0; j < currentFunction->HintSize; j++) { if (j != 0) { add_to_sig(result,", ",&currPos); } add_to_sig(result,"long",&currPos); } add_to_sig(result,")",&currPos); break; case 0x1: case 0x7: add_to_sig(result,"float",&currPos); break; case 0xA: case 0xB: case 0xC: case 0xD: case 0x1B: case 0x1C: case 0x13: case 0x14: case 0x15: case 0x16: case 0x4: case 0x5: case 0x6: add_to_sig(result,"int",&currPos); break; case 0x3: add_to_sig(result,"char",&currPos); break; } } if (currentFunction->Signature) { add_to_sig(result,"\\nC++: ",&currPos); add_to_sig(result,currentFunction->Signature,&currPos); } currentFunction->Signature = realloc(currentFunction->Signature,currPos+1); strcpy(currentFunction->Signature,result); /* fprintf(stderr,"%s\n",currentFunction->Signature); */ } /* convert special characters in a string into their escape codes, so that the string can be quoted in a source file (the specified maxlen must be at least 32 chars)*/ static const char *quote_string(const char *comment, int maxlen) { static char *result = 0; static int oldmaxlen = 0; int i, j, n; if (maxlen > oldmaxlen) { if (result) { free(result); } result = (char *)malloc(maxlen); oldmaxlen = maxlen; } if (comment == NULL) { return ""; } j = 0; n = (int)strlen(comment); for (i = 0; i < n; i++) { if (comment[i] == '\"') { strcpy(&result[j],"\\\""); j += 2; } else if (comment[i] == '\\') { strcpy(&result[j],"\\\\"); j += 2; } else if (comment[i] == '\n') { strcpy(&result[j],"\\n"); j += 2; } else if (isprint(comment[i])) { result[j] = comment[i]; j++; } else { sprintf(&result[j],"\\%3.3o",comment[i]); j += 4; } if (j >= maxlen - 21) { sprintf(&result[j]," ...\\n [Truncated]\\n"); j += (int)strlen(" ...\\n [Truncated]\\n"); break; } } result[j] = '\0'; return result; } void outputFunction2(FILE *fp, FileInfo *data) { int i, j, k, is_static, is_vtkobject, fnum, occ, backnum, goto_used; FunctionInfo *theFunc; FunctionInfo *backFunc; is_vtkobject = ((strcmp(data->ClassName,"vtkObjectBase") == 0) || (data->NumberOfSuperClasses != 0)); /* create a python-type signature for each method (for use in docstring) */ for (fnum = 0; fnum < numberOfWrappedFunctions; fnum++) { theFunc = wrappedFunctions[fnum]; currentFunction = theFunc; get_python_signature(); } /* create external type declarations for all object return types */ for (fnum = 0; fnum < numberOfWrappedFunctions; fnum++) { theFunc = wrappedFunctions[fnum]; currentFunction = theFunc; /* check for object return types */ if ((theFunc->ReturnType % 0x1000 == 0x309)|| (theFunc->ReturnType % 0x1000 == 0x109)) { /* check that we haven't done this type (no duplicate declarations) */ for (backnum = fnum-1; backnum >= 0; backnum--) { backFunc = wrappedFunctions[backnum]; if (((backFunc->ReturnType % 0x1000 == 0x309)|| (backFunc->ReturnType % 0x1000 == 0x109)) && (strcmp(theFunc->ReturnClass,backFunc->ReturnClass) == 0)) { break; } } } } /* for each function in the array */ for (fnum = 0; fnum < numberOfWrappedFunctions; fnum++) { /* make sure we haven't already done one of these */ theFunc = wrappedFunctions[fnum]; currentFunction = theFunc; if (theFunc->Name) { fprintf(fp,"\n"); /* check whether all signatures are static methods */ is_static = 1; for (occ = fnum; occ < numberOfWrappedFunctions; occ++) { /* is it the same name */ if (wrappedFunctions[occ]->Name && !strcmp(theFunc->Name,wrappedFunctions[occ]->Name)) { /* check for static methods */ if (((wrappedFunctions[occ]->ReturnType/0x1000) & 0x2) != 0x2) { is_static = 0; } } } if(currentFunction->IsLegacy) { fprintf(fp,"#if !defined(VTK_LEGACY_REMOVE)\n"); } fprintf(fp,"static PyObject *Py%s_%s(PyObject *%s, PyObject *args)\n", data->ClassName,currentFunction->Name, (is_static ? "" : "self")); fprintf(fp,"{\n"); /* find all occurances of this method */ for (occ = fnum; occ < numberOfWrappedFunctions; occ++) { goto_used = 0; is_static = 0; /* is it the same name */ if (wrappedFunctions[occ]->Name && !strcmp(theFunc->Name,wrappedFunctions[occ]->Name)) { /* check for static methods */ if (((wrappedFunctions[occ]->ReturnType/0x1000) & 0x2) == 0x2) { is_static = 1; } fprintf(fp," /* handle an occurrence */\n {\n"); /* declare the variables */ if (!is_static) { if (is_vtkobject) { fprintf(fp," %s *op;\n\n",data->ClassName); } else { fprintf(fp," %s *op = (%s *)((PyVTKSpecialObject *)self)->vtk_ptr;\n\n",data->ClassName,data->ClassName); } } currentFunction = wrappedFunctions[occ]; /* process the args */ for (i = 0; i < currentFunction->NumberOfArguments; i++) { output_temp(fp, i, currentFunction->ArgTypes[i], currentFunction->ArgClasses[i], currentFunction->ArgCounts[i]); } output_temp(fp, MAX_ARGS,currentFunction->ReturnType, currentFunction->ReturnClass,0); /* don't clear error first time around */ if (occ != fnum) { fprintf(fp," PyErr_Clear();\n"); } if (is_static || !is_vtkobject) { fprintf(fp," if ((PyArg_ParseTuple(args, (char*)\"%s\"", get_format_string()); } else { fprintf(fp," if ((op = (%s *)PyArg_VTKParseTuple(self, args, (char*)\"%s\"", data->ClassName,get_format_string()); } for (i = 0; i < currentFunction->NumberOfArguments; i++) { if ((currentFunction->ArgTypes[i] % 0x1000 == 0x309)|| (currentFunction->ArgTypes[i] % 0x1000 == 0x109)) { fprintf(fp,", &tempH%d",i); } else if (currentFunction->ArgTypes[i] % 0x1000 == 0x302) { fprintf(fp,", &temp%d, &size%d",i,i); } else { if (currentFunction->ArgCounts[i]) { for (j = 0; j < currentFunction->ArgCounts[i]; j++) { fprintf(fp,", temp%d + %d",i,j); } } else { fprintf(fp,", &temp%d",i); } } } fprintf(fp,")))\n {\n"); /* lookup and required objects */ for (i = 0; i < currentFunction->NumberOfArguments; i++) { if ((currentFunction->ArgTypes[i] % 0x1000 == 0x309)|| (currentFunction->ArgTypes[i] % 0x1000 == 0x109)) { fprintf(fp," temp%d = (%s *)vtkPythonGetPointerFromObject(tempH%d,(char*)\"%s\");\n", i, currentFunction->ArgClasses[i], i, currentFunction->ArgClasses[i]); fprintf(fp," if (!temp%d && tempH%d != Py_None) goto break%d;\n",i,i,occ); goto_used = 1; } } /* make sure passed method is callable for VAR functions */ if (currentFunction->NumberOfArguments == 0x1 && currentFunction->ArgTypes[0] == 0x5000) { fprintf(fp," if (!PyCallable_Check(temp0) && temp0 != Py_None)\n"); fprintf(fp," {\n PyErr_SetString(PyExc_ValueError,\"vtk callback method passed to %s in %s was not callable.\");\n", currentFunction->Name,data->ClassName); fprintf(fp," return NULL;\n }\n"); fprintf(fp," Py_INCREF(temp0);\n"); } /* check for void pointers and pass appropriate info*/ for (i = 0; i < currentFunction->NumberOfArguments; i++) { if (currentFunction->ArgTypes[i] % 0x1000 == 0x302) { fprintf(fp," temp%i = vtkPythonUnmanglePointer((char *)temp%i,&size%i,(char*)\"%s\");\n",i,i,i,"void_p"); fprintf(fp," if (size%i == -1) {\n PyErr_SetString(PyExc_ValueError,\"mangled pointer to %s in %s was of incorrect type.\");\n", i,currentFunction->Name,data->ClassName); fprintf(fp," return NULL;\n }\n"); fprintf(fp," else if (size%i == -2) {\n PyErr_SetString(PyExc_ValueError,\"mangled pointer to %s in %s was poorly formed.\");\n", i,currentFunction->Name,data->ClassName); fprintf(fp," return NULL;\n }\n"); } } for (k = 0; k < (2 - (is_static || !is_vtkobject)); k++) { char methodname[256]; if (k == 0) { if (is_static) { fprintf(fp," {\n"); sprintf(methodname,"%s::%s", data->ClassName,currentFunction->Name); } else if (!is_vtkobject) { fprintf(fp," {\n"); sprintf(methodname,"op->%s",currentFunction->Name); } else { if (currentFunction->IsPureVirtual) { fprintf(fp," if (PyVTKClass_Check(self))\n {\n"); fprintf(fp," PyErr_SetString(PyExc_TypeError,\"pure virtual method call\");\n"); fprintf(fp," return NULL;\n }\n"); continue; } else { fprintf(fp," if (PyVTKClass_Check(self))\n {\n"); sprintf(methodname,"op->%s::%s", data->ClassName,currentFunction->Name); } } } else { fprintf(fp," else\n {\n"); sprintf(methodname,"op->%s",currentFunction->Name); } switch (currentFunction->ReturnType % 0x1000) { case 0x2: fprintf(fp," %s(",methodname); break; case 0x109: fprintf(fp," temp%i = &%s(",MAX_ARGS,methodname); break; default: fprintf(fp," temp%i = %s(",MAX_ARGS,methodname); } for (i = 0; i < currentFunction->NumberOfArguments; i++) { if (i) { fprintf(fp,","); } if (currentFunction->ArgTypes[i] % 0x1000 == 0x109) { fprintf(fp,"*(temp%i)",i); } else if (currentFunction->NumberOfArguments == 1 && currentFunction->ArgTypes[i] == 0x5000) { fprintf(fp,"((temp0 != Py_None) ? vtkPythonVoidFunc : NULL),(void *)temp%i",i); } else { fprintf(fp,"temp%i",i); } } fprintf(fp,");\n"); if (currentFunction->NumberOfArguments == 1 && currentFunction->ArgTypes[0] == 0x5000) { fprintf(fp," %sArgDelete(vtkPythonVoidFuncArgDelete);\n", methodname); } fprintf(fp," }\n"); } for (i = 0; i < currentFunction->NumberOfArguments; i++) { if (currentFunction->ArgCounts[i] && /* array */ currentFunction->ArgTypes[i] % 0x10 != 0 && /* not a special type */ currentFunction->ArgTypes[i] % 0x10 != 0x9 && /* not class pointer */ currentFunction->ArgTypes[i] % 0x10 != 0x8 && currentFunction->ArgTypes[i] % 0x10 != 0x2 && /* not void pointer */ (currentFunction->ArgTypes[i] % 0x2000 < 0x1000)) /* not const */ { fprintf(fp," if (vtkPythonCheckArray(args,%d,temp%d,%d)) {\n" " return 0;\n" " }\n", i, i, currentFunction->ArgCounts[i]); } } do_return(fp); fprintf(fp," }\n }\n"); if (goto_used) { fprintf(fp," break%d:\n",occ); } } } fprintf(fp," return NULL;\n}\n"); if(currentFunction->IsLegacy) { fprintf(fp,"#endif\n"); } fprintf(fp,"\n"); /* clear all occurances of this method from further consideration */ for (occ = fnum + 1; occ < numberOfWrappedFunctions; occ++) { /* is it the same name */ if (wrappedFunctions[occ]->Name && !strcmp(theFunc->Name,wrappedFunctions[occ]->Name)) { int siglen = (int)strlen(wrappedFunctions[fnum]->Signature); /* memory leak here but ... */ wrappedFunctions[occ]->Name = NULL; wrappedFunctions[fnum]->Signature = (char *) realloc(wrappedFunctions[fnum]->Signature,siglen+3+ strlen(wrappedFunctions[occ]->Signature)); strcpy(&wrappedFunctions[fnum]->Signature[siglen],"\\n"); strcpy(&wrappedFunctions[fnum]->Signature[siglen+2], wrappedFunctions[occ]->Signature); } } } /* is this method non NULL */ } /* loop over all methods */ /* output the method table */ /* for each function in the array */ fprintf(fp,"static PyMethodDef Py%sMethods[] = {\n",data->ClassName); for (fnum = 0; fnum < numberOfWrappedFunctions; fnum++) { if(wrappedFunctions[fnum]->IsLegacy) { fprintf(fp,"#if !defined(VTK_LEGACY_REMOVE)\n"); } if (wrappedFunctions[fnum]->Name) { fprintf(fp," {(char*)\"%s\", (PyCFunction)Py%s_%s, 1,\n (char*)\"%s\\n\\n%s\"},\n", wrappedFunctions[fnum]->Name, data->ClassName, wrappedFunctions[fnum]->Name, wrappedFunctions[fnum]->Signature, quote_string(wrappedFunctions[fnum]->Comment,1000)); } if(wrappedFunctions[fnum]->IsLegacy) { fprintf(fp,"#endif\n"); } } if (!strcmp("vtkObject",data->ClassName)) { fprintf(fp," {(char*)\"AddObserver\", (PyCFunction)Py%s_AddObserver, 1,\n (char*)\"V.AddObserver(int, function) -> int\\n\\n Add an event callback function(vtkObject, int) for an event type.\\n Returns a handle that can be used with RemoveEvent(int).\"},\n", data->ClassName); } else if (!strcmp("vtkObjectBase",data->ClassName)) { fprintf(fp," {(char*)\"GetAddressAsString\", (PyCFunction)Py%s_GetAddressAsString, 1,\n (char*)\"V.GetAddressAsString(string) -> string\\n\\n Get address of C++ object in format 'Addr=%%p' after casting to\\n the specified type. You can get the same information from V.__this__.\"},\n", data->ClassName); fprintf(fp," {(char*)\"PrintRevisions\", (PyCFunction)Py%s_PrintRevisions, 1,\n (char*)\"V.PrintRevisions() -> string\\n\\n Prints the .cxx file CVS revisions of the classes in the\\n object's inheritance chain.\"},\n", data->ClassName); } fprintf(fp," {NULL, NULL, 0, NULL}\n};\n\n"); } void outputFunction(FILE *fp, FileInfo *data) { int i; int args_ok = 1; fp = fp; /* some functions will not get wrapped no matter what else, and some really common functions will appear only in vtkObjectPython */ if (currentFunction->IsOperator || currentFunction->ArrayFailure || !currentFunction->IsPublic || !currentFunction->Name) { return; } /* check to see if we can handle the args */ for (i = 0; i < currentFunction->NumberOfArguments; i++) { if (currentFunction->ArgTypes[i] % 0x1000 == 9) args_ok = 0; if ((currentFunction->ArgTypes[i] % 0x10) == 8) args_ok = 0; if (((currentFunction->ArgTypes[i] % 0x1000)/0x100 != 0x3)&& (currentFunction->ArgTypes[i] % 0x1000 != 0x109)&& ((currentFunction->ArgTypes[i] % 0x1000)/0x100)) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x313) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x314) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x31A) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x31B) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x31C) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x315) args_ok = 0; if (currentFunction->ArgTypes[i] % 0x1000 == 0x316) args_ok = 0; } if ((currentFunction->ReturnType % 0x10) == 0x8) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x9) args_ok = 0; if (((currentFunction->ReturnType % 0x1000)/0x100 != 0x3)&& (currentFunction->ReturnType % 0x1000 != 0x109)&& ((currentFunction->ReturnType % 0x1000)/0x100)) args_ok = 0; /* eliminate unsigned char * and unsigned short * */ if (currentFunction->ReturnType % 0x1000 == 0x313) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x314) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x31A) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x31B) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x31C) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x315) args_ok = 0; if (currentFunction->ReturnType % 0x1000 == 0x316) args_ok = 0; if (currentFunction->NumberOfArguments && (currentFunction->ArgTypes[0] == 0x5000) &&(currentFunction->NumberOfArguments != 0x1)) args_ok = 0; /* make sure we have all the info we need for array arguments in */ for (i = 0; i < currentFunction->NumberOfArguments; i++) { if (((currentFunction->ArgTypes[i] % 0x1000)/0x100 == 0x3)&& (currentFunction->ArgCounts[i] <= 0)&& (currentFunction->ArgTypes[i] % 0x1000 != 0x309)&& (currentFunction->ArgTypes[i] % 0x1000 != 0x303)&& (currentFunction->ArgTypes[i] % 0x1000 != 0x302)) args_ok = 0; } /* if we need a return type hint make sure we have one */ switch (currentFunction->ReturnType % 0x1000) { case 0x301: case 0x307: case 0x30A: case 0x30B: case 0x30C: case 0x30D: case 0x304: case 0x305: case 0x306: args_ok = currentFunction->HaveHint; break; } /* make sure it isn't a Delete or New function */ if (!strcmp("Delete",currentFunction->Name) || !strcmp("New",currentFunction->Name)) { args_ok = 0; } /* check for New() function */ if (!strcmp("New",currentFunction->Name) && currentFunction->NumberOfArguments == 0) { class_has_new = 1; } if (currentFunction->IsPublic && args_ok && strcmp(data->ClassName,currentFunction->Name) && strcmp(data->ClassName, currentFunction->Name + 1)) { wrappedFunctions[numberOfWrappedFunctions] = currentFunction; numberOfWrappedFunctions++; } } static void create_class_doc(FILE *fp, FileInfo *data) { const char *text; int i, n; char temp[500]; if (data->NameComment) { text = data->NameComment; while (*text == ' ') { text++; } fprintf(fp," (char*)\"%s\\n\\n\",\n",quote_string(text,500)); } else { fprintf(fp," (char*)\"%s - no description provided.\\n\\n\",\n", quote_string(data->ClassName,500)); } if (data->NumberOfSuperClasses > 0) { fprintf(fp," \"Super Class:\\n\\n %s\\n\\n\",\n", quote_string(data->SuperClasses[0],500)); } if (data->Description) { n = (int)((strlen(data->Description) + 400-1)/400); for (i = 0; i < n; i++) { strncpy(temp, &data->Description[400*i], 400); temp[400] = '\0'; if (i < n-1) { fprintf(fp," (char*)\"%s\",\n",quote_string(temp,500)); } else { /* just for the last time */ fprintf(fp," (char*)\"%s\\n\",\n",quote_string(temp,500)); } } } else { fprintf(fp," (char*)\"%s\\n\",\n", "None provided.\\n"); } if (data->Caveats) { fprintf(fp," \"Caveats:\\n\\n"); fprintf(fp,"%s\\n\",\n", quote_string(data->Caveats,500)); } if (data->SeeAlso) { char *dup, *tok; fprintf(fp," \"See Also:\\n\\n"); dup = strdup(data->SeeAlso); tok = strtok(dup," "); while (tok) { fprintf(fp," %s",quote_string(tok,120)); tok = strtok(NULL," "); } free(dup); fprintf(fp,"\\n\",\n"); } fprintf(fp," NULL\n"); } /* print the parsed structures */ void vtkParseOutput(FILE *fp, FileInfo *data) { int i; fprintf(fp,"// python wrapper for %s object\n//\n",data->ClassName); fprintf(fp,"#define VTK_WRAPPING_CXX\n"); if (strcmp("vtkObjectBase",data->ClassName) != 0) { /* Block inclusion of full streams. */ fprintf(fp,"#define VTK_STREAMS_FWD_ONLY\n"); } #if !defined(__APPLE__) fprintf(fp,"#include \"vtkPython.h\"\n"); fprintf(fp,"#undef _XOPEN_SOURCE /* Conflicts with standards.h. */\n"); fprintf(fp,"#undef _THREAD_SAFE /* Conflicts with pthread.h. */\n"); fprintf(fp,"#include \"vtkPythonUtil.h\"\n"); #endif fprintf(fp,"#include \"%s.h\"\n",data->ClassName); #if defined(__APPLE__) fprintf(fp,"#include \"vtkPythonUtil.h\"\n"); #endif fprintf(fp,"#if defined(WIN32)\n"); fprintf(fp,"extern \"C\" { __declspec( dllexport ) PyObject *PyVTKClass_%sNew(char *); }\n", data->ClassName); fprintf(fp,"#else\n"); fprintf(fp,"extern \"C\" { PyObject *PyVTKClass_%sNew(char *); }\n", data->ClassName); fprintf(fp,"#endif\n\n"); for (i = 0; i < data->NumberOfSuperClasses; i++) { fprintf(fp,"extern \"C\" { PyObject *PyVTKClass_%sNew(char *); }\n", data->SuperClasses[i]); } if (!strcmp("vtkObject",data->ClassName)) { /* Add the AddObserver method to vtkObject. */ fprintf(fp,"static PyObject *PyvtkObject_AddObserver(PyObject *self, PyObject *args)\n"); fprintf(fp,"{\n"); fprintf(fp," vtkObject *op;\n"); fprintf(fp," char *temp0;\n"); fprintf(fp," PyObject *temp1;\n"); fprintf(fp," float temp2;\n"); fprintf(fp," unsigned long temp20 = 0;\n"); fprintf(fp," if ((op = (vtkObject *)PyArg_VTKParseTuple(self, args, (char*)\"zO\", &temp0, &temp1)))\n"); fprintf(fp," {\n"); fprintf(fp," if (!PyCallable_Check(temp1) && temp1 != Py_None)\n"); fprintf(fp," {\n"); fprintf(fp," PyErr_SetString(PyExc_ValueError,\"vtk callback method passed to AddObserver was not callable.\");\n"); fprintf(fp," return NULL;\n"); fprintf(fp," }\n"); fprintf(fp," Py_INCREF(temp1);\n"); fprintf(fp," vtkPythonCommand *cbc = vtkPythonCommand::New();\n"); fprintf(fp," cbc->SetObject(temp1);\n"); fprintf(fp," temp20 = op->AddObserver(temp0,cbc);\n"); fprintf(fp," cbc->Delete();\n"); fprintf(fp," return PyInt_FromLong((long)temp20);\n"); fprintf(fp," }\n"); fprintf(fp," PyErr_Clear();\n"); fprintf(fp," if ((op = (vtkObject *)PyArg_VTKParseTuple(self, args, (char*)\"zOf\", &temp0, &temp1, &temp2)))\n"); fprintf(fp," {\n"); fprintf(fp," if (!PyCallable_Check(temp1) && temp1 != Py_None)\n"); fprintf(fp," {\n"); fprintf(fp," PyErr_SetString(PyExc_ValueError,\"vtk callback method passed to AddObserver was not callable.\");\n"); fprintf(fp," return NULL;\n"); fprintf(fp," }\n"); fprintf(fp," Py_INCREF(temp1);\n"); fprintf(fp," vtkPythonCommand *cbc = vtkPythonCommand::New();\n"); fprintf(fp," cbc->SetObject(temp1);\n"); fprintf(fp," temp20 = op->AddObserver(temp0,cbc,temp2);\n"); fprintf(fp," cbc->Delete();\n"); fprintf(fp," return PyInt_FromLong((long)temp20);\n"); fprintf(fp," }\n"); fprintf(fp," return NULL;\n"); fprintf(fp,"}\n\n"); } if (!strcmp("vtkObjectBase",data->ClassName)) { /* while we are at it spit out the GetStringFromObject method */ fprintf(fp,"PyObject *PyvtkObjectBase_GetAddressAsString(PyObject *self, PyObject *args)\n"); fprintf(fp,"{\n"); /* declare the variables */ fprintf(fp," %s *op;\n",data->ClassName); /* handle unbound method call if 'self' is a PyVTKClass */ fprintf(fp," char *typecast;\n\n"); fprintf(fp," if ((op = (%s *)PyArg_VTKParseTuple(self, args, (char*)\"s\", &typecast)))\n",data->ClassName); fprintf(fp," {\n char temp20[256];\n"); fprintf(fp," sprintf(temp20,\"Addr=%%p\",op);\n"); fprintf(fp," return PyString_FromString(temp20);\n"); fprintf(fp," }\n"); fprintf(fp," return NULL;\n}\n\n"); /* Add the PrintRevisions method to vtkObjectBase. */ fprintf(fp,"PyObject *PyvtkObjectBase_PrintRevisions(PyObject *self, PyObject *args)\n"); fprintf(fp,"{\n"); fprintf(fp," %s *op;\n",data->ClassName); fprintf(fp," if ((op = (%s *)PyArg_VTKParseTuple(self, args, (char*)\"\")))\n",data->ClassName); fprintf(fp," {\n"); fprintf(fp," ostrstream vtkmsg_with_warning_C4701;\n"); fprintf(fp," op->PrintRevisions(vtkmsg_with_warning_C4701);\n"); fprintf(fp," vtkmsg_with_warning_C4701.put('\\0');\n"); fprintf(fp," PyObject *result = PyString_FromString(vtkmsg_with_warning_C4701.str());\n"); fprintf(fp," delete vtkmsg_with_warning_C4701.str();\n"); fprintf(fp," return result;\n"); fprintf(fp," }\n"); fprintf(fp," return NULL;\n}\n\n"); } /* insert function handling code here */ for (i = 0; i < data->NumberOfFunctions; i++) { currentFunction = data->Functions + i; outputFunction(fp, data); } if (data->NumberOfSuperClasses || !data->IsAbstract) { outputFunction2(fp, data); } /* the docstring for the class */ if (data->NumberOfSuperClasses || !data->IsAbstract) { fprintf(fp,"static const char *%sDoc[] = {\n",data->ClassName); create_class_doc(fp,data); fprintf(fp,"};\n\n"); } /* output the class initilization function */ if (strcmp(data->ClassName,"vtkObjectBase") == 0) { /* special wrapping for vtkObject */ if (class_has_new) { fprintf(fp,"static vtkObjectBase *%sStaticNew()\n",data->ClassName); fprintf(fp,"{\n return %s::New();\n}\n\n",data->ClassName); } fprintf(fp,"PyObject *PyVTKClass_%sNew(char *modulename)\n{\n",data->ClassName); if (class_has_new) { fprintf(fp," return PyVTKClass_New(&%sStaticNew,\n",data->ClassName); } else { fprintf(fp," return PyVTKClass_New(NULL,\n"); } fprintf(fp," Py%sMethods,\n",data->ClassName); fprintf(fp," (char*)\"%s\",modulename,\n",data->ClassName); fprintf(fp," (char**)%sDoc,0);\n}\n\n",data->ClassName); } else if (data->NumberOfSuperClasses) { /* wrapping of descendants of vtkObjectBase */ if (class_has_new) { fprintf(fp,"static vtkObjectBase *%sStaticNew()\n",data->ClassName); fprintf(fp,"{\n return %s::New();\n}\n\n",data->ClassName); } fprintf(fp,"PyObject *PyVTKClass_%sNew(char *modulename)\n{\n",data->ClassName); if (class_has_new) { fprintf(fp," return PyVTKClass_New(&%sStaticNew,\n",data->ClassName); } else { fprintf(fp," return PyVTKClass_New(NULL,\n"); } fprintf(fp," Py%sMethods,\n",data->ClassName); fprintf(fp," (char*)\"%s\",modulename,\n",data->ClassName); fprintf(fp," (char**)%sDoc,\n",data->ClassName); fprintf(fp," PyVTKClass_%sNew(modulename));\n}\n\n", data->SuperClasses[0]); } else if (!data->IsAbstract) { /* wrapping of 'special' non-vtkObject classes */ fprintf(fp,"PyObject *PyVTKObject_%sNew(PyObject *, PyObject *args)\n{\n",data->ClassName); fprintf(fp," if (!(PyArg_ParseTuple(args, (char*)\"\")))\n {\n"); fprintf(fp," return NULL;\n }\n\n"); fprintf(fp," %s *obj = new %s;\n",data->ClassName,data->ClassName); fprintf(fp," return PyVTKSpecialObject_New(obj, Py%sMethods, (char*)\"%s\",(char**)%sDoc);\n",data->ClassName,data->ClassName,data->ClassName); fprintf(fp,"}\n\n"); fprintf(fp,"static PyMethodDef Py%sNewMethod = \\\n",data->ClassName); fprintf(fp,"{ (char*)\"%s\", (PyCFunction)PyVTKObject_%sNew, 1,\n", data->ClassName,data->ClassName); fprintf(fp," (char*)%sDoc[0] };\n\n",data->ClassName); fprintf(fp,"PyObject *PyVTKClass_%sNew(char *)\n{\n",data->ClassName); fprintf(fp," return PyCFunction_New(&Py%sNewMethod,Py_None);\n}\n\n", data->ClassName); } else { /* un-wrappable classes */ fprintf(fp,"PyObject *PyVTKClass_%sNew(char *)\n{\n",data->ClassName); fprintf(fp," return NULL;\n}\n\n"); } }