1 /**
2  * @file    local.i
3  * @brief   Ruby-specific SWIG directives for wrapping libSBML API
4  * @author  Alex Gutteridge
5  * @author  Ben Bornstein
6  * @author  Akiya Jouraku
7  *
8  * <!--------------------------------------------------------------------------
9  * This file is part of libSBML.  Please visit http://sbml.org for more
10  * information about SBML, and the latest version of libSBML.
11  *
12  * Copyright (C) 2020 jointly by the following organizations:
13  *     1. California Institute of Technology, Pasadena, CA, USA
14  *     2. University of Heidelberg, Heidelberg, Germany
15  *     3. University College London, London, UK
16  *
17  * Copyright (C) 2019 jointly by the following organizations:
18  *     1. California Institute of Technology, Pasadena, CA, USA
19  *     2. University of Heidelberg, Heidelberg, Germany
20  *
21  * Copyright (C) 2013-2018 jointly by the following organizations:
22  *     1. California Institute of Technology, Pasadena, CA, USA
23  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
24  *     3. University of Heidelberg, Heidelberg, Germany
25  *
26  * Copyright (C) 2009-2013 jointly by the following organizations:
27  *     1. California Institute of Technology, Pasadena, CA, USA
28  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
29  *
30  * Copyright (C) 2006-2008 by the California Institute of Technology,
31  *     Pasadena, CA, USA
32  *
33  * Copyright (C) 2002-2005 jointly by the following organizations:
34  *     1. California Institute of Technology, Pasadena, CA, USA
35  *     2. Japan Science and Technology Agency, Japan
36  *
37  * This library is free software; you can redistribute it and/or modify it
38  * under the terms of the GNU Lesser General Public License as published by
39  * the Free Software Foundation.  A copy of the license agreement is provided
40  * in the file named "LICENSE.txt" included with this software distribution
41  * and also available online as http://sbml.org/software/libsbml/license.html
42  * ---------------------------------------------------------------------- -->*/
43 
44 %trackobjects;
45 
46 #pragma SWIG nowarn=509
47 %warnfilter(365) operator+=;
48 %warnfilter(401) basic_ios<char>;
49 %warnfilter(801) basic_string<char>;
50 
51 /**
52  *  Wraps std::cout, std::cerr, std::clog, std::ostream, and std::ostringstream,
53  *
54  * (sample code) -----------------------------------------------------
55  *
56  * 1. wraps std::cout
57  *
58  *    xos = LibSBML::XMLOutputStream.new(LibSBML::cout)
59  *
60  * 2. wraps std::cerr
61  *
62  *    d = LibSBML::readSBML("foo.xml")
63  *    if ( d.getNumErrors > 0 )
64  *       d.printErrors(LibSBML::cerr)
65  *    end
66  *
67  * 3. wraps std::ostringstream
68  *
69  *    oss = LibSBML::Ostringstream.new()
70  *    xos = LibSBML::XMLOutputStream.new(oss)
71  *    ...
72  *    LibSBML::endl(oss)
73  *    s = oss.str();
74  *
75  */
76 
77 // ignores C++ specific methods in std::string.
78 %ignore std::basic_string<char>::begin;
79 %ignore std::basic_string<char>::end;
80 %ignore std::basic_string<char>::rbegin;
81 %ignore std::basic_string<char>::rend;
82 %ignore std::basic_string<char>::get_allocator;
83 %ignore std::basic_string<char>::capacity;
84 %ignore std::basic_string<char>::reserve;
85 
86 %include <std_alloc.i>
87 %include <std_basic_string.i>
88 %include <std_string.i>
89 
90 namespace std
91 {
92   // Template class basic ios
93   template<typename _CharT, typename _Traits = char_traits<_CharT> >
94   class basic_ios : public ios_base {};
95 
96   // Template class basic_ostream
97   template<typename _CharT, typename _Traits = char_traits<_CharT> >
98   class basic_ostream : virtual public basic_ios<_CharT, _Traits>
99   {
100     public:
101       explicit
102       basic_ostream(std::basic_streambuf<_CharT, _Traits>* __sb);
103       virtual
104       ~basic_ostream();
105   };
106 
107   // Template class basic_ostringstream
108   template<typename _CharT, typename _Traits = char_traits<_CharT>,
109            typename _Alloc = allocator<_CharT> >
110   class basic_ostringstream : public basic_ostream<_CharT, _Traits>
111   {
112     public:
113       explicit
114       basic_ostringstream(std::ios_base::openmode __mode = std::ios_base::out);
115       ~basic_ostringstream();
116 
117       basic_string<_CharT, _Traits, _Alloc>
118       str() const;
119 
120       void
121       str(const basic_string<_CharT, _Traits, _Alloc>& __s);
122   };
123 
124   template<typename _CharT, typename _Traits = char_traits<_CharT> >
125   basic_ostream<_CharT, _Traits>&
126   endl(basic_ostream<_CharT, _Traits>&);
127 
128   template<typename _CharT, typename _Traits = char_traits<_CharT> >
129   basic_ostream<_CharT, _Traits>&
130   flush(basic_ostream<_CharT, _Traits>&);
131 }
132 
133 namespace std
134 {
135   /**
136    *  std::ostream and std::ostringstream
137    *  (std::ios is not wrapped)
138    */
139   typedef basic_ios<char>           ios;
140   typedef basic_ostream<char>       ostream ;
141   typedef basic_ostringstream<char> ostringstream ;
142 
143   %template()              basic_ios<char>;
144   %template(Ostream)       basic_ostream<char>;
145   %template(Ostringstream) basic_ostringstream<char>;
146 
147   /**
148    *  output manipulators
149    */
150   %template(endl)  endl<char, char_traits<char> >;
151   %template(flush) flush<char, char_traits<char> >;
152 
153   /**
154    *  std::cout, std::cerr, and std::clog.
155    */
156   %immutable;
157   extern std::ostream cout;
158   extern std::ostream cerr;
159   extern std::ostream clog;
160   %mutable;
161 }
162 
163 
164 
165 /**
166  * Convert an SBase object to a string.
167  */
168 
169 %extend SBase
170 {
__str__(void)171    char* __str__(void){
172      return self->toSBML();
173    }
174 }
175 
176 /**
177  * Allows ListOf objects:
178  *
179  *   - To be indexed and sliced, e.g. lst[0].
180  */
181 
182 %mixin ListOf "Enumerable";
183 
184 %extend ListOf
185 {
__len__()186   int __len__()
187   {
188     return self->size();
189   }
190 
__getitem__(int i)191   SBase* __getitem__(int i)
192   {
193      return self->get(fixNegativeIndex(i,self));
194   }
195 
each(void)196   void each(void)
197   {
198      unsigned int i;
199      for(i=0;i<self->size();i++){
200        rb_yield(SWIG_NewPointerObj(self->get(i),
201        GetDowncastSwigType(self->get(i)), 0));
202      }
203   }
204 }
205 
206 /**
207  * Convert SBase, SimpleSpeciesReference, and Rule objects into the most specific type possible.
208  */
209 %typemap(out) SBase*, SimpleSpeciesReference*, Rule*, SBasePlugin*, SBMLExtension*, SBMLNamespaces*, SBMLConverter*, Reaction*
210 {
211   $result = SWIG_NewPointerObj(SWIG_as_voidptr($1), GetDowncastSwigType($1), $owner | %newpointer_flags);
212 }
213 
214 %typemap(out) ASTBasePlugin*
215 {
216   $result = SWIG_NewPointerObj(SWIG_as_voidptr($1), GetDowncastSwigType($1), $owner | %newpointer_flags);
217 }
218 
219 
220 
221 /*
222  * SWIG-generated wrapper code for Ruby binding wrongly invokes
223  * XMLOutputStream::writeAttribute(.., const unsigned int& value) instead of
224  * XMLOutputStream::writeAttribute(.., const bool& value) even if the writeAttribute
225  * function properly invoked with a bool value (true or false) in Ruby code.
226  * It seems that a bool value could be casted to unsigned int, int, or long value
227  * in SWIG-generated internal type check code when these types are overloaded in the
228  * wrapped function.
229  *
230  * To avoid this problem, XMLOutputStream::writeAttributeBool(.., const bool&)
231  * functions, which internally invoke XMLOutputStream::writeAttribute(.., const bool& value)
232  * functions properly, are additionally wrapped as aliases.
233  */
234 %extend XMLOutputStream
235 {
writeAttributeBool(const std::string & name,const bool & value)236   void writeAttributeBool(const std::string& name, const bool& value)
237   {
238     $self->writeAttribute(name, value);
239   }
240 
writeAttributeBool(const XMLTriple & name,const bool & value)241   void writeAttributeBool(const XMLTriple& name, const bool& value)
242   {
243     $self->writeAttribute(name, value);
244   }
245 }
246 
247 
248 /**
249  * Wraps the SBMLConstructorException
250  *
251  * The SBMLConstructorException (C++ class) is wrapped as the
252  * SBMLConsturctorException (Ruby class) which is derived from
253  * the built-in ArgumentError class (Ruby class).
254  *
255  * For example, the exception can be catched in Ruby code as follows:
256  *
257  * -------------------------------------------------
258  *  begin
259  *    s = LibSBML::Compartment.new(level,version)
260  *  rescue SBMLConstructorException
261  *    errmsg = $!
262  *  end
263  * -------------------------------------------------
264  */
265 
266 %exceptionclass SBMLConstructorException;
267 
268 %define SBMLCONSTRUCTOR_EXCEPTION(SBASE_CLASS_NAME)
269 %exception SBASE_CLASS_NAME{
270   try {
271     $action
272   }
catch(const SBMLConstructorException & e)273   catch (const SBMLConstructorException &e){
274     static VALUE cpperror = rb_define_class("SBMLConstructorException", rb_eArgError);
275     rb_raise(cpperror, "%s", e.what());
276   }
catch(const SBMLExtensionException & e)277   catch (const SBMLExtensionException &e){
278     static VALUE cpperror = rb_define_class("SBMLConstructorException", rb_eArgError);
279     rb_raise(cpperror, "%s", e.what());
280   }
281 }
282 %enddef
283 
284 SBMLCONSTRUCTOR_EXCEPTION(Compartment)
285 SBMLCONSTRUCTOR_EXCEPTION(CompartmentType)
286 SBMLCONSTRUCTOR_EXCEPTION(Constraint)
287 SBMLCONSTRUCTOR_EXCEPTION(Delay)
288 SBMLCONSTRUCTOR_EXCEPTION(Event)
289 SBMLCONSTRUCTOR_EXCEPTION(EventAssignment)
290 SBMLCONSTRUCTOR_EXCEPTION(FunctionDefinition)
291 SBMLCONSTRUCTOR_EXCEPTION(InitialAssignment)
292 SBMLCONSTRUCTOR_EXCEPTION(KineticLaw)
293 SBMLCONSTRUCTOR_EXCEPTION(Model)
294 SBMLCONSTRUCTOR_EXCEPTION(Parameter)
295 SBMLCONSTRUCTOR_EXCEPTION(Priority)
296 SBMLCONSTRUCTOR_EXCEPTION(LocalParameter)
297 SBMLCONSTRUCTOR_EXCEPTION(Reaction)
298 SBMLCONSTRUCTOR_EXCEPTION(AssignmentRule)
299 SBMLCONSTRUCTOR_EXCEPTION(AlgebraicRule)
300 SBMLCONSTRUCTOR_EXCEPTION(RateRule)
301 SBMLCONSTRUCTOR_EXCEPTION(Species)
302 SBMLCONSTRUCTOR_EXCEPTION(SpeciesReference)
303 SBMLCONSTRUCTOR_EXCEPTION(ModifierSpeciesReference)
304 SBMLCONSTRUCTOR_EXCEPTION(SpeciesType)
305 SBMLCONSTRUCTOR_EXCEPTION(StoichiometryMath)
306 SBMLCONSTRUCTOR_EXCEPTION(Trigger)
307 SBMLCONSTRUCTOR_EXCEPTION(Unit)
308 SBMLCONSTRUCTOR_EXCEPTION(UnitDefinition)
309 SBMLCONSTRUCTOR_EXCEPTION(SBMLDocument)
310 SBMLCONSTRUCTOR_EXCEPTION(SBMLNamespaces)
311 SBMLCONSTRUCTOR_EXCEPTION(SBMLExtensionNamespaces)
312 
313 SBMLCONSTRUCTOR_EXCEPTION(ListOf)
314 SBMLCONSTRUCTOR_EXCEPTION(ListOfCompartments)
315 SBMLCONSTRUCTOR_EXCEPTION(ListOfCompartmentTypes)
316 SBMLCONSTRUCTOR_EXCEPTION(ListOfConstraints)
317 SBMLCONSTRUCTOR_EXCEPTION(ListOfEventAssignments)
318 SBMLCONSTRUCTOR_EXCEPTION(ListOfEvents)
319 SBMLCONSTRUCTOR_EXCEPTION(ListOfFunctionDefinitions)
320 SBMLCONSTRUCTOR_EXCEPTION(ListOfInitialAssignments)
321 SBMLCONSTRUCTOR_EXCEPTION(ListOfParameters)
322 SBMLCONSTRUCTOR_EXCEPTION(ListOfLocalParameters)
323 SBMLCONSTRUCTOR_EXCEPTION(ListOfReactions)
324 SBMLCONSTRUCTOR_EXCEPTION(ListOfRules)
325 SBMLCONSTRUCTOR_EXCEPTION(ListOfSpecies)
326 SBMLCONSTRUCTOR_EXCEPTION(ListOfSpeciesReferences)
327 SBMLCONSTRUCTOR_EXCEPTION(ListOfSpeciesTypes)
328 SBMLCONSTRUCTOR_EXCEPTION(ListOfUnitDefinitions)
329 SBMLCONSTRUCTOR_EXCEPTION(ListOfUnits)
330 
331 /**
332  * Wraps the XMLConstructorException
333  *
334  * The XMLConstructorException (C++ class) is wrapped as the
335  * SBMLConsturctorException (Ruby class) which is derived from
336  * the built-in ArgumentError class (Ruby class).
337  *
338  * For example, the exception can be catched in Ruby code as follows:
339  *
340  * -------------------------------------------------
341  *  begin
342  *    s = LibSBML::XMLAttributes.new(invalid arguments)
343  *  rescue XMLConstructorException
344  *    errmsg = $!
345  *  end
346  * -------------------------------------------------
347  */
348 
349 %exceptionclass XMLConstructorException;
350 
351 %define XMLCONSTRUCTOR_EXCEPTION(SBASE_CLASS_NAME)
352 %exception SBASE_CLASS_NAME{
353   try {
354     $action
355   }
catch(const XMLConstructorException & e)356   catch (const XMLConstructorException &e){
357     static VALUE cpperror = rb_define_class("XMLConstructorException", rb_eArgError);
358     rb_raise(cpperror, "%s", e.what());
359   }
360 }
361 %enddef
362 
363 
364 XMLCONSTRUCTOR_EXCEPTION(XMLAttributes)
365 XMLCONSTRUCTOR_EXCEPTION(XMLError)
366 XMLCONSTRUCTOR_EXCEPTION(XMLNamespaces)
367 XMLCONSTRUCTOR_EXCEPTION(XMLNode)
368 XMLCONSTRUCTOR_EXCEPTION(XMLOutputStream)
369 XMLCONSTRUCTOR_EXCEPTION(XMLToken)
370 XMLCONSTRUCTOR_EXCEPTION(XMLTripple)
371 
372 /**
373  *  Wraps the following functions by using the corresponding
374  *  ListWrapper<TYPENAME> class.
375  *
376  *  - List* ModelHistory::getListCreators()
377  *  - List* ModelHistory::getListModifiedDates()
378  *  - List* SBase::getCVTerms()
379  *  - List* SBMLNamespaces::getSupportedNamespaces()
380  *
381  *  ListWrapper<TYPENAME> class is wrapped as ListTYPENAMEs class.
382  *  So, the above functions are wrapped as follows:
383  *
384  *  - ModelCreatorList ModelHistory.getListCreators()
385  *  - DateList         ModelHistory.getListModifiedDates()
386  *  - CVTermList       SBase.getCVTerms()
387  *  - SBMLNamespacesList SBMLNamespaces::getSupportedNamespaces()
388  *
389  */
390 
391  %typemap(out) List* SBMLNamespaces::getSupportedNamespaces
392 {
393   ListWrapper<SBMLNamespaces> *listw = ($1 != 0) ? new ListWrapper<SBMLNamespaces>($1) : 0;
394   $result = SWIG_NewPointerObj(SWIG_as_voidptr(listw),
395 #if SWIG_VERSION > 0x010333
396                                SWIGTYPE_p_ListWrapperT_SBMLNamespaces_t,
397 #else
398                                SWIGTYPE_p_ListWrapperTSBMLNamespaces_t,
399 #endif
400                                SWIG_POINTER_OWN |  0 );
401 }
402 
403 
404 %typemap(out) List* ModelHistory::getListCreators
405 {
406   ListWrapper<ModelCreator> *listw = ($1 != 0) ? new ListWrapper<ModelCreator>($1) : 0;
407   $result = SWIG_NewPointerObj(SWIG_as_voidptr(listw),
408 #if SWIG_VERSION > 0x010333
409                                SWIGTYPE_p_ListWrapperT_ModelCreator_t,
410 #else
411                                SWIGTYPE_p_ListWrapperTModelCreator_t,
412 #endif
413                                SWIG_POINTER_OWN |  0 );
414 }
415 
416 %typemap(out) List* ModelHistory::getListModifiedDates
417 {
418   ListWrapper<Date> *listw = ($1 != 0) ? new ListWrapper<Date>($1) : 0;
419   $result = SWIG_NewPointerObj(SWIG_as_voidptr(listw),
420 #if SWIG_VERSION > 0x010333
421                                SWIGTYPE_p_ListWrapperT_Date_t,
422 #else
423                                SWIGTYPE_p_ListWrapperTDate_t,
424 #endif
425                                SWIG_POINTER_OWN |  0 );
426 }
427 
428 %define LIST_WRAPPER(_FNAME_,_TYPENAME_)
429 %typemap(out) List* _FNAME_
430 {
431   ListWrapper<_TYPENAME_> *listw = ($1 != 0)? new ListWrapper<_TYPENAME_>($1) : 0;
432   $result = SWIG_NewPointerObj(SWIG_as_voidptr(listw),
433 #if SWIG_VERSION > 0x010333
434                                SWIGTYPE_p_ListWrapperT_ ## _TYPENAME_ ## _t,
435 #else
436                                SWIGTYPE_p_ListWrapperT ## _TYPENAME_ ## _t,
437 #endif
438                                SWIG_POINTER_OWN |  0 );
439 }
440 %enddef
441 LIST_WRAPPER(SBase::getCVTerms,CVTerm)
442 LIST_WRAPPER(SBase::getListOfAllElements,SBase)
443 LIST_WRAPPER(SBasePlugin::getListOfAllElements,SBase)
444 LIST_WRAPPER(SBase::getListOfAllElementsFromPlugins,SBase)
445 
446 
447 %include "local-packages.i"
448 
449