Salome HOME
Merge branch 'V7_dev'
[modules/kernel.git] / src / DSC / DSC_Python / calcium.i
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 %define DOCSTRING
21 "CALCIUM python wrapping : Superv_Component class
22 "
23 %enddef
24
25 %module(docstring=DOCSTRING) calcium
26
27 %feature("autodoc", "1");
28
29 %include cstring.i
30
31 %{
32 //C++ Includes 
33 #include <SALOMEconfig.h>
34 #include <Calcium.hxx>
35 #include <calcium.h>
36 #include <Superv_Component_i.hxx>
37 #include <Salome_file_i.hxx>
38 #include <omniORB4/CORBA.h>
39
40 //--- from omniORBpy.h (not present on Debian Sarge packages)
41
42 struct omniORBpyAPI {
43
44   PyObject* (*cxxObjRefToPyObjRef)(const CORBA::Object_ptr cxx_obj,
45            CORBA::Boolean hold_lock);
46   // Convert a C++ object reference to a Python object reference.
47   // If <hold_lock> is true, caller holds the Python interpreter lock.
48
49   CORBA::Object_ptr (*pyObjRefToCxxObjRef)(PyObject* py_obj,
50              CORBA::Boolean hold_lock);
51   // Convert a Python object reference to a C++ object reference.
52   // Raises BAD_PARAM if the Python object is not an object reference.
53   // If <hold_lock> is true, caller holds the Python interpreter lock.
54
55   PyObject* (*handleCxxSystemException)(const CORBA::SystemException& ex);
56   // Sets the Python exception state to reflect the given C++ system
57   // exception. Always returns NULL. The caller must hold the Python
58   // interpreter lock.
59 };
60
61   omniORBpyAPI* api;
62   PyObject* dsc ;
63
64
65 %}
66
67 %init
68 %{
69   // init section
70
71 #ifdef WITH_NUMPY
72   import_array()
73 #endif
74
75   PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
76   if (!omnipy)
77   {
78     PyErr_SetString(PyExc_ImportError,
79         (char*)"Cannot import _omnipy");
80     return;
81   }
82   PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
83   api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
84   Py_DECREF(pyapi);
85
86   PyObject* engines = PyImport_ImportModule("Engines");
87   dsc = PyObject_GetAttrString(engines, "DSC");
88 %}
89
90 %include <exception.i>
91
92
93
94 /*
95  * Most of this code is borrowed from numpy distribution
96  * The following code originally appeared in enthought/kiva/agg/src/numeric.i,
97  * author unknown.  It was translated from C++ to C by John Hunter.  Bill
98  * Spotz has modified it slightly to fix some minor bugs, add some comments
99  * and some functionality.
100  */
101
102 %{
103
104 #ifdef WITH_NUMPY
105 /* With Numpy */
106 #ifdef HAVE_ISINF
107 #undef HAVE_ISINF
108 #endif
109 #include <numpy/arrayobject.h>
110
111 typedef PyArrayObject ArrayObject;
112
113 /* Macros to extract array attributes.
114  */
115 #define is_array(a)            ((a) && PyArray_Check((PyArrayObject *)a))
116 #define array_type(a)          (int)(PyArray_TYPE(a))
117 #define array_dimensions(a)    (((PyArrayObject *)a)->nd)
118 #define array_size(a,i)        (((PyArrayObject *)a)->dimensions[i])
119 #define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
120
121 const char* pytype_string(PyObject*);
122 const char* typecode_string(int);
123 int type_match(int, int);
124 int require_size(PyArrayObject*, int*, int);
125 int require_dimensions_n(PyArrayObject*, int*, int);
126 int require_dimensions(PyArrayObject*, int);
127 int require_contiguous(PyArrayObject*);
128 PyArrayObject* make_contiguous(PyArrayObject*, int*, int, int);
129 PyArrayObject* obj_to_array_no_conversion(PyObject*, int);
130 PyArrayObject* obj_to_array_allow_conversion(PyObject*, int, int*);
131 PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject*, int, int*);
132 PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject*, int, int*);
133
134 /* Given a PyObject, return a string describing its type.
135  */
136 const char* pytype_string(PyObject* py_obj) {
137   if (py_obj == NULL          ) return "C NULL value";
138   if (PyCallable_Check(py_obj)) return "callable"    ;
139   if (PyString_Check(  py_obj)) return "string"      ;
140   if (PyInt_Check(     py_obj)) return "int"         ;
141   if (PyFloat_Check(   py_obj)) return "float"       ;
142   if (PyDict_Check(    py_obj)) return "dict"        ;
143   if (PyList_Check(    py_obj)) return "list"        ;
144   if (PyTuple_Check(   py_obj)) return "tuple"       ;
145   if (PyFile_Check(    py_obj)) return "file"        ;
146   if (PyModule_Check(  py_obj)) return "module"      ;
147   if (PyInstance_Check(py_obj)) return "instance"    ;
148
149   return "unknown type";
150 }
151
152 /*
153 For documentation only : numpy typecodes
154
155 enum NPY_TYPECHAR { NPY_BOOLLTR = '?',
156                         NPY_BYTELTR = 'b',
157                         NPY_UBYTELTR = 'B',
158                         NPY_SHORTLTR = 'h',
159                         NPY_USHORTLTR = 'H',
160                         NPY_INTLTR = 'i',
161                         NPY_UINTLTR = 'I',
162                         NPY_LONGLTR = 'l',
163                         NPY_ULONGLTR = 'L',
164                         NPY_LONGLONGLTR = 'q',
165                         NPY_ULONGLONGLTR = 'Q',
166                         NPY_FLOATLTR = 'f',
167                         NPY_DOUBLELTR = 'd',
168                         NPY_LONGDOUBLELTR = 'g',
169                         NPY_CFLOATLTR = 'F',
170                         NPY_CDOUBLELTR = 'D',
171                         NPY_CLONGDOUBLELTR = 'G',
172                         NPY_OBJECTLTR = 'O',
173                         NPY_STRINGLTR = 'S',
174                         NPY_STRINGLTR2 = 'a',
175                         NPY_UNICODELTR = 'U',
176                         NPY_VOIDLTR = 'V',
177                         NPY_CHARLTR = 'c',
178
179                         NPY_INTPLTR = 'p',
180                         NPY_UINTPLTR = 'P',
181
182                         NPY_GENBOOLLTR ='b',
183                         NPY_SIGNEDLTR = 'i',
184                         NPY_UNSIGNEDLTR = 'u',
185                         NPY_FLOATINGLTR = 'f',
186                         NPY_COMPLEXLTR = 'c'
187 };
188 */
189
190 /* Given a Numeric typecode, return a string describing the type.
191  */
192 const char* typecode_string(int typecode) {
193   const char* type_names[] = {"bool","byte","unsigned byte","short",
194         "unsigned short","int","unsigned int","long","unsigned long",
195         "longlong","unsigned longlong",
196         "float","double","long double","complex float","complex double","complex long double",
197         "object","string","unicode","void","ntypes","notype","char","unkown"};
198   return type_names[typecode];
199 }
200
201 /* Make sure input has correct numeric type.  Allow character and byte
202  * to match.  Also allow int and long to match.
203  */
204 int type_match(int actual_type, int desired_type) {
205   return PyArray_EquivTypenums(actual_type, desired_type);
206 }
207
208 /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
209  * legal.  If not, set the python error string appropriately and
210  * return NULL./
211  */
212 PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) {
213   PyArrayObject* ary = NULL;
214   if (is_array(input) && (typecode == PyArray_NOTYPE ||
215         PyArray_EquivTypenums(array_type(input),
216             typecode))) {
217         ary = (PyArrayObject*) input;
218     }
219     else if is_array(input) {
220       const char* desired_type = typecode_string(typecode);
221       const char* actual_type = typecode_string(array_type(input));
222       PyErr_Format(PyExc_TypeError,
223        "Array of type '%s' required.  Array of type '%s' given",
224        desired_type, actual_type);
225       ary = NULL;
226     }
227     else {
228       const char * desired_type = typecode_string(typecode);
229       const char * actual_type = pytype_string(input);
230       PyErr_Format(PyExc_TypeError,
231        "Array of type '%s' required.  A %s was given",
232        desired_type, actual_type);
233       ary = NULL;
234     }
235   return ary;
236 }
237
238 /* Convert the given PyObject to a Numeric array with the given
239  * typecode.  On Success, return a valid PyArrayObject* with the
240  * correct type.  On failure, the python error string will be set and
241  * the routine returns NULL.
242  */
243 PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
244                                              int* is_new_object)
245 {
246   PyArrayObject* ary = NULL;
247   PyObject* py_obj;
248   if (is_array(input) && (typecode == PyArray_NOTYPE || type_match(array_type(input),typecode))) {
249     ary = (PyArrayObject*) input;
250     *is_new_object = 0;
251   }
252   else {
253     py_obj = PyArray_FromObject(input, typecode, 0, 0);
254     /* If NULL, PyArray_FromObject will have set python error value.*/
255     ary = (PyArrayObject*) py_obj;
256     *is_new_object = 1;
257   }
258   return ary;
259 }
260
261 /* Given a PyArrayObject, check to see if it is contiguous.  If so,
262  * return the input pointer and flag it as not a new object.  If it is
263  * not contiguous, create a new PyArrayObject using the original data,
264  * flag it as a new object and return the pointer.
265  */
266 PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
267                                int min_dims, int max_dims)
268 {
269   PyArrayObject* result;
270   if (array_is_contiguous(ary)) {
271     result = ary;
272     *is_new_object = 0;
273   }
274   else {
275     result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
276                  array_type(ary),
277                  min_dims,
278                  max_dims);
279     *is_new_object = 1;
280   }
281   return result;
282 }
283
284 /* Convert a given PyObject to a contiguous PyArrayObject of the
285  * specified type.  If the input object is not a contiguous
286  * PyArrayObject, a new one will be created and the new object flag
287  * will be set.
288  */
289 PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
290                                                         int typecode,
291                                                         int* is_new_object) {
292   int is_new1 = 0;
293   int is_new2 = 0;
294   PyArrayObject* ary2;
295   PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
296                   &is_new1);
297   if (ary1) {
298     ary2 = make_contiguous(ary1, &is_new2, 0, 0);
299     if ( is_new1 && is_new2) {
300       Py_DECREF(ary1);
301     }
302     ary1 = ary2;
303   }
304   *is_new_object = is_new1 || is_new2;
305   return ary1;
306 }
307
308 /* Test whether a python object is contiguous.  If array is
309  * contiguous, return 1.  Otherwise, set the python error string and
310  * return 0.
311  */
312 int require_contiguous(PyArrayObject* ary) {
313   int contiguous = 1;
314   if (!array_is_contiguous(ary)) {
315     PyErr_SetString(PyExc_TypeError, "Array must be contiguous.  A discontiguous array was given");
316     contiguous = 0;
317   }
318   return contiguous;
319 }
320
321 /* Require the given PyArrayObject to have a specified number of
322  * dimensions.  If the array has the specified number of dimensions,
323  * return 1.  Otherwise, set the python error string and return 0.
324  */
325 int require_dimensions(PyArrayObject* ary, int exact_dimensions) {
326   int success = 1;
327   if (array_dimensions(ary) != exact_dimensions) {
328     PyErr_Format(PyExc_TypeError,
329      "Array must have %d dimensions.  Given array has %d dimensions",
330      exact_dimensions, array_dimensions(ary));
331     success = 0;
332   }
333   return success;
334 }
335
336 /* Require the given PyArrayObject to have one of a list of specified
337  * number of dimensions.  If the array has one of the specified number
338  * of dimensions, return 1.  Otherwise, set the python error string
339  * and return 0.
340  */
341 int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n) {
342   int success = 0;
343   int i;
344   char dims_str[255] = "";
345   char s[255];
346   for (i = 0; i < n && !success; i++) {
347     if (array_dimensions(ary) == exact_dimensions[i]) {
348       success = 1;
349     }
350   }
351   if (!success) {
352     for (i = 0; i < n-1; i++) {
353       sprintf(s, "%d, ", exact_dimensions[i]);
354       strcat(dims_str,s);
355     }
356     sprintf(s, " or %d", exact_dimensions[n-1]);
357     strcat(dims_str,s);
358     PyErr_Format(PyExc_TypeError,
359      "Array must have %s dimensions.  Given array has %d dimensions",
360      dims_str, array_dimensions(ary));
361   }
362   return success;
363 }
364
365 /* Require the given PyArrayObject to have a specified shape.  If the
366  * array has the specified shape, return 1.  Otherwise, set the python
367  * error string and return 0.
368  */
369 int require_size(PyArrayObject* ary, int* size, int n) {
370   int i;
371   int success = 1;
372   int len;
373   char desired_dims[255] = "[";
374   char s[255];
375   char actual_dims[255] = "[";
376   for(i=0; i < n;i++) {
377     if (size[i] != -1 &&  size[i] != array_size(ary,i)) {
378       success = 0;
379     }
380   }
381   if (!success) {
382     for (i = 0; i < n; i++) {
383       if (size[i] == -1) {
384         sprintf(s, "*,");
385       }
386       else
387       {
388         sprintf(s, "%d,", size[i]);
389       }
390       strcat(desired_dims,s);
391     }
392     len = strlen(desired_dims);
393     desired_dims[len-1] = ']';
394     for (i = 0; i < n; i++) {
395       sprintf(s, "%d,", array_size(ary,i));
396       strcat(actual_dims,s);
397     }
398     len = strlen(actual_dims);
399     actual_dims[len-1] = ']';
400     PyErr_Format(PyExc_TypeError,
401      "Array must have shape of %s.  Given array has shape of %s",
402      desired_dims, actual_dims);
403   }
404   return success;
405 }
406
407 #else
408 /* Without Numpy */
409 typedef PyObject ArrayObject;
410
411 #endif
412 %}
413
414 %include "carrays.i" 
415
416 %array_class(int,    intArray);
417 %array_class(long,   longArray);
418 %array_class(float,  floatArray);
419 %array_class(double, doubleArray);
420
421 /* special struct to handle string arrays */
422 %inline %{
423 struct stringArray
424 {
425   stringArray(int nelements,int size=0) {
426     nelem=nelements;
427     size=size;
428     data= new char*[nelements];
429     for(int i=0;i<nelements;i++)
430     {
431       data[i]=(char *)malloc((size+1)*sizeof(char));
432       data[i][size+1]='\0';
433     }
434   }
435   ~stringArray() 
436   {
437     for(int i=0;i<nelem;i++)
438       free(data[i]);
439     delete [] data;
440   }
441   char* __getitem__(int index) {
442     return data[index];
443   }
444   void __setitem__(int index, char* value) {
445     free(data[index]);
446     data[index] = strdup(value);
447   }
448   char** data;
449   int nelem;
450   int size;
451 };
452 %}
453 /* End of special struct to handle string arrays */
454
455 /* input typemap 
456    This typemap can be used for input array objects only.
457    It accepts swig carray objects or numpy contiguous or non contiguous objects.
458    In case of non-contiguous numpy object, it is converted (new object) into a contiguous numpy object
459    This new object is deleted after the call.
460 */
461 %define TYPEMAP_IN3(type,typecode)
462 %typemap(in) type* IN_ARRAY3
463              (ArrayObject* array=NULL, int is_new_object) {
464   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
465   {
466 %#ifdef WITH_NUMPY
467     int size[1] = {-1};
468     array = obj_to_array_contiguous_allow_conversion($input, typecode, &is_new_object);
469     if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
470     $1 = (type*) array->data;
471 %#else
472     SWIG_exception(SWIG_TypeError, "type* expected");
473 %#endif
474   }
475 }
476 %typemap(freearg) type* IN_ARRAY3 {
477 %#ifdef WITH_NUMPY
478   if (is_new_object$argnum && array$argnum) 
479     {
480       Py_DECREF(array$argnum);
481     }
482 %#endif
483 }
484 %enddef
485
486 TYPEMAP_IN3(int,     PyArray_INT)
487 TYPEMAP_IN3(long,    PyArray_LONG)
488 TYPEMAP_IN3(float,   PyArray_FLOAT )
489 TYPEMAP_IN3(double,  PyArray_DOUBLE)
490
491 #undef TYPEMAP_IN3
492
493 %apply int*    IN_ARRAY3 {int    *eval};
494 %apply long*   IN_ARRAY3 {long   *eval};
495 %apply float*  IN_ARRAY3 {float  *eval};
496 %apply double* IN_ARRAY3 {double *eval};
497
498 /*  Specific typemap for complex */
499 %typemap(in) float*  ecpval
500              (ArrayObject* array=NULL, int is_new_object) {
501   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
502   {
503 %#ifdef WITH_NUMPY
504     int size[1] = {-1};
505     array = obj_to_array_contiguous_allow_conversion($input, PyArray_CFLOAT, &is_new_object);
506     if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
507     $1 = (float*) array->data;
508 %#else
509     SWIG_exception(SWIG_TypeError, "complex array expected");
510 %#endif
511   }
512 }
513 %typemap(freearg) float* ecpval {
514 %#ifdef WITH_NUMPY
515   if (is_new_object$argnum && array$argnum) 
516     {
517       Py_DECREF(array$argnum);
518     }
519 %#endif
520 }
521 /* End of  Specific typemap for complex */
522
523 /* array of strings on input */
524 %typemap(in) (char** eval,int strSize)
525          (ArrayObject* array=NULL, int is_new_object) {
526   stringArray* sarray;
527   if ((SWIG_ConvertPtr($input, (void **) &sarray, $descriptor(stringArray *),0)) == -1)
528   {
529 %#ifdef WITH_NUMPY
530     int size[1] = {-1};
531     array = obj_to_array_contiguous_allow_conversion($input, PyArray_STRING, &is_new_object);
532     if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
533     $1 = (char**) malloc(array_size(array,0)*sizeof(char*));
534     $2 = array->strides[0];
535     for(int i=0;i<array_size(array,0);i++)
536       {
537         $1[i]=(char*) malloc(sizeof(char)*(array->strides[0]+1));
538         strncpy($1[i],(char*) array->data + i* array->strides[0],array->strides[0]);
539         *($1[i]+array->strides[0])='\0';
540       }
541 %#else
542     SWIG_exception(SWIG_TypeError, "string array expected");
543 %#endif
544   }
545   else
546   {
547     $1=sarray->data;
548     $2=sarray->size;
549   }
550 }
551
552 %typemap(freearg) (char** eval,int strSize) {
553 %#ifdef WITH_NUMPY
554   if (array$argnum)
555     {
556       for(int i=0;i<array_size(array$argnum,0);i++)
557         free($1[i]);
558       free($1);
559     }
560   if (is_new_object$argnum && array$argnum) 
561     {
562       Py_DECREF(array$argnum);
563     }
564 %#endif
565 }
566 /* End of array of strings on input */
567
568 /* inplace typemaps 
569    This typemap can be used for input/output array objects.
570    It accepts swig carray objects or numpy contiguous objects.
571 */
572
573 %define TYPEMAP_INPLACE3(type,typecode)
574 %typemap(in) type* INPLACE_ARRAY3 (ArrayObject* temp=NULL) {
575   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
576   {
577 %#ifdef WITH_NUMPY
578     temp = obj_to_array_no_conversion($input,typecode);
579     if (!temp  || !require_contiguous(temp)) SWIG_fail;
580     $1 = (type*) temp->data;
581 %#else
582     temp = NULL;
583     SWIG_exception(SWIG_TypeError, "type* expected");
584 %#endif
585   }
586 }
587 %enddef
588
589 TYPEMAP_INPLACE3(int,     PyArray_INT)
590 TYPEMAP_INPLACE3(long,    PyArray_LONG)
591 TYPEMAP_INPLACE3(float,   PyArray_FLOAT )
592 TYPEMAP_INPLACE3(double,  PyArray_DOUBLE)
593
594 #undef TYPEMAP_INPLACE3
595
596 %apply int*    INPLACE_ARRAY3 {int    *lval};
597 %apply long*   INPLACE_ARRAY3 {long   *lval};
598 %apply float*  INPLACE_ARRAY3 {float  *lval};
599 %apply double* INPLACE_ARRAY3 {double *lval};
600
601 /*  typemap for complex inout */
602 %typemap(in) float* lcpval
603              (ArrayObject* temp=NULL) {
604   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
605   {
606 %#ifdef WITH_NUMPY
607     temp = obj_to_array_no_conversion($input,PyArray_CFLOAT);
608     if (!temp  || !require_contiguous(temp)) SWIG_fail;
609     $1 = (float*) temp->data;
610 %#else
611     temp = NULL;
612     SWIG_exception(SWIG_TypeError, "complex array expected");
613 %#endif
614   }
615 }
616 /*  End of typemap for complex inout */
617
618 /* typemap for array of strings on input/output */
619 %typemap(in) (char** lval,int strSize)
620             (ArrayObject* temp=NULL) {
621   stringArray* sarray;
622   if ((SWIG_ConvertPtr($input, (void **) &sarray, $descriptor(stringArray *) ,0)) == -1)
623   {
624 %#ifdef WITH_NUMPY
625     temp = obj_to_array_no_conversion($input,PyArray_STRING);
626     if (!temp  || !require_contiguous(temp)) SWIG_fail;
627     $1 = (char**) malloc(array_size(temp,0)*sizeof(char*));
628     $2 = temp->strides[0];
629     for(int i=0;i<array_size(temp,0);i++)
630       {
631         $1[i]=(char*) temp->data+i*temp->strides[0];
632         memset($1[i],0,temp->strides[0]); //numpy strings must be completed with 0 up to elsize
633       }
634 %#else
635     temp = NULL;
636     SWIG_exception(SWIG_TypeError, "string array expected");
637 %#endif
638   }
639   else
640   {
641     $1=sarray->data;
642     $2=sarray->size;
643   }
644 }
645 %typemap(freearg) (char** lval,int strSize) {
646 %#ifdef WITH_NUMPY
647   if (temp$argnum) free($1);
648 %#endif
649 }
650 /* End of typemap for array of strings on input/output */
651
652 %typemap(in) CORBA::Boolean
653 {
654   $1=(CORBA::Boolean)PyInt_AsLong($input);
655 }
656 %typemap(out) CORBA::Boolean
657 {
658   $result=PyInt_FromLong($1 ? 1 : 0);
659 }
660
661 %define CORBAPTR(type)
662 %typemap(in) type##_ptr
663 {
664   Py_BEGIN_ALLOW_THREADS
665   try
666   {
667      CORBA::Object_var obj = api->pyObjRefToCxxObjRef($input,0);
668      $1 = type##::_narrow(obj);
669   }
670   catch(...)
671   {
672      Py_BLOCK_THREADS
673      PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr");
674   }
675   Py_END_ALLOW_THREADS
676 }
677 %typemap(freearg) type##_ptr {
678   CORBA::release($1);
679 }
680 %enddef
681
682 CORBAPTR(CORBA::ORB)
683 CORBAPTR(Ports::PortProperties)
684 CORBAPTR(Ports::Port)
685 CORBAPTR(Engines::Container)
686 CORBAPTR(PortableServer::POA)
687
688 %typemap(out) Ports::Port_ptr 
689 {
690   $result = api->cxxObjRefToPyObjRef($1, 1);
691   //All output Ports::Port_ptr variables are duplicated by security. Need to release them for python.
692   CORBA::release($1);
693 }
694
695 %typemap(out) Ports::PortProperties_ptr, Engines::Salome_file_ptr
696 {
697   $result = api->cxxObjRefToPyObjRef($1, 1);
698   //the _ptr is duplicated by the routine called. 
699   //Need to release it for Python because the call to cxxObjRefToPyObjRef has created another ref with a count of 1
700   CORBA::release($1);
701 }
702
703 %typemap(out) Engines::DSC::uses_port *
704 {
705    $result = PyList_New($1->length());
706    for (CORBA::ULong i=0; i < $1->length() ; i++)
707      PyList_SetItem($result,i,api->cxxObjRefToPyObjRef((*$1)[i], 1));
708    //delete the copy (created by new) of uses port sequence
709    delete $1;
710 }
711
712 /*
713  * Exception section
714  */
715 // a general exception handler
716 %exception {
717    Py_BEGIN_ALLOW_THREADS
718    try {
719       $action
720    }
721    catch(Engines::DSC::PortNotDefined& _e) {
722       Py_BLOCK_THREADS
723       PyObject* excc = PyObject_GetAttrString(dsc, "PortNotDefined");
724       PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL);
725       PyErr_SetObject(excc, exci);
726       Py_XDECREF(excc);
727       Py_XDECREF(exci);
728       return NULL;
729    }
730    catch(Engines::DSC::PortNotConnected& _e) {
731       Py_BLOCK_THREADS
732       PyObject* excc = PyObject_GetAttrString(dsc, "PortNotConnected");
733       PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL);
734       PyErr_SetObject(excc, exci);
735       Py_XDECREF(excc);
736       Py_XDECREF(exci);
737       return NULL;
738    }
739    catch(Engines::DSC::BadPortType& _e) {
740       Py_BLOCK_THREADS
741       PyObject* excc = PyObject_GetAttrString(dsc, "BadPortType");
742       PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL);
743       PyErr_SetObject(excc, exci);
744       Py_XDECREF(excc);
745       Py_XDECREF(exci);
746       return NULL;
747    }
748    catch (SALOME_Exception &e) {
749       Py_BLOCK_THREADS
750       PyErr_SetString(PyExc_RuntimeError,e.what());
751       return NULL;
752    }
753    catch (SALOME::SALOME_Exception &e) {
754       Py_BLOCK_THREADS
755       //This one should be converted into a python corba exception
756       PyErr_SetString(PyExc_RuntimeError,e.details.text);
757       return NULL;
758    }
759    catch (const CORBA::SystemException& e) {
760       Py_BLOCK_THREADS 
761       return api->handleCxxSystemException(e);
762    }
763    catch(...) {
764       Py_BLOCK_THREADS
765       PyErr_SetString(PyExc_ValueError,"Unknown exception");
766       return NULL;
767    }
768    Py_END_ALLOW_THREADS
769 }
770
771 /*
772  * End of Exception section
773  */
774 namespace Engines
775 {
776 class DSC
777 {
778   public:
779     enum Message { AddingConnection, RemovingConnection, ApplicationError };
780 };
781 }
782
783 class PySupervCompo:public Superv_Component_i
784 {
785   public:
786
787     PySupervCompo(CORBA::ORB_ptr orb,
788          PortableServer::POA_ptr poa,
789          Engines::Container_ptr contai,
790          const char *instanceName,
791          const char *interfaceName);
792
793     virtual ~PySupervCompo();
794     CORBA::Boolean init_service(const char * service_name){return true;};
795     virtual provides_port * create_provides_data_port(const char* port_fab_type)
796         throw (BadFabType);
797     virtual uses_port * create_uses_data_port(const char* port_fab_type)
798         throw (BadFabType);
799     virtual void add_port(const char * port_fab_type,
800         const char * port_type,
801         const char * port_name)
802         throw (PortAlreadyDefined, BadFabType, BadType, BadProperty);
803     template < typename SpecificPortType >
804     SpecificPortType * add_port(const char * port_fab_type,
805             const char * port_type,
806             const char * port_name)
807           throw (PortAlreadyDefined, BadFabType, BadType, BadCast, BadProperty);
808     virtual void add_port(provides_port * port,
809           const char* provides_port_name)
810           throw (PortAlreadyDefined, NilPort, BadProperty);
811     virtual void add_port(uses_port * port,
812           const char* uses_port_name)
813           throw (PortAlreadyDefined, NilPort, BadProperty);
814     template <typename SpecificPortType >
815     SpecificPortType * get_port( const char * port_name)
816           throw (PortNotDefined, PortNotConnected, BadCast, UnexpectedState);
817     virtual Ports::Port_ptr get_provides_port(const char* provides_port_name,
818               const CORBA::Boolean connection_error)
819               throw (Engines::DSC::PortNotDefined,
820                      Engines::DSC::PortNotConnected,
821                      Engines::DSC::BadPortType);
822     virtual void connect_uses_port(const char* uses_port_name,
823                          Ports::Port_ptr provides_port_ref)
824               throw (Engines::DSC::PortNotDefined,
825                      Engines::DSC::BadPortType,
826                      Engines::DSC::NilPort);
827     virtual void connect_provides_port(const char* provides_port_name)
828               throw (Engines::DSC::PortNotDefined);
829     virtual void disconnect_provides_port(const char* provides_port_name,
830               const Engines::DSC::Message message)
831               throw (Engines::DSC::PortNotDefined,
832                      Engines::DSC::PortNotConnected);
833
834     virtual void disconnect_uses_port(const char* uses_port_name,
835                   Ports::Port_ptr provides_port_ref,
836                   const Engines::DSC::Message message)
837               throw (Engines::DSC::PortNotDefined,
838                      Engines::DSC::PortNotConnected,
839                      Engines::DSC::BadPortReference);
840
841     virtual Ports::PortProperties_ptr get_port_properties(const char* port_name);
842
843 // Interface for Salome_file
844     Engines::Salome_file_ptr getInputFileToService(const char* service_name, const char* Salome_file_name);
845     void checkInputFilesToService(const char* service_name);
846     Engines::Salome_file_ptr setInputFileToService(const char* service_name, const char* Salome_file_name);
847     Engines::Salome_file_ptr getOutputFileToService(const char* service_name, const char* Salome_file_name);
848     void checkOutputFilesToService(const char* service_name);
849     Engines::Salome_file_ptr setOutputFileToService(const char* service_name, const char* Salome_file_name);
850 // End of Interface for Salome_file
851
852 // DSC interface for python components
853   virtual void add_provides_port(Ports::Port_ptr ref, const char* provides_port_name, Ports::PortProperties_ptr port_prop);
854   virtual void add_uses_port(const char* repository_id, const char* uses_port_name, Ports::PortProperties_ptr port_prop);
855   virtual Engines::DSC::uses_port * get_uses_port(const char* uses_port_name);
856   CORBA::Boolean is_connected(const char* port_name) throw (Engines::DSC::PortNotDefined);
857 // End of DSC interface for python components
858
859    static void setTimeOut();
860
861
862     %extend
863       {
864        //To get the address of the component
865         long ptr()
866         {
867           return (long)self;
868         }
869       }
870 };
871
872 %apply int *OUTPUT { int *nval };
873 %apply float *INOUT { float  *ti };
874 %apply float *INPUT { float  *tf };
875 %apply int *INOUT { int  *niter };
876 %apply double *INOUT { double  *ti };
877 %apply double *INPUT { double  *tf };
878
879 extern "C" void create_calcium_port(Superv_Component_i* compo,char* name,char* type,char *mode,char* depend);
880
881 %ignore CPMESSAGE;
882 %include "calciumP.h"
883
884 %cstring_bounded_output(char *instanceName, 1024);
885
886 int  cp_cd(Superv_Component_i *component,char *instanceName);
887
888 int cp_een(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,int    *eval);
889 int cp_edb(Superv_Component_i *component,int dep,double t,int n,char *nom,int nval,double *eval);
890 int cp_ere(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *eval);
891 int cp_erd(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *eval);
892 int cp_ecp(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *ecpval);
893 int cp_elo(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,int    *eval);
894 int cp_ech(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,char** eval,int strSize);
895 int cp_elg(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,long   *eval);
896 int cp_eln(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,long   *eval);
897
898
899 int cp_len(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,int    *lval);
900 int cp_ldb(Superv_Component_i *component,int dep,double *ti,double *tf,int *niter,char *nom,int nmax,int *nval,double *lval);
901 int cp_lre(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lval);
902 int cp_lrd(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lval);
903 int cp_lcp(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lcpval);
904 int cp_llo(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,int    *lval);
905 int cp_lch(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,char** lval,int strSize);
906 int cp_llg(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,long   *lval);
907 int cp_lln(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,long   *lval);
908
909 int cp_fini(Superv_Component_i *component,char *nom, int n);
910 int cp_fint(Superv_Component_i *component,char *nom, float t);
911 int cp_effi(Superv_Component_i *component,char *nom, int n);
912 int cp_efft(Superv_Component_i *component,char *nom, float t);
913
914 int cp_fin(Superv_Component_i *component,int cp_end);
915