swig/Source/Modules/lang.cxx
Jamie Kirkpatrick 825e67b2b0 Merged revisions 10487,10498-10499,10503-10504,10506,10508,10511,10515-10516,10518-10519,10527,10530-10531,10536-10537,10539-10552,10558-10568,10574-10580,10582,10584,10588-10589,10594,10607-10610,10616,10621,10624-10629,10633-10641,10643,10647,10649-10650,10662,10672,10676-10677,10682-10683,10714,10726-10727,10738,10743,10747,10749,10794,10801-10809,10827-10831,10834 via svnmerge from
https://swig.svn.sourceforge.net/svnroot/swig/trunk

................
  r10487 | wsfulton | 2008-05-21 23:15:52 +0100 (Wed, 21 May 2008) | 1 line
  
  Apply patch from Petr Viktorin to fix some recent regressions in CFFI/CLOS
................
  r10498 | talby | 2008-05-26 21:09:56 +0100 (Mon, 26 May 2008) | 2 lines
  
  run test cases in the Perl set by the --with-perl5 configure option.
................
  r10499 | talby | 2008-05-26 22:04:06 +0100 (Mon, 26 May 2008) | 3 lines
  
  The perl5 minherit runtime test will work better if the classes are 
  actually built under SWIGPERL.
................
  r10503 | wsfulton | 2008-05-28 10:44:37 +0100 (Wed, 28 May 2008) | 1 line
  
  Fix variable wrappers when using -proxy. Patch from Jan Jezabek
................
  r10504 | bhy | 2008-05-28 18:27:48 +0100 (Wed, 28 May 2008) | 2 lines
  
  Fixed SF #1971977:  typo in pycontainer.swg (related to -extranative option)
................
  r10506 | wsfulton | 2008-05-29 01:45:28 +0100 (Thu, 29 May 2008) | 1 line
  
  Fix variable wrappers when using -noproxy
................
  r10508 | bhy | 2008-05-30 14:53:33 +0100 (Fri, 30 May 2008) | 1 line
  
  Fixed SF #1976978, apply the macros for primitive types to std::wstring
