~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/python/api2_2x/gen_utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* 
 
2
 * $Id: gen_utils.c,v 1.29 2005/05/22 17:40:00 stiv Exp $
2
3
 *
3
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4
5
 *
17
18
 *
18
19
 * You should have received a copy of the GNU General Public License
19
20
 * along with this program; if not, write to the Free Software Foundation,
20
 
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
21
 * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
21
22
 *
22
23
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23
24
 * All rights reserved.
24
25
 *
25
26
 * This is a new part of Blender.
26
27
 *
27
 
 * Contributor(s): Michel Selten, Willian P. Germano
 
28
 * Contributor(s): Michel Selten, Willian P. Germano, Alex Mole, Ken Hughes
28
29
 *
29
30
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
30
31
*/
31
32
 
 
33
#include <DNA_text_types.h>
 
34
#include <MEM_guardedalloc.h>
 
35
#include <BLI_blenlib.h>
 
36
#include <BIF_space.h>
 
37
 
32
38
#include "gen_utils.h"
33
39
#include "constant.h"
34
40
 
35
41
/*****************************************************************************/
36
 
/* Description: This function clamps an int to the given interval            */
37
 
/*              [min, max].                                                  */
 
42
/* Description: This function clamps an int to the given interval         */
 
43
/*                                                      [min, max].        */
38
44
/*****************************************************************************/
39
 
int EXPP_ClampInt (int value, int min, int max)
 
45
int EXPP_ClampInt( int value, int min, int max )
40
46
{
41
 
        if (value < min) return min;
42
 
        else if (value > max) return max;
 
47
        if( value < min )
 
48
                return min;
 
49
        else if( value > max )
 
50
                return max;
43
51
        return value;
44
52
}
45
53
 
46
54
/*****************************************************************************/
47
 
/* Description: This function clamps a float to the given interval           */
48
 
/*              [min, max].                                                  */
 
55
/* Description: This function clamps a float to the given interval       */
 
56
/*                                                      [min, max].      */
49
57
/*****************************************************************************/
50
 
float EXPP_ClampFloat (float value, float min, float max)
 
58
float EXPP_ClampFloat( float value, float min, float max )
51
59
{
52
 
        if (value < min) return min;
53
 
        else if (value > max) return max;
 
60
        if( value < min )
 
61
                return min;
 
62
        else if( value > max )
 
63
                return max;
54
64
        return value;
55
65
}
56
66
 
57
67
/*****************************************************************************/
58
68
/* Description: This function returns true if both given strings are equal,  */
59
 
/*              otherwise it returns false.                                  */
 
69
/*              otherwise it returns false.                             */
60
70
/*****************************************************************************/
61
 
int StringEqual (const char * string1, const char * string2)
 
71
int StringEqual( const char *string1, const char *string2 )
62
72
{
63
 
        return (strcmp(string1, string2)==0);
 
73
        return ( strcmp( string1, string2 ) == 0 );
64
74
}
65
75
 
66
76
/*****************************************************************************/
67
 
/* Description: This function returns the name of the given ID struct        */
68
 
/*              without the Object type identifying characters prepended.    */
 
77
/* Description: This function returns the name of the given ID struct    */
 
78
/*               without the Object type identifying characters prepended.   */
69
79
/*****************************************************************************/
70
 
char * GetIdName (ID *id)
 
80
char *GetIdName( ID * id )
71
81
{
72
 
        return ((id->name)+2);
 
82
        return ( ( id->name ) + 2 );
73
83
}
74
84
 
75
85
/*****************************************************************************/
76
86
/* Description: This function returns the ID of the object with given name   */
77
 
/*              from a given list.                                           */
 
87
/*              from a given list.                                          */
78
88
/*****************************************************************************/
79
 
ID *GetIdFromList(ListBase *list, char *name)
 
