diff options
Diffstat (limited to 'source/blender/python/BPY_interface.c')
-rw-r--r-- | source/blender/python/BPY_interface.c | 138 |
1 files changed, 72 insertions, 66 deletions
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 041ba069928..69bff059356 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -292,7 +292,7 @@ void syspath_append( char *dirname ) short ok=1; PyErr_Clear( ); - dir = PyString_FromString( dirname ); + dir = Py_BuildValue( "s", dirname ); mod_sys = PyImport_ImportModule( "sys" ); /* new ref */ @@ -308,29 +308,32 @@ void syspath_append( char *dirname ) } if (PySequence_Contains(path, dir)==0) { /* Only add if we need to */ - if (ok && PyList_Append( path, dir ) != 0) /* decref below */ + if (ok && PyList_Append( path, dir ) != 0) ok = 0; /* append failed */ if( (ok==0) || PyErr_Occurred( ) ) Py_FatalError( "could import or build sys.path, can't continue" ); } - Py_DECREF( dir ); Py_XDECREF( mod_sys ); } void init_syspath( int first_time ) { + PyObject *path; PyObject *mod, *d; char *progname; char execdir[FILE_MAXDIR]; /*defines from DNA_space_types.h */ int n; + + + path = Py_BuildValue( "s", bprogname ); mod = PyImport_ImportModule( "Blender.sys" ); if( mod ) { d = PyModule_GetDict( mod ); - EXPP_dict_set_item_str( d, "progname", PyString_FromString( bprogname ) ); + EXPP_dict_set_item_str( d, "progname", path ); Py_DECREF( mod ); } else printf( "Warning: could not set Blender.sys.progname\n" ); @@ -553,7 +556,6 @@ void BPY_Err_Handle( char *script_name ) if( exception && PyErr_GivenExceptionMatches( exception, PyExc_SyntaxError ) ) { /* no traceback available when SyntaxError */ - PyErr_NormalizeException( &exception, &err, &tb ); PyErr_Restore( exception, err, tb ); /* takes away reference! */ PyErr_Print( ); v = PyObject_GetAttrString( err, "lineno" ); @@ -720,23 +722,13 @@ int BPY_txt_do_python_Text( struct Text *text ) * automatically. The script can be a file or a Blender Text in the current * .blend. ****************************************************************************/ -void BPY_run_python_script( const char *fn ) +void BPY_run_python_script( char *fn ) { - char filename[FILE_MAXDIR + FILE_MAXFILE]; Text *text = NULL; int is_blender_text = 0; - - BLI_strncpy(filename, fn, FILE_MAXDIR + FILE_MAXFILE); - - if (!BLI_exists(filename)) - BLI_convertstringcwd(filename); - - if (!BLI_exists(filename)) { /* if there's no such filename ... */ - /* try an already existing Blender Text. - * use 'fn' rather then filename for this since were looking for - * internal text - */ - text = G.main->text.first; + + if (!BLI_exists(fn)) { /* if there's no such filename ... */ + text = G.main->text.first; /* try an already existing Blender Text */ while (text) { if (!strcmp(fn, text->id.name + 2)) break; @@ -751,14 +743,11 @@ void BPY_run_python_script( const char *fn ) } else { - /* use filename here since we know it exists, - * 'fn' may have been a relative path - */ - text = add_text(filename); + text = add_text(fn); if (text == NULL) { printf("\nError in BPY_run_python_script:\n" - "couldn't create Blender text from \"%s\"\n", filename); + "couldn't create Blender text from %s\n", fn); /* Chris: On Windows if I continue I just get a segmentation * violation. To get a baseline file I exit here. */ exit(2); @@ -775,8 +764,13 @@ void BPY_run_python_script( const char *fn ) /* We can't simply free the text, since the script might have called * Blender.Load() to load a new .blend, freeing previous data. * So we check if the pointer is still valid. */ - if (BLI_findindex(&G.main->text, text) != -1) { - free_libblock(&G.main->text, text); + Text *txtptr = G.main->text.first; + while (txtptr) { + if (txtptr == text) { + free_libblock(&G.main->text, text); + break; + } + txtptr = txtptr->id.next; } } } @@ -786,6 +780,9 @@ int BPY_run_script(Script *script) PyObject *py_dict, *py_res, *pyarg; Text *text = NULL; BPy_constant *info; + int len; + + FILE *fp = NULL; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -830,8 +827,12 @@ int BPY_run_script(Script *script) Py_INCREF( Py_None ); pyarg = Py_None; } else { - if (!BLI_exists(script->scriptname)) { - printf( "Script does not exit %s\n", script->scriptname ); + if (BLI_exists(script->scriptname)) { + fp = fopen( script->scriptname, "rb" ); + } + + if( !fp ) { + printf( "Error loading script: couldn't open file %s\n", script->scriptname ); free_libblock( &G.main->script, script ); PyGILState_Release(gilstate); return 0; @@ -876,17 +877,51 @@ int BPY_run_script(Script *script) if (text) { py_res = RunPython( text, py_dict ); } else { - char pystring[sizeof(script->scriptname) + 15]; - sprintf(pystring, "execfile(r'%s')", script->scriptname); - py_res = PyRun_String( pystring, Py_file_input, py_dict, py_dict ); - } - - if( !py_res ) { /* Failed execution of the script */ /* Previously we used PyRun_File to run directly the code on a FILE * object, but as written in the Python/C API Ref Manual, chapter 2, * 'FILE structs for different C libraries can be different and * incompatible'. * So now we load the script file data to a buffer */ + char *buffer=NULL, *buffer_ofs=NULL, *b_to, *b_from; + + fseek( fp, 0L, SEEK_END ); + len = ftell( fp ); + fseek( fp, 0L, SEEK_SET ); + + buffer = buffer_ofs = MEM_mallocN( len + 2, "pyfilebuf" ); /* len+2 to add '\n\0' */ + len = fread( buffer, 1, len, fp ); + + buffer[len] = '\n'; /* fix syntax error in files w/o eol */ + buffer[len + 1] = '\0'; + + + /* fast clean-up of dos cr/lf line endings, remove convert '\r\n's to '\n' */ + if (*buffer_ofs == '\r' && *(buffer_ofs+1) == '\n') { + buffer_ofs++; + } + b_from = b_to = buffer_ofs; + + while(*b_from != '\0') { + if (*b_from == '\r' && *( b_from+1 ) == '\n') { + b_from++; + } + if (b_from != b_to) { + *b_to = *b_from; + } + b_to++; + b_from++; + } + *b_to = '\0'; + /* done cleaning the string */ + + fclose( fp ); + + py_res = PyRun_String( buffer_ofs, Py_file_input, py_dict, py_dict ); + MEM_freeN( buffer ); + } + + if( !py_res ) { /* Failed execution of the script */ + BPY_Err_Handle( script->id.name + 2 ); ReleaseGlobalDictionary( py_dict ); script->py_globaldict = NULL; @@ -930,38 +965,8 @@ int BPY_run_script(Script *script) *****************************************************************************/ int BPY_menu_do_python( short menutype, int event ) { - BPyMenu *pym; - pym = BPyMenu_GetEntry( menutype, ( short ) event ); - return BPY_menu_invoke( pym, menutype ); -} - -/**************************************************************************** -* Description: This function executes the script by its shortcut. -* Notes: It is called by the ui code in src/???.c when a user presses an -* unassigned key combination. Scripts are searched in the BPyMenuTable, -* using the given menutype and event values to know which one to invoke. -*****************************************************************************/ -int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short qual ) -{ - BPyMenu *pym; - pym = BPyMenu_GetEntry( menutype, 0 ); - - while ( pym ) { - if ( pym->key && pym->key == key && pym->qual == qual ) { - return BPY_menu_invoke( pym, menutype ); - } - pym = pym->next; - } - - return 0; -} - -/**************************************************************************** -* Description: This function executes the script described by a menu item. -*****************************************************************************/ -int BPY_menu_invoke( BPyMenu *pym, short menutype ) -{ char *argstr = NULL; + BPyMenu *pym; BPySubMenu *pysm; char scriptname[21]; Script *script = NULL; @@ -969,6 +974,8 @@ int BPY_menu_invoke( BPyMenu *pym, short menutype ) PyGILState_STATE gilstate; char filestr[FILE_MAX]; + pym = BPyMenu_GetEntry( menutype, ( short ) event ); + if( !pym ) return 0; @@ -1052,7 +1059,6 @@ int BPY_menu_invoke( BPyMenu *pym, short menutype ) case PYMENU_RENDER: case PYMENU_WIZARDS: case PYMENU_SCRIPTTEMPLATE: - case PYMENU_TEXTPLUGIN: case PYMENU_MESHFACEKEY: break; |