................
  r10511 | olly | 2008-05-30 17:11:27 +0100 (Fri, 30 May 2008) | 4 lines
  
  Fix typo in handling of /*@SWIG[...]*/ comments in the scanner.  This just
  meant we were only actually looking for /*@SWI at the start of the comment, so
  was pretty harmless in practice.
................
  r10515 | wsfulton | 2008-06-02 21:10:40 +0100 (Mon, 02 Jun 2008) | 1 line
  
  Fix samename testcase for c# and java
................
  r10516 | wsfulton | 2008-06-02 21:15:39 +0100 (Mon, 02 Jun 2008) | 1 line
  
  Fix enums when using -noproxy
................
  r10518 | bhy | 2008-06-07 12:20:07 +0100 (Sat, 07 Jun 2008) | 4 lines
  
  Added a test case for keyword renaming.
  Now it works for Python in SWIG's -c++ mode,
  but in C mode it doesn't work! (you can try with make keyword_rename.ctest)
................
  r10519 | bhy | 2008-06-07 14:40:51 +0100 (Sat, 07 Jun 2008) | 1 line
  
  fixed keyword_rename.ctest tese case, caused by a mistake in Swig/naming.c
................
  r10527 | mgossage | 2008-06-17 03:57:15 +0100 (Tue, 17 Jun 2008) | 1 line
  
  [lua] bugfix 1938142 (bool& and bool* support)
................
  r10530 | wsfulton | 2008-06-19 21:02:13 +0100 (Thu, 19 Jun 2008) | 1 line
  
  Add R keyword support. Rename keywords for successful compilation of Java and C# code. More consistent keyword warnings across the different languages.
................
  r10531 | wsfulton | 2008-06-19 22:15:48 +0100 (Thu, 19 Jun 2008) | 1 line
  
  add complete list of R reserved words
................
  r10536 | wsfulton | 2008-06-21 12:35:33 +0100 (Sat, 21 Jun 2008) | 1 line
  
  better terminology for static types
................
  r10537 | wsfulton | 2008-06-21 12:42:48 +0100 (Sat, 21 Jun 2008) | 1 line
  
  remove raise as keyword test- it conflicts with _raise in LIBCMT on windows
................
  r10539 | wsfulton | 2008-06-21 16:21:29 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Lua example warning removal fixes for vc++
................
  r10540 | wsfulton | 2008-06-21 16:23:02 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Remove some vc++ /W4 warnings
................
  r10541 | wsfulton | 2008-06-21 17:04:55 +0100 (Sat, 21 Jun 2008) | 1 line
  
  minor vc++ /W4 warning fixes
................
  r10542 | wsfulton | 2008-06-21 20:07:51 +0100 (Sat, 21 Jun 2008) | 1 line
  
  'byte' is already used in Ruby on windows, so use another keyword
................
  r10543 | wsfulton | 2008-06-21 21:45:32 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Fix crashing in the Ruby reject method in the STL wrappers
................
  r10544 | wsfulton | 2008-06-21 21:48:28 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Fix crashing in the Ruby reject method in the STL wrappers
................
  r10545 | wsfulton | 2008-06-21 21:49:10 +0100 (Sat, 21 Jun 2008) | 1 line
  
  remove unnecessary variable int the char **STRING_ARRAY out typemap
................
  r10546 | wsfulton | 2008-06-21 22:07:49 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Fix Ruby C++ example dependencies in dsp files
................
  r10547 | wsfulton | 2008-06-21 23:25:36 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Fix unused parameter warnings in python when using gcc's -W -Wall options
................
  r10548 | wsfulton | 2008-06-21 23:26:35 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Fix virtual destructor
................
  r10549 | wsfulton | 2008-06-22 00:25:20 +0100 (Sun, 22 Jun 2008) | 1 line
  
  various warning fixes
................
  r10550 | wsfulton | 2008-06-22 01:09:11 +0100 (Sun, 22 Jun 2008) | 1 line
  
  Another fix for the JVM hanging on exit problem when using directors
................
  r10551 | wsfulton | 2008-06-22 01:09:51 +0100 (Sun, 22 Jun 2008) | 1 line
  
  documentation sections update
................
  r10552 | wsfulton | 2008-06-22 01:18:10 +0100 (Sun, 22 Jun 2008) | 1 line
  
  more docs on defining macros for the thread hanging problem
................
  r10558 | wsfulton | 2008-06-22 22:30:20 +0100 (Sun, 22 Jun 2008) | 1 line
  
  fix unused parms in last commit for C code
................
  r10559 | wsfulton | 2008-06-22 23:12:43 +0100 (Sun, 22 Jun 2008) | 1 line
  
  Suppress unused methods warning for VC++
................
  r10560 | wsfulton | 2008-06-23 21:26:07 +0100 (Mon, 23 Jun 2008) | 1 line
  
  fix partialcheck-test-suite and parallel make for r, chicken, tcl and php
................
  r10561 | wsfulton | 2008-06-23 21:39:41 +0100 (Mon, 23 Jun 2008) | 1 line
  
  correct message display when running the partialcheck-test-suite make target
................
  r10562 | wsfulton | 2008-06-23 22:14:53 +0100 (Mon, 23 Jun 2008) | 1 line
  
  fix typo
................
  r10563 | olly | 2008-06-23 22:23:54 +0100 (Mon, 23 Jun 2008) | 3 lines
  
  Fix bad use of Python API (untested, since I can't even compile this code on
  x86-64!)
................
  r10564 | olly | 2008-06-23 23:58:03 +0100 (Mon, 23 Jun 2008) | 3 lines
  
  [PHP] Fix segfault when wrapping a non-class function marked with
  %newobject (testcase char_strings).
................
  r10565 | olly | 2008-06-24 01:27:34 +0100 (Tue, 24 Jun 2008) | 3 lines
  
  [PHP] Fix assertion failure when handling %typemap(in,numinputs=0)
  (testcase ignore_parameter).
................
  r10566 | olly | 2008-06-24 01:33:08 +0100 (Tue, 24 Jun 2008) | 2 lines
  
  [PHP] Fix typemap_namespace.i to not try to copy a non-existent typemap.
................
  r10567 | olly | 2008-06-24 01:41:07 +0100 (Tue, 24 Jun 2008) | 3 lines
  
  Clean up dead and unused code in SwigToPhpType(), and rename to
  GetShadowReturnType().
................
  r10568 | olly | 2008-06-24 01:42:29 +0100 (Tue, 24 Jun 2008) | 2 lines
  
  Fix cosmetic typo in string constant.
................
  r10574 | wsfulton | 2008-06-24 21:10:28 +0100 (Tue, 24 Jun 2008) | 1 line
  
  zap last entry
................
  r10575 | wsfulton | 2008-06-24 21:11:46 +0100 (Tue, 24 Jun 2008) | 1 line
  
  variable name changes to remove php keywords
................
  r10576 | wsfulton | 2008-06-24 21:12:08 +0100 (Tue, 24 Jun 2008) | 1 line
  
  variable name hiding fix
................
  r10577 | wsfulton | 2008-06-24 21:12:43 +0100 (Tue, 24 Jun 2008) | 1 line
  
  More info about numobjects added
................
  r10578 | wsfulton | 2008-06-24 21:13:41 +0100 (Tue, 24 Jun 2008) | 1 line
  
  update for 1.3.36 release
................
  r10579 | wsfulton | 2008-06-24 22:48:46 +0100 (Tue, 24 Jun 2008) | 1 line
  
  remove deprecated -c commandline option (runtime library generation)
................
  r10580 | wsfulton | 2008-06-24 22:53:12 +0100 (Tue, 24 Jun 2008) | 1 line
  
  correct comment about deprecated option
................
  r10582 | wsfulton | 2008-06-25 00:00:27 +0100 (Wed, 25 Jun 2008) | 1 line
  
  use rsync and ssh to upload releases to SourceForge as ftp no longer works
................
  r10584 | wsfulton | 2008-06-25 00:24:48 +0100 (Wed, 25 Jun 2008) | 1 line
  
  correction for 1.3.36
................
  r10588 | wsfulton | 2008-06-25 01:16:04 +0100 (Wed, 25 Jun 2008) | 1 line
  
  section update
................
  r10589 | wsfulton | 2008-06-25 01:16:40 +0100 (Wed, 25 Jun 2008) | 1 line
  
  bump version to 1.3.37
................
  r10594 | wsfulton | 2008-06-26 19:33:06 +0100 (Thu, 26 Jun 2008) | 1 line
  
  correct typo in first entry about %fragment
................
  r10607 | wsfulton | 2008-06-29 01:19:05 +0100 (Sun, 29 Jun 2008) | 1 line
  
  fix some potential null pointer usage as reported by CoveriCoverity Prevent
................
  r10608 | wsfulton | 2008-06-29 01:50:27 +0100 (Sun, 29 Jun 2008) | 1 line
  
  fix potential null pointer usage as reported by Coverity Prevent
................
  r10609 | wsfulton | 2008-06-29 10:57:41 +0100 (Sun, 29 Jun 2008) | 1 line
  
  make life easier for svn status updates as everyone has different autotool versions installed - use svn:ignore on config.sub and config.guess
................
  r10610 | wsfulton | 2008-06-29 11:08:14 +0100 (Sun, 29 Jun 2008) | 1 line
  
  make life easier for svn status updates as everyone has different autotool versions installed - use svn:ignore on config.sub and config.guess
................
  r10616 | talby | 2008-07-01 00:41:27 +0100 (Tue, 01 Jul 2008) | 2 lines
  
  Hopefully this provides more portable values for Infinity and NaN in Perl.
................
  r10621 | wsfulton | 2008-07-01 23:02:14 +0100 (Tue, 01 Jul 2008) | 1 line
  
  update old commandline option
................
  r10624 | olly | 2008-07-02 04:17:46 +0100 (Wed, 02 Jul 2008) | 5 lines
  
  [Python] Import the C extension differently for Python 2.6 and
  later so that an implicit relative import doesn't produce a
  deprecation warning for 2.6 and a failure for 2.7 and later.
  Patch from Richard Boulton in SF#2008229.
................
  r10625 | bhy | 2008-07-02 05:56:11 +0100 (Wed, 02 Jul 2008) | 1 line
  
  fix the relative import patch by try both relative and absolute import
................
  r10626 | olly | 2008-07-02 06:55:18 +0100 (Wed, 02 Jul 2008) | 4 lines
  
  [PHP4] Support for PHP4 has been removed.  The PHP developers are
  no longer making new PHP4 releases, and won't even be patching
  critical security issues after 2008-08-08.
................
  r10627 | bhy | 2008-07-02 07:06:56 +0100 (Wed, 02 Jul 2008) | 1 line
  
  fix the previous commit -- new approach using imp module
................
  r10628 | bhy | 2008-07-02 07:29:15 +0100 (Wed, 02 Jul 2008) | 1 line
  
  minor fix on relative import: close fp if exception occured during imp.find_module
................
  r10629 | bhy | 2008-07-02 08:08:00 +0100 (Wed, 02 Jul 2008) | 1 line
  
  reconstruct the relative import, now the generated code looks better
................
  r10633 | olly | 2008-07-03 01:09:56 +0100 (Thu, 03 Jul 2008) | 9 lines
  
  WARN_* constants are user visible, so keep existing WARN_PHP4_* for
  backward compatibility, but add preferred forms WARN_PHP_* and use
  these ourselves.
  
  Rename Lib/php4 to Lib/php, Source/Modules/php4.cxx to Source/Modules/php.cxx.
   
  Add typemaps for const reference so Examples/test-suite/apply_signed_char.i
  works.
................
  r10634 | olly | 2008-07-03 01:12:58 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Remove file added in error.
................
  r10635 | olly | 2008-07-03 01:37:38 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Rename php4*.swg to php*.swg.
................
  r10636 | olly | 2008-07-03 02:13:51 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Update wrt PHP4.
................
  r10637 | olly | 2008-07-03 03:32:11 +0100 (Thu, 03 Jul 2008) | 4 lines
  
  [PHP] The deprecated command line option "-phpfull" has been
  removed.  We recommend building your extension as a dynamically
  loadable module.
................
  r10638 | olly | 2008-07-03 03:32:41 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Fix version number
................
  r10639 | olly | 2008-07-03 07:04:24 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Make t_output_helper() static.
................
  r10640 | olly | 2008-07-03 07:05:34 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Make testcase li_typemaps work for PHP.
................
  r10641 | olly | 2008-07-03 10:12:16 +0100 (Thu, 03 Jul 2008) | 2 lines
  
  Fix check::classname() to compare case-insensitively and not try to interpolate objects into strings.
................
  r10643 | olly | 2008-07-03 23:00:01 +0100 (Thu, 03 Jul 2008) | 4 lines
  
  The operator& trick in allowexcept.i doesn't work for SWIG/PHP because the
  generated code takes the address of the variable in the code in the "vinit"
  section.  So comment out the private operator& for PHP.
................
  r10647 | olly | 2008-07-04 00:55:33 +0100 (Fri, 04 Jul 2008) | 2 lines
  
  [PHP] The SWIG cdata.i library module is now supported.
................
  r10649 | olly | 2008-07-04 02:02:22 +0100 (Fri, 04 Jul 2008) | 4 lines
  
  [PHP] The deprecated command line option "-make" has been removed.  
  Searches on Google codesearch suggest that nobody is using it now
  anyway.
................
  r10650 | olly | 2008-07-04 02:22:11 +0100 (Fri, 04 Jul 2008) | 4 lines
  
  [PHP] For std_vector.i and std_map.i, rename empty() to is_empty()
  since "empty" is a PHP reserved word.  Based of patch from Mark Klein
  in SF#1943417.
................
  r10662 | wsfulton | 2008-07-14 22:09:23 +0100 (Mon, 14 Jul 2008) | 1 line
  
  Fix director typemaps for pointers so that NULL pointers are correctly marshalled to C#/Java null in director methods
................
  r10672 | olly | 2008-07-17 02:17:08 +0100 (Thu, 17 Jul 2008) | 2 lines
  
  Fix a typo; improve wording.
................
  r10676 | wsfulton | 2008-07-17 22:05:49 +0100 (Thu, 17 Jul 2008) | 1 line
  
  SF #2019156 Configuring with --without-octave or --without-alllang did not disable octave.
................
  r10677 | wsfulton | 2008-07-17 22:08:22 +0100 (Thu, 17 Jul 2008) | 1 line
  
  tidy output after detecting X11 headers
................
  r10682 | wsfulton | 2008-07-19 19:08:06 +0100 (Sat, 19 Jul 2008) | 1 line
  
  a bit more on pgcpp
................
  r10683 | wsfulton | 2008-07-19 23:45:54 +0100 (Sat, 19 Jul 2008) | 1 line
  
  Fix building of Tcl examples/test-suite on Mac OSX
................
  r10714 | olly | 2008-07-27 13:51:16 +0100 (Sun, 27 Jul 2008) | 2 lines
  
  Fix "can can" typo in docs (SF#2026756)
................
  r10726 | wuzzeb | 2008-08-02 09:28:02 +0100 (Sat, 02 Aug 2008) | 1 line
  
  Commit patch 2019314
................
  r10727 | wuzzeb | 2008-08-02 09:49:43 +0100 (Sat, 02 Aug 2008) | 1 line
  
  add assert.h to fix chicken build of external runtime (ext_test testsuite)
................
  r10738 | talby | 2008-08-07 07:28:13 +0100 (Thu, 07 Aug 2008) | 2 lines
  
  hoist globals to local scope where trival.
................
  r10743 | talby | 2008-08-08 04:10:55 +0100 (Fri, 08 Aug 2008) | 2 lines
  
  initial steps to clean up perl5 class methods (primarily constructors).
................
  r10747 | talby | 2008-08-09 05:08:26 +0100 (Sat, 09 Aug 2008) | 2 lines
  
  moves perl space constructor fixups into wrapper code.
................
  r10749 | talby | 2008-08-10 00:57:55 +0100 (Sun, 10 Aug 2008) | 2 lines
  
  usage_func() fix + CHANGES.current entry to explain my past few commits.
................
  r10794 | talby | 2008-08-19 08:09:29 +0100 (Tue, 19 Aug 2008) | 3 lines
  
  rollback 10737:10749, this work is better left on a branch until it is 
  in support a significant feature enhancement.
................
  r10801 | drjoe | 2008-08-31 17:07:43 +0100 (Sun, 31 Aug 2008) | 2 lines
  
  change Rf_warning to warning.  Looks like a typo
................
  r10802 | wsfulton | 2008-09-01 20:59:23 +0100 (Mon, 01 Sep 2008) | 1 line
  
  Fix ruby detection problem breaking configure
................
  r10803 | wsfulton | 2008-09-01 21:00:28 +0100 (Mon, 01 Sep 2008) | 1 line
  
  Fix another perl global namespace pollution
................
  r10804 | wsfulton | 2008-09-01 21:32:53 +0100 (Mon, 01 Sep 2008) | 1 line
  
  Fix array bounds checking in C# std::vector wrappers
................
  r10805 | wsfulton | 2008-09-01 21:34:49 +0100 (Mon, 01 Sep 2008) | 1 line
  
  fix runtime problem in Ruby std_vector example
................
  r10806 | wsfulton | 2008-09-01 21:42:40 +0100 (Mon, 01 Sep 2008) | 1 line
  
  Fix portability problem using /dev/null
................
  r10807 | wsfulton | 2008-09-01 22:46:41 +0100 (Mon, 01 Sep 2008) | 1 line
  
  patch #2079381 submitted by Boris Smilga - constant exprs put into no-eval context in DEFCENUM
................
  r10808 | wsfulton | 2008-09-02 21:56:52 +0100 (Tue, 02 Sep 2008) | 1 line
  
  Add new terminator attribute for the csin typemap for C#
................
  r10809 | wsfulton | 2008-09-03 00:01:37 +0100 (Wed, 03 Sep 2008) | 1 line
  
  Fix #1988296 - Multiple module director linking issue
................
  r10827 | richardb | 2008-09-10 11:08:21 +0100 (Wed, 10 Sep 2008) | 6 lines
  
  [Python] Commit patch #2089149: Director exception handling mangles
  returned exception.  Exceptions raised by Python code in directors
  are now passed through to the caller without change.  Also, remove
  the ": " prefix which used to be added to other director exceptions
  (eg, those due to incorrect return types).
................
  r10828 | bhy | 2008-09-10 11:45:33 +0100 (Wed, 10 Sep 2008) | 3 lines
  
  Initialized merge tracking via "svnmerge" with revisions "1-10827" from 
  https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-bhy
................
  r10829 | bhy | 2008-09-10 12:04:09 +0100 (Wed, 10 Sep 2008) | 4 lines
  
  Removed merge tracking for "svnmerge" for 
  https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-bhy
  (Undo the init due to user error)
................
  r10830 | bhy | 2008-09-10 12:08:16 +0100 (Wed, 10 Sep 2008) | 3 lines
  
  Initialized merge tracking via "svnmerge" with revisions "1-10403" from 
  https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-bhy
................
  r10831 | bhy | 2008-09-10 12:51:12 +0100 (Wed, 10 Sep 2008) | 11 lines
  
  (Still trying to set right properity to get svnmerge work...)
  Recorded merge of revisions 10404 via svnmerge from 
  https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-bhy
  
  ........
    r10404 | bhy | 2008-05-01 08:35:49 +0800 (Thu, 01 May 2008) | 5 lines
    
    Start of gsoc2008-bhy branch. This is a branch for Haoyu Bai's Python 3.0 backend project.
    Some file already modified since a little of work already done when starting the branch. 
  ........
................
  r10834 | bhy | 2008-09-11 18:18:07 +0100 (Thu, 11 Sep 2008) | 8 lines
  
  Merged the Python 3.0 support branch. The merging progress is not so smooth, so hope this commit won't make anything broken.
  
  This is the (incomplemete) log produced by svnmerge.py:
  
  Merged revisions 10405-10409,10420-10422,10426,10438,10445,10451,10454-10465,10467,10473-10475,10485,10488-10489,10493-10495,10497,10509-10510,10513-10514,10517,10520,10525,10528-10529,10533-10535,10554-10557,10570,10573,10593,10614,10666-10669,10673,10678,10687,10690,10704-10706,10731,10744,10750-10752,10755,10759,10770,10775-10776,10813,10819 via svnmerge from 
  https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-bhy
................


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-cherylfoil@10837 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2008-09-12 10:51:51 +00:00

3432 lines
103 KiB
C++

/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* lang.cxx
*
* Language base class functions. Default C++ handling is also implemented here.
* ----------------------------------------------------------------------------- */
char cvsroot_lang_cxx[] = "$Id$";
#include "swigmod.h"
#include "cparse.h"
#include <ctype.h>
/* default mode settings */
static int director_mode = 0;
static int director_protected_mode = 1;
static int all_protected_mode = 0;
static int naturalvar_mode = 0;
/* Set director_protected_mode */
void Wrapper_director_mode_set(int flag) {
director_mode = flag;
}
void Wrapper_director_protected_mode_set(int flag) {
director_protected_mode = flag;
}
void Wrapper_all_protected_mode_set(int flag) {
all_protected_mode = flag;
}
void Wrapper_naturalvar_mode_set(int flag) {
naturalvar_mode = flag;
}
extern "C" {
int Swig_director_mode() {
return director_mode;
}
int Swig_director_protected_mode() {
return director_protected_mode;
}
int Swig_all_protected_mode() {
return all_protected_mode;
}
}
/* Some status variables used during parsing */
static int InClass = 0; /* Parsing C++ or not */
static String *ClassName = 0; /* This is the real name of the current class */
static String *ClassPrefix = 0; /* Class prefix */
static String *ClassType = 0; /* Fully qualified type name to use */
static String *DirectorClassName = 0; /* Director name of the current class */
int Abstract = 0;
int ImportMode = 0;
int IsVirtual = 0;
static String *AttributeFunctionGet = 0;
static String *AttributeFunctionSet = 0;
static Node *CurrentClass = 0;
int line_number = 0;
char *input_file = 0;
int SmartPointer = 0;
static Hash *classhash;
extern int GenerateDefault;
extern int ForceExtern;
extern int AddExtern;
/* import modes */
#define IMPORT_MODE 1
#define IMPORT_MODULE 2
/* ----------------------------------------------------------------------
* Dispatcher::emit_one()
*
* Dispatch a single node
* ---------------------------------------------------------------------- */
int Dispatcher::emit_one(Node *n) {
String *wrn;
int ret = SWIG_OK;
char *tag = Char(nodeType(n));
if (!tag) {
/* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree
node!\n"); */
return SWIG_OK;
}
/* Do not proceed if marked with an error */
if (Getattr(n, "error"))
return SWIG_OK;
/* Look for warnings */
wrn = Getattr(n, "feature:warnfilter");
if (wrn) {
Swig_warnfilter(wrn, 1);
}
/* ============================================================
* C/C++ parsing
* ============================================================ */
if (strcmp(tag, "extern") == 0) {
ret = externDeclaration(n);
} else if (strcmp(tag, "cdecl") == 0) {
ret = cDeclaration(n);
} else if (strcmp(tag, "enum") == 0) {
ret = enumDeclaration(n);
} else if (strcmp(tag, "enumitem") == 0) {
ret = enumvalueDeclaration(n);
} else if (strcmp(tag, "enumforward") == 0) {
ret = enumforwardDeclaration(n);
} else if (strcmp(tag, "class") == 0) {
ret = classDeclaration(n);
} else if (strcmp(tag, "classforward") == 0) {
ret = classforwardDeclaration(n);
} else if (strcmp(tag, "constructor") == 0) {
ret = constructorDeclaration(n);
} else if (strcmp(tag, "destructor") == 0) {
ret = destructorDeclaration(n);
} else if (strcmp(tag, "access") == 0) {
ret = accessDeclaration(n);
} else if (strcmp(tag, "using") == 0) {
ret = usingDeclaration(n);
} else if (strcmp(tag, "namespace") == 0) {
ret = namespaceDeclaration(n);
} else if (strcmp(tag, "template") == 0) {
ret = templateDeclaration(n);
}
/* ===============================================================
* Doxygen Comment
* =============================================================== */
else if (strcmp(tag, "doxycomm") == 0) {
ret = doxygenComment(n);
}
/* ===============================================================
* SWIG directives
* =============================================================== */
else if (strcmp(tag, "top") == 0) {
ret = top(n);
} else if (strcmp(tag, "extend") == 0) {
ret = extendDirective(n);
} else if (strcmp(tag, "apply") == 0) {
ret = applyDirective(n);
} else if (strcmp(tag, "clear") == 0) {
ret = clearDirective(n);
} else if (strcmp(tag, "constant") == 0) {
ret = constantDirective(n);
} else if (strcmp(tag, "fragment") == 0) {
ret = fragmentDirective(n);
} else if (strcmp(tag, "import") == 0) {
ret = importDirective(n);
} else if (strcmp(tag, "include") == 0) {
ret = includeDirective(n);
} else if (strcmp(tag, "insert") == 0) {
ret = insertDirective(n);
} else if (strcmp(tag, "module") == 0) {
ret = moduleDirective(n);
} else if (strcmp(tag, "native") == 0) {
ret = nativeDirective(n);
} else if (strcmp(tag, "pragma") == 0) {
ret = pragmaDirective(n);
} else if (strcmp(tag, "typemap") == 0) {
ret = typemapDirective(n);
} else if (strcmp(tag, "typemapcopy") == 0) {
ret = typemapcopyDirective(n);
} else if (strcmp(tag, "typemapitem") == 0) {
ret = typemapitemDirective(n);
} else if (strcmp(tag, "types") == 0) {
ret = typesDirective(n);
} else {
Printf(stderr, "%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag);
ret = SWIG_ERROR;
}
if (wrn) {
Swig_warnfilter(wrn, 0);
}
return ret;
}
/* ----------------------------------------------------------------------
* Dispatcher::emit_children()
*
* Emit all children that match the given type. type = 0 means all types.
* ---------------------------------------------------------------------- */
int Dispatcher::emit_children(Node *n) {
Node *c;
char *eo = Char(Getattr(n, "feature:emitonlychildren"));
for (c = firstChild(n); c; c = nextSibling(c)) {
if (eo) {
const char *tag = Char(nodeType(c));
if (strcmp(tag, "cdecl") == 0) {
if (checkAttribute(c, "storage", "typedef"))
tag = "typedef";
}
if (strstr(eo, tag) == 0) {
continue;
}
}
emit_one(c);
}
return SWIG_OK;
}
/* Stubs for dispatcher class. We don't do anything by default---up to derived class
to fill in traversal code */
int Dispatcher::defaultHandler(Node *) {
return SWIG_OK;
}
int Dispatcher::extendDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::applyDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::clearDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::constantDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::fragmentDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::importDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::includeDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::insertDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::moduleDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::nativeDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::pragmaDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typemapDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typemapitemDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typemapcopyDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::typesDirective(Node *n) {
return defaultHandler(n);
}
int Dispatcher::cDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::externDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::enumDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::enumvalueDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::enumforwardDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::classDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::templateDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::classforwardDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::constructorDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::destructorDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::accessDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::usingDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::namespaceDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::doxygenComment(Node *n){
return defaultHandler(n);
}
/* Allocators */
Language::Language():
none_comparison(NewString("$arg != 0")),
director_ctor_code(NewString("")),
director_prot_ctor_code(0),
symbols(NewHash()),
classtypes(NewHash()),
enumtypes(NewHash()),
overloading(0),
multiinput(0),
cplus_runtime(0),
directors(0) {
argc_template_string = NewString("argc");
argv_template_string = NewString("argv[%d]");
/* Default director constructor code, passed to Swig_ConstructorToFunction */
Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
/*
Default director 'protected' constructor code, disabled by
default. Each language that needs it, has to define it.
*/
director_prot_ctor_code = 0;
director_multiple_inheritance = 1;
director_language = 0;
}
Language::~Language() {
Delete(symbols);
Delete(classtypes);
Delete(enumtypes);
Delete(director_ctor_code);
Delete(none_comparison);
}
/* ----------------------------------------------------------------------
emit_one()
---------------------------------------------------------------------- */
int Language::emit_one(Node *n) {
int ret;
int oldext;
if (!n)
return SWIG_OK;
if (GetFlag(n, "feature:ignore")
&& !Getattr(n, "feature:onlychildren"))
return SWIG_OK;
oldext = Extend;
if (Getattr(n, "feature:extend"))
Extend = 1;
line_number = Getline(n);
input_file = Char(Getfile(n));
/*
symtab = Getattr(n,"symtab");
if (symtab) {
symtab = Swig_symbol_setscope(symtab);
}
*/
ret = Dispatcher::emit_one(n);
/*
if (symtab) {
Swig_symbol_setscope(symtab);
}
*/
Extend = oldext;
return ret;
}
static Parm *nonvoid_parms(Parm *p) {
if (p) {
SwigType *t = Getattr(p, "type");
if (SwigType_type(t) == T_VOID)
return 0;
}
return p;
}
/* -----------------------------------------------------------------------------
* cplus_value_type()
*
* Returns the alternative value type needed in C++ for class value
* types. When swig is not sure about using a plain $ltype value,
* since the class doesn't have a default constructor, or it can't be
* assigned, you will get back 'SwigValueWrapper<type >'.
*
* ----------------------------------------------------------------------------- */
SwigType *cplus_value_type(SwigType *t) {
return SwigType_alttype(t, 0);
}
static Node *first_nontemplate(Node *n) {
while (n) {
if (Strcmp(nodeType(n), "template") != 0)
return n;
n = Getattr(n, "sym:nextSibling");
}
return n;
}
/* --------------------------------------------------------------------------
* swig_pragma()
*
* Handle swig pragma directives.
* -------------------------------------------------------------------------- */
void swig_pragma(char *lang, char *name, char *value) {
if (strcmp(lang, "swig") == 0) {
if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
GenerateDefault = 1;
} else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
GenerateDefault = 0;
} else if (strcmp(name, "attributefunction") == 0) {
String *nvalue = NewString(value);
char *s = strchr(Char(nvalue), ':');
if (!s) {
Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
} else {
*s = 0;
AttributeFunctionGet = NewString(Char(nvalue));
AttributeFunctionSet = NewString(s + 1);
}
Delete(nvalue);
} else if (strcmp(name, "noattributefunction") == 0) {
AttributeFunctionGet = 0;
AttributeFunctionSet = 0;
}
}
}
/* --------------------------------------------------------------------------
* use_naturalvar_mode()
* -------------------------------------------------------------------------- */
int use_naturalvar_mode(Node *n) {
if (Getattr(n, "unnamed"))
return 0;
int nvar = naturalvar_mode || GetFlag(n, "feature:naturalvar");
if (!nvar) {
/* look for feature in the class */
SwigType *ty = Getattr(n, "type");
SwigType *fullty = SwigType_typedef_resolve_all(ty);
if (SwigType_isclass(fullty)) {
Node *m = Copy(n);
SwigType *tys = SwigType_strip_qualifiers(fullty);
Swig_features_get(Swig_cparse_features(), 0, tys, 0, m);
nvar = GetFlag(m, "feature:naturalvar");
Delete(tys);
Delete(m);
}
Delete(fullty);
}
return nvar ? CWRAP_NATURAL_VAR : 0;
}
/* ----------------------------------------------------------------------
* Language::top() - Top of parsing tree
* ---------------------------------------------------------------------- */
int Language::top(Node *n) {
Node *mod = Getattr(n, "module");
if (mod) {
Node *options = Getattr(mod, "options");
if (options) {
if (Getattr(options, "naturalvar")) {
naturalvar_mode = 1;
}
if (Getattr(options, "nonaturalvar")) {
naturalvar_mode = 0;
}
}
}
classhash = Getattr(n, "classes");
return emit_children(n);
}
/* ----------------------------------------------------------------------
* Language::extendDirective()
* ---------------------------------------------------------------------- */
int Language::extendDirective(Node *n) {
int oldam = Extend;
AccessMode oldmode = cplus_mode;
Extend = CWRAP_EXTEND;
cplus_mode = PUBLIC;
emit_children(n);
Extend = oldam;
cplus_mode = oldmode;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::applyDirective()
* ---------------------------------------------------------------------- */
int Language::applyDirective(Node *n) {
Parm *pattern = Getattr(n, "pattern");
Node *c = firstChild(n);
while (c) {
Parm *apattern = Getattr(c, "pattern");
if (ParmList_len(pattern) != ParmList_len(apattern)) {
Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
} else {
if (!Swig_typemap_apply(pattern, apattern)) {
Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
}
}
c = nextSibling(c);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::clearDirective()
* ---------------------------------------------------------------------- */
int Language::clearDirective(Node *n) {
Node *p;
for (p = firstChild(n); p; p = nextSibling(p)) {
ParmList *pattern = Getattr(p, "pattern");
Swig_typemap_clear_apply(pattern);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::constantDirective()
* ---------------------------------------------------------------------- */
int Language::constantDirective(Node *n) {
if (CurrentClass && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
if (!GetFlag(n, "feature:allowexcept")) {
UnsetFlag(n, "feature:except");
}
if (Getattr(n, "feature:exceptvar")) {
Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
}
if (!ImportMode) {
Swig_require("constantDirective", n, "name", "?value", NIL);
String *name = Getattr(n, "name");
String *value = Getattr(n, "value");
if (!value) {
value = Copy(name);
} else {
/* if (checkAttribute(n,"type","char")) {
value = NewString(value);
} else {
value = NewStringf("%(escape)s", value);
}
*/
Setattr(n, "rawvalue", value);
value = NewStringf("%(escape)s", value);
if (!Len(value))
Append(value, "\\0");
/* Printf(stdout,"'%s' = '%s'\n", name, value); */
}
Setattr(n, "value", value);
this->constantWrapper(n);
Swig_restore(n);
return SWIG_OK;
}
return SWIG_NOWRAP;
}
/* ----------------------------------------------------------------------
* Language::fragmentDirective()
* ---------------------------------------------------------------------- */
int Language::fragmentDirective(Node *n) {
Swig_fragment_register(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::importDirective()
* ---------------------------------------------------------------------- */
int Language::importDirective(Node *n) {
int oldim = ImportMode;
ImportMode = IMPORT_MODE;
emit_children(n);
ImportMode = oldim;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::includeDirective()
* ---------------------------------------------------------------------- */
int Language::includeDirective(Node *n) {
emit_children(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::insertDirective()
* ---------------------------------------------------------------------- */
int Language::insertDirective(Node *n) {
/* %insert directive */
if ((!ImportMode) || Getattr(n, "generated")) {
String *code = Getattr(n, "code");
String *section = Getattr(n, "section");
File *f = 0;
if (!section) { /* %{ ... %} */
f = Swig_filebyname("header");
} else {
f = Swig_filebyname(section);
}
if (f) {
Printf(f, "%s\n", code);
} else {
Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
}
return SWIG_OK;
} else {
return SWIG_NOWRAP;
}
}
/* ----------------------------------------------------------------------
* Language::moduleDirective()
* ---------------------------------------------------------------------- */
int Language::moduleDirective(Node *n) {
(void) n;
/* %module directive */
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::nativeDirective()
* ---------------------------------------------------------------------- */
int Language::nativeDirective(Node *n) {
if (!ImportMode) {
return nativeWrapper(n);
} else {
return SWIG_NOWRAP;
}
}
/* ----------------------------------------------------------------------
* Language::pragmaDirective()
* ---------------------------------------------------------------------- */
int Language::pragmaDirective(Node *n) {
/* %pragma directive */
if (!ImportMode) {
String *lan = Getattr(n, "lang");
String *name = Getattr(n, "name");
String *value = Getattr(n, "value");
swig_pragma(Char(lan), Char(name), Char(value));
/* pragma(Char(lan),Char(name),Char(value)); */
return SWIG_OK;
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::typemapDirective()
* ---------------------------------------------------------------------- */
int Language::typemapDirective(Node *n) {
/* %typemap directive */
String *method = Getattr(n, "method");
String *code = Getattr(n, "code");
Parm *kwargs = Getattr(n, "kwargs");
Node *items = firstChild(n);
static int namewarn = 0;
if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "Deprecated typemap feature ($source/$target).\n");
if (!namewarn) {
Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\
For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
$source by $input and $target by $1. For typemaps related to return values (out,\n\
argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
Doc/Manual/Typemaps.html for complete details.\n");
namewarn = 1;
}
}
if (Strcmp(method, "except") == 0) {
Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
}
if (Strcmp(method, "in") == 0) {
Hash *k;
k = kwargs;
while (k) {
if (checkAttribute(k, "name", "numinputs")) {
if (!multiinput && (GetInt(k, "value") > 1)) {
Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
return SWIG_ERROR;
}
break;
}
k = nextSibling(k);
}
if (!k) {
k = NewHash();
Setattr(k, "name", "numinputs");
Setattr(k, "value", "1");
set_nextSibling(k, kwargs);
Setattr(n, "kwargs", k);
kwargs = k;
}
}
if (Strcmp(method, "ignore") == 0) {
Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
Clear(method);
Append(method, "in");
Hash *k = NewHash();
Setattr(k, "name", "numinputs");
Setattr(k, "value", "0");
set_nextSibling(k, kwargs);
Setattr(n, "kwargs", k);
kwargs = k;
}
/* Replace $descriptor() macros */
if (code) {
Setfile(code, Getfile(n));
Setline(code, Getline(n));
Swig_cparse_replace_descriptor(code);
}
while (items) {
Parm *pattern = Getattr(items, "pattern");
Parm *parms = Getattr(items, "parms");
if (code) {
Swig_typemap_register(method, pattern, code, parms, kwargs);
} else {
Swig_typemap_clear(method, pattern);
}
items = nextSibling(items);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::typemapcopyDirective()
* ---------------------------------------------------------------------- */
int Language::typemapcopyDirective(Node *n) {
String *method = Getattr(n, "method");
Parm *pattern = Getattr(n, "pattern");
Node *items = firstChild(n);
int nsrc = 0;
nsrc = ParmList_len(pattern);
while (items) {
ParmList *npattern = Getattr(items, "pattern");
if (nsrc != ParmList_len(npattern)) {
Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
} else {
if (Swig_typemap_copy(method, pattern, npattern) < 0) {
Swig_error(input_file, line_number, "Can't copy typemap.\n");
}
}
items = nextSibling(items);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::typesDirective()
* ---------------------------------------------------------------------- */
int Language::typesDirective(Node *n) {
Parm *parms = Getattr(n, "parms");
String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
while (parms) {
SwigType *t = Getattr(parms, "type");
String *v = Getattr(parms, "value");
if (!v) {
SwigType_remember(t);
} else {
if (SwigType_issimple(t)) {
SwigType_inherit(t, v, 0, convcode);
}
}
parms = nextSibling(parms);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::cDeclaration()
* ---------------------------------------------------------------------- */
int Language::cDeclaration(Node *n) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
SwigType *decl = Getattr(n, "decl");
String *storage = Getattr(n, "storage");
Node *over;
File *f_header = 0;
SwigType *ty, *fullty;
/* discards nodes following the access control rules */
if (cplus_mode != PUBLIC || !is_public(n)) {
/* except for friends, they are not affected by access control */
int isfriend = storage && (Cmp(storage, "friend") == 0);
if (!isfriend) {
/* Check what the director needs. If the method is pure virtual, it is always needed.
* Also wrap non-virtual protected members if asked for (allprotected mode). */
if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || is_non_virtual_protected_access(n)))) {
return SWIG_NOWRAP;
}
#if 0
// I don't see why this is needed - WSF
/* prevent wrapping the method twice due to overload */
String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
if (Getattr(CurrentClass, wrapname)) {
Delete(wrapname);
return SWIG_NOWRAP;
}
SetFlag(CurrentClass, wrapname);
Delete(wrapname);
#endif
}
}
if (Cmp(storage, "typedef") == 0) {
Swig_save("cDeclaration", n, "type", NIL);
SwigType *t = Copy(type);
if (t) {
SwigType_push(t, decl);
Setattr(n, "type", t);
typedefHandler(n);
}
Swig_restore(n);
return SWIG_OK;
}
/* If in import mode, we proceed no further */
if (ImportMode)
return SWIG_NOWRAP;
/* If we're in extend mode and there is code, replace the $descriptor macros */
if (Extend) {
String *code = Getattr(n, "code");
if (code) {
Setfile(code, Getfile(n));
Setline(code, Getline(n));
Swig_cparse_replace_descriptor(code);
}
}
/* Overloaded symbol check */
over = Swig_symbol_isoverloaded(n);
if (!overloading) {
if (over)
over = first_nontemplate(over);
if (over && (over != n)) {
SwigType *tc = Copy(decl);
SwigType *td = SwigType_pop_function(tc);
String *oname;
String *cname;
if (CurrentClass) {
oname = NewStringf("%s::%s", ClassName, name);
cname = NewStringf("%s::%s", ClassName, Getattr(over, "name"));
} else {
oname = NewString(name);
cname = NewString(Getattr(over, "name"));
}
SwigType *tc2 = Copy(Getattr(over, "decl"));
SwigType *td2 = SwigType_pop_function(tc2);
Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", SwigType_str(td, SwigType_namestr(oname)));
Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", SwigType_str(td2, SwigType_namestr(cname)));
Delete(tc2);
Delete(td2);
Delete(tc);
Delete(td);
Delete(oname);
Delete(cname);
return SWIG_NOWRAP;
}
}
if (symname && !validIdentifier(symname)) {
Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", symname);
return SWIG_NOWRAP;
}
ty = NewString(type);
SwigType_push(ty, decl);
fullty = SwigType_typedef_resolve_all(ty);
if (SwigType_isfunction(fullty)) {
if (!SwigType_isfunction(ty)) {
Delete(ty);
ty = fullty;
fullty = 0;
ParmList *parms = SwigType_function_parms(ty);
Setattr(n, "parms", parms);
}
/* Transform the node into a 'function' node and emit */
if (!CurrentClass) {
f_header = Swig_filebyname("header");
if (AddExtern) {
if (f_header) {
if ((Cmp(storage, "extern") == 0) || (ForceExtern && !storage)) {
/* we don't need the 'extern' part in the C/C++ declaration,
and it produces some problems when namespace and SUN
Studio is used.
Printf(f_header,"extern %s", SwigType_str(ty,name));
In fact generating extern declarations is quite error prone and is
no longer the default. Getting it right seems impossible with namespaces
and default arguments and when a method is declared with the various Windows
calling conventions - SWIG doesn't understand Windows (non standard) calling
conventions in the first place, so can't regenerate them.
*/
String *str = SwigType_str(ty, name);
Printf(f_header, "%s", str);
Delete(str);
{
DOH *t = Getattr(n, "throws");
if (t) {
Printf(f_header, " throw(");
while (t) {
Printf(f_header, "%s", Getattr(t, "type"));
t = nextSibling(t);
if (t)
Printf(f_header, ",");
}
Printf(f_header, ")");
}
}
Printf(f_header, ";\n");
} else if (Cmp(storage, "externc") == 0) {
/* here 'extern "C"' is needed */
String *str = SwigType_str(ty, name);
Printf(f_header, "extern \"C\" %s;\n", str);
Delete(str);
}
}
}
}
/* This needs to check qualifiers */
if (SwigType_isqualifier(ty)) {
SwigType *qual = SwigType_pop(ty);
Setattr(n, "qualifier", qual);
Delete(qual);
}
Delete(SwigType_pop_function(ty));
DohIncref(type);
Setattr(n, "type", ty);
if (GetFlag(n, "feature:onlychildren") && !GetFlag(n, "feature:ignore")) {
// Found an unignored templated method that has a an empty template instantiation (%template())
// Ignore it unless it has been %rename'd
if (Strncmp(symname, "__dummy_", 8) == 0) {
SetFlag(n, "feature:ignore");
Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
"%%template() contains no name. Template method ignored: %s\n", SwigType_str(decl, SwigType_namestr(Getattr(n,"name"))));
}
}
if (!GetFlag(n, "feature:ignore"))
functionHandler(n);
Setattr(n, "type", type);
Delete(ty);
Delete(type);
return SWIG_OK;
} else {
/* Some kind of variable declaration */
String *declaration = Copy(decl);
Delattr(n, "decl");
if (Getattr(n, "nested"))
SetFlag(n, "feature:immutable");
if (!CurrentClass) {
if ((Cmp(storage, "extern") == 0) || ForceExtern) {
f_header = Swig_filebyname("header");
if (AddExtern) {
if (f_header) {
String *str = SwigType_str(ty, name);
Printf(f_header, "extern %s;\n", str);
Delete(str);
}
}
}
}
if (!SwigType_ismutable(ty)) {
SetFlag(n, "feature:immutable");
}
/* If an array and elements are const, then read-only */
if (SwigType_isarray(ty)) {
SwigType *tya = SwigType_array_type(ty);
if (SwigType_isconst(tya)) {
SetFlag(n, "feature:immutable");
}
Delete(tya);
}
DohIncref(type);
Setattr(n, "type", ty);
variableHandler(n);
Setattr(n, "type", type);
Setattr(n, "decl", declaration);
Delete(ty);
Delete(type);
Delete(fullty);
return SWIG_OK;
}
}
/* ----------------------------------------------------------------------
* Language::functionHandler()
* ---------------------------------------------------------------------- */
int Language::functionHandler(Node *n) {
String *storage = Getattr(n, "storage");
int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
int isstatic = CurrentClass && Cmp(storage, "static") == 0 && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
Parm *p = Getattr(n, "parms");
if (GetFlag(n, "feature:del")) {
/* the method acts like a delete operator, ie, we need to disown the parameter */
if (CurrentClass && !isstatic && !isfriend) {
SetFlag(n, "feature:self:disown");
} else {
if (p)
SetFlag(p, "wrap:disown");
}
}
if (!CurrentClass) {
globalfunctionHandler(n);
} else {
if (isstatic) {
staticmemberfunctionHandler(n);
} else if (isfriend) {
globalfunctionHandler(n);
} else {
Node *explicit_n = 0;
if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
if (virtual_but_not_pure_virtual) {
// Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
explicit_n = Copy(n);
String *new_symname = Copy(Getattr(n, "sym:name"));
String *suffix = Getattr(parentNode(n), "sym:name");
Printv(new_symname, "SwigExplicit", suffix, NIL);
Setattr(explicit_n, "sym:name", new_symname);
Delattr(explicit_n, "storage");
Delattr(explicit_n, "override");
Delattr(explicit_n, "hides");
SetFlag(explicit_n, "explicitcall");
Setattr(n, "explicitcallnode", explicit_n);
}
}
memberfunctionHandler(n);
if (explicit_n) {
memberfunctionHandler(explicit_n);
Delattr(explicit_n, "explicitcall");
Delete(explicit_n);
}
}
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::globalfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::globalfunctionHandler(Node *n) {
Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
/* Check for callback mode */
String *cb = GetFlagAttr(n, "feature:callback");
if (cb) {
String *cbname = Getattr(n, "feature:callback:name");
if (!cbname) {
cbname = NewStringf(cb, symname);
Setattr(n, "feature:callback:name", cbname);
}
callbackfunctionHandler(n);
if (Cmp(cbname, symname) == 0) {
Delete(cbname);
Swig_restore(n);
return SWIG_NOWRAP;
}
Delete(cbname);
}
Setattr(n, "parms", nonvoid_parms(parms));
String *call = Swig_cfunction_call(name, parms);
String *cres = Swig_cresult(type, "result", call);
Setattr(n, "wrap:action", cres);
Delete(cres);
Delete(call);
functionWrapper(n);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::callbackfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::callbackfunctionHandler(Node *n) {
Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL);
String *symname = Getattr(n, "sym:name");
String *type = Getattr(n, "type");
String *name = Getattr(n, "name");
String *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
String *cbname = Getattr(n, "feature:callback:name");
String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
SwigType *cbty = Copy(type);
SwigType_add_function(cbty, parms);
SwigType_add_pointer(cbty);
if (!cbname) {
cbname = NewStringf(cb, symname);
Setattr(n, "feature:callback:name", cbname);
}
Setattr(n, "sym:name", cbname);
Setattr(n, "type", cbty);
Setattr(n, "value", calltype);
Node *ns = Getattr(symbols, cbname);
if (!ns)
constantWrapper(n);
Delete(cbname);
Delete(cbty);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::memberfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::memberfunctionHandler(Node *n) {
Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL);
String *storage = Getattr(n, "storage");
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
ParmList *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
if (Cmp(storage, "virtual") == 0) {
if (Cmp(value, "0") == 0) {
IsVirtual = PURE_VIRTUAL;
} else {
IsVirtual = PLAIN_VIRTUAL;
}
} else {
IsVirtual = 0;
}
if (cb) {
Node *cbn = NewHash();
String *cbname = Getattr(n, "feature:callback:name");
if (!cbname) {
cbname = NewStringf(cb, symname);
}
SwigType *cbty = Copy(type);
SwigType_add_function(cbty, parms);
SwigType_add_memberpointer(cbty, ClassName);
String *cbvalue = NewStringf("&%s::%s", ClassName, name);
Setattr(cbn, "sym:name", cbname);
Setattr(cbn, "type", cbty);
Setattr(cbn, "value", cbvalue);
Setattr(cbn, "name", name);
memberconstantHandler(cbn);
Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname));
Delete(cb);
Delete(cbn);
Delete(cbvalue);
Delete(cbty);
Delete(cbname);
if (Cmp(cbname, symname) == 0) {
Swig_restore(n);
return SWIG_NOWRAP;
}
}
String *fname = Swig_name_member(ClassPrefix, symname);
if (Extend && SmartPointer) {
if (!Getattr(n, "classname")) {
Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase"));
}
}
// Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
// Note: protected director methods or when allprotected mode turned on.
String *director_type = 0;
if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || is_non_virtual_protected_access(n))) {
director_type = Copy(DirectorClassName);
String *qualifier = Getattr(n, "qualifier");
if (qualifier)
SwigType_push(director_type, qualifier);
SwigType_add_pointer(director_type);
}
int DirectorExtraCall = 0;
if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
if (extraDirectorProtectedCPPMethodsRequired())
DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
if (GetFlag(n, "explicitcall"))
DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
Swig_MethodToFunction(n, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
is_member_director(CurrentClass, n));
Setattr(n, "sym:name", fname);
functionWrapper(n);
Delete(director_type);
Delete(fname);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::staticmemberfunctionHandler()
* ---------------------------------------------------------------------- */
int Language::staticmemberfunctionHandler(Node *n) {
Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
Swig_save("staticmemberfunctionHandler", n, "storage", NIL);
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
String *cb = GetFlagAttr(n, "feature:callback");
String *cname, *mrename;
if (!Extend) {
Node *sb = Getattr(n, "cplus:staticbase");
String *sname = Getattr(sb, "name");
if (is_non_virtual_protected_access(n))
cname = NewStringf("%s::%s", DirectorClassName, name);
else
cname = NewStringf("%s::%s", sname, name);
} else {
String *mname = Swig_name_mangle(ClassName);
cname = Swig_name_member(mname, name);
Delete(mname);
}
mrename = Swig_name_member(ClassPrefix, symname);
if (Extend) {
String *code = Getattr(n, "code");
String *defaultargs = Getattr(n, "defaultargs");
String *mangled = Swig_name_mangle(mrename);
Delete(mrename);
mrename = mangled;
if (Getattr(n, "sym:overloaded") && code) {
Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
}
if (!defaultargs && code) {
/* Hmmm. An added static member. We have to create a little wrapper for this */
Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus, 0);
}
}
Setattr(n, "name", cname);
Setattr(n, "sym:name", mrename);
if (cb) {
String *cbname = NewStringf(cb, symname);
Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname));
Setattr(n, "feature:callback:staticname", name);
}
Delattr(n, "storage");
globalfunctionHandler(n);
Delete(cname);
Delete(mrename);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::variableHandler()
* ---------------------------------------------------------------------- */
int Language::variableHandler(Node *n) {
/* If not a smart-pointer access or added method. We clear
feature:except. There is no way C++ or C would throw
an exception merely for accessing a member data.
Caveat: Some compilers seem to route attribute access through
methods which can generate exceptions. The feature:allowexcept
allows this. Also, the feature:exceptvar can be used to match
only variables.
*/
if (!(Extend | SmartPointer)) {
if (!GetFlag(n, "feature:allowexcept")) {
UnsetFlag(n, "feature:except");
}
if (Getattr(n, "feature:exceptvar")) {
Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
}
}
if (!CurrentClass) {
globalvariableHandler(n);
} else {
String *storage = Getattr(n, "storage");
Swig_save("variableHandler", n, "feature:immutable", NIL);
if (SmartPointer) {
/* If a smart-pointer and it's a constant access, we have to set immutable */
if (Getattr(CurrentClass, "allocate:smartpointerconst")) {
SetFlag(n, "feature:immutable");
}
}
if ((Cmp(storage, "static") == 0) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
staticmembervariableHandler(n);
} else {
membervariableHandler(n);
}
Swig_restore(n);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::globalvariableHandler()
* ---------------------------------------------------------------------- */
int Language::globalvariableHandler(Node *n) {
variableWrapper(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::membervariableHandler()
* ---------------------------------------------------------------------- */
int Language::membervariableHandler(Node *n) {
Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
Swig_save("membervariableHandler", n, "parms", NIL);
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
if (!AttributeFunctionGet) {
String *mname = Swig_name_member(ClassPrefix, symname);
String *mrename_get = Swig_name_get(mname);
String *mrename_set = Swig_name_set(mname);
Delete(mname);
/* Create a function to set the value of the variable */
int assignable = is_assignable(n);
if (SmartPointer) {
if (Getattr(CurrentClass, "allocate:smartpointerconst")) {
assignable = 0;
}
}
if (assignable) {
int make_set_wrapper = 1;
String *tm = 0;
String *target = 0;
if (!Extend) {
if (SmartPointer) {
if (checkAttribute(n, "storage", "static")) {
Node *sn = Getattr(n, "cplus:staticbase");
String *base = Getattr(sn, "name");
target = NewStringf("%s::%s", base, name);
} else {
String *pname = Swig_cparm_name(0, 0);
target = NewStringf("(*%s)->%s", pname, name);
Delete(pname);
}
} else {
String *pname = is_non_virtual_protected_access(n) ? NewString("darg") : Swig_cparm_name(0, 0);
target = NewStringf("%s->%s", pname, name);
Delete(pname);
}
tm = Swig_typemap_lookup("memberin", n, target, 0);
}
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
if (is_non_virtual_protected_access(n))
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
Swig_MembersetToFunction(n, ClassType, flags);
Setattr(n, "memberset", "1");
if (!Extend) {
/* Check for a member in typemap here */
if (!tm) {
if (SwigType_isarray(type)) {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
make_set_wrapper = 0;
}
} else {
String *pname0 = Swig_cparm_name(0, 0);
String *pname1 = Swig_cparm_name(0, 1);
Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
Replace(tm, "$target", target, DOH_REPLACE_ANY);
Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
Setattr(n, "wrap:action", tm);
Delete(tm);
Delete(pname0);
Delete(pname1);
}
Delete(target);
}
if (make_set_wrapper) {
Setattr(n, "sym:name", mrename_set);
functionWrapper(n);
} else {
SetFlag(n, "feature:immutable");
}
/* Restore parameters */
Setattr(n, "type", type);
Setattr(n, "name", name);
Setattr(n, "sym:name", symname);
/* Delete all attached typemaps and typemap attributes */
Iterator ki;
for (ki = First(n); ki.key; ki = Next(ki)) {
if (Strncmp(ki.key, "tmap:", 5) == 0)
Delattr(n, ki.key);
}
}
/* Emit get function */
{
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
if (is_non_virtual_protected_access(n))
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
Swig_MembergetToFunction(n, ClassType, flags);
Setattr(n, "sym:name", mrename_get);
Setattr(n, "memberget", "1");
functionWrapper(n);
}
Delete(mrename_get);
Delete(mrename_set);
} else {
/* This code is used to support the attributefunction directive
where member variables are converted automagically to
accessor functions */
#if 0
Parm *p;
String *gname;
SwigType *vty;
p = NewParm(type, 0);
gname = NewStringf(AttributeFunctionGet, symname);
if (!Extend) {
ActionFunc = Copy(Swig_cmemberget_call(name, type));
cpp_member_func(Char(gname), Char(gname), type, 0);
Delete(ActionFunc);
} else {
String *cname = Swig_name_get(name);
cpp_member_func(Char(cname), Char(gname), type, 0);
Delete(cname);
}
Delete(gname);
if (!GetFlag(n, "feature:immutable")) {
gname = NewStringf(AttributeFunctionSet, symname);
vty = NewString("void");
if (!Extend) {
ActionFunc = Copy(Swig_cmemberset_call(name, type));
cpp_member_func(Char(gname), Char(gname), vty, p);
Delete(ActionFunc);
} else {
String *cname = Swig_name_set(name);
cpp_member_func(Char(cname), Char(gname), vty, p);
Delete(cname);
}
Delete(gname);
}
ActionFunc = 0;
#endif
}
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::staticmembervariableHandler()
* ---------------------------------------------------------------------- */
int Language::staticmembervariableHandler(Node *n) {
Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
String *value = Getattr(n, "value");
String *classname = !SmartPointer ? (is_non_virtual_protected_access(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
if (!value || !Getattr(n, "hasconsttype")) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
String *cname, *mrename;
/* Create the variable name */
mrename = Swig_name_member(ClassPrefix, symname);
cname = NewStringf("%s::%s", classname, name);
Setattr(n, "sym:name", mrename);
Setattr(n, "name", cname);
/* Wrap as an ordinary global variable */
variableWrapper(n);
Delete(mrename);
Delete(cname);
} else {
/* This is a C++ static member declaration with an initializer and it's const.
Certain C++ compilers optimize this out so that there is no linkage to a
memory address. Example:
class Foo {
public:
static const int x = 3;
};
Some discussion of this in section 9.4 of the C++ draft standard.
Also, we have to manage the case:
class Foo {
public:
%extend {
static const int x = 3;
}
};
in which there's no actual Foo::x variable to refer to. In this case,
the best we can do is to wrap the given value verbatim.
*/
String *name = Getattr(n, "name");
String *cname = NewStringf("%s::%s", classname, name);
if (Extend) {
/* the variable is a synthesized one.
There's nothing we can do; we just keep the given value */
} else {
/* we refer to the value as Foo::x */
String *value = SwigType_namestr(cname);
Setattr(n, "value", value);
}
SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type"));
SwigType *t2 = SwigType_strip_qualifiers(t1);
Setattr(n, "type", t2);
Delete(t1);
Delete(t2);
SetFlag(n, "wrappedasconstant");
memberconstantHandler(n);
Delete(cname);
}
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::externDeclaration()
* ---------------------------------------------------------------------- */
int Language::externDeclaration(Node *n) {
return emit_children(n);
}
/* ----------------------------------------------------------------------
* Language::enumDeclaration()
* ---------------------------------------------------------------------- */
int Language::enumDeclaration(Node *n) {
if (!ImportMode) {
emit_children(n);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::enumvalueDeclaration()
* ---------------------------------------------------------------------- */
int Language::enumvalueDeclaration(Node *n) {
if (CurrentClass && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
String *value = Getattr(n, "value");
String *name = Getattr(n, "name");
String *tmpValue;
if (value)
tmpValue = NewString(value);
else
tmpValue = NewString(name);
Setattr(n, "value", tmpValue);
if (!CurrentClass || !cparse_cplusplus) {
Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
constantWrapper(n);
} else {
memberconstantHandler(n);
}
Delete(tmpValue);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::enumforwardDeclaration()
* ---------------------------------------------------------------------- */
int Language::enumforwardDeclaration(Node *n) {
(void) n;
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* Language::memberconstantHandler()
* ----------------------------------------------------------------------------- */
int Language::memberconstantHandler(Node *n) {
Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL);
if (!GetFlag(n, "feature:allowexcept")) {
UnsetFlag(n, "feature:except");
}
if (Getattr(n, "feature:exceptvar")) {
Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
}
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
String *value = Getattr(n, "value");
String *mrename = Swig_name_member(ClassPrefix, symname);
Setattr(n, "sym:name", mrename);
String *new_name = 0;
if (Extend)
new_name = Copy(value);
else
new_name = NewStringf("%s::%s", is_non_virtual_protected_access(n) ? DirectorClassName : ClassName, name);
Setattr(n, "name", new_name);
constantWrapper(n);
Delete(mrename);
Delete(new_name);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::typedefHandler()
* ---------------------------------------------------------------------- */
int Language::typedefHandler(Node *n) {
/* since this is a recurring issue, we are going to remember the
typedef pointer, if already it is not a pointer or reference, as
in
typedef void NT;
int func(NT *p);
see director_basic.i for example.
*/
SwigType *name = Getattr(n, "name");
SwigType *decl = Getattr(n, "decl");
if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
SwigType *pname = Copy(name);
SwigType_add_pointer(pname);
SwigType_remember(pname);
Delete(pname);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorMethod()
* ---------------------------------------------------------------------- */
int Language::classDirectorMethod(Node *n, Node *parent, String *super) {
(void) n;
(void) parent;
(void) super;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorConstructor()
* ---------------------------------------------------------------------- */
int Language::classDirectorConstructor(Node *n) {
(void) n;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorDefaultConstructor()
* ---------------------------------------------------------------------- */
int Language::classDirectorDefaultConstructor(Node *n) {
(void) n;
return SWIG_OK;
}
static String *vtable_method_id(Node *n) {
String *nodeType = Getattr(n, "nodeType");
int is_destructor = (Cmp(nodeType, "destructor") == 0);
if (is_destructor)
return 0;
String *name = Getattr(n, "name");
String *decl = Getattr(n, "decl");
String *local_decl = SwigType_typedef_resolve_all(decl);
String *tmp = SwigType_pop_function(local_decl);
Delete(local_decl);
local_decl = tmp;
Node *method_id = NewStringf("%s|%s", name, local_decl);
Delete(local_decl);
return method_id;
}
/* ----------------------------------------------------------------------
* Language::unrollVirtualMethods()
* ---------------------------------------------------------------------- */
int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) {
Node *ni;
String *nodeType;
String *classname;
String *decl;
bool first_base = false;
// recurse through all base classes to build the vtable
List *bl = Getattr(n, "bases");
if (bl) {
Iterator bi;
for (bi = First(bl); bi.item; bi = Next(bi)) {
if (first_base && !director_multiple_inheritance)
break;
unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
first_base = true;
}
}
// recurse through all protected base classes to build the vtable, as needed
bl = Getattr(n, "protectedbases");
if (bl) {
Iterator bi;
for (bi = First(bl); bi.item; bi = Next(bi)) {
if (first_base && !director_multiple_inheritance)
break;
unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
first_base = true;
}
}
// find the methods that need directors
classname = Getattr(n, "name");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
/* we only need to check the virtual members */
if (!checkAttribute(ni, "storage", "virtual"))
continue;
nodeType = Getattr(ni, "nodeType");
/* we need to add methods(cdecl) and destructor (to check for throw decl) */
int is_destructor = (Cmp(nodeType, "destructor") == 0);
if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
decl = Getattr(ni, "decl");
/* extra check for function type and proper access */
if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(ni)) || need_nonpublic_member(ni))) {
String *name = Getattr(ni, "name");
Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(ni);
/* Make sure that the new method overwrites the existing: */
int len = Len(vm);
const int DO_NOT_REPLACE = -1;
int replace = DO_NOT_REPLACE;
for (int i = 0; i < len; i++) {
Node *item = Getitem(vm, i);
String *check_vmid = Getattr(item, "vmid");
if (Strcmp(method_id, check_vmid) == 0) {
replace = i;
break;
}
}
/* filling a new method item */
String *fqdname = NewStringf("%s::%s", classname, name);
Hash *item = NewHash();
Setattr(item, "fqdname", fqdname);
Node *m = Copy(ni);
/* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
SwigType *ty = NewString(Getattr(m, "type"));
SwigType_push(ty, decl);
if (SwigType_isqualifier(ty)) {
Delete(SwigType_pop(ty));
}
Delete(SwigType_pop_function(ty));
Setattr(m, "returntype", ty);
String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
/* apply the features of the original method found in the base class */
Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
Setattr(item, "methodNode", m);
Setattr(item, "vmid", method_id);
if (replace == DO_NOT_REPLACE)
Append(vm, item);
else
Setitem(vm, replace, item);
Delete(mname);
}
if (is_destructor) {
virtual_destructor = 1;
}
}
}
/*
We delete all the nodirector methods. This prevents the
generation of 'empty' director classes.
But this has to be done outside the previous 'for'
an the recursive loop!.
*/
if (n == parent) {
int len = Len(vm);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vm, i);
Node *m = Getattr(item, "methodNode");
/* retrieve the director features */
int mdir = GetFlag(m, "feature:director");
int mndir = GetFlag(m, "feature:nodirector");
/* 'nodirector' has precedence over 'director' */
int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
/* check if the method was found only in a base class */
Node *p = Getattr(m, "parentNode");
if (p != n) {
Node *c = Copy(m);
Setattr(c, "parentNode", n);
int cdir = GetFlag(c, "feature:director");
int cndir = GetFlag(c, "feature:nodirector");
dir = (cdir || cndir) ? (cdir && !cndir) : dir;
Delete(c);
}
if (dir) {
/* be sure the 'nodirector' feature is disabled */
if (mndir)
Delattr(m, "feature:nodirector");
} else {
/* or just delete from the vm, since is not a director method */
Delitem(vm, i);
len--;
i--;
}
}
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorDisown()
* ---------------------------------------------------------------------- */
int Language::classDirectorDisown(Node *n) {
Node *disown = NewHash();
String *mrename;
String *symname = Getattr(n, "sym:name");
mrename = Swig_name_disown(symname); //Getattr(n, "name"));
String *type = NewString(ClassType);
String *name = NewString("self");
SwigType_add_pointer(type);
Parm *p = NewParm(type, name);
Delete(name);
Delete(type);
type = NewString("void");
String *action = NewString("");
Printv(action, "{\n", "Swig::Director *director = dynamic_cast<Swig::Director *>(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL);
Setattr(disown, "wrap:action", action);
Setattr(disown, "name", mrename);
Setattr(disown, "sym:name", mrename);
Setattr(disown, "type", type);
Setattr(disown, "parms", p);
Delete(action);
Delete(mrename);
Delete(type);
Delete(p);
functionWrapper(disown);
Delete(disown);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorConstructors()
* ---------------------------------------------------------------------- */
int Language::classDirectorConstructors(Node *n) {
Node *ni;
String *nodeType;
Node *parent = Swig_methodclass(n);
int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
int protected_ctor = 0;
int constructor = 0;
/* emit constructors */
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
nodeType = Getattr(ni, "nodeType");
if (Cmp(nodeType, "constructor") == 0) {
Parm *parms = Getattr(ni, "parms");
if (is_public(ni)) {
/* emit public constructor */
classDirectorConstructor(ni);
constructor = 1;
if (default_ctor)
default_ctor = !ParmList_numrequired(parms);
} else {
/* emit protected constructor if needed */
if (need_nonpublic_ctor(ni)) {
classDirectorConstructor(ni);
constructor = 1;
protected_ctor = 1;
if (default_ctor)
default_ctor = !ParmList_numrequired(parms);
}
}
}
}
/* emit default constructor if needed */
if (!constructor) {
if (!default_ctor) {
/* we get here because the class has no public, protected or
default constructor, therefore, the director class can't be
created, ie, is kind of abstract. */
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name")));
return SWIG_OK;
}
classDirectorDefaultConstructor(n);
default_ctor = 1;
}
/* this is just to support old java behavior, ie, the default
constructor is always emitted, even when protected, and not
needed, since there is a public constructor already defined.
(scottm) This code is needed here to make the director_abstract +
test generate compileable code (Example2 in director_abastract.i).
(mmatus) This is very strange, since swig compiled with gcc3.2.3
doesn't need it here....
*/
if (!default_ctor && !protected_ctor) {
if (Getattr(parent, "allocate:default_base_constructor")) {
classDirectorDefaultConstructor(n);
}
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorMethods()
* ---------------------------------------------------------------------- */
int Language::classDirectorMethods(Node *n) {
Node *vtable = Getattr(n, "vtable");
int len = Len(vtable);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vtable, i);
String *method = Getattr(item, "methodNode");
String *fqdname = Getattr(item, "fqdname");
if (GetFlag(method, "feature:nodirector"))
continue;
String *type = Getattr(method, "nodeType");
if (!Cmp(type, "destructor")) {
classDirectorDestructor(method);
} else {
if (classDirectorMethod(method, n, fqdname) == SWIG_OK) {
Setattr(item, "director", "1");
}
}
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorInit()
* ---------------------------------------------------------------------- */
int Language::classDirectorInit(Node *n) {
(void) n;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorDestructor()
* ---------------------------------------------------------------------- */
int Language::classDirectorDestructor(Node *n) {
/*
Always emit the virtual destructor in the declaration and in the
compilation unit. Been explicit here can't make any damage, and
can solve some nasty C++ compiler problems.
*/
File *f_directors = Swig_filebyname("director");
File *f_directors_h = Swig_filebyname("director_h");
if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw () {\n}\n\n", DirectorClassName, DirectorClassName);
} else {
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirectorEnd()
* ---------------------------------------------------------------------- */
int Language::classDirectorEnd(Node *n) {
(void) n;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDirector()
* ---------------------------------------------------------------------- */
int Language::classDirector(Node *n) {
Node *module = Getattr(n, "module");
String *classtype = Getattr(n, "classtype");
Hash *directormap = 0;
if (module) {
directormap = Getattr(module, "wrap:directormap");
if (directormap == 0) {
directormap = NewHash();
Setattr(module, "wrap:directormap", directormap);
}
}
List *vtable = NewList();
int virtual_destructor = 0;
unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
// Emit all the using base::member statements for non virtual members (allprotected mode)
Node *ni;
String *using_protected_members_code = NewString("");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
Node *nodeType = Getattr(ni, "nodeType");
bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
if (is_non_virtual_protected_access(ni)) {
Node *overloaded = Getattr(ni, "sym:overloaded");
// emit the using base::member statement (but only once if the method is overloaded)
if (!overloaded || (overloaded && (overloaded == ni)))
Printf(using_protected_members_code, " using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name"));
}
}
}
if (virtual_destructor || Len(vtable) > 0) {
if (!virtual_destructor) {
String *classtype = Getattr(n, "classtype");
Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype);
}
Setattr(n, "vtable", vtable);
if (directormap != 0) {
Setattr(directormap, classtype, n);
}
classDirectorInit(n);
classDirectorConstructors(n);
classDirectorMethods(n);
File *f_directors_h = Swig_filebyname("director_h");
Printv(f_directors_h, using_protected_members_code, NIL);
classDirectorEnd(n);
}
Delete(vtable);
Delete(using_protected_members_code);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classDeclaration()
* ---------------------------------------------------------------------- */
static void addCopyConstructor(Node *n) {
Node *cn = NewHash();
set_nodeType(cn, "constructor");
Setattr(cn, "access", "public");
Setfile(cn, Getfile(n));
Setline(cn, Getline(n));
String *cname = Getattr(n, "name");
SwigType *type = Copy(cname);
String *last = Swig_scopename_last(cname);
String *name = NewStringf("%s::%s", cname, last);
String *cc = NewStringf("r.q(const).%s", type);
String *decl = NewStringf("f(%s).", cc);
String *csymname = Getattr(n, "sym:name");
String *oldname = csymname;
if (Getattr(n, "allocate:has_constructor")) {
// to work properly with '%rename Class', we must look
// for any other constructor in the class, which has not been
// renamed, and use its name as oldname.
Node *c;
for (c = firstChild(n); c; c = nextSibling(c)) {
const char *tag = Char(nodeType(c));
if (strcmp(tag, "constructor") == 0) {
String *cname = Getattr(c, "name");
String *csname = Getattr(c, "sym:name");
String *clast = Swig_scopename_last(cname);
if (Equal(csname, clast)) {
oldname = csname;
break;
}
}
}
}
String *symname = Swig_name_make(cn, cname, last, decl, oldname);
if (Strcmp(symname, "$ignore") != 0) {
if (!symname) {
symname = Copy(csymname);
}
Parm *p = NewParm(cc, "other");
Setattr(cn, "name", name);
Setattr(cn, "sym:name", symname);
SetFlag(cn, "feature:new");
Setattr(cn, "decl", decl);
Setattr(cn, "parentNode", n);
Setattr(cn, "parms", p);
Setattr(cn, "copy_constructor", "1");
Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
Node *on = Swig_symbol_add(symname, cn);
Swig_symbol_setscope(oldscope);
Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
if (on == cn) {
Node *access = NewHash();
set_nodeType(access, "access");
Setattr(access, "kind", "public");
appendChild(n, access);
appendChild(n, cn);
Setattr(n, "has_copy_constructor", "1");
Setattr(n, "copy_constructor_decl", decl);
Setattr(n, "allocate:copy_constructor", "1");
Delete(access);
}
}
Delete(cn);
Delete(last);
Delete(name);
Delete(decl);
Delete(symname);
}
static void addDefaultConstructor(Node *n) {
Node *cn = NewHash();
set_nodeType(cn, "constructor");
Setattr(cn, "access", "public");
Setfile(cn, Getfile(n));
Setline(cn, Getline(n));
String *cname = Getattr(n, "name");
String *last = Swig_scopename_last(cname);
String *name = NewStringf("%s::%s", cname, last);
String *decl = NewString("f().");
String *csymname = Getattr(n, "sym:name");
String *oldname = csymname;
String *symname = Swig_name_make(cn, cname, last, decl, oldname);
if (Strcmp(symname, "$ignore") != 0) {
if (!symname) {
symname = Copy(csymname);
}
Setattr(cn, "name", name);
Setattr(cn, "sym:name", symname);
SetFlag(cn, "feature:new");
Setattr(cn, "decl", decl);
Setattr(cn, "parentNode", n);
Setattr(cn, "default_constructor", "1");
Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
Node *on = Swig_symbol_add(symname, cn);
Swig_symbol_setscope(oldscope);
Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
if (on == cn) {
Node *access = NewHash();
set_nodeType(access, "access");
Setattr(access, "kind", "public");
appendChild(n, access);
appendChild(n, cn);
Setattr(n, "has_default_constructor", "1");
Setattr(n, "allocate:default_constructor", "1");
Delete(access);
}
}
Delete(cn);
Delete(last);
Delete(name);
Delete(decl);
Delete(symname);
}
static void addDestructor(Node *n) {
Node *cn = NewHash();
set_nodeType(cn, "destructor");
Setattr(cn, "access", "public");
Setfile(cn, Getfile(n));
Setline(cn, Getline(n));
String *cname = Getattr(n, "name");
String *last = Swig_scopename_last(cname);
Insert(last, 0, "~");
String *name = NewStringf("%s::%s", cname, last);
String *decl = NewString("f().");
String *symname = Swig_name_make(cn, cname, last, decl, 0);
if (Strcmp(symname, "$ignore") != 0) {
if (!symname) {
symname = NewStringf("~%s", Getattr(n, "sym:name"));
}
Setattr(cn, "name", name);
Setattr(cn, "sym:name", symname);
Setattr(cn, "decl", "f().");
Setattr(cn, "parentNode", n);
Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
Node *on = Swig_symbol_add(symname, cn);
Swig_symbol_setscope(oldscope);
Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
if (on == cn) {
Node *access = NewHash();
set_nodeType(access, "access");
Setattr(access, "kind", "public");
appendChild(n, access);
appendChild(n, cn);
Setattr(n, "has_destructor", "1");
Setattr(n, "allocate:destructor", "1");
Delete(access);
}
}
Delete(cn);
Delete(last);
Delete(name);
Delete(decl);
Delete(symname);
}
int Language::classDeclaration(Node *n) {
String *ochildren = Getattr(n, "feature:onlychildren");
if (ochildren) {
Setattr(n, "feature:emitonlychildren", ochildren);
emit_children(n);
Delattr(n, "feature:emitonlychildren");
SetFlag(n, "feature:ignore");
return SWIG_NOWRAP;
}
String *kind = Getattr(n, "kind");
String *name = Getattr(n, "name");
String *tdname = Getattr(n, "tdname");
String *symname = Getattr(n, "sym:name");
char *classname = tdname ? Char(tdname) : Char(name);
char *iname = Char(symname);
int strip = (tdname || CPlusPlus) ? 1 : 0;
if (!classname) {
Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
return SWIG_NOWRAP;
}
/* Check symbol name for template. If not renamed. Issue a warning */
if (!validIdentifier(symname)) {
Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
return SWIG_NOWRAP;
}
Swig_save("classDeclaration", n, "name", NIL);
Setattr(n, "name", classname);
if (Cmp(kind, "class") == 0) {
cplus_mode = PRIVATE;
} else {
cplus_mode = PUBLIC;
}
ClassName = NewString(classname);
ClassPrefix = NewString(iname);
if (strip) {
ClassType = NewString(classname);
} else {
ClassType = NewStringf("%s %s", kind, classname);
}
Setattr(n, "classtypeobj", Copy(ClassType));
Setattr(n, "classtype", SwigType_namestr(ClassType));
InClass = 1;
CurrentClass = n;
/* Call classHandler() here */
if (!ImportMode) {
int dir = 0;
if (directorsEnabled()) {
int ndir = GetFlag(n, "feature:director");
int nndir = GetFlag(n, "feature:nodirector");
/* 'nodirector' has precedence over 'director' */
dir = (ndir || nndir) ? (ndir && !nndir) : 0;
}
int abstract = !dir && abstractClassTest(n);
int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault"));
/* default constructor */
if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) {
addDefaultConstructor(n);
}
}
/* copy constructor */
if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor")
&& (Getattr(n, "allocate:copy_constructor"))
&& (!GetFlag(n, "feature:ignore"))) {
addCopyConstructor(n);
}
}
/* default destructor */
if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor"))
&& (Getattr(n, "allocate:default_destructor"))
&& (!GetFlag(n, "feature:ignore"))) {
addDestructor(n);
}
}
if (dir) {
DirectorClassName = NewStringf("SwigDirector_%s", symname);
classDirector(n);
}
/* check for abstract after resolving directors */
Abstract = abstractClassTest(n);
classHandler(n);
} else {
Abstract = abstractClassTest(n);
Language::classHandler(n);
}
InClass = 0;
CurrentClass = 0;
Delete(ClassType);
ClassType = 0;
Delete(ClassPrefix);
ClassPrefix = 0;
Delete(ClassName);
ClassName = 0;
Delete(DirectorClassName);
DirectorClassName = 0;
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classHandler()
* ---------------------------------------------------------------------- */
int Language::classHandler(Node *n) {
bool hasDirector = Swig_directorclass(n) ? true : false;
/* Emit all of the class members */
emit_children(n);
/* Look for smart pointer handling */
if (Getattr(n, "allocate:smartpointer")) {
List *methods = Getattr(n, "allocate:smartpointer");
cplus_mode = PUBLIC;
SmartPointer = CWRAP_SMART_POINTER;
Iterator c;
for (c = First(methods); c.item; c = Next(c)) {
emit_one(c.item);
}
SmartPointer = 0;
}
cplus_mode = PUBLIC;
/* emit director disown method */
if (hasDirector) {
classDirectorDisown(n);
/* Emit additional protected virtual methods - only needed if the language module
* codes logic in the C++ layer instead of the director proxy class method - primarily
* to catch public use of protected methods by the scripting languages. */
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
Node *vtable = Getattr(n, "vtable");
String *symname = Getattr(n, "sym:name");
AccessMode old_mode = cplus_mode;
cplus_mode = PROTECTED;
int len = Len(vtable);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vtable, i);
Node *method = Getattr(item, "methodNode");
SwigType *type = Getattr(method, "nodeType");
if (Strcmp(type, "cdecl") != 0)
continue;
if (GetFlag(method, "feature:ignore"))
continue;
String *methodname = Getattr(method, "sym:name");
String *wrapname = NewStringf("%s_%s", symname, methodname);
if (!Getattr(symbols, wrapname) && (!is_public(method))) {
Node *m = Copy(method);
Setattr(m, "director", "1");
Setattr(m, "parentNode", n);
cDeclaration(m);
Delete(m);
}
Delete(wrapname);
}
cplus_mode = old_mode;
}
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::classforwardDeclaration()
* ---------------------------------------------------------------------- */
int Language::classforwardDeclaration(Node *n) {
(void) n;
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::constructorDeclaration()
* ---------------------------------------------------------------------- */
int Language::constructorDeclaration(Node *n) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
if (!symname)
return SWIG_NOWRAP;
if (!CurrentClass)
return SWIG_NOWRAP;
if (ImportMode)
return SWIG_NOWRAP;
if (Extend) {
/* extend default constructor can be safely ignored if there is already one */
int num_required = ParmList_numrequired(Getattr(n, "parms"));
if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) {
return SWIG_NOWRAP;
}
if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) {
String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl");
if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) {
return SWIG_NOWRAP;
}
}
}
/* clean protected overloaded constructors, in case they are not needed anymore */
Node *over = Swig_symbol_isoverloaded(n);
if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) {
int dirclass = Swig_directorclass(CurrentClass);
Node *nn = over;
while (nn) {
if (!is_public(nn)) {
if (!dirclass || !need_nonpublic_ctor(nn)) {
SetFlag(nn, "feature:ignore");
}
}
nn = Getattr(nn, "sym:nextSibling");
}
clean_overloaded(over);
Setattr(CurrentClass, "sym:cleanconstructor", "1");
}
if ((cplus_mode != PUBLIC)) {
/* check only for director classes */
if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
return SWIG_NOWRAP;
}
/* Name adjustment for %name */
Swig_save("constructorDeclaration", n, "sym:name", NIL);
{
String *base = Swig_scopename_last(name);
if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
Setattr(n, "sym:name", ClassPrefix);
}
Delete(base);
}
/* Only create a constructor if the class is not abstract */
if (!Abstract) {
Node *over;
over = Swig_symbol_isoverloaded(n);
if (over)
over = first_nontemplate(over);
if ((over) && (!overloading)) {
/* If the symbol is overloaded. We check to see if it is a copy constructor. If so,
we invoke copyconstructorHandler() as a special case. */
if (Getattr(n, "copy_constructor") && (!Getattr(CurrentClass, "has_copy_constructor"))) {
copyconstructorHandler(n);
Setattr(CurrentClass, "has_copy_constructor", "1");
} else {
if (Getattr(over, "copy_constructor"))
over = Getattr(over, "sym:nextSibling");
if (over != n) {
Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
"Overloaded constructor ignored. %s\n", Swig_name_decl(n));
Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
"Previous declaration is %s\n", Swig_name_decl(over));
} else {
constructorHandler(n);
}
}
} else {
if (name && (Cmp(Swig_scopename_last(name), Swig_scopename_last(ClassName))) && !(Getattr(n, "template"))) {
Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type.\n", SwigType_namestr(name));
Swig_restore(n);
return SWIG_NOWRAP;
}
constructorHandler(n);
}
}
Setattr(CurrentClass, "has_constructor", "1");
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* get_director_ctor_code()
* ---------------------------------------------------------------------- */
static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstract) {
String *director_ctor = director_ctor_code;
int use_director = Swig_directorclass(n);
if (use_director) {
Node *pn = Swig_methodclass(n);
abstract = Getattr(pn, "abstract");
if (director_prot_ctor_code) {
int is_notabstract = GetFlag(pn, "feature:notabstract");
int is_abstract = abstract && !is_notabstract;
if (is_protected(n) || is_abstract) {
director_ctor = director_prot_ctor_code;
Delattr(pn, "abstract");
} else {
if (is_notabstract) {
Delattr(pn, "abstract");
} else {
abstract = 0;
}
}
}
}
return director_ctor;
}
/* ----------------------------------------------------------------------
* Language::constructorHandler()
* ---------------------------------------------------------------------- */
int Language::constructorHandler(Node *n) {
Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_construct(symname);
String *nodeType = Getattr(n, "nodeType");
int constructor = (!Cmp(nodeType, "constructor"));
List *abstract = 0;
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
director_prot_ctor_code,
abstract);
if (!constructor) {
/* if not originally a constructor, still handle it as one */
Setattr(n, "handled_as_constructor", "1");
}
Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
Swig_restore(n);
if (abstract)
Setattr(Swig_methodclass(n), "abstract", abstract);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::copyconstructorHandler()
* ---------------------------------------------------------------------- */
int Language::copyconstructorHandler(Node *n) {
Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_copyconstructor(symname);
List *abstract = 0;
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
director_prot_ctor_code,
abstract);
Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
Swig_restore(n);
if (abstract)
Setattr(Swig_methodclass(n), "abstract", abstract);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::destructorDeclaration()
* ---------------------------------------------------------------------- */
int Language::destructorDeclaration(Node *n) {
if (!CurrentClass)
return SWIG_NOWRAP;
if (cplus_mode != PUBLIC)
return SWIG_NOWRAP;
if (ImportMode)
return SWIG_NOWRAP;
if (Extend) {
/* extend destructor can be safetly ignored if there is already one */
if (Getattr(CurrentClass, "has_destructor")) {
return SWIG_NOWRAP;
}
}
Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
char *c = GetChar(n, "name");
if (c && (*c == '~'))
Setattr(n, "name", c + 1);
c = GetChar(n, "sym:name");
if (c && (*c == '~'))
Setattr(n, "sym:name", c + 1);
/* Name adjustment for %name */
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
if ((Strcmp(name, symname) == 0) || (Strcmp(symname, ClassPrefix) != 0)) {
Setattr(n, "sym:name", ClassPrefix);
}
destructorHandler(n);
Setattr(CurrentClass, "has_destructor", "1");
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::destructorHandler()
* ---------------------------------------------------------------------- */
int Language::destructorHandler(Node *n) {
Swig_require("destructorHandler", n, "?name", "*sym:name", NIL);
Swig_save("destructorHandler", n, "type", "parms", NIL);
String *symname = Getattr(n, "sym:name");
String *mrename;
char *csymname = Char(symname);
if (csymname && (*csymname == '~'))
csymname += 1;
mrename = Swig_name_destroy(csymname);
Swig_DestructorToFunction(n, ClassType, CPlusPlus, Extend);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::accessDeclaration()
* ---------------------------------------------------------------------- */
int Language::accessDeclaration(Node *n) {
String *kind = Getattr(n, "kind");
if (Cmp(kind, "public") == 0) {
cplus_mode = PUBLIC;
} else if (Cmp(kind, "private") == 0) {
cplus_mode = PRIVATE;
} else if (Cmp(kind, "protected") == 0) {
cplus_mode = PROTECTED;
}
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* Language::namespaceDeclaration()
* ----------------------------------------------------------------------------- */
int Language::namespaceDeclaration(Node *n) {
if (Getattr(n, "alias"))
return SWIG_OK;
if (Getattr(n, "unnamed"))
return SWIG_OK;
emit_children(n);
return SWIG_OK;
}
int Language::validIdentifier(String *s) {
char *c = Char(s);
while (*c) {
if (!(isalnum(*c) || (*c == '_')))
return 0;
c++;
}
return 1;
}
/* -----------------------------------------------------------------------------
* Language::usingDeclaration()
* ----------------------------------------------------------------------------- */
int Language::usingDeclaration(Node *n) {
if ((cplus_mode == PUBLIC)) {
Node *np = Copy(n);
Node *c;
for (c = firstChild(np); c; c = nextSibling(c)) {
/* it seems for some cases this is needed, like A* A::boo() */
if (CurrentClass)
Setattr(c, "parentNode", CurrentClass);
emit_one(c);
}
Delete(np);
}
return SWIG_OK;
}
/* Stubs. Language modules need to implement these */
/* ----------------------------------------------------------------------
* Language::doxygenComment()
* ---------------------------------------------------------------------- */
int Language::doxygenComment(Node *n){
String *comment = Getattr(n, "comment");
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::constantWrapper()
* ---------------------------------------------------------------------- */
int Language::constantWrapper(Node *n) {
String *name = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
String *str = SwigType_str(type, name);
Printf(stdout, "constantWrapper : %s = %s\n", str, value);
Delete(str);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::variableWrapper()
* ---------------------------------------------------------------------- */
int Language::variableWrapper(Node *n) {
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", NIL);
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *name = Getattr(n, "name");
/* If no way to set variables. We simply create functions */
int assignable = is_assignable(n);
int flags = use_naturalvar_mode(n);
if (!GetFlag(n, "wrappedasconstant"))
flags = flags | Extend;
if (assignable) {
int make_set_wrapper = 1;
String *tm = Swig_typemap_lookup("globalin", n, name, 0);
Swig_VarsetToFunction(n, flags);
String *sname = Swig_name_set(symname);
Setattr(n, "sym:name", sname);
Delete(sname);
if (!tm) {
if (SwigType_isarray(type)) {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
make_set_wrapper = 0;
}
} else {
String *pname0 = Swig_cparm_name(0, 0);
Replace(tm, "$source", pname0, DOH_REPLACE_ANY);
Replace(tm, "$target", name, DOH_REPLACE_ANY);
Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
Setattr(n, "wrap:action", tm);
Delete(tm);
Delete(pname0);
}
if (make_set_wrapper) {
functionWrapper(n);
}
/* Restore parameters */
Setattr(n, "sym:name", symname);
Setattr(n, "type", type);
Setattr(n, "name", name);
/* Delete all attached typemaps and typemap attributes */
Iterator ki;
for (ki = First(n); ki.key; ki = Next(ki)) {
if (Strncmp(ki.key, "tmap:", 5) == 0)
Delattr(n, ki.key);
}
}
Swig_VargetToFunction(n, flags);
String *gname = Swig_name_get(symname);
Setattr(n, "sym:name", gname);
Delete(gname);
functionWrapper(n);
Swig_restore(n);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* Language::functionWrapper()
* ---------------------------------------------------------------------- */
int Language::functionWrapper(Node *n) {
String *name = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
ParmList *parms = Getattr(n, "parms");
Printf(stdout, "functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms))));
Printf(stdout, " action : %s\n", Getattr(n, "wrap:action"));
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* Language::nativeWrapper()
* ----------------------------------------------------------------------------- */
int Language::nativeWrapper(Node *n) {
(void) n;
return SWIG_OK;
}
void Language::main(int argc, char *argv[]) {
(void) argc;
(void) argv;
}
/* -----------------------------------------------------------------------------
* Language::addSymbol()
*
* Adds a symbol entry. Returns 1 if the symbol is added successfully.
* Prints an error message and returns 0 if a conflict occurs.
* ----------------------------------------------------------------------------- */
int
Language::addSymbol(const String *s, const Node *n) {
Node *c = Getattr(symbols, s);
if (c && (c != n)) {
Swig_error(input_file, line_number, "'%s' is multiply defined in the generated module.\n", s);
Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
return 0;
}
Setattr(symbols, s, n);
return 1;
}
/* -----------------------------------------------------------------------------
* Language::symbolLookup()
* ----------------------------------------------------------------------------- */
Node *Language::symbolLookup(String *s) {
return Getattr(symbols, s);
}
/* -----------------------------------------------------------------------------
* Language::classLookup()
*
* Tries to locate a class from a type definition
* ----------------------------------------------------------------------------- */
Node *Language::classLookup(SwigType *s) {
Node *n = 0;
/* Look in hash of cached values */
n = Getattr(classtypes, s);
if (!n) {
Symtab *stab = 0;
// SwigType *lt = SwigType_ltype(s);
// SwigType *ty1 = SwigType_typedef_resolve_all(lt);
SwigType *ty1 = SwigType_typedef_resolve_all(s);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
// Printf(stdout, " stages... ty1: %s ty2: %s\n", ty1, ty2);
// Delete(lt);
Delete(ty1);
// lt = 0;
ty1 = 0;
String *base = SwigType_base(ty2);
Replaceall(base, "class ", "");
Replaceall(base, "struct ", "");
Replaceall(base, "union ", "");
String *prefix = SwigType_prefix(ty2);
/* Do a symbol table search on the base type */
while (!n) {
Hash *nstab;
n = Swig_symbol_clookup(base, stab);
if (!n)
break;
if (Strcmp(nodeType(n), "class") == 0)
break;
n = parentNode(n);
if (!n)
break;
nstab = Getattr(n, "sym:symtab");
n = 0;
if ((!nstab) || (nstab == stab)) {
break;
}
stab = nstab;
}
if (n) {
/* Found a match. Look at the prefix. We only allow
the cases where where we want a proxy class for the particular type */
if ((Len(prefix) == 0) || // simple type (pass by value)
(Strcmp(prefix, "p.") == 0) || // pointer
(Strcmp(prefix, "r.") == 0) || // reference
(Strcmp(prefix, "r.p.") == 0) || // pointer by reference
SwigType_prefix_is_simple_1D_array(prefix)) { // Simple 1D array (not arrays of pointers/references)
SwigType *cs = Copy(s);
Setattr(classtypes, cs, n);
Delete(cs);
} else {
n = 0;
}
}
Delete(ty2);
Delete(base);
Delete(prefix);
}
if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
n = 0;
}
return n;
}
/* -----------------------------------------------------------------------------
* Language::enumLookup()
*
* Finds and returns the Node containing the enum declaration for the (enum)
* type passed in.
* ----------------------------------------------------------------------------- */
Node *Language::enumLookup(SwigType *s) {
Node *n = 0;
/* Look in hash of cached values */
n = Getattr(enumtypes, s);
if (!n) {
Symtab *stab = 0;
SwigType *lt = SwigType_ltype(s);
SwigType *ty1 = SwigType_typedef_resolve_all(lt);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
Delete(lt);
Delete(ty1);
lt = 0;
ty1 = 0;
String *base = SwigType_base(ty2);
Replaceall(base, "enum ", "");
String *prefix = SwigType_prefix(ty2);
/* Look for type in symbol table */
while (!n) {
Hash *nstab;
n = Swig_symbol_clookup(base, stab);
if (!n)
break;
if (Strcmp(nodeType(n), "enum") == 0)
break;
n = parentNode(n);
if (!n)
break;
nstab = Getattr(n, "sym:symtab");
n = 0;
if ((!nstab) || (nstab == stab)) {
break;
}
stab = nstab;
}
if (n) {
/* Found a match. Look at the prefix. We only allow simple types. */
if (Len(prefix) == 0) { /* Simple type */
Setattr(enumtypes, Copy(s), n);
} else {
n = 0;
}
}
Delete(ty2);
Delete(base);
Delete(prefix);
}
if (n && (GetFlag(n, "feature:ignore"))) {
n = 0;
}
return n;
}
/* -----------------------------------------------------------------------------
* Language::allow_overloading()
* ----------------------------------------------------------------------------- */
void Language::allow_overloading(int val) {
overloading = val;
}
/* -----------------------------------------------------------------------------
* Language::allow_multiple_input()
* ----------------------------------------------------------------------------- */
void Language::allow_multiple_input(int val) {
multiinput = val;
}
/* -----------------------------------------------------------------------------
* Language::enable_cplus_runtime_mode()
* ----------------------------------------------------------------------------- */
void Language::enable_cplus_runtime_mode() {
cplus_runtime = 1;
}
/* -----------------------------------------------------------------------------
* Language::cplus_runtime_mode()
* ----------------------------------------------------------------------------- */
int Language::cplus_runtime_mode() {
return cplus_runtime;
}
/* -----------------------------------------------------------------------------
* Language::allow_directors()
* ----------------------------------------------------------------------------- */
void Language::allow_directors(int val) {
directors = val;
}
/* -----------------------------------------------------------------------------
* Language::directorsEnabled()
* ----------------------------------------------------------------------------- */
int Language::directorsEnabled() const {
return director_language && CPlusPlus && (directors || director_mode);
}
/* -----------------------------------------------------------------------------
* Language::allow_dirprot()
* ----------------------------------------------------------------------------- */
void Language::allow_dirprot(int val) {
director_protected_mode = val;
}
/* -----------------------------------------------------------------------------
* Language::allow_allprotected()
* ----------------------------------------------------------------------------- */
void Language::allow_allprotected(int val) {
all_protected_mode = val;
}
/* -----------------------------------------------------------------------------
* Language::dirprot_mode()
* ----------------------------------------------------------------------------- */
int Language::dirprot_mode() const {
return directorsEnabled() ? director_protected_mode : 0;
}
/* -----------------------------------------------------------------------------
* Language::need_nonpublic_ctor()
* ----------------------------------------------------------------------------- */
int Language::need_nonpublic_ctor(Node *n) {
/*
detects when a protected constructor is needed, which is always
the case if 'dirprot' mode is used. However, if that is not the
case, we will try to strictly emit what is minimal to don't break
the generated, while preserving compatibility with java, which
always try to emit the default constructor.
rules:
- when dirprot mode is used, the protected constructors are
always needed.
- the protected default constructor is always needed.
- if dirprot mode is not used, the protected constructors will be
needed only if:
- there is no any public constructor in the class, and
- there is no protected default constructor
In that case, all the declared protected constructors are
needed since we don't know which one to pick up.
Note: given all the complications here, I am always in favor to
always enable 'dirprot', since is the C++ idea of protected
members, and use %ignore for the method you don't whan to add in
the director class.
*/
if (directorsEnabled()) {
if (is_protected(n)) {
if (dirprot_mode()) {
/* when using dirprot mode, the protected constructors are
always needed */
return 1;
} else {
int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms"));
if (is_default_ctor) {
/* the default protected constructor is always needed, for java compatibility */
return 1;
} else {
/* check if there is a public constructor */
Node *parent = Swig_methodclass(n);
int public_ctor = Getattr(parent, "allocate:default_constructor")
|| Getattr(parent, "allocate:public_constructor");
if (!public_ctor) {
/* if not, the protected constructor will be needed only
if there is no protected default constructor declared */
int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor");
return no_prot_default_ctor;
}
}
}
}
}
return 0;
}
/* -----------------------------------------------------------------------------
* Language::need_nonpublic_member()
* ----------------------------------------------------------------------------- */
int Language::need_nonpublic_member(Node *n) {
if (directorsEnabled()) {
if (is_protected(n)) {
if (dirprot_mode()) {
/* when using dirprot mode, the protected members are always needed. */
return 1;
} else {
/* if the method is pure virtual, we need it. */
int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0);
return pure_virtual;
}
}
}
return 0;
}
/* -----------------------------------------------------------------------------
* Language::is_smart_pointer()
* ----------------------------------------------------------------------------- */
int Language::is_smart_pointer() const {
return SmartPointer;
}
/* -----------------------------------------------------------------------------
* Language::extraDirectorProtectedCPPMethodsRequired()
* ----------------------------------------------------------------------------- */
bool Language::extraDirectorProtectedCPPMethodsRequired() const {
return true;
}
/* -----------------------------------------------------------------------------
* Language::is_wrapping_class()
* ----------------------------------------------------------------------------- */
int Language::is_wrapping_class() {
return InClass;
}
/* -----------------------------------------------------------------------------
* Language::getCurrentClass()
* ----------------------------------------------------------------------------- */
Node *Language::getCurrentClass() const {
return CurrentClass;
}
/* -----------------------------------------------------------------------------
* Language::getClassName()
* ----------------------------------------------------------------------------- */
String *Language::getClassName() const {
return ClassName;
}
/* -----------------------------------------------------------------------------
* Language::getClassPrefix()
* ----------------------------------------------------------------------------- */
String *Language::getClassPrefix() const {
return ClassPrefix;
}
/* -----------------------------------------------------------------------------
* Language::getClassType()
* ----------------------------------------------------------------------------- */
String *Language::getClassType() const {
return ClassType;
}
/* -----------------------------------------------------------------------------
* Language::abstractClassTest()
* ----------------------------------------------------------------------------- */
//#define SWIG_DEBUG
int Language::abstractClassTest(Node *n) {
/* check for non public operator new */
if (GetFlag(n, "feature:notabstract"))
return 0;
if (Getattr(n, "allocate:nonew"))
return 1;
/* now check for the rest */
List *abstract = Getattr(n, "abstract");
if (!abstract)
return 0;
int labs = Len(abstract);
#ifdef SWIG_DEBUG
List *bases = Getattr(n, "allbases");
Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(bases));
#endif
if (!labs)
return 0; /*strange, but need to be fixed */
if (abstract && !directorsEnabled())
return 1;
if (!GetFlag(n, "feature:director"))
return 1;
Node *dirabstract = 0;
Node *vtable = Getattr(n, "vtable");
if (vtable) {
#ifdef SWIG_DEBUG
Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs);
#endif
for (int i = 0; i < labs; i++) {
Node *ni = Getitem(abstract, i);
Node *method_id = vtable_method_id(ni);
if (!method_id)
continue;
bool exists_item = false;
int len = Len(vtable);
for (int i = 0; i < len; i++) {
Node *item = Getitem(vtable, i);
String *check_item = Getattr(item, "vmid");
if (Strcmp(method_id, check_item) == 0) {
exists_item = true;
break;
}
}
#ifdef SWIG_DEBUG
Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0);
#endif
Delete(method_id);
if (!exists_item) {
dirabstract = ni;
break;
}
}
if (dirabstract) {
if (is_public(dirabstract)) {
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
"Director class '%s' is abstract, abstract method '%s' is not accesible, maybe due to multiple inheritance or 'nodirector' feature\n",
SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
} else {
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
"Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
}
return 1;
}
} else {
return 1;
}
return dirabstract ? 1 : 0;
}
void Language::setSubclassInstanceCheck(String *nc) {
none_comparison = nc;
}
void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
Delete(argc_template_string);
argc_template_string = Copy(argc);
Delete(argv_template_string);
argv_template_string = Copy(argv);
}
int Language::is_assignable(Node *n) {
if (GetFlag(n, "feature:immutable"))
return 0;
SwigType *type = Getattr(n, "type");
Node *cn = 0;
SwigType *ftd = SwigType_typedef_resolve_all(type);
SwigType *td = SwigType_strip_qualifiers(ftd);
if (SwigType_type(td) == T_USER) {
cn = Swig_symbol_clookup(td, 0);
if (cn) {
if ((Strcmp(nodeType(cn), "class") == 0)) {
if (Getattr(cn, "allocate:noassign")) {
SetFlag(n, "feature:immutable");
Delete(ftd);
Delete(td);
return 0;
}
}
}
}
Delete(ftd);
Delete(td);
return 1;
}
String *Language::runtimeCode() {
return NewString("");
}
String *Language::defaultExternalRuntimeFilename() {
return 0;
}
Hash *Language::getClassHash() const {
return classhash;
}