89
ID *GetIdFromList( ListBase * list, char *name )
80
90
{
81
91
        ID *id = list->first;
82
92
 
83
 
        while (id) {
84
 
                if(strcmp(name, id->name+2) == 0) break;
85
 
                        id= id->next;
 
93
        while( id ) {
 
94
                if( strcmp( name, id->name + 2 ) == 0 )
 
95
                        break;
 
96
                id = id->next;
86
97
        }
87
98
 
88
99
        return id;
90
101
 
91
102
/*****************************************************************************/
92
103
/* Description: These functions set an internal string with the given type   */
93
 
/*              and error_msg arguments.                                     */
 
104
/*                and error_msg arguments.                                   */
94
105
/*****************************************************************************/
95
 
PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg)
96
 
{
97
 
        PyErr_SetString (type, error_msg);
98
 
        return (NULL);
99
 
}
100
106
 
101
 
PyObject *EXPP_ReturnPyObjError (PyObject * type, char * error_msg)
102
 
{ /* same as above, just to change its name smoothly */
103
 
        PyErr_SetString (type, error_msg);
 
107
PyObject *EXPP_ReturnPyObjError( PyObject * type, char *error_msg )
 
108
{                               /* same as above, just to change its name smoothly */
 
109
        PyErr_SetString( type, error_msg );
104
110
        return NULL;
105
111
}
106
112
 
107
 
int EXPP_ReturnIntError (PyObject *type, char *error_msg)
 
113
int EXPP_ReturnIntError( PyObject * type, char *error_msg )
108
114
{
109
 
        PyErr_SetString (type, error_msg);
 
115
        PyErr_SetString( type, error_msg );
110
116
        return -1;
111
117
}
112
118
 
113
119
/*****************************************************************************/
114
 
/* Description: This function increments the reference count of the given    */
115
 
/*              Python object (usually Py_None) and returns it.              */
116
 
/*****************************************************************************/
117
 
PyObject * PythonIncRef (PyObject *object)
118
 
{
119
 
        Py_INCREF (object);
120
 
        return (object);
121
 
}
122
 
 
123
 
PyObject *EXPP_incr_ret (PyObject *object)
124
 
{
125
 
        Py_INCREF (object);
126
 
        return (object);
127
 
}
128
 
/*****************************************************************************/
129
 
/* Description: This function maps the event identifier to a string.         */
130
 
/*****************************************************************************/
131
 
char * event_to_name(short event)
132
 
{
133
 
        switch (event)
134
 
        {
135
 
                case SCRIPT_FRAMECHANGED:
136
 
                        return "FrameChanged";
137
 
                case SCRIPT_ONLOAD:
138
 
                        return "OnLoad";
139
 
                case SCRIPT_REDRAW:
140
 
                        return "Redraw";
141
 
                default:
142
 
                        return "Unknown";
 
120
/* Description: This function increments the reference count of the given   */
 
121
/*                       Python object (usually Py_None) and returns it.    */
 
122
/*****************************************************************************/
 
123
 
 
124
PyObject *EXPP_incr_ret( PyObject * object )
 
125
{
 
126
        Py_INCREF( object );
 
127
        return ( object );
 
128
}
 
129
 
 
130
/* return Py_False - to avoid warnings, we use the fact that
 
131
 * 0 == False in Python: */
 
132
PyObject *EXPP_incr_ret_False()
 
133
{
 
134
        return Py_BuildValue("i", 0);
 
135
}
 
136
 
 
137
/* return Py_True - to avoid warnings, we use the fact that
 
138
 * 1 == True in Python: */
 
139
PyObject *EXPP_incr_ret_True()
 
140
{
 
141
        return Py_BuildValue("i", 1);
 
142
}
 
143
 
 
144
/*****************************************************************************/
 
145
/* Description: This function maps the event identifier to a string.      */
 
146
/*****************************************************************************/
 
147
char *event_to_name( short event )
 
148
{
 
149
        switch ( event ) {
 
150
        case SCRIPT_FRAMECHANGED:
 
151
                return "FrameChanged";
 
152
        case SCRIPT_ONLOAD:
 
153
                return "OnLoad";
 
154
        case SCRIPT_ONSAVE:
 
155
                return "OnSave";
 
156
        case SCRIPT_REDRAW:
 
157
                return "Redraw";
 
158
        case SCRIPT_RENDER:
 
159
                return "Render";
 
160
        case SCRIPT_POSTRENDER:
 
161
                return "PostRender";
 
162
        default:
 
163
                return "Unknown";
143
164
        }
144
 
}       
 
165
}
145
166
 
146
167
/*****************************************************************************/
147
 
/* Description: Checks whether all objects in a PySequence are of a same     */
148
 
/*              given type.  Returns 0 if not, 1 on success.                 */
 
168
/* Description: Checks whether all objects in a PySequence are of a same  */
 
169
/*              given type.  Returns 0 if not, 1 on success.             */
149
170
/*****************************************************************************/
150
 
int EXPP_check_sequence_consistency(PyObject *seq, PyTypeObject *against)
 
171
int EXPP_check_sequence_consistency( PyObject * seq, PyTypeObject * against )
151
172
{
152
173
        PyObject *ob;
153
 
        int len = PySequence_Length(seq);
154
 
        int i;
 
174
        int len = PySequence_Length( seq );
 
175
        int i, result = 1;
155
176
 
156
 
        for (i = 0; i < len; i++) {
157
 
                ob = PySequence_GetItem(seq, i);
158
 
                if (ob->ob_type != against) {
159
 
                        Py_DECREF(ob);
 
177
        for( i = 0; i < len; i++ ) {
 
178
                ob = PySequence_GetItem( seq, i );
 
179
                if( ob == Py_None )
 
180
                        result = 2;
 
181
                else if( ob->ob_type != against ) {
 
182
                        Py_DECREF( ob );
160
183
                        return 0;
161
184
                }
162
 
                Py_DECREF(ob);
 
185
                Py_DECREF( ob );
163
186
        }
164
 
        return 1;
 
187
        return result;          /* 1 if all of 'against' type, 2 if there are (also) Nones */
165
188
}
166
189
 
167
 
PyObject *EXPP_tuple_repr(PyObject *self, int size)
 
190
PyObject *EXPP_tuple_repr( PyObject * self, int size )
168
191
{
169
192
        PyObject *repr, *item;
170
193
        int i;
172
195
/*@     note: a value must be built because the list is decrefed!
173
196
 * otherwise we have nirvana pointers inside python.. */
174
197
 
175
 
        repr = PyString_FromString("");
176
 
        if (!repr) return 0;
177
 
 
178
 
        item = PySequence_GetItem(self, 0); 
179
 
        PyString_ConcatAndDel(&repr, PyObject_Repr(item));
180
 
        Py_DECREF(item);
181
 
 
182
 
        for (i = 1; i < size; i++) {
183
 
                item = PySequence_GetItem(self, i);
184
 
                PyString_ConcatAndDel(&repr, PyObject_Repr(item));
185
 
                Py_DECREF(item);
 
198
        repr = PyString_FromString( "" );
 
199
        if( !repr )
 
200
                return 0;
 
201
 
 
202
        item = PySequence_GetItem( self, 0 );
 
203
        PyString_ConcatAndDel( &repr, PyObject_Repr( item ) );
 
204
        Py_DECREF( item );
 
205
 
 
206
        for( i = 1; i < size; i++ ) {
 
207
                item = PySequence_GetItem( self, i );
 
208
                PyString_ConcatAndDel( &repr, PyObject_Repr( item ) );
 
209
                Py_DECREF( item );
186
210
        }
187
211
 
188
212
        return repr;
190
214
 
191
215
/****************************************************************************/
192
216
/* Description: searches through a map for a pair with a given name. If the */
193
 
/*              pair is present, its ival is stored in *ival and nonzero is */
194
 
/*              returned. If the pair is absent, zero is returned.          */
 
217
/*               pair is present, its ival is stored in *ival and nonzero is */
 
218
/*               returned. If the pair is absent, zero is returned.     */
195
219
/****************************************************************************/
196
 
int EXPP_map_getIntVal (const EXPP_map_pair *map, const char *sval, int *ival)
197
 
{
198
 
    while (map->sval)
199
 
    {
200
 
        if (StringEqual(sval, map->sval))
201
 
        {
202
 
            *ival = map->ival;
203
 
            return 1;
204
 
        }
205
 
        ++map;
206
 
    }
207
 
    return 0;
 
220
int EXPP_map_getIntVal( const EXPP_map_pair * map, const char *sval,
 
221
                        int *ival )
 
222
{
 
223
        while( map->sval ) {
 
224
                if( StringEqual( sval, map->sval ) ) {
 
225
                        *ival = map->ival;
 
226
                        return 1;
 
227
                }
 
228
                ++map;
 
229
        }
 
230
        return 0;
 
231
}
 
232
 
 
233
/* same as above, but string case is ignored */
 
234
int EXPP_map_case_getIntVal( const EXPP_map_pair * map, const char *sval,
 
235
                             int *ival )
 
236
{
 
237
        while( map->sval ) {
 
238
                if( !BLI_strcasecmp( sval, map->sval ) ) {
 
239
                        *ival = map->ival;
 
240
                        return 1;
 
241
                }
 
242
                ++map;
 
243
        }
 
244
        return 0;
208
245
}
209
246
 
210
247
/****************************************************************************/
211
248
/* Description: searches through a map for a pair with a given name. If the */
212
 
/*              pair is present, its ival is stored in *ival and nonzero is */
213
 
/*              returned. If the pair is absent, zero is returned.          */
214
 
/* note: this function is identical to EXPP_map_getIntVal except that the   */
215
 
/*       output is stored in a short value.                                 */
 
249
/*               pair is present, its ival is stored in *ival and nonzero is */
 
250
/*              returned. If the pair is absent, zero is returned.           */
 
251
/* note: this function is identical to EXPP_map_getIntVal except that the  */
 
252
/*              output is stored in a short value.                         */
216
253
/****************************************************************************/
217
 
int EXPP_map_getShortVal (const EXPP_map_pair *map, 
218
 
                                        const char *sval, short *ival)
 
254
int EXPP_map_getShortVal( const EXPP_map_pair * map,
 
255
                          const char *sval, short *ival )
219
256
{
220
 
    while (map->sval)
221
 
    {
222
 
        if (StringEqual(sval, map->sval))
223
 
        {
224
 
            *ival = map->ival;
225
 
            return 1;
226
 
        }
227
 
        ++map;
228
 
    }
229
 
    return 0;
 
257
        while( map->sval ) {
 
258
                if( StringEqual( sval, map->sval ) ) {
 
259
                        *ival = map->ival;
 
260
                        return 1;
 
261
                }
 
262
                ++map;
 
263
        }
 
264
        return 0;
230
265
}
231
266
 
232
267
/****************************************************************************/
233
268
/* Description: searches through a map for a pair with a given ival. If the */
234
 
/*              pair is present, a pointer to its name is stored in *sval   */
235
 
/*              and nonzero is returned. If the pair is absent, zero is     */
236
 
/*              returned.                                                   */
 
269
/*              pair is present, a pointer to its name is stored in *sval */
 
270
/*              and nonzero is returned. If the pair is absent, zero is */
 
271
/*              returned.                                               */
237
272
/****************************************************************************/
238
 
int EXPP_map_getStrVal (const EXPP_map_pair *map, int ival, const char **sval)
239
 
{
240
 
  while (map->sval)
241
 
  {
242
 
    if (ival == map->ival)
243
 
    {
244
 
      *sval = map->sval;
245
 
      return 1;
246
 
    }
247
 
    ++map;
248
 
  }
249
 
  return 0;
 
273
int EXPP_map_getStrVal( const EXPP_map_pair * map, int ival,
 
274
                        const char **sval )
 
275
{
 
276
        while( map->sval ) {
 
277
                if( ival == map->ival ) {
 
278
                        *sval = map->sval;
 
279
                        return 1;
 
280
                }
 
281
                ++map;
 
282
        }
 
283
        return 0;
 
284
}
 
285
 
 
286
/* Redraw wrappers */
 
287
 
 
288
/* this queues redraws if we're not in background mode: */
 
289
void EXPP_allqueue(unsigned short event, short val)
 
290
{
 
291
        if (!G.background) allqueue(event, val);
 
292
}
 
293
 
 
294
/************************************************************************/
 
295
/* Scriptlink-related functions, used by scene, object, etc. bpyobjects */
 
296
/************************************************************************/
 
297
PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * args,
 
298
                               int is_scene )
 
299
{
 
300
        PyObject *list = NULL;
 
301
        char *eventname = NULL;
 
302
        int i, event = 0;
 
303
 
 
304
        /* actually !scriptlink shouldn't happen ... */
 
305
        if( !slink || !slink->totscript )
 
306
                return EXPP_incr_ret( Py_None );
 
307
 
 
308
        if( !PyArg_ParseTuple( args, "s", &eventname ) )
 
309
                return EXPP_ReturnPyObjError( PyExc_TypeError,
 
310
                                              "expected event name (string) as argument" );
 
311
 
 
312
        list = PyList_New( 0 );
 
313
        if( !list )
 
314
                return EXPP_ReturnPyObjError( PyExc_MemoryError,
 
315
                                              "couldn't create PyList!" );
 
316
 
 
317
        if( !strcmp( eventname, "FrameChanged" ) )
 
318
                event = SCRIPT_FRAMECHANGED;
 
319
        else if( !strcmp( eventname, "Redraw" ) )
 
320
                event = SCRIPT_REDRAW;
 
321
        else if( !strcmp( eventname, "Render" ) )
 
322
                event = SCRIPT_RENDER;
 
323
        else if( is_scene && !strcmp( eventname, "OnLoad" ) )
 
324
                event = SCRIPT_ONLOAD;
 
325
        else if( is_scene && !strcmp( eventname, "OnSave" ) )
 
326
                event = SCRIPT_ONSAVE;
 
327
        else
 
328
                return EXPP_ReturnPyObjError( PyExc_AttributeError,
 
329
                                              "invalid event name" );
 
330
 
 
331
        for( i = 0; i < slink->totscript; i++ ) {
 
332
                if( ( slink->flag[i] == event ) && slink->scripts[i] )
 
333
                        PyList_Append( list,
 
334
                                       PyString_FromString( slink->scripts[i]->
 
335
                                                            name + 2 ) );
 
336
        }
 
337
 
 
338
        return list;
 
339
}
 
340
 
 
341
PyObject *EXPP_clearScriptLinks( ScriptLink * slink, PyObject * args )
 
342
{
 
343
        int i, j, totLinks, deleted = 0;
 
344
        PyObject *seq = NULL;
 
345
        ID **stmp = NULL;
 
346
        short *ftmp = NULL;
 
347
 
 
348
        /* check for an optional list of strings */
 
349
        if( !PyArg_ParseTuple( args, "|O", &seq ) )
 
350
                return ( EXPP_ReturnPyObjError
 
351
                         ( PyExc_TypeError,
 
352
                           "expected no arguments or a list of strings" ) );
 
353
 
 
354
 
 
355
        /* if there was a parameter, handle it */
 
356
        if ( seq != NULL ) {
 
357
                /* check that parameter IS list of strings */
 
358
                if ( !PyList_Check ( seq ) )
 
359
                        return ( EXPP_ReturnPyObjError
 
360
                                 ( PyExc_TypeError,
 
361
                                   "expected a list of strings" ) );
 
362
 
 
363
                totLinks = PyList_Size ( seq );
 
364
                for ( i = 0 ; i < totLinks ; ++i ) {
 
365
                        if ( !PyString_Check ( PySequence_GetItem( seq, i ) ) )
 
366
                                return ( EXPP_ReturnPyObjError
 
367
                                         ( PyExc_TypeError,
 
368
                                           "expected list to contain strings" ) );
 
369
                }
 
370
 
 
371
                /*
 
372
                  parameters OK: now look for each script, and delete
 
373
                  its link as we find it (this handles multiple links)
 
374
                */
 
375
                for ( i = 0 ; i < totLinks ; ++i )
 
376
                {
 
377
                        char *str;
 
378
                        str = PyString_AsString ( PySequence_GetItem( seq, i ) );
 
379
                        for ( j = 0 ; j < slink->totscript ; ++j ) {
 
380
                                if ( slink->scripts[j] && !strcmp ( slink->scripts[j]->name+2, str ) ) {
 
381
                                        slink->scripts[j] = NULL;
 
382
                                        ++deleted; 
 
383
                                }
 
384
                        }
 
385
                }
 
386
        }
 
387
        /* if no parameter, then delete all scripts */
 
388
        else {
 
389
                deleted = slink->totscript;
 
390
        }
 
391
 
 
392
        /*
 
393
           if not all scripts deleted, create new lists and copy remaining
 
394
           links to them
 
395
        */
 
396
 
 
397
        if ( slink->totscript > deleted ) {
 
398
                slink->totscript -= deleted;
 
399
 
 
400
                stmp = slink->scripts;
 
401
                slink->scripts =
 
402
                        MEM_mallocN( sizeof( ID * ) * ( slink->totscript ),
 
403
                                     "bpySlinkL" );
 
404
 
 
405
                ftmp = slink->flag;
 
406
                slink->flag =
 
407
                        MEM_mallocN( sizeof( short * ) * ( slink->totscript ),
 
408
                                     "bpySlinkF" );
 
409
 
 
410
                for ( i = 0, j = 0 ; i < slink->totscript ; ++j ) {
 
411
                        if ( stmp[j] != NULL ) {
 
412
                                memcpy( slink->scripts+i, stmp+j, sizeof( ID * ) );
 
413
                                memcpy( slink->flag+i, ftmp+j, sizeof( short ) );
 
414
                                ++i;
 
415
                        }
 
416
                }
 
417
                MEM_freeN( stmp );
 
418
                MEM_freeN( ftmp );
 
419
 
 
420
                /*EXPP_allqueue (REDRAWBUTSSCRIPT, 0 );*/
 
421
                slink->actscript = 1;
 
422
        } else {
 
423
 
 
424
        /* all scripts deleted, so delete entire list and free memory */
 
425
 
 
426
                if( slink->scripts )
 
427
                        MEM_freeN( slink->scripts );
 
428
                if( slink->flag )
 
429
                        MEM_freeN( slink->flag );
 
430
 
 
431
                slink->scripts = NULL;
 
432
                slink->flag = NULL;
 
433
                slink->totscript = slink->actscript = 0;
 
434
        }
 
435
 
 
436
        return EXPP_incr_ret( Py_None );
 
437
}
 
438
 
 
439
 
 
440
PyObject *EXPP_addScriptLink(ScriptLink *slink, PyObject *args, int is_scene)
 
441
{
 
442
        int event = 0, found_txt = 0;
 
443
        void *stmp = NULL, *ftmp = NULL;
 
444
        Text *bltxt = G.main->text.first;
 
445
        char *textname = NULL;
 
446
        char *eventname = NULL;
 
447
 
 
448
        /* !scriptlink shouldn't happen ... */
 
449
        if( !slink ) {
 
450
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 
451
                        "internal error: no scriptlink!" );
 
452
        }
 
453
 
 
454
        if( !PyArg_ParseTuple( args, "ss", &textname, &eventname ) )
 
455
                return EXPP_ReturnPyObjError( PyExc_TypeError,
 
456
            "expected two strings as arguments" );
 
457
 
 
458
        while( bltxt ) {
 
459
                if( !strcmp( bltxt->id.name + 2, textname ) ) {
 
460
                        found_txt = 1;
 
461
                        break;
 
462
                }
 
463
                bltxt = bltxt->id.next;
 
464
        }
 
465
 
 
466
        if( !found_txt )
 
467
                return EXPP_ReturnPyObjError( PyExc_AttributeError,
 
468
            "no such Blender Text" );
 
469
 
 
470
        if( !strcmp( eventname, "FrameChanged" ) )
 
471
                event = SCRIPT_FRAMECHANGED;
 
472
        else if( !strcmp( eventname, "Redraw" ) )
 
473
                event = SCRIPT_REDRAW;
 
474
        else if( !strcmp( eventname, "Render" ) )
 
475
                event = SCRIPT_RENDER;
 
476
        else if( is_scene && !strcmp( eventname, "OnLoad" ) )
 
477
                event = SCRIPT_ONLOAD;
 
478
        else if( is_scene && !strcmp( eventname, "OnSave" ) )
 
479
                event = SCRIPT_ONSAVE;
 
480
        else
 
481
                return EXPP_ReturnPyObjError( PyExc_AttributeError,
 
482
                        "invalid event name" );
 
483
 
 
484
        stmp = slink->scripts;
 
485
        slink->scripts =
 
486
                MEM_mallocN( sizeof( ID * ) * ( slink->totscript + 1 ),
 
487
                             "bpySlinkL" );
 
488
 
 
489
        ftmp = slink->flag;
 
490
        slink->flag =
 
491
                MEM_mallocN( sizeof( short * ) * ( slink->totscript + 1 ),
 
492
                             "bpySlinkF" );
 
493
 
 
494
        if( slink->totscript ) {
 
495
                memcpy( slink->scripts, stmp,
 
496
                        sizeof( ID * ) * ( slink->totscript ) );
 
497
                MEM_freeN( stmp );
 
498
 
 
499
                memcpy( slink->flag, ftmp,
 
500
                        sizeof( short ) * ( slink->totscript ) );
 
501
                MEM_freeN( ftmp );
 
502
        }
 
503
 
 
504
        slink->scripts[slink->totscript] = ( ID * ) bltxt;
 
505
        slink->flag[slink->totscript] = event;
 
506
 
 
507
        slink->totscript++;
 
508
 
 
509
        if( slink->actscript < 1 )
 
510
                slink->actscript = 1;
 
511
 
 
512
        return EXPP_incr_ret (Py_None);         /* normal exit */
250
513
}