diff options
Diffstat (limited to 'source/blender/python/BPY_interface.c')
-rw-r--r-- | source/blender/python/BPY_interface.c | 138 |
1 files changed, 66 insertions, 72 deletions
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 69bff059356..041ba069928 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 = Py_BuildValue( "s", dirname ); + dir = PyString_FromString( dirname ); mod_sys = PyImport_ImportModule( "sys" ); /* new ref */ @@ -308,32 +308,29 @@ void syspath_append( char *dirname ) } if (PySequence_Contains(path, dir)==0) { /* Only add if we need to */ - if (ok && PyList_Append( path, dir ) != 0) + if (ok && PyList_Append( path, dir ) != 0) /* decref below */ 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", path ); + EXPP_dict_set_item_str( d, "progname", PyString_FromString( bprogname ) ); Py_DECREF( mod ); } else printf( "Warning: could not set Blender.sys.progname\n" ); @@ -556,6 +553,7 @@ 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" ); @@ -722,13 +720,23 @@ 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( char *fn ) +void BPY_run_python_script( const char *fn ) { + char filename[FILE_MAXDIR + FILE_MAXFILE]; Text *text = NULL; int is_blender_text = 0; - - if (!BLI_exists(fn)) { /* if there's no such filename ... */ - text = G.main->text.first; /* try an already existing Blender Text */ + + 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; while (text) { if (!strcmp(fn, text->id.name + 2)) break; @@ -743,11 +751,14 @@ void BPY_run_python_script( char *fn ) } else { - text = add_text(fn); + /* use filename here since we know it exists, + * 'fn' may have been a relative path + */ + text = add_text(filename); if (text == NULL) { printf("\nError in BPY_run_python_script:\n" - "couldn't create Blender text from %s\n", fn); + "couldn't create Blender text from \"%s\"\n", filename); /* Chris: On Windows if I continue I just get a segmentation * violation. To get a baseline file I exit here. */ exit(2); @@ -764,13 +775,8 @@ void BPY_run_python_script( 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. */ - Text *txtptr = G.main->text.first; - while (txtptr) { - if (txtptr == text) { - free_libblock(&G.main->text, text); - break; - } - txtptr = txtptr->id.next; + if (BLI_findindex(&G.main->text, text) != -1) { + free_libblock(&G.main->text, text); } } } @@ -780,9 +786,6 @@ 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(); @@ -827,12 +830,8 @@ int BPY_run_script(Script *script) Py_INCREF( Py_None ); pyarg = Py_None; } else { - if (BLI_exists(script->scriptname)) { - fp = fopen( script->scriptname, "rb" ); - } - - if( !fp ) { - printf( "Error loading script: couldn't open file %s\n", script->scriptname ); + if (!BLI_exists(script->scriptname)) { + printf( "Script does not exit %s\n", script->scriptname ); free_libblock( &G.main->script, script ); PyGILState_Release(gilstate); return 0; @@ -877,51 +876,17 @@ 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; @@ -965,8 +930,38 @@ int BPY_run_script(Script *script) *****************************************************************************/ int BPY_menu_do_python( short menutype, int event ) { - char *argstr = NULL; 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; BPySubMenu *pysm; char scriptname[21]; Script *script = NULL; @@ -974,8 +969,6 @@ int BPY_menu_do_python( short menutype, int event ) PyGILState_STATE gilstate; char filestr[FILE_MAX]; - pym = BPyMenu_GetEntry( menutype, ( short ) event ); - if( !pym ) return 0; @@ -1059,6 +1052,7 @@ int BPY_menu_do_python( short menutype, int event ) case PYMENU_RENDER: case PYMENU_WIZARDS: case PYMENU_SCRIPTTEMPLATE: + case PYMENU_TEXTPLUGIN: case PYMENU_MESHFACEKEY: break; |