From 12a43edc2df8853e8e0315f742e57be88f0c4269 Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Sat, 30 Nov 2002 22:01:28 +0000 Subject: [PATCH] The great merge git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .cvsignore | 3 + ANNOUNCE | 95 +- CHANGES.current | 232 + Doc/{ => Devel}/engineering.html | 13 +- Doc/{ => Devel}/index.html | 1 - Doc/{ => Devel}/internals.html | 216 +- Doc/{ => Devel}/migrate.txt | 0 Doc/Manual/About.html | 54 + Doc/Manual/Advanced.html | 350 + Doc/Manual/Arguments.html | 427 + Doc/Manual/Contents.html | 946 ++ Doc/Manual/Copyright.html | 71 + Doc/Manual/Customization.html | 643 + Doc/Manual/Documentation.html | 17 + Doc/Manual/Extending.html | 2796 ++++ Doc/Manual/Guile.html | 456 + Doc/Manual/Introduction.html | 392 + Doc/Manual/Java.html | 3990 ++++++ Doc/Manual/Library.html | 1346 ++ Doc/Manual/Ocaml.html | 522 + Doc/Manual/Perl5.html | 2465 ++++ Doc/Manual/Php.html | 496 + Doc/Manual/Preface.html | 196 + Doc/Manual/Preprocessor.html | 302 + Doc/Manual/Python.html | 3311 +++++ Doc/Manual/README | 6 + Doc/Manual/Ruby.html | 3007 +++++ Doc/Manual/SWIG.html | 2631 ++++ Doc/Manual/SWIGPlus.html | 3408 +++++ Doc/Manual/Scripting.html | 439 + Doc/Manual/Tcl.html | 2930 ++++ Doc/Manual/Typemaps.html | 2764 ++++ Doc/Manual/Varargs.html | 831 ++ Doc/Manual/Warnings.html | 401 + Doc/Manual/Windows.html | 180 + Doc/Manual/ch11.1.png | Bin 0 -> 2492 bytes Doc/Manual/ch11.2.png | Bin 0 -> 2624 bytes Doc/Manual/ch11.3.png | Bin 0 -> 2942 bytes Doc/Manual/ch12.1.png | Bin 0 -> 3605 bytes Doc/Manual/ch2.1.png | Bin 0 -> 3146 bytes Doc/Manual/ch9.table.2.png | Bin 0 -> 3821 bytes Doc/Manual/chapters | 23 + Doc/Manual/index.html | 92 + Doc/Manual/makechap.py | 139 + Doc/Manual/maketoc.py | 36 + Doc/README | 5 + Doc/whitepaper.html | 363 - Examples/GIFPlot/.cvsignore | 1 + .../GIFPlot/{Java => Common-Lisp/full}/cmap | Bin Examples/GIFPlot/Common-Lisp/full/gifplot.i | 21 + Examples/GIFPlot/Common-Lisp/full/runme.lisp | 59 + Examples/GIFPlot/Guile/check.list | 3 + Examples/GIFPlot/Guile/full/.cvsignore | 3 + Examples/GIFPlot/Guile/full/Makefile | 9 +- Examples/GIFPlot/Guile/simple/.cvsignore | 4 + Examples/GIFPlot/Guile/simple/Makefile | 9 +- Examples/GIFPlot/Include/gifplot.h | 10 +- Examples/GIFPlot/Interface/gifplot.i | 39 +- Examples/GIFPlot/Java/Makefile | 18 - Examples/GIFPlot/Java/README | 30 - Examples/GIFPlot/Java/check.list | 4 + Examples/GIFPlot/Java/cm15 | Bin 768 -> 0 bytes Examples/GIFPlot/Java/full/.cvsignore | 7 + Examples/GIFPlot/Java/full/Makefile | 20 + Examples/GIFPlot/Java/full/README | 8 + Examples/GIFPlot/Java/full/cmap | Bin 0 -> 768 bytes Examples/GIFPlot/Java/full/gifplot.i | 15 + Examples/GIFPlot/Java/full/main.java | 75 + Examples/GIFPlot/Java/gifplot.i | 273 - Examples/GIFPlot/Java/ortho.java | 107 - Examples/GIFPlot/Java/shadow.java | 22 - Examples/GIFPlot/Java/shadow/.cvsignore | 7 + Examples/GIFPlot/Java/shadow/Makefile | 20 + Examples/GIFPlot/Java/shadow/README | 5 + Examples/GIFPlot/Java/shadow/cmap | Bin 0 -> 768 bytes Examples/GIFPlot/Java/shadow/main.java | 76 + Examples/GIFPlot/Java/simple.java | 22 - Examples/GIFPlot/Java/simple/.cvsignore | 7 + Examples/GIFPlot/Java/simple/Makefile | 21 + Examples/GIFPlot/Java/simple/README | 5 + Examples/GIFPlot/Java/simple/main.java | 41 + Examples/GIFPlot/Java/simple/simple.i | 38 + Examples/GIFPlot/LICENSE | 41 - Examples/GIFPlot/Lib/.cvsignore | 1 + Examples/GIFPlot/Lib/Makefile.in | 12 +- Examples/GIFPlot/Lib/pixmap.c | 4 +- Examples/GIFPlot/Makefile.in | 4 +- Examples/GIFPlot/Ocaml/check.list | 3 + Examples/GIFPlot/Ocaml/full/Makefile | 26 + Examples/GIFPlot/Ocaml/full/README | 8 + Examples/GIFPlot/Ocaml/full/cmap | Bin 0 -> 768 bytes Examples/GIFPlot/Ocaml/full/gifplot.i | 15 + Examples/GIFPlot/Ocaml/full/runme.ml | 86 + Examples/GIFPlot/Ocaml/simple/Makefile | 26 + Examples/GIFPlot/Ocaml/simple/cmap | Bin 0 -> 768 bytes Examples/GIFPlot/Ocaml/simple/runme.ml | 34 + Examples/GIFPlot/Ocaml/simple/simple.i | 33 + Examples/GIFPlot/Perl/check.list | 4 + Examples/GIFPlot/Perl/full/.cvsignore | 5 + Examples/GIFPlot/Perl/full/Makefile | 9 +- Examples/GIFPlot/Perl/shadow/.cvsignore | 5 + Examples/GIFPlot/Perl/shadow/Makefile | 9 +- Examples/GIFPlot/Perl/simple/.cvsignore | 5 + Examples/GIFPlot/Perl/simple/Makefile | 9 +- Examples/GIFPlot/Php/check.list | 3 + Examples/GIFPlot/Php/full/Makefile | 19 + Examples/GIFPlot/Php/full/README | 4 + Examples/GIFPlot/Php/full/cmap | Bin 0 -> 768 bytes Examples/GIFPlot/Php/full/gifplot.i | 15 + Examples/GIFPlot/Php/full/runme.php4 | 78 + Examples/GIFPlot/Php/shadow/Makefile | 19 + Examples/GIFPlot/Php/shadow/README | 2 + Examples/GIFPlot/Php/shadow/cmap | Bin 0 -> 768 bytes Examples/GIFPlot/Php/shadow/runme.php4 | 79 + Examples/GIFPlot/Php/simple/Makefile | 19 + Examples/GIFPlot/Php/simple/README | 5 + Examples/GIFPlot/Php/simple/runme.php4 | 32 + Examples/GIFPlot/Php/simple/simple.i | 38 + Examples/GIFPlot/Pike/check.list | 2 + Examples/GIFPlot/Pike/simple/.cvsignore | 4 + Examples/GIFPlot/Pike/simple/Makefile | 24 + Examples/GIFPlot/Pike/simple/README | 5 + Examples/GIFPlot/Pike/simple/runme.pike | 30 + Examples/GIFPlot/Pike/simple/simple.i | 38 + Examples/GIFPlot/Python/check.list | 4 + Examples/GIFPlot/Python/full/.cvsignore | 4 + Examples/GIFPlot/Python/full/Makefile | 12 +- Examples/GIFPlot/Python/full/runme.py | 4 +- Examples/GIFPlot/Python/shadow/.cvsignore | 6 + Examples/GIFPlot/Python/shadow/Makefile | 14 +- Examples/GIFPlot/Python/simple/.cvsignore | 4 + Examples/GIFPlot/Python/simple/Makefile | 10 +- Examples/GIFPlot/README | 4 +- Examples/GIFPlot/Ruby/check.list | 4 + Examples/GIFPlot/Ruby/full/.cvsignore | 4 + Examples/GIFPlot/Ruby/full/Makefile | 9 +- Examples/GIFPlot/Ruby/shadow/.cvsignore | 4 + Examples/GIFPlot/Ruby/shadow/Makefile | 9 +- Examples/GIFPlot/Ruby/simple/.cvsignore | 4 + Examples/GIFPlot/Ruby/simple/Makefile | 9 +- Examples/GIFPlot/Tcl/check.list | 4 + Examples/GIFPlot/Tcl/full/.cvsignore | 4 + Examples/GIFPlot/Tcl/full/Makefile | 9 +- Examples/GIFPlot/Tcl/mandel/.cvsignore | 4 + Examples/GIFPlot/Tcl/mandel/Makefile | 9 +- Examples/GIFPlot/Tcl/simple/.cvsignore | 4 + Examples/GIFPlot/Tcl/simple/Makefile | 9 +- Examples/GIFPlot/configure | 1299 -- Examples/GIFPlot/configure.in | 52 - Examples/Makefile.in | 479 +- Examples/README | 2 - Examples/guile/Makefile.in | 23 +- Examples/guile/README | 14 +- Examples/guile/check.list | 7 + Examples/guile/constants/.cvsignore | 2 + Examples/guile/constants/Makefile | 17 + Examples/guile/constants/constants.scm | 10 + Examples/guile/constants/example.i | 27 + Examples/guile/matrix/Makefile | 4 +- Examples/guile/matrix/README | 2 +- Examples/guile/matrix/matrix.c | 2 + Examples/guile/matrix/matrix.i | 3 +- Examples/guile/matrix/package.i | 3 +- Examples/guile/matrix/vector.c | 2 + Examples/guile/multimap/Makefile | 18 + Examples/guile/multimap/example.c | 53 + Examples/guile/multimap/example.i | 75 + Examples/guile/multimap/runme.scm | 30 + Examples/guile/multivalue/Makefile | 18 + Examples/guile/multivalue/example.c | 18 + Examples/guile/multivalue/example.i | 26 + Examples/guile/multivalue/runme.scm | 66 + Examples/guile/port/Makefile | 4 +- Examples/guile/port/port.i | 4 + Examples/guile/simple/Makefile | 11 +- Examples/guile/simple/README | 2 +- Examples/guile/simple/example.c | 2 +- Examples/guile/simple/example.scm | 33 +- Examples/guile/std_vector/.cvsignore | 1 + Examples/guile/std_vector/Makefile | 18 + Examples/guile/std_vector/example.h | 25 + Examples/guile/std_vector/example.i | 17 + Examples/guile/std_vector/runme.scm | 54 + Examples/index.html | 6 +- Examples/java/check.list | 14 + Examples/java/class/.cvsignore | 11 + Examples/java/class/Makefile | 18 + Examples/java/class/example.cxx | 28 + Examples/java/class/example.dsp | 162 + Examples/java/class/example.h | 39 + Examples/java/class/example.i | 10 + Examples/java/class/index.html | 199 + Examples/java/class/main.java | 70 + Examples/java/constants/.cvsignore | 11 + Examples/java/constants/Makefile | 18 + Examples/java/constants/example.i | 27 + Examples/java/constants/index.html | 53 + Examples/java/constants/main.java | 44 + Examples/java/enum/.cvsignore | 11 + Examples/java/enum/Makefile | 18 + Examples/java/enum/example.cxx | 37 + Examples/java/enum/example.h | 13 + Examples/java/enum/example.i | 13 + Examples/java/enum/index.html | 37 + Examples/java/enum/main.java | 39 + Examples/java/funcptr/.cvsignore | 11 + Examples/java/funcptr/Makefile | 18 + Examples/java/funcptr/example.c | 19 + Examples/java/funcptr/example.h | 7 + Examples/java/funcptr/example.i | 16 + Examples/java/funcptr/index.html | 93 + Examples/java/funcptr/main.java | 33 + Examples/java/index.html | 68 + Examples/java/mpointer/Makefile | 18 + Examples/java/mpointer/example.cxx | 45 + Examples/java/mpointer/example.h | 50 + Examples/java/mpointer/example.i | 16 + Examples/java/mpointer/main.java | 61 + Examples/java/multimap/.cvsignore | 11 + Examples/java/multimap/Makefile | 18 + Examples/java/multimap/example.c | 53 + Examples/java/multimap/example.i | 101 + Examples/java/multimap/main.java | 40 + Examples/java/native/.cvsignore | 11 + Examples/java/native/Makefile | 7 +- Examples/java/native/README | 6 - Examples/java/native/example.i | 14 +- Examples/java/native/index.html | 33 + Examples/java/native/main.java | 6 +- Examples/java/pointer/.cvsignore | 11 + Examples/java/pointer/Makefile | 18 + Examples/java/pointer/example.c | 16 + Examples/java/pointer/example.i | 24 + Examples/java/pointer/index.html | 167 + Examples/java/pointer/main.java | 55 + Examples/java/reference/.cvsignore | 11 + Examples/java/reference/Makefile | 18 + Examples/java/reference/example.cxx | 41 + Examples/java/reference/example.h | 26 + Examples/java/reference/example.i | 46 + Examples/java/reference/index.html | 149 + Examples/java/reference/main.java | 79 + Examples/java/simple/.cvsignore | 11 + Examples/java/simple/Makefile | 7 +- Examples/java/simple/README | 8 - Examples/java/simple/example.c | 30 +- Examples/java/simple/example.dsp | 158 + Examples/java/simple/example.i | 10 +- Examples/java/simple/index.html | 110 + Examples/java/simple/main.java | 36 +- Examples/java/template/.cvsignore | 11 + Examples/java/template/Makefile | 18 + Examples/java/template/example.h | 32 + Examples/java/template/example.i | 17 + Examples/java/template/index.html | 104 + Examples/java/template/main.java | 45 + Examples/java/typemap/.cvsignore | 11 + Examples/java/typemap/Makefile | 7 +- Examples/java/typemap/README | 8 - Examples/java/typemap/index.html | 34 + Examples/java/typemap/main.java | 3 +- Examples/java/variables/.cvsignore | 11 + Examples/java/variables/Makefile | 18 + Examples/java/variables/example.c | 86 + Examples/java/variables/example.h | 6 + Examples/java/variables/example.i | 44 + Examples/java/variables/index.html | 85 + Examples/java/variables/main.java | 98 + Examples/mzscheme/check.list | 3 + Examples/mzscheme/multimap/Makefile | 13 + Examples/mzscheme/multimap/example.c | 53 + Examples/mzscheme/multimap/example.i | 81 + Examples/mzscheme/multimap/example.scm | 27 + Examples/mzscheme/simple/.cvsignore | 1 + Examples/mzscheme/simple/Makefile | 2 +- Examples/mzscheme/std_vector/.cvsignore | 1 + Examples/mzscheme/std_vector/Makefile | 19 + Examples/mzscheme/std_vector/example.h | 25 + Examples/mzscheme/std_vector/example.i | 17 + Examples/mzscheme/std_vector/example.scm | 54 + Examples/ocaml/check.list | 2 + Examples/ocaml/simple/Makefile | 21 + Examples/ocaml/simple/example.c | 18 + Examples/ocaml/simple/example.dsp | 148 + Examples/ocaml/simple/example.i | 5 + Examples/ocaml/simple/example_prog.ml | 37 + Examples/ocaml/simple/index.html | 99 + Examples/perl5/check.list | 13 + Examples/perl5/class/.cvsignore | 10 + Examples/perl5/class/Makefile | 2 +- Examples/perl5/class/example.cxx | 10 +- Examples/perl5/class/example.dsp | 150 + Examples/perl5/class/example.h | 12 +- Examples/perl5/class/example.pl | 6 +- Examples/perl5/class/index.html | 29 +- Examples/perl5/constants/.cvsignore | 10 + Examples/perl5/constants/Makefile | 2 +- Examples/perl5/constants/example.i | 7 +- Examples/perl5/constants2/.cvsignore | 10 + Examples/perl5/constants2/Makefile | 18 + Examples/perl5/constants2/example.i | 27 + Examples/perl5/constants2/example.pl | 16 + Examples/perl5/funcptr/.cvsignore | 10 + Examples/perl5/funcptr/Makefile | 2 +- Examples/perl5/funcptr/example.c | 2 + Examples/perl5/funcptr/example.i | 7 +- Examples/perl5/import/.cvsignore | 14 + Examples/perl5/import/Makefile | 21 + Examples/perl5/import/README | 28 + Examples/perl5/import/bar.h | 22 + Examples/perl5/import/bar.i | 9 + Examples/perl5/import/base.h | 18 + Examples/perl5/import/base.i | 6 + Examples/perl5/import/foo.h | 21 + Examples/perl5/import/foo.i | 8 + Examples/perl5/import/runme.pl | 116 + Examples/perl5/import/spam.h | 24 + Examples/perl5/import/spam.i | 9 + Examples/perl5/index.html | 3 +- Examples/perl5/multimap/.cvsignore | 10 + Examples/perl5/multimap/Makefile | 18 + Examples/perl5/multimap/example.c | 53 + Examples/perl5/multimap/example.dsp | 146 + Examples/perl5/multimap/example.i | 81 + Examples/perl5/multimap/example.pl | 28 + Examples/perl5/pointer/.cvsignore | 10 + Examples/perl5/pointer/Makefile | 2 +- Examples/perl5/pointer/example.i | 3 +- Examples/perl5/pointer/example.pl | 16 +- Examples/perl5/reference/.cvsignore | 10 + Examples/perl5/reference/Makefile | 2 +- Examples/perl5/reference/example.i | 2 +- Examples/perl5/shadow/.cvsignore | 10 + Examples/perl5/shadow/Makefile | 2 +- Examples/perl5/shadow/example.cxx | 8 +- Examples/perl5/shadow/example.h | 14 +- Examples/perl5/shadow/example.pl | 21 +- Examples/perl5/simple/.cvsignore | 10 + Examples/perl5/simple/Makefile | 2 +- Examples/perl5/simple/example.dsp | 146 + Examples/perl5/value/.cvsignore | 10 + Examples/perl5/value/Makefile | 2 +- Examples/perl5/variables/.cvsignore | 10 + Examples/perl5/variables/Makefile | 2 +- Examples/perl5/variables/example.i | 4 +- Examples/perl5/variables/index.html | 10 +- Examples/php4/Makefile.php | 30 + Examples/php4/check.list | 13 + Examples/php4/class/BUILD.sh | 4 + Examples/php4/class/Makefile.old | 17 + Examples/php4/class/example.cxx | 28 + Examples/php4/class/example.h | 39 + Examples/php4/class/example.i | 10 + Examples/php4/class/runme.php4 | 58 + Examples/php4/constants/BUILD.sh | 4 + Examples/php4/constants/Makefile.old | 15 + Examples/php4/constants/example.i | 26 + Examples/php4/constants/runme.php4 | 28 + Examples/php4/enum/BUILD.sh | 4 + Examples/php4/enum/Makefile.old | 17 + Examples/php4/enum/example.cxx | 37 + Examples/php4/enum/example.h | 13 + Examples/php4/enum/example.i | 12 + Examples/php4/enum/runme.php4 | 32 + Examples/php4/funcptr/BUILD.sh | 4 + Examples/php4/funcptr/Makefile.old | 15 + Examples/php4/funcptr/example.c | 17 + Examples/php4/funcptr/example.h | 7 + Examples/php4/funcptr/example.i | 15 + Examples/php4/funcptr/runme.php4 | 24 + Examples/php4/pointer/BUILD.sh | 4 + Examples/php4/pointer/Makefile.old | 15 + Examples/php4/pointer/example.c | 16 + Examples/php4/pointer/example.i | 26 + Examples/php4/pointer/runme.php4 | 45 + Examples/php4/reference/BUILD.sh | 4 + Examples/php4/reference/Makefile.old | 17 + Examples/php4/reference/example.cxx | 44 + Examples/php4/reference/example.h | 26 + Examples/php4/reference/example.i | 44 + Examples/php4/reference/runme.php4 | 78 + Examples/php4/shadow/BUILD.sh | 4 + Examples/php4/shadow/Makefile.old | 16 + Examples/php4/shadow/example.cxx | 28 + Examples/php4/shadow/example.h | 43 + Examples/php4/shadow/example.i | 11 + Examples/php4/shadow/runme.php4 | 58 + Examples/php4/simple/BUILD.sh | 4 + Examples/php4/simple/Makefile.old | 15 + Examples/php4/simple/example.c | 18 + Examples/php4/simple/example.i | 5 + Examples/php4/simple/runme.php4 | 24 + Examples/php4/sync/BUILD.sh | 4 + Examples/php4/sync/Makefile.old | 15 + Examples/php4/sync/example.cxx | 13 + Examples/php4/sync/example.h | 9 + Examples/php4/sync/example.i | 7 + Examples/php4/sync/runme.php4 | 15 + Examples/php4/value/BUILD.sh | 4 + Examples/php4/value/Makefile.old | 15 + Examples/php4/value/example.c | 15 + Examples/php4/value/example.h | 5 + Examples/php4/value/example.i | 31 + Examples/php4/value/runme.php4 | 35 + Examples/php4/variables/BUILD.sh | 4 + Examples/php4/variables/Makefile.old | 15 + Examples/php4/variables/example.c | 90 + Examples/php4/variables/example.h | 6 + Examples/php4/variables/example.i | 45 + Examples/php4/variables/runme.php4 | 71 + Examples/php4/variables/runme.php4.old | 80 + Examples/pike/check.list | 8 + Examples/pike/class/.cvsignore | 9 + Examples/pike/class/Makefile | 19 + Examples/pike/class/example.cxx | 48 + Examples/pike/class/example.h | 35 + Examples/pike/class/example.i | 10 + Examples/pike/class/runme.pike | 61 + Examples/pike/constants/.cvsignore | 9 + Examples/pike/constants/Makefile | 18 + Examples/pike/constants/example.i | 27 + Examples/pike/constants/runme.pike | 24 + Examples/pike/enum/.cvsignore | 9 + Examples/pike/enum/Makefile | 19 + Examples/pike/enum/example.cxx | 37 + Examples/pike/enum/example.h | 13 + Examples/pike/enum/example.i | 11 + Examples/pike/enum/runme.pike | 27 + Examples/pike/overload/.cvsignore | 4 + Examples/pike/overload/Makefile | 19 + Examples/pike/overload/example.cxx | 115 + Examples/pike/overload/example.h | 41 + Examples/pike/overload/example.i | 28 + Examples/pike/overload/runme.pike | 83 + Examples/pike/simple/.cvsignore | 9 + Examples/pike/simple/Makefile | 18 + Examples/pike/simple/example.c | 18 + Examples/pike/simple/example.i | 5 + Examples/pike/simple/runme.pike | 20 + Examples/pike/template/.cvsignore | 1 + Examples/pike/template/Makefile | 20 + Examples/pike/template/example.h | 32 + Examples/pike/template/example.i | 17 + Examples/pike/template/runme.pike | 33 + Examples/python/check.list | 23 + Examples/python/class/.cvsignore | 9 + Examples/python/class/Makefile | 3 +- Examples/python/class/example.cxx | 10 +- Examples/python/class/example.dsp | 152 + Examples/python/class/example.h | 14 +- Examples/python/class/example.py | 67 - Examples/python/class/index.html | 41 +- Examples/python/class/runme.py | 51 + Examples/python/constants/.cvsignore | 9 + Examples/python/constants/Makefile | 3 +- Examples/python/constants/example.i | 16 +- .../python/constants/{example.py => runme.py} | 2 +- Examples/python/enum/.cvsignore | 9 + Examples/python/enum/Makefile | 3 +- Examples/python/enum/example.py | 30 - Examples/python/enum/runme.py | 31 + Examples/python/exception/Makefile | 20 + Examples/python/exception/example.h | 37 + Examples/python/exception/example.i | 12 + Examples/python/exception/runme.py | 29 + Examples/python/exceptshadow/.cvsignore | 10 + Examples/python/exceptshadow/Makefile | 21 + Examples/python/exceptshadow/example.h | 51 + Examples/python/exceptshadow/example.i | 83 + Examples/python/exceptshadow/runme.py | 45 + Examples/python/funcattr/.cvsignore | 10 + Examples/python/funcattr/Makefile | 21 + Examples/python/funcattr/example.i | 17 + Examples/python/funcattr/index.html | 22 + Examples/python/funcattr/runme.py | 17 + Examples/python/funcptr/.cvsignore | 9 + Examples/python/funcptr/Makefile | 3 +- Examples/python/funcptr/example.c | 2 + Examples/python/funcptr/example.i | 7 +- .../python/funcptr/{example.py => runme.py} | 0 Examples/python/funcptr2/.cvsignore | 9 + Examples/python/funcptr2/Makefile | 19 + Examples/python/funcptr2/example.c | 19 + Examples/python/funcptr2/example.h | 7 + Examples/python/funcptr2/example.i | 18 + Examples/python/funcptr2/runme.py | 20 + Examples/python/functor/.cvsignore | 10 + Examples/python/functor/Makefile | 21 + Examples/python/functor/example.i | 29 + Examples/python/functor/runme.py | 17 + Examples/python/import/.cvsignore | 13 + Examples/python/import/Makefile | 22 + Examples/python/import/README | 28 + Examples/python/import/bar.h | 22 + Examples/python/import/bar.i | 9 + Examples/python/import/base.h | 18 + Examples/python/import/base.i | 6 + Examples/python/import/foo.h | 21 + Examples/python/import/foo.i | 8 + Examples/python/import/runme.py | 111 + Examples/python/import/spam.h | 24 + Examples/python/import/spam.i | 9 + Examples/python/import_template/.cvsignore | 10 + Examples/python/import_template/Makefile | 22 + Examples/python/import_template/README | 30 + Examples/python/import_template/bar.h | 22 + Examples/python/import_template/bar.i | 11 + Examples/python/import_template/base.h | 18 + Examples/python/import_template/base.i | 7 + Examples/python/import_template/foo.h | 21 + Examples/python/import_template/foo.i | 10 + Examples/python/import_template/runme.py | 111 + Examples/python/import_template/spam.h | 24 + Examples/python/import_template/spam.i | 10 + Examples/python/index.html | 6 +- Examples/python/libffi/Makefile | 19 + Examples/python/libffi/example.i | 176 + Examples/python/mpointer/.cvsignore | 10 + Examples/python/mpointer/Makefile | 21 + Examples/python/mpointer/example.cxx | 45 + Examples/python/mpointer/example.h | 50 + Examples/python/mpointer/example.i | 16 + Examples/python/mpointer/runme.py | 51 + Examples/python/multimap/.cvsignore | 9 + Examples/python/multimap/Makefile | 19 + Examples/python/multimap/example.c | 53 + Examples/python/multimap/example.dsp | 148 + Examples/python/multimap/example.i | 83 + Examples/python/multimap/runme.py | 27 + Examples/python/operator/.cvsignore | 10 + Examples/python/operator/Makefile | 21 + Examples/python/operator/example.h | 36 + Examples/python/operator/example.i | 28 + Examples/python/operator/runme.py | 21 + Examples/python/overload_feature/.cvsignore | 2 + Examples/python/pointer/.cvsignore | 9 + Examples/python/pointer/Makefile | 3 +- Examples/python/pointer/example.i | 3 +- .../python/pointer/{example.py => runme.py} | 16 +- Examples/python/reference/.cvsignore | 9 + Examples/python/reference/Makefile | 3 +- Examples/python/reference/example.i | 4 +- .../python/reference/{example.py => runme.py} | 38 +- Examples/python/shadow/.cvsignore | 10 + Examples/python/shadow/Makefile | 12 +- Examples/python/simple/.cvsignore | 9 + Examples/python/simple/Makefile | 3 +- Examples/python/simple/example.dsp | 148 + .../python/simple/{example.py => runme.py} | 0 Examples/python/smartptr/Makefile | 21 + Examples/python/smartptr/example.cxx | 28 + Examples/python/smartptr/example.h | 39 + Examples/python/smartptr/example.i | 20 + Examples/python/smartptr/runme.py | 55 + Examples/python/smartptr/smartptr.h | 13 + Examples/python/std_vector/.cvsignore | 10 + Examples/python/std_vector/Makefile | 21 + Examples/python/std_vector/example.h | 25 + Examples/python/std_vector/example.i | 17 + Examples/python/std_vector/runme.py | 36 + Examples/python/template/.cvsignore | 10 + Examples/python/template/Makefile | 21 + Examples/python/template/example.h | 32 + Examples/python/template/example.i | 17 + Examples/python/template/runme.py | 34 + Examples/python/value/.cvsignore | 9 + Examples/python/value/Makefile | 3 +- Examples/python/varargs/Makefile | 19 + Examples/python/varargs/example.i | 65 + Examples/python/varargs/runme.py | 34 + Examples/python/variables/.cvsignore | 9 + Examples/python/variables/Makefile | 3 +- Examples/python/variables/example.i | 4 +- Examples/python/variables/index.html | 10 +- .../python/variables/{example.py => runme.py} | 0 Examples/ruby/check.list | 21 + Examples/ruby/class/.cvsignore | 9 + Examples/ruby/class/Makefile | 2 +- Examples/ruby/class/example.cxx | 10 +- Examples/ruby/class/example.dsp | 154 + Examples/ruby/class/example.h | 14 +- Examples/ruby/class/index.html | 20 - Examples/ruby/constants/.cvsignore | 9 + Examples/ruby/constants/Makefile | 2 +- Examples/ruby/constants/example.i | 7 +- Examples/ruby/constants/{run.rb => runme.rb} | 0 Examples/ruby/enum/.cvsignore | 9 + Examples/ruby/enum/Makefile | 2 +- Examples/ruby/funcptr/.cvsignore | 9 + Examples/ruby/funcptr/Makefile | 2 +- Examples/ruby/funcptr/example.i | 6 +- Examples/ruby/funcptr2/.cvsignore | 9 + Examples/ruby/funcptr2/Makefile | 18 + Examples/ruby/funcptr2/example.c | 19 + Examples/ruby/funcptr2/example.h | 7 + Examples/ruby/funcptr2/example.i | 18 + Examples/ruby/funcptr2/runme.rb | 18 + Examples/ruby/functor/.cvsignore | 2 + Examples/ruby/functor/Makefile | 18 + Examples/ruby/functor/example.i | 26 + Examples/ruby/functor/runme.rb | 17 + Examples/ruby/hashargs/.cvsignore | 1 + Examples/ruby/hashargs/Makefile | 20 + Examples/ruby/hashargs/example.i | 36 + Examples/ruby/hashargs/runme.rb | 26 + Examples/ruby/import/.cvsignore | 4 + Examples/ruby/import/Makefile | 20 + Examples/ruby/import/README | 28 + Examples/ruby/import/bar.h | 21 + Examples/ruby/import/bar.i | 9 + Examples/ruby/import/base.h | 16 + Examples/ruby/import/base.i | 6 + Examples/ruby/import/foo.h | 21 + Examples/ruby/import/foo.i | 8 + Examples/ruby/import/runme.rb | 90 + Examples/ruby/import/spam.h | 24 + Examples/ruby/import/spam.i | 9 + Examples/ruby/import_template/.cvsignore | 4 + Examples/ruby/import_template/Makefile | 20 + Examples/ruby/import_template/README | 30 + Examples/ruby/import_template/bar.h | 22 + Examples/ruby/import_template/bar.i | 11 + Examples/ruby/import_template/base.h | 18 + Examples/ruby/import_template/base.i | 7 + Examples/ruby/import_template/foo.h | 21 + Examples/ruby/import_template/foo.i | 10 + Examples/ruby/import_template/runme.rb | 92 + Examples/ruby/import_template/spam.h | 24 + Examples/ruby/import_template/spam.i | 10 + Examples/ruby/index.html | 6 +- Examples/ruby/mpointer/.cvsignore | 2 + Examples/ruby/mpointer/Makefile | 20 + Examples/ruby/mpointer/example.cxx | 45 + Examples/ruby/mpointer/example.h | 47 + Examples/ruby/mpointer/example.i | 15 + Examples/ruby/mpointer/runme.rb | 48 + Examples/ruby/multimap/.cvsignore | 2 + Examples/ruby/multimap/Makefile | 18 + Examples/ruby/multimap/example.c | 53 + Examples/ruby/multimap/example.dsp | 150 + Examples/ruby/multimap/example.i | 83 + Examples/ruby/multimap/runme.rb | 22 + Examples/ruby/operator/.cvsignore | 2 + Examples/ruby/operator/Makefile | 20 + Examples/ruby/operator/example.h | 36 + Examples/ruby/operator/example.i | 23 + Examples/ruby/operator/runme.rb | 25 + Examples/ruby/overloading/.cvsignore | 1 + Examples/ruby/overloading/Makefile | 19 + Examples/ruby/overloading/example.cxx | 125 + Examples/ruby/overloading/example.h | 41 + Examples/ruby/overloading/example.i | 24 + Examples/ruby/overloading/runme.rb | 88 + Examples/ruby/pointer/.cvsignore | 9 + Examples/ruby/pointer/Makefile | 2 +- Examples/ruby/pointer/example.i | 3 +- Examples/ruby/pointer/runme.rb | 17 +- Examples/ruby/reference/.cvsignore | 9 + Examples/ruby/reference/Makefile | 2 +- Examples/ruby/reference/example.i | 2 +- Examples/ruby/simple/.cvsignore | 9 + Examples/ruby/simple/Makefile | 2 +- Examples/ruby/simple/example.dsp | 150 + Examples/ruby/simple/{run.rb => runme.rb} | 0 Examples/ruby/std_vector/.cvsignore | 1 + Examples/ruby/std_vector/Makefile | 20 + Examples/ruby/std_vector/example.h | 25 + Examples/ruby/std_vector/example.i | 17 + Examples/ruby/std_vector/runme.rb | 36 + Examples/ruby/template/.cvsignore | 9 + Examples/ruby/template/Makefile | 20 + Examples/ruby/template/example.h | 32 + Examples/ruby/template/example.i | 17 + Examples/ruby/template/runme.rb | 25 + Examples/ruby/value/.cvsignore | 9 + Examples/ruby/value/Makefile | 2 +- Examples/ruby/variables/.cvsignore | 9 + Examples/ruby/variables/Makefile | 2 +- Examples/ruby/variables/example.i | 4 +- Examples/ruby/variables/index.html | 10 +- Examples/ruby/variables/runme.rb | 38 +- Examples/s-exp/uffi.lisp | 349 + Examples/tcl/check.list | 13 + Examples/tcl/class/.cvsignore | 9 + Examples/tcl/class/Makefile | 2 +- Examples/tcl/class/example.cxx | 10 +- Examples/tcl/class/example.dsp | 152 + Examples/tcl/class/example.h | 12 +- Examples/tcl/class/example1.tcl | 7 +- Examples/tcl/class/example2.tcl | 2 +- Examples/tcl/class/index.html | 29 +- Examples/tcl/constants/.cvsignore | 9 + Examples/tcl/constants/Makefile | 2 +- Examples/tcl/constants/example.i | 7 +- Examples/tcl/enum/.cvsignore | 9 + Examples/tcl/enum/Makefile | 2 +- Examples/tcl/funcptr/.cvsignore | 9 + Examples/tcl/funcptr/Makefile | 2 +- Examples/tcl/funcptr/example.c | 2 + Examples/tcl/funcptr/example.i | 7 +- Examples/tcl/import/.cvsignore | 4 + Examples/tcl/import/Makefile | 22 + Examples/tcl/import/README | 28 + Examples/tcl/import/bar.h | 22 + Examples/tcl/import/bar.i | 9 + Examples/tcl/import/base.h | 18 + Examples/tcl/import/base.i | 6 + Examples/tcl/import/foo.h | 21 + Examples/tcl/import/foo.i | 8 + Examples/tcl/import/runme.tcl | 121 + Examples/tcl/import/spam.h | 24 + Examples/tcl/import/spam.i | 9 + Examples/tcl/index.html | 4 + Examples/tcl/multimap/.cvsignore | 9 + Examples/tcl/multimap/Makefile | 19 + Examples/tcl/multimap/example.c | 53 + Examples/tcl/multimap/example.dsp | 148 + Examples/tcl/multimap/example.i | 68 + Examples/tcl/multimap/example.tcl | 25 + Examples/tcl/operator/.cvsignore | 9 + Examples/tcl/operator/Makefile | 19 + Examples/tcl/operator/example.h | 36 + Examples/tcl/operator/example.i | 28 + Examples/tcl/operator/runme.tcl | 31 + Examples/tcl/pointer/.cvsignore | 9 + Examples/tcl/pointer/Makefile | 2 +- Examples/tcl/pointer/example.i | 4 +- Examples/tcl/pointer/example.tcl | 17 +- Examples/tcl/reference/.cvsignore | 9 + Examples/tcl/reference/Makefile | 2 +- Examples/tcl/reference/example.i | 2 +- Examples/tcl/simple/.cvsignore | 9 + Examples/tcl/simple/Makefile | 2 +- Examples/tcl/simple/example.dsp | 148 + Examples/tcl/value/.cvsignore | 9 + Examples/tcl/value/Makefile | 2 +- Examples/tcl/variables/.cvsignore | 9 + Examples/tcl/variables/Makefile | 2 +- Examples/tcl/variables/example.i | 8 +- Examples/tcl/variables/index.html | 10 +- Examples/test-suite/README | 42 + Examples/test-suite/abstract_inherit.i | 20 + Examples/test-suite/abstract_inherit_ok.i | 21 + Examples/test-suite/abstract_signature.i | 25 + Examples/test-suite/abstract_typedef.i | 52 + Examples/test-suite/add_link.i | 20 + Examples/test-suite/anonymous_arg.i | 12 + Examples/test-suite/argout.i | 37 + Examples/test-suite/arrayptr.i | 12 + Examples/test-suite/arrays.i | 52 + Examples/test-suite/arrays_global.i | 37 + Examples/test-suite/arrays_global_twodim.i | 42 + Examples/test-suite/arrays_scope.i | 19 + Examples/test-suite/bool_default.i | 9 + Examples/test-suite/casts.i | 21 + Examples/test-suite/char_constant.i | 11 + Examples/test-suite/class_ignore.i | 20 + Examples/test-suite/common.mk | 291 + Examples/test-suite/const_const.i | 13 + Examples/test-suite/const_const_2.i | 21 + Examples/test-suite/constant_pointers.i | 74 + Examples/test-suite/constover.i | 38 + Examples/test-suite/constructor_exception.i | 27 + Examples/test-suite/constructor_explicit.i | 13 + Examples/test-suite/constructor_value.i | 15 + Examples/test-suite/conversion.i | 11 + Examples/test-suite/conversion_namespace.i | 14 + Examples/test-suite/conversion_ns_template.i | 49 + Examples/test-suite/cplusplus_throw.i | 22 + Examples/test-suite/cpp_enum.i | 27 + Examples/test-suite/cpp_enum_scope.i | 17 + Examples/test-suite/cpp_namespace.i | 104 + Examples/test-suite/cpp_nodefault.i | 42 + Examples/test-suite/cpp_static.i | 24 + Examples/test-suite/cpp_typedef.i | 46 + Examples/test-suite/default_cast.i | 6 + Examples/test-suite/default_constructor.i | 109 + Examples/test-suite/default_ns.i | 23 + Examples/test-suite/default_ref.i | 12 + Examples/test-suite/defineop.i | 22 + Examples/test-suite/defines.i | 18 + Examples/test-suite/dynamic_cast.i | 65 + Examples/test-suite/enum.i | 26 + Examples/test-suite/enum_scope.i | 16 + Examples/test-suite/enum_scope_template.i | 20 + Examples/test-suite/enum_var.i | 8 + Examples/test-suite/errors/c_bad_name.i | 4 + Examples/test-suite/errors/c_bad_native.i | 5 + Examples/test-suite/errors/c_class.i | 8 + Examples/test-suite/errors/c_default_error.i | 4 + Examples/test-suite/errors/c_deprecated.i | 8 + Examples/test-suite/errors/c_empty_char.i | 4 + Examples/test-suite/errors/c_enum_badvalue.i | 7 + Examples/test-suite/errors/c_extra_rblock.i | 8 + Examples/test-suite/errors/c_extra_rbrace.i | 7 + Examples/test-suite/errors/c_extra_unsigned.i | 6 + Examples/test-suite/errors/c_insert_missing.i | 3 + Examples/test-suite/errors/c_long_short.i | 6 + Examples/test-suite/errors/c_missing_rbrace.i | 10 + Examples/test-suite/errors/c_missing_semi.i | 4 + Examples/test-suite/errors/c_redefine.i | 20 + Examples/test-suite/errors/c_varargs.i | 3 + Examples/test-suite/errors/c_varargs_neg.i | 7 + Examples/test-suite/errors/cpp_bad_extern.i | 7 + .../test-suite/errors/cpp_extend_redefine.i | 23 + .../test-suite/errors/cpp_extend_undefined.i | 6 + .../test-suite/errors/cpp_inline_namespace.i | 7 + .../test-suite/errors/cpp_missing_rtemplate.i | 11 + .../test-suite/errors/cpp_namespace_alias.i | 14 + .../errors/cpp_namespace_aliasnot.i | 4 + .../errors/cpp_namespace_aliasundef.i | 3 + Examples/test-suite/errors/cpp_nested.i | 13 + Examples/test-suite/errors/cpp_no_access.i | 4 + Examples/test-suite/errors/cpp_nobase.i | 7 + Examples/test-suite/errors/cpp_overload.i | 15 + .../test-suite/errors/cpp_private_defvalue.i | 7 + .../test-suite/errors/cpp_private_inherit.i | 11 + .../test-suite/errors/cpp_template_argname.i | 8 + .../test-suite/errors/cpp_template_nargs.i | 10 + Examples/test-suite/errors/cpp_template_not.i | 9 + .../test-suite/errors/cpp_template_partial.i | 4 + .../test-suite/errors/cpp_template_repeat.i | 7 + .../test-suite/errors/cpp_template_undef.i | 7 + Examples/test-suite/errors/cpp_using_not.i | 9 + Examples/test-suite/errors/cpp_using_undef.i | 9 + Examples/test-suite/errors/make.sh | 103 + Examples/test-suite/errors/nomodule.i | 2 + Examples/test-suite/errors/pp_badeval.i | 11 + Examples/test-suite/errors/pp_defined.i | 7 + Examples/test-suite/errors/pp_macro_args.i | 7 + Examples/test-suite/errors/pp_macro_badchar.i | 5 + Examples/test-suite/errors/pp_macro_nargs.i | 16 + Examples/test-suite/errors/pp_macro_redef.i | 8 + Examples/test-suite/errors/pp_macro_rparen.i | 3 + .../test-suite/errors/pp_macro_unterminated.i | 7 + .../test-suite/errors/pp_misplaced_elif.i | 7 + .../test-suite/errors/pp_misplaced_else.i | 7 + .../test-suite/errors/pp_missing_enddef.i | 7 + Examples/test-suite/errors/pp_missing_endif.i | 6 + Examples/test-suite/errors/pp_missing_file.i | 3 + .../test-suite/errors/pp_missing_rblock.i | 7 + Examples/test-suite/errors/pp_unterm_char.i | 7 + .../test-suite/errors/pp_unterm_comment.i | 6 + Examples/test-suite/errors/pp_unterm_string.i | 6 + Examples/test-suite/errors/swig_apply_nargs.i | 6 + Examples/test-suite/errors/swig_identifier.i | 6 + Examples/test-suite/errors/swig_insert_bad.i | 5 + .../test-suite/errors/swig_typemap_copy.i | 3 + Examples/test-suite/errors/swig_typemap_old.i | 6 + Examples/test-suite/evil_diamond.i | 23 + Examples/test-suite/evil_diamond_ns.i | 24 + Examples/test-suite/evil_diamond_prop.i | 36 + Examples/test-suite/explicit.i | 15 + Examples/test-suite/extend_template.i | 26 + Examples/test-suite/extend_template_ns.i | 32 + Examples/test-suite/grouping.i | 31 + Examples/test-suite/guile/.cvsignore | 2 + Examples/test-suite/guile/Makefile | 44 + Examples/test-suite/guile/README | 4 + Examples/test-suite/guile/casts_runme.scm | 13 + .../test-suite/guile/char_constant_runme.scm | 9 + Examples/test-suite/guile/imports_runme.scm | 19 + .../test-suite/guile/list_vector_runme.scm | 28 + .../test-suite/guile/multivalue_runme.scm | 24 + Examples/test-suite/guile/name_runme.scm | 10 + .../guile/overload_complicated_runme.scm | 18 + .../guile/overload_simple_runme.scm | 56 + .../guile/overload_subtype_runme.scm | 12 + .../test-suite/guile/pointer_in_out_runme.scm | 18 + Examples/test-suite/guile/unions_runme.scm | 41 + Examples/test-suite/ignore_parameter.i | 42 + Examples/test-suite/import_nomodule.h | 2 + Examples/test-suite/import_nomodule.i | 24 + Examples/test-suite/imports.list | 2 + Examples/test-suite/imports_a.h | 7 + Examples/test-suite/imports_a.i | 12 + Examples/test-suite/imports_b.h | 11 + Examples/test-suite/imports_b.i | 14 + Examples/test-suite/inherit_missing.i | 43 + Examples/test-suite/java/.cvsignore | 185 + Examples/test-suite/java/Makefile | 72 + Examples/test-suite/java/README | 6 + .../java/arrays_global_twodim_runme.java | 33 + .../test-suite/java/cpp_typedef_runme.java | 30 + .../test-suite/java/dynamic_cast_runme.java | 29 + .../java/ignore_parameter_runme.java | 36 + Examples/test-suite/java/imports_runme.java | 24 + .../test-suite/java/java_constants_runme.java | 29 + .../test-suite/java/java_jnitypes_runme.java | 57 + .../java/java_lib_arrays_runme.java | 150 + .../test-suite/java/java_pragmas_runme.java | 15 + .../test-suite/java/java_throws_runme.java | 46 + .../java/java_typemaps_proxy_runme.java | 48 + .../java/java_typemaps_typewrapper_runme.java | 45 + .../test-suite/java/lib_typemaps_runme.java | 85 + Examples/test-suite/java/long_long_runme.java | 50 + .../test-suite/java/primitive_ref_runme.java | 64 + .../test-suite/java/ret_by_value_runme.java | 33 + .../java/template_classes_runme.java | 25 + Examples/test-suite/java/unions_runme.java | 68 + Examples/test-suite/java_constants.i | 30 + Examples/test-suite/java_jnitypes.i | 29 + Examples/test-suite/java_lib_arrays.i | 11 + Examples/test-suite/java_pragmas.i | 48 + Examples/test-suite/java_throws.i | 41 + Examples/test-suite/java_typemaps_proxy.i | 53 + .../test-suite/java_typemaps_typewrapper.i | 57 + Examples/test-suite/kind.i | 34 + Examples/test-suite/lib_carrays.i | 9 + Examples/test-suite/lib_cdata.i | 8 + Examples/test-suite/lib_cmalloc.i | 12 + Examples/test-suite/lib_constraints.i | 32 + Examples/test-suite/lib_cpointer.i | 10 + Examples/test-suite/lib_cstring.i | 88 + Examples/test-suite/lib_math.i | 2 + Examples/test-suite/lib_std_deque.i | 47 + Examples/test-suite/lib_std_string.i | 20 + Examples/test-suite/lib_std_vector.i | 47 + Examples/test-suite/lib_typemaps.i | 95 + Examples/test-suite/list_vector.i | 153 + Examples/test-suite/long_long.i | 40 + Examples/test-suite/macro_2.i | 22 + Examples/test-suite/member_template.i | 20 + Examples/test-suite/memberin1.i | 63 + Examples/test-suite/minherit.i | 80 + Examples/test-suite/multivalue.i | 52 + Examples/test-suite/mzscheme/.cvsignore | 1 + Examples/test-suite/mzscheme/Makefile | 40 + Examples/test-suite/mzscheme/README | 4 + Examples/test-suite/mzscheme/casts_runme.scm | 7 + .../mzscheme/char_constant_runme.scm | 6 + Examples/test-suite/mzscheme/import_runme.scm | 16 + Examples/test-suite/mzscheme/name_runme.scm | 10 + Examples/test-suite/mzscheme/unions_runme.scm | 38 + Examples/test-suite/name.i | 26 + Examples/test-suite/name_cxx.i | 16 + Examples/test-suite/name_inherit.i | 13 + Examples/test-suite/namespace_enum.i | 24 + Examples/test-suite/namespace_extend.i | 34 + Examples/test-suite/namespace_nested.i | 59 + Examples/test-suite/namespace_template.i | 78 + Examples/test-suite/namespace_typemap.i | 229 + Examples/test-suite/nested.i | 34 + Examples/test-suite/newobject1.i | 51 + Examples/test-suite/newobject2.i | 38 + Examples/test-suite/ocaml/Makefile | 64 + Examples/test-suite/ocaml/README | 2 + .../test-suite/ocaml/class_ignore_runme.ml | 6 + Examples/test-suite/ocaml/makedebugtop | 21 + Examples/test-suite/ocaml/newobject1_runme.ml | 25 + .../test-suite/ocaml/overload_copy_runme.ml | 4 + Examples/test-suite/ocaml/results | 180 + Examples/test-suite/ocaml/sneaky1_runme.ml | 8 + .../test-suite/ocaml/throw_exception_runme.ml | 27 + Examples/test-suite/ocaml/typename_runme.ml | 11 + Examples/test-suite/ocaml/unions_runme.ml | 27 + Examples/test-suite/overload_complicated.i | 21 + Examples/test-suite/overload_copy.i | 16 + Examples/test-suite/overload_extend.i | 16 + Examples/test-suite/overload_extendc.i | 16 + Examples/test-suite/overload_simple.i | 92 + Examples/test-suite/overload_subtype.i | 17 + Examples/test-suite/overload_template.i | 19 + Examples/test-suite/perl5/.cvsignore | 4 + Examples/test-suite/perl5/Makefile | 42 + Examples/test-suite/perl5/README | 4 + .../test-suite/perl5/import_nomodule_runme.pl | 7 + Examples/test-suite/perl5/imports_runme.pl | 5 + .../test-suite/perl5/overload_copy_runme.pl | 5 + .../test-suite/perl5/overload_simple_runme.pl | 120 + .../test-suite/perl5/primitive_ref_runme.pl | 38 + Examples/test-suite/perl5/unions_runme.pl | 54 + Examples/test-suite/php4/Makefile | 67 + .../php4/abstract_inherit_ok_runme.php4 | 13 + .../php4/abstract_inherit_runme.php4 | 14 + Examples/test-suite/php4/add_link_runme.php4 | 23 + .../test-suite/php4/anonymous_arg_runme.php4 | 13 + Examples/test-suite/php4/argout_runme.php4 | 37 + Examples/test-suite/php4/arrayptr_runme.php4 | 15 + .../test-suite/php4/arrays_global_runme.php4 | 16 + .../php4/arrays_global_twodim_runme.php4 | 25 + Examples/test-suite/php4/arrays_runme.php4 | 22 + .../test-suite/php4/arrays_scope_runme.php4 | 17 + .../test-suite/php4/bool_default_runme.php4 | 20 + Examples/test-suite/php4/casts_runme.php4 | 19 + .../test-suite/php4/class_ignore_runme.php4 | 19 + .../php4/conversion_namespace_runme.php4 | 14 + .../php4/conversion_ns_template_runme.php4 | 10 + .../test-suite/php4/conversion_runme.php4 | 14 + .../test-suite/php4/cpp_static_runme.php4 | 15 + .../test-suite/php4/enum_scope_runme.php4 | 17 + .../php4/enum_scope_template_runme.php4 | 17 + .../php4/evil_diamond_ns_runme.php4 | 19 + .../php4/evil_diamond_prop_runme.php4 | 38 + .../test-suite/php4/evil_diamond_runme.php4 | 17 + .../php4/extend_template_ns_runme.php4 | 13 + .../php4/extend_template_runme.php4 | 13 + Examples/test-suite/php4/grouping_runme.php4 | 24 + .../php4/ignore_parameter_runme.php4 | 39 + .../test-suite/php4/lib_carrays_runme.php4 | 15 + .../test-suite/php4/rename_scope_runme.php4 | 17 + Examples/test-suite/php4/skel.php4 | 15 + .../php4/smart_pointer_rename_runme.php4 | 28 + Examples/test-suite/php4/sym_runme.php4 | 23 + .../php4/template_arg_typename_runme.php4 | 19 + .../php4/template_construct_runme.php4 | 11 + Examples/test-suite/php4/tests.php4 | 217 + .../php4/typedef_reference_runme.php4 | 13 + .../php4/typemap_ns_using_runme.php4 | 9 + Examples/test-suite/php4/using1_runme.php4 | 9 + Examples/test-suite/php4/using2_runme.php4 | 9 + .../php4/valuewrapper_base_runme.php4 | 14 + Examples/test-suite/pike/Makefile | 44 + Examples/test-suite/pointer_in_out.i | 35 + Examples/test-suite/pointer_reference.i | 17 + Examples/test-suite/preproc_1.i | 10 + Examples/test-suite/preproc_2.i | 22 + Examples/test-suite/preproc_3.i | 6 + Examples/test-suite/primitive_ref.i | 26 + Examples/test-suite/private_assign.i | 21 + Examples/test-suite/pure_virtual.i | 74 + Examples/test-suite/python/.cvsignore | 5 + Examples/test-suite/python/Makefile | 44 + Examples/test-suite/python/README | 4 + .../python/abstract_typedef_runme.py | 11 + .../test-suite/python/class_ignore_runme.py | 6 + Examples/test-suite/python/constover_runme.py | 38 + .../test-suite/python/cpp_namespace_runme.py | 45 + .../python/default_constructor_runme.py | 96 + .../test-suite/python/dynamic_cast_runme.py | 12 + Examples/test-suite/python/enum_runme.py | 7 + .../python/extend_template_ns_runme.py | 7 + .../python/extend_template_runme.py | 8 + Examples/test-suite/python/grouping_runme.py | 13 + .../python/import_nomodule_runme.py | 7 + Examples/test-suite/python/imports_runme.py | 9 + .../python/inherit_missing_runme.py | 17 + .../test-suite/python/lib_std_vector_runme.py | 17 + Examples/test-suite/python/minherit_runme.py | 71 + .../python/namespace_typemap_runme.py | 82 + .../test-suite/python/overload_copy_runme.py | 3 + .../python/overload_extend_runme.py | 11 + .../python/overload_extendc_runme.py | 11 + .../python/overload_simple_runme.py | 97 + .../python/overload_subtype_runme.py | 11 + .../python/overload_template_runme.py | 5 + .../test-suite/python/primitive_ref_runme.py | 37 + .../test-suite/python/rename_scope_runme.py | 10 + .../python/smart_pointer_multi_runme.py | 15 + .../smart_pointer_multi_typedef_runme.py | 15 + .../python/smart_pointer_not_runme.py | 42 + .../python/smart_pointer_overload_runme.py | 21 + .../python/smart_pointer_rename_runme.py | 13 + .../python/smart_pointer_simple_runme.py | 13 + .../python/smart_pointer_typedef_runme.py | 13 + Examples/test-suite/python/sneaky1_runme.py | 5 + .../python/static_const_member_2_runme.py | 15 + .../test-suite/python/struct_value_runme.py | 9 + .../python/template_construct_runme.py | 1 + .../python/template_inherit_runme.py | 53 + .../test-suite/python/template_ns4_runme.py | 5 + .../test-suite/python/template_ns_runme.py | 17 + .../python/template_rename_runme.py | 12 + .../python/template_tbase_template_runme.py | 5 + .../python/template_type_namespace_runme.py | 5 + .../python/template_typedef_cplx2_runme.py | 95 + .../python/template_typedef_cplx3_runme.py | 34 + .../python/template_typedef_cplx4_runme.py | 34 + .../python/template_typedef_cplx_runme.py | 88 + .../python/template_typedef_import_runme.py | 35 + .../python/template_typedef_runme.py | 33 + .../python/typedef_inherit_runme.py | 23 + .../test-suite/python/typedef_scope_runme.py | 12 + .../python/typemap_namespace_runme.py | 8 + .../python/typemap_ns_using_runme.py | 4 + Examples/test-suite/python/typename_runme.py | 12 + Examples/test-suite/python/unions_runme.py | 51 + Examples/test-suite/python/using1_runme.py | 4 + Examples/test-suite/python/using2_runme.py | 4 + .../python/using_composition_runme.py | 11 + .../test-suite/python/using_extend_runme.py | 17 + .../test-suite/python/using_inherit_runme.py | 8 + .../test-suite/python/using_private_runme.py | 7 + .../python/using_protected_runme.py | 7 + Examples/test-suite/python/voidtest_runme.py | 7 + Examples/test-suite/rename_default.i | 27 + Examples/test-suite/rename_scope.i | 49 + Examples/test-suite/ret_by_value.i | 19 + Examples/test-suite/return_value_scope.i | 28 + Examples/test-suite/rname.i | 48 + Examples/test-suite/ruby/.cvsignore | 3 + Examples/test-suite/ruby/Makefile | 41 + Examples/test-suite/ruby/README | 4 + .../test-suite/ruby/class_ignore_runme.rb | 10 + Examples/test-suite/ruby/constover_runme.rb | 44 + .../test-suite/ruby/cpp_namespace_runme.rb | 51 + .../ruby/default_constructor_runme.rb | 94 + .../test-suite/ruby/dynamic_cast_runme.rb | 13 + Examples/test-suite/ruby/enum_runme.rb | 6 + .../ruby/extend_template_ns_runme.rb | 12 + .../test-suite/ruby/extend_template_runme.rb | 10 + Examples/test-suite/ruby/grouping_runme.rb | 15 + Examples/test-suite/ruby/imports_runme.rb | 9 + .../test-suite/ruby/inherit_missing_runme.rb | 20 + .../test-suite/ruby/lib_std_vector_runme.rb | 17 + .../ruby/namespace_typemap_runme.rb | 33 + Examples/test-suite/ruby/newobject1_runme.rb | 15 + Examples/test-suite/ruby/newobject2_runme.rb | 15 + .../test-suite/ruby/overload_copy_runme.rb | 6 + .../test-suite/ruby/overload_extend_runme.rb | 8 + .../test-suite/ruby/overload_extendc_runme.rb | 7 + .../test-suite/ruby/overload_simple_runme.rb | 119 + .../test-suite/ruby/overload_subtype_runme.rb | 15 + .../ruby/overload_template_runme.rb | 6 + .../test-suite/ruby/primitive_ref_runme.rb | 27 + .../test-suite/ruby/rename_scope_runme.rb | 10 + .../ruby/smart_pointer_const_runme.rb | 13 + .../ruby/smart_pointer_multi_runme.rb | 15 + .../ruby/smart_pointer_multi_typedef_runme.rb | 14 + .../ruby/smart_pointer_not_runme.rb | 44 + .../ruby/smart_pointer_overload_runme.rb | 16 + .../ruby/smart_pointer_rename_runme.rb | 12 + .../ruby/smart_pointer_simple_runme.rb | 13 + .../ruby/smart_pointer_typedef_runme.rb | 13 + Examples/test-suite/ruby/sneaky1_runme.rb | 6 + .../test-suite/ruby/template_inherit_runme.rb | 40 + .../test-suite/ruby/template_ns4_runme.rb | 4 + Examples/test-suite/ruby/template_ns_runme.rb | 15 + .../test-suite/ruby/template_rename_runme.rb | 12 + .../test-suite/ruby/typedef_inherit_runme.rb | 27 + .../test-suite/ruby/typedef_scope_runme.rb | 13 + .../ruby/typemap_namespace_runme.rb | 7 + Examples/test-suite/ruby/typename_runme.rb | 14 + Examples/test-suite/ruby/unions_runme.rb | 54 + Examples/test-suite/sizeof_pointer.i | 19 + Examples/test-suite/smart_pointer_const.i | 19 + Examples/test-suite/smart_pointer_multi.i | 39 + .../test-suite/smart_pointer_multi_typedef.i | 45 + Examples/test-suite/smart_pointer_not.i | 39 + Examples/test-suite/smart_pointer_overload.i | 24 + Examples/test-suite/smart_pointer_protected.i | 29 + Examples/test-suite/smart_pointer_rename.i | 25 + Examples/test-suite/smart_pointer_simple.i | 19 + Examples/test-suite/smart_pointer_typedef.i | 21 + Examples/test-suite/sneaky1.i | 29 + Examples/test-suite/static_array_member.i | 12 + Examples/test-suite/static_const_member.i | 17 + Examples/test-suite/static_const_member_2.i | 53 + Examples/test-suite/struct_value.i | 14 + Examples/test-suite/sym.i | 24 + Examples/test-suite/tcl/.cvsignore | 3 + Examples/test-suite/tcl/Makefile | 41 + Examples/test-suite/tcl/README | 4 + .../test-suite/tcl/import_nomodule_runme.tcl | 10 + Examples/test-suite/tcl/imports_runme.tcl | 26 + .../test-suite/tcl/overload_copy_runme.tcl | 18 + .../test-suite/tcl/overload_simple_runme.tcl | 172 + .../test-suite/tcl/primitive_ref_runme.tcl | 25 + Examples/test-suite/tcl/unions_runme.tcl | 69 + Examples/test-suite/template.i | 46 + Examples/test-suite/template_arg_scope.i | 16 + Examples/test-suite/template_arg_typename.i | 26 + Examples/test-suite/template_base_template.i | 35 + Examples/test-suite/template_classes.i | 30 + Examples/test-suite/template_const_ref.i | 14 + Examples/test-suite/template_construct.i | 15 + Examples/test-suite/template_default.i | 10 + Examples/test-suite/template_default2.i | 44 + Examples/test-suite/template_default_arg.i | 34 + .../test-suite/template_default_inherit.i | 25 + .../test-suite/template_default_qualify.i | 56 + Examples/test-suite/template_enum.i | 15 + .../test-suite/template_enum_ns_inherit.i | 48 + Examples/test-suite/template_enum_typedef.i | 39 + Examples/test-suite/template_forward.i | 20 + Examples/test-suite/template_inherit.i | 40 + .../test-suite/template_inherit_abstract.i | 59 + Examples/test-suite/template_int_const.i | 50 + Examples/test-suite/template_ns.i | 35 + Examples/test-suite/template_ns2.i | 16 + Examples/test-suite/template_ns3.i | 21 + Examples/test-suite/template_ns4.i | 66 + Examples/test-suite/template_ns_enum.i | 18 + Examples/test-suite/template_ns_enum2.i | 38 + Examples/test-suite/template_ns_inherit.i | 30 + Examples/test-suite/template_ns_scope.i | 38 + Examples/test-suite/template_qualifier.i | 15 + Examples/test-suite/template_rename.i | 24 + Examples/test-suite/template_retvalue.i | 32 + Examples/test-suite/template_specialization.i | 40 + Examples/test-suite/template_static.i | 16 + Examples/test-suite/template_tbase_template.i | 43 + Examples/test-suite/template_type_namespace.i | 14 + Examples/test-suite/template_typedef.i | 156 + Examples/test-suite/template_typedef_cplx.i | 159 + Examples/test-suite/template_typedef_cplx2.h | 156 + Examples/test-suite/template_typedef_cplx2.i | 7 + Examples/test-suite/template_typedef_cplx3.i | 37 + Examples/test-suite/template_typedef_cplx4.i | 44 + Examples/test-suite/template_typedef_import.i | 37 + .../test-suite/template_typedef_import.list | 2 + Examples/test-suite/template_virtual.i | 32 + Examples/test-suite/template_whitespace.i | 22 + Examples/test-suite/throw_exception.i | 29 + Examples/test-suite/typedef_array_member.i | 10 + Examples/test-suite/typedef_funcptr.i | 26 + Examples/test-suite/typedef_inherit.i | 41 + Examples/test-suite/typedef_mptr.i | 34 + Examples/test-suite/typedef_reference.i | 10 + Examples/test-suite/typedef_scope.i | 21 + Examples/test-suite/typemap_namespace.i | 39 + Examples/test-suite/typemap_ns_using.i | 21 + Examples/test-suite/typemap_subst.i | 54 + Examples/test-suite/typename.i | 34 + Examples/test-suite/union_scope.i | 13 + Examples/test-suite/unions.i | 35 + Examples/test-suite/using1.i | 22 + Examples/test-suite/using2.i | 22 + Examples/test-suite/using_composition.i | 24 + Examples/test-suite/using_extend.i | 37 + Examples/test-suite/using_inherit.i | 17 + Examples/test-suite/using_namespace.i | 56 + Examples/test-suite/using_private.i | 17 + Examples/test-suite/using_protected.i | 17 + Examples/test-suite/valuewrapper_base.i | 28 + Examples/test-suite/virtual_destructor.i | 16 + Examples/test-suite/voidtest.i | 16 + FUTURE | 335 + INSTALL | 226 + Lib/_std_deque.i | 143 + Lib/array.i | 401 - Lib/autodoc.i | 101 - Lib/carray.i | 175 - Lib/carrays.i | 132 + Lib/cdata.i | 92 + Lib/cmalloc.i | 110 + Lib/common.swg | 81 +- Lib/constraints.i | 20 +- Lib/cpointer.i | 184 + Lib/cstring.i | 6 + Lib/ctype.i | 64 - Lib/exception.i | 187 +- Lib/guile/cplusplus.i | 20 + Lib/guile/guile.i | 41 +- Lib/guile/guile.swg | 84 +- Lib/guile/guiledec.swg | 72 +- Lib/guile/guilemain.i | 8 + Lib/guile/list-vector.i | 430 + Lib/guile/pointer-in-out.i | 68 + Lib/guile/ports.i | 29 +- Lib/guile/std_common.i | 26 + Lib/guile/std_string.i | 58 + Lib/guile/std_vector.i | 436 + Lib/guile/stl.i | 9 + Lib/guile/typemaps.i | 367 +- Lib/java/arrays_java.i | 407 + Lib/java/java.swg | 699 +- Lib/java/javahead.swg | 84 + Lib/java/std_string.i | 183 + Lib/java/std_vector.i | 137 + Lib/java/stl.i | 9 + Lib/java/typemaps.i | 579 +- Lib/java/various.i | 106 + Lib/malloc.i | 57 - Lib/math.i | 39 +- Lib/memory.i | 39 - Lib/mzscheme/mzscheme.i | 26 + Lib/mzscheme/mzscheme.swg | 279 +- Lib/mzscheme/mzschemedec.swg | 84 + Lib/mzscheme/std_common.i | 17 + Lib/mzscheme/std_string.i | 56 + Lib/mzscheme/std_vector.i | 460 + Lib/mzscheme/stl.i | 9 + Lib/mzscheme/typemaps.i | 978 +- Lib/objc.i | 56 - Lib/ocaml/carray.i | 36 + Lib/ocaml/cstring.i | 274 + Lib/ocaml/extra-install.list | 2 + Lib/ocaml/libswigocaml.h | 20 + Lib/ocaml/libswigocaml.swg | 18 + Lib/ocaml/mlheading.swg | 54 + Lib/ocaml/mliheading.swg | 27 + Lib/ocaml/ocaml.i | 32 + Lib/ocaml/ocaml.swg | 533 + Lib/ocaml/ocamldec.swg | 106 + Lib/ocaml/std_common.i | 17 + Lib/ocaml/std_complex.i | 65 + Lib/ocaml/std_deque.i | 23 + Lib/ocaml/std_list.i | 246 + Lib/ocaml/std_string.i | 55 + Lib/ocaml/std_vector.i | 90 + Lib/ocaml/stl.i | 9 + Lib/ocaml/swig.ml | 100 + Lib/ocaml/typecheck.i | 175 + Lib/ocaml/typemaps.i | 174 + Lib/perl5/Makefile.in | 10 +- Lib/perl5/extra-install.list | 2 + Lib/perl5/perl5.swg | 703 +- Lib/perl5/perlrun.swg | 286 + Lib/perl5/ptrlang.i | 511 - Lib/perl5/std_string.i | 69 + Lib/perl5/std_vector.i | 297 + Lib/perl5/stl.i | 9 + Lib/perl5/typemaps.i | 465 +- Lib/php4/php4.swg | 498 + Lib/php4/php4run.swg | 240 + Lib/php4/std_string.i | 45 + Lib/php4/std_vector.i | 156 + Lib/php4/stl.i | 9 + Lib/php4/typemaps.i | 234 + Lib/php4/utils.i | 145 + Lib/pike/pike.swg | 337 + Lib/pike/pikerun.swg | 59 + Lib/pointer.i | 56 +- Lib/python/Makefile.in | 10 +- Lib/python/cstring.i | 288 + Lib/python/embed13.i | 342 - Lib/python/embed14.i | 340 - Lib/python/fragments.i | 29 + Lib/python/ptrlang.i | 464 - Lib/python/pyrun.swg | 416 + Lib/python/python.swg | 880 +- Lib/python/std_common.i | 26 + Lib/python/std_complex.i | 64 + Lib/python/std_deque.i | 23 + Lib/python/std_list.i | 245 + Lib/python/std_string.i | 54 + Lib/python/std_vector.i | 726 + Lib/python/stl.i | 9 + Lib/python/typemaps.i | 520 +- Lib/python/typemaps_old.i | 441 - Lib/ruby/Makefile.swig | 4 +- Lib/ruby/exception.i | 27 - Lib/ruby/extra-install.list | 3 + Lib/ruby/fragments.i | 17 + Lib/ruby/ptrlang.i | 461 - Lib/ruby/ruby.i | 5 - Lib/ruby/ruby.swg | 529 +- Lib/ruby/rubydec.swg | 17 +- Lib/ruby/rubydef.swg | 186 +- Lib/ruby/rubyhead.swg | 71 + Lib/ruby/std_common.i | 35 + Lib/ruby/std_string.i | 56 + Lib/ruby/std_vector.i | 373 + Lib/ruby/stl.i | 9 + Lib/ruby/typemaps.i | 416 +- Lib/std_deque.i | 5 + Lib/stdlib.i | 43 - Lib/swig.swg | 303 +- Lib/tcl/Makefile.in | 10 +- Lib/tcl/constarray.i | 108 - Lib/tcl/consthash.i | 223 - Lib/tcl/cstring.i | 290 + Lib/tcl/object.swg | 229 - Lib/tcl/ptrlang.i | 490 - Lib/tcl/std_string.i | 47 + Lib/tcl/std_vector.i | 442 + Lib/tcl/stl.i | 9 + Lib/tcl/swigtcl8.swg | 706 +- Lib/tcl/tcl8.swg | 594 +- Lib/tcl/tclsh.i | 4 +- Lib/tcl/typemaps.i | 340 +- Lib/tcl/wish.i | 10 +- Lib/timers.i | 173 - Makefile.in | 394 +- Runtime/.cvsignore | 7 + Runtime/Makefile.in | 159 +- Source/CParse/.cvsignore | 9 + Source/CParse/Makefile.in | 69 + Source/CParse/cparse.h | 12 + Source/CParse/cscanner.c | 1290 ++ Source/CParse/parser.y | 4568 +++++++ Source/CParse/templ.c | 495 + Source/CParse/util.c | 71 + Source/DOH/.cvsignore | 1 + Source/DOH/Doh/Makefile | 50 - Source/DOH/Doh/Makefile.in | 14 +- Source/DOH/Doh/base.c | 175 +- Source/DOH/Doh/file.c | 59 +- Source/DOH/Doh/fio.c | 17 +- Source/DOH/Doh/hash.c | 109 +- Source/DOH/Doh/list.c | 50 +- Source/DOH/Doh/memory.c | 14 +- Source/DOH/Doh/string.c | 203 +- Source/DOH/Doh/void.c | 11 +- Source/DOH/Include/doh.h | 319 +- Source/DOH/Include/dohobj.h | 36 +- Source/DOH/Makefile.in | 4 +- Source/DOH/configure.in | 4 +- Source/Include/.cvsignore | 3 + Source/Include/swigconfig.h.in | 19 +- Source/Include/swigver.h | 10 - Source/Include/swigver.h.in | 12 +- Source/Include/swigwarn.h | 186 + Source/Modules1.1/Makefile.in | 27 +- Source/Modules1.1/README | 9 + Source/Modules1.1/allocate.cxx | 453 + Source/Modules1.1/browser.cxx | 415 + Source/Modules1.1/contract.cxx | 118 + Source/Modules1.1/emit.cxx | 620 +- Source/Modules1.1/generate.cxx | 909 -- Source/Modules1.1/guile.cxx | 1983 +-- Source/Modules1.1/guile.h | 55 - Source/Modules1.1/java.cxx | 3057 +++-- Source/Modules1.1/java.h | 49 - Source/Modules1.1/lang.cxx | 2150 ++- Source/Modules1.1/main.cxx | 751 +- Source/Modules1.1/module.cxx | 57 + Source/Modules1.1/mzscheme.cxx | 1295 +- Source/Modules1.1/mzscheme.h | 43 - Source/Modules1.1/ocaml.cxx | 1072 ++ Source/Modules1.1/overload.cxx | 338 + Source/Modules1.1/perl5.cxx | 3204 ++--- Source/Modules1.1/perl5.h | 53 - Source/Modules1.1/php4.cxx | 2113 +++ Source/Modules1.1/pike.cxx | 881 ++ Source/Modules1.1/python.cxx | 2540 ++-- Source/Modules1.1/python.h | 62 - Source/Modules1.1/ruby.cxx | 2614 ++-- Source/Modules1.1/ruby.h | 55 - Source/Modules1.1/s-exp.cxx | 401 + Source/Modules1.1/swig11.h | 121 - Source/Modules1.1/swigmod.h | 255 + Source/Modules1.1/tcl8.cxx | 1752 +-- Source/Modules1.1/tcl8.h | 53 - Source/Modules1.1/typepass.cxx | 966 ++ Source/Modules1.1/xml.cxx | 604 +- Source/Modules1.1/xml.dtd | 119 - Source/Modules1.1/xml.h | 18 - Source/Preprocessor/Makefile.in | 10 +- Source/Preprocessor/cpp.c | 514 +- Source/Preprocessor/expr.c | 228 +- Source/Preprocessor/preprocessor.h | 20 +- Source/README | 32 + Source/Swig/Makefile.in | 16 +- Source/Swig/cwrap.c | 1078 +- Source/Swig/error.c | 198 + Source/Swig/fragment.c | 64 + Source/Swig/getopt.c | 2 +- Source/Swig/include.c | 89 +- Source/Swig/main.c | 103 - Source/Swig/map.c | 352 - Source/Swig/misc.c | 374 +- Source/Swig/module.c | 210 - Source/Swig/naming.c | 495 +- Source/Swig/parms.c | 82 +- Source/Swig/scanner.c | 32 +- Source/Swig/stype.c | 1620 ++- Source/Swig/swig.h | 438 +- Source/Swig/swig.i | 4 - Source/Swig/symbol.c | 1124 ++ Source/Swig/tree.c | 732 +- Source/Swig/typemap.c | 1260 +- Source/Swig/typesys.c | 1609 +++ Source/Swig/warn.c | 42 + Source/Swig/wrapfunc.c | 314 +- Tools/.cvsignore | 6 + Tools/WAD/CHANGES | 4 + Tools/WAD/Papers/README | 9 +- Tools/WAD/Papers/WADTalk.pdf | Bin 385395 -> 0 bytes Tools/WAD/Papers/fig1.png | Bin 7965 -> 0 bytes Tools/WAD/Papers/python.html | 860 -- Tools/WAD/Papers/tcl.ps | 11006 ---------------- Tools/WAD/Papers/usenix2001.tex | 1347 -- Tools/WAD/README | 11 +- Tools/WAD/configure.in | 2 +- Tools/aclocal.m4 | 3704 ++++++ Tools/capitalize | 5 + Tools/check-include-path.pike | 20 + Tools/config.guess | 994 +- Tools/config.sub | 510 +- Tools/configure.in | 47 +- Tools/ltconfig | 3078 ----- Tools/ltmain.sh | 2738 ++-- Tools/mkdist.py | 20 +- Tools/setup.py.tmpl | 139 + Tools/swig-1.3a1-1.spec | 83 - Tools/swig.spec | 88 - Tools/swig.spec.1 | 42 + VERSION | 6 +- Win/README.txt | 2 +- autogen.sh | 5 + configure.in | 561 +- debian/.cvsignore | 1 + debian/README | 20 + debian/changelog | 60 + debian/control | 18 + debian/copyright | 83 + debian/dirs | 4 + debian/docs | 10 + debian/postinst | 45 + debian/rules | 76 + debian/substvars | 1 + swig.spec.in | 78 + vms/aaareadme.txt | 18 + vms/build_end.com | 21 + vms/build_init.com | 13 + vms/build_swig.com | 1 + vms/genbuild.py | 155 + vms/logicals.com | 18 + vms/scripts/build_all.com | 15 + vms/scripts/compil_cparse.com | 98 + vms/scripts/compil_doh.com | 106 + vms/scripts/compil_modules1_1.com | 132 + vms/scripts/compil_preprocessor.com | 94 + vms/scripts/compil_swig.com | 122 + vms/swigconfig.h | 19 + vms/swigver.h | 18 + 1508 files changed, 125983 insertions(+), 44037 deletions(-) create mode 100644 CHANGES.current rename Doc/{ => Devel}/engineering.html (96%) rename Doc/{ => Devel}/index.html (86%) rename Doc/{ => Devel}/internals.html (78%) rename Doc/{ => Devel}/migrate.txt (100%) create mode 100644 Doc/Manual/About.html create mode 100644 Doc/Manual/Advanced.html create mode 100644 Doc/Manual/Arguments.html create mode 100644 Doc/Manual/Contents.html create mode 100644 Doc/Manual/Copyright.html create mode 100644 Doc/Manual/Customization.html create mode 100644 Doc/Manual/Documentation.html create mode 100644 Doc/Manual/Extending.html create mode 100644 Doc/Manual/Guile.html create mode 100644 Doc/Manual/Introduction.html create mode 100644 Doc/Manual/Java.html create mode 100644 Doc/Manual/Library.html create mode 100644 Doc/Manual/Ocaml.html create mode 100644 Doc/Manual/Perl5.html create mode 100644 Doc/Manual/Php.html create mode 100644 Doc/Manual/Preface.html create mode 100644 Doc/Manual/Preprocessor.html create mode 100644 Doc/Manual/Python.html create mode 100644 Doc/Manual/README create mode 100644 Doc/Manual/Ruby.html create mode 100644 Doc/Manual/SWIG.html create mode 100644 Doc/Manual/SWIGPlus.html create mode 100644 Doc/Manual/Scripting.html create mode 100644 Doc/Manual/Tcl.html create mode 100644 Doc/Manual/Typemaps.html create mode 100644 Doc/Manual/Varargs.html create mode 100644 Doc/Manual/Warnings.html create mode 100644 Doc/Manual/Windows.html create mode 100644 Doc/Manual/ch11.1.png create mode 100644 Doc/Manual/ch11.2.png create mode 100644 Doc/Manual/ch11.3.png create mode 100644 Doc/Manual/ch12.1.png create mode 100644 Doc/Manual/ch2.1.png create mode 100644 Doc/Manual/ch9.table.2.png create mode 100644 Doc/Manual/chapters create mode 100644 Doc/Manual/index.html create mode 100644 Doc/Manual/makechap.py create mode 100644 Doc/Manual/maketoc.py create mode 100644 Doc/README delete mode 100644 Doc/whitepaper.html create mode 100644 Examples/GIFPlot/.cvsignore rename Examples/GIFPlot/{Java => Common-Lisp/full}/cmap (100%) create mode 100644 Examples/GIFPlot/Common-Lisp/full/gifplot.i create mode 100644 Examples/GIFPlot/Common-Lisp/full/runme.lisp create mode 100644 Examples/GIFPlot/Guile/check.list create mode 100644 Examples/GIFPlot/Guile/full/.cvsignore create mode 100644 Examples/GIFPlot/Guile/simple/.cvsignore delete mode 100644 Examples/GIFPlot/Java/Makefile delete mode 100644 Examples/GIFPlot/Java/README create mode 100644 Examples/GIFPlot/Java/check.list delete mode 100644 Examples/GIFPlot/Java/cm15 create mode 100644 Examples/GIFPlot/Java/full/.cvsignore create mode 100644 Examples/GIFPlot/Java/full/Makefile create mode 100644 Examples/GIFPlot/Java/full/README create mode 100644 Examples/GIFPlot/Java/full/cmap create mode 100644 Examples/GIFPlot/Java/full/gifplot.i create mode 100644 Examples/GIFPlot/Java/full/main.java delete mode 100644 Examples/GIFPlot/Java/gifplot.i delete mode 100644 Examples/GIFPlot/Java/ortho.java delete mode 100644 Examples/GIFPlot/Java/shadow.java create mode 100644 Examples/GIFPlot/Java/shadow/.cvsignore create mode 100644 Examples/GIFPlot/Java/shadow/Makefile create mode 100644 Examples/GIFPlot/Java/shadow/README create mode 100644 Examples/GIFPlot/Java/shadow/cmap create mode 100644 Examples/GIFPlot/Java/shadow/main.java delete mode 100644 Examples/GIFPlot/Java/simple.java create mode 100644 Examples/GIFPlot/Java/simple/.cvsignore create mode 100644 Examples/GIFPlot/Java/simple/Makefile create mode 100644 Examples/GIFPlot/Java/simple/README create mode 100644 Examples/GIFPlot/Java/simple/main.java create mode 100644 Examples/GIFPlot/Java/simple/simple.i delete mode 100644 Examples/GIFPlot/LICENSE create mode 100644 Examples/GIFPlot/Lib/.cvsignore create mode 100644 Examples/GIFPlot/Ocaml/check.list create mode 100644 Examples/GIFPlot/Ocaml/full/Makefile create mode 100644 Examples/GIFPlot/Ocaml/full/README create mode 100644 Examples/GIFPlot/Ocaml/full/cmap create mode 100644 Examples/GIFPlot/Ocaml/full/gifplot.i create mode 100644 Examples/GIFPlot/Ocaml/full/runme.ml create mode 100644 Examples/GIFPlot/Ocaml/simple/Makefile create mode 100644 Examples/GIFPlot/Ocaml/simple/cmap create mode 100644 Examples/GIFPlot/Ocaml/simple/runme.ml create mode 100644 Examples/GIFPlot/Ocaml/simple/simple.i create mode 100644 Examples/GIFPlot/Perl/check.list create mode 100644 Examples/GIFPlot/Perl/full/.cvsignore create mode 100644 Examples/GIFPlot/Perl/shadow/.cvsignore create mode 100644 Examples/GIFPlot/Perl/simple/.cvsignore create mode 100644 Examples/GIFPlot/Php/check.list create mode 100644 Examples/GIFPlot/Php/full/Makefile create mode 100644 Examples/GIFPlot/Php/full/README create mode 100644 Examples/GIFPlot/Php/full/cmap create mode 100644 Examples/GIFPlot/Php/full/gifplot.i create mode 100644 Examples/GIFPlot/Php/full/runme.php4 create mode 100644 Examples/GIFPlot/Php/shadow/Makefile create mode 100644 Examples/GIFPlot/Php/shadow/README create mode 100644 Examples/GIFPlot/Php/shadow/cmap create mode 100644 Examples/GIFPlot/Php/shadow/runme.php4 create mode 100644 Examples/GIFPlot/Php/simple/Makefile create mode 100644 Examples/GIFPlot/Php/simple/README create mode 100644 Examples/GIFPlot/Php/simple/runme.php4 create mode 100644 Examples/GIFPlot/Php/simple/simple.i create mode 100644 Examples/GIFPlot/Pike/check.list create mode 100644 Examples/GIFPlot/Pike/simple/.cvsignore create mode 100644 Examples/GIFPlot/Pike/simple/Makefile create mode 100644 Examples/GIFPlot/Pike/simple/README create mode 100644 Examples/GIFPlot/Pike/simple/runme.pike create mode 100644 Examples/GIFPlot/Pike/simple/simple.i create mode 100644 Examples/GIFPlot/Python/check.list create mode 100644 Examples/GIFPlot/Python/full/.cvsignore create mode 100644 Examples/GIFPlot/Python/shadow/.cvsignore create mode 100644 Examples/GIFPlot/Python/simple/.cvsignore create mode 100644 Examples/GIFPlot/Ruby/check.list create mode 100644 Examples/GIFPlot/Ruby/full/.cvsignore create mode 100644 Examples/GIFPlot/Ruby/shadow/.cvsignore create mode 100644 Examples/GIFPlot/Ruby/simple/.cvsignore create mode 100644 Examples/GIFPlot/Tcl/check.list create mode 100644 Examples/GIFPlot/Tcl/full/.cvsignore create mode 100644 Examples/GIFPlot/Tcl/mandel/.cvsignore create mode 100644 Examples/GIFPlot/Tcl/simple/.cvsignore delete mode 100755 Examples/GIFPlot/configure delete mode 100644 Examples/GIFPlot/configure.in create mode 100644 Examples/guile/check.list create mode 100644 Examples/guile/constants/.cvsignore create mode 100644 Examples/guile/constants/Makefile create mode 100644 Examples/guile/constants/constants.scm create mode 100644 Examples/guile/constants/example.i create mode 100644 Examples/guile/multimap/Makefile create mode 100644 Examples/guile/multimap/example.c create mode 100644 Examples/guile/multimap/example.i create mode 100644 Examples/guile/multimap/runme.scm create mode 100644 Examples/guile/multivalue/Makefile create mode 100644 Examples/guile/multivalue/example.c create mode 100644 Examples/guile/multivalue/example.i create mode 100644 Examples/guile/multivalue/runme.scm create mode 100644 Examples/guile/std_vector/.cvsignore create mode 100644 Examples/guile/std_vector/Makefile create mode 100644 Examples/guile/std_vector/example.h create mode 100644 Examples/guile/std_vector/example.i create mode 100644 Examples/guile/std_vector/runme.scm create mode 100644 Examples/java/check.list create mode 100644 Examples/java/class/.cvsignore create mode 100644 Examples/java/class/Makefile create mode 100644 Examples/java/class/example.cxx create mode 100644 Examples/java/class/example.dsp create mode 100644 Examples/java/class/example.h create mode 100644 Examples/java/class/example.i create mode 100644 Examples/java/class/index.html create mode 100644 Examples/java/class/main.java create mode 100644 Examples/java/constants/.cvsignore create mode 100644 Examples/java/constants/Makefile create mode 100644 Examples/java/constants/example.i create mode 100644 Examples/java/constants/index.html create mode 100644 Examples/java/constants/main.java create mode 100644 Examples/java/enum/.cvsignore create mode 100644 Examples/java/enum/Makefile create mode 100644 Examples/java/enum/example.cxx create mode 100644 Examples/java/enum/example.h create mode 100644 Examples/java/enum/example.i create mode 100644 Examples/java/enum/index.html create mode 100644 Examples/java/enum/main.java create mode 100644 Examples/java/funcptr/.cvsignore create mode 100644 Examples/java/funcptr/Makefile create mode 100644 Examples/java/funcptr/example.c create mode 100644 Examples/java/funcptr/example.h create mode 100644 Examples/java/funcptr/example.i create mode 100644 Examples/java/funcptr/index.html create mode 100644 Examples/java/funcptr/main.java create mode 100644 Examples/java/index.html create mode 100644 Examples/java/mpointer/Makefile create mode 100644 Examples/java/mpointer/example.cxx create mode 100644 Examples/java/mpointer/example.h create mode 100644 Examples/java/mpointer/example.i create mode 100644 Examples/java/mpointer/main.java create mode 100644 Examples/java/multimap/.cvsignore create mode 100644 Examples/java/multimap/Makefile create mode 100644 Examples/java/multimap/example.c create mode 100644 Examples/java/multimap/example.i create mode 100644 Examples/java/multimap/main.java create mode 100644 Examples/java/native/.cvsignore delete mode 100644 Examples/java/native/README create mode 100644 Examples/java/native/index.html create mode 100644 Examples/java/pointer/.cvsignore create mode 100644 Examples/java/pointer/Makefile create mode 100644 Examples/java/pointer/example.c create mode 100644 Examples/java/pointer/example.i create mode 100644 Examples/java/pointer/index.html create mode 100644 Examples/java/pointer/main.java create mode 100644 Examples/java/reference/.cvsignore create mode 100644 Examples/java/reference/Makefile create mode 100644 Examples/java/reference/example.cxx create mode 100644 Examples/java/reference/example.h create mode 100644 Examples/java/reference/example.i create mode 100644 Examples/java/reference/index.html create mode 100644 Examples/java/reference/main.java create mode 100644 Examples/java/simple/.cvsignore delete mode 100644 Examples/java/simple/README create mode 100644 Examples/java/simple/example.dsp create mode 100644 Examples/java/simple/index.html create mode 100644 Examples/java/template/.cvsignore create mode 100644 Examples/java/template/Makefile create mode 100644 Examples/java/template/example.h create mode 100644 Examples/java/template/example.i create mode 100644 Examples/java/template/index.html create mode 100644 Examples/java/template/main.java create mode 100644 Examples/java/typemap/.cvsignore delete mode 100644 Examples/java/typemap/README create mode 100644 Examples/java/typemap/index.html create mode 100644 Examples/java/variables/.cvsignore create mode 100644 Examples/java/variables/Makefile create mode 100644 Examples/java/variables/example.c create mode 100644 Examples/java/variables/example.h create mode 100644 Examples/java/variables/example.i create mode 100644 Examples/java/variables/index.html create mode 100644 Examples/java/variables/main.java create mode 100644 Examples/mzscheme/check.list create mode 100644 Examples/mzscheme/multimap/Makefile create mode 100644 Examples/mzscheme/multimap/example.c create mode 100644 Examples/mzscheme/multimap/example.i create mode 100644 Examples/mzscheme/multimap/example.scm create mode 100644 Examples/mzscheme/simple/.cvsignore create mode 100644 Examples/mzscheme/std_vector/.cvsignore create mode 100644 Examples/mzscheme/std_vector/Makefile create mode 100644 Examples/mzscheme/std_vector/example.h create mode 100644 Examples/mzscheme/std_vector/example.i create mode 100644 Examples/mzscheme/std_vector/example.scm create mode 100644 Examples/ocaml/check.list create mode 100644 Examples/ocaml/simple/Makefile create mode 100644 Examples/ocaml/simple/example.c create mode 100644 Examples/ocaml/simple/example.dsp create mode 100644 Examples/ocaml/simple/example.i create mode 100644 Examples/ocaml/simple/example_prog.ml create mode 100644 Examples/ocaml/simple/index.html create mode 100644 Examples/perl5/check.list create mode 100644 Examples/perl5/class/.cvsignore create mode 100644 Examples/perl5/class/example.dsp create mode 100644 Examples/perl5/constants/.cvsignore create mode 100644 Examples/perl5/constants2/.cvsignore create mode 100644 Examples/perl5/constants2/Makefile create mode 100644 Examples/perl5/constants2/example.i create mode 100644 Examples/perl5/constants2/example.pl create mode 100644 Examples/perl5/funcptr/.cvsignore create mode 100644 Examples/perl5/import/.cvsignore create mode 100644 Examples/perl5/import/Makefile create mode 100644 Examples/perl5/import/README create mode 100644 Examples/perl5/import/bar.h create mode 100644 Examples/perl5/import/bar.i create mode 100644 Examples/perl5/import/base.h create mode 100644 Examples/perl5/import/base.i create mode 100644 Examples/perl5/import/foo.h create mode 100644 Examples/perl5/import/foo.i create mode 100644 Examples/perl5/import/runme.pl create mode 100644 Examples/perl5/import/spam.h create mode 100644 Examples/perl5/import/spam.i create mode 100644 Examples/perl5/multimap/.cvsignore create mode 100644 Examples/perl5/multimap/Makefile create mode 100644 Examples/perl5/multimap/example.c create mode 100644 Examples/perl5/multimap/example.dsp create mode 100644 Examples/perl5/multimap/example.i create mode 100755 Examples/perl5/multimap/example.pl create mode 100644 Examples/perl5/pointer/.cvsignore create mode 100644 Examples/perl5/reference/.cvsignore create mode 100644 Examples/perl5/shadow/.cvsignore create mode 100644 Examples/perl5/simple/.cvsignore create mode 100644 Examples/perl5/simple/example.dsp create mode 100644 Examples/perl5/value/.cvsignore create mode 100644 Examples/perl5/variables/.cvsignore create mode 100644 Examples/php4/Makefile.php create mode 100644 Examples/php4/check.list create mode 100755 Examples/php4/class/BUILD.sh create mode 100644 Examples/php4/class/Makefile.old create mode 100644 Examples/php4/class/example.cxx create mode 100644 Examples/php4/class/example.h create mode 100644 Examples/php4/class/example.i create mode 100644 Examples/php4/class/runme.php4 create mode 100755 Examples/php4/constants/BUILD.sh create mode 100644 Examples/php4/constants/Makefile.old create mode 100644 Examples/php4/constants/example.i create mode 100644 Examples/php4/constants/runme.php4 create mode 100755 Examples/php4/enum/BUILD.sh create mode 100644 Examples/php4/enum/Makefile.old create mode 100644 Examples/php4/enum/example.cxx create mode 100644 Examples/php4/enum/example.h create mode 100644 Examples/php4/enum/example.i create mode 100644 Examples/php4/enum/runme.php4 create mode 100755 Examples/php4/funcptr/BUILD.sh create mode 100644 Examples/php4/funcptr/Makefile.old create mode 100644 Examples/php4/funcptr/example.c create mode 100644 Examples/php4/funcptr/example.h create mode 100644 Examples/php4/funcptr/example.i create mode 100644 Examples/php4/funcptr/runme.php4 create mode 100755 Examples/php4/pointer/BUILD.sh create mode 100644 Examples/php4/pointer/Makefile.old create mode 100644 Examples/php4/pointer/example.c create mode 100644 Examples/php4/pointer/example.i create mode 100644 Examples/php4/pointer/runme.php4 create mode 100755 Examples/php4/reference/BUILD.sh create mode 100644 Examples/php4/reference/Makefile.old create mode 100644 Examples/php4/reference/example.cxx create mode 100644 Examples/php4/reference/example.h create mode 100644 Examples/php4/reference/example.i create mode 100644 Examples/php4/reference/runme.php4 create mode 100755 Examples/php4/shadow/BUILD.sh create mode 100644 Examples/php4/shadow/Makefile.old create mode 100644 Examples/php4/shadow/example.cxx create mode 100644 Examples/php4/shadow/example.h create mode 100644 Examples/php4/shadow/example.i create mode 100644 Examples/php4/shadow/runme.php4 create mode 100755 Examples/php4/simple/BUILD.sh create mode 100644 Examples/php4/simple/Makefile.old create mode 100644 Examples/php4/simple/example.c create mode 100644 Examples/php4/simple/example.i create mode 100755 Examples/php4/simple/runme.php4 create mode 100755 Examples/php4/sync/BUILD.sh create mode 100644 Examples/php4/sync/Makefile.old create mode 100644 Examples/php4/sync/example.cxx create mode 100644 Examples/php4/sync/example.h create mode 100644 Examples/php4/sync/example.i create mode 100644 Examples/php4/sync/runme.php4 create mode 100755 Examples/php4/value/BUILD.sh create mode 100644 Examples/php4/value/Makefile.old create mode 100644 Examples/php4/value/example.c create mode 100644 Examples/php4/value/example.h create mode 100644 Examples/php4/value/example.i create mode 100644 Examples/php4/value/runme.php4 create mode 100755 Examples/php4/variables/BUILD.sh create mode 100644 Examples/php4/variables/Makefile.old create mode 100644 Examples/php4/variables/example.c create mode 100644 Examples/php4/variables/example.h create mode 100644 Examples/php4/variables/example.i create mode 100644 Examples/php4/variables/runme.php4 create mode 100644 Examples/php4/variables/runme.php4.old create mode 100644 Examples/pike/check.list create mode 100755 Examples/pike/class/.cvsignore create mode 100755 Examples/pike/class/Makefile create mode 100755 Examples/pike/class/example.cxx create mode 100755 Examples/pike/class/example.h create mode 100755 Examples/pike/class/example.i create mode 100755 Examples/pike/class/runme.pike create mode 100755 Examples/pike/constants/.cvsignore create mode 100755 Examples/pike/constants/Makefile create mode 100755 Examples/pike/constants/example.i create mode 100755 Examples/pike/constants/runme.pike create mode 100644 Examples/pike/enum/.cvsignore create mode 100644 Examples/pike/enum/Makefile create mode 100644 Examples/pike/enum/example.cxx create mode 100644 Examples/pike/enum/example.h create mode 100644 Examples/pike/enum/example.i create mode 100644 Examples/pike/enum/runme.pike create mode 100644 Examples/pike/overload/.cvsignore create mode 100644 Examples/pike/overload/Makefile create mode 100755 Examples/pike/overload/example.cxx create mode 100755 Examples/pike/overload/example.h create mode 100644 Examples/pike/overload/example.i create mode 100644 Examples/pike/overload/runme.pike create mode 100644 Examples/pike/simple/.cvsignore create mode 100644 Examples/pike/simple/Makefile create mode 100644 Examples/pike/simple/example.c create mode 100644 Examples/pike/simple/example.i create mode 100644 Examples/pike/simple/runme.pike create mode 100755 Examples/pike/template/.cvsignore create mode 100755 Examples/pike/template/Makefile create mode 100755 Examples/pike/template/example.h create mode 100755 Examples/pike/template/example.i create mode 100755 Examples/pike/template/runme.pike create mode 100644 Examples/python/check.list create mode 100644 Examples/python/class/.cvsignore create mode 100644 Examples/python/class/example.dsp delete mode 100644 Examples/python/class/example.py create mode 100644 Examples/python/class/runme.py create mode 100644 Examples/python/constants/.cvsignore rename Examples/python/constants/{example.py => runme.py} (94%) create mode 100644 Examples/python/enum/.cvsignore delete mode 100644 Examples/python/enum/example.py create mode 100644 Examples/python/enum/runme.py create mode 100644 Examples/python/exception/Makefile create mode 100644 Examples/python/exception/example.h create mode 100644 Examples/python/exception/example.i create mode 100644 Examples/python/exception/runme.py create mode 100644 Examples/python/exceptshadow/.cvsignore create mode 100644 Examples/python/exceptshadow/Makefile create mode 100644 Examples/python/exceptshadow/example.h create mode 100644 Examples/python/exceptshadow/example.i create mode 100644 Examples/python/exceptshadow/runme.py create mode 100644 Examples/python/funcattr/.cvsignore create mode 100644 Examples/python/funcattr/Makefile create mode 100644 Examples/python/funcattr/example.i create mode 100644 Examples/python/funcattr/index.html create mode 100644 Examples/python/funcattr/runme.py create mode 100644 Examples/python/funcptr/.cvsignore rename Examples/python/funcptr/{example.py => runme.py} (100%) create mode 100644 Examples/python/funcptr2/.cvsignore create mode 100644 Examples/python/funcptr2/Makefile create mode 100644 Examples/python/funcptr2/example.c create mode 100644 Examples/python/funcptr2/example.h create mode 100644 Examples/python/funcptr2/example.i create mode 100644 Examples/python/funcptr2/runme.py create mode 100644 Examples/python/functor/.cvsignore create mode 100644 Examples/python/functor/Makefile create mode 100644 Examples/python/functor/example.i create mode 100644 Examples/python/functor/runme.py create mode 100644 Examples/python/import/.cvsignore create mode 100644 Examples/python/import/Makefile create mode 100644 Examples/python/import/README create mode 100644 Examples/python/import/bar.h create mode 100644 Examples/python/import/bar.i create mode 100644 Examples/python/import/base.h create mode 100644 Examples/python/import/base.i create mode 100644 Examples/python/import/foo.h create mode 100644 Examples/python/import/foo.i create mode 100644 Examples/python/import/runme.py create mode 100644 Examples/python/import/spam.h create mode 100644 Examples/python/import/spam.i create mode 100644 Examples/python/import_template/.cvsignore create mode 100644 Examples/python/import_template/Makefile create mode 100644 Examples/python/import_template/README create mode 100644 Examples/python/import_template/bar.h create mode 100644 Examples/python/import_template/bar.i create mode 100644 Examples/python/import_template/base.h create mode 100644 Examples/python/import_template/base.i create mode 100644 Examples/python/import_template/foo.h create mode 100644 Examples/python/import_template/foo.i create mode 100644 Examples/python/import_template/runme.py create mode 100644 Examples/python/import_template/spam.h create mode 100644 Examples/python/import_template/spam.i create mode 100644 Examples/python/libffi/Makefile create mode 100644 Examples/python/libffi/example.i create mode 100644 Examples/python/mpointer/.cvsignore create mode 100644 Examples/python/mpointer/Makefile create mode 100644 Examples/python/mpointer/example.cxx create mode 100644 Examples/python/mpointer/example.h create mode 100644 Examples/python/mpointer/example.i create mode 100644 Examples/python/mpointer/runme.py create mode 100644 Examples/python/multimap/.cvsignore create mode 100644 Examples/python/multimap/Makefile create mode 100644 Examples/python/multimap/example.c create mode 100644 Examples/python/multimap/example.dsp create mode 100644 Examples/python/multimap/example.i create mode 100644 Examples/python/multimap/runme.py create mode 100644 Examples/python/operator/.cvsignore create mode 100644 Examples/python/operator/Makefile create mode 100644 Examples/python/operator/example.h create mode 100644 Examples/python/operator/example.i create mode 100644 Examples/python/operator/runme.py create mode 100644 Examples/python/overload_feature/.cvsignore create mode 100644 Examples/python/pointer/.cvsignore rename Examples/python/pointer/{example.py => runme.py} (75%) create mode 100644 Examples/python/reference/.cvsignore rename Examples/python/reference/{example.py => runme.py} (58%) create mode 100644 Examples/python/shadow/.cvsignore create mode 100644 Examples/python/simple/.cvsignore create mode 100644 Examples/python/simple/example.dsp rename Examples/python/simple/{example.py => runme.py} (100%) create mode 100644 Examples/python/smartptr/Makefile create mode 100644 Examples/python/smartptr/example.cxx create mode 100644 Examples/python/smartptr/example.h create mode 100644 Examples/python/smartptr/example.i create mode 100644 Examples/python/smartptr/runme.py create mode 100644 Examples/python/smartptr/smartptr.h create mode 100644 Examples/python/std_vector/.cvsignore create mode 100644 Examples/python/std_vector/Makefile create mode 100644 Examples/python/std_vector/example.h create mode 100644 Examples/python/std_vector/example.i create mode 100644 Examples/python/std_vector/runme.py create mode 100644 Examples/python/template/.cvsignore create mode 100644 Examples/python/template/Makefile create mode 100644 Examples/python/template/example.h create mode 100644 Examples/python/template/example.i create mode 100644 Examples/python/template/runme.py create mode 100644 Examples/python/value/.cvsignore create mode 100644 Examples/python/varargs/Makefile create mode 100644 Examples/python/varargs/example.i create mode 100644 Examples/python/varargs/runme.py create mode 100644 Examples/python/variables/.cvsignore rename Examples/python/variables/{example.py => runme.py} (100%) create mode 100644 Examples/ruby/check.list create mode 100644 Examples/ruby/class/.cvsignore create mode 100644 Examples/ruby/class/example.dsp create mode 100644 Examples/ruby/constants/.cvsignore rename Examples/ruby/constants/{run.rb => runme.rb} (100%) mode change 100644 => 100755 create mode 100644 Examples/ruby/enum/.cvsignore create mode 100644 Examples/ruby/funcptr/.cvsignore create mode 100644 Examples/ruby/funcptr2/.cvsignore create mode 100644 Examples/ruby/funcptr2/Makefile create mode 100644 Examples/ruby/funcptr2/example.c create mode 100644 Examples/ruby/funcptr2/example.h create mode 100644 Examples/ruby/funcptr2/example.i create mode 100644 Examples/ruby/funcptr2/runme.rb create mode 100644 Examples/ruby/functor/.cvsignore create mode 100644 Examples/ruby/functor/Makefile create mode 100644 Examples/ruby/functor/example.i create mode 100644 Examples/ruby/functor/runme.rb create mode 100644 Examples/ruby/hashargs/.cvsignore create mode 100755 Examples/ruby/hashargs/Makefile create mode 100755 Examples/ruby/hashargs/example.i create mode 100755 Examples/ruby/hashargs/runme.rb create mode 100644 Examples/ruby/import/.cvsignore create mode 100644 Examples/ruby/import/Makefile create mode 100644 Examples/ruby/import/README create mode 100644 Examples/ruby/import/bar.h create mode 100644 Examples/ruby/import/bar.i create mode 100644 Examples/ruby/import/base.h create mode 100644 Examples/ruby/import/base.i create mode 100644 Examples/ruby/import/foo.h create mode 100644 Examples/ruby/import/foo.i create mode 100644 Examples/ruby/import/runme.rb create mode 100644 Examples/ruby/import/spam.h create mode 100644 Examples/ruby/import/spam.i create mode 100644 Examples/ruby/import_template/.cvsignore create mode 100644 Examples/ruby/import_template/Makefile create mode 100644 Examples/ruby/import_template/README create mode 100644 Examples/ruby/import_template/bar.h create mode 100644 Examples/ruby/import_template/bar.i create mode 100644 Examples/ruby/import_template/base.h create mode 100644 Examples/ruby/import_template/base.i create mode 100644 Examples/ruby/import_template/foo.h create mode 100644 Examples/ruby/import_template/foo.i create mode 100644 Examples/ruby/import_template/runme.rb create mode 100644 Examples/ruby/import_template/spam.h create mode 100644 Examples/ruby/import_template/spam.i create mode 100644 Examples/ruby/mpointer/.cvsignore create mode 100644 Examples/ruby/mpointer/Makefile create mode 100644 Examples/ruby/mpointer/example.cxx create mode 100644 Examples/ruby/mpointer/example.h create mode 100644 Examples/ruby/mpointer/example.i create mode 100644 Examples/ruby/mpointer/runme.rb create mode 100644 Examples/ruby/multimap/.cvsignore create mode 100644 Examples/ruby/multimap/Makefile create mode 100644 Examples/ruby/multimap/example.c create mode 100644 Examples/ruby/multimap/example.dsp create mode 100644 Examples/ruby/multimap/example.i create mode 100755 Examples/ruby/multimap/runme.rb create mode 100644 Examples/ruby/operator/.cvsignore create mode 100644 Examples/ruby/operator/Makefile create mode 100644 Examples/ruby/operator/example.h create mode 100644 Examples/ruby/operator/example.i create mode 100644 Examples/ruby/operator/runme.rb create mode 100644 Examples/ruby/overloading/.cvsignore create mode 100644 Examples/ruby/overloading/Makefile create mode 100644 Examples/ruby/overloading/example.cxx create mode 100644 Examples/ruby/overloading/example.h create mode 100644 Examples/ruby/overloading/example.i create mode 100644 Examples/ruby/overloading/runme.rb create mode 100644 Examples/ruby/pointer/.cvsignore create mode 100644 Examples/ruby/reference/.cvsignore create mode 100644 Examples/ruby/simple/.cvsignore create mode 100644 Examples/ruby/simple/example.dsp rename Examples/ruby/simple/{run.rb => runme.rb} (100%) mode change 100644 => 100755 create mode 100644 Examples/ruby/std_vector/.cvsignore create mode 100644 Examples/ruby/std_vector/Makefile create mode 100644 Examples/ruby/std_vector/example.h create mode 100644 Examples/ruby/std_vector/example.i create mode 100644 Examples/ruby/std_vector/runme.rb create mode 100644 Examples/ruby/template/.cvsignore create mode 100644 Examples/ruby/template/Makefile create mode 100644 Examples/ruby/template/example.h create mode 100644 Examples/ruby/template/example.i create mode 100644 Examples/ruby/template/runme.rb create mode 100644 Examples/ruby/value/.cvsignore create mode 100644 Examples/ruby/variables/.cvsignore create mode 100644 Examples/s-exp/uffi.lisp create mode 100644 Examples/tcl/check.list create mode 100644 Examples/tcl/class/.cvsignore create mode 100644 Examples/tcl/class/example.dsp create mode 100644 Examples/tcl/constants/.cvsignore create mode 100644 Examples/tcl/enum/.cvsignore create mode 100644 Examples/tcl/funcptr/.cvsignore create mode 100644 Examples/tcl/import/.cvsignore create mode 100644 Examples/tcl/import/Makefile create mode 100644 Examples/tcl/import/README create mode 100644 Examples/tcl/import/bar.h create mode 100644 Examples/tcl/import/bar.i create mode 100644 Examples/tcl/import/base.h create mode 100644 Examples/tcl/import/base.i create mode 100644 Examples/tcl/import/foo.h create mode 100644 Examples/tcl/import/foo.i create mode 100644 Examples/tcl/import/runme.tcl create mode 100644 Examples/tcl/import/spam.h create mode 100644 Examples/tcl/import/spam.i create mode 100644 Examples/tcl/multimap/.cvsignore create mode 100644 Examples/tcl/multimap/Makefile create mode 100644 Examples/tcl/multimap/example.c create mode 100644 Examples/tcl/multimap/example.dsp create mode 100644 Examples/tcl/multimap/example.i create mode 100644 Examples/tcl/multimap/example.tcl create mode 100644 Examples/tcl/operator/.cvsignore create mode 100644 Examples/tcl/operator/Makefile create mode 100644 Examples/tcl/operator/example.h create mode 100644 Examples/tcl/operator/example.i create mode 100644 Examples/tcl/operator/runme.tcl create mode 100644 Examples/tcl/pointer/.cvsignore create mode 100644 Examples/tcl/reference/.cvsignore create mode 100644 Examples/tcl/simple/.cvsignore create mode 100644 Examples/tcl/simple/example.dsp create mode 100644 Examples/tcl/value/.cvsignore create mode 100644 Examples/tcl/variables/.cvsignore create mode 100644 Examples/test-suite/README create mode 100644 Examples/test-suite/abstract_inherit.i create mode 100644 Examples/test-suite/abstract_inherit_ok.i create mode 100644 Examples/test-suite/abstract_signature.i create mode 100644 Examples/test-suite/abstract_typedef.i create mode 100644 Examples/test-suite/add_link.i create mode 100644 Examples/test-suite/anonymous_arg.i create mode 100644 Examples/test-suite/argout.i create mode 100644 Examples/test-suite/arrayptr.i create mode 100644 Examples/test-suite/arrays.i create mode 100644 Examples/test-suite/arrays_global.i create mode 100644 Examples/test-suite/arrays_global_twodim.i create mode 100644 Examples/test-suite/arrays_scope.i create mode 100644 Examples/test-suite/bool_default.i create mode 100644 Examples/test-suite/casts.i create mode 100644 Examples/test-suite/char_constant.i create mode 100644 Examples/test-suite/class_ignore.i create mode 100644 Examples/test-suite/common.mk create mode 100644 Examples/test-suite/const_const.i create mode 100644 Examples/test-suite/const_const_2.i create mode 100644 Examples/test-suite/constant_pointers.i create mode 100644 Examples/test-suite/constover.i create mode 100644 Examples/test-suite/constructor_exception.i create mode 100644 Examples/test-suite/constructor_explicit.i create mode 100644 Examples/test-suite/constructor_value.i create mode 100644 Examples/test-suite/conversion.i create mode 100644 Examples/test-suite/conversion_namespace.i create mode 100644 Examples/test-suite/conversion_ns_template.i create mode 100644 Examples/test-suite/cplusplus_throw.i create mode 100644 Examples/test-suite/cpp_enum.i create mode 100644 Examples/test-suite/cpp_enum_scope.i create mode 100644 Examples/test-suite/cpp_namespace.i create mode 100644 Examples/test-suite/cpp_nodefault.i create mode 100644 Examples/test-suite/cpp_static.i create mode 100644 Examples/test-suite/cpp_typedef.i create mode 100644 Examples/test-suite/default_cast.i create mode 100644 Examples/test-suite/default_constructor.i create mode 100644 Examples/test-suite/default_ns.i create mode 100644 Examples/test-suite/default_ref.i create mode 100644 Examples/test-suite/defineop.i create mode 100644 Examples/test-suite/defines.i create mode 100644 Examples/test-suite/dynamic_cast.i create mode 100644 Examples/test-suite/enum.i create mode 100644 Examples/test-suite/enum_scope.i create mode 100644 Examples/test-suite/enum_scope_template.i create mode 100644 Examples/test-suite/enum_var.i create mode 100644 Examples/test-suite/errors/c_bad_name.i create mode 100644 Examples/test-suite/errors/c_bad_native.i create mode 100644 Examples/test-suite/errors/c_class.i create mode 100644 Examples/test-suite/errors/c_default_error.i create mode 100644 Examples/test-suite/errors/c_deprecated.i create mode 100644 Examples/test-suite/errors/c_empty_char.i create mode 100644 Examples/test-suite/errors/c_enum_badvalue.i create mode 100644 Examples/test-suite/errors/c_extra_rblock.i create mode 100644 Examples/test-suite/errors/c_extra_rbrace.i create mode 100644 Examples/test-suite/errors/c_extra_unsigned.i create mode 100644 Examples/test-suite/errors/c_insert_missing.i create mode 100644 Examples/test-suite/errors/c_long_short.i create mode 100644 Examples/test-suite/errors/c_missing_rbrace.i create mode 100644 Examples/test-suite/errors/c_missing_semi.i create mode 100644 Examples/test-suite/errors/c_redefine.i create mode 100644 Examples/test-suite/errors/c_varargs.i create mode 100644 Examples/test-suite/errors/c_varargs_neg.i create mode 100644 Examples/test-suite/errors/cpp_bad_extern.i create mode 100644 Examples/test-suite/errors/cpp_extend_redefine.i create mode 100644 Examples/test-suite/errors/cpp_extend_undefined.i create mode 100644 Examples/test-suite/errors/cpp_inline_namespace.i create mode 100644 Examples/test-suite/errors/cpp_missing_rtemplate.i create mode 100644 Examples/test-suite/errors/cpp_namespace_alias.i create mode 100644 Examples/test-suite/errors/cpp_namespace_aliasnot.i create mode 100644 Examples/test-suite/errors/cpp_namespace_aliasundef.i create mode 100644 Examples/test-suite/errors/cpp_nested.i create mode 100644 Examples/test-suite/errors/cpp_no_access.i create mode 100644 Examples/test-suite/errors/cpp_nobase.i create mode 100644 Examples/test-suite/errors/cpp_overload.i create mode 100644 Examples/test-suite/errors/cpp_private_defvalue.i create mode 100644 Examples/test-suite/errors/cpp_private_inherit.i create mode 100644 Examples/test-suite/errors/cpp_template_argname.i create mode 100644 Examples/test-suite/errors/cpp_template_nargs.i create mode 100644 Examples/test-suite/errors/cpp_template_not.i create mode 100644 Examples/test-suite/errors/cpp_template_partial.i create mode 100644 Examples/test-suite/errors/cpp_template_repeat.i create mode 100644 Examples/test-suite/errors/cpp_template_undef.i create mode 100644 Examples/test-suite/errors/cpp_using_not.i create mode 100644 Examples/test-suite/errors/cpp_using_undef.i create mode 100755 Examples/test-suite/errors/make.sh create mode 100644 Examples/test-suite/errors/nomodule.i create mode 100644 Examples/test-suite/errors/pp_badeval.i create mode 100644 Examples/test-suite/errors/pp_defined.i create mode 100644 Examples/test-suite/errors/pp_macro_args.i create mode 100644 Examples/test-suite/errors/pp_macro_badchar.i create mode 100644 Examples/test-suite/errors/pp_macro_nargs.i create mode 100644 Examples/test-suite/errors/pp_macro_redef.i create mode 100644 Examples/test-suite/errors/pp_macro_rparen.i create mode 100644 Examples/test-suite/errors/pp_macro_unterminated.i create mode 100644 Examples/test-suite/errors/pp_misplaced_elif.i create mode 100644 Examples/test-suite/errors/pp_misplaced_else.i create mode 100644 Examples/test-suite/errors/pp_missing_enddef.i create mode 100644 Examples/test-suite/errors/pp_missing_endif.i create mode 100644 Examples/test-suite/errors/pp_missing_file.i create mode 100644 Examples/test-suite/errors/pp_missing_rblock.i create mode 100644 Examples/test-suite/errors/pp_unterm_char.i create mode 100644 Examples/test-suite/errors/pp_unterm_comment.i create mode 100644 Examples/test-suite/errors/pp_unterm_string.i create mode 100644 Examples/test-suite/errors/swig_apply_nargs.i create mode 100644 Examples/test-suite/errors/swig_identifier.i create mode 100644 Examples/test-suite/errors/swig_insert_bad.i create mode 100644 Examples/test-suite/errors/swig_typemap_copy.i create mode 100644 Examples/test-suite/errors/swig_typemap_old.i create mode 100644 Examples/test-suite/evil_diamond.i create mode 100644 Examples/test-suite/evil_diamond_ns.i create mode 100644 Examples/test-suite/evil_diamond_prop.i create mode 100644 Examples/test-suite/explicit.i create mode 100644 Examples/test-suite/extend_template.i create mode 100644 Examples/test-suite/extend_template_ns.i create mode 100644 Examples/test-suite/grouping.i create mode 100644 Examples/test-suite/guile/.cvsignore create mode 100644 Examples/test-suite/guile/Makefile create mode 100644 Examples/test-suite/guile/README create mode 100644 Examples/test-suite/guile/casts_runme.scm create mode 100644 Examples/test-suite/guile/char_constant_runme.scm create mode 100644 Examples/test-suite/guile/imports_runme.scm create mode 100644 Examples/test-suite/guile/list_vector_runme.scm create mode 100644 Examples/test-suite/guile/multivalue_runme.scm create mode 100644 Examples/test-suite/guile/name_runme.scm create mode 100644 Examples/test-suite/guile/overload_complicated_runme.scm create mode 100644 Examples/test-suite/guile/overload_simple_runme.scm create mode 100644 Examples/test-suite/guile/overload_subtype_runme.scm create mode 100644 Examples/test-suite/guile/pointer_in_out_runme.scm create mode 100644 Examples/test-suite/guile/unions_runme.scm create mode 100644 Examples/test-suite/ignore_parameter.i create mode 100644 Examples/test-suite/import_nomodule.h create mode 100644 Examples/test-suite/import_nomodule.i create mode 100644 Examples/test-suite/imports.list create mode 100644 Examples/test-suite/imports_a.h create mode 100644 Examples/test-suite/imports_a.i create mode 100644 Examples/test-suite/imports_b.h create mode 100644 Examples/test-suite/imports_b.i create mode 100644 Examples/test-suite/inherit_missing.i create mode 100644 Examples/test-suite/java/.cvsignore create mode 100644 Examples/test-suite/java/Makefile create mode 100644 Examples/test-suite/java/README create mode 100644 Examples/test-suite/java/arrays_global_twodim_runme.java create mode 100644 Examples/test-suite/java/cpp_typedef_runme.java create mode 100644 Examples/test-suite/java/dynamic_cast_runme.java create mode 100644 Examples/test-suite/java/ignore_parameter_runme.java create mode 100644 Examples/test-suite/java/imports_runme.java create mode 100644 Examples/test-suite/java/java_constants_runme.java create mode 100644 Examples/test-suite/java/java_jnitypes_runme.java create mode 100644 Examples/test-suite/java/java_lib_arrays_runme.java create mode 100644 Examples/test-suite/java/java_pragmas_runme.java create mode 100644 Examples/test-suite/java/java_throws_runme.java create mode 100644 Examples/test-suite/java/java_typemaps_proxy_runme.java create mode 100644 Examples/test-suite/java/java_typemaps_typewrapper_runme.java create mode 100644 Examples/test-suite/java/lib_typemaps_runme.java create mode 100644 Examples/test-suite/java/long_long_runme.java create mode 100644 Examples/test-suite/java/primitive_ref_runme.java create mode 100644 Examples/test-suite/java/ret_by_value_runme.java create mode 100644 Examples/test-suite/java/template_classes_runme.java create mode 100644 Examples/test-suite/java/unions_runme.java create mode 100644 Examples/test-suite/java_constants.i create mode 100644 Examples/test-suite/java_jnitypes.i create mode 100644 Examples/test-suite/java_lib_arrays.i create mode 100644 Examples/test-suite/java_pragmas.i create mode 100644 Examples/test-suite/java_throws.i create mode 100644 Examples/test-suite/java_typemaps_proxy.i create mode 100644 Examples/test-suite/java_typemaps_typewrapper.i create mode 100644 Examples/test-suite/kind.i create mode 100644 Examples/test-suite/lib_carrays.i create mode 100644 Examples/test-suite/lib_cdata.i create mode 100644 Examples/test-suite/lib_cmalloc.i create mode 100644 Examples/test-suite/lib_constraints.i create mode 100644 Examples/test-suite/lib_cpointer.i create mode 100644 Examples/test-suite/lib_cstring.i create mode 100644 Examples/test-suite/lib_math.i create mode 100644 Examples/test-suite/lib_std_deque.i create mode 100644 Examples/test-suite/lib_std_string.i create mode 100644 Examples/test-suite/lib_std_vector.i create mode 100644 Examples/test-suite/lib_typemaps.i create mode 100644 Examples/test-suite/list_vector.i create mode 100644 Examples/test-suite/long_long.i create mode 100644 Examples/test-suite/macro_2.i create mode 100644 Examples/test-suite/member_template.i create mode 100644 Examples/test-suite/memberin1.i create mode 100644 Examples/test-suite/minherit.i create mode 100644 Examples/test-suite/multivalue.i create mode 100644 Examples/test-suite/mzscheme/.cvsignore create mode 100644 Examples/test-suite/mzscheme/Makefile create mode 100644 Examples/test-suite/mzscheme/README create mode 100644 Examples/test-suite/mzscheme/casts_runme.scm create mode 100644 Examples/test-suite/mzscheme/char_constant_runme.scm create mode 100644 Examples/test-suite/mzscheme/import_runme.scm create mode 100644 Examples/test-suite/mzscheme/name_runme.scm create mode 100644 Examples/test-suite/mzscheme/unions_runme.scm create mode 100644 Examples/test-suite/name.i create mode 100644 Examples/test-suite/name_cxx.i create mode 100644 Examples/test-suite/name_inherit.i create mode 100644 Examples/test-suite/namespace_enum.i create mode 100644 Examples/test-suite/namespace_extend.i create mode 100644 Examples/test-suite/namespace_nested.i create mode 100644 Examples/test-suite/namespace_template.i create mode 100644 Examples/test-suite/namespace_typemap.i create mode 100644 Examples/test-suite/nested.i create mode 100644 Examples/test-suite/newobject1.i create mode 100644 Examples/test-suite/newobject2.i create mode 100644 Examples/test-suite/ocaml/Makefile create mode 100644 Examples/test-suite/ocaml/README create mode 100644 Examples/test-suite/ocaml/class_ignore_runme.ml create mode 100755 Examples/test-suite/ocaml/makedebugtop create mode 100644 Examples/test-suite/ocaml/newobject1_runme.ml create mode 100644 Examples/test-suite/ocaml/overload_copy_runme.ml create mode 100644 Examples/test-suite/ocaml/results create mode 100644 Examples/test-suite/ocaml/sneaky1_runme.ml create mode 100644 Examples/test-suite/ocaml/throw_exception_runme.ml create mode 100644 Examples/test-suite/ocaml/typename_runme.ml create mode 100644 Examples/test-suite/ocaml/unions_runme.ml create mode 100644 Examples/test-suite/overload_complicated.i create mode 100644 Examples/test-suite/overload_copy.i create mode 100644 Examples/test-suite/overload_extend.i create mode 100644 Examples/test-suite/overload_extendc.i create mode 100644 Examples/test-suite/overload_simple.i create mode 100644 Examples/test-suite/overload_subtype.i create mode 100644 Examples/test-suite/overload_template.i create mode 100644 Examples/test-suite/perl5/.cvsignore create mode 100644 Examples/test-suite/perl5/Makefile create mode 100644 Examples/test-suite/perl5/README create mode 100644 Examples/test-suite/perl5/import_nomodule_runme.pl create mode 100644 Examples/test-suite/perl5/imports_runme.pl create mode 100644 Examples/test-suite/perl5/overload_copy_runme.pl create mode 100644 Examples/test-suite/perl5/overload_simple_runme.pl create mode 100644 Examples/test-suite/perl5/primitive_ref_runme.pl create mode 100644 Examples/test-suite/perl5/unions_runme.pl create mode 100644 Examples/test-suite/php4/Makefile create mode 100644 Examples/test-suite/php4/abstract_inherit_ok_runme.php4 create mode 100644 Examples/test-suite/php4/abstract_inherit_runme.php4 create mode 100644 Examples/test-suite/php4/add_link_runme.php4 create mode 100644 Examples/test-suite/php4/anonymous_arg_runme.php4 create mode 100644 Examples/test-suite/php4/argout_runme.php4 create mode 100644 Examples/test-suite/php4/arrayptr_runme.php4 create mode 100644 Examples/test-suite/php4/arrays_global_runme.php4 create mode 100644 Examples/test-suite/php4/arrays_global_twodim_runme.php4 create mode 100644 Examples/test-suite/php4/arrays_runme.php4 create mode 100644 Examples/test-suite/php4/arrays_scope_runme.php4 create mode 100644 Examples/test-suite/php4/bool_default_runme.php4 create mode 100644 Examples/test-suite/php4/casts_runme.php4 create mode 100644 Examples/test-suite/php4/class_ignore_runme.php4 create mode 100644 Examples/test-suite/php4/conversion_namespace_runme.php4 create mode 100644 Examples/test-suite/php4/conversion_ns_template_runme.php4 create mode 100644 Examples/test-suite/php4/conversion_runme.php4 create mode 100644 Examples/test-suite/php4/cpp_static_runme.php4 create mode 100644 Examples/test-suite/php4/enum_scope_runme.php4 create mode 100644 Examples/test-suite/php4/enum_scope_template_runme.php4 create mode 100644 Examples/test-suite/php4/evil_diamond_ns_runme.php4 create mode 100644 Examples/test-suite/php4/evil_diamond_prop_runme.php4 create mode 100644 Examples/test-suite/php4/evil_diamond_runme.php4 create mode 100644 Examples/test-suite/php4/extend_template_ns_runme.php4 create mode 100644 Examples/test-suite/php4/extend_template_runme.php4 create mode 100644 Examples/test-suite/php4/grouping_runme.php4 create mode 100644 Examples/test-suite/php4/ignore_parameter_runme.php4 create mode 100644 Examples/test-suite/php4/lib_carrays_runme.php4 create mode 100644 Examples/test-suite/php4/rename_scope_runme.php4 create mode 100644 Examples/test-suite/php4/skel.php4 create mode 100644 Examples/test-suite/php4/smart_pointer_rename_runme.php4 create mode 100644 Examples/test-suite/php4/sym_runme.php4 create mode 100644 Examples/test-suite/php4/template_arg_typename_runme.php4 create mode 100644 Examples/test-suite/php4/template_construct_runme.php4 create mode 100644 Examples/test-suite/php4/tests.php4 create mode 100644 Examples/test-suite/php4/typedef_reference_runme.php4 create mode 100644 Examples/test-suite/php4/typemap_ns_using_runme.php4 create mode 100644 Examples/test-suite/php4/using1_runme.php4 create mode 100644 Examples/test-suite/php4/using2_runme.php4 create mode 100644 Examples/test-suite/php4/valuewrapper_base_runme.php4 create mode 100644 Examples/test-suite/pike/Makefile create mode 100644 Examples/test-suite/pointer_in_out.i create mode 100644 Examples/test-suite/pointer_reference.i create mode 100644 Examples/test-suite/preproc_1.i create mode 100644 Examples/test-suite/preproc_2.i create mode 100644 Examples/test-suite/preproc_3.i create mode 100644 Examples/test-suite/primitive_ref.i create mode 100644 Examples/test-suite/private_assign.i create mode 100644 Examples/test-suite/pure_virtual.i create mode 100644 Examples/test-suite/python/.cvsignore create mode 100644 Examples/test-suite/python/Makefile create mode 100644 Examples/test-suite/python/README create mode 100644 Examples/test-suite/python/abstract_typedef_runme.py create mode 100644 Examples/test-suite/python/class_ignore_runme.py create mode 100644 Examples/test-suite/python/constover_runme.py create mode 100644 Examples/test-suite/python/cpp_namespace_runme.py create mode 100644 Examples/test-suite/python/default_constructor_runme.py create mode 100644 Examples/test-suite/python/dynamic_cast_runme.py create mode 100644 Examples/test-suite/python/enum_runme.py create mode 100644 Examples/test-suite/python/extend_template_ns_runme.py create mode 100644 Examples/test-suite/python/extend_template_runme.py create mode 100644 Examples/test-suite/python/grouping_runme.py create mode 100644 Examples/test-suite/python/import_nomodule_runme.py create mode 100644 Examples/test-suite/python/imports_runme.py create mode 100644 Examples/test-suite/python/inherit_missing_runme.py create mode 100644 Examples/test-suite/python/lib_std_vector_runme.py create mode 100644 Examples/test-suite/python/minherit_runme.py create mode 100644 Examples/test-suite/python/namespace_typemap_runme.py create mode 100644 Examples/test-suite/python/overload_copy_runme.py create mode 100644 Examples/test-suite/python/overload_extend_runme.py create mode 100644 Examples/test-suite/python/overload_extendc_runme.py create mode 100644 Examples/test-suite/python/overload_simple_runme.py create mode 100644 Examples/test-suite/python/overload_subtype_runme.py create mode 100644 Examples/test-suite/python/overload_template_runme.py create mode 100644 Examples/test-suite/python/primitive_ref_runme.py create mode 100644 Examples/test-suite/python/rename_scope_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_multi_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_multi_typedef_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_not_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_overload_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_rename_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_simple_runme.py create mode 100644 Examples/test-suite/python/smart_pointer_typedef_runme.py create mode 100644 Examples/test-suite/python/sneaky1_runme.py create mode 100644 Examples/test-suite/python/static_const_member_2_runme.py create mode 100644 Examples/test-suite/python/struct_value_runme.py create mode 100644 Examples/test-suite/python/template_construct_runme.py create mode 100644 Examples/test-suite/python/template_inherit_runme.py create mode 100644 Examples/test-suite/python/template_ns4_runme.py create mode 100644 Examples/test-suite/python/template_ns_runme.py create mode 100644 Examples/test-suite/python/template_rename_runme.py create mode 100644 Examples/test-suite/python/template_tbase_template_runme.py create mode 100644 Examples/test-suite/python/template_type_namespace_runme.py create mode 100644 Examples/test-suite/python/template_typedef_cplx2_runme.py create mode 100644 Examples/test-suite/python/template_typedef_cplx3_runme.py create mode 100644 Examples/test-suite/python/template_typedef_cplx4_runme.py create mode 100644 Examples/test-suite/python/template_typedef_cplx_runme.py create mode 100644 Examples/test-suite/python/template_typedef_import_runme.py create mode 100644 Examples/test-suite/python/template_typedef_runme.py create mode 100644 Examples/test-suite/python/typedef_inherit_runme.py create mode 100644 Examples/test-suite/python/typedef_scope_runme.py create mode 100644 Examples/test-suite/python/typemap_namespace_runme.py create mode 100644 Examples/test-suite/python/typemap_ns_using_runme.py create mode 100644 Examples/test-suite/python/typename_runme.py create mode 100644 Examples/test-suite/python/unions_runme.py create mode 100644 Examples/test-suite/python/using1_runme.py create mode 100644 Examples/test-suite/python/using2_runme.py create mode 100644 Examples/test-suite/python/using_composition_runme.py create mode 100644 Examples/test-suite/python/using_extend_runme.py create mode 100644 Examples/test-suite/python/using_inherit_runme.py create mode 100644 Examples/test-suite/python/using_private_runme.py create mode 100644 Examples/test-suite/python/using_protected_runme.py create mode 100644 Examples/test-suite/python/voidtest_runme.py create mode 100644 Examples/test-suite/rename_default.i create mode 100644 Examples/test-suite/rename_scope.i create mode 100644 Examples/test-suite/ret_by_value.i create mode 100644 Examples/test-suite/return_value_scope.i create mode 100644 Examples/test-suite/rname.i create mode 100644 Examples/test-suite/ruby/.cvsignore create mode 100644 Examples/test-suite/ruby/Makefile create mode 100644 Examples/test-suite/ruby/README create mode 100755 Examples/test-suite/ruby/class_ignore_runme.rb create mode 100755 Examples/test-suite/ruby/constover_runme.rb create mode 100755 Examples/test-suite/ruby/cpp_namespace_runme.rb create mode 100755 Examples/test-suite/ruby/default_constructor_runme.rb create mode 100755 Examples/test-suite/ruby/dynamic_cast_runme.rb create mode 100755 Examples/test-suite/ruby/enum_runme.rb create mode 100644 Examples/test-suite/ruby/extend_template_ns_runme.rb create mode 100644 Examples/test-suite/ruby/extend_template_runme.rb create mode 100644 Examples/test-suite/ruby/grouping_runme.rb create mode 100755 Examples/test-suite/ruby/imports_runme.rb create mode 100644 Examples/test-suite/ruby/inherit_missing_runme.rb create mode 100755 Examples/test-suite/ruby/lib_std_vector_runme.rb create mode 100755 Examples/test-suite/ruby/namespace_typemap_runme.rb create mode 100644 Examples/test-suite/ruby/newobject1_runme.rb create mode 100644 Examples/test-suite/ruby/newobject2_runme.rb create mode 100755 Examples/test-suite/ruby/overload_copy_runme.rb create mode 100755 Examples/test-suite/ruby/overload_extend_runme.rb create mode 100755 Examples/test-suite/ruby/overload_extendc_runme.rb create mode 100755 Examples/test-suite/ruby/overload_simple_runme.rb create mode 100644 Examples/test-suite/ruby/overload_subtype_runme.rb create mode 100755 Examples/test-suite/ruby/overload_template_runme.rb create mode 100755 Examples/test-suite/ruby/primitive_ref_runme.rb create mode 100644 Examples/test-suite/ruby/rename_scope_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_const_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_multi_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_multi_typedef_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_not_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_overload_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_rename_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_simple_runme.rb create mode 100644 Examples/test-suite/ruby/smart_pointer_typedef_runme.rb create mode 100755 Examples/test-suite/ruby/sneaky1_runme.rb create mode 100755 Examples/test-suite/ruby/template_inherit_runme.rb create mode 100755 Examples/test-suite/ruby/template_ns4_runme.rb create mode 100755 Examples/test-suite/ruby/template_ns_runme.rb create mode 100755 Examples/test-suite/ruby/template_rename_runme.rb create mode 100755 Examples/test-suite/ruby/typedef_inherit_runme.rb create mode 100755 Examples/test-suite/ruby/typedef_scope_runme.rb create mode 100755 Examples/test-suite/ruby/typemap_namespace_runme.rb create mode 100755 Examples/test-suite/ruby/typename_runme.rb create mode 100644 Examples/test-suite/ruby/unions_runme.rb create mode 100644 Examples/test-suite/sizeof_pointer.i create mode 100644 Examples/test-suite/smart_pointer_const.i create mode 100644 Examples/test-suite/smart_pointer_multi.i create mode 100644 Examples/test-suite/smart_pointer_multi_typedef.i create mode 100644 Examples/test-suite/smart_pointer_not.i create mode 100644 Examples/test-suite/smart_pointer_overload.i create mode 100644 Examples/test-suite/smart_pointer_protected.i create mode 100644 Examples/test-suite/smart_pointer_rename.i create mode 100644 Examples/test-suite/smart_pointer_simple.i create mode 100644 Examples/test-suite/smart_pointer_typedef.i create mode 100644 Examples/test-suite/sneaky1.i create mode 100644 Examples/test-suite/static_array_member.i create mode 100644 Examples/test-suite/static_const_member.i create mode 100644 Examples/test-suite/static_const_member_2.i create mode 100644 Examples/test-suite/struct_value.i create mode 100644 Examples/test-suite/sym.i create mode 100644 Examples/test-suite/tcl/.cvsignore create mode 100644 Examples/test-suite/tcl/Makefile create mode 100644 Examples/test-suite/tcl/README create mode 100644 Examples/test-suite/tcl/import_nomodule_runme.tcl create mode 100644 Examples/test-suite/tcl/imports_runme.tcl create mode 100644 Examples/test-suite/tcl/overload_copy_runme.tcl create mode 100644 Examples/test-suite/tcl/overload_simple_runme.tcl create mode 100644 Examples/test-suite/tcl/primitive_ref_runme.tcl create mode 100644 Examples/test-suite/tcl/unions_runme.tcl create mode 100644 Examples/test-suite/template.i create mode 100644 Examples/test-suite/template_arg_scope.i create mode 100644 Examples/test-suite/template_arg_typename.i create mode 100644 Examples/test-suite/template_base_template.i create mode 100644 Examples/test-suite/template_classes.i create mode 100644 Examples/test-suite/template_const_ref.i create mode 100644 Examples/test-suite/template_construct.i create mode 100644 Examples/test-suite/template_default.i create mode 100644 Examples/test-suite/template_default2.i create mode 100644 Examples/test-suite/template_default_arg.i create mode 100644 Examples/test-suite/template_default_inherit.i create mode 100644 Examples/test-suite/template_default_qualify.i create mode 100644 Examples/test-suite/template_enum.i create mode 100644 Examples/test-suite/template_enum_ns_inherit.i create mode 100644 Examples/test-suite/template_enum_typedef.i create mode 100644 Examples/test-suite/template_forward.i create mode 100644 Examples/test-suite/template_inherit.i create mode 100644 Examples/test-suite/template_inherit_abstract.i create mode 100644 Examples/test-suite/template_int_const.i create mode 100644 Examples/test-suite/template_ns.i create mode 100644 Examples/test-suite/template_ns2.i create mode 100644 Examples/test-suite/template_ns3.i create mode 100644 Examples/test-suite/template_ns4.i create mode 100644 Examples/test-suite/template_ns_enum.i create mode 100644 Examples/test-suite/template_ns_enum2.i create mode 100644 Examples/test-suite/template_ns_inherit.i create mode 100644 Examples/test-suite/template_ns_scope.i create mode 100644 Examples/test-suite/template_qualifier.i create mode 100644 Examples/test-suite/template_rename.i create mode 100644 Examples/test-suite/template_retvalue.i create mode 100644 Examples/test-suite/template_specialization.i create mode 100644 Examples/test-suite/template_static.i create mode 100644 Examples/test-suite/template_tbase_template.i create mode 100644 Examples/test-suite/template_type_namespace.i create mode 100644 Examples/test-suite/template_typedef.i create mode 100644 Examples/test-suite/template_typedef_cplx.i create mode 100644 Examples/test-suite/template_typedef_cplx2.h create mode 100644 Examples/test-suite/template_typedef_cplx2.i create mode 100644 Examples/test-suite/template_typedef_cplx3.i create mode 100644 Examples/test-suite/template_typedef_cplx4.i create mode 100644 Examples/test-suite/template_typedef_import.i create mode 100644 Examples/test-suite/template_typedef_import.list create mode 100644 Examples/test-suite/template_virtual.i create mode 100644 Examples/test-suite/template_whitespace.i create mode 100644 Examples/test-suite/throw_exception.i create mode 100644 Examples/test-suite/typedef_array_member.i create mode 100644 Examples/test-suite/typedef_funcptr.i create mode 100644 Examples/test-suite/typedef_inherit.i create mode 100644 Examples/test-suite/typedef_mptr.i create mode 100644 Examples/test-suite/typedef_reference.i create mode 100644 Examples/test-suite/typedef_scope.i create mode 100644 Examples/test-suite/typemap_namespace.i create mode 100644 Examples/test-suite/typemap_ns_using.i create mode 100644 Examples/test-suite/typemap_subst.i create mode 100644 Examples/test-suite/typename.i create mode 100644 Examples/test-suite/union_scope.i create mode 100644 Examples/test-suite/unions.i create mode 100644 Examples/test-suite/using1.i create mode 100644 Examples/test-suite/using2.i create mode 100644 Examples/test-suite/using_composition.i create mode 100644 Examples/test-suite/using_extend.i create mode 100644 Examples/test-suite/using_inherit.i create mode 100644 Examples/test-suite/using_namespace.i create mode 100644 Examples/test-suite/using_private.i create mode 100644 Examples/test-suite/using_protected.i create mode 100644 Examples/test-suite/valuewrapper_base.i create mode 100644 Examples/test-suite/virtual_destructor.i create mode 100644 Examples/test-suite/voidtest.i create mode 100644 FUTURE create mode 100644 INSTALL create mode 100644 Lib/_std_deque.i delete mode 100644 Lib/array.i delete mode 100644 Lib/autodoc.i delete mode 100644 Lib/carray.i create mode 100644 Lib/carrays.i create mode 100644 Lib/cdata.i create mode 100644 Lib/cmalloc.i create mode 100644 Lib/cpointer.i create mode 100644 Lib/cstring.i delete mode 100644 Lib/ctype.i create mode 100644 Lib/guile/cplusplus.i create mode 100644 Lib/guile/list-vector.i create mode 100644 Lib/guile/pointer-in-out.i create mode 100644 Lib/guile/std_common.i create mode 100644 Lib/guile/std_string.i create mode 100644 Lib/guile/std_vector.i create mode 100644 Lib/guile/stl.i create mode 100644 Lib/java/arrays_java.i create mode 100644 Lib/java/javahead.swg create mode 100644 Lib/java/std_string.i create mode 100644 Lib/java/std_vector.i create mode 100644 Lib/java/stl.i create mode 100644 Lib/java/various.i delete mode 100644 Lib/malloc.i delete mode 100644 Lib/memory.i create mode 100644 Lib/mzscheme/mzscheme.i create mode 100644 Lib/mzscheme/mzschemedec.swg create mode 100644 Lib/mzscheme/std_common.i create mode 100644 Lib/mzscheme/std_string.i create mode 100644 Lib/mzscheme/std_vector.i create mode 100644 Lib/mzscheme/stl.i delete mode 100644 Lib/objc.i create mode 100644 Lib/ocaml/carray.i create mode 100644 Lib/ocaml/cstring.i create mode 100644 Lib/ocaml/extra-install.list create mode 100644 Lib/ocaml/libswigocaml.h create mode 100644 Lib/ocaml/libswigocaml.swg create mode 100644 Lib/ocaml/mlheading.swg create mode 100644 Lib/ocaml/mliheading.swg create mode 100644 Lib/ocaml/ocaml.i create mode 100644 Lib/ocaml/ocaml.swg create mode 100644 Lib/ocaml/ocamldec.swg create mode 100644 Lib/ocaml/std_common.i create mode 100644 Lib/ocaml/std_complex.i create mode 100644 Lib/ocaml/std_deque.i create mode 100644 Lib/ocaml/std_list.i create mode 100644 Lib/ocaml/std_string.i create mode 100644 Lib/ocaml/std_vector.i create mode 100644 Lib/ocaml/stl.i create mode 100644 Lib/ocaml/swig.ml create mode 100644 Lib/ocaml/typecheck.i create mode 100644 Lib/ocaml/typemaps.i create mode 100644 Lib/perl5/extra-install.list create mode 100644 Lib/perl5/perlrun.swg delete mode 100644 Lib/perl5/ptrlang.i create mode 100644 Lib/perl5/std_string.i create mode 100644 Lib/perl5/std_vector.i create mode 100644 Lib/perl5/stl.i create mode 100644 Lib/php4/php4.swg create mode 100644 Lib/php4/php4run.swg create mode 100644 Lib/php4/std_string.i create mode 100644 Lib/php4/std_vector.i create mode 100644 Lib/php4/stl.i create mode 100644 Lib/php4/typemaps.i create mode 100644 Lib/php4/utils.i create mode 100644 Lib/pike/pike.swg create mode 100644 Lib/pike/pikerun.swg create mode 100644 Lib/python/cstring.i delete mode 100644 Lib/python/embed13.i delete mode 100644 Lib/python/embed14.i create mode 100644 Lib/python/fragments.i delete mode 100644 Lib/python/ptrlang.i create mode 100644 Lib/python/pyrun.swg create mode 100644 Lib/python/std_common.i create mode 100644 Lib/python/std_complex.i create mode 100644 Lib/python/std_deque.i create mode 100644 Lib/python/std_list.i create mode 100644 Lib/python/std_string.i create mode 100644 Lib/python/std_vector.i create mode 100644 Lib/python/stl.i delete mode 100644 Lib/python/typemaps_old.i delete mode 100644 Lib/ruby/exception.i create mode 100644 Lib/ruby/extra-install.list create mode 100644 Lib/ruby/fragments.i delete mode 100644 Lib/ruby/ptrlang.i delete mode 100644 Lib/ruby/ruby.i create mode 100644 Lib/ruby/rubyhead.swg create mode 100644 Lib/ruby/std_common.i create mode 100644 Lib/ruby/std_string.i create mode 100644 Lib/ruby/std_vector.i create mode 100644 Lib/ruby/stl.i create mode 100644 Lib/std_deque.i delete mode 100644 Lib/stdlib.i delete mode 100644 Lib/tcl/constarray.i delete mode 100644 Lib/tcl/consthash.i create mode 100644 Lib/tcl/cstring.i delete mode 100644 Lib/tcl/object.swg delete mode 100644 Lib/tcl/ptrlang.i create mode 100644 Lib/tcl/std_string.i create mode 100644 Lib/tcl/std_vector.i create mode 100644 Lib/tcl/stl.i delete mode 100644 Lib/timers.i create mode 100644 Runtime/.cvsignore create mode 100644 Source/CParse/.cvsignore create mode 100644 Source/CParse/Makefile.in create mode 100644 Source/CParse/cparse.h create mode 100644 Source/CParse/cscanner.c create mode 100644 Source/CParse/parser.y create mode 100644 Source/CParse/templ.c create mode 100644 Source/CParse/util.c delete mode 100644 Source/DOH/Doh/Makefile create mode 100644 Source/Include/.cvsignore delete mode 100644 Source/Include/swigver.h create mode 100644 Source/Include/swigwarn.h create mode 100644 Source/Modules1.1/README create mode 100644 Source/Modules1.1/allocate.cxx create mode 100644 Source/Modules1.1/browser.cxx create mode 100644 Source/Modules1.1/contract.cxx delete mode 100644 Source/Modules1.1/generate.cxx delete mode 100644 Source/Modules1.1/guile.h delete mode 100644 Source/Modules1.1/java.h create mode 100644 Source/Modules1.1/module.cxx delete mode 100644 Source/Modules1.1/mzscheme.h create mode 100755 Source/Modules1.1/ocaml.cxx create mode 100644 Source/Modules1.1/overload.cxx delete mode 100644 Source/Modules1.1/perl5.h create mode 100644 Source/Modules1.1/php4.cxx create mode 100644 Source/Modules1.1/pike.cxx delete mode 100644 Source/Modules1.1/python.h delete mode 100644 Source/Modules1.1/ruby.h create mode 100644 Source/Modules1.1/s-exp.cxx delete mode 100644 Source/Modules1.1/swig11.h create mode 100644 Source/Modules1.1/swigmod.h delete mode 100644 Source/Modules1.1/tcl8.h create mode 100644 Source/Modules1.1/typepass.cxx delete mode 100644 Source/Modules1.1/xml.dtd delete mode 100644 Source/Modules1.1/xml.h create mode 100644 Source/README create mode 100644 Source/Swig/error.c create mode 100644 Source/Swig/fragment.c delete mode 100644 Source/Swig/main.c delete mode 100644 Source/Swig/map.c delete mode 100644 Source/Swig/module.c create mode 100644 Source/Swig/symbol.c create mode 100644 Source/Swig/typesys.c create mode 100644 Source/Swig/warn.c create mode 100644 Tools/.cvsignore delete mode 100644 Tools/WAD/Papers/WADTalk.pdf delete mode 100644 Tools/WAD/Papers/fig1.png delete mode 100644 Tools/WAD/Papers/python.html delete mode 100644 Tools/WAD/Papers/tcl.ps delete mode 100644 Tools/WAD/Papers/usenix2001.tex create mode 100644 Tools/aclocal.m4 create mode 100755 Tools/capitalize create mode 100644 Tools/check-include-path.pike delete mode 100755 Tools/ltconfig create mode 100644 Tools/setup.py.tmpl delete mode 100644 Tools/swig-1.3a1-1.spec delete mode 100644 Tools/swig.spec create mode 100644 Tools/swig.spec.1 create mode 100755 autogen.sh create mode 100644 debian/.cvsignore create mode 100644 debian/README create mode 100644 debian/changelog create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/dirs create mode 100644 debian/docs create mode 100644 debian/postinst create mode 100755 debian/rules create mode 100644 debian/substvars create mode 100644 swig.spec.in create mode 100644 vms/aaareadme.txt create mode 100644 vms/build_end.com create mode 100644 vms/build_init.com create mode 100644 vms/build_swig.com create mode 100644 vms/genbuild.py create mode 100644 vms/logicals.com create mode 100644 vms/scripts/build_all.com create mode 100644 vms/scripts/compil_cparse.com create mode 100644 vms/scripts/compil_doh.com create mode 100644 vms/scripts/compil_modules1_1.com create mode 100644 vms/scripts/compil_preprocessor.com create mode 100644 vms/scripts/compil_swig.com create mode 100644 vms/swigconfig.h create mode 100644 vms/swigver.h diff --git a/.cvsignore b/.cvsignore index d0405a8cd..ac494bc64 100644 --- a/.cvsignore +++ b/.cvsignore @@ -3,3 +3,6 @@ Makefile swig *.tar.gz configure +swig.spec +autom4te.cache +.gdbinit diff --git a/ANNOUNCE b/ANNOUNCE index fe6f534ba..e15fa0896 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,54 +1,45 @@ +*** ANNOUNCE: SWIG 1.3.16 *** -*** ANNOUNCE : SWIG1.3 (Alpha 5) *** +http://www.swig.org -September 22, 2000 +October 14, 2002 -Overview --------- -We're pleased to announce the next installment of the SWIG1.3 -redevelopment effort. This release represents a reasonably stable -snapshot of the CVS repository that has undergone extensive testing -and debugging. However, this release also represents work in progress -so there may be obscure bugs and problems that we haven't found yet. -Please send us your feedback. +We're pleased to announce SWIG 1.3.16, the latest installment in the +SWIG development effort. SWIG-1.3.16 is mostly a bug-fix release to +SWIG-1.3.15. + +What is SWIG? +------------- +SWIG is a software development tool that reads C/C++ header files and +generates the wrapper code needed to make C and C++ code accessible +from other languages including Perl, Python, Tcl, Ruby, PHP, Java, +Guile, Mzscheme, and Ocaml. Major applications of SWIG include +generation of scripting language extension modules, rapid prototyping, +testing, and user interface development for large C/C++ systems. Availability: ------------- The release is available for download on Sourceforge at - http://download.sourceforge.net/swig/swig1.3a5.tar.gz + http://prdownloads.sourceforge.net/swig/swig-1.3.16.tar.gz -What's new? ------------ -On the surface, this release still looks a lot like SWIG1.1p5 except -that a lot of bugs have been fixed and the language modules tend to -generate smaller and more efficient wrappers. New modules have also -been added to support Ruby and Mzscheme. In addition, Python, Perl, -and Guile support has been enhanced to support new releases such as -Python1.6 and Perl5.6. +Within the next day, a Windows version will also be made available at -Under the hood, you will find that this release is an almost complete -reimplementation of SWIG's internals. In fact the only code that -still remains from SWIG1.1 is the C/C++ parser and the language -modules (all of which have undergone significant changes as well). As -a result, a lot of minor improvements can be found throughout the -system and things that used to cause problems may now work (for -instance, pointers to functions are now supported). In addition, this -release incorporates a number of feature requests that have been made -on the mailing list. + http://prdownloads.sourceforge.net/swig/swigwin-1.3.16.zip -What's broken? --------------- -As this is a work in progress, a number of features are still missing -or incomplete. The documentation system is still missing and won't be -reimplemented for some time. The Java module is also temporarily out -of service for this release. In addition, C++ programmers who make -extensive use of typemaps may encounter a few strange problems -(although SWIG will generate warning messages). +Release numbers +--------------- +With SWIG1.3, we are adopting an odd/even version numbering scheme for +SWIG. Odd version numbers (1.3, 1.5, 1.7, etc...) are considered to +be development releases. Even numbers (1.4,1.6,1.8) are stable +releases. The current 1.3 effort is working to produce a stable 2.0 +release. A stable 2.0 release will not be made until it can +accompanied by fully updated documentation. In the meantime, we will +continue to make periodic 1.3.x releases. We need your help! ------------------ -Even if you are perfectly happy with SWIG1.1, we can use your +Even if you are perfectly happy with SWIG1.1, we can still use your feedback. First, we like to know about compilation problems and other issues concerning the building of SWIG. Second, if SWIG1.3 is unable to compile your old interface files, we would like to get information @@ -56,18 +47,28 @@ about the features you are using. This information will help us find bugs in the SWIG1.3 release, develop techniques for supporting backwards compatibility, and write documentation that addresses specific issues related to migrating from SWIG1.1 to SWIG1.3. -Finally, we are still looking for volunteers to work on aspects of -SWIG development. Please send email to beazley@cs.uchicago.edu for -details. + +We are also looking for volunteers who would like to work on various +aspects of SWIG development. SWIG is an unfunded project that would +not exist without volunteers. We are also looking for the developers +of other SWIG language modules. If you have developed a SWIG module +and would like to see it incorporated into the new release, please +contact us to obtain SWIG-CVS access. We are also more than willing +to help port your module from SWIG1.1 to SWIG1.3. Please send email +to beazley@cs.uchicago.edu for further information. Please report problems with this release to swig-dev@cs.uchicago.edu. --- The SWIG Developers -David Beazley -Thien-Thi Nguyen -Matthias Köppe -Masaki Fukushima -Harco de Hilster -Loic Dachary -Oleg Tolmatcev + + + + + + + + + + + diff --git a/CHANGES.current b/CHANGES.current new file mode 100644 index 000000000..6d1b6b357 --- /dev/null +++ b/CHANGES.current @@ -0,0 +1,232 @@ +Version 1.3.17 (November 22, 2002) +================================== +11/19/2002: beazley + Fixed [ 613922 ] preprocessor errors with HAVE_LONG_LONG. + +11/19/2002: beazley + Fixed [ 615480 ] mzscheme SWIG_MustGetPtr_. + +11/19/2002: beazley + Fixed [ 635119 ] SWIG_croak causes compiler warning. + +11/16/2002: cheetah (William Fulton) + [Java] Added typemaps for pointers to class members. + +11/15/2002: cheetah (William Fulton) + [Java] Bug fix: Overloaded C++ functions which cannot be overloaded in Java + once again issue a warning. + +11/14/2002: cheetah (William Fulton) + [Java] Handling of NULL pointers is improved. A java null object will now + be translated to and from a NULL C/C++ pointer by default. Previously when + wrapping: + + class SomeClass {...}; + void foo(SomeClass *s); + + and it was called from Java with null: + + modulename.foo(null) + + a Java NullPointerException was thrown. Extra typemaps had to be written in + order to obtain a NULL pointer to pass to functions like this one. Now the + default wrapping will detect 'null' and translate it into a NULL pointer. + Also if a function returns a NULL pointer, eg: + + SomeClass *bar() { return NULL; } + + Then this used to be wrapped with a SomeClass proxy class holding a NULL + pointer. Now null is returned instead. These changes are subtle but useful. + The original behaviour can be obtained by using the original typemaps: + + %typemap(javaout) SWIGTYPE { + return new $&javaclassname($jnicall, true); + } + %typemap(javaout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + return new $javaclassname($jnicall, $owner); + } + %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{ + protected static long getCPtr($javaclassname obj) { + return obj.swigCPtr; + } + %} + + *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** + + +11/12/2002: beazley + Fixed problem with abstract methods and signatures. For example: + + class abstract_foo { + public: + virtual int meth(int meth_param) = 0; + }; + + + class abstract_bar : public abstract_foo { + public: + int meth(int meth_param_1, int meth_param_2) { return 0; } + }; + + In this case, abstract_bar is still abstract. + + Fixes [ 628438 ] Derived abstract class not abstract. + Reported and patched by Scott Michel. + +11/11/2002: beazley + Fixed a matching problem with typemaps and array dimensions. For example, if you + had this: + + typedef char blah[20]; + + and a typemap: + + %typemap() char [ANY] { + ... $1_dim0 ... + } + + then $1_dim* variables weren't be expanded properly. It should work now. + Problem reported by Pankaj Kumar Goel. + +11/07/2002: mkoeppe + Added an experimental new module that dumps SWIG's parse + tree as (Common) Lisp s-expressions. The module is + invoked with SWIG's -sexp command-line switch. The output + can be read into Common Lisp. There is (prototype) + example Lisp code that generates Foreign Function Interface + definitions for use with Kevin Rosenberg's UFFI. + + *** EXPERIMENTAL NEW FEATURE *** + +11/07/2002: mkoeppe + Removed duplicate declaration of "cpp_template_decl" in + parser.y; bison 1.75 complained. + +11/06/2002: cheetah (William Fulton) + [Java] Default primitive array handling has changed like arrays of classes. + C primitive arrays are no longer wrapped by a Java array but with a pointer + (type wrapper class). Again the changes have been made for efficiency reasons. + The original typemaps have been moved into arrays_java.i, so the original + behaviour can be obtained merely including this file: + + %include "arrays_java.i" + + The array support functions are no longer generated by default. They are only + generated when including this file, thus this often unused code is only + generated when specifically requiring this type of array support. + + *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** + +11/05/2002: ljohnson (Lyle Johnson) + [Ruby] Added support for nested module declarations (as was + previously added for the Perl module). So a %module directive + of the form: + + %module "Outer::Inner::Foo" + + will nest everything as (in Ruby code): + + module Outer + module Inner + module Foo + # stuff goes here + end + end + end + +11/05/2002: mkoeppe + [MzScheme] Add an argument (-declaremodule) that generates + code to correctly declare a primitive module extension. + Patch submitted by Bruce Butterfield. + +11/02/2002: cheetah (William Fulton) + [Java] Added patch submitted by Michael Cahill to remove unused parameter + warnings for the jenv and cls parameters. This patch also also allows one + to use "void" in the jni typemap for any type without code being generated + attempting to return a value. + +10/29/2002: cheetah (William Fulton) + [Java] Array handling is different. Arrays of classes are no longer wrapped + with proxy arrays, eg wrapping + + class X {...}; + X foo[10]; + + used to be wrapped with these Java getters and setters: + + public static void setFoo(X[] value) {...} + public static X[] getFoo() {...} + + This approach is very inefficient as the entire array is copied numerous + times on each invocation of the getter or setter. These arrays are now + wrapped with a pointer so it is only possible to access the first array element + using a proxy class: + + public static void setFoo(X value) {...} + public static X getFoo() {...} + + Arrays of enums have also been similarly changed. This behaviour is now like the + other SWIG language's implementation and the array library should be used to + access the other elements. The original behaviour can be achieved using the + macros and typemaps in arrays_java.i, for example: + + %include "arrays_java.i" + JAVA_ARRAYSOFCLASSES(X) + class X {...}; + X foo[10]; + + *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** + +10/29/2002: cheetah (William Fulton) + [Java] Two new typemaps javain and javaout for generating the proxy class + and type wrapper class method calls to the JNI class. The new typemaps are + really used for transforming the jstype (used in proxy class and type wrapper + classes) to the jtype (used in the JNI class) and visa versa. A javain typemap + is required whenever an in typemap is written and similarly javaout for an out + typemap. An example is probably best to show them working: + + %typemap(javain) Class "Class.getCPtr($javainput)" + %typemap(javain) unsigned short "$javainput" + %typemap(javaout) Class * { + return new Class($jnicall, $owner); + } + + %inline %{ + class Class {}; + Class * bar(Class cls, unsigned short ush) { return new Class(); }; + %} + + The generated proxy code is then: + + public static Class bar(Class cls, int ush) { + return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false); + } + + + Some new special variables have been introduced in order to use these typemaps. + Here $javainput has been replaced by 'cls' and 'ush'. $jnicall has been replaced by + the native method call, 'exampleJNI.bar(...)' and $owner has been replaced by 'false'. + $javainput is analogous to the $input special variable. It is replaced by the parameter name. + $jnicall is analogous to $action in %exception. It is replaced by the call to the native + method in the JNI class. + $owner is replaced by either true if %newobject has been used otherwise false. + + The java.swg file contains default javain and javout typemaps which will produce the same code + as previously. This change is only of concern to those who have written their own typemaps as + you will then most likely have to write your own javain and javaout typemaps. + + The javaout typemap also makes it possible to use a Java downcast to be used on abstract + proxy base classes. See the Java documentation on dynamic_cast. + + *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** + +10/24/2002: ttn + [Methodology] Upgaded to libtool 1.4.3, presumably w/ better + support for newish platforms (like MacOS X). + +10/21/2002: ttn + Fixed Runtime/Makefile.in bug -- thanks to Richard Calmbach. + +10/18/2002: ttn + Fixed typo in doh.h -- thanks to Max Horn. + diff --git a/Doc/engineering.html b/Doc/Devel/engineering.html similarity index 96% rename from Doc/engineering.html rename to Doc/Devel/engineering.html index e9d60b347..7427e2f5d 100644 --- a/Doc/engineering.html +++ b/Doc/Devel/engineering.html @@ -81,15 +81,10 @@ observing the practices of other successful projects. All SWIG modules must be written in either ANSI C or one of the scripting languages for which SWIG can generate an interface (e.g., -Perl, Python, or Tcl). C++ is NOT an acceptable alternative and -will not be utilized for any future development due to the fact that -it is too complicated, too dogmatic, too problematic, and that Dave -would rather take a bullet to the head than write one more line of -code in this most decidedly unpleasant language. Rare exceptions -to this rule may be made if there is a justifiable need to interface -an existing piece of software written in C++ into the SWIG module -system. Anyone who finds this rule to be unreasonable is more than -welcome to go write their own wrapper generator--so there. +Perl, Python, or Tcl). C++ is currently being used to write +SWIG modules, but it is only being utilized to avoid working with +a lot of pointers to functions. Advanced C++ features like namespaces, templates, +and overloading should not be used..

Module writers should make every attempt to use only those functions diff --git a/Doc/index.html b/Doc/Devel/index.html similarity index 86% rename from Doc/index.html rename to Doc/Devel/index.html index 2ab1d6937..68074fe21 100644 --- a/Doc/index.html +++ b/Doc/Devel/index.html @@ -7,7 +7,6 @@ This directory contains SWIG documentation:

\n" + + if subsection == 1: + index += "\n" + +if section: + index += "\n" + +index += "\n" + +data = "\n".join(result) + +data = data.replace("@INDEX@",index); + +# Write the file back out +open(filename,"w").write(data) + +# Print the TOC data + +index = index.replace("#n","%s#n" % filename) +print """

%d %s

\n""" % (filename,num,name) +print index + + + + diff --git a/Doc/Manual/maketoc.py b/Doc/Manual/maketoc.py new file mode 100644 index 000000000..16583df7b --- /dev/null +++ b/Doc/Manual/maketoc.py @@ -0,0 +1,36 @@ +#!/usr/local/bin/python + +import sys +import os +chs = open("chapters").readlines() + +f = open("Contents.html","w") +print >>f, """ + + +SWIG Users Manual + + +

SWIG Users Manual

+ +

+""" + +f.close() + +num = 0 + +for c in chs: + c = c.strip() + print "Processing %s" % c + if c: + os.system("python makechap.py %s %d >> Contents.html" % (c,num)) + num += 1 + +f = open("Contents.html","a") +print >>f, """ + + +""" + + diff --git a/Doc/README b/Doc/README new file mode 100644 index 000000000..110428199 --- /dev/null +++ b/Doc/README @@ -0,0 +1,5 @@ +Doc/Manual - Latest version of the SWIG user manual +Doc/Devel - Developer documentation concerning SWIG internals. + (not necessarily up to date) + + \ No newline at end of file diff --git a/Doc/whitepaper.html b/Doc/whitepaper.html deleted file mode 100644 index 94a44057b..000000000 --- a/Doc/whitepaper.html +++ /dev/null @@ -1,363 +0,0 @@ - - -SWIG Project Overview - - -

-

The SWIG Redevelopment Effort

- -David Beazley
-Department of Computer Science
-University of Chicago
-Chicago, IL 60637
-beazley@cs.uchicago.edu
-
-
- -

-$Header$ - -

- -

1. An Introduction

- -One of the biggest problems faced by people writing software is the -problem how to make software easier to use, more interactive, and more -modular. Typically, the computer science community has approached -these problems by focusing on formal design methodology and highly -specified frameworks built around notions of software components, -object-oriented programming, and anything labeled as "best practice" -(whatever that means). Although this type of approach is perhaps -appropriate for very large software projects involving hundreds of -programmers, software engineers, and managers, I've never met a sane -programmer who really enjoys writing software in such an environment. -Furthermore, a large number of software projects are undertaken by -small groups of people who would not classify themselves as -professional software developers or software engineers. Typical -examples might include scientific computing software, specialized -systems for engineering applications, or just about any kind of -experimental research and development project. These are the types of -programming projects "in the small" that are my primary interest. - -

-First, programming projects in the small should not be confused with -the toy programs one might write as part of a class project or when -solving exceedingly trivial problems. More often that not, a software -package written by only a few people may have been developed over a -period of several years and may contain of hundreds of thousands of -lines of source code. Furthermore, due to limited manpower, these -projects are likely to rely on a variety of third-party packages and -programming libraries to accomplish certain tasks. Finally, it is not -uncommon for such software to have been developed in a relatively -piecemeal fashion with little if any formal design. The developers -may also be burdened with the task of supporting a large base of -legacy code that is critical to the application, but which is too -complicated to simply rewrite from scratch. As a result, the software -developed in such an environment may be a tangled web of code that -gets the job done, but which is less than ideal in terms of its -usuability and overall design. - -

-Of course, one does not need to look very far to see examples of this -kind of development. For instance, I would claim that just about -every successful project within the Open Source community has been -developed in this way. As a more specific example, Swig itself was -developed in a relatively adhoc manner over a period of two years. -Although it was my intent to have a relatively clean design at the -start, the system has since evolved into a very tangled mess of -monolithic C++ code. It's not that I wanted to end up in this -situation--rather the experience gained by Swig's early users pushed -the system in an unanticipated direction that the original design -failed to address. In many ways, it is ironic that SWIG should end up -in this particular state given that this is exactly the type -of situation that Swig was built to address! - -

-Naturally, this brings us to the overall motivation behind SWIG itself. -In a nutshell, SWIG is a software development tool that aims to make it -easier to do the following: - -

- -I also want to emphasize that the target users of Swig are not professional -software engineers. Rather the system is designed to be very easy to use for -more ordinary people who just happen to be working on programming projects as -part of their work or for fun (physicists, engineers, hackers, etc...). It is also -designed to provide a certain element of "instant gratification" if you will. I believe that -the following quotes from a SWIG user survey put things in the right perspective: - - - -

2. Problems with SWIG

- -Despite the early success of SWIG, the system suffers from a number of serious -limitations. Furthermore, these problems are not easily fixed within the current -design. - - - -Of course, the real trick is how one goes about solving these issues -without making Swig excessively complicated--both from the point of -development and use. - -

3. SWIG Redevelopment: Modules

- -Simply stated, the primary goal of SWIG redevlopment is to redesign -the SWIG compiler as an extensible set of loosely coupled modules -(Note: it is not my intent to radically change the way in which an -end-user uses SWIG). -In this context, my intent is to allow a module to be virtually anything -that might be part of a compiler or which would interact with a -compiler in some manner. For example: - - - -Unfortunately, as programs go, compilers tend to be extremely -complicated. Therefore, to make any sort of module system work, the -mechanism by which modules interact and exchange data needs to be -extremely powerful and extremely simple. - -

-To address these problems, SWIG redevelopment is based on a few fundamental ideas: - -

    -
  1. All data will be internally represented using an XML-like scheme -in which every piece of data is identified by a unique element "tag" -and a set of associated attributes. Manipulation of the data in turn -will involve nothing more than making an appropriate association of -the "tags" with some sort of "action" to be performed. Unlike an -approach in which objects are placed into a rigid C++ class hierarchy, -the XML-based approach allows a virtually unlimited number of -different object types and attributes to be created and manipulated without ever -having to recompile anything. As a result, this would allow modules to easily -extend the system in novel ways. It should also be added that this -data representation greatly simplifies the underlying core of -the system because an XML-like representation can be -built entirely using nothing more than a hash-table object and a -few fundamental datatypes such as strings and lists. - -

    -

  2. All underlying data structures will be built using a dynamic type -handling mechanism and a small collection of fundamental datatypes -including strings, lists, and hash tables. There are several -advantages to this approach. First, dynamic typing generally results -in substantially less code if done correctly. For instance, in my -own experiences using Objective-C vs. C++, I found that my dynamically -typed Objective-C programs were up to 5 times smaller than their C++ -counterparts. Furthermore, dynamic typing is also one of the reasons -why scripting languages are so powerful. - -

    -

  3. -Modules will interact with each other and exchange data using the XML-scheme -previously described. Due to the flexibility of this approach, this allows -modules to be written in a relatively stand-alone manner. Furthermore, the -use of XML may simplify the development of external tools that do not share -any commonality with the SWIG executable or its internal data structures. - -

    -

  4. Dynamic loading. Closely associated with loose-coupling, the SWIG module -system should optionally support dynamic loading of compiler modules. This might -be accomplished in two ways. First, I believe that SWIG itself should -provide a scripting interface that allows its modules to be dynamically -loaded into a variety of scripting languages. Second, SWIG -should probably implement some sort of module loading system that allows modules -to be used without the optional scripting interace. - -
- -Finally, it should be noted that the implementation language of choice for -the SWIG redevelopment effort is ANSI C. There are several reasons for this: - - - -

4. The Initial Module Set

- -The following list describes the proposed modules that will be part of the new -system: - - - - - - - - - - - diff --git a/Examples/GIFPlot/.cvsignore b/Examples/GIFPlot/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/Examples/GIFPlot/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/Examples/GIFPlot/Java/cmap b/Examples/GIFPlot/Common-Lisp/full/cmap similarity index 100% rename from Examples/GIFPlot/Java/cmap rename to Examples/GIFPlot/Common-Lisp/full/cmap diff --git a/Examples/GIFPlot/Common-Lisp/full/gifplot.i b/Examples/GIFPlot/Common-Lisp/full/gifplot.i new file mode 100644 index 000000000..e5c15aa2b --- /dev/null +++ b/Examples/GIFPlot/Common-Lisp/full/gifplot.i @@ -0,0 +1,21 @@ +/* Oh what the heck, let's just grab the whole darn header file + and see what happens. */ + +%module gifplot +%{ + +/* Note: You still need this part because the %include directive + merely causes SWIG to interpret the contents of a file. It doesn't + include the right include headers for the resulting C code */ + +#include "gifplot.h" + +%} + +/* Pixel is typedef'd to unsigned char, and SWIG will translate this + type into Scheme characters. We would like to translate Pixels to + Scheme integers instead, so: */ + +SIMPLE_MAP(Pixel, gh_scm2int, gh_int2scm, integer); + +%include gifplot.h diff --git a/Examples/GIFPlot/Common-Lisp/full/runme.lisp b/Examples/GIFPlot/Common-Lisp/full/runme.lisp new file mode 100644 index 000000000..48f804201 --- /dev/null +++ b/Examples/GIFPlot/Common-Lisp/full/runme.lisp @@ -0,0 +1,59 @@ +;;; Plot a 3D function + +;; Here is the function to plot +(defun func (x y) + (* 5 + (cos (* 2 (sqrt (+ (* x x) (* y y))))) + (exp (* -0.3 (sqrt (+ (* x x) (* y y))))))) + +;; Here are some plotting parameters +(defvar xmin -5D0) +(defvar xmax 5D0) +(defvar ymin -5D0) +(defvar ymax 5D0) +(defvar zmin -5D0) +(defvar zmax 5D0) + +;; Grid resolution +(defvar nxpoints 60) +(defvar nypoints 60) + +(defun drawsolid (p3) + (Plot3D-clear p3 0) + (Plot3D-start p3) + (let ((dx (/ (- xmax xmin) nxpoints)) + (dy (/ (- ymax ymin) nypoints)) + (cscale (/ 240 (- zmax zmin)))) + (loop for x from xmin by dx + repeat nxpoints + do (loop for y from ymin by dy + repeat nypoints + do (let* ((z1 (func x y)) + (z2 (func (+ x dx) y)) + (z3 (func (+ x dx) (+ y dy))) + (z4 (func x (+ y dy))) + (c1 (* cscale (- z1 zmin))) + (c2 (* cscale (- z2 zmin))) + (c3 (* cscale (- z3 zmin))) + (c4 (* cscale (- z4 zmin))) + (cc (/ (+ c1 c2 c3 c4) 4)) + (c (round (max (min cc 239) 0)))) + (Plot3D-solidquad p3 x y z1 (+ x dx) y z2 (+ x dx) (+ y dy) + z3 x (+ y dy) z4 (+ c 16))))))) + +(defun action (cmap-filename) + (let ((cmap (new-ColorMap cmap-filename)) + (frame (new-FrameBuffer 500 500))) + (format t "Making a nice 3D plot...~%") + (FrameBuffer-clear frame 0) + (let ((p3 (new-Plot3D frame xmin ymin zmin xmax ymax zmax))) + (Plot3D-lookat p3 (* 2 (- zmax zmin))) + (Plot3D-autoperspective p3 40D0) + (Plot3D-rotu p3 60D0) + (Plot3D-rotr p3 30D0) + (Plot3D-rotd p3 10D0) + (drawsolid p3)) + (FrameBuffer-writeGIF frame cmap "/tmp/image.gif") + (format t "Wrote image.gif~%"))) + + diff --git a/Examples/GIFPlot/Guile/check.list b/Examples/GIFPlot/Guile/check.list new file mode 100644 index 000000000..e75ee586a --- /dev/null +++ b/Examples/GIFPlot/Guile/check.list @@ -0,0 +1,3 @@ +# see top-level Makefile.in +full +simple diff --git a/Examples/GIFPlot/Guile/full/.cvsignore b/Examples/GIFPlot/Guile/full/.cvsignore new file mode 100644 index 000000000..7b4d35ff7 --- /dev/null +++ b/Examples/GIFPlot/Guile/full/.cvsignore @@ -0,0 +1,3 @@ +gifplot-guile +gifplot_wrap.c +image.gif diff --git a/Examples/GIFPlot/Guile/full/Makefile b/Examples/GIFPlot/Guile/full/Makefile index 608e394da..1fcdf58d2 100644 --- a/Examples/GIFPlot/Guile/full/Makefile +++ b/Examples/GIFPlot/Guile/full/Makefile @@ -5,23 +5,24 @@ SRCS = TARGET = gifplot INTERFACE = gifplot.i LIBS = -L../.. -lgifplot -lm -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: static dynamic:: $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \ SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile static:: $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \ SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile_static clean:: - rm -f *_wrap* *.o *~ *.so gifguile .~* core *.gif + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Guile/simple/.cvsignore b/Examples/GIFPlot/Guile/simple/.cvsignore new file mode 100644 index 000000000..46c5ec496 --- /dev/null +++ b/Examples/GIFPlot/Guile/simple/.cvsignore @@ -0,0 +1,4 @@ +gifguile +image.gif +simple-guile +simple_wrap.c diff --git a/Examples/GIFPlot/Guile/simple/Makefile b/Examples/GIFPlot/Guile/simple/Makefile index f3397cf22..7986214a0 100644 --- a/Examples/GIFPlot/Guile/simple/Makefile +++ b/Examples/GIFPlot/Guile/simple/Makefile @@ -5,23 +5,24 @@ SRCS = TARGET = simple INTERFACE = simple.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: static dynamic:: $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \ SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile static:: $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \ SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile_static clean:: - rm -f *_wrap* *.o *~ *.so gifguile .~* core *.gif + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Include/gifplot.h b/Examples/GIFPlot/Include/gifplot.h index f0fb3b183..921a5b63b 100644 --- a/Examples/GIFPlot/Include/gifplot.h +++ b/Examples/GIFPlot/Include/gifplot.h @@ -18,6 +18,10 @@ #ifndef GIFPLOT_H +#ifdef SWIG +%pragma no_default +#endif + /* Pixel is 8-bits */ typedef unsigned char Pixel; @@ -125,9 +129,9 @@ extern void delete_PixMap(PixMap *pm); extern void PixMap_set(PixMap *pm, int x, int y, int pix); extern void FrameBuffer_drawpixmap(FrameBuffer *f, PixMap *pm, int x, int y, int fgcolor, int bgcolor); -#define TRANSPARENT 0 -#define FOREGROUND 1 -#define BACKGROUND 2 +#define GIFPLOT_TRANSPARENT 0 +#define GIFPLOT_FOREGROUND 1 +#define GIFPLOT_BACKGROUND 2 /* ------------------------------------------------------------------------ Plot2D diff --git a/Examples/GIFPlot/Interface/gifplot.i b/Examples/GIFPlot/Interface/gifplot.i index 69a7cdbb9..57784f35f 100644 --- a/Examples/GIFPlot/Interface/gifplot.i +++ b/Examples/GIFPlot/Interface/gifplot.i @@ -11,8 +11,6 @@ typedef unsigned char Pixel; typedef float Zvalue; -%disabledoc - /* ------------------------------------------------------------------------ ColorMap @@ -23,14 +21,14 @@ typedef struct ColorMap { char *name; // -// %addmethods adds some C methods to this structure to make it +// %extend adds some C methods to this structure to make it // look like a C++ class in Python. // These are really named things like ColorMap_default, ColorMap_assign, etc... - %addmethods { + %extend { ColorMap(char *filename); ~ColorMap(); -#ifdef SWIGJAVA +#if defined(SWIGJAVA ) || defined(SWIGPHP4) %name(make_default) void default(); #else void default(); @@ -44,16 +42,6 @@ typedef struct ColorMap { /* Some default colors */ -#ifdef SWIGJAVA -const Pixel BLACK = 0; -const Pixel WHITE = 1; -const Pixel RED = 2; -const Pixel GREEN = 3; -const Pixel BLUE = 4; -const Pixel YELLOW = 5; -const Pixel CYAN = 6; -const Pixel MAGENTA = 7; -#else #define BLACK 0 #define WHITE 1 #define RED 2 @@ -62,7 +50,6 @@ const Pixel MAGENTA = 7; #define YELLOW 5 #define CYAN 6 #define MAGENTA 7 -#endif /*------------------------------------------------------------------------- FrameBuffer @@ -77,7 +64,7 @@ typedef struct FrameBuffer { int ymin; int xmax; int ymax; - %addmethods { + %extend { FrameBuffer(unsigned int width, unsigned int height); ~FrameBuffer(); void resize(int width, int height); @@ -119,9 +106,9 @@ extern PixMap *new_PixMap(int width, int height, int centerx, int centery); extern void delete_PixMap(PixMap *pm); extern void PixMap_set(PixMap *pm, int x, int y, int pix); -#define TRANSPARENT 0 -#define FOREGROUND 1 -#define BACKGROUND 2 +#define GIFPLOT_TRANSPARENT 0 +#define GIFPLOT_FOREGROUND 1 +#define GIFPLOT_BACKGROUND 2 /* -------------------------------------------------------------------------- Plot2D @@ -141,7 +128,7 @@ typedef struct Plot2D { double ymax; int xscale; /* Type of scaling (LINEAR, LOG, etc..) */ int yscale; - %addmethods { + %extend { Plot2D(FrameBuffer *frame,double xmin,double ymin, double xmax, double ymax); ~Plot2D(); Plot2D *copy(); @@ -203,7 +190,7 @@ typedef struct Plot3D { double lookatz; /* Where is the z-lookat point */ double xshift; /* Used for translation and stuff */ double yshift; - %addmethods { + %extend { Plot3D(FrameBuffer *frame, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax); ~Plot3D(); Plot3D *copy(); @@ -264,13 +251,11 @@ typedef struct Plot3D { /* These directives create constants of a specific type. They do not correspond to any C variable or declared constant in the header file */ -%constant(PixMap *) SQUARE = &PixMap_SQUARE; -%constant(PixMap *) TRIANGLE = &PixMap_TRIANGLE; -%constant(PixMap *) CROSS = &PixMap_CROSS; +%constant PixMap * SQUARE = &PixMap_SQUARE; +%constant PixMap * TRIANGLE = &PixMap_TRIANGLE; +%constant PixMap * CROSS = &PixMap_CROSS; #endif -%enabledoc - diff --git a/Examples/GIFPlot/Java/Makefile b/Examples/GIFPlot/Java/Makefile deleted file mode 100644 index 6017e1a77..000000000 --- a/Examples/GIFPlot/Java/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -TOP = ../.. -SWIG = $(TOP)/../swig -shadow -SWIGOPT = -I../Include -SRCS = -TARGET = libjgifplot -INTERFACE = gifplot.i -LIBS = -L.. -lgifplot -lm -INCLUDE = -I../Include - -all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java - -clean:: - rm -f *_wrap* *.o *~ *.so .~* core *.gif *.class ColorMap.java FrameBuffer.java Plot2D.java Plot3D.java gifplot.java - -check: all diff --git a/Examples/GIFPlot/Java/README b/Examples/GIFPlot/Java/README deleted file mode 100644 index 30058e52b..000000000 --- a/Examples/GIFPlot/Java/README +++ /dev/null @@ -1,30 +0,0 @@ -The gifplot example does not work straight out of the box, -I had to change ../Interface/gifplot.i slightly for java. - -a) -The colors (e.g. BLACK) where defined as: - - #define BLACK 0 - -and the functions expect 'Pixel color' where Pixel is a unsigned char. -#define constants contain no type information and are translated to integer -constants. Because of that, you have to cast every Pixel to a byte in java. - -Changing the definition to: - const Pixel BLACK = 0; -fixes this. - -b) -The definitions: - -const PixMap *SQUARE = &PixMap_SQUARE; -const PixMap *TRIANGLE = &PixMap_TRIANGLE; -const PixMap *CROSS = &PixMap_CROSS; - -don't work. -The wrapper code expects actual variables SQUARE, etc. and they are not -defined in gifplot.h. - -c) -In shadow mode the method ColorMap::default() clashes with the reserved name -default. diff --git a/Examples/GIFPlot/Java/check.list b/Examples/GIFPlot/Java/check.list new file mode 100644 index 000000000..13de977af --- /dev/null +++ b/Examples/GIFPlot/Java/check.list @@ -0,0 +1,4 @@ +# see top-level Makefile.in +full +shadow +simple diff --git a/Examples/GIFPlot/Java/cm15 b/Examples/GIFPlot/Java/cm15 deleted file mode 100644 index 7a8cd99b58dc0f11a6cdd13309e58d0de1ec7366..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 768 zcmaEK_vV!gr;i`rw`=RhH7l0PpFM3-Z)a;mO?h!%R$5|gM2Nq)yOW)zsez7$vb>a- z5Ca-u<>D8Wl2_HzH?^{N_3{smiciVPFR7|;>FS>{YyOf|>$mLOf8^x(D>v^ydHMd! z&;O)?e}Dh{{`K?6_itaneE#(D!-x0p-oAPL>g9{)&z?Sc{OIAs2lwyYy>t84%^TOR zUA=Po(xvlfPoF$~^zgy`dw1{LzGc&fRZHg0oZQ>dR8wAhI}dXJM?Xt|TKS z$j!>Y@QBX-|M}(p%P045UO9jA$o`#M)~{MJf7X=#u9o_$lKiZcc%b{dT^}KY#uH^Y`EXC)Gb_$%i19RR3STa_#!fTX*i>fAHw>(`V0LzI^ri k^_#bE-@X6v;p3-IpTB(l`tAGoA3uNn`u*q6-+%uZ0Llc9m;e9( diff --git a/Examples/GIFPlot/Java/full/.cvsignore b/Examples/GIFPlot/Java/full/.cvsignore new file mode 100644 index 000000000..2ef5d25c2 --- /dev/null +++ b/Examples/GIFPlot/Java/full/.cvsignore @@ -0,0 +1,7 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Java/full/Makefile b/Examples/GIFPlot/Java/full/Makefile new file mode 100644 index 000000000..8f167237d --- /dev/null +++ b/Examples/GIFPlot/Java/full/Makefile @@ -0,0 +1,20 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -I../../Include -noproxy +SRCS = +TARGET = gifplot +INTERFACE = gifplot.i +LIBS = -L../.. -lgifplot +INCLUDES = -I../../Include + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Java/full/README b/Examples/GIFPlot/Java/full/README new file mode 100644 index 000000000..f536864de --- /dev/null +++ b/Examples/GIFPlot/Java/full/README @@ -0,0 +1,8 @@ +This example runs the entire gifplot.h header file through SWIG without +any changes. The program 'main.java' does something a little more +interesting. After doing a make, run it using 'java main'. You'll have to go +look at the header file to get a complete listing of the functions. + +Note the differences in the main.java files between this example and the +'full' example. This example does not use shadow classes. + diff --git a/Examples/GIFPlot/Java/full/cmap b/Examples/GIFPlot/Java/full/cmap new file mode 100644 index 0000000000000000000000000000000000000000..a20c331a9573dd8443380680bfe2cc428780d8a9 GIT binary patch literal 768 zcmZQzpd(=A5)hSEP}Mdtvvzdz4h)M)OwTDSuW4%Uoiu&!q7`d5@7R0z#JS5i?>&C` z?#s{r^Z@9-XXO?YlTlLFHMX#G@$?UkN=VBFxv-;m^2~WlR;}N<`@pd?7q8!a^y1xT znmh34m-nxpKDd4D;+bOy_iW#^cE#d(Gbi_Tw$xXZ7G$R-M27|XxI5We80l&#%Snpx zbFrd(h8Vt}lCeu@T6xFJRlCpJeMef510DGC$^DyG&YwK8f9IC 239) c = 239; + gifplot.Plot3D_solidquad(p3,x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,(short)(c+16)); + y = y + dy; + } + x = x + dx; + } + + gifplot.FrameBuffer_writeGIF(frame,cmap,"image.gif"); + System.out.println( "Wrote image.gif" ); + } + + // Here is the function to plot + public static double func(double x, double y) { + return 5*java.lang.Math.cos(2*java.lang.Math.sqrt(x*x+y*y))*java.lang.Math.exp(-0.3*java.lang.Math.sqrt(x*x+y*y)); + } +} diff --git a/Examples/GIFPlot/Java/gifplot.i b/Examples/GIFPlot/Java/gifplot.i deleted file mode 100644 index b8f17f657..000000000 --- a/Examples/GIFPlot/Java/gifplot.i +++ /dev/null @@ -1,273 +0,0 @@ -// -// Graphics module -// -%module gifplot -%{ -#include "gifplot.h" -%} - -/* Pixel is 8-bits */ - -typedef unsigned char Pixel; -typedef float Zvalue; - -%disabledoc - -/* ------------------------------------------------------------------------ - ColorMap - - Definition and methods for colormaps - ------------------------------------------------------------------------ */ - -typedef struct ColorMap { - char *name; - -// -// %addmethods adds some C methods to this structure to make it -// look like a C++ class in Python. -// These are really named things like ColorMap_default, ColorMap_assign, etc... - - %addmethods { - ColorMap(char *filename); - ~ColorMap(); -#ifdef SWIGJAVA - %name(make_default) void default(); -#else - void default(); -#endif - void assign(int index,int r, int g, int b); - %name(__getitem__) int getitem(int index); - %name(__setitem__) void setitem(int index, int value); - int write(char *filename); - } -} ColorMap; - -/* Some default colors */ - -#ifdef SWIGJAVA -const Pixel BLACK = 0; -const Pixel WHITE = 1; -const Pixel RED = 2; -const Pixel GREEN = 3; -const Pixel BLUE = 4; -const Pixel YELLOW = 5; -const Pixel CYAN = 6; -const Pixel MAGENTA = 7; -#else -#define BLACK 0 -#define WHITE 1 -#define RED 2 -#define GREEN 3 -#define BLUE 4 -#define YELLOW 5 -#define CYAN 6 -#define MAGENTA 7 -#endif - -/*------------------------------------------------------------------------- - FrameBuffer - - This structure defines a simple 8 bit framebuffer. - ------------------------------------------------------------------------- */ - -typedef struct FrameBuffer { - unsigned int height; - unsigned int width; - int xmin; /* These are used for clipping */ - int ymin; - int xmax; - int ymax; - %addmethods { - FrameBuffer(unsigned int width, unsigned int height); - ~FrameBuffer(); - void resize(int width, int height); - void clear(Pixel color); - void plot(int x, int y, Pixel color); - void horizontal(int xmin, int xmax, int y, Pixel color); - void horizontalinterp(int xmin, int xmax, int y, Pixel c1, Pixel c2); - void vertical(int ymin, int ymax, int x, Pixel color); - void box(int x1, int y1, int x2, int y2, Pixel color); - void solidbox(int x1, int y1, int x2, int y2, Pixel color); - void interpbox(int x1, int y1, int x2, int y2, Pixel c1, Pixel c2, Pixel c3, Pixel c4); - void circle(int x1, int y1, int radius, Pixel color); - void solidcircle(int x1, int y1, int radius, Pixel color); - void line(int x1, int y1, int x2, int y2, Pixel color); - void setclip(int xmin, int ymin, int xmax, int ymax); - void noclip(); - int makeGIF(ColorMap *cmap, void *buffer, unsigned int maxsize); - void zresize(int width, int height); - void zclear(); - void drawchar(int x, int y, int fgcolor, int bgcolor, char chr, int orientation); - void drawstring(int x, int y, int fgcolor, int bgcolor, char *text, int orientation); - void drawpixmap(PixMap *pm, int x, int y, int fgcolor, int bgcolor); - int writeGIF(ColorMap *cmap, char *filename); - } -} FrameBuffer; - -#define HORIZONTAL 1 -#define VERTICAL 2 - -/* -------------------------------------------------------------------------- - PixMap - - The equivalent of "bit-maps". - -------------------------------------------------------------------------- */ - -/* PIXMAP methods */ - -extern PixMap *new_PixMap(int width, int height, int centerx, int centery); -extern void delete_PixMap(PixMap *pm); -extern void PixMap_set(PixMap *pm, int x, int y, int pix); - -#define TRANSPARENT 0 -#define FOREGROUND 1 -#define BACKGROUND 2 - -/* -------------------------------------------------------------------------- - Plot2D - - Definition and methods for 2D plots. - --------------------------------------------------------------------------- */ - -typedef struct Plot2D { - FrameBuffer *frame; - int view_xmin; /* Minimum coordinates of view region */ - int view_ymin; - int view_xmax; /* Maximum coordinates of view region */ - int view_ymax; - double xmin; /* Minimum coordinates of plot region */ - double ymin; - double xmax; /* Maximum coordinates of plot region */ - double ymax; - int xscale; /* Type of scaling (LINEAR, LOG, etc..) */ - int yscale; - %addmethods { - Plot2D(FrameBuffer *frame,double xmin,double ymin, double xmax, double ymax); - ~Plot2D(); - Plot2D *copy(); - void clear(Pixel c); - void setview(int vxmin, int vymin, int vxmax, int vymax); - void setrange(double xmin, double ymin, double xmax, double ymax); - void setscale(int xscale, int yscale); - void plot(double x, double y, Pixel color); - void box(double x1, double y1, double x2, double y2, Pixel color); - void solidbox(double x1, double y1, double x2, double y2, Pixel color); - void interpbox(double x1, double y1, double x2, double y2, Pixel c1, Pixel c2, Pixel c3, Pixel c4); - - void circle(double x, double y, double radius, Pixel color); - void solidcircle(double x, double y, double radius, Pixel color); - void line(double x1, double y1, double x2, double y2, Pixel color); - void start(); - void drawpixmap(PixMap *pm, double x, double y, Pixel color, Pixel bgcolor); - void xaxis(double x, double y, double xtick, int ticklength, Pixel color); - void yaxis(double x, double y, double ytick, int ticklength, Pixel color); - void triangle(double x1, double y1, double x2, double y2, double x3, double y3, Pixel c); - - void solidtriangle(double x1, double y1, double x2, double y2, double x3, double y3, Pixel c); - - void interptriangle(double x1, double y1, Pixel c1, - double x2, double y2, Pixel c2, - double x3, double y3, Pixel c3); - - } -} Plot2D; - -#define LINEAR 10 -#define LOG 11 - -/* ------------------------------------------------------------------------------ - Plot3D - - Data Structure for 3-D plots - ------------------------------------------------------------------------------ */ - -typedef struct Plot3D { - FrameBuffer *frame; - int view_xmin; /* Viewing region */ - int view_ymin; - int view_xmax; - int view_ymax; - double xmin; /* Bounding box */ - double ymin; - double zmin; - double xmax; - double ymax; - double zmax; - double xcenter; /* Center point */ - double ycenter; - double zcenter; - double fovy; /* Field of view */ - double aspect; /* Aspect ratio */ - double znear; /* near "clipping" plane */ - double zfar; /* far "clipping" plane */ - double lookatz; /* Where is the z-lookat point */ - double xshift; /* Used for translation and stuff */ - double yshift; - %addmethods { - Plot3D(FrameBuffer *frame, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax); - ~Plot3D(); - Plot3D *copy(); - void clear(Pixel bgcolor); - void perspective( double fovy, double znear, double zfar); - void lookat( double z); - void autoperspective( double fovy); - void ortho(double left, double right, double bottom, double top); - void autoortho(); - void rotx( double deg); - void roty( double deg); - void rotz( double deg); - void rotl( double deg); - void rotr( double deg); - void rotd( double deg); - void rotu( double deg); - void rotc( double deg); - void zoom( double percent); - void left( double percent); - void right( double percent); - void down( double percent); - void up( double percent); - void center( double cx, double cy); - void plot( double x, double y, double z, Pixel Color); - void setview( int vxmin, int vymin, int vxmax, int vymax); - void start(); - void line( double x1, double y1, double z1, - double x2, double y2, double z2, Pixel color); - void triangle( double x1, double y1, double z1, - double x2, double y2, double z2, - double x3, double y3, double z3, Pixel color); - void solidtriangle( double x1, double y1, double z1, - double x2, double y2, double z2, - double x3, double y3, double z3, Pixel color); - void interptriangle(double x1, double y1, double z1, Pixel c1, - double x2, double y2, double z2, Pixel c2, - double x3, double y3, double z3, Pixel c3); - void quad( double x1, double y1, double z1, - double x2, double y2, double z2, - double x3, double y3, double z3, - double x4, double y4, double z4, - Pixel color); - void solidquad( double x1, double y1, double z1, - double x2, double y2, double z2, - double x3, double y3, double z3, - double x4, double y4, double z4, - Pixel color); - void interpquad( double x1, double y1, double z1, Pixel c1, - double x2, double y2, double z2, Pixel c2, - double x3, double y3, double z3, Pixel c3, - double x4, double y4, double z4, Pixel c4); - void solidsphere( double x, double y, double z, double radius,Pixel c); - void outlinesphere( double x, double y, double z, double radius,Pixel c, Pixel bc); - } -} Plot3D; - -#ifndef SWIGJAVA -const PixMap *SQUARE = &PixMap_SQUARE; -const PixMap *TRIANGLE = &PixMap_TRIANGLE; -const PixMap *CROSS = &PixMap_CROSS; -#endif - -%enabledoc - - - - diff --git a/Examples/GIFPlot/Java/ortho.java b/Examples/GIFPlot/Java/ortho.java deleted file mode 100644 index 78d1d2cdd..000000000 --- a/Examples/GIFPlot/Java/ortho.java +++ /dev/null @@ -1,107 +0,0 @@ -import gifplot; - -public class ortho { - - static { - System.loadLibrary("jgifplot"); - }; - - public static double func(double x, double y) { - double r; - double f; - r = Math.sqrt(x*x + y*y); - - f = (Math.sin(0.30*r*x)+Math.cos(0.30*r*y))/(1.0+r); - return f; - } - - public static void main(String argv[]) { - - FrameBuffer f; - Plot3D p3; - ColorMap cm; - - double x,y; - double dx,dy; - double z1,z2,z3,z4; - int c1,c2,c3,c4; - - /* Create a framebuffer */ - - f = new FrameBuffer(700,400); - - /* Load a colormap */ - - cm = new ColorMap("cm15"); - - /* Create a new 2D image */ - - f.clear(gifplot.BLACK); - p3 = new Plot3D(f,-6.3,-6.3,-1.5,6.3,6.3,1.5); - - /* Set viewing region in 2D plot */ - - p3.setview(50,50,650,350); - - /* Set how far away from the image we are */ - p3.lookat(20); - - /* Set the field of view for the perspective */ - - -// Plot3D_autoperspective(p3,40); - - p3.autoortho(); - - /* Now make a plot of a 3D function */ - - /* Make a frame */ - - f.noclip(); - f.box(49,49,650,350,gifplot.WHITE); - p3.start(); /* Always call this prior to making an image */ - p3.clear(gifplot.BLACK); - p3.rotu(60); - p3.rotz(40); - x = -6.3; - dx = 0.25; - while (x < 6.3) { - y = -6.3; - dy = 0.25; - while (y < 6.3) { - z1 = func(x,y); - z2 = func(x+dx,y); - z3 = func(x+dx,y+dy); - z4 = func(x,y+dy); - c1 = (int) ((z1 + 1.0)*120) + 16; - if (c1 < 16) c1 = 16; - if (c1 > 254) c1 = 254; - - c2 = (int) ((z2 + 1.0)*120) + 16; - if (c2 < 16) c2 = 16; - if (c2 > 254) c2 = 254; - - c3 = (int) ((z3 + 1.0)*120) + 16; - if (c3 < 16) c3 = 16; - if (c3 > 254) c3 = 254; - - c4 = (int) ((z4 + 1.0)*120) + 16; - if (c4 < 16) c4 = 16; - if (c4 > 254) c4= 254; - - p3.interpquad(x,y,z1,(byte) c1, - x+dx,y,z2,(byte) c2, - x+dx,y+dy,z3,(byte) c3, - x,y+dy,z4,(byte) c4); - y = y + dy; - } - x = x + dx; - } - - /* Make a GIF file */ - - f.writeGIF(cm,"plot.gif"); - - System.out.println("Image written to 'plot.gif'"); - } -} diff --git a/Examples/GIFPlot/Java/shadow.java b/Examples/GIFPlot/Java/shadow.java deleted file mode 100644 index 34e9bf6f9..000000000 --- a/Examples/GIFPlot/Java/shadow.java +++ /dev/null @@ -1,22 +0,0 @@ -import gifplot; - -public class shadow { - - static { - System.loadLibrary("jgifplot"); - } - - public static void main(String argv[]) { - FrameBuffer fb = new FrameBuffer(300, 300); - ColorMap cm = new ColorMap("cmap"); - - fb.clear(gifplot.BLACK); - fb.drawstring(50, 50, gifplot.WHITE, gifplot.BLACK, "Hello world", gifplot.VERTICAL); - fb.solidbox(200, 200, 220, 240, gifplot.BLUE); - fb.line(0, 290, 293, 50, gifplot.RED); - fb.circle(100, 100, 10, gifplot.YELLOW); - fb.writeGIF(cm, "plot.gif"); - - System.out.println("Image written to 'plot.gif'"); - } -} diff --git a/Examples/GIFPlot/Java/shadow/.cvsignore b/Examples/GIFPlot/Java/shadow/.cvsignore new file mode 100644 index 000000000..2ef5d25c2 --- /dev/null +++ b/Examples/GIFPlot/Java/shadow/.cvsignore @@ -0,0 +1,7 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Java/shadow/Makefile b/Examples/GIFPlot/Java/shadow/Makefile new file mode 100644 index 000000000..e513b9b5a --- /dev/null +++ b/Examples/GIFPlot/Java/shadow/Makefile @@ -0,0 +1,20 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -I../../Interface +SRCS = +TARGET = gifplot +INTERFACE = gifplot.i +LIBS = -L../.. -lgifplot +INCLUDES = -I../../Include + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Java/shadow/README b/Examples/GIFPlot/Java/shadow/README new file mode 100644 index 000000000..4adbde306 --- /dev/null +++ b/Examples/GIFPlot/Java/shadow/README @@ -0,0 +1,5 @@ +This example uses the file in ../../Interface/gifplot.i to build +an interface with shadow classes. After doing a make, run the program main, ie: 'java main'. + +Note the differences in the main.java files between this example and the +'full' example. This example uses the shadow classes. diff --git a/Examples/GIFPlot/Java/shadow/cmap b/Examples/GIFPlot/Java/shadow/cmap new file mode 100644 index 0000000000000000000000000000000000000000..a20c331a9573dd8443380680bfe2cc428780d8a9 GIT binary patch literal 768 zcmZQzpd(=A5)hSEP}Mdtvvzdz4h)M)OwTDSuW4%Uoiu&!q7`d5@7R0z#JS5i?>&C` z?#s{r^Z@9-XXO?YlTlLFHMX#G@$?UkN=VBFxv-;m^2~WlR;}N<`@pd?7q8!a^y1xT znmh34m-nxpKDd4D;+bOy_iW#^cE#d(Gbi_Tw$xXZ7G$R-M27|XxI5We80l&#%Snpx zbFrd(h8Vt}lCeu@T6xFJRlCpJeMef510DGC$^DyG&YwK8f9IC 239) c = 239; + p3.solidquad(x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,(short)(c+16)); + y = y + dy; + } + x = x + dx; + } + + frame.writeGIF(cmap,"image.gif"); + System.out.println( "Wrote image.gif" ); + } + + // Here is the function to plot + public static double func(double x, double y) { + return 5*java.lang.Math.cos(2*java.lang.Math.sqrt(x*x+y*y))*java.lang.Math.exp(-0.3*java.lang.Math.sqrt(x*x+y*y)); + } +} diff --git a/Examples/GIFPlot/Java/simple.java b/Examples/GIFPlot/Java/simple.java deleted file mode 100644 index b5a243206..000000000 --- a/Examples/GIFPlot/Java/simple.java +++ /dev/null @@ -1,22 +0,0 @@ -import gifplot; - -public class simple { - - static { - System.loadLibrary("jgifplot"); - } - - public static void main(String argv[]) { - long f = gifplot.new_FrameBuffer(300, 300); - long c = gifplot.new_ColorMap("cmap"); - - gifplot.FrameBuffer_clear(f, gifplot.BLACK); - gifplot.FrameBuffer_drawstring(f, 50, 50, gifplot.WHITE, gifplot.BLACK, "Hello world", gifplot.HORIZONTAL); - gifplot.FrameBuffer_solidbox(f, 200, 200, 220, 240, gifplot.BLUE); - gifplot.FrameBuffer_line(f, 0, 290, 293, 50, gifplot.RED); - gifplot.FrameBuffer_circle(f, 100, 100, 10, gifplot.YELLOW); - gifplot.FrameBuffer_writeGIF(f, c, "plot.gif"); - - System.out.println("Image written to 'plot.gif'"); - } -} diff --git a/Examples/GIFPlot/Java/simple/.cvsignore b/Examples/GIFPlot/Java/simple/.cvsignore new file mode 100644 index 000000000..2ef5d25c2 --- /dev/null +++ b/Examples/GIFPlot/Java/simple/.cvsignore @@ -0,0 +1,7 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Java/simple/Makefile b/Examples/GIFPlot/Java/simple/Makefile new file mode 100644 index 000000000..d707fd458 --- /dev/null +++ b/Examples/GIFPlot/Java/simple/Makefile @@ -0,0 +1,21 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -noproxy +SRCS = +TARGET = simple +INTERFACE = simple.i +LIBS = -L../.. -lgifplot +INCLUDES = -I../../Include + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Java/simple/README b/Examples/GIFPlot/Java/simple/README new file mode 100644 index 000000000..1fb8453f0 --- /dev/null +++ b/Examples/GIFPlot/Java/simple/README @@ -0,0 +1,5 @@ +This is a very minimalistic example in which just a few functions +and constants from library are wrapped and used to draw some simple +shapes. After doing a make, run the java program, ie 'java main'. + + diff --git a/Examples/GIFPlot/Java/simple/main.java b/Examples/GIFPlot/Java/simple/main.java new file mode 100644 index 000000000..b165a4baa --- /dev/null +++ b/Examples/GIFPlot/Java/simple/main.java @@ -0,0 +1,41 @@ + +public class main { + + static { + try { + System.loadLibrary("simple"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + + // Draw some simple shapes + System.out.println( "Drawing some basic shapes" ); + + SWIGTYPE_p_ColorMap cmap = simple.new_ColorMap(null); + SWIGTYPE_p_FrameBuffer f = simple.new_FrameBuffer(400,400); + + // Clear the picture + simple.FrameBuffer_clear(f,(short)simple.BLACK); + + // Make a red box + simple.FrameBuffer_box(f,40,40,200,200,(short)simple.RED); + + // Make a blue circle + simple.FrameBuffer_circle(f,200,200,40,(short)simple.BLUE); + + // Make green line + simple.FrameBuffer_line(f,10,390,390,200, (short)simple.GREEN); + + // Write an image out to disk + + simple.FrameBuffer_writeGIF(f,cmap,"image.gif"); + System.out.println( "Wrote image.gif" ); + + simple.delete_FrameBuffer(f); + simple.delete_ColorMap(cmap); + } +} diff --git a/Examples/GIFPlot/Java/simple/simple.i b/Examples/GIFPlot/Java/simple/simple.i new file mode 100644 index 000000000..457bc4c09 --- /dev/null +++ b/Examples/GIFPlot/Java/simple/simple.i @@ -0,0 +1,38 @@ +/* This example shows a very simple interface wrapping a few + primitive declarations */ + +%module simple +%{ +#include "gifplot.h" +%} + +typedef unsigned char Pixel; + +/* Here are a few useful functions */ + +ColorMap *new_ColorMap(char *filename = 0); +void delete_ColorMap(ColorMap *cmap); + +FrameBuffer *new_FrameBuffer(unsigned int width, unsigned int height); +void delete_FrameBuffer(FrameBuffer *frame); +void FrameBuffer_clear(FrameBuffer *frame, Pixel color); +void FrameBuffer_line(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color); +void FrameBuffer_box(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color); +void FrameBuffer_circle(FrameBuffer *frame, int x1, int y1, int radius, Pixel color); +int FrameBuffer_writeGIF(FrameBuffer *f, ColorMap *c, char *filename); + +/* And some useful constants */ + +#define BLACK 0 +#define WHITE 1 +#define RED 2 +#define GREEN 3 +#define BLUE 4 +#define YELLOW 5 +#define CYAN 6 +#define MAGENTA 7 + + + + + diff --git a/Examples/GIFPlot/LICENSE b/Examples/GIFPlot/LICENSE deleted file mode 100644 index 95d776626..000000000 --- a/Examples/GIFPlot/LICENSE +++ /dev/null @@ -1,41 +0,0 @@ - -/********************************************************************** - * GIFPlot 0.0 - * - * Dave Beazley - * - * Department of Computer Science Theoretical Division (T-11) - * University of Utah Los Alamos National Laboratory - * Salt Lake City, Utah 84112 Los Alamos, New Mexico 87545 - * beazley@cs.utah.edu beazley@lanl.gov - * - * Copyright (c) 1996 - * The Regents of the University of California and the University of Utah - * All Rights Reserved - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that - * (1) The above copyright notice and the following two paragraphs - * appear in all copies of the source code and (2) redistributions - * including binaries reproduces these notices in the supporting - * documentation. Substantial modifications to this software may be - * copyrighted by their authors and need not follow the licensing terms - * described here, provided that the new terms are clearly indicated in - * all files where they apply. - * - * IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE - * UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH - * SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND - * THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - **************************************************************************/ diff --git a/Examples/GIFPlot/Lib/.cvsignore b/Examples/GIFPlot/Lib/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/Examples/GIFPlot/Lib/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/Examples/GIFPlot/Lib/Makefile.in b/Examples/GIFPlot/Lib/Makefile.in index 46e85e9d4..1cc6c4ffe 100644 --- a/Examples/GIFPlot/Lib/Makefile.in +++ b/Examples/GIFPlot/Lib/Makefile.in @@ -1,14 +1,14 @@ CC = @CC@ -INCLUDE = -I../Include +INCLUDES= -I../Include CFLAGS = -O SRCS = frame.c color.c plot2d.c plot3d.c font.c pixmap.c matrix.c gif.c -OBJS = $(SRCS:.c=.o) +OBJS = $(SRCS:.c=.@OBJEXT@) AR = @AR@ RANLIB = @RANLIB@ TARGET = ../libgifplot.a -.c.o: - $(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $< +.c.@OBJEXT@: + $(CC) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $< all: $(OBJS) @rm -f ../libgifplot.a @@ -16,6 +16,6 @@ all: $(OBJS) $(RANLIB) $(TARGET) clean: - rm -f *.o *~ $(TARGET) - + rm -f *.@OBJEXT@ *~ $(TARGET) +check: all diff --git a/Examples/GIFPlot/Lib/pixmap.c b/Examples/GIFPlot/Lib/pixmap.c index ff8e0bff0..a55cf041f 100644 --- a/Examples/GIFPlot/Lib/pixmap.c +++ b/Examples/GIFPlot/Lib/pixmap.c @@ -99,10 +99,10 @@ FrameBuffer_drawpixmap(FrameBuffer *f, PixMap *pm, int x, int y, int fgcolor, in for (i = startx; i < endx; i++) { c = pm->map[py*pm->width + px]; switch (c) { - case FOREGROUND: + case GIFPLOT_FOREGROUND: f->pixels[j][i] = fgcolor; break; - case BACKGROUND: + case GIFPLOT_BACKGROUND: f->pixels[j][i] = bgcolor; break; default: diff --git a/Examples/GIFPlot/Makefile.in b/Examples/GIFPlot/Makefile.in index 292c93e21..74c1d8253 100644 --- a/Examples/GIFPlot/Makefile.in +++ b/Examples/GIFPlot/Makefile.in @@ -16,8 +16,8 @@ install: $(RANLIB) $(exec_prefix)/lib/libgifplot.a clean:: - rm -f *.o *~ libgifplot.a *_wrap* *_man* + rm -f *.@OBJEXT@ *~ libgifplot.a *_wrap* *_man* cd Lib; $(MAKE) clean rm -f config.log config.status config.cache - +check: all diff --git a/Examples/GIFPlot/Ocaml/check.list b/Examples/GIFPlot/Ocaml/check.list new file mode 100644 index 000000000..e75ee586a --- /dev/null +++ b/Examples/GIFPlot/Ocaml/check.list @@ -0,0 +1,3 @@ +# see top-level Makefile.in +full +simple diff --git a/Examples/GIFPlot/Ocaml/full/Makefile b/Examples/GIFPlot/Ocaml/full/Makefile new file mode 100644 index 000000000..5b1e907f3 --- /dev/null +++ b/Examples/GIFPlot/Ocaml/full/Makefile @@ -0,0 +1,26 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -I../../Include +SRCS = +TARGET = gifcaml +INTERFACE = gifplot.i +LIBS = -L../.. -lgifplot -lm +INCLUDES = -I../../Include +MLFILE = gifplot.ml +IOBJS = runme.cmo +PROGFILE = runme.ml + +all:: static + +static:: + $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \ + IOBJS='$(IOBJS)' PROGFILE='$(PROGFILE)' \ + SRCS='$(SRCS)' SWIG='$(SWIG)' MLFILE='$(MLFILE)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static + +clean:: + $(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Ocaml/full/README b/Examples/GIFPlot/Ocaml/full/README new file mode 100644 index 000000000..4a2b400b5 --- /dev/null +++ b/Examples/GIFPlot/Ocaml/full/README @@ -0,0 +1,8 @@ +This example runs the entire gifplot.h header file through SWIG without +any changes. The ocaml program 'runme.ml' does something a little more +interesting. You'll have to go look at the header file to get a complete +listing of the functions. + + + + diff --git a/Examples/GIFPlot/Ocaml/full/cmap b/Examples/GIFPlot/Ocaml/full/cmap new file mode 100644 index 0000000000000000000000000000000000000000..a20c331a9573dd8443380680bfe2cc428780d8a9 GIT binary patch literal 768 zcmZQzpd(=A5)hSEP}Mdtvvzdz4h)M)OwTDSuW4%Uoiu&!q7`d5@7R0z#JS5i?>&C` z?#s{r^Z@9-XXO?YlTlLFHMX#G@$?UkN=VBFxv-;m^2~WlR;}N<`@pd?7q8!a^y1xT znmh34m-nxpKDd4D;+bOy_iW#^cE#d(Gbi_Tw$xXZ7G$R-M27|XxI5We80l&#%Snpx zbFrd(h8Vt}lCeu@T6xFJRlCpJeMef510DGC$^DyG&YwK8f9IC C_float x) + [ x ; y ; z1 ; + (x +. dx) ; y ; z2 ; + (x +. dx) ; (y +. dy) ; z3 ; + x ; (y +. dx) ; z4 ; + (float_of_int (c + 16)) ]))) ; + y_loop (y +. dy) (j + 1) + end in + begin + y_loop ymin 0 ; + x_loop (x +. dx) (i + 1) + end + end in + x_loop xmin 0 + end + +let _ = print_endline "Making a nice 3D plot..." +let _ = drawsolid () + +let _ = _FrameBuffer_writeGIF (C_list [ frame ; cmap ; C_string "image.gif" ]) +let _ = print_endline "Write image.gif" diff --git a/Examples/GIFPlot/Ocaml/simple/Makefile b/Examples/GIFPlot/Ocaml/simple/Makefile new file mode 100644 index 000000000..52d2a49a4 --- /dev/null +++ b/Examples/GIFPlot/Ocaml/simple/Makefile @@ -0,0 +1,26 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -I../../Include +SRCS = +TARGET = gifsimple +INTERFACE = simple.i +LIBS = -L../.. -lgifplot -lm +INCLUDES = -I../../Include +MLFILE = simple.ml +IOBJS = simple_wrap.o simple.cmo runme.cmo +PROGFILE = runme.ml + +all:: static + +static:: + $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \ + IOBJS='$(IOBJS)' PROGFILE='$(PROGFILE)' \ + SRCS='$(SRCS)' SWIG='$(SWIG)' MLFILE='$(MLFILE)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static + +clean:: + $(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Ocaml/simple/cmap b/Examples/GIFPlot/Ocaml/simple/cmap new file mode 100644 index 0000000000000000000000000000000000000000..a20c331a9573dd8443380680bfe2cc428780d8a9 GIT binary patch literal 768 zcmZQzpd(=A5)hSEP}Mdtvvzdz4h)M)OwTDSuW4%Uoiu&!q7`d5@7R0z#JS5i?>&C` z?#s{r^Z@9-XXO?YlTlLFHMX#G@$?UkN=VBFxv-;m^2~WlR;}N<`@pd?7q8!a^y1xT znmh34m-nxpKDd4D;+bOy_iW#^cE#d(Gbi_Tw$xXZ7G$R-M27|XxI5We80l&#%Snpx zbFrd(h8Vt}lCeu@T6xFJRlCpJeMef510DGC$^DyG&YwK8f9IC&C` z?#s{r^Z@9-XXO?YlTlLFHMX#G@$?UkN=VBFxv-;m^2~WlR;}N<`@pd?7q8!a^y1xT znmh34m-nxpKDd4D;+bOy_iW#^cE#d(Gbi_Tw$xXZ7G$R-M27|XxI5We80l&#%Snpx zbFrd(h8Vt}lCeu@T6xFJRlCpJeMef510DGC$^DyG&YwK8f9IC 239) { $c = 239; } + Plot3D_solidquad($p3, $x,$y,$z1,$x+$dx,$y,$z2,$x+$dx,$y+$dy,$z3,$x,$y+$dy,$z4,$c+16); + $y = $y + $dy; + } + $x = $x + $dx; + } +} + +print "Making a nice 3D plot...\n"; +drawsolid(); + +FrameBuffer_writeGIF($frame, $cmap,"image.gif"); +print "Wrote image.gif\n"; + +?> diff --git a/Examples/GIFPlot/Php/shadow/Makefile b/Examples/GIFPlot/Php/shadow/Makefile new file mode 100644 index 000000000..5627e53a0 --- /dev/null +++ b/Examples/GIFPlot/Php/shadow/Makefile @@ -0,0 +1,19 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -I../../Interface +SRCS = +TARGET = php_gifplot +INTERFACE = gifplot.i +LIBS = -L../.. -lgifplot -lm +INCLUDES = -I../../Include + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + $(MAKE) -f $(TOP)/Makefile php4_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Php/shadow/README b/Examples/GIFPlot/Php/shadow/README new file mode 100644 index 000000000..3e91f7d59 --- /dev/null +++ b/Examples/GIFPlot/Php/shadow/README @@ -0,0 +1,2 @@ +This example use the file in ../../Interface/gifplot.i to build +an interface with shadow classes. Run the script 'runme.php3'. diff --git a/Examples/GIFPlot/Php/shadow/cmap b/Examples/GIFPlot/Php/shadow/cmap new file mode 100644 index 0000000000000000000000000000000000000000..a20c331a9573dd8443380680bfe2cc428780d8a9 GIT binary patch literal 768 zcmZQzpd(=A5)hSEP}Mdtvvzdz4h)M)OwTDSuW4%Uoiu&!q7`d5@7R0z#JS5i?>&C` z?#s{r^Z@9-XXO?YlTlLFHMX#G@$?UkN=VBFxv-;m^2~WlR;}N<`@pd?7q8!a^y1xT znmh34m-nxpKDd4D;+bOy_iW#^cE#d(Gbi_Tw$xXZ7G$R-M27|XxI5We80l&#%Snpx zbFrd(h8Vt}lCeu@T6xFJRlCpJeMef510DGC$^DyG&YwK8f9ICclear(BLACK); + + +$p3 = new Plot3D($frame,$xmin,$ymin,$zmin,$xmax,$ymax,$zmax); +$p3->lookat(2*($zmax-$zmin)); +$p3->autoperspective(40); +$p3->rotu(60); +$p3->rotr(30); +$p3->rotd(10); + +function drawsolid() { + global $xmax; + global $xmin; + global $ymax; + global $ymin; + global $zmin; + global $zmax; + global $nxpoints; + global $nypoints; + global $p3; + + $p3->clear(BLACK); + $p3->start(); + $dx = 1.0*($xmax-$xmin)/$nxpoints; + $dy = 1.0*($ymax-$ymin)/$nypoints; + $cscale = 240.0/($zmax-$zmin); + $x = $xmin; + for ($i = 0; $i < $nxpoints; $i++) { + $y = $ymin; + for ($j = 0; $j < $nypoints; $j++) { + $z1 = func($x,$y); + $z2 = func($x+$dx,$y); + $z3 = func($x+$dx,$y+$dy); + $z4 = func($x,$y+$dy); + $c1 = $cscale*($z1-$zmin); + $c2 = $cscale*($z2-$zmin); + $c3 = $cscale*($z3-$zmin); + $c4 = $cscale*($z4-$zmin); + $c = ($c1+$c2+$c3+$c4)/4; + if ($c < 0) { $c = 0; } + if ($c > 239) { $c = 239; } + $p3->solidquad($x,$y,$z1,$x+$dx,$y,$z2,$x+$dx,$y+$dy,$z3,$x,$y+$dy,$z4,$c+16); + $y = $y + $dy; + } + $x = $x + $dx; + } +} + +print "Making a nice 3D plot...\n"; +drawsolid(); + +$frame->writeGIF($cmap,"image.gif"); +print "Wrote image.gif\n"; + +?> diff --git a/Examples/GIFPlot/Php/simple/Makefile b/Examples/GIFPlot/Php/simple/Makefile new file mode 100644 index 000000000..e49e22043 --- /dev/null +++ b/Examples/GIFPlot/Php/simple/Makefile @@ -0,0 +1,19 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = -noproxy +SRCS = +TARGET = php_simple +INTERFACE = simple.i +LIBS = -L../.. -lgifplot +INCLUDES = -I../../Include + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + $(MAKE) -f $(TOP)/Makefile php4_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Php/simple/README b/Examples/GIFPlot/Php/simple/README new file mode 100644 index 000000000..c2c799a70 --- /dev/null +++ b/Examples/GIFPlot/Php/simple/README @@ -0,0 +1,5 @@ +This is a very minimalistic example in which just a few functions +and constants from library are wrapped and used to draw some simple +shapes. The script 'runme.pl' runs the example. + + diff --git a/Examples/GIFPlot/Php/simple/runme.php4 b/Examples/GIFPlot/Php/simple/runme.php4 new file mode 100644 index 000000000..cf21a0927 --- /dev/null +++ b/Examples/GIFPlot/Php/simple/runme.php4 @@ -0,0 +1,32 @@ + + diff --git a/Examples/GIFPlot/Php/simple/simple.i b/Examples/GIFPlot/Php/simple/simple.i new file mode 100644 index 000000000..457bc4c09 --- /dev/null +++ b/Examples/GIFPlot/Php/simple/simple.i @@ -0,0 +1,38 @@ +/* This example shows a very simple interface wrapping a few + primitive declarations */ + +%module simple +%{ +#include "gifplot.h" +%} + +typedef unsigned char Pixel; + +/* Here are a few useful functions */ + +ColorMap *new_ColorMap(char *filename = 0); +void delete_ColorMap(ColorMap *cmap); + +FrameBuffer *new_FrameBuffer(unsigned int width, unsigned int height); +void delete_FrameBuffer(FrameBuffer *frame); +void FrameBuffer_clear(FrameBuffer *frame, Pixel color); +void FrameBuffer_line(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color); +void FrameBuffer_box(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color); +void FrameBuffer_circle(FrameBuffer *frame, int x1, int y1, int radius, Pixel color); +int FrameBuffer_writeGIF(FrameBuffer *f, ColorMap *c, char *filename); + +/* And some useful constants */ + +#define BLACK 0 +#define WHITE 1 +#define RED 2 +#define GREEN 3 +#define BLUE 4 +#define YELLOW 5 +#define CYAN 6 +#define MAGENTA 7 + + + + + diff --git a/Examples/GIFPlot/Pike/check.list b/Examples/GIFPlot/Pike/check.list new file mode 100644 index 000000000..d38998cab --- /dev/null +++ b/Examples/GIFPlot/Pike/check.list @@ -0,0 +1,2 @@ +# see top-level Makefile.in +simple diff --git a/Examples/GIFPlot/Pike/simple/.cvsignore b/Examples/GIFPlot/Pike/simple/.cvsignore new file mode 100644 index 000000000..0c4113eb0 --- /dev/null +++ b/Examples/GIFPlot/Pike/simple/.cvsignore @@ -0,0 +1,4 @@ +simple_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Pike/simple/Makefile b/Examples/GIFPlot/Pike/simple/Makefile new file mode 100644 index 000000000..d339e0333 --- /dev/null +++ b/Examples/GIFPlot/Pike/simple/Makefile @@ -0,0 +1,24 @@ +TOP = ../../.. +SWIG = $(TOP)/../swig +SWIGOPT = +SRCS = +TARGET = simple +INTERFACE = simple.i +LIBS = -L../.. -lgifplot +INCLUDES = -I../../Include + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + TARGET='mypike' INTERFACE='$(INTERFACE)' pike_static + +clean:: + $(MAKE) -f $(TOP)/Makefile pike_clean + rm -f *.gif + +check: all diff --git a/Examples/GIFPlot/Pike/simple/README b/Examples/GIFPlot/Pike/simple/README new file mode 100644 index 000000000..177b3633b --- /dev/null +++ b/Examples/GIFPlot/Pike/simple/README @@ -0,0 +1,5 @@ +This is a very minimalistic example in which just a few functions +and constants from library are wrapped and used to draw some simple +shapes. The script 'runme.pike' runs the example. + + diff --git a/Examples/GIFPlot/Pike/simple/runme.pike b/Examples/GIFPlot/Pike/simple/runme.pike new file mode 100644 index 000000000..0e70235f1 --- /dev/null +++ b/Examples/GIFPlot/Pike/simple/runme.pike @@ -0,0 +1,30 @@ +int main() +{ + // Draw some simple shapes + write("Drawing some basic shapes\n"); + + .simple.ColorMap cmap = .simple.new_ColorMap(); + .simple.FrameBuffer f = .simple.new_FrameBuffer(400, 400); + + // Clear the picture + .simple.FrameBuffer_clear(f, .simple.BLACK); + + // Make a red box + .simple.FrameBuffer_box(f, 40, 40, 200, 200, .simple.RED); + + // Make a blue circle + .simple.FrameBuffer_circle(f, 200, 200, 40, .simple.BLUE); + + // Make green line + .simple.FrameBuffer_line(f, 10, 390, 390, 200, .simple.GREEN); + + // Write an image out to disk + .simple.FrameBuffer_writeGIF(f, cmap, "image.gif"); + write("Wrote image.gif\n"); + + .simple.delete_FrameBuffer(f); + .simple.delete_ColorMap(cmap); + + return 0; +} + diff --git a/Examples/GIFPlot/Pike/simple/simple.i b/Examples/GIFPlot/Pike/simple/simple.i new file mode 100644 index 000000000..457bc4c09 --- /dev/null +++ b/Examples/GIFPlot/Pike/simple/simple.i @@ -0,0 +1,38 @@ +/* This example shows a very simple interface wrapping a few + primitive declarations */ + +%module simple +%{ +#include "gifplot.h" +%} + +typedef unsigned char Pixel; + +/* Here are a few useful functions */ + +ColorMap *new_ColorMap(char *filename = 0); +void delete_ColorMap(ColorMap *cmap); + +FrameBuffer *new_FrameBuffer(unsigned int width, unsigned int height); +void delete_FrameBuffer(FrameBuffer *frame); +void FrameBuffer_clear(FrameBuffer *frame, Pixel color); +void FrameBuffer_line(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color); +void FrameBuffer_box(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color); +void FrameBuffer_circle(FrameBuffer *frame, int x1, int y1, int radius, Pixel color); +int FrameBuffer_writeGIF(FrameBuffer *f, ColorMap *c, char *filename); + +/* And some useful constants */ + +#define BLACK 0 +#define WHITE 1 +#define RED 2 +#define GREEN 3 +#define BLUE 4 +#define YELLOW 5 +#define CYAN 6 +#define MAGENTA 7 + + + + + diff --git a/Examples/GIFPlot/Python/check.list b/Examples/GIFPlot/Python/check.list new file mode 100644 index 000000000..13de977af --- /dev/null +++ b/Examples/GIFPlot/Python/check.list @@ -0,0 +1,4 @@ +# see top-level Makefile.in +full +shadow +simple diff --git a/Examples/GIFPlot/Python/full/.cvsignore b/Examples/GIFPlot/Python/full/.cvsignore new file mode 100644 index 000000000..c5d112b05 --- /dev/null +++ b/Examples/GIFPlot/Python/full/.cvsignore @@ -0,0 +1,4 @@ +gifplot_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Python/full/Makefile b/Examples/GIFPlot/Python/full/Makefile index 361717c5c..ae927b72b 100644 --- a/Examples/GIFPlot/Python/full/Makefile +++ b/Examples/GIFPlot/Python/full/Makefile @@ -1,23 +1,25 @@ TOP = ../../.. SWIG = $(TOP)/../swig -SWIGOPT = -I../../Include +SWIGOPT = -I../../Include SRCS = TARGET = gifplot INTERFACE = gifplot.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core *.gif + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Python/full/runme.py b/Examples/GIFPlot/Python/full/runme.py index 1c73cec69..9f4ada602 100644 --- a/Examples/GIFPlot/Python/full/runme.py +++ b/Examples/GIFPlot/Python/full/runme.py @@ -1,5 +1,7 @@ # Plot a 3D function -from gifplot import * +# This example uses the low-level C interface. + +from _gifplot import * from math import * # Here is the function to plot diff --git a/Examples/GIFPlot/Python/shadow/.cvsignore b/Examples/GIFPlot/Python/shadow/.cvsignore new file mode 100644 index 000000000..7533bf0c4 --- /dev/null +++ b/Examples/GIFPlot/Python/shadow/.cvsignore @@ -0,0 +1,6 @@ +gifplot.py +gifplot.pyc +gifplot_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Python/shadow/Makefile b/Examples/GIFPlot/Python/shadow/Makefile index 82097b7e9..1f5014895 100644 --- a/Examples/GIFPlot/Python/shadow/Makefile +++ b/Examples/GIFPlot/Python/shadow/Makefile @@ -1,23 +1,25 @@ TOP = ../../.. SWIG = $(TOP)/../swig -SWIGOPT = -I../../Interface -shadow +SWIGOPT = -I../../Interface SRCS = -TARGET = gifplotc +TARGET = gifplot INTERFACE = gifplot.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core *.gif + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Python/simple/.cvsignore b/Examples/GIFPlot/Python/simple/.cvsignore new file mode 100644 index 000000000..0c4113eb0 --- /dev/null +++ b/Examples/GIFPlot/Python/simple/.cvsignore @@ -0,0 +1,4 @@ +simple_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Python/simple/Makefile b/Examples/GIFPlot/Python/simple/Makefile index e9b708633..5eb0344e8 100644 --- a/Examples/GIFPlot/Python/simple/Makefile +++ b/Examples/GIFPlot/Python/simple/Makefile @@ -5,19 +5,21 @@ SRCS = TARGET = simple INTERFACE = simple.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core *.gif + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + rm -f *.gif check: all diff --git a/Examples/GIFPlot/README b/Examples/GIFPlot/README index 7960a6f98..73ecddd76 100644 --- a/Examples/GIFPlot/README +++ b/Examples/GIFPlot/README @@ -4,7 +4,7 @@ GIFPlot To illustrate various SWIG features, the following examples involve building an interface to a small, but somewhat useful graphics library for creating 2D and 3D images in the form of GIF files. The Perl, -Python, Tcl, and Ruby directories contain various examples specific to +Python, Tcl, Java and Ruby directories contain various examples specific to those languages. This library was originally developed as part of the SPaSM molecular @@ -36,7 +36,7 @@ On Windows, you can probably just do this: Running the Examples ==================== -Once the library has been built, go the Perl, Python, Tcl, or Ruby directory +Once the library has been built, go the Perl, Python, Tcl, Java or Ruby directory to see various SWIG examples. Each example should have a README file with a description. diff --git a/Examples/GIFPlot/Ruby/check.list b/Examples/GIFPlot/Ruby/check.list new file mode 100644 index 000000000..13de977af --- /dev/null +++ b/Examples/GIFPlot/Ruby/check.list @@ -0,0 +1,4 @@ +# see top-level Makefile.in +full +shadow +simple diff --git a/Examples/GIFPlot/Ruby/full/.cvsignore b/Examples/GIFPlot/Ruby/full/.cvsignore new file mode 100644 index 000000000..c5d112b05 --- /dev/null +++ b/Examples/GIFPlot/Ruby/full/.cvsignore @@ -0,0 +1,4 @@ +gifplot_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Ruby/full/Makefile b/Examples/GIFPlot/Ruby/full/Makefile index 251fcb282..5af8bc832 100644 --- a/Examples/GIFPlot/Ruby/full/Makefile +++ b/Examples/GIFPlot/Ruby/full/Makefile @@ -5,19 +5,20 @@ SRCS = TARGET = gifplot INTERFACE = gifplot.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core *.gif + $(MAKE) -f $(TOP)/Makefile ruby_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Ruby/shadow/.cvsignore b/Examples/GIFPlot/Ruby/shadow/.cvsignore new file mode 100644 index 000000000..c5d112b05 --- /dev/null +++ b/Examples/GIFPlot/Ruby/shadow/.cvsignore @@ -0,0 +1,4 @@ +gifplot_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Ruby/shadow/Makefile b/Examples/GIFPlot/Ruby/shadow/Makefile index a0f6b6325..ea382ea88 100644 --- a/Examples/GIFPlot/Ruby/shadow/Makefile +++ b/Examples/GIFPlot/Ruby/shadow/Makefile @@ -5,19 +5,20 @@ SRCS = TARGET = gifplot INTERFACE = gifplot.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core *.gif + $(MAKE) -f $(TOP)/Makefile ruby_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Ruby/simple/.cvsignore b/Examples/GIFPlot/Ruby/simple/.cvsignore new file mode 100644 index 000000000..0c4113eb0 --- /dev/null +++ b/Examples/GIFPlot/Ruby/simple/.cvsignore @@ -0,0 +1,4 @@ +simple_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Ruby/simple/Makefile b/Examples/GIFPlot/Ruby/simple/Makefile index 7d44e5f0b..f7ca1a7d8 100644 --- a/Examples/GIFPlot/Ruby/simple/Makefile +++ b/Examples/GIFPlot/Ruby/simple/Makefile @@ -5,19 +5,20 @@ SRCS = TARGET = simple INTERFACE = simple.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core *.gif + $(MAKE) -f $(TOP)/Makefile ruby_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Tcl/check.list b/Examples/GIFPlot/Tcl/check.list new file mode 100644 index 000000000..2b6e3d28a --- /dev/null +++ b/Examples/GIFPlot/Tcl/check.list @@ -0,0 +1,4 @@ +# see top-level Makefile.in +full +mandel +simple diff --git a/Examples/GIFPlot/Tcl/full/.cvsignore b/Examples/GIFPlot/Tcl/full/.cvsignore new file mode 100644 index 000000000..c5d112b05 --- /dev/null +++ b/Examples/GIFPlot/Tcl/full/.cvsignore @@ -0,0 +1,4 @@ +gifplot_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Tcl/full/Makefile b/Examples/GIFPlot/Tcl/full/Makefile index c14250a27..0c016e364 100644 --- a/Examples/GIFPlot/Tcl/full/Makefile +++ b/Examples/GIFPlot/Tcl/full/Makefile @@ -5,19 +5,20 @@ SRCS = TARGET = gifplot INTERFACE = gifplot.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tcl static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o *~ *.so mytclsh .~* core *.gif + $(MAKE) -f $(TOP)/Makefile tcl_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Tcl/mandel/.cvsignore b/Examples/GIFPlot/Tcl/mandel/.cvsignore new file mode 100644 index 000000000..0d9d6a601 --- /dev/null +++ b/Examples/GIFPlot/Tcl/mandel/.cvsignore @@ -0,0 +1,4 @@ +mandel_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Tcl/mandel/Makefile b/Examples/GIFPlot/Tcl/mandel/Makefile index 703812129..9280d7bb2 100644 --- a/Examples/GIFPlot/Tcl/mandel/Makefile +++ b/Examples/GIFPlot/Tcl/mandel/Makefile @@ -5,19 +5,20 @@ SRCS = TARGET = gifplot INTERFACE = mandel.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tcl static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='mywish' INTERFACE='$(INTERFACE)' wish clean:: - rm -f *_wrap* *.o *~ *.so mywish .~* core *.gif + $(MAKE) -f $(TOP)/Makefile tcl_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/Tcl/simple/.cvsignore b/Examples/GIFPlot/Tcl/simple/.cvsignore new file mode 100644 index 000000000..0c4113eb0 --- /dev/null +++ b/Examples/GIFPlot/Tcl/simple/.cvsignore @@ -0,0 +1,4 @@ +simple_wrap.c +*.so +*.dll +*.gif diff --git a/Examples/GIFPlot/Tcl/simple/Makefile b/Examples/GIFPlot/Tcl/simple/Makefile index 9a49d7e89..752d79c10 100644 --- a/Examples/GIFPlot/Tcl/simple/Makefile +++ b/Examples/GIFPlot/Tcl/simple/Makefile @@ -5,19 +5,20 @@ SRCS = TARGET = simple INTERFACE = simple.i LIBS = -L../.. -lgifplot -INCLUDE = -I../../Include +INCLUDES = -I../../Include all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tcl static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ + INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \ TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o *~ *.so mytclsh .~* core *.gif + $(MAKE) -f $(TOP)/Makefile tcl_clean + rm -f *.gif check: all diff --git a/Examples/GIFPlot/configure b/Examples/GIFPlot/configure deleted file mode 100755 index 3997b4d84..000000000 --- a/Examples/GIFPlot/configure +++ /dev/null @@ -1,1299 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.13" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=Include/gifplot.h - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -ac_exeext= -ac_objext=o -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - - -# Set name for machine-dependent library files - -echo $ac_n "checking MACHDEP""... $ac_c" 1>&6 -echo "configure:530: checking MACHDEP" >&5 -if test -z "$MACHDEP" -then - if test -f /usr/lib/NextStep/software_version; then - set X `hostinfo | grep 'NeXT Mach.*:' | \ - sed -e 's/://' -e 's/\./_/'` && \ - ac_sys_system=next && ac_sys_release=$4 - MACHDEP="$ac_sys_system$ac_sys_release$ac_sys_cpu" - else - ac_sys_system=`uname -s` - if test "$ac_sys_system" = "AIX" ; then - ac_sys_release=`uname -v` - else - ac_sys_release=`uname -r` - fi - ac_md_system=`echo $ac_sys_system | - tr -d '/ ' | tr '[A-Z]' '[a-z]'` - ac_md_release=`echo $ac_sys_release | - tr -d '/ ' | sed 's/\..*//'` - MACHDEP="$ac_md_system$ac_md_release" - fi - case MACHDEP in - '') MACHDEP=unknown;; - esac -fi -echo "$ac_t""$MACHDEP" 1>&6 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:568: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:598: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test -z "$CC"; then - case "`uname -s`" in - *win32* | *WIN32*) - # Extract the first word of "cl", so it can be a program name with args. -set dummy cl; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:649: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="cl" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - ;; - esac - fi - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:681: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext << EOF - -#line 692 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:723: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:728: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes -else - GCC= -fi - -ac_test_CFLAGS="${CFLAGS+set}" -ac_save_CFLAGS="$CFLAGS" -CFLAGS= -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:756: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi - -# Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:790: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="ranlib" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -for ac_prog in ar aal -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:823: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AR="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -AR="$ac_cv_prog_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$AR" && break -done -test -n "$AR" || AR="ar" - - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:855: checking how to run the C preprocessor" >&5 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:876: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:893: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -nologo -E" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:935: checking for ANSI C header files" >&5 -if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#include -#include -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:948: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - ac_cv_header_stdc=yes -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. -cat > conftest.$ac_ext < -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "memchr" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. -cat > conftest.$ac_ext < -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "free" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. -if test "$cross_compiling" = yes; then - : -else - cat > conftest.$ac_ext < -#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int main () { int i; for (i = 0; i < 256; i++) -if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); -exit (0); } - -EOF -if { (eval echo configure:1015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - : -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_header_stdc=no -fi -rm -fr conftest* -fi - -fi -fi - -echo "$ac_t""$ac_cv_header_stdc" 1>&6 -if test $ac_cv_header_stdc = yes; then - cat >> confdefs.h <<\EOF -#define STDC_HEADERS 1 -EOF - -fi - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.13" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir - -trap 'rm -fr `echo "Makefile Lib/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@SHELL@%$SHELL%g -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@FFLAGS@%$FFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@MACHDEP@%$MACHDEP%g -s%@CC@%$CC%g -s%@RANLIB@%$RANLIB%g -s%@AR@%$AR%g -s%@CPP@%$CPP%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - - - - - - - diff --git a/Examples/GIFPlot/configure.in b/Examples/GIFPlot/configure.in deleted file mode 100644 index 271399590..000000000 --- a/Examples/GIFPlot/configure.in +++ /dev/null @@ -1,52 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(Include/gifplot.h) -AC_PREREQ(2.0) - -# Set name for machine-dependent library files -AC_SUBST(MACHDEP) -AC_MSG_CHECKING(MACHDEP) -if test -z "$MACHDEP" -then - if test -f /usr/lib/NextStep/software_version; then - set X `hostinfo | grep 'NeXT Mach.*:' | \ - sed -e 's/://' -e 's/\./_/'` && \ - ac_sys_system=next && ac_sys_release=$4 - MACHDEP="$ac_sys_system$ac_sys_release$ac_sys_cpu" - else - ac_sys_system=`uname -s` - if test "$ac_sys_system" = "AIX" ; then - ac_sys_release=`uname -v` - else - ac_sys_release=`uname -r` - fi - ac_md_system=`echo $ac_sys_system | - tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'` - ac_md_release=`echo $ac_sys_release | - tr -d '[/ ]' | sed 's/\..*//'` - MACHDEP="$ac_md_system$ac_md_release" - fi - case MACHDEP in - '') MACHDEP=unknown;; - esac -fi -AC_MSG_RESULT($MACHDEP) - -AC_LANG_C - -dnl Checks for programs. -AC_PROG_CC -AC_PROG_RANLIB -AC_SUBST(AR) -AC_CHECK_PROGS(AR, ar aal, ar) - -dnl Checks for header files. -AC_HEADER_STDC -dnl Checks for library functions. - -AC_OUTPUT(Makefile Lib/Makefile) - - - - - - diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 6ae82386d..cd0dcb336 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -12,10 +12,10 @@ # certain packages have been installed. Set the prefixes # accordingly. # -# 2. To use this makefile, simply set SRCS, INTERFACE, INCLUDE, LIBS, +# 2. To use this makefile, simply set SRCS, INTERFACE, INCLUDES, LIBS, # TARGET, and do a # $(MAKE) -f Makefile.template.in SRCS='$(SRCS)' \ -# INCLUDE='$(INCLUDE) LIBS='$(LIBS)' INTERFACE='$(INTERFACE)' \ +# INCLUDES='$(INCLUDES) LIBS='$(LIBS)' INTERFACE='$(INTERFACE)' \ # TARGET='$(TARGET)' method # # 'method' describes what is being built. @@ -28,11 +28,12 @@ CFLAGS = prefix = @prefix@ exec_prefix= @exec_prefix@ SRCS = -INCLUDE = +INCLUDES = LIBS = INTERFACE = SWIGOPT = -SWIG = SWIG +SWIG = swig@release_suffix@ +RUNTIMEDIR = $(exec_prefix)/lib LIBM = @LIBM@ LIBC = @LIBC@ @@ -47,7 +48,10 @@ libtool_link = $(TOP)/../Tools/libtool --mode link XLIB = @XLIBSW@ XINCLUDE = @XINCLUDES@ -ISRCS = $(INTERFACE:.i=_wrap.c) +IWRAP = $(INTERFACE:.i=_wrap.i) +ISRCS = $(IWRAP:.i=.c) +ICXXSRCS = $(IWRAP:.i=.cxx) +IOBJS = $(IWRAP:.i=.@OBJEXT@) ################################################################## # Dynamic loading for C++ @@ -68,15 +72,13 @@ CPP_DLLIBS = #-L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ SO= @SO@ LDSHARED= @LDSHARED@ CCSHARED= @CCSHARED@ -CXXSHARED= @LDSHARED@ +CXXSHARED= @CXXSHARED@ # This is used for building shared libraries with a number of C++ # compilers. If it doesn't work, comment it out. +@TRYLINKINGWITHCXX@ -CXXSHARED= @CXX@ -shared - -OBJS = $(SRCS:.c=.o) $(CXXSRCS:.cxx=.o) -IOBJS = $(ISRCS:.c=.o) +OBJS = $(SRCS:.c=.@OBJEXT@) $(CXXSRCS:.cxx=.@OBJEXT@) ################################################################## ##### Tcl/Tk ###### @@ -86,9 +88,12 @@ IOBJS = $(ISRCS:.c=.o) TCL_INCLUDE = @TCLINCLUDE@ TCL_LIB = @TCLLIB@ -TCL_OPTS = -ltcl @LIBS@ +TCL_OPTS = @LIBS@ TK_OPTS = -ltk -ltcl @LIBS@ +# Extra Tcl specific dynamic linking options +TCL_DLNK = @TCLDYNAMICLINKING@ + # ----------------------------------------------------------- # Build a new version of the tclsh shell # ----------------------------------------------------------- @@ -96,12 +101,12 @@ TK_OPTS = -ltk -ltcl @LIBS@ tclsh: $(SRCS) $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i $(INTERFACE) - $(CC) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDE) $(TCL_INCLUDE) \ + $(CC) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) \ $(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET) tclsh_cpp: $(SRCS) $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i $(INTERFACE) - $(CXX) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ISRCS) $(INCLUDE) $(TCL_INCLUDE) \ + $(CXX) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) \ $(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET) # ----------------------------------------------------------- @@ -110,13 +115,13 @@ tclsh_cpp: $(SRCS) wish: $(SRCS) $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -lwish.i $(INTERFACE) - $(CC) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDE) $(TCL_INCLUDE) \ + $(CC) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) \ $(XINCLUDE) $(TCL_LIB) $(TK_OPTS) $(XLIB) $(LIBS) $(SYSLIBS) -o $(TARGET) wish_cpp: $(SRCS) $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -lwish.i $(INTERFACE) - $(CXX) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ISRCS) $(INCLUDE) $(TCL_INCLUDE) \ + $(CXX) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) \ $(XINCLUDE) $(TCL_LIB) $(TK_OPTS) $(XLIB) $(LIBS) $(SYSLIBS) -o $(TARGET) # ----------------------------------------------------------- @@ -125,8 +130,8 @@ wish_cpp: $(SRCS) tcl: $(SRCS) $(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) $(INTERFACE) - $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDE) $(TCL_INCLUDE) - $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)$(SO) + $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(TARGET)$(SO) # ----------------------------------------------------------- # Build a Tcl7.5 dynamic loadable module for C++ @@ -134,8 +139,31 @@ tcl: $(SRCS) tcl_cpp: $(SRCS) $(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) $(INTERFACE) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ISRCS) $(INCLUDE) $(TCL_INCLUDE) - $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# ----------------------------------------------------------- +# Build a Tcl7.5 dynamic loadable module, linked against SWIG runtime lib +# ----------------------------------------------------------- + +TCL_RUNTIME=-L$(RUNTIMEDIR) -lswigtcl8@release_suffix@ + +tcl_multi: $(SRCS) + $(SWIG) -c -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(TCL_RUNTIME) $(TCL_DLNK) $(LIBS) -o $(TARGET)$(SO) + +tcl_multi_cpp: $(SRCS) + $(SWIG) -c -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(TCL_RUNTIME) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Cleaning the Tcl examples +# ----------------------------------------------------------------- + +tcl_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core mytclsh@EXEEXT@ ################################################################## ##### PERL 5 ###### @@ -147,6 +175,8 @@ tcl_cpp: $(SRCS) PERL5_INCLUDE= @PERL5EXT@ +# Extra Perl specific dynamic linking options +PERL5_DLNK = @PERL5DYNAMICLINKING@ # ---------------------------------------------------------------- # Build a Perl5 dynamically loadable module (C) @@ -154,8 +184,8 @@ PERL5_INCLUDE= @PERL5EXT@ perl5: $(SRCS) $(SWIG) -perl5 $(SWIGOPT) $(INTERFACE) - $(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDE) -I$(PERL5_INCLUDE) - $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)$(SO) + $(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PERL5_DLNK) $(LIBS) -o $(TARGET)$(SO) # ---------------------------------------------------------------- # Build a Perl5 dynamically loadable module (C++) @@ -163,30 +193,52 @@ perl5: $(SRCS) perl5_cpp: $(SRCS) $(SWIG) -perl5 -c++ $(SWIGOPT) $(INTERFACE) - $(CXX) -c $(CCSHARED) $(CFLAGS) -Dexplicit= $(SRCS) $(CXXSRCS) $(ISRCS) $(INCLUDE) -I$(PERL5_INCLUDE) - $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + $(CXX) -c $(CCSHARED) $(CFLAGS) -Dexplicit= $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PERL5_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# ---------------------------------------------------------------- +# Build a Perl5 dynamically loadable module, linked against SWIG runtime lib +# ---------------------------------------------------------------- + +PERL5_RUNTIME=-L$(RUNTIMEDIR) -lswigpl@release_suffix@ + +perl5_multi: $(SRCS) + $(SWIG) -c -perl5 $(SWIGOPT) $(INTERFACE) + $(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PERL5_RUNTIME) $(PERL5_DLNK) $(LIBS) -o $(TARGET)$(SO) + +perl5_multi_cpp: $(SRCS) + $(SWIG) -c -perl5 -c++ $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) -Dexplicit= $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PERL5_RUNTIME) $(PERL5_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) # ---------------------------------------------------------------- # Build a module from existing XS C source code. (ie. from xsubpp). # ---------------------------------------------------------------- perl5_xs: $(SRCS) - $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(INCLUDE) -I$(PERL5_INCLUDE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(LDSHARED) $(OBJS) $(LIBS) -o $(TARGET)$(SO) # ---------------------------------------------------------------- # Build a statically linked Perl5 executable # ---------------------------------------------------------------- -PERL5_LIB = -L$(PERL5_INCLUDE) -lperl @LIBS@ $(SYSLIBS) +PERL5_LIB = -L$(PERL5_INCLUDE) -l@PERL5LIB@ @LIBS@ $(SYSLIBS) perl5_static: $(SRCS) $(SWIG) -perl5 -static -lperlmain.i $(SWIGOPT) $(INTERFACE) - $(CC) $(CFLAGS) -Dbool=char $(SRCS) $(ISRCS) $(INCLUDE) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET) + $(CC) $(CFLAGS) -Dbool=char $(SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET) perl5_static_cpp: $(SRCS) $(SWIG) -perl5 -c++ -static -lperlmain.i $(SWIGOPT) $(INTERFACE) - $(CXX) $(CFLAGS) -Dexplicit= $(SRCS) $(CXXSRCS) $(ISRCS) $(INCLUDE) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET) + $(CXX) $(CFLAGS) -Dexplicit= $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET) +# ----------------------------------------------------------------- +# Cleaning the Perl5 examples +# ----------------------------------------------------------------- + +perl5_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core myperl@EXEEXT@ *.pm ################################################################## ##### PYTHON ###### @@ -196,14 +248,17 @@ perl5_static_cpp: $(SRCS) PYTHON_INCLUDE= -DHAVE_CONFIG_H @PYINCLUDE@ PYTHON_LIB = @PYLIB@ +# Extra Python specific dynamic linking options +PYTHON_DLNK = @PYTHONDYNAMICLINKING@ + # ---------------------------------------------------------------- # Build a C dynamically loadable module # ---------------------------------------------------------------- python: $(SRCS) $(SWIG) -python $(SWIGOPT) $(INTERFACE) - $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDE) $(PYTHON_INCLUDE) - $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)module$(SO) + $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(PYTHON_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o _$(TARGET)$(SO) # ----------------------------------------------------------------- # Build a C++ dynamically loadable module @@ -211,8 +266,25 @@ python: $(SRCS) python_cpp: $(SRCS) $(SWIG) -c++ -python $(SWIGOPT) $(INTERFACE) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDE) $(PYTHON_INCLUDE) - $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)module$(SO) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o _$(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build a dynamically loadable module, linked against SWIG Runtime lib +# ----------------------------------------------------------------- + +PYTHON_RUNTIME=-L$(RUNTIMEDIR) -lswigpy@release_suffix@ + +python_multi: $(SRCS) + $(SWIG) -c -python $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(PYTHON_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PYTHON_RUNTIME) $(PYTHON_DLNK) $(LIBS) -o _$(TARGET)$(SO) + +python_multi_cpp: $(SRCS) + $(SWIG) -c -c++ -python $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PYTHON_RUNTIME) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o _$(TARGET)$(SO) + # ----------------------------------------------------------------- # Build statically linked Python interpreter @@ -227,14 +299,20 @@ PYTHON_LIBOPTS = @PYLINK@ @LIBS@ $(TKINTER) $(SYSLIBS) python_static: $(SRCS) $(SWIG) -python -lembed.i $(SWIGOPT) $(INTERFACE) - $(CC) $(CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCS) $(INCLUDE) \ + $(CC) $(CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCS) $(INCLUDES) \ $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET) python_static_cpp: $(SRCS) $(SWIG) -c++ -python -lembed.i $(SWIGOPT) $(INTERFACE) - $(CXX) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDE) \ + $(CXX) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \ $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET) +# ----------------------------------------------------------------- +# Cleaning the python examples +# ----------------------------------------------------------------- + +python_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core mypython@EXEEXT@ *.pyc ################################################################## ##### GUILE ###### @@ -250,7 +328,7 @@ GUILE_LIB = @GUILELIB@ guile: $(SRCS) $(SWIG) -guile -Linkage ltdlmod $(SWIGOPT) $(INTERFACE) - $(CC) -c $(CCSHARED) $(CFLAGS) $(INCLUDE) $(GUILE_INCLUDE) $(ISRCS) $(SRCS) + $(CC) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(GUILE_INCLUDE) $(ISRCS) $(SRCS) $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o lib$(TARGET)$(SO) # ----------------------------------------------------------------- @@ -259,9 +337,40 @@ guile: $(SRCS) guile_cpp: $(SRCS) $(SWIG) -c++ -guile -Linkage ltdlmod $(SWIGOPT) $(INTERFACE) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(INCLUDE) $(GUILE_INCLUDE) $(ISRCS) $(SRCS) $(CXXSRCS) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(GUILE_INCLUDE) $(ICXXSRCS) $(SRCS) $(CXXSRCS) + $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o lib$(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build a dynamically loadable module with passive linkage +# ----------------------------------------------------------------- + +guile_passive: $(SRCS) + $(SWIG) -guile -Linkage passive $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(GUILE_INCLUDE) $(ISRCS) $(SRCS) $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o lib$(TARGET)$(SO) +guile_passive_cpp: $(SRCS) + $(SWIG) -c++ -guile -Linkage passive $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(GUILE_INCLUDE) $(ICXXSRCS) $(SRCS) $(CXXSRCS) + $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o lib$(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build a dynamically loadable module with passive linkage, +# linked against SWIG runtime lib +# ----------------------------------------------------------------- + +GUILE_RUNTIME=-L$(RUNTIMEDIR) -lswigguile@release_suffix@ + +guile_passive_multi: $(SRCS) + $(SWIG) -c -guile -Linkage passive $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(GUILE_INCLUDE) $(ISRCS) $(SRCS) + $(LDSHARED) $(OBJS) $(IOBJS) $(GUILE_RUNTIME) $(LIBS) -o lib$(TARGET)$(SO) + +guile_passive_multi_cpp: $(SRCS) + $(SWIG) -c -c++ -guile -Linkage passive $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(GUILE_INCLUDE) $(ICXXSRCS) $(SRCS) $(CXXSRCS) + $(CXXSHARED) $(OBJS) $(IOBJS) $(GUILE_RUNTIME) $(LIBS) $(CPP_DLLIBS) -o lib$(TARGET)$(SO) + # ----------------------------------------------------------------- # Build statically linked Guile interpreter # ----------------------------------------------------------------- @@ -270,16 +379,32 @@ GUILE_LIBOPTS = @GUILELINK@ @LIBS@ $(SYSLIBS) guile_static: $(SRCS) $(SWIG) -guile -lguilemain.i -Linkage ltdlmod $(SWIGOPT) $(INTERFACE) - $(CC) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDE) \ + $(CC) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) \ -DSWIGINIT="SCM scm_init_$(TARGET)_module(void); scm_init_$(TARGET)_module();" \ $(GUILE_INCLUDE) $(LIBS) -L$(GUILE_LIB) $(GUILE_LIBOPTS) -o $(TARGET)-guile guile_static_cpp: $(SRCS) $(SWIG) -c++ -guile -lguilemain.i -Linkage ltdlmod $(SWIGOPT) $(INTERFACE) - $(CXX) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDE) \ + $(CXX) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \ -DSWIGINIT="SCM scm_init_$(TARGET)_module(void); scm_init_$(TARGET)_module();" \ $(GUILE_INCLUDE) $(LIBS) -L$(GUILE_LIB) $(GUILE_LIBOPTS) -o $(TARGET)-guile +guile_simple: $(SRCS) + $(SWIG) -guile -lguilemain.i -Linkage simple $(SWIGOPT) $(INTERFACE) + $(CC) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) \ + $(GUILE_INCLUDE) $(LIBS) -L$(GUILE_LIB) $(GUILE_LIBOPTS) -o $(TARGET)-guile + +guile_simple_cpp: $(SRCS) + $(SWIG) -c++ -guile -lguilemain.i -Linkage simple $(SWIGOPT) $(INTERFACE) + $(CXX) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \ + $(GUILE_INCLUDE) $(LIBS) -L$(GUILE_LIB) $(GUILE_LIBOPTS) -o $(TARGET)-guile + +# ----------------------------------------------------------------- +# Cleaning the Guile examples +# ----------------------------------------------------------------- + +guile_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core my-guile@EXEEXT@ $(TARGET)@EXEEXT@ ################################################################## ##### JAVA ###### @@ -288,17 +413,20 @@ guile_static_cpp: $(SRCS) # You need to set this variable to the java directories containing the # files "jni.h" and "md.h" # usually something like /usr/java/include and /usr/java/include/. - JAVA_INCLUDE= @JAVAINC@ +# Extra Java specific dynamic linking options +JAVA_DLNK = @JAVADYNAMICLINKING@ +JAVALIBPREFIX = @JAVALIBRARYPREFIX@ + # ---------------------------------------------------------------- # Build a java dynamically loadable module (C) # ---------------------------------------------------------------- java: $(SRCS) $(SWIG) -java $(SWIGOPT) $(INTERFACE) - $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDE) $(JAVA_INCLUDE) - $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)$(SO) + $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JAVA_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(JAVA_DLNK) $(LIBS) -o $(JAVALIBPREFIX)$(TARGET)$(SO) # ---------------------------------------------------------------- # Build a java dynamically loadable module (C++) @@ -306,30 +434,130 @@ java: $(SRCS) java_cpp: $(SRCS) $(SWIG) -java -c++ $(SWIGOPT) $(INTERFACE) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ISRCS) $(INCLUDE) $(JAVA_INCLUDE) - $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JAVA_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(JAVA_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JAVALIBPREFIX)$(TARGET)$(SO) + +# ---------------------------------------------------------------- +# Build a java dynamically loadable module +# ---------------------------------------------------------------- + +java_multi: $(SRCS) + $(SWIG) -java $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JAVA_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(JAVA_DLNK) $(LIBS) -o $(JAVALIBPREFIX)$(TARGET)$(SO) + +java_multi_cpp: $(SRCS) + $(SWIG) -java -c++ $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JAVA_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(JAVA_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JAVALIBPREFIX)$(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Cleaning the java examples +# ----------------------------------------------------------------- + +java_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core *.class `find . -name \*.java | grep -v main.java` ################################################################## ##### MZSCHEME ###### ################################################################## -# ---------------------------------------------------------------- -# Build a C dynamically loadable module -# ---------------------------------------------------------------- - MZC = test -n "@MZC@" && @MZC@ +# ---------------------------------------------------------------- +# Build a C/C++ dynamically loadable module +# ---------------------------------------------------------------- + mzscheme: $(SRCS) $(SWIG) -mzscheme $(SWIGOPT) $(INTERFACE) - $(MZC) --cc $(ISRCS) $(SRCS) + $(MZC) ++ccf "$(INCLUDES)" --cc $(ISRCS) $(SRCS) $(MZC) --ld $(TARGET)$(SO) $(OBJS) $(IOBJS) +mzscheme_cpp: $(SRCS) + $(SWIG) -mzscheme -c++ $(SWIGOPT) $(INTERFACE) + $(MZC) ++ccf "$(INCLUDES)" --cc $(ICXXSRCS) $(SRCS) $(CXXSRCS) + $(MZC) --ld $(TARGET)$(SO) $(OBJS) $(IOBJS) $(CPP_DLLIBS) + +# ---------------------------------------------------------------- +# Build a dynamically loadable module, linked against SWIG runtime +# ---------------------------------------------------------------- + +MZSCHEME_RUNTIME=-L$(RUNTIMEDIR) -lswigmz@release_suffix@ + +mzscheme_multi: $(SRCS) + $(SWIG) -c -mzscheme $(SWIGOPT) $(INTERFACE) + $(MZC) ++ccf "$(INCLUDES)" --cc $(ISRCS) $(SRCS) + $(MZC) --ld $(TARGET)$(SO) $(OBJS) $(IOBJS) $(MZSCHEME_RUNTIME) + +mzscheme_multi_cpp: $(SRCS) + $(SWIG) -c -mzscheme -c++ $(SWIGOPT) $(INTERFACE) + $(MZC) ++ccf "$(INCLUDES)" --cc $(ICXXSRCS) $(SRCS) $(CXXSRCS) + $(MZC) --ld $(TARGET)$(SO) $(OBJS) $(IOBJS) $(MZSCHEME_RUNTIME) $(CPP_DLLIBS) + +# ----------------------------------------------------------------- +# Cleaning the mzscheme examples +# ----------------------------------------------------------------- + +mzscheme_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core + +################################################################## +##### Ocaml ##### +################################################################## + +OCC=@OCAMLC@ +NOLINK ?= false + +ocaml_static: $(SRCS) + $(SWIG) -ocaml $(SWIGOPT) $(INTERFACE) + $(OCC) -g -c -ccopt "$(INCLUDES)" $(ISRCS) $(SRCS) + $(OCC) -g -c $(INTERFACE:%.i=%.mli) + $(OCC) -g -c $(INTERFACE:%.i=%.ml) + test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ + $(OCC) -c $(PROGFILE) + $(NOLINK) || $(OCC) -g -custom -o $(TARGET) \ + $(INTERFACE:%.i=%.cmo) \ + $(PROGFILE:%.ml=%.cmo) \ + $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" + +ocaml_static_cpp: $(SRCS) + $(SWIG) -ocaml -c++ $(SWIGOPT) \ + $(INTERFACE) + cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) + $(OCC) -g -c -ccopt "-xc++ $(INCLUDES)" \ + $(ICXXSRCS:%.cxx=%.c) $(SRCS) $(CXXSRCS) + $(OCC) -g -c $(INTERFACE:%.i=%.mli) + $(OCC) -g -c $(INTERFACE:%.i=%.ml) + test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ + $(OCC) -c $(PROGFILE) + $(NOLINK) || $(OCC) -g -custom -o $(TARGET) $(INTERFACE:%.i=%.cmo) \ + $(INTERFACE:%.i=%_wrap.@OBJEXT@) -cclib "$(LIBS)" + +ocaml_static_multi_cpp: $(SRCS) + $(SWIG) -c -ocaml -c++ $(SWIGOPT) \ + $(INTERFACE) + cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) + $(OCC) -g -c -ccopt "-xc++ $(INCLUDES)" \ + $(ICXXSRCS:%.cxx=%.c) $(SRCS) $(CXXSRCS) + $(OCC) -g -c $(INTERFACE:%.i=%.mli) + $(OCC) -g -c $(INTERFACE:%.i=%.ml) + test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ + $(OCC) -c $(PROGFILE) + $(NOLINK) || $(OCC) -g -custom -o $(TARGET) $(INTERFACE:%.i=%.cmo) \ + $(INTERFACE:%.i=%_wrap.@OBJEXT@) -cclib "$(LIBS)" + +ocaml_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core *.cmo *.cmi $(MLFILE) $(MLFILE)i + ################################################################## ##### RUBY ###### ################################################################## # Make sure these locate your Ruby installation -RUBY_INCLUDE= -DHAVE_CONFIG_H @RUBYINCLUDE@ +RUBY_CFLAGS= @RUBYCCDLFLAGS@ -DHAVE_CONFIG_H +RUBY_INCLUDE= @RUBYINCLUDE@ +RUBY_LIB = @RUBYLIB@ +RUBY_DLNK = @RUBYDYNAMICLINKING@ # ---------------------------------------------------------------- # Build a C dynamically loadable module @@ -337,8 +565,8 @@ RUBY_INCLUDE= -DHAVE_CONFIG_H @RUBYINCLUDE@ ruby: $(SRCS) $(SWIG) -ruby $(SWIGOPT) $(INTERFACE) - $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDE) $(RUBY_INCLUDE) - $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)$(SO) + $(CC) -c $(CCSHARED) $(CFLAGS) $(RUBY_CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(RUBY_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) -o $(TARGET)$(SO) # ----------------------------------------------------------------- # Build a C++ dynamically loadable module @@ -346,8 +574,24 @@ ruby: $(SRCS) ruby_cpp: $(SRCS) $(SWIG) -c++ -ruby $(SWIGOPT) $(INTERFACE) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDE) $(RUBY_INCLUDE) - $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(RUBY_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build a dynamically loadable module, linked against SWIG runtime lib +# ----------------------------------------------------------------- + +RUBY_RUNTIME=-L$(RUNTIMEDIR) -lswigrb@release_suffix@ + +ruby_multi: $(SRCS) + $(SWIG) -c -ruby $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(RUBY_CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(RUBY_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(RUBY_RUNTIME) $(RUBY_DLNK) $(LIBS) -o $(TARGET)$(SO) + +ruby_multi_cpp: $(SRCS) + $(SWIG) -c -c++ -ruby $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(RUBY_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(RUBY_RUNTIME) $(RUBY_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) # ----------------------------------------------------------------- # Build statically linked Ruby interpreter @@ -356,29 +600,140 @@ ruby_cpp: $(SRCS) # library file # ----------------------------------------------------------------- -RUBY_LIB = @RUBYLIB@ RUBY_LIBOPTS = @RUBYLINK@ @LIBS@ $(SYSLIBS) ruby_static: $(SRCS) $(SWIG) -ruby -lembed.i $(SWIGOPT) $(INTERFACE) - $(CC) $(CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCS) $(INCLUDE) \ + $(CC) $(CFLAGS) $(RUBY_CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCS) $(INCLUDES) \ $(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET) -ruby_static_cpp: $(SRCS) +ruby_cpp_static: $(SRCS) $(SWIG) -c++ -ruby -lembed.i $(SWIGOPT) $(INTERFACE) - $(CXX) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDE) \ + $(CXX) $(CFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \ $(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET) +# ----------------------------------------------------------------- +# Cleaning the Ruby examples +# ----------------------------------------------------------------- + +ruby_clean: + rm -f *.@OBJEXT@ *@SO@ *_wrap* *~ .~* core myruby@EXEEXT@ *.pm + ################################################################## -##### SWIG ###### +##### PHP ###### ################################################################## -# Build a new SWIG extension +# ------------------------------------------------------------------- +# Build a PHP4 dynamically loadable module (C) +# ------------------------------------------------------------------- -SWIGINCLUDE = -I${prefix}/include -SWIGLIB = -L${exec_prefix}/lib +PHP4_INCLUDE = @PHP4INC@ -swig: $(SRCS) - $(CXX) $(SRCS) $(SWIGINCLUDE) $(INCLUDE) $(SWIGLIB) $(LIBS) -lswig -o $(TARGET) +php4: $(SRCS) + $(SWIG) -php4 -cppext cxx $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(PHP4_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)$(SO) + +# -------------------------------------------------------------------- +# Build a PHP4 dynamically loadable module (C++) +# -------------------------------------------------------------------- + +php4_cpp: $(SRCS) + $(SWIG) -php4 -cppext cxx -c++ $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP4_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# --------------------------------------------------------------------- +# Build a dynamically loadable module, linked against SWIG Runtime lib +# --------------------------------------------------------------------- + +PHP4_RUNTIME=-L$(RUNTIMEDIR) -lswigphp4@release_suffix@ + +php4_multi: $(SRCS) + $(SWIG) -c -php4 -cppext cxx $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(PHP4_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PHP4_RUNTIME) $(PHP4_DLNK) $(LIBS) -o $(TARGET)module$(SO) + +php4_multi_cpp: $(SRCS) + $(SWIG) -c -c++ -php4 -cppext cxx $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(PHP4_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PHP4_RUNTIME) $(PHP4_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)module$(SO) + +# ----------------------------------------------------------------- +# Cleaning the PHP4 examples +# ----------------------------------------------------------------- + +php4_clean: + rm -f *.@OBJEXT@ *$(SO) *_wrap* *~ .~* core *.php + +################################################################## +##### Pike ###### +################################################################## + +# Make sure these locate your Pike installation +PIKE_CFLAGS = @PIKECCDLFLAGS@ -DHAVE_CONFIG_H +PIKE_INCLUDE = @PIKEINCLUDE@ +PIKE_LIB = @PIKELIB@ +PIKE_DLNK = @PIKEDYNAMICLINKING@ + +# ---------------------------------------------------------------- +# Build a C dynamically loadable module +# ---------------------------------------------------------------- + +pike: $(SRCS) + $(SWIG) -pike $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(PIKE_CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(PIKE_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PIKE_DLNK) $(LIBS) -o $(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build a C++ dynamically loadable module +# ----------------------------------------------------------------- + +pike_cpp: $(SRCS) + $(SWIG) -c++ -pike $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(PIKE_CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(PIKE_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PIKE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build a dynamically loadable module, linked against SWIG runtime lib +# ----------------------------------------------------------------- + +PIKE_RUNTIME=-L$(RUNTIMEDIR) -lswigpike@release_suffix@ + +pike_multi: $(SRCS) + $(SWIG) -c -pike $(SWIGOPT) $(INTERFACE) + $(CC) -c $(CCSHARED) $(CFLAGS) $(PIKE_CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(PIKE_INCLUDE) + $(LDSHARED) $(OBJS) $(IOBJS) $(PIKE_RUNTIME) $(PIKE_DLNK) $(LIBS) -o $(TARGET)$(SO) + +pike_multi_cpp: $(SRCS) + $(SWIG) -c -c++ -pike $(SWIGOPT) $(INTERFACE) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(PIKE_CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(PIKE_INCLUDE) + $(CXXSHARED) $(OBJS) $(IOBJS) $(PIKE_RUNTIME) $(PIKE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Build statically linked Pike interpreter +# +# These should only be used in conjunction with the %include embed.i +# library file +# ----------------------------------------------------------------- + +PIKE_LIBOPTS = @PIKELINK@ @LIBS@ $(SYSLIBS) + +pike_static: $(SRCS) + $(SWIG) -pike -lembed.i $(SWIGOPT) $(INTERFACE) + $(CC) $(CFLAGS) $(PIKE_CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCS) $(INCLUDES) \ + $(PIKE_INCLUDE) $(LIBS) -L$(PIKE_LIB) $(PIKE_LIBOPTS) -o $(TARGET) + +pike_cpp_static: $(SRCS) + $(SWIG) -c++ -pike -lembed.i $(SWIGOPT) $(INTERFACE) + $(CXX) $(CFLAGS) $(PIKE_CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \ + $(PIKE_INCLUDE) $(LIBS) -L$(PIKE_LIB) $(PIKE_LIBOPTS) -o $(TARGET) + +# ----------------------------------------------------------------- +# Cleaning the Pike examples +# ----------------------------------------------------------------- + +pike_clean: + rm -f *.@OBJEXT@ *$(SO) *_wrap* *~ .~* core mypike@EXEEXT@ diff --git a/Examples/README b/Examples/README index 3a476a79a..c18d30ed7 100644 --- a/Examples/README +++ b/Examples/README @@ -37,8 +37,6 @@ the rules of thumb for making C++ work: This can be set by modifying the setting of CPP_DLLIBS in the Makefile. - - RTM (sorry) - *** Special note for SWIG Maintainers *** diff --git a/Examples/guile/Makefile.in b/Examples/guile/Makefile.in index 1c31a6725..b97249c06 100644 --- a/Examples/guile/Makefile.in +++ b/Examples/guile/Makefile.in @@ -1,27 +1,38 @@ # Makefile for Guile. Used by all of the example programs. -subdirs = simple matrix +subdirs = simple matrix port constants multimap multivalue top_srcdir = @top_srcdir@ - +SWIG = ../$(top_srcdir)/swig@release_suffix@ +CC = @CC@ +CXX = @CXX@ +CFLAGS = @CFLAGS@ GUILEINCLUDE = @GUILEINCLUDE@ GUILELINK = @GUILELINK@ +SWIGOPT = WRAP = $(IFILE:.i=_wrap.c) +CXXWRAP = $(IFILE:.i=_wrap.cxx) all: for d in $(subdirs) ; do (cd $$d ; $(MAKE)) ; done clean:: - cd simple; make clean - cd matrix; make clean + for d in $(subdirs) ; do (cd $$d ; $(MAKE) clean) ; done rm -f *~ .~* +guile_clean: + rm -f *.@OBJEXT@ *$(SO) *_wrap* *~ .~* core my-guile $(TARGET) + # This is meant to be used w/ "make -f ../Makefile" from subdirs. # Doesn't make sense to use it from here. sub-all:: - ../$(top_srcdir)/swig -guile $(IFILE) - $(CC) -o $(TARGET) $(SRCS) $(WRAP) $(GUILEINCLUDE) $(GUILELINK) + $(SWIG) -guile $(SWIGOPT) $(IFILE) + $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(WRAP) $(GUILEINCLUDE) $(GUILELINK) + +sub-all-cxx:: + $(SWIG) -c++ -guile $(SWIGOPT) $(IFILE) + $(CXX) $(CFLAGS) -o $(TARGET) $(SRCS) $(CXXWRAP) $(GUILEINCLUDE) $(GUILELINK) # Makefile ends here diff --git a/Examples/guile/README b/Examples/guile/README index e006d02ce..acec7773b 100644 --- a/Examples/guile/README +++ b/Examples/guile/README @@ -1,11 +1,17 @@ This directory contains examples for Guile. -simple - The simple example from the user manual. -matrix - A very simple Matrix example. +constants -- handling #define and %constant literals +matrix -- a very simple Matrix example +multimap -- typemaps with multiple sub-types +multivalue -- using the %values_as_list directive +port -- scheme ports as temporary FILE streams +simple -- the simple example from the user manual +std_vector -- C++ STL vector and vector + Note that the examples in this directory build a special version of -Guile which includes the wrapped functions in the top-level module. +Guile which includes the wrapped functions in the top-level module. If you want to put the wrapped functions into an own module, statically or dynamically linked, see the Examples/GIFPlot/Guile -directory. +directory. diff --git a/Examples/guile/check.list b/Examples/guile/check.list new file mode 100644 index 000000000..d35b2d693 --- /dev/null +++ b/Examples/guile/check.list @@ -0,0 +1,7 @@ +# see top-level Makefile.in +constants +matrix +simple +port +multimap +multivalue diff --git a/Examples/guile/constants/.cvsignore b/Examples/guile/constants/.cvsignore new file mode 100644 index 000000000..7d0f67de1 --- /dev/null +++ b/Examples/guile/constants/.cvsignore @@ -0,0 +1,2 @@ +example_wrap.c +my-guile diff --git a/Examples/guile/constants/Makefile b/Examples/guile/constants/Makefile new file mode 100644 index 000000000..70243c75e --- /dev/null +++ b/Examples/guile/constants/Makefile @@ -0,0 +1,17 @@ +SRCS = +TARGET = my-guile +IFILE = example.i +MKDIR = .. + +all:: + $(MAKE) -f $(MKDIR)/Makefile \ + SRCS='$(SRCS)' \ + TARGET=$(TARGET) \ + IFILE=$(IFILE) \ + sub-all + +clean:: + $(MAKE) -f $(MKDIR)/Makefile TARGET='$(TARGET)' guile_clean + +check: all + ./my-guile -s constants.scm diff --git a/Examples/guile/constants/constants.scm b/Examples/guile/constants/constants.scm new file mode 100644 index 000000000..5220150f1 --- /dev/null +++ b/Examples/guile/constants/constants.scm @@ -0,0 +1,10 @@ +(or (= (ICONST) 42) (exit 1)) +(or (< (abs (- (FCONST) 2.1828)) 0.00001) (exit 1)) +(or (char=? (CCONST) #\x) (exit 1)) +(or (char=? (CCONST2) #\newline) (exit 1)) +(or (string=? (SCONST) "Hello World") (exit 1)) +(or (string=? (SCONST2) "\"Hello World\"") (exit 1)) +(or (< (abs (- (EXPR) (+ (ICONST) (* 3 (FCONST))))) 0.00001) (exit 1)) +(or (= (iconst) 37) (exit 1)) +(or (< (abs (- (fconst) 3.14)) 0.00001) (exit 1)) +(exit 0) diff --git a/Examples/guile/constants/example.i b/Examples/guile/constants/example.i new file mode 100644 index 000000000..0b602e5ab --- /dev/null +++ b/Examples/guile/constants/example.i @@ -0,0 +1,27 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; + +%include guilemain.i diff --git a/Examples/guile/matrix/Makefile b/Examples/guile/matrix/Makefile index bbe78539a..5df2c6515 100644 --- a/Examples/guile/matrix/Makefile +++ b/Examples/guile/matrix/Makefile @@ -1,4 +1,3 @@ -CC = gcc SRCS = matrix.c vector.c TARGET = matrix IFILE = package.i @@ -10,11 +9,10 @@ all:: SRCS='$(SRCS)' \ TARGET=$(TARGET) \ IFILE=$(IFILE) \ - CC=$(CC) \ MODULE=$(MODULE) \ sub-all clean:: - rm -f matrix *_wrap* *~ .~* core + $(MAKE) -f $(MKDIR)/Makefile TARGET='$(TARGET)' guile_clean check: all diff --git a/Examples/guile/matrix/README b/Examples/guile/matrix/README index 7776129f7..dc1957719 100644 --- a/Examples/guile/matrix/README +++ b/Examples/guile/matrix/README @@ -1,7 +1,7 @@ Matrix example. To run the example, execute the program 'matrix' and type the following : - (load 'matrix.scm) + (load "matrix.scm") (do-test 0) Alternatively, use the command-line: diff --git a/Examples/guile/matrix/matrix.c b/Examples/guile/matrix/matrix.c index 7ecb6ddd4..6ce10098b 100644 --- a/Examples/guile/matrix/matrix.c +++ b/Examples/guile/matrix/matrix.c @@ -1,4 +1,6 @@ /* FILE : matrix.c : some simple 4x4 matrix operations */ +#include +#include double **new_matrix() { diff --git a/Examples/guile/matrix/matrix.i b/Examples/guile/matrix/matrix.i index 25f44cc47..3ff8ec7ac 100644 --- a/Examples/guile/matrix/matrix.i +++ b/Examples/guile/matrix/matrix.i @@ -12,7 +12,8 @@ double get_m(double **M, int i, int j) { } %} -%section "Matrix Operations" +/*** Matrix Operations ***/ + extern double **new_matrix(); /* Creates a new matrix and returns a pointer to it */ diff --git a/Examples/guile/matrix/package.i b/Examples/guile/matrix/package.i index c820a3494..aaa55511c 100644 --- a/Examples/guile/matrix/package.i +++ b/Examples/guile/matrix/package.i @@ -1,7 +1,8 @@ // FILE : package.i // See the SWIG users manual -%title "Matrix and vector package" +/*** Matrix and vector package ***/ + %module Matrix %{ #include diff --git a/Examples/guile/matrix/vector.c b/Examples/guile/matrix/vector.c index cdb726ad5..3012993f8 100644 --- a/Examples/guile/matrix/vector.c +++ b/Examples/guile/matrix/vector.c @@ -1,5 +1,7 @@ /* File : vector.c */ +#include +#include #include "vector.h" Vector *createv(double x, double y, double z, double w) { diff --git a/Examples/guile/multimap/Makefile b/Examples/guile/multimap/Makefile new file mode 100644 index 000000000..1ab46d030 --- /dev/null +++ b/Examples/guile/multimap/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='my-guile' INTERFACE='$(INTERFACE)' guile_static + +clean:: + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean + +check: all diff --git a/Examples/guile/multimap/example.c b/Examples/guile/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/guile/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/guile/multimap/example.i b/Examples/guile/multimap/example.i new file mode 100644 index 000000000..e9cb6507d --- /dev/null +++ b/Examples/guile/multimap/example.i @@ -0,0 +1,75 @@ +/* File : example.i */ +%module example +%include exception.i +%include typemaps.i + +extern int gcd(int x, int y); + +%typemap(guile,in) (int argc, char *argv[]) { + int i; + SCM *v; + if (!(SCM_NIMP($input) && SCM_VECTORP($input))) { + SWIG_exception(SWIG_ValueError, "Expecting a vector"); + return; + } + $1 = SCM_LENGTH($input); + if ($1 == 0) { + SWIG_exception(SWIG_ValueError, "Vector must contain at least 1 element"); + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + v = SCM_VELTS($input); + for (i = 0; i < $1; i++) { + if (!(SCM_NIMP(v[i]) && SCM_STRINGP(v[i]))) { + free($2); + SWIG_exception(SWIG_ValueError, "Vector items must be strings"); + return; + } + $2[i] = SCM_CHARS(v[i]); + } + $2[i] = 0; +} + +%typemap(guile,freearg) (int argc, char *argv[]) { + free($2); +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(guile,in) (char *bytes, int len) { + if (!(SCM_NIMP($input) && SCM_STRINGP($input))) { + SWIG_exception(SWIG_ValueError, "Expecting a string"); + } + $1 = SCM_CHARS($input); + $2 = SCM_LENGTH($input); +} + +extern int count(char *bytes, int len, char c); + +/* This example shows how to wrap a function that mutates a string */ + +%typemap(guile,in) (char *str, int len) { + $1 = gh_scm2newstr($input,&$2); +} + +/* Return the mutated string as a new object. */ + +%typemap(guile,argout) (char *str, int len) { + SWIG_APPEND_VALUE(gh_str2scm($1,$2)); + if ($1) scm_must_free($1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + } +} + +extern void circle(double cx, double cy); + + diff --git a/Examples/guile/multimap/runme.scm b/Examples/guile/multimap/runme.scm new file mode 100644 index 000000000..edc197259 --- /dev/null +++ b/Examples/guile/multimap/runme.scm @@ -0,0 +1,30 @@ +;;; Test out some multi-argument typemaps + +(use-modules (example)) + +; Call the GCD function + +(define x 42) +(define y 105) +(define g (gcd x y)) + +(display "The gcd of ") +(display x) +(display " and ") +(display y) +(display " is ") +(display g) +(newline) + +; Call the gcdmain() function +(gcdmain #("gcdmain" "42" "105")) + +; Call the count function +(display (count "Hello World" #\l)) +(newline) + +; Call the capitalize function +(display (capitalize "hello world")) +(newline) + + diff --git a/Examples/guile/multivalue/Makefile b/Examples/guile/multivalue/Makefile new file mode 100644 index 000000000..1ab46d030 --- /dev/null +++ b/Examples/guile/multivalue/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='my-guile' INTERFACE='$(INTERFACE)' guile_static + +clean:: + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean + +check: all diff --git a/Examples/guile/multivalue/example.c b/Examples/guile/multivalue/example.c new file mode 100644 index 000000000..c9ebad1ae --- /dev/null +++ b/Examples/guile/multivalue/example.c @@ -0,0 +1,18 @@ +void divide_l(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +void divide_v(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +void divide_mv(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + diff --git a/Examples/guile/multivalue/example.i b/Examples/guile/multivalue/example.i new file mode 100644 index 000000000..abc2a6fbc --- /dev/null +++ b/Examples/guile/multivalue/example.i @@ -0,0 +1,26 @@ +/* -*- c -*- */ + +%module example; + +/* Multiple values as lists. By default, if more than one value is to +be returned, a list of the values is created and returned; to switch +back to this behavior, use: */ +%values_as_list; + +void divide_l(int a, int b, int *OUTPUT, int *OUTPUT); + +/* Multiple values as vectors. By issueing: */ +%values_as_vector; +/* vectors instead of lists will be used. */ + +void divide_v(int a, int b, int *OUTPUT, int *OUTPUT); + +/* Multiple values for multiple-value continuations. + (This is the most elegant way.) By issueing: */ +%multiple_values; +/* multiple values are passed to the multiple-value + continuation, as created by `call-with-values' or the + convenience macro `receive'. (See the Scheme file.) */ + +void divide_mv(int a, int b, int *OUTPUT, int *OUTPUT); + diff --git a/Examples/guile/multivalue/runme.scm b/Examples/guile/multivalue/runme.scm new file mode 100644 index 000000000..73eb5affa --- /dev/null +++ b/Examples/guile/multivalue/runme.scm @@ -0,0 +1,66 @@ +;;;; Show the three different ways to deal with multiple return values + +(use-modules (example)) + +;;; Multiple values as lists. By default, if more than one value is to +;;; be returned, a list of the values is created and returned. The +;;; procedure divide-l does so: + +(let* ((quotient/remainder (divide-l 37 5)) + ;; divide-l returns a list of the two values, so get them: + (quotient (car quotient/remainder)) + (remainder (cadr quotient/remainder))) + (display "37 divided by 5 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline)) + +;;; Multiple values as vectors. You can get vectors instead of lists +;;; if you want: + +(let* ((quotient-remainder-vector (divide-v 40 7)) + ;; divide-v returns a vector of two values, so get them: + (quotient (vector-ref quotient-remainder-vector 0)) + (remainder (vector-ref quotient-remainder-vector 1))) + (display "40 divided by 7 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline)) + +;;; Multiple values for multiple-value continuations. (The most +;;; elegant way.) You can get multiple values passed to the +;;; multiple-value continuation, as created by `call-with-values'. + +(call-with-values (lambda () + ;; the "producer" procedure + (divide-mv 91 13)) + (lambda (quotient remainder) + ;; the "consumer" procedure + (display "91 divided by 13 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline))) + +;;; SRFI-8 has a very convenient macro for this construction: + +(use-modules (srfi srfi-8)) + +;;; If your Guile is too old, you can define the receive macro yourself: +;;; +;;; (define-macro (receive vars vals . body) +;;; `(call-with-values (lambda () ,vals) +;;; (lambda ,vars ,@body))) + +(receive (quotient remainder) + (divide-mv 111 19) ; the "producer" form + ;; In the body, `quotient' and `remainder' are bound to the two + ;; values. + (display "111 divided by 19 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline)) + diff --git a/Examples/guile/port/Makefile b/Examples/guile/port/Makefile index 668c66bd3..824f3f823 100644 --- a/Examples/guile/port/Makefile +++ b/Examples/guile/port/Makefile @@ -1,4 +1,3 @@ -CC = gcc SRCS = port.c TARGET = port IFILE = port.i @@ -10,11 +9,10 @@ all:: SRCS='$(SRCS)' \ TARGET=$(TARGET) \ IFILE=$(IFILE) \ - CC=$(CC) \ MODULE=$(MODULE) \ sub-all clean:: - rm -f $(TARGET) *_wrap* *~ .~* core test.out + $(MAKE) -f $(MKDIR)/Makefile TARGET='$(TARGET)' guile_clean check: all diff --git a/Examples/guile/port/port.i b/Examples/guile/port/port.i index 553cfba23..eb7539173 100644 --- a/Examples/guile/port/port.i +++ b/Examples/guile/port/port.i @@ -1,3 +1,5 @@ +%module port + %include guilemain.i /* Include the required FILE * typemaps */ @@ -7,5 +9,7 @@ #include %} +%inline %{ void print_int(FILE *f, int i); int read_int(FILE *f); +%} diff --git a/Examples/guile/simple/Makefile b/Examples/guile/simple/Makefile index 151dcc4b3..702b5bb96 100644 --- a/Examples/guile/simple/Makefile +++ b/Examples/guile/simple/Makefile @@ -1,18 +1,19 @@ -CC = gcc SRCS = example.c TARGET = my-guile IFILE = example.i MKDIR = .. -all:: +all: $(TARGET) + +$(TARGET): $(MAKE) -f $(MKDIR)/Makefile \ SRCS='$(SRCS)' \ TARGET=$(TARGET) \ IFILE=$(IFILE) \ - CC=$(CC) \ sub-all clean:: - rm -f *_wrap* my-guile *~ .~* core + $(MAKE) -f $(MKDIR)/Makefile TARGET='$(TARGET)' guile_clean -check: all +check: $(TARGET) + ./$(TARGET) -s example.scm > /dev/null diff --git a/Examples/guile/simple/README b/Examples/guile/simple/README index 3ca6e40cf..982216eaa 100644 --- a/Examples/guile/simple/README +++ b/Examples/guile/simple/README @@ -2,7 +2,7 @@ A very simple example. To run it, start the program 'my-guile' and type: - (load 'example.scm) + (load "example.scm") Alternatively, you can use the shell command: diff --git a/Examples/guile/simple/example.c b/Examples/guile/simple/example.c index 0e6b284b6..dcafc4dc4 100644 --- a/Examples/guile/simple/example.c +++ b/Examples/guile/simple/example.c @@ -1,7 +1,7 @@ /* Simple example from documentation */ /* File : example.c */ -#include +#include double My_variable = 3.0; diff --git a/Examples/guile/simple/example.scm b/Examples/guile/simple/example.scm index 7356aad74..9408b1aa6 100644 --- a/Examples/guile/simple/example.scm +++ b/Examples/guile/simple/example.scm @@ -1,23 +1,14 @@ -;;; -;;; Guile script for simple example. -;;; Is a little clumsy since I'm not the greatest scheme programmer. -;;; +;;; example.scm -(display (get-time)) -(display "My variable = ") -(display (My-variable)) -(newline) +(define (mdisplay-newline . args) ; does guile-1.3.4 have `format #t'? + (for-each display args) + (newline)) -(define (facts x max) - (if (< x max) - (begin - (display (string-append (number->string x) " factorial is " - (number->string (fact x)))) - (newline) - (facts (+ x 1) max)))) - -(facts 0 14) +(mdisplay-newline (get-time) "My variable = " (My-variable)) +(do ((i 0 (1+ i))) + ((= 14 i)) + (mdisplay-newline i " factorial is " (fact i))) (define (mods i imax j jmax) (if (< i imax) @@ -27,9 +18,11 @@ (mods i imax (+ j 1) jmax)) (mods (+ i 1) imax 1 jmax)))) -(mods 1 250 1 250) +(mods 1 150 1 150) -(display (string-append "My-variable = " (number->string (My-variable)))) -(newline) +(mdisplay-newline "My-variable = " (My-variable)) + +(exit (and (= 1932053504 (fact 13)) + (= 745470.0 (My-variable)))) ;;; example.scm ends here diff --git a/Examples/guile/std_vector/.cvsignore b/Examples/guile/std_vector/.cvsignore new file mode 100644 index 000000000..bd7dd8a57 --- /dev/null +++ b/Examples/guile/std_vector/.cvsignore @@ -0,0 +1 @@ +example_wrap.cxx diff --git a/Examples/guile/std_vector/Makefile b/Examples/guile/std_vector/Makefile new file mode 100644 index 000000000..fb491c2e7 --- /dev/null +++ b/Examples/guile/std_vector/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='my-guile' INTERFACE='$(INTERFACE)' guile_static_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean + +check: all diff --git a/Examples/guile/std_vector/example.h b/Examples/guile/std_vector/example.h new file mode 100644 index 000000000..4f0dac70d --- /dev/null +++ b/Examples/guile/std_vector/example.h @@ -0,0 +1,25 @@ +/* File : example.h */ + +#include +#include +#include +#include + +double average(std::vector v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector half(const std::vector& v) { + std::vector w(v); + for (unsigned int i=0; i& v) { + // would you believe this is the same as the above? + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides(),2.0)); +} + + diff --git a/Examples/guile/std_vector/example.i b/Examples/guile/std_vector/example.i new file mode 100644 index 000000000..aa58b66e0 --- /dev/null +++ b/Examples/guile/std_vector/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include stl.i +/* instantiate the required template specializations */ +namespace std { + %template(IntVector) vector; + %template(DoubleVector) vector; +} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/guile/std_vector/runme.scm b/Examples/guile/std_vector/runme.scm new file mode 100644 index 000000000..77443a156 --- /dev/null +++ b/Examples/guile/std_vector/runme.scm @@ -0,0 +1,54 @@ +;; run with mzscheme -r example.scm + +(use-modules (example)) + +; repeatedly invoke a procedure with v and an index as arguments +(define (with-vector v proc size-proc) + (let ((size (size-proc v))) + (define (with-vector-item v i) + (if (< i size) + (begin + (proc v i) + (with-vector-item v (+ i 1))))) + (with-vector-item v 0))) + +(define (with-IntVector v proc) + (with-vector v proc IntVector-length)) +(define (with-DoubleVector v proc) + (with-vector v proc DoubleVector-length)) + +(define (print-DoubleVector v) + (with-DoubleVector v (lambda (v i) (display (DoubleVector-ref v i)) + (display " "))) + (newline)) + + +; Call average with a Scheme list... + +(display (average '(1 2 3 4))) +(newline) + +; ... or a wrapped std::vector +(define v (new-IntVector 4)) +(with-IntVector v (lambda (v i) (IntVector-set! v i (+ i 1)))) +(display (average v)) +(newline) +(delete-IntVector v) + +; half will return a Scheme vector. +; Call it with a Scheme vector... + +(display (half #(1 1.5 2 2.5 3))) +(newline) + +; ... or a wrapped std::vector +(define v (new-DoubleVector)) +(map (lambda (i) (DoubleVector-push! v i)) '(1 2 3 4)) +(display (half v)) +(newline) + +; now halve a wrapped std::vector in place +(halve-in-place v) +(print-DoubleVector v) +(delete-DoubleVector v) + diff --git a/Examples/index.html b/Examples/index.html index 7737e1bdc..1458e8dee 100644 --- a/Examples/index.html +++ b/Examples/index.html @@ -41,11 +41,13 @@ language:
  • Perl5
  • Tcl
  • Guile -
  • Java -
  • Mzscheme +
  • Java +
  • Mzscheme
  • Ruby +If your target platform is Windows, make sure you also see the Windows page in the main manual. +

    Real Life

    The GIFPlot directory contains examples that illustrate the use of SWIG with diff --git a/Examples/java/check.list b/Examples/java/check.list new file mode 100644 index 000000000..c2272cde4 --- /dev/null +++ b/Examples/java/check.list @@ -0,0 +1,14 @@ +# see top-level Makefile.in +class +constants +enum +funcptr +mpointer +multimap +native +pointer +reference +simple +template +typemap +variables diff --git a/Examples/java/class/.cvsignore b/Examples/java/class/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/class/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/class/Makefile b/Examples/java/class/Makefile new file mode 100644 index 000000000..69fb4e670 --- /dev/null +++ b/Examples/java/class/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/class/example.cxx b/Examples/java/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/java/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/java/class/example.dsp b/Examples/java/class/example.dsp new file mode 100644 index 000000000..36f0e9ef1 --- /dev/null +++ b/Examples/java/class/example.dsp @@ -0,0 +1,162 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_INCLUDE)" /I "$(JAVA_INCLUDE)\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Java compile post-build step +PostBuild_Cmds=echo on %JAVA_BIN%\javac *.java +# End Special Build Tool + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(JAVA_INCLUDE)" /I "$(JAVA_INCLUDE)\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"example.dll" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Java compile post-build step +PostBuild_Cmds=echo on %JAVA_BIN%\javac *.java +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.cxx +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\example.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo JAVA_INCLUDE: %JAVA_INCLUDE% + echo JAVA_BIN: %JAVA_BIN% + echo on + ..\..\..\swig.exe -c++ -java $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo JAVA_INCLUDE: %JAVA_INCLUDE% + echo JAVA_BIN: %JAVA_BIN% + echo on + ..\..\..\swig.exe -c++ -java $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/java/class/example.h b/Examples/java/class/example.h new file mode 100644 index 000000000..46d901361 --- /dev/null +++ b/Examples/java/class/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/Examples/java/class/example.i b/Examples/java/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/Examples/java/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/java/class/index.html b/Examples/java/class/index.html new file mode 100644 index 000000000..0360ce9ee --- /dev/null +++ b/Examples/java/class/index.html @@ -0,0 +1,199 @@ + + +SWIG:Examples:java:class + + + + + +SWIG/Examples/java/class/ +
    + +

    Wrapping a simple C++ class

    + +$Header$
    + +

    +This example illustrates the high level form of C++ class wrapping performed +by SWIG. In this case, a C++ class has a proxy Java class, which +provides access to C++ class members. + +

    The C++ Code

    + +Suppose you have some C++ classes described by the following (and admittedly lame) +header file: + +
    +
    +/* File : example.h */
    +
    +class Shape {
    +public:
    +  Shape() {
    +    nshapes++;
    +  }
    +  virtual ~Shape() {
    +    nshapes--;
    +  };
    +  double  x, y;   
    +  void    move(double dx, double dy);
    +  virtual double area() = 0;
    +  virtual double perimeter() = 0;
    +  static  int nshapes;
    +};
    +
    +class Circle : public Shape {
    +private:
    +  double radius;
    +public:
    +  Circle(double r) : radius(r) { };
    +  virtual double area();
    +  virtual double perimeter();
    +};
    +
    +class Square : public Shape {
    +private:
    +  double width;
    +public:
    +  Square(double w) : width(w) { };
    +  virtual double area();
    +  virtual double perimeter();
    +};
    +
    +
    + +

    The SWIG interface

    + +A simple SWIG interface for this can be built by simply grabbing the header file +like this: + +
    +
    +/* File : example.i */
    +%module example
    +
    +%{
    +#include "example.h"
    +%}
    +
    +/* Let's just grab the original header file here */
    +%include "example.h"
    +
    +
    + +Note: when creating a C++ extension, you must run SWIG with the -c++ option like this: +
    +
    +% swig -c++ -java example.i
    +
    +
    + +

    A sample Java program

    + +Click here to see a Java program that calls the C++ functions from Java. + +

    Key points

    + +
      +
    • To create a new object, you call a constructor like this: + +
      +
      +Circle c = new Circle(10);
      +
      +
      + +

      +

    • To access member data, a pair of accessor functions are used. +For example: + +
      +
      +c.setX(15);        // Set member data
      +x = c.getX();      // Get member data
      +
      +
      + +

      +

    • To invoke a member function, you simply do this + +
      +
      +System.out.println( "The area is " + c.area() );
      +
      +
      + +

      +

    • To invoke a destructor, simply do this + +
      +
      +c.delete();     // Deletes a shape
      +
      +
      + +

      +

    • Static member variables are wrapped with java static get and set access functions. For example: + +
      +
      +n = Shape.getNshapes();     // Get a static data member
      +Shape.setNshapes(13);       // Set a static data member
      +
      +
      + +
    + +

    General Comments

    + +
      +
    • This high-level interface using shadow classes is not the only way to handle C++ code. +A low level interface using c functions to access member variables and member functions is the alternative SWIG +approach. This entails passing around the c pointer or c++ 'this' pointer and as such it is not difficult to crash the JVM. +The abstraction of the underlying pointer by the java shadow classes far better fits the java programming paradigm. + +

      +

    • SWIG *does* know how to properly perform upcasting of objects in an inheritance +hierarchy (including multiple inheritance). However Java classes can only derive from one base class so multiple inheritance +is not implemented. Java classes can implement more than one interface so there is scope for improvement in the future. + +

      +

    • A wide variety of C++ features are not currently supported by SWIG. Here is the +short and incomplete list: + +

      +

        +
      • Overloaded methods and functions. SWIG wrappers don't know how to resolve name +conflicts so you must give an alternative name to any overloaded method name using the +%name directive like this: + +
        +
        +void foo(int a);  
        +%name(foo2) void foo(double a, double b);
        +
        +
        + +

        +

      • Overloaded operators. Not supported at all. The only workaround for this is +to write a helper function. For example: + +
        +
        +%inline %{
        +    Vector *vector_add(Vector *a, Vector *b) {
        +          ... whatever ...
        +    }
        +%}
        +
        +
        + +

        +

      • Namespaces. Not supported at all. Won't be supported until SWIG2.0 (if at all). + +
      +
    + +
    + + diff --git a/Examples/java/class/main.java b/Examples/java/class/main.java new file mode 100644 index 000000000..8ef35db6d --- /dev/null +++ b/Examples/java/class/main.java @@ -0,0 +1,70 @@ +// This example illustrates how C++ classes can be used from Java using SWIG. +// The Java class gets mapped onto the C++ class and behaves as if it is a Java class. + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + // ----- Object creation ----- + + System.out.println( "Creating some objects:" ); + Circle c = new Circle(10); + System.out.println( " Created circle " + c ); + Square s = new Square(10); + System.out.println( " Created square " + s ); + + // ----- Access a static member ----- + + System.out.println( "\nA total of " + Shape.getNshapes() + " shapes were created" ); + + // ----- Member data access ----- + + // Notice how we can do this using functions specific to + // the 'Circle' class. + c.setX(20); + c.setY(30); + + // Now use the same functions in the base class + Shape shape = s; + shape.setX(-10); + shape.setY(5); + + System.out.println( "\nHere is their current position:" ); + System.out.println( " Circle = (" + c.getX() + " " + c.getY() + ")" ); + System.out.println( " Square = (" + s.getX() + " " + s.getY() + ")" ); + + // ----- Call some methods ----- + + System.out.println( "\nHere are some properties of the shapes:" ); + Shape[] shapes = {c,s}; + for (int i=0; i + +SWIG:Examples:java:constants + + + + +SWIG/Examples/java/constants/ +
    + +

    Wrapping C Constants

    + +$Header$
    + +

    +When SWIG encounters C preprocessor macros and C declarations that look like constants, +it creates Java constant with an identical value. Click here +to see a SWIG interface with some constant declarations in it. + +

    Accessing Constants from Java

    + +Click here to see a Java program that prints out the values +of the constants contained in the above file. + +

    Key points

    + +
      +
    • The values of preprocessor macros are converted into Java constants. +
    • Types are inferred by syntax (e.g., "3" is an integer and "3.5" is a float). +
    • Character constants such as 'x' are converted into Java strings. +
    • C string literals such as "Hello World" are converted into Java strings. +
    • Macros that are not fully defined are simply ignored. For example: +
      +
      +#define EXTERN extern
      +
      +
      +is ignored because SWIG has no idea what type of variable this would be. + +

      +

    • Expressions are allowed provided that all of their components are defined. Otherwise, the constant is ignored. + +
    • Certain C declarations involving 'const' are also turned into Java constants. +
    • The constants that appear in a SWIG interface file do not have to appear in any sort +of matching C source file since the creation of a constant does not require linkage +to a stored value (i.e., a value held in a C global variable or memory location). +
    + +
    + + + + diff --git a/Examples/java/constants/main.java b/Examples/java/constants/main.java new file mode 100644 index 000000000..7130c3d70 --- /dev/null +++ b/Examples/java/constants/main.java @@ -0,0 +1,44 @@ +import java.lang.reflect.*; + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + System.out.println("ICONST = " + example.ICONST + " (should be 42)"); + System.out.println("FCONST = " + example.FCONST + " (should be 2.1828)"); + System.out.println("CCONST = " + example.CCONST + " (should be 'x')"); + System.out.println("CCONST2 = " + example.CCONST2 + " (this should be on a new line)"); + System.out.println("SCONST = " + example.SCONST + " (should be 'Hello World')"); + System.out.println("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')"); + System.out.println("EXPR = " + example.EXPR + " (should be 48.5484)"); + System.out.println("iconst = " + example.iconst + " (should be 37)"); + System.out.println("fconst = " + example.fconst + " (should be 3.14)"); + +// Use reflection to check if these variables are defined: + try + { + System.out.println("EXTERN = " + example.class.getField("EXTERN") + " (Arg! This shouldn't print anything)"); + } + catch (NoSuchFieldException e) + { + System.out.println("EXTERN isn't defined (good)"); + } + + try + { + System.out.println("FOO = " + example.class.getField("FOO") + " (Arg! This shouldn't print anything)"); + } + catch (NoSuchFieldException e) + { + System.out.println("FOO isn't defined (good)"); + } + } +} diff --git a/Examples/java/enum/.cvsignore b/Examples/java/enum/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/enum/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/enum/Makefile b/Examples/java/enum/Makefile new file mode 100644 index 000000000..69fb4e670 --- /dev/null +++ b/Examples/java/enum/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/enum/example.cxx b/Examples/java/enum/example.cxx new file mode 100644 index 000000000..df7bb6328 --- /dev/null +++ b/Examples/java/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.cxx */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/java/enum/example.h b/Examples/java/enum/example.h new file mode 100644 index 000000000..525d62afc --- /dev/null +++ b/Examples/java/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE, WARP, LUDICROUS }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/java/enum/example.i b/Examples/java/enum/example.i new file mode 100644 index 000000000..4c873824c --- /dev/null +++ b/Examples/java/enum/example.i @@ -0,0 +1,13 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%pragma make_default + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/java/enum/index.html b/Examples/java/enum/index.html new file mode 100644 index 000000000..cd81244e3 --- /dev/null +++ b/Examples/java/enum/index.html @@ -0,0 +1,37 @@ + + +SWIG:Examples:java:enum + + + + + +SWIG/Examples/java/enum/ +
    + +

    Wrapping enumerations

    + +$Header$
    + +

    +This example tests SWIG's ability to wrap enumerations. By default, SWIG +converts enumeration specifications into integer constants. Further use +of enumerated types are handled as integers. + +

    + +

    Notes

    + +
      +
    • SWIG allows arbitrary integers to be passed as enum values. However, +the result of passing an integer not corresponding to any of the values +specified in the enum specification is undefined. +
    + +
    + + diff --git a/Examples/java/enum/main.java b/Examples/java/enum/main.java new file mode 100644 index 000000000..b1098c7b1 --- /dev/null +++ b/Examples/java/enum/main.java @@ -0,0 +1,39 @@ + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + // Print out the value of some enums + System.out.println("*** color ***"); + System.out.println(" RED = " + example.RED); + System.out.println(" BLUE = " + example.BLUE); + System.out.println(" GREEN = " + example.GREEN); + + System.out.println("\n*** Foo::speed ***"); + System.out.println(" Foo::IMPULSE = " + Foo.IMPULSE); + System.out.println(" Foo::WARP = " + Foo.WARP); + System.out.println(" Foo::LUDICROUS = " + Foo.LUDICROUS); + + System.out.println("\nTesting use of enums with functions\n"); + + example.enum_test(example.RED, Foo.IMPULSE); + example.enum_test(example.BLUE, Foo.WARP); + example.enum_test(example.GREEN, Foo.LUDICROUS); + example.enum_test(1234,5678); + + System.out.println( "\nTesting use of enum with class method" ); + Foo f = new Foo(); + + f.enum_test(Foo.IMPULSE); + f.enum_test(Foo.WARP); + f.enum_test(Foo.LUDICROUS); + } +} diff --git a/Examples/java/funcptr/.cvsignore b/Examples/java/funcptr/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/funcptr/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/funcptr/Makefile b/Examples/java/funcptr/Makefile new file mode 100644 index 000000000..b1f254ed3 --- /dev/null +++ b/Examples/java/funcptr/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/funcptr/example.c b/Examples/java/funcptr/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/Examples/java/funcptr/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/java/funcptr/example.h b/Examples/java/funcptr/example.h new file mode 100644 index 000000000..58989db79 --- /dev/null +++ b/Examples/java/funcptr/example.h @@ -0,0 +1,7 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + diff --git a/Examples/java/funcptr/example.i b/Examples/java/funcptr/example.i new file mode 100644 index 000000000..8b3bef678 --- /dev/null +++ b/Examples/java/funcptr/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; + +extern int (*funcvar)(int,int); + diff --git a/Examples/java/funcptr/index.html b/Examples/java/funcptr/index.html new file mode 100644 index 000000000..06d9008bf --- /dev/null +++ b/Examples/java/funcptr/index.html @@ -0,0 +1,93 @@ + + +SWIG:Examples:java:funcptr + + + + + +SWIG/Examples/java/funcptr/ +
    + +

    Pointers to Functions

    + +$Header$
    + +

    +Okay, just what in the heck does SWIG do with a declaration like this? + +

    +
    +int do_op(int a, int b, int (*op)(int, int));
    +
    +
    + +Well, it creates a wrapper as usual. Of course, that does raise some +questions about the third argument (the pointer to a function). + +

    +In this case, SWIG will wrap the function pointer as it does for all other +pointers. However, in order to actually call this function from a Java program, +you will need to pass some kind of C function pointer object. In C, +this is easy, you just supply a function name as an argument like this: + +

    +
    +/* Some callback function */
    +int add(int a, int b) {
    +   return a+b;
    +} 
    +...
    +int r = do_op(x,y,add);
    +
    +
    + +To make this work with SWIG, you will need to do a little extra work. Specifically, +you need to create some function pointer objects using the %constant directive like this: + +
    +
    +%constant(int (*)(int,int)) ADD = add;
    +
    +
    + +Now, in a Java program, you would do this: + +
    +
    +int r = do_op(x,y, example.ADD)
    +
    +
    +where example is the module name. + +

    An Example

    + +Here are some files that illustrate this with a simple example: + + + +

    Notes

    + +
      +
    • The value of a function pointer must correspond to a function written in C or C++. +It is not possible to pass an arbitrary Java function in as a substitute for a C +function pointer. + +

      +

    • A Java function can be used as a C/C++ callback if you write some +clever typemaps and are very careful about how you create your extension. +This is an advanced topic not covered here. +
    + +
    + + + + + + diff --git a/Examples/java/funcptr/main.java b/Examples/java/funcptr/main.java new file mode 100644 index 000000000..cf81f92b4 --- /dev/null +++ b/Examples/java/funcptr/main.java @@ -0,0 +1,33 @@ + +public class main { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + + + int a = 37; + int b = 42; + + // Now call our C function with a bunch of callbacks + + System.out.println( "Trying some C callback functions" ); + System.out.println( " a = " + a ); + System.out.println( " b = " + b ); + System.out.println( " ADD(a,b) = " + example.do_op(a,b,example.ADD) ); + System.out.println( " SUB(a,b) = " + example.do_op(a,b,example.SUB) ); + System.out.println( " MUL(a,b) = " + example.do_op(a,b,example.MUL) ); + + System.out.println( "Here is what the C callback function classes are called in Java" ); + System.out.println( " ADD = " + example.ADD.getClass().getName() ); + System.out.println( " SUB = " + example.SUB.getClass().getName() ); + System.out.println( " MUL = " + example.MUL.getClass().getName() ); + } +} diff --git a/Examples/java/index.html b/Examples/java/index.html new file mode 100644 index 000000000..547a78af9 --- /dev/null +++ b/Examples/java/index.html @@ -0,0 +1,68 @@ + + +SWIG:Examples:java + + + +

    SWIG Java Examples

    + +$Header$
    + +

    +The following examples illustrate the use of SWIG with Java. + +

      +
    • simple. A minimal example showing how SWIG can +be used to wrap a C function, a global variable, and a constant. +
    • native. Comparing the manual and the SWIG approach to calling native code. +
    • typemap. Modifying the Java module's default behaviour by using typemaps. +
    • constants. This shows how preprocessor macros and +certain C declarations are turned into constants. +
    • variables. An example showing how to access C global variables. +
    • enum. Wrapping enumerations. +
    • class. How to wrap a simple C++ class. +
    • reference. C++ references. +
    • pointer. Simple pointer handling. +
    • template. C++ templates. +
    • funcptr. Pointers to functions. +
    + +

    Running the examples

    +Please see the Windows page in the main manual for information on using the examples on Windows.

    + +On Unix most of the examples work by making the Makefile before executing the program main.java. The Makefile will output the swig generated JNI c code as well as the Java wrapper classes. Additionally the JNI c/c++ code is compiled into the shared object (dynamic link library) which is needed for dynamic linking to the native code. The Makefiles also compile the Java files using javac. +

    +Ensure that the dynamic link library file is in the appropriate path before executing the Java program. For example in Unix, libexample.so must be in the LD_LIBRARY_PATH. +

    +A Unix example: +

    +
    +$ make
    +$ export LD_LIBRARY_PATH=. #ksh 
    +$ java main
    +
    +
    +

    + + + +

    Compatibility

    + +The examples have been extensively tested on the following platforms: + +
      +
    • Solaris +
    + +The examples have been extensively tested using Sun's JDK on: + +
      +
    • Sparc Solaris 2.6. +
    + +Your mileage may vary. If you experience a problem, please let us know by +sending a message to swig-dev@cs.uchicago.edu. + + + + diff --git a/Examples/java/mpointer/Makefile b/Examples/java/mpointer/Makefile new file mode 100644 index 000000000..69fb4e670 --- /dev/null +++ b/Examples/java/mpointer/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/mpointer/example.cxx b/Examples/java/mpointer/example.cxx new file mode 100644 index 000000000..1a6bb666a --- /dev/null +++ b/Examples/java/mpointer/example.cxx @@ -0,0 +1,45 @@ +/* File : example.c */ + +#include "example.h" +#include + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} + +double do_op(Shape *s, double (Shape::*m)(void)) { + return (s->*m)(); +} + +double (Shape::*areapt())(void) { + return &Shape::area; +} + +double (Shape::*perimeterpt())(void) { + return &Shape::perimeter; +} + +/* Member pointer variables */ +double (Shape::*areavar)(void) = &Shape::area; +double (Shape::*perimetervar)(void) = &Shape::perimeter; + diff --git a/Examples/java/mpointer/example.h b/Examples/java/mpointer/example.h new file mode 100644 index 000000000..110fe91c1 --- /dev/null +++ b/Examples/java/mpointer/example.h @@ -0,0 +1,50 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + double *z; + + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +extern double do_op(Shape *s, double (Shape::*m)(void)); + +/* Functions that return member pointers */ + +extern double (Shape::*areapt())(void); +extern double (Shape::*perimeterpt())(void); + +/* Global variables that are member pointers */ +extern double (Shape::*areavar)(void); +extern double (Shape::*perimetervar)(void); + + + diff --git a/Examples/java/mpointer/example.i b/Examples/java/mpointer/example.i new file mode 100644 index 000000000..238792be8 --- /dev/null +++ b/Examples/java/mpointer/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Some constants */ + +%constant double (Shape::*AREAPT)(void) = &Shape::area; +%constant double (Shape::*PERIMPT)(void) = &Shape::perimeter; +%constant double (Shape::*NULLPT)(void) = 0; + diff --git a/Examples/java/mpointer/main.java b/Examples/java/mpointer/main.java new file mode 100644 index 000000000..ab6cdf159 --- /dev/null +++ b/Examples/java/mpointer/main.java @@ -0,0 +1,61 @@ +// Example using pointers to member functions + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + // Get the pointers + + SWIGTYPE_m_Shape__f_void__double area_pt = example.areapt(); + SWIGTYPE_m_Shape__f_void__double perim_pt = example.perimeterpt(); + + System.out.println( "area_pt =" + area_pt ); + System.out.println( "perim_pt = " + perim_pt ); + + // Create some objects + + Circle c = new Circle(4); + Square s = new Square(10); + + // Do some calculations + + System.out.println( "Circle area = " + example.do_op(c,area_pt) ); + System.out.println( "Circle perim = " + example.do_op(c,perim_pt) ); + System.out.println( "Square area = " + example.do_op(s,area_pt) ); + System.out.println( "Square perim = " + example.do_op(s,perim_pt) ); + + System.out.println( "areavar = " + example.getAreavar() ); + System.out.println( "perimetervar = " + example.getPerimetervar() ); + + // Try the variables + System.out.println( "Circle area = " + example.do_op(c,example.getAreavar()) ); + System.out.println( "Circle perim = " + example.do_op(c,example.getPerimetervar()) ); + System.out.println( "Square area = " + example.do_op(s,example.getAreavar()) ); + System.out.println( "Square perim = " + example.do_op(s,example.getPerimetervar()) ); + + // Modify one of the variables + example.setAreavar(perim_pt); + + System.out.println( "Circle perimeter = " + example.do_op(c,example.getAreavar()) ); + + // Try the constants + + System.out.println( "example.AREAPT =" + example.AREAPT ); + System.out.println( "example.PERIMPT=" + example.PERIMPT ); + System.out.println( "example.NULLPT =" + example.NULLPT ); + + System.out.println( "Circle area = " + example.do_op(c,example.AREAPT) ); + System.out.println( "Circle perim = " + example.do_op(c,example.PERIMPT) ); + System.out.println( "Square area = " + example.do_op(s,example.AREAPT) ); + System.out.println( "Square perim = " + example.do_op(s,example.PERIMPT) ); + + } +} diff --git a/Examples/java/multimap/.cvsignore b/Examples/java/multimap/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/multimap/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/multimap/Makefile b/Examples/java/multimap/Makefile new file mode 100644 index 000000000..b1f254ed3 --- /dev/null +++ b/Examples/java/multimap/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/multimap/example.c b/Examples/java/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/java/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/java/multimap/example.i b/Examples/java/multimap/example.i new file mode 100644 index 000000000..6b0743001 --- /dev/null +++ b/Examples/java/multimap/example.i @@ -0,0 +1,101 @@ +/* File : example.i */ +%module example + +extern int gcd(int x, int y); + +%typemap(jni) (int argc, char *argv[]) "jobjectArray" +%typemap(jtype) (int argc, char *argv[]) "String[]" +%typemap(jstype) (int argc, char *argv[]) "String[]" + +%typemap(javain) (int argc, char *argv[]) "$javainput" + +%typemap(in) (int argc, char *argv[]) (jstring *jsarray) { +int i; + + $1 = (*jenv)->GetArrayLength(jenv, $input); + if ($1 == 0) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); + return $null; + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + jsarray = (jstring *) malloc($1*sizeof(jstring)); + for (i = 0; i < $1; i++) { + jsarray[i] = (jstring) (*jenv)->GetObjectArrayElement(jenv, $input, i); + $2[i] = (char *) (*jenv)->GetStringUTFChars(jenv, jsarray[i], 0); + } + $2[i] = 0; +} + +%typemap(argout) (int argc, char *argv[]) "" /* override char *[] default */ + +%typemap(freearg) (int argc, char *argv[]) { +int i; + for (i = 0; i < $1; i++) { + (*jenv)->ReleaseStringUTFChars(jenv, jsarray$argnum[i], $2[i]); + } + free($2); +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(jni) (char *bytes, int len) "jstring" +%typemap(jtype) (char *bytes, int len) "String" +%typemap(jstype) (char *bytes, int len) "String" + +%typemap(javain) (char *bytes, int len) "$javainput" + +%typemap(in) (char *bytes, int len) { + $1 = ($1_type)(*jenv)->GetStringUTFChars(jenv, $input, 0); + $2 = (*jenv)->GetStringUTFLength(jenv, $input); +} + +%typemap(freearg) (char *bytes, int len) %{ + (*jenv)->ReleaseStringUTFChars(jenv, $input, $1); +%} + +extern int count(char *bytes, int len, char c); + +/* This example shows how to wrap a function that mutates a c string. A one + * element Java string array is used so that the string can be returned modified.*/ + +%typemap(jni) (char *str, int len) "jobjectArray" +%typemap(jtype) (char *str, int len) "String[]" +%typemap(jstype) (char *str, int len) "String[]" + +%typemap(javain) (char *str, int len) "$javainput" + +%typemap(in) (char *str, int len) (jstring js) %{ + int index=0; + + js = (jstring) (*jenv)->GetObjectArrayElement(jenv, $input, index); + $1 = (char *) (*jenv)->GetStringUTFChars(jenv, js, 0); + $2 = (*jenv)->GetStringUTFLength(jenv, js); +%} + +/* Return the mutated string as a modified element in the array. */ +%typemap(argout) (char *str, int len) { + jstring newstring = (*jenv)->NewStringUTF(jenv, $1); + (*jenv)->SetObjectArrayElement(jenv, $input, 0, newstring); +} + +/* Release memory */ +%typemap(freearg) (char *str, int len) { + (*jenv)->ReleaseStringUTFChars(jenv, js$argnum, $1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, "$1_name and $2_name must be in unit circle"); + return; + } +} + +extern void circle(double cx, double cy); + + diff --git a/Examples/java/multimap/main.java b/Examples/java/multimap/main.java new file mode 100644 index 000000000..331ac6b89 --- /dev/null +++ b/Examples/java/multimap/main.java @@ -0,0 +1,40 @@ + +public class main { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + + // Call our gcd() function + int x = 42; + int y = 105; + int g = example.gcd(x,y); + System.out.println("The gcd of " + x + " and " + y + " is " + g); + + // Call the gcdmain() function + String[] args = {"gcdmain","42","105"}; + example.gcdmain(args); + + // Call the count function + System.out.println(example.count("Hello World", 'l')); + + // Call the capitalize function + String[] capitalizeMe = {"hello world"}; + example.capitalize(capitalizeMe); + System.out.println(capitalizeMe[0]); + } +} + + + + + + + diff --git a/Examples/java/native/.cvsignore b/Examples/java/native/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/native/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/native/Makefile b/Examples/java/native/Makefile index 1bd5ddd3a..e8b93c0d3 100644 --- a/Examples/java/native/Makefile +++ b/Examples/java/native/Makefile @@ -1,17 +1,18 @@ TOP = ../.. SWIG = $(TOP)/../swig -SWIGOPT = SRCS = -TARGET = libexample +TARGET = example INTERFACE = example.i +SWIGOPT = -noproxy all:: java java:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java clean:: - rm -f *_wrap* example.java *.class *.o *~ .~* core *.so *.sl so_locations + $(MAKE) -f $(TOP)/Makefile java_clean check: all diff --git a/Examples/java/native/README b/Examples/java/native/README deleted file mode 100644 index 2b5bbcdb4..000000000 --- a/Examples/java/native/README +++ /dev/null @@ -1,6 +0,0 @@ -type: -make -javac *.java -export LD_LIBRARY_PATH=. # sh -setenv LD_LIBRARY_PATH . # csh -java main diff --git a/Examples/java/native/example.i b/Examples/java/native/example.i index 331a2265b..76ae9eea8 100644 --- a/Examples/java/native/example.i +++ b/Examples/java/native/example.i @@ -18,17 +18,17 @@ Point *point_create(int x, int y) { return p; } -/* this function will be wrapped by jswig */ +/* this function will be wrapped by SWIG */ char *point_toString1(Point *p) { - char buf[80]; + static char buf[80]; sprintf(buf, "(%d,%d)", p->x, p->y); - return strdup(buf); /* memory leak */ + return buf; } /* this one we wrapped manually*/ -JNIEXPORT jstring JNICALL Java_example_point_1toString2(JNIEnv *jenv, jclass jcls, jlong jpoint) { +JNIEXPORT jstring JNICALL Java_exampleJNI_point_1toString2(JNIEnv *jenv, jclass jcls, jlong jpoint) { Point * p; char buf[80]; jstring result; @@ -45,10 +45,8 @@ JNIEXPORT jstring JNICALL Java_example_point_1toString2(JNIEnv *jenv, jclass jcl Point *point_create(int x, int y); char *point_toString1(Point *p); -/* - Use %new to free the memory returned by point_toString1 - %new char *point_toString1(Point *p); -*/ +/* give access to free() for memory cleanup of the malloc'd Point */ +extern void free(void *memblock); %native(point_toString2) char *point_toString2(Point *p); diff --git a/Examples/java/native/index.html b/Examples/java/native/index.html new file mode 100644 index 000000000..1942d7440 --- /dev/null +++ b/Examples/java/native/index.html @@ -0,0 +1,33 @@ + + +SWIG:Examples:java:native + + + + + +SWIG/Examples/java/native/ +
    + +

    SWIG wrapped and manually wrapped functions in Java

    + +$Header$
    + +

    +This example compares wrapping a c global function using the manual way and the SWIG way. + +

      +
    • example.i. Interface file comparing code wrapped by SWIG and wrapped manually. +
    • main.java. Sample Java program showing calls to both manually wrapped and SWIG wrapped c functions. +
    + +

    Notes

    + +
      +
    • SWIG writes all the awkward JNI code for you. You just have to tell SWIG which functions to wrap. +
    • If memory is allocated in c it needs to be free'd. A function, such as free(), can be provided with access from Java to free the memory. +
    + +
    + + diff --git a/Examples/java/native/main.java b/Examples/java/native/main.java index 444d53b58..f4760bb3d 100644 --- a/Examples/java/native/main.java +++ b/Examples/java/native/main.java @@ -1,4 +1,3 @@ -import example; public class main { @@ -6,14 +5,15 @@ public class main { try { System.loadLibrary("example"); } catch (UnsatisfiedLinkError e) { - System.err.println("Cannot load the native code.\nMake sure your LD_LIBRARY_PATH contains \'.\'\n" + e); + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); System.exit(1); } } public static void main(String argv[]) { - long p = example.point_create(1, 2); + SWIGTYPE_p_Point p = example.point_create(1, 2); System.out.println("auto wrapped : " + example.point_toString1(p)); System.out.println("manual wrapped: " + example.point_toString2(p)); + example.free(new SWIGTYPE_p_void(SWIGTYPE_p_Point.getCPtr(p), false)); //clean up c allocated memory } } diff --git a/Examples/java/pointer/.cvsignore b/Examples/java/pointer/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/pointer/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/pointer/Makefile b/Examples/java/pointer/Makefile new file mode 100644 index 000000000..b1f254ed3 --- /dev/null +++ b/Examples/java/pointer/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/pointer/example.c b/Examples/java/pointer/example.c new file mode 100644 index 000000000..b877d9a5b --- /dev/null +++ b/Examples/java/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void sub(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/java/pointer/example.i b/Examples/java/pointer/example.i new file mode 100644 index 000000000..4483b0f77 --- /dev/null +++ b/Examples/java/pointer/example.i @@ -0,0 +1,24 @@ +/* File : example.i */ +%module example + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void sub(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/java/pointer/index.html b/Examples/java/pointer/index.html new file mode 100644 index 000000000..2be8d38d7 --- /dev/null +++ b/Examples/java/pointer/index.html @@ -0,0 +1,167 @@ + + +SWIG:Examples:java:pointer + + + + +SWIG/Examples/java/pointer/ +
    + +

    Simple Pointer Handling

    + +$Header$
    + +

    +This example illustrates a couple of techniques for handling +simple pointers in SWIG. The prototypical example is a C function +that operates on pointers such as this: + +

    +
    +void add(int *x, int *y, int *r) { 
    +    *r = *x + *y;
    +}
    +
    +
    + +By default, SWIG wraps this function exactly as specified and creates +an interface that expects pointer objects for arguments. +SWIG wraps a C pointer with a type wrapper class, for example, SWIGTYPE_p_int for an int*. +The only problem is how does one go about creating these objects from a Java program? +

    + + +

    Possible Solutions

    + +
      +
    • Write some helper functions to explicitly create objects. For +example: + +
      +
      +int *new_int(int ivalue) {
      +  int *i = (int *) malloc(sizeof(ivalue));
      +  *i = ivalue;
      +  return i;
      +}
      +int get_int(int *i) {
      +  return *i;
      +}
      +
      +void delete_int(int *i) {
      +  free(i);
      +}
      +
      +
      + +

      +

    • The SWIG pointer library provides an easier way.
      +For example, in the interface file +you would do this: + +
      +
      +%include cpointer.i
      +%pointer_functions(int, intp);
      +
      +
      + +and from Java you would use pointers like this: + +
      +
      +SWIGTYPE_p_int a = example.new_intp();
      +SWIGTYPE_p_int b = example.new_intp();
      +SWIGTYPE_p_int c = example.new_intp();
      +example.intp_assign(a,37);
      +example.intp_assign(b,42);
      +
      +// Note that getCPtr() has package access by default
      +System.out.println("     a =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(a)));
      +System.out.println("     b =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(b)));
      +System.out.println("     c =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(c)));
      +
      +// Call the add() function with some pointers
      +example.add(a,b,c);
      +
      +// Now get the result
      +int res = example.intp_value(c);
      +System.out.println("     37 + 42 =" + res);
      +
      +// Clean up the pointers
      +example.delete_intp(a);
      +example.delete_intp(b);
      +example.delete_intp(c);
      +
      +
      + +

      +

    • Use the SWIG typemap library. This library allows you to completely +change the way arguments are processed by SWIG. For example: + +
      +
      +%include "typemaps.i"
      +void add(int *INPUT, int *INPUT, int *OUTPUT);
      +
      +
      + +And in a Java program: + +
      +
      +int[] r = {0};
      +example.sub(37,42,r);
      +System.out.println("Result =" + r[0]);
      +
      +
      +Needless to say, this is substantially easier although a bit unusual. + +

      +

    • A final alternative is to use the typemaps library in combination +with the %apply directive. This allows you to change the names of parameters +that behave as input or output parameters. For example: + +
      +
      +%include "typemaps.i"
      +%apply int *INPUT {int *x, int *y};
      +%apply int *OUTPUT {int *r};
      +
      +void add(int *x, int *y, int *r);
      +void sub(int *x, int *y, int *r);
      +void mul(int *x, int *y, int *r);
      +... etc ...
      +
      +
      + +
    + +

    Example

    + +The following example illustrates the use of these features for pointer +extraction. + + + +

    Notes

    + +
      +
    • Since pointers are used for so many different things (arrays, output values, +etc...) the complexity of pointer handling can be as complicated as you want to +make it. + +

      +

    • More documentation on the typemaps.i and cpointer.i library files can be +found in the SWIG user manual. The files also contain documentation. + +
    + +
    + + diff --git a/Examples/java/pointer/main.java b/Examples/java/pointer/main.java new file mode 100644 index 000000000..e96e02eaa --- /dev/null +++ b/Examples/java/pointer/main.java @@ -0,0 +1,55 @@ + +public class main { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + + // First create some objects using the pointer library. + System.out.println("Testing the pointer library"); + SWIGTYPE_p_int a = example.new_intp(); + SWIGTYPE_p_int b = example.new_intp(); + SWIGTYPE_p_int c = example.new_intp(); + example.intp_assign(a,37); + example.intp_assign(b,42); + + // Note that getCPtr() has package access by default + System.out.println(" a =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(a))); + System.out.println(" b =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(b))); + System.out.println(" c =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(c))); + + // Call the add() function with some pointers + example.add(a,b,c); + + // Now get the result + int res = example.intp_value(c); + System.out.println(" 37 + 42 =" + res); + + // Clean up the pointers + example.delete_intp(a); + example.delete_intp(b); + example.delete_intp(c); + + // Now try the typemap library + // Now it is no longer necessary to manufacture pointers. + // Instead we use a single element array which in Java is modifiable. + + System.out.println("Trying the typemap library"); + int[] r = {0}; + example.sub(37,42,r); + System.out.println(" 37 - 42 = " + r[0]); + + // Now try the version with return value + + System.out.println("Testing return value"); + int q = example.divide(42,37,r); + System.out.println(" 42/37 = " + q + " remainder " + r[0]); + } +} diff --git a/Examples/java/reference/.cvsignore b/Examples/java/reference/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/reference/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/reference/Makefile b/Examples/java/reference/Makefile new file mode 100644 index 000000000..69fb4e670 --- /dev/null +++ b/Examples/java/reference/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/reference/example.cxx b/Examples/java/reference/example.cxx new file mode 100644 index 000000000..384e40bb7 --- /dev/null +++ b/Examples/java/reference/example.cxx @@ -0,0 +1,41 @@ +/* File : example.cxx */ + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %x (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/java/reference/example.h b/Examples/java/reference/example.h new file mode 100644 index 000000000..4915adb1b --- /dev/null +++ b/Examples/java/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/java/reference/example.i b/Examples/java/reference/example.i new file mode 100644 index 000000000..e71f297bf --- /dev/null +++ b/Examples/java/reference/example.i @@ -0,0 +1,46 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*self)[index]; + } + void set(int index, Vector &a) { + (*self)[index] = a; + } + } +}; + + + + diff --git a/Examples/java/reference/index.html b/Examples/java/reference/index.html new file mode 100644 index 000000000..946bda0fa --- /dev/null +++ b/Examples/java/reference/index.html @@ -0,0 +1,149 @@ + + +SWIG:Examples:java:reference + + + + + +SWIG/Examples/java/reference/ +
    + +

    C++ Reference Handling

    + +$Header$
    + +

    +This example tests SWIG's handling of C++ references. Since C++ +references are closely related to pointers (as both refer to a +location in memory), SWIG simply collapses all references into +pointers when creating wrappers. + +

    Some examples

    + +References are most commonly used as function parameter. For example, +you might have an operator like this: + +
    +
    +Vector operator+(const Vector &a, const Vector &b) {
    +   Vector result;
    +   result.x = a.x + b.x;
    +   result.y = a.y + b.y;
    +   result.z = a.z + b.z;
    +   return result;
    +}
    +
    +
    + +or a function: + +
    +
    +Vector addv(const Vector &a, const Vector &b) {
    +   Vector result;
    +   result.x = a.x + b.x;
    +   result.y = a.y + b.y;
    +   result.z = a.z + b.z;
    +   return result;
    +}
    +
    +
    + +In these cases, SWIG transforms everything into a pointer and creates a wrapper +that looks like this: + +
    +
    +Vector wrap_addv(Vector *a, Vector *b) {
    +    return addv(*a,*b);
    +}
    +
    +
    + +Occasionally, a reference is used as a return value of a function +when the return result is to be used as an lvalue in an expression. +The prototypical example is an operator like this: + +
    +
    +Vector &operator[](int index);
    +
    +
    + +or a method: + +
    +
    +Vector &get(int index);
    +
    +
    + +For functions returning references, a wrapper like this is created: + +
    +
    +Vector *wrap_Object_get(Object *self, int index) {
    +    Vector &result = self->get(index);
    +    return &result;
    +}
    +
    +
    + +The following header file contains some class +definitions with some operators and use of references. + +

    SWIG Interface

    + +SWIG does NOT support overloaded operators so it can not directly build +an interface to the classes in the above file. However, a number of workarounds +can be made. For example, an overloaded operator can be stuck behind a function +call such as the addv() function above. Array access can be handled +with a pair of set/get functions like this: + +
    +
    +class VectorArray {
    +public:
    + ...
    +   %addmethods {
    +    Vector &get(int index) {
    +      return (*self)[index];
    +    }
    +    void set(int index, Vector &a) {
    +      (*self)[index] = a;
    +    }
    +   }
    +   ...
    +}
    +
    +
    + +Click here to see a SWIG interface file with these additions. + +

    Sample Java program

    + +Click here to see a Java program that manipulates some C++ references. + +

    Notes:

    + +
      +
    • C++ references primarily provide notational convenience for C++ +source code. However, Java only supports the 'x.a' +notation so it doesn't much matter. + +

      +

    • When a program returns a reference, a pointer is returned. +Unlike return by value, memory is not allocated to hold the +return result. + +

      +

    • SWIG has particular trouble handling various combinations of references +and pointers. This is side effect of an old parsing scheme and +type representation that will be replaced in future versions. + +
    + +
    + + diff --git a/Examples/java/reference/main.java b/Examples/java/reference/main.java new file mode 100644 index 000000000..4fd354761 --- /dev/null +++ b/Examples/java/reference/main.java @@ -0,0 +1,79 @@ +// This example illustrates the manipulation of C++ references in Java. + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + System.out.println( "Creating some objects:" ); + Vector a = new Vector(3,4,5); + Vector b = new Vector(10,11,12); + + System.out.println( " Created " + a.print() ); + System.out.println( " Created " + b.print() ); + + // ----- Call an overloaded operator ----- + + // This calls the wrapper we placed around + // + // operator+(const Vector &a, const Vector &) + // + // It returns a new allocated object. + + System.out.println( "Adding a+b" ); + Vector c = example.addv(a,b); + System.out.println( " a+b = " + c.print() ); + + // Note: Unless we free the result, a memory leak will occur if the -noproxy commandline + // is used as the proxy classes define finalizers which call the delete() method. When + // -noproxy is not specified the memory management is controlled by the garbage collector. + // You can still call delete(). It will free the c++ memory immediately, but not the + // Java memory! You then must be careful not to call any member functions as it will + // use a NULL c pointer on the underlying c++ object. We set the Java object to null + // which will then throw a Java exception should we attempt to use it again. + c.delete(); + c = null; + + // ----- Create a vector array ----- + + System.out.println( "Creating an array of vectors" ); + VectorArray va = new VectorArray(10); + System.out.println( " va = " + va.toString() ); + + // ----- Set some values in the array ----- + + // These operators copy the value of Vector a and Vector b to the vector array + va.set(0,a); + va.set(1,b); + + // This works, but it would cause a memory leak if -noproxy was used! + + va.set(2,example.addv(a,b)); + + + // Get some values from the array + + System.out.println( "Getting some array values" ); + for (int i=0; i<5; i++) + System.out.println( " va(" + i + ") = " + va.get(i).print() ); + + // Watch under resource meter to check on this + System.out.println( "Making sure we don't leak memory." ); + for (int i=0; i<1000000; i++) + c = va.get(i%10); + + // ----- Clean up ----- + // This could be omitted. The garbage collector would then clean up for us. + System.out.println( "Cleaning up" ); + va.delete(); + a.delete(); + b.delete(); + } +} diff --git a/Examples/java/simple/.cvsignore b/Examples/java/simple/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/simple/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/simple/Makefile b/Examples/java/simple/Makefile index f55601b9c..b1f254ed3 100644 --- a/Examples/java/simple/Makefile +++ b/Examples/java/simple/Makefile @@ -1,17 +1,18 @@ TOP = ../.. SWIG = $(TOP)/../swig SRCS = example.c -TARGET = libexample +TARGET = example INTERFACE = example.i -SWIGOPT = +SWIGOPT = all:: java java:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java clean:: - rm -f *_wrap* *.o core *~ *.so *.class example.java + $(MAKE) -f $(TOP)/Makefile java_clean check: all diff --git a/Examples/java/simple/README b/Examples/java/simple/README deleted file mode 100644 index b52b7d7b0..000000000 --- a/Examples/java/simple/README +++ /dev/null @@ -1,8 +0,0 @@ -Simple example from users manual. - -type: -make -javac *.java -export LD_LIBRARY_PATH=. # sh -setenv LD_LIBRARY_PATH . # csh -java main diff --git a/Examples/java/simple/example.c b/Examples/java/simple/example.c index f2b074781..1c2af789c 100644 --- a/Examples/java/simple/example.c +++ b/Examples/java/simple/example.c @@ -1,24 +1,18 @@ -/* Simple example from documentation */ /* File : example.c */ -#include +/* A global variable */ +double Foo = 3.0; -double My_variable = 3.0; - -/* Compute factorial of n */ -int fact(int n) { - if (n <= 1) return 1; - else return n*fact(n-1); -} - -/* Compute n mod m */ -int my_mod(int n, int m) { - return (n % m); +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; } -char *get_time() { - long ltime; - time(<ime); - return ctime(<ime); -} diff --git a/Examples/java/simple/example.dsp b/Examples/java/simple/example.dsp new file mode 100644 index 000000000..7228d6cbb --- /dev/null +++ b/Examples/java/simple/example.dsp @@ -0,0 +1,158 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_INCLUDE)" /I "$(JAVA_INCLUDE)\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Java compile post-build step +PostBuild_Cmds=echo on %JAVA_BIN%\javac *.java +# End Special Build Tool + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(JAVA_INCLUDE)" /I "$(JAVA_INCLUDE)\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"example.dll" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Java compile post-build step +PostBuild_Cmds=echo on %JAVA_BIN%\javac *.java +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo JAVA_INCLUDE: %JAVA_INCLUDE% + echo JAVA_BIN: %JAVA_BIN% + echo on + ..\..\..\swig.exe -java $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo JAVA_INCLUDE: %JAVA_INCLUDE% + echo JAVA_BIN: %JAVA_BIN% + echo on + ..\..\..\swig.exe -java $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/java/simple/example.i b/Examples/java/simple/example.i index b7b678776..6702abb1e 100644 --- a/Examples/java/simple/example.i +++ b/Examples/java/simple/example.i @@ -1,11 +1,5 @@ /* File : example.i */ %module example -%{ -/* Put headers and other declarations here */ -%} - -extern double My_variable; -extern int fact(int); -%name(mod) extern int my_mod(int n, int m); -extern char *get_time(); +extern int gcd(int x, int y); +extern double Foo; diff --git a/Examples/java/simple/index.html b/Examples/java/simple/index.html new file mode 100644 index 000000000..ac06b7302 --- /dev/null +++ b/Examples/java/simple/index.html @@ -0,0 +1,110 @@ + + +SWIG:Examples:java:simple + + + + + +SWIG/Examples/java/simple/ +
    + +

    Simple Java Example

    + +$Header$
    + +

    +This example illustrates how you can hook Java to a very simple C program containing +a function and a global variable. + +

    The C Code

    + +Suppose you have the following C code: + +
    +
    +/* File : example.c */
    +
    +/* A global variable */
    +double Foo = 3.0;
    +
    +/* Compute the greatest common divisor of positive integers */
    +int gcd(int x, int y) {
    +  int g;
    +  g = y;
    +  while (x > 0) {
    +    g = x;
    +    x = y % x;
    +    y = g;
    +  }
    +  return g;
    +}
    +
    +
    + +

    The SWIG interface

    + +Here is a simple SWIG interface file: + +
    +
    +/* File: example.i */
    +%module example
    +
    +extern int gcd(int x, int y);
    +extern double Foo;
    +
    +
    + +

    Compilation

    + +
      +
    1. swig -java example.i +

      +

    2. Compile example_wrap.c and example.c +to create the extension libexample.so (unix). +
    + +

    Using the extension

    + +Click here to see a program that calls our C functions from Java. +

    +Compile the java files example.java and main.java +to create the class files example.class and main.class before running main in the JVM. Ensure that the libexample.so file is in your LD_LIBRARY_PATH before running. For example: +

    +
    +export LD_LIBRARY_PATH=. #ksh 
    +javac *.java
    +java main
    +
    +
    + +

    Key points

    + +
      +
    • Use the loadLibrary statement from java to load and access the generated java classes. For example: +
      +
      +System.loadLibrary("example");
      +
      +
      + +
    • C functions work just like Java functions. For example: +
      +
      +int g = example.gcd(42,105);
      +
      +
      + +
    • C global variables are accessed through get and set functions in the module class. For example: +
      +
      +double a = example.get_Foo();
      +example.set_Foo(20.0);
      +
      +
      +
    + +
    + + diff --git a/Examples/java/simple/main.java b/Examples/java/simple/main.java index bbebfb660..6d224a4dc 100644 --- a/Examples/java/simple/main.java +++ b/Examples/java/simple/main.java @@ -1,4 +1,3 @@ -import example; public class main { @@ -6,27 +5,28 @@ public class main { try { System.loadLibrary("example"); } catch (UnsatisfiedLinkError e) { - System.err.println("Cannot load the example native code.\nMake sure your LD_LIBRARY_PATH contains \'.\'\n" + e); + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); System.exit(1); } } public static void main(String argv[]) { - System.out.println(example.get_time()); - - System.out.println("My Variable = " + example.get_My_variable()); - - for(int i=0; i<14; i++) { - System.out.println("" + i + " factorial is " + example.fact(i)); - } - - for(int i=1; i<100; i++) { - for(int j=1; j<100; j++) { - int n = example.mod(i, j); - example.set_My_variable(example.get_My_variable() + n); - } - } - - System.out.println("My_variable = " + example.get_My_variable()); + // Call our gcd() function + + int x = 42; + int y = 105; + int g = example.gcd(x,y); + System.out.println("The gcd of " + x + " and " + y + " is " + g); + + // Manipulate the Foo global variable + + // Output its current value + System.out.println("Foo = " + example.getFoo()); + + // Change its value + example.setFoo(3.1415926); + + // See if the change took effect + System.out.println("Foo = " + example.getFoo()); } } diff --git a/Examples/java/template/.cvsignore b/Examples/java/template/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/template/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/template/Makefile b/Examples/java/template/Makefile new file mode 100644 index 000000000..75ec0045a --- /dev/null +++ b/Examples/java/template/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/template/example.h b/Examples/java/template/example.h new file mode 100644 index 000000000..4d9a58c54 --- /dev/null +++ b/Examples/java/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return self->get(index); + } + void setitem(int index, T val) { + self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/java/template/example.i b/Examples/java/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/java/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/java/template/index.html b/Examples/java/template/index.html new file mode 100644 index 000000000..f8fcce08e --- /dev/null +++ b/Examples/java/template/index.html @@ -0,0 +1,104 @@ + + +SWIG:Examples:java:template + + + + + +SWIG/Examples/java/template/ +
    + +

    C++ template support

    + +$Header$
    + +

    +This example illustrates how C++ templates can be used from Java using SWIG. + +

    The C++ Code

    + +Lets take a templated function and a templated class as follows: + +
    +
    +/* File : example.h */
    +
    +// Some template definitions
    +
    +template T max(T a, T b) { return  a>b ? a : b; }
    +
    +template class vector {
    +  T *v;
    +  int sz;
    + public:
    +  vector(int _sz) {
    +    v = new T[_sz];
    +    sz = _sz;
    +  }
    +  T &get(int index) {
    +    return v[index];
    +  }
    +  void set(int index, T &val) {
    +    v[index] = val;
    +  }
    +#ifdef SWIG
    +  %addmethods {
    +    T getitem(int index) {
    +      return self->get(index);
    +    }
    +    void setitem(int index, T val) {
    +      self->set(index,val);
    +    }
    +  }
    +#endif
    +};
    +
    +
    +The %addmethods is used for a neater interface from Java as the functions get and set use C++ references to primitive types. These are tricky to use from Java as they end up as a pointer in Java (Java long). + +

    The SWIG interface

    + +A simple SWIG interface for this can be built by simply grabbing the header file +like this: + +
    +
    +/* File : example.i */
    +%module example
    +
    +%{
    +#include "example.h"
    +%}
    +
    +/* Let's just grab the original header file here */
    +%include "example.h"
    +
    +/* Now instantiate some specific template declarations */
    +
    +%template(maxint) max;
    +%template(maxdouble) max;
    +%template(vecint) vector;
    +%template(vecdouble) vector;
    +
    +
    + +Note that SWIG parses the templated function max and templated class vector and so knows about them. However to generate code for use from Java, SWIG has to be told which class/type to use as the template parameter. The SWIG directive %template is used for this. + +

    A sample Java program

    + +Click here to see a Java program that calls the C++ functions from Java. + +

    Notes

    +Use templated classes just like you would any other SWIG generated Java class. Use the classnames specified by the %template directive. + +
    +
    +vecdouble dv = new vecdouble(1000);
    +dv.setitem(i, 12.34));
    +
    +
    + +
    + + diff --git a/Examples/java/template/main.java b/Examples/java/template/main.java new file mode 100644 index 000000000..9129fcf2a --- /dev/null +++ b/Examples/java/template/main.java @@ -0,0 +1,45 @@ +// This example illustrates how C++ templates can be used from Java. + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + // Call some templated functions + System.out.println(example.maxint(3,7)); + System.out.println(example.maxdouble(3.14,2.18)); + + // Create some class + + vecint iv = new vecint(100); + vecdouble dv = new vecdouble(1000); + + for (int i=0; i<100; i++) + iv.setitem(i,2*i); + + for (int i=0; i<1000; i++) + dv.setitem(i, 1.0/(i+1)); + + { + int sum = 0; + for (int i=0; i<100; i++) + sum = sum + iv.getitem(i); + + System.out.println(sum); + } + + { + double sum = 0.0; + for (int i=0; i<1000; i++) + sum = sum + dv.getitem(i); + System.out.println(sum); + } + } +} diff --git a/Examples/java/typemap/.cvsignore b/Examples/java/typemap/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/typemap/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/typemap/Makefile b/Examples/java/typemap/Makefile index ddba664d9..e8b93c0d3 100644 --- a/Examples/java/typemap/Makefile +++ b/Examples/java/typemap/Makefile @@ -1,17 +1,18 @@ TOP = ../.. SWIG = $(TOP)/../swig SRCS = -TARGET = libexample +TARGET = example INTERFACE = example.i -SWIGOPT = +SWIGOPT = -noproxy all:: java java:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java clean:: - rm -f *_wrap* *.o core *~ *.so *.class example.java + $(MAKE) -f $(TOP)/Makefile java_clean check: all diff --git a/Examples/java/typemap/README b/Examples/java/typemap/README deleted file mode 100644 index 67dabbfdc..000000000 --- a/Examples/java/typemap/README +++ /dev/null @@ -1,8 +0,0 @@ -Example of a typemap to handle return values in char * arguments. - -type: -make -javac *.java -export LD_LIBRARY_PATH=. # sh -setenv LD_LIBRARY_PATH . # csh -java main diff --git a/Examples/java/typemap/index.html b/Examples/java/typemap/index.html new file mode 100644 index 000000000..259f42953 --- /dev/null +++ b/Examples/java/typemap/index.html @@ -0,0 +1,34 @@ + + +SWIG:Examples:java:typemap + + + + + +SWIG/Examples/java/typemap/ +
    + +

    Typemaps in Java

    + +$Header$
    + +

    +This example shows how typemaps can be used to modify the default behaviour of the Java SWIG module. + +

    + +

    Notes

    + +
      +
    • Shows how to pass strings to Java from c and visa versa. +
    • Typemaps can modify the default behaviour of the Java SWIG module. +
    • The default c to java mapping can be modified using typemaps. +
    + +
    + + diff --git a/Examples/java/typemap/main.java b/Examples/java/typemap/main.java index f7da20cdc..bd9a4e1b6 100644 --- a/Examples/java/typemap/main.java +++ b/Examples/java/typemap/main.java @@ -1,4 +1,3 @@ -import example; public class main { @@ -6,7 +5,7 @@ public class main { try { System.loadLibrary("example"); } catch (UnsatisfiedLinkError e) { - System.err.println("Cannot load the example native code.\nMake sure your LD_LIBRARY_PATH contains \'.\'\n" + e); + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); System.exit(1); } } diff --git a/Examples/java/variables/.cvsignore b/Examples/java/variables/.cvsignore new file mode 100644 index 000000000..49312b8c6 --- /dev/null +++ b/Examples/java/variables/.cvsignore @@ -0,0 +1,11 @@ +*.class +*.java +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/java/variables/Makefile b/Examples/java/variables/Makefile new file mode 100644 index 000000000..b1f254ed3 --- /dev/null +++ b/Examples/java/variables/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/variables/example.c b/Examples/java/variables/example.c new file mode 100644 index 000000000..37e9feb33 --- /dev/null +++ b/Examples/java/variables/example.c @@ -0,0 +1,86 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char *cstrvar = 0; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %x\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %x (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/java/variables/example.h b/Examples/java/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/java/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/java/variables/example.i b/Examples/java/variables/example.i new file mode 100644 index 000000000..91bd0679d --- /dev/null +++ b/Examples/java/variables/example.i @@ -0,0 +1,44 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char *cstrvar; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; + + +/* Some read-only variables */ + +%immutable; +extern int status; +extern char path[256]; +%mutable; + +/* Some helper functions to make it easier to test */ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); + + + + diff --git a/Examples/java/variables/index.html b/Examples/java/variables/index.html new file mode 100644 index 000000000..efb6f9d9b --- /dev/null +++ b/Examples/java/variables/index.html @@ -0,0 +1,85 @@ + + +SWIG:Examples:java:variables + + + + +SWIG/Examples/java/variables/ +
    + +

    Wrapping C Global Variables

    + +$Header$
    + +

    +When a C global variable appears in an interface file, SWIG tries to +wrap it using a technique known as "variable linking." The idea is +pretty simple---we try to create a Java variable that magically +retrieves or updates the value of the underlying C variable when it is +accessed. Click here to see a SWIG interface with some variable +declarations in it. + +

    Manipulating Variables from Java

    + +C variables are accessed through getters and setters from Java. Unfortunately this is the only way to get current values from variables because it is not possible to overload the dot operator in Java. All global variables are accessible from the module class. For example if the module class is called 'example', the global variable + +
    +
    +double foo;
    +
    +
    + +will be accessed in the Java module as +
    +
    +example.get_foo();
    +example.set_foo(12.3);
    +
    +
    + +Click here to see the example program that updates and prints +out the values of the variables using this technique. + +

    Key points

    + +
      +
    • When a global variable has the type "char *", SWIG manages it as a character +string. However, whenever the value of such a variable is set from Java, the old +value is destroyed using free() or delete (the choice of which depends +on whether or not SWIG was run with the -c++ option). +
    • signed char and unsigned char are handled as small 8-bit integers. +
    • String array variables such as 'char name[256]' are managed as Java strings, but +when setting the value, the result is truncated to the maximum length of the array. Furthermore, the string is assumed to be null-terminated. +
    • When structures and classes are used as global variables, they are mapped into pointers. +Getting the "value" returns a pointer to the global variable. Setting the value of a structure results in a memory copy from a pointer to the global. +
    + +

    Creating read-only variables

    + +The %immutable and %mutable directives can be used to +specify a collection of read-only variables. For example: + +
    +
    +%immutable;
    +int    status;
    +double blah;
    +...
    +%mutable;
    +
    +
    + +The %immutable directive remains in effect until it is explicitly disabled +using the %mutable directive. + +

    Comments

    +
      +
    • Management of global variables is one of the most problematic aspects +of C/C++ wrapping because the Java interface and resulting memory management +is much trickier than simply creating a wrapper function. +
    + + + +
    diff --git a/Examples/java/variables/main.java b/Examples/java/variables/main.java new file mode 100644 index 000000000..f0a760b00 --- /dev/null +++ b/Examples/java/variables/main.java @@ -0,0 +1,98 @@ +// This example illustrates global variable access from Java. + +import java.lang.reflect.*; + +public class main { + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + +// Try to set the values of some global variables + + example.setIvar(42); + example.setSvar((short)-31000); + example.setLvar(65537); + example.setUivar(123456); + example.setUsvar(61000); + example.setUlvar(654321); + example.setScvar((byte)-13); + example.setUcvar((short)251); + example.setCvar('S'); + example.setFvar((float)3.14159); + example.setDvar(2.1828); + example.setStrvar("Hello World"); + example.setCstrvar("Goodbye"); + example.setIptrvar(example.new_int(37)); + example.setPtptr(example.new_Point(37,42)); + example.setName("Bill"); + + // Now print out the values of the variables + + System.out.println( "Variables (values printed from Java)" ); + + System.out.println( "ivar =" + example.getIvar() ); + System.out.println( "svar =" + example.getSvar() ); + System.out.println( "lvar =" + example.getLvar() ); + System.out.println( "uivar =" + example.getUivar() ); + System.out.println( "usvar =" + example.getUsvar() ); + System.out.println( "ulvar =" + example.getUlvar() ); + System.out.println( "scvar =" + example.getScvar() ); + System.out.println( "ucvar =" + example.getUcvar() ); + System.out.println( "fvar =" + example.getFvar() ); + System.out.println( "dvar =" + example.getDvar() ); + System.out.println( "cvar =" + (char)example.getCvar() ); + System.out.println( "strvar =" + example.getStrvar() ); + System.out.println( "cstrvar =" + example.getCstrvar() ); + System.out.println( "iptrvar =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(example.getIptrvar())) ); + System.out.println( "name =" + example.getName() ); + System.out.println( "ptptr =" + Long.toHexString(SWIGTYPE_p_Point.getCPtr(example.getPtptr())) + example.Point_print(example.getPtptr()) ); + System.out.println( "pt =" + Long.toHexString(SWIGTYPE_p_Point.getCPtr(example.getPt())) + example.Point_print(example.getPt()) ); + + System.out.println( "\nVariables (values printed from C)" ); + + example.print_vars(); + + System.out.println( "\nNow I'm going to try and modify some read only variables" ); + + System.out.println( " Trying to set 'path'" ); + try { + Method m = example.class.getDeclaredMethod("setPath", new Class[] {String.class}); + m.invoke(example.class, new Object[] {"Whoa!"} ); + System.out.println( "Hey, what's going on?!?! This shouldn't work" ); + } + catch (NoSuchMethodException e) { + System.out.println( "Good." ); + } + catch (Throwable t) { + System.out.println( "You shouldn't see this!" ); + } + + System.out.println( " Trying to set 'status'" ); + try { + Method m = example.class.getDeclaredMethod("setStatus", new Class[] {Integer.class}); + m.invoke(example.class, new Object[] {new Integer(0)} ); + System.out.println( "Hey, what's going on?!?! This shouldn't work" ); + } + catch (NoSuchMethodException e) { + System.out.println( "Good." ); + } + catch (Throwable t) { + System.out.println( "You shouldn't see this!" ); + } + + System.out.println( "\nI'm going to try and update a structure variable.\n" ); + + example.setPt(example.getPtptr()); + + System.out.println( "The new value is" ); + example.pt_print(); + System.out.println( "You should see the value" + example.Point_print(example.getPtptr()) ); + } +} diff --git a/Examples/mzscheme/check.list b/Examples/mzscheme/check.list new file mode 100644 index 000000000..ae728ea43 --- /dev/null +++ b/Examples/mzscheme/check.list @@ -0,0 +1,3 @@ +# see top-level Makefile.in +multimap +simple diff --git a/Examples/mzscheme/multimap/Makefile b/Examples/mzscheme/multimap/Makefile new file mode 100644 index 000000000..5ac93f8f0 --- /dev/null +++ b/Examples/mzscheme/multimap/Makefile @@ -0,0 +1,13 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' mzscheme +clean:: + $(MAKE) -f $(TOP)/Makefile mzscheme_clean + +check: all diff --git a/Examples/mzscheme/multimap/example.c b/Examples/mzscheme/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/mzscheme/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/mzscheme/multimap/example.i b/Examples/mzscheme/multimap/example.i new file mode 100644 index 000000000..6ca7dc33e --- /dev/null +++ b/Examples/mzscheme/multimap/example.i @@ -0,0 +1,81 @@ +/* File : example.i */ +%module example +%include exception.i +%include typemaps.i + +extern int gcd(int x, int y); + +%typemap(mzscheme,in) (int argc, char *argv[]) { + int i; + Scheme_Object **elms; + if (!SCHEME_VECTORP($input)) { + scheme_wrong_type("$name","vector",$argnum,argc,argv); + } + $1 = SCHEME_VEC_SIZE($input); + elms = SCHEME_VEC_ELS($input); + if ($1 == 0) { + scheme_wrong_type("$name","vector",$argnum,argc,argv); + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + if (!SCHEME_STRINGP(elms[i])) { + free($2); + scheme_wrong_type("$name","vector",$argnum,argc,argv); + } + $2[i] = SCHEME_STR_VAL(elms[i]); + } + $2[i] = 0; +} + +%typemap(mzscheme,freear) (int argc, char *argv[]) { + free($2); +} +extern int gcdmain(int argc, char *argv[]); + +%typemap(mzscheme,in) (char *bytes, int len) { + if (!SCHEME_STRINGP($input)) { + scheme_wrong_type("$name","string",1,argc,argv); + } + $1 = SCHEME_STR_VAL($input); + $2 = SCHEME_STRLEN_VAL($input); +} + +extern int count(char *bytes, int len, char c); + + +/* This example shows how to wrap a function that mutates a string */ + +%typemap(mzscheme,in) (char *str, int len) { + if (!SCHEME_STRINGP($input)) { + scheme_wrong_type("$name","string",1,argc,argv); + } + $2 = SCHEME_STRLEN_VAL($input); + $1 = (char *) malloc($2+1); + memmove($1,SCHEME_STR_VAL($input),$2); +} + +/* Return the mutated string as a new object. */ + +%typemap(mzscheme,argout) (char *str, int len) { + Scheme_Object *s; + s = scheme_make_sized_string($1,$2,1); + SWIG_APPEND_VALUE(s); + free($1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + return NULL; + } +} + +extern void circle(double cx, double cy); + + diff --git a/Examples/mzscheme/multimap/example.scm b/Examples/mzscheme/multimap/example.scm new file mode 100644 index 000000000..ac9f64283 --- /dev/null +++ b/Examples/mzscheme/multimap/example.scm @@ -0,0 +1,27 @@ +;; run with mzscheme -r example.scm + +(load-extension "example.so") + +; Call the GCD function + +(define x 42) +(define y 105) +(define g (gcd x y)) + +(display "The gcd of ") +(display x) +(display " and ") +(display y) +(display " is ") +(display g) +(newline) + +; Call the gcdmain() function +(gcdmain #("gcdmain" "42" "105")) + + +(display (count "Hello World" #\l)) +(newline) + +(display (capitalize "hello world")) +(newline) \ No newline at end of file diff --git a/Examples/mzscheme/simple/.cvsignore b/Examples/mzscheme/simple/.cvsignore new file mode 100644 index 000000000..11550eb76 --- /dev/null +++ b/Examples/mzscheme/simple/.cvsignore @@ -0,0 +1 @@ +example_wrap.c diff --git a/Examples/mzscheme/simple/Makefile b/Examples/mzscheme/simple/Makefile index c8e5242b3..5ac93f8f0 100644 --- a/Examples/mzscheme/simple/Makefile +++ b/Examples/mzscheme/simple/Makefile @@ -8,6 +8,6 @@ all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' mzscheme clean:: - rm -f *_wrap* *.o core *~ *.so + $(MAKE) -f $(TOP)/Makefile mzscheme_clean check: all diff --git a/Examples/mzscheme/std_vector/.cvsignore b/Examples/mzscheme/std_vector/.cvsignore new file mode 100644 index 000000000..bd7dd8a57 --- /dev/null +++ b/Examples/mzscheme/std_vector/.cvsignore @@ -0,0 +1 @@ +example_wrap.cxx diff --git a/Examples/mzscheme/std_vector/Makefile b/Examples/mzscheme/std_vector/Makefile new file mode 100644 index 000000000..587173b44 --- /dev/null +++ b/Examples/mzscheme/std_vector/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = + +GPP = `which g++` +MZC = test -n "/usr/bin/mzc" && /usr/bin/mzc + +all:: + $(SWIG) -mzscheme -c++ $(SWIGOPT) $(INTERFACE) + $(MZC) --compiler $(GPP) ++ccf "-I." --cc example_wrap.cxx + $(MZC) --linker $(GPP) --ld $(TARGET).so example_wrap.o + +clean: + $(MAKE) -f $(TOP)/Makefile mzscheme_clean + +check: all diff --git a/Examples/mzscheme/std_vector/example.h b/Examples/mzscheme/std_vector/example.h new file mode 100644 index 000000000..4f0dac70d --- /dev/null +++ b/Examples/mzscheme/std_vector/example.h @@ -0,0 +1,25 @@ +/* File : example.h */ + +#include +#include +#include +#include + +double average(std::vector v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector half(const std::vector& v) { + std::vector w(v); + for (unsigned int i=0; i& v) { + // would you believe this is the same as the above? + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides(),2.0)); +} + + diff --git a/Examples/mzscheme/std_vector/example.i b/Examples/mzscheme/std_vector/example.i new file mode 100644 index 000000000..aa58b66e0 --- /dev/null +++ b/Examples/mzscheme/std_vector/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include stl.i +/* instantiate the required template specializations */ +namespace std { + %template(IntVector) vector; + %template(DoubleVector) vector; +} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/mzscheme/std_vector/example.scm b/Examples/mzscheme/std_vector/example.scm new file mode 100644 index 000000000..0e4ac3f97 --- /dev/null +++ b/Examples/mzscheme/std_vector/example.scm @@ -0,0 +1,54 @@ +;; run with mzscheme -r example.scm + +(load-extension "example.so") + +; repeatedly invoke a procedure with v and an index as arguments +(define (with-vector v proc size-proc) + (let ((size (size-proc v))) + (define (with-vector-item v i) + (if (< i size) + (begin + (proc v i) + (with-vector-item v (+ i 1))))) + (with-vector-item v 0))) + +(define (with-intvector v proc) + (with-vector v proc intvector-length)) +(define (with-doublevector v proc) + (with-vector v proc doublevector-length)) + +(define (print-doublevector v) + (with-doublevector v (lambda (v i) (display (doublevector-ref v i)) + (display " "))) + (newline)) + + +; Call average with a Scheme list... + +(display (average '(1 2 3 4))) +(newline) + +; ... or a wrapped std::vector +(define v (new-intvector 4)) +(with-intvector v (lambda (v i) (intvector-set! v i (+ i 1)))) +(display (average v)) +(newline) +(delete-intvector v) + +; half will return a Scheme vector. +; Call it with a Scheme vector... + +(display (half #(1 1.5 2 2.5 3))) +(newline) + +; ... or a wrapped std::vector +(define v (new-doublevector)) +(map (lambda (i) (doublevector-push! v i)) '(1 2 3 4)) +(display (half v)) +(newline) + +; now halve a wrapped std::vector in place +(halve-in-place v) +(print-doublevector v) +(delete-doublevector v) + diff --git a/Examples/ocaml/check.list b/Examples/ocaml/check.list new file mode 100644 index 000000000..d38998cab --- /dev/null +++ b/Examples/ocaml/check.list @@ -0,0 +1,2 @@ +# see top-level Makefile.in +simple diff --git a/Examples/ocaml/simple/Makefile b/Examples/ocaml/simple/Makefile new file mode 100644 index 000000000..bac7edf47 --- /dev/null +++ b/Examples/ocaml/simple/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +MLFILE = example.ml +PROGFILE = example_prog.ml +OBJS = example.o + +all:: static + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MLFILE='$(MLFILE)' \ + PROGFILE='$(PROGFILE)' OBJS='$(OBJS)' \ + ocaml_static + +clean:: + $(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean + +check: all diff --git a/Examples/ocaml/simple/example.c b/Examples/ocaml/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/ocaml/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/ocaml/simple/example.dsp b/Examples/ocaml/simple/example.dsp new file mode 100644 index 000000000..e905647a5 --- /dev/null +++ b/Examples/ocaml/simple/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PYTHON_LIB) /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PYTHON_LIB) /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -python $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -python $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/ocaml/simple/example.i b/Examples/ocaml/simple/example.i new file mode 100644 index 000000000..6702abb1e --- /dev/null +++ b/Examples/ocaml/simple/example.i @@ -0,0 +1,5 @@ +/* File : example.i */ +%module example + +extern int gcd(int x, int y); +extern double Foo; diff --git a/Examples/ocaml/simple/example_prog.ml b/Examples/ocaml/simple/example_prog.ml new file mode 100644 index 000000000..5dafdc219 --- /dev/null +++ b/Examples/ocaml/simple/example_prog.ml @@ -0,0 +1,37 @@ +(* example_prog.ml *) + +open Example + +(* Call our gcd() function *) + +exception NoReturn + +let single_int x = + match x with C_int a -> a | _ -> raise NoReturn +let get_float x = + match x with C_float f -> f | C_double f -> f | _ -> raise NoReturn + +let x = 42 +let y = 105 +let g = single_int (_gcd (C_list [ C_int x ; C_int y ])) +let _ = Printf.printf "The gcd of %d and %d is %d\n" x y g + +(* Manipulate the Foo global variable *) + +(* Output its current value *) +let _ = Printf.printf "Foo = %f\n" (get_float (_Foo C_void)) + +(* Change its value *) +let _ = _Foo (C_float 3.1415926) + +(* See if the change took effect *) +let _ = Printf.printf "Foo = %f\n" (get_float (_Foo C_void)) + + + + + + + + + diff --git a/Examples/ocaml/simple/index.html b/Examples/ocaml/simple/index.html new file mode 100644 index 000000000..9638708cc --- /dev/null +++ b/Examples/ocaml/simple/index.html @@ -0,0 +1,99 @@ + + +SWIG:Examples:python:simple + + + + + +SWIG/Examples/python/simple/ +
    + +

    Simple Python Example

    + +$Header$
    + +

    +This example illustrates how you can hook Python to a very simple C program containing +a function and a global variable. + +

    The C Code

    + +Suppose you have the following C code: + +
    +
    +/* File : example.c */
    +
    +/* A global variable */
    +double Foo = 3.0;
    +
    +/* Compute the greatest common divisor of positive integers */
    +int gcd(int x, int y) {
    +  int g;
    +  g = y;
    +  while (x > 0) {
    +    g = x;
    +    x = y % x;
    +    y = g;
    +  }
    +  return g;
    +}
    +
    +
    + +

    The SWIG interface

    + +Here is a simple SWIG interface file: + +
    +
    +/* File: example.i */
    +%module example
    +
    +extern int gcd(int x, int y);
    +extern double Foo;
    +
    +
    + +

    Compilation

    + +
      +
    1. swig -python example.i +

      +

    2. Compile example_wrap.c and example.c +to create the extension examplemodule.so. +
    + +

    Using the extension

    + +Click here to see a script that calls our C functions from Python. + +

    Key points

    + +
      +
    • Use the import statement to load your extension module from Python. For example: +
      +
      +import example
      +
      +
      + +
    • C functions work just like Python functions. For example: +
      +
      +g = example.gcd(42,105)
      +
      +
      + +
    • C global variables are accessed through a special variable called 'cvar'. For example: +
      +
      +a = example.cvar.Foo
      +
      +
      +
    + +
    + + diff --git a/Examples/perl5/check.list b/Examples/perl5/check.list new file mode 100644 index 000000000..abaa4e017 --- /dev/null +++ b/Examples/perl5/check.list @@ -0,0 +1,13 @@ +# see top-level Makefile.in +class +constants +constants2 +funcptr +import +multimap +pointer +reference +shadow +simple +value +variables diff --git a/Examples/perl5/class/.cvsignore b/Examples/perl5/class/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/class/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/class/Makefile b/Examples/perl5/class/Makefile index e0483a897..8b8ae7f72 100644 --- a/Examples/perl5/class/Makefile +++ b/Examples/perl5/class/Makefile @@ -14,6 +14,6 @@ static:: TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so myperl *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/class/example.cxx b/Examples/perl5/class/example.cxx index 21582f4d1..1e8e203dd 100644 --- a/Examples/perl5/class/example.cxx +++ b/Examples/perl5/class/example.cxx @@ -1,7 +1,7 @@ /* File : example.c */ #include "example.h" -#include +#define M_PI 3.14159265358979323846 /* Move the shape to a new location */ void Shape::move(double dx, double dy) { @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area() { +double Circle::area(void) { return M_PI*radius*radius; } -double Circle::perimeter() { +double Circle::perimeter(void) { return 2*M_PI*radius; } -double Square::area() { +double Square::area(void) { return width*width; } -double Square::perimeter() { +double Square::perimeter(void) { return 4*width; } diff --git a/Examples/perl5/class/example.dsp b/Examples/perl5/class/example.dsp new file mode 100644 index 000000000..2d7734aca --- /dev/null +++ b/Examples/perl5/class/example.dsp @@ -0,0 +1,150 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PERL5_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PERL5_INCLUDE)/perl.lib /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PERL5_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PERL5_INCLUDE)/perl.lib /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.cxx +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\example.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PERL5_INCLUDE: %PERL5_INCLUDE% + echo on + ..\..\..\swig -c++ -perl5 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PERL5_INCLUDE: %PERL5_INCLUDE% + echo on + ..\..\..\swig -c++ -perl5 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/perl5/class/example.h b/Examples/perl5/class/example.h index 849071dd3..46d901361 100644 --- a/Examples/perl5/class/example.h +++ b/Examples/perl5/class/example.h @@ -10,8 +10,8 @@ public: }; double x, y; void move(double dx, double dy); - virtual double area() = 0; - virtual double perimeter() = 0; + virtual double area(void) = 0; + virtual double perimeter(void) = 0; static int nshapes; }; @@ -20,8 +20,8 @@ private: double radius; public: Circle(double r) : radius(r) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; class Square : public Shape { @@ -29,8 +29,8 @@ private: double width; public: Square(double w) : width(w) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; diff --git a/Examples/perl5/class/example.pl b/Examples/perl5/class/example.pl index c14160e92..02e7a889b 100644 --- a/Examples/perl5/class/example.pl +++ b/Examples/perl5/class/example.pl @@ -20,12 +20,12 @@ print "\nA total of $example::Shape_nshapes shapes were created\n"; # ----- Member data access ----- -# Set the location of the object +# Set the location of the object. +# Note: methods in the base class Shape are used since +# x and y are defined there. example::Shape_x_set($c, 20); example::Shape_y_set($c, 30); - -# Now use the same functions in the base class example::Shape_x_set($s,-10); example::Shape_y_set($s,5); diff --git a/Examples/perl5/class/index.html b/Examples/perl5/class/index.html index 05627e8fb..8ca90bf55 100644 --- a/Examples/perl5/class/index.html +++ b/Examples/perl5/class/index.html @@ -109,14 +109,13 @@ For example:
    -example::Circle_x_set($c,15);    # Set member data
    +example::Shape_x_set($c,15);    # Set member data
     $x = example::Shape_x_get($c);   # Get member data
     
    -Note: when accessing member data, the name of the base class or the derived class can be -used in the function name as shown above. Of course, it would probably be more -proper to just use the base class version such as Shape_x_get() +Note: when accessing member data, the name of the class in which +the data member is defined is used. For example Shape_x_get().

  • To invoke a member function, you simply do this @@ -204,28 +203,6 @@ to write a helper function. For example:

  • Namespaces. Not supported at all. Won't be supported until SWIG2.0 (if at all). -

    -

  • Templates. Not supported at all. SWIG throws out anything that looks like a template. -You can work around the problem by aliasing a template class behind a typedef however. -For example: - -
    -
    -%{
    -typedef vector IntVector;
    -%}
    -
    -class IntVector {
    -public:
    -    ... methods ...
    -};
    -
    -
    - -

    -

  • There is no guarantee that an extremely complex C++ application will be able to compile -as a Python extension. Sorry. -
    diff --git a/Examples/perl5/constants/.cvsignore b/Examples/perl5/constants/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/constants/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/constants/Makefile b/Examples/perl5/constants/Makefile index 428f9f5cd..c1e2bf29e 100644 --- a/Examples/perl5/constants/Makefile +++ b/Examples/perl5/constants/Makefile @@ -13,6 +13,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static clean:: - rm -f *_wrap* *.o core *~ *.so *.pm myperl + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/constants/example.i b/Examples/perl5/constants/example.i index 29a1a7f11..4f7b1a4d7 100644 --- a/Examples/perl5/constants/example.i +++ b/Examples/perl5/constants/example.i @@ -19,8 +19,9 @@ /* Neither should this (BAR isn't defined) */ #define FOO (ICONST + BAR) -/* The following statements also produce constants */ -const int iconst = 37; -const double fconst = 3.14; +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/perl5/constants2/.cvsignore b/Examples/perl5/constants2/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/constants2/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/constants2/Makefile b/Examples/perl5/constants2/Makefile new file mode 100644 index 000000000..50b3fe046 --- /dev/null +++ b/Examples/perl5/constants2/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = -const +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' perl5 + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static + +clean:: + $(MAKE) -f $(TOP)/Makefile perl5_clean + +check: all diff --git a/Examples/perl5/constants2/example.i b/Examples/perl5/constants2/example.i new file mode 100644 index 000000000..4f7b1a4d7 --- /dev/null +++ b/Examples/perl5/constants2/example.i @@ -0,0 +1,27 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; + + diff --git a/Examples/perl5/constants2/example.pl b/Examples/perl5/constants2/example.pl new file mode 100644 index 000000000..65682e68b --- /dev/null +++ b/Examples/perl5/constants2/example.pl @@ -0,0 +1,16 @@ +# file: example.pl + +use example; + +print "ICONST = ", example::ICONST, " (should be 42)\n"; +print "FCONST = ", example::FCONST, " (should be 2.1828)\n"; +print "CCONST = ", example::CCONST, " (should be 'x')\n"; +print "CCONST2 = ", example::CCONST2," (this should be on a new line)\n"; +print "SCONST = ", example::SCONST, " (should be 'Hello World')\n"; +print "SCONST2 = ", example::SCONST2, " (should be '\"Hello World\"')\n"; +print "EXPR = ", example::EXPR, " (should be 48.5484)\n"; +print "iconst = ", example::iconst, " (should be 37)\n"; +print "fconst = ", example::fconst, " (should be 3.14)\n"; + + + diff --git a/Examples/perl5/funcptr/.cvsignore b/Examples/perl5/funcptr/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/funcptr/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/funcptr/Makefile b/Examples/perl5/funcptr/Makefile index e5944f9af..ef644a35f 100644 --- a/Examples/perl5/funcptr/Makefile +++ b/Examples/perl5/funcptr/Makefile @@ -13,6 +13,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static clean:: - rm -f *_wrap* *.o core *~ *.so *.pm myperl + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/funcptr/example.c b/Examples/perl5/funcptr/example.c index 99583b72e..5c4a3dabf 100644 --- a/Examples/perl5/funcptr/example.c +++ b/Examples/perl5/funcptr/example.c @@ -15,3 +15,5 @@ int sub(int a, int b) { int mul(int a, int b) { return a*b; } + +int (*funcvar)(int,int) = add; diff --git a/Examples/perl5/funcptr/example.i b/Examples/perl5/funcptr/example.i index 73cc6eb8c..8b3bef678 100644 --- a/Examples/perl5/funcptr/example.i +++ b/Examples/perl5/funcptr/example.i @@ -8,8 +8,9 @@ extern int do_op(int a, int b, int (*op)(int, int)); /* Now install a bunch of "ops" as constants */ -%constant(int (*)(int,int)) ADD = add; -%constant(int (*)(int,int)) SUB = sub; -%constant(int (*)(int,int)) MUL = mul; +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; +extern int (*funcvar)(int,int); diff --git a/Examples/perl5/import/.cvsignore b/Examples/perl5/import/.cvsignore new file mode 100644 index 000000000..96e7844ab --- /dev/null +++ b/Examples/perl5/import/.cvsignore @@ -0,0 +1,14 @@ +baseclass.pm +example.pm +foo.pm +bar.pm +spam.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/import/Makefile b/Examples/perl5/import/Makefile new file mode 100644 index 000000000..fb66eb38e --- /dev/null +++ b/Examples/perl5/import/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SWIGOPT = -c -shadow +#If your system requires linking with the runtime libraries then set the directory location here +RUNTIMEDIR = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='baseclass' INTERFACE='base.i' perl5_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' perl5_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' perl5_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' perl5_multi_cpp + + +clean:: + $(MAKE) -f $(TOP)/Makefile perl5_clean + +check: all diff --git a/Examples/perl5/import/README b/Examples/perl5/import/README new file mode 100644 index 000000000..64faee271 --- /dev/null +++ b/Examples/perl5/import/README @@ -0,0 +1,28 @@ +This example tests the SWIG run-time libraries and use of the +%import directive to work with multiple modules. + +Use 'perl runme.pl' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module used %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is working correctly, all of the modules will load +correctly and type checking will work correctly. The +example requires the use of the SWIG run-time libraries +which must be built and properly installed. + + + + diff --git a/Examples/perl5/import/bar.h b/Examples/perl5/import/bar.h new file mode 100644 index 000000000..fa4185f1f --- /dev/null +++ b/Examples/perl5/import/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual void A() { + printf("I'm Bar::A\n"); + } + void B() { + printf("I'm Bar::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast(b); + } + +}; + + diff --git a/Examples/perl5/import/bar.i b/Examples/perl5/import/bar.i new file mode 100644 index 000000000..5816cbe17 --- /dev/null +++ b/Examples/perl5/import/bar.i @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + diff --git a/Examples/perl5/import/base.h b/Examples/perl5/import/base.h new file mode 100644 index 000000000..be3cdef7d --- /dev/null +++ b/Examples/perl5/import/base.h @@ -0,0 +1,18 @@ +#include + +class Base { + public: + Base() { }; + ~Base() { }; + virtual void A() { + printf("I'm Base::A\n"); + } + void B() { + printf("I'm Base::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } +}; + + diff --git a/Examples/perl5/import/base.i b/Examples/perl5/import/base.i new file mode 100644 index 000000000..dc99383a7 --- /dev/null +++ b/Examples/perl5/import/base.i @@ -0,0 +1,6 @@ +%module baseclass +%{ +#include "base.h" +%} + +%include base.h diff --git a/Examples/perl5/import/foo.h b/Examples/perl5/import/foo.h new file mode 100644 index 000000000..dd5184031 --- /dev/null +++ b/Examples/perl5/import/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual void A() { + printf("I'm Foo::A\n"); + } + void B() { + printf("I'm Foo::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/perl5/import/foo.i b/Examples/perl5/import/foo.i new file mode 100644 index 000000000..27feb2e6a --- /dev/null +++ b/Examples/perl5/import/foo.i @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + diff --git a/Examples/perl5/import/runme.pl b/Examples/perl5/import/runme.pl new file mode 100644 index 000000000..ea71f3dc1 --- /dev/null +++ b/Examples/perl5/import/runme.pl @@ -0,0 +1,116 @@ +# file: runme.pl +# Test various properties of classes defined in separate modules + +print "Testing the %import directive\n"; +use baseclass; +use foo; +use bar; +use spam; + +# Create some objects + +print "Creating some objects\n"; + +$a = new baseclass::Base(); +$b = new foo::Foo(); +$c = new bar::Bar(); +$d = new spam::Spam(); + +# Try calling some methods +print "Testing some methods\n"; +print "Should see 'Base::A' ---> "; +$a->A(); +print "Should see 'Base::B' ---> "; +$a->B(); + +print "Should see 'Foo::A' ---> "; +$b->A(); +print "Should see 'Foo::B' ---> "; +$b->B(); + +print "Should see 'Bar::A' ---> "; +$c->A(); +print "Should see 'Bar::B' ---> "; +$c->B(); + +print "Should see 'Spam::A' ---> "; +$d->A(); +print "Should see 'Spam::B' ---> "; +$d->B(); + +# Try some casts + +print "\nTesting some casts\n"; + +$x = $a->toBase(); +print "Should see 'Base::A' ---> "; +$x->A(); +print "Should see 'Base::B' ---> "; +$x->B(); + +$x = $b->toBase(); +print "Should see 'Foo::A' ---> "; +$x->A(); + +print "Should see 'Base::B' ---> "; +$x->B(); + +$x = $c->toBase(); +print "Should see 'Bar::A' ---> "; +$x->A(); + +print "Should see 'Base::B' ---> "; +$x->B(); + +$x = $d->toBase(); +print "Should see 'Spam::A' ---> "; +$x->A(); + +print "Should see 'Base::B' ---> "; +$x->B(); + +$x = $d->toBar(); +print "Should see 'Bar::B' ---> "; +$x->B(); + +print "\nTesting some dynamic casts\n"; +$x = $d->toBase(); + +print " Spam -> Base -> Foo : "; +$y = foo::Foo_fromBase($x); +if ($y) { + print "bad swig\n"; +} else { + print "good swig\n"; +} + +print " Spam -> Base -> Bar : "; +$y = bar::Bar_fromBase($x); +if ($y) { + print "good swig\n"; +} else { + print "bad swig\n"; +} + +print " Spam -> Base -> Spam : "; +$y = spam::Spam_fromBase($x); +if ($y) { + print "good swig\n"; +} else { + print "bad swig\n"; +} + +print " Foo -> Spam : "; +#print $b; +$y = spam::Spam_fromBase($b); +print $y; +if ($y) { + print "bad swig\n"; +} else { + print "good swig\n"; +} + + + + + diff --git a/Examples/perl5/import/spam.h b/Examples/perl5/import/spam.h new file mode 100644 index 000000000..b4e7a2646 --- /dev/null +++ b/Examples/perl5/import/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual void A() { + printf("I'm Spam::A\n"); + } + void B() { + printf("I'm Spam::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + virtual Bar *toBar() { + return static_cast(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/perl5/import/spam.i b/Examples/perl5/import/spam.i new file mode 100644 index 000000000..d3d9121db --- /dev/null +++ b/Examples/perl5/import/spam.i @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + diff --git a/Examples/perl5/index.html b/Examples/perl5/index.html index 9f6556cd6..119f7b241 100644 --- a/Examples/perl5/index.html +++ b/Examples/perl5/index.html @@ -66,7 +66,8 @@ The examples have been extensively tested on the following platforms:
  • Solaris -

    +Please see the Windows page in the main manual for information on using the examples on Windows.

    + The most recent version of Perl used for testing is as follows:

    diff --git a/Examples/perl5/multimap/.cvsignore b/Examples/perl5/multimap/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/multimap/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/multimap/Makefile b/Examples/perl5/multimap/Makefile new file mode 100644 index 000000000..ef644a35f --- /dev/null +++ b/Examples/perl5/multimap/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' perl5 + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static + +clean:: + $(MAKE) -f $(TOP)/Makefile perl5_clean + +check: all diff --git a/Examples/perl5/multimap/example.c b/Examples/perl5/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/perl5/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/perl5/multimap/example.dsp b/Examples/perl5/multimap/example.dsp new file mode 100644 index 000000000..d3a197f0c --- /dev/null +++ b/Examples/perl5/multimap/example.dsp @@ -0,0 +1,146 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PERL5_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PERL5_INCLUDE)/perl.lib /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PERL5_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PERL5_INCLUDE)/perl.lib /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PERL5_INCLUDE: %PERL5_INCLUDE% + echo on + ..\..\..\swig -perl5 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PERL5_INCLUDE: %PERL5_INCLUDE% + echo on + ..\..\..\swig -perl5 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/perl5/multimap/example.i b/Examples/perl5/multimap/example.i new file mode 100644 index 000000000..c162c0019 --- /dev/null +++ b/Examples/perl5/multimap/example.i @@ -0,0 +1,81 @@ +/* File : example.i */ +%module example +%include exception.i +%include typemaps.i + +extern int gcd(int x, int y); + +%typemap(perl5,in) (int argc, char *argv[]) { + AV *tempav; + SV **tv; + I32 len; + int i; + if (!SvROK($input)) { + SWIG_exception(SWIG_ValueError,"$input is not an array."); + } + if (SvTYPE(SvRV($input)) != SVt_PVAV) { + SWIG_exception(SWIG_ValueError,"$input is not an array."); + } + tempav = (AV*)SvRV($input); + len = av_len(tempav); + $1 = (int) len+1; + $2 = (char **) malloc($1*sizeof(char *)); + for (i = 0; i < $1; i++) { + tv = av_fetch(tempav, i, 0); + $2[i] = (char *) SvPV(*tv,PL_na); + } + $2[i] = 0; +} + +%typemap(perl5,freearg) (int argc, char *argv[]) { + free($2); +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(perl5,in) (char *bytes, int len) { + unsigned int temp; + $1 = (char *) SvPV($input, temp); + $2 = (int) temp; +} + +extern int count(char *bytes, int len, char c); + + +/* This example shows how to wrap a function that mutates a string */ + +%typemap(perl5,in) (char *str, int len) { + unsigned int templen; + char *temp; + temp = (char *) SvPV($input,templen); + $2 = (int) templen; + $1 = (char *) malloc($2+1); + memmove($1,temp,$2); +} + +/* Return the mutated string as a new object. */ + +%typemap(perl5,argout) (char *str, int len) { + if (argvi >= items) { + EXTEND(sp,1); + } + $result = sv_newmortal(); + sv_setpvn((SV*)ST(argvi++),$1,$2); + free($1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + } +} + +extern void circle(double cx, double cy); + + diff --git a/Examples/perl5/multimap/example.pl b/Examples/perl5/multimap/example.pl new file mode 100755 index 000000000..9c86633f9 --- /dev/null +++ b/Examples/perl5/multimap/example.pl @@ -0,0 +1,28 @@ +# file: example.pl + +use example; + +# Call our gcd() function + +$x = 42; +$y = 105; +$g = example::gcd($x,$y); +print "The gcd of $x and $y is $g\n"; + +# Call the gcdmain() function +@a = ("gcdmain","42","105"); +example::gcdmain(\@a); + +# Call the count function +print example::count("Hello World", "l"),"\n"; + +# Call the capitize function + +print example::capitalize("hello world"),"\n"; + + + + + + + diff --git a/Examples/perl5/pointer/.cvsignore b/Examples/perl5/pointer/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/pointer/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/pointer/Makefile b/Examples/perl5/pointer/Makefile index e5944f9af..ef644a35f 100644 --- a/Examples/perl5/pointer/Makefile +++ b/Examples/perl5/pointer/Makefile @@ -13,6 +13,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static clean:: - rm -f *_wrap* *.o core *~ *.so *.pm myperl + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/pointer/example.i b/Examples/perl5/pointer/example.i index 2ed2b5bbf..4483b0f77 100644 --- a/Examples/perl5/pointer/example.i +++ b/Examples/perl5/pointer/example.i @@ -6,7 +6,8 @@ /* First we'll use the pointer library */ extern void add(int *x, int *y, int *result); -%include pointer.i +%include cpointer.i +%pointer_functions(int, intp); /* Next we'll use some typemaps */ diff --git a/Examples/perl5/pointer/example.pl b/Examples/perl5/pointer/example.pl index dc18144cf..9d9711dd0 100644 --- a/Examples/perl5/pointer/example.pl +++ b/Examples/perl5/pointer/example.pl @@ -4,9 +4,11 @@ use example; # First create some objects using the pointer library. print "Testing the pointer library\n"; -$a = example::ptrcreate("int",37); -$b = example::ptrcreate("int",42); -$c = example::ptrcreate("int"); +$a = example::new_intp(); +$b = example::new_intp(); +$c = example::new_intp(); +example::intp_assign($a,37); +example::intp_assign($b,42); print " a = $a\n"; print " b = $b\n"; @@ -16,13 +18,13 @@ print " c = $c\n"; example::add($a,$b,$c); # Now get the result -$r = example::ptrvalue($c); +$r = example::intp_value($c); print " 37 + 42 = $r\n"; # Clean up the pointers -example::ptrfree($a); -example::ptrfree($b); -example::ptrfree($c); +example::delete_intp($a); +example::delete_intp($b); +example::delete_intp($c); # Now try the typemap library # This should be much easier. Now how it is no longer diff --git a/Examples/perl5/reference/.cvsignore b/Examples/perl5/reference/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/reference/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/reference/Makefile b/Examples/perl5/reference/Makefile index e0483a897..8b8ae7f72 100644 --- a/Examples/perl5/reference/Makefile +++ b/Examples/perl5/reference/Makefile @@ -14,6 +14,6 @@ static:: TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so myperl *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/reference/example.i b/Examples/perl5/reference/example.i index 8538326f6..e71f297bf 100644 --- a/Examples/perl5/reference/example.i +++ b/Examples/perl5/reference/example.i @@ -31,7 +31,7 @@ public: int size(); /* This wrapper provides an alternative to the [] operator */ - %addmethods { + %extend { Vector &get(int index) { return (*self)[index]; } diff --git a/Examples/perl5/shadow/.cvsignore b/Examples/perl5/shadow/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/shadow/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/shadow/Makefile b/Examples/perl5/shadow/Makefile index 36f9d099c..99b6c40c1 100644 --- a/Examples/perl5/shadow/Makefile +++ b/Examples/perl5/shadow/Makefile @@ -15,6 +15,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so myperl *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/shadow/example.cxx b/Examples/perl5/shadow/example.cxx index 21582f4d1..d7f5046fe 100644 --- a/Examples/perl5/shadow/example.cxx +++ b/Examples/perl5/shadow/example.cxx @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area() { +double Circle::area(void) { return M_PI*radius*radius; } -double Circle::perimeter() { +double Circle::perimeter(void) { return 2*M_PI*radius; } -double Square::area() { +double Square::area(void) { return width*width; } -double Square::perimeter() { +double Square::perimeter(void) { return 4*width; } diff --git a/Examples/perl5/shadow/example.h b/Examples/perl5/shadow/example.h index 849071dd3..1f6f8b304 100644 --- a/Examples/perl5/shadow/example.h +++ b/Examples/perl5/shadow/example.h @@ -10,8 +10,8 @@ public: }; double x, y; void move(double dx, double dy); - virtual double area() = 0; - virtual double perimeter() = 0; + virtual double area(void) = 0; + virtual double perimeter(void) = 0; static int nshapes; }; @@ -20,8 +20,9 @@ private: double radius; public: Circle(double r) : radius(r) { }; - virtual double area(); - virtual double perimeter(); + ~Circle() { }; + virtual double area(void); + virtual double perimeter(void); }; class Square : public Shape { @@ -29,8 +30,9 @@ private: double width; public: Square(double w) : width(w) { }; - virtual double area(); - virtual double perimeter(); + ~Square() { } + virtual double area(void); + virtual double perimeter(void); }; diff --git a/Examples/perl5/shadow/example.pl b/Examples/perl5/shadow/example.pl index be26415f2..7cc334e6a 100644 --- a/Examples/perl5/shadow/example.pl +++ b/Examples/perl5/shadow/example.pl @@ -16,18 +16,18 @@ print " Created square $s\n"; # ----- Access a static member ----- -print "\nA total of $example::Shape_nshapes shapes were created\n"; +print "\nA total of $example::Shape::nshapes shapes were created\n"; # ----- Member data access ----- -# Set the location of the object +# Set the location of the object. +# Note: methods in the base class Shape are used since +# x and y are defined there. -$c->{'x'} = 20; -$c->{'y'} = 30; - -# Now use the same functions in the base class -$s->{'x'} = -10; -$s->{'y'} = 5; +$c->{x} = 20; +$c->{y} = 30; +$s->{x} = -10; +$s->{y} = 5; print "\nHere is their current position:\n"; print " Circle = (",$c->{x},",", $c->{y},")\n"; @@ -41,17 +41,16 @@ foreach $o ($c,$s) { print " area = ", $o->area(), "\n"; print " perimeter = ", $o->perimeter(), "\n"; } -# Notice how the Shape_area() and Shape_perimeter() functions really -# invoke the appropriate virtual method on each object. # ----- Delete everything ----- print "\nGuess I'll clean up now\n"; # Note: this invokes the virtual destructor + $c->DESTROY(); $s->DESTROY(); -print $example::Shape_nshapes," shapes remain\n"; +print $example::Shape::nshapes," shapes remain\n"; print "Goodbye\n"; diff --git a/Examples/perl5/simple/.cvsignore b/Examples/perl5/simple/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/simple/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/simple/Makefile b/Examples/perl5/simple/Makefile index e5944f9af..ef644a35f 100644 --- a/Examples/perl5/simple/Makefile +++ b/Examples/perl5/simple/Makefile @@ -13,6 +13,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static clean:: - rm -f *_wrap* *.o core *~ *.so *.pm myperl + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/simple/example.dsp b/Examples/perl5/simple/example.dsp new file mode 100644 index 000000000..d3a197f0c --- /dev/null +++ b/Examples/perl5/simple/example.dsp @@ -0,0 +1,146 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PERL5_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PERL5_INCLUDE)/perl.lib /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PERL5_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PERL5_INCLUDE)/perl.lib /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PERL5_INCLUDE: %PERL5_INCLUDE% + echo on + ..\..\..\swig -perl5 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PERL5_INCLUDE: %PERL5_INCLUDE% + echo on + ..\..\..\swig -perl5 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/perl5/value/.cvsignore b/Examples/perl5/value/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/value/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/value/Makefile b/Examples/perl5/value/Makefile index e5944f9af..ef644a35f 100644 --- a/Examples/perl5/value/Makefile +++ b/Examples/perl5/value/Makefile @@ -13,6 +13,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static clean:: - rm -f *_wrap* *.o core *~ *.so *.pm myperl + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/variables/.cvsignore b/Examples/perl5/variables/.cvsignore new file mode 100644 index 000000000..618145e24 --- /dev/null +++ b/Examples/perl5/variables/.cvsignore @@ -0,0 +1,10 @@ +example.pm +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/perl5/variables/Makefile b/Examples/perl5/variables/Makefile index e5944f9af..ef644a35f 100644 --- a/Examples/perl5/variables/Makefile +++ b/Examples/perl5/variables/Makefile @@ -13,6 +13,6 @@ static:: SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static clean:: - rm -f *_wrap* *.o core *~ *.so *.pm myperl + $(MAKE) -f $(TOP)/Makefile perl5_clean check: all diff --git a/Examples/perl5/variables/example.i b/Examples/perl5/variables/example.i index 35eafc2c0..91bd0679d 100644 --- a/Examples/perl5/variables/example.i +++ b/Examples/perl5/variables/example.i @@ -27,10 +27,10 @@ extern Point pt; /* Some read-only variables */ -%readonly { +%immutable; extern int status; extern char path[256]; -} +%mutable; /* Some helper functions to make it easier to test */ extern void print_vars(); diff --git a/Examples/perl5/variables/index.html b/Examples/perl5/variables/index.html index a278445fe..a6d015dd2 100644 --- a/Examples/perl5/variables/index.html +++ b/Examples/perl5/variables/index.html @@ -27,21 +27,21 @@ Click here to see a script that updates and prints some

    Creating read-only variables

    -The %readonly and %readwrite directives can be used to +The %immutable and %mutable directives can be used to specify a collection of read-only variables. For example:
    -%readonly
    +%immutable;
     int    status;
     double blah;
     ...
    -%readwrite
    +%mutable;
     
    -The %readonly directive remains in effect until it is explicitly disabled -using the %readwrite directive. +The %immutable directive remains in effect until it is explicitly disabled +using the %mutable directive.

    Notes:

    diff --git a/Examples/php4/Makefile.php b/Examples/php4/Makefile.php new file mode 100644 index 000000000..ed9d786e5 --- /dev/null +++ b/Examples/php4/Makefile.php @@ -0,0 +1,30 @@ +CRUD=acinclude.m4 aclocal.m4 config.cache config.h config.h.in config.log \ + config.m4 config.nice config.status config.sub configure configure.in \ + config_vars.mk config.guess CREDITS dynlib.m4 *.so *.lo *.o *.slo \ + install-sh libs.mk libtool ltmain.sh Makefile Makefile.in missing \ + mkinstalldirs php_example.h php_example.la *_wrap.c* example.php \ + build modules .deps .libs conftest conftest.c + +all: check + +check: BUILD.sh + ./BUILD.sh +# SWIG=$(SWIG) ./BUILD.sh + +# This one is fun! How do we know what shouldn't be there? +clean: + rm -fr $(CRUD) + +BUILD.sh: + echo "-------------------------------------------------" + echo `pwd`"/BUILD.sh missing!" + echo "I need BUILD.sh file to show me how to invoke swig" + echo "It usually looks like this:" + echo + echo "swig -php -phpfull -c++ example.i" + echo "# and then the rest is always the same..." + echo "phpize && ./configure && make && make install" + echo + echo + exit 1 + diff --git a/Examples/php4/check.list b/Examples/php4/check.list new file mode 100644 index 000000000..2eef45816 --- /dev/null +++ b/Examples/php4/check.list @@ -0,0 +1,13 @@ +# see top-level Makefile.in +# (see also top-level configure.in kludge) +class +constants +enum +funcptr +pointer +reference +shadow +simple +sync +value +variables diff --git a/Examples/php4/class/BUILD.sh b/Examples/php4/class/BUILD.sh new file mode 100755 index 000000000..99ee15273 --- /dev/null +++ b/Examples/php4/class/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -c++ -noproxy -withcxx example.cxx example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/class/Makefile.old b/Examples/php4/class/Makefile.old new file mode 100644 index 000000000..cc44776e9 --- /dev/null +++ b/Examples/php4/class/Makefile.old @@ -0,0 +1,17 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = php_example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' SWIGOPT='$(SWIGOPT)' \ + php4_cpp + +clean:: + rm -f *_wrap* *.o *~ *.so .~* core *.php php_example.h + +check: all diff --git a/Examples/php4/class/example.cxx b/Examples/php4/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/php4/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/php4/class/example.h b/Examples/php4/class/example.h new file mode 100644 index 000000000..46d901361 --- /dev/null +++ b/Examples/php4/class/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/Examples/php4/class/example.i b/Examples/php4/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/Examples/php4/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/php4/class/runme.php4 b/Examples/php4/class/runme.php4 new file mode 100644 index 000000000..653ced256 --- /dev/null +++ b/Examples/php4/class/runme.php4 @@ -0,0 +1,58 @@ + diff --git a/Examples/php4/constants/BUILD.sh b/Examples/php4/constants/BUILD.sh new file mode 100755 index 000000000..19b79dbc6 --- /dev/null +++ b/Examples/php4/constants/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -c++ -noproxy example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/constants/Makefile.old b/Examples/php4/constants/Makefile.old new file mode 100644 index 000000000..54af9e8d0 --- /dev/null +++ b/Examples/php4/constants/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = php_example +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php *.h + +check: all diff --git a/Examples/php4/constants/example.i b/Examples/php4/constants/example.i new file mode 100644 index 000000000..0098a893a --- /dev/null +++ b/Examples/php4/constants/example.i @@ -0,0 +1,26 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following statements also produce constants */ +%constant int iconst = 37; +%constant double fconst = 3.14; + + diff --git a/Examples/php4/constants/runme.php4 b/Examples/php4/constants/runme.php4 new file mode 100644 index 000000000..cea06485f --- /dev/null +++ b/Examples/php4/constants/runme.php4 @@ -0,0 +1,28 @@ + diff --git a/Examples/php4/enum/BUILD.sh b/Examples/php4/enum/BUILD.sh new file mode 100755 index 000000000..cccb24029 --- /dev/null +++ b/Examples/php4/enum/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -c++ -noproxy -withcxx example.cxx example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/enum/Makefile.old b/Examples/php4/enum/Makefile.old new file mode 100644 index 000000000..cc4574bea --- /dev/null +++ b/Examples/php4/enum/Makefile.old @@ -0,0 +1,17 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = php_example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)'\ + php4_cpp + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php + +check: all diff --git a/Examples/php4/enum/example.cxx b/Examples/php4/enum/example.cxx new file mode 100644 index 000000000..df7bb6328 --- /dev/null +++ b/Examples/php4/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.cxx */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/php4/enum/example.h b/Examples/php4/enum/example.h new file mode 100644 index 000000000..525d62afc --- /dev/null +++ b/Examples/php4/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE, WARP, LUDICROUS }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/php4/enum/example.i b/Examples/php4/enum/example.i new file mode 100644 index 000000000..abf254731 --- /dev/null +++ b/Examples/php4/enum/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/php4/enum/runme.php4 b/Examples/php4/enum/runme.php4 new file mode 100644 index 000000000..55b0bc4c3 --- /dev/null +++ b/Examples/php4/enum/runme.php4 @@ -0,0 +1,32 @@ + diff --git a/Examples/php4/funcptr/BUILD.sh b/Examples/php4/funcptr/BUILD.sh new file mode 100755 index 000000000..881e5881f --- /dev/null +++ b/Examples/php4/funcptr/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -noproxy -withc example.c example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/funcptr/Makefile.old b/Examples/php4/funcptr/Makefile.old new file mode 100644 index 000000000..c48cc7bd5 --- /dev/null +++ b/Examples/php4/funcptr/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = php_example +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php php_example.h + +check: all diff --git a/Examples/php4/funcptr/example.c b/Examples/php4/funcptr/example.c new file mode 100644 index 000000000..99583b72e --- /dev/null +++ b/Examples/php4/funcptr/example.c @@ -0,0 +1,17 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} diff --git a/Examples/php4/funcptr/example.h b/Examples/php4/funcptr/example.h new file mode 100644 index 000000000..58989db79 --- /dev/null +++ b/Examples/php4/funcptr/example.h @@ -0,0 +1,7 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + diff --git a/Examples/php4/funcptr/example.i b/Examples/php4/funcptr/example.i new file mode 100644 index 000000000..39390da27 --- /dev/null +++ b/Examples/php4/funcptr/example.i @@ -0,0 +1,15 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; + + diff --git a/Examples/php4/funcptr/runme.php4 b/Examples/php4/funcptr/runme.php4 new file mode 100644 index 000000000..712d4147c --- /dev/null +++ b/Examples/php4/funcptr/runme.php4 @@ -0,0 +1,24 @@ + + diff --git a/Examples/php4/pointer/BUILD.sh b/Examples/php4/pointer/BUILD.sh new file mode 100755 index 000000000..881e5881f --- /dev/null +++ b/Examples/php4/pointer/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -noproxy -withc example.c example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/pointer/Makefile.old b/Examples/php4/pointer/Makefile.old new file mode 100644 index 000000000..c48cc7bd5 --- /dev/null +++ b/Examples/php4/pointer/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = php_example +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php php_example.h + +check: all diff --git a/Examples/php4/pointer/example.c b/Examples/php4/pointer/example.c new file mode 100644 index 000000000..3326dec3e --- /dev/null +++ b/Examples/php4/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(double *x, double *y, double *result) { + *result = *x + *y; +} + +void sub(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/php4/pointer/example.i b/Examples/php4/pointer/example.i new file mode 100644 index 000000000..52e6df190 --- /dev/null +++ b/Examples/php4/pointer/example.i @@ -0,0 +1,26 @@ +/* File : example.i */ +%module example + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); + +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void sub(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +//%apply int *OUTPUT { int *r }; +//extern int divide(int n, int d, int *r); + + + + + diff --git a/Examples/php4/pointer/runme.php4 b/Examples/php4/pointer/runme.php4 new file mode 100644 index 000000000..48f0ad631 --- /dev/null +++ b/Examples/php4/pointer/runme.php4 @@ -0,0 +1,45 @@ + diff --git a/Examples/php4/reference/BUILD.sh b/Examples/php4/reference/BUILD.sh new file mode 100755 index 000000000..cccb24029 --- /dev/null +++ b/Examples/php4/reference/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -c++ -noproxy -withcxx example.cxx example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/reference/Makefile.old b/Examples/php4/reference/Makefile.old new file mode 100644 index 000000000..7465de804 --- /dev/null +++ b/Examples/php4/reference/Makefile.old @@ -0,0 +1,17 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = php_example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ + php4_cpp + +clean:: + rm -f *_wrap* *.o *~ *.so .~* core php_example.h *.php + +check: all diff --git a/Examples/php4/reference/example.cxx b/Examples/php4/reference/example.cxx new file mode 100644 index 000000000..a37660666 --- /dev/null +++ b/Examples/php4/reference/example.cxx @@ -0,0 +1,44 @@ +/* File : example.cxx */ + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %x (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +printf("Vectorarray new: self=%p\n",this); +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { +printf("Vectorarray: read[%d] self=%p\n",index,this); + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { +printf("Vectorarray: size %d self=%p\n",maxsize,this); + return maxsize; +} + diff --git a/Examples/php4/reference/example.h b/Examples/php4/reference/example.h new file mode 100644 index 000000000..4915adb1b --- /dev/null +++ b/Examples/php4/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/php4/reference/example.i b/Examples/php4/reference/example.i new file mode 100644 index 000000000..73e8c62ec --- /dev/null +++ b/Examples/php4/reference/example.i @@ -0,0 +1,44 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { +printf("%p %d\n",self,index); + return (*self)[index]; + } + void set(int index, Vector &a) { + (*self)[index] = a; + } + } +}; + diff --git a/Examples/php4/reference/runme.php4 b/Examples/php4/reference/runme.php4 new file mode 100644 index 000000000..ecf9ce507 --- /dev/null +++ b/Examples/php4/reference/runme.php4 @@ -0,0 +1,78 @@ + diff --git a/Examples/php4/shadow/BUILD.sh b/Examples/php4/shadow/BUILD.sh new file mode 100755 index 000000000..99b520879 --- /dev/null +++ b/Examples/php4/shadow/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -c++ -withcxx example.cxx example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/shadow/Makefile.old b/Examples/php4/shadow/Makefile.old new file mode 100644 index 000000000..4878e8abe --- /dev/null +++ b/Examples/php4/shadow/Makefile.old @@ -0,0 +1,16 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = php_example +INTERFACE = example.i +LIBS = -lm +#SWIGOPT = -proxy + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4_cpp + +clean:: + rm -f *_wrap* *.o *~ *.so .~* core *.php php_example.h + +check: all diff --git a/Examples/php4/shadow/example.cxx b/Examples/php4/shadow/example.cxx new file mode 100644 index 000000000..d7f5046fe --- /dev/null +++ b/Examples/php4/shadow/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#include + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/php4/shadow/example.h b/Examples/php4/shadow/example.h new file mode 100644 index 000000000..226ec3a9b --- /dev/null +++ b/Examples/php4/shadow/example.h @@ -0,0 +1,43 @@ +/* File : example.h */ + +#include + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + ~Circle() { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + ~Square() { } + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/Examples/php4/shadow/example.i b/Examples/php4/shadow/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/php4/shadow/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/php4/shadow/runme.php4 b/Examples/php4/shadow/runme.php4 new file mode 100644 index 000000000..bd10dad6e --- /dev/null +++ b/Examples/php4/shadow/runme.php4 @@ -0,0 +1,58 @@ +x = 20; +$c->y = 30; +$s->x = -10; +$s->y = 5; + +print "\nHere is their current position:\n"; +print " Circle = (" . $c->x . "," . $c->y . ")\n"; +print " Square = (" . $s->x . "," . $s->y . ")\n"; + +# ----- Call some methods ----- + +print "\nHere are some properties of the shapes:\n"; +foreach (array($c,$s) as $o) { + print " ".get_class($o)." $o\n"; + print " area = " . $o->area() . "\n"; + print " perimeter = " . $o->perimeter() . "\n"; + } + +# ----- Delete everything ----- + +print "\nGuess I'll clean up now\n"; + +# Note: this invokes the virtual destructor + +# This causes a seq fault, possibly php trying to call destructor twice ? +#$c->_destroy(); +#$s->_destroy(); + +print Shape::nshapes() . " shapes remain\n"; +print "Goodbye\n"; + +?> diff --git a/Examples/php4/simple/BUILD.sh b/Examples/php4/simple/BUILD.sh new file mode 100755 index 000000000..881e5881f --- /dev/null +++ b/Examples/php4/simple/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -noproxy -withc example.c example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/simple/Makefile.old b/Examples/php4/simple/Makefile.old new file mode 100644 index 000000000..816da0c2b --- /dev/null +++ b/Examples/php4/simple/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = libexample +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php + +check: all diff --git a/Examples/php4/simple/example.c b/Examples/php4/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/php4/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/php4/simple/example.i b/Examples/php4/simple/example.i new file mode 100644 index 000000000..6702abb1e --- /dev/null +++ b/Examples/php4/simple/example.i @@ -0,0 +1,5 @@ +/* File : example.i */ +%module example + +extern int gcd(int x, int y); +extern double Foo; diff --git a/Examples/php4/simple/runme.php4 b/Examples/php4/simple/runme.php4 new file mode 100755 index 000000000..825c44891 --- /dev/null +++ b/Examples/php4/simple/runme.php4 @@ -0,0 +1,24 @@ + diff --git a/Examples/php4/sync/BUILD.sh b/Examples/php4/sync/BUILD.sh new file mode 100755 index 000000000..99b520879 --- /dev/null +++ b/Examples/php4/sync/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -c++ -withcxx example.cxx example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/sync/Makefile.old b/Examples/php4/sync/Makefile.old new file mode 100644 index 000000000..3418f733f --- /dev/null +++ b/Examples/php4/sync/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = libexample +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4_cpp + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php php_example.h + +check: all diff --git a/Examples/php4/sync/example.cxx b/Examples/php4/sync/example.cxx new file mode 100644 index 000000000..47378924b --- /dev/null +++ b/Examples/php4/sync/example.cxx @@ -0,0 +1,13 @@ +#include "example.h" +#include + +int x = 42; +char *s = "Test"; + +void Sync::printer(void) { + + printf("The value of global s is %s\n", s); + printf("The value of global x is %d\n", x); + printf("The value of class s is %s\n", s); + printf("The value of class x is %d\n", x); +}; diff --git a/Examples/php4/sync/example.h b/Examples/php4/sync/example.h new file mode 100644 index 000000000..d67ec21dc --- /dev/null +++ b/Examples/php4/sync/example.h @@ -0,0 +1,9 @@ +extern char *s; +extern int x; + +class Sync { + public: + int x; + char *s; + void printer(void); +}; diff --git a/Examples/php4/sync/example.i b/Examples/php4/sync/example.i new file mode 100644 index 000000000..17ff87cf3 --- /dev/null +++ b/Examples/php4/sync/example.i @@ -0,0 +1,7 @@ +%module example + +%{ +#include "example.h" +%} + +%include "example.h" diff --git a/Examples/php4/sync/runme.php4 b/Examples/php4/sync/runme.php4 new file mode 100644 index 000000000..a7c43474f --- /dev/null +++ b/Examples/php4/sync/runme.php4 @@ -0,0 +1,15 @@ +printer(); + +?> + diff --git a/Examples/php4/value/BUILD.sh b/Examples/php4/value/BUILD.sh new file mode 100755 index 000000000..881e5881f --- /dev/null +++ b/Examples/php4/value/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -noproxy -withc example.c example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/value/Makefile.old b/Examples/php4/value/Makefile.old new file mode 100644 index 000000000..c48cc7bd5 --- /dev/null +++ b/Examples/php4/value/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = php_example +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php php_example.h + +check: all diff --git a/Examples/php4/value/example.c b/Examples/php4/value/example.c new file mode 100644 index 000000000..4ed2fe10a --- /dev/null +++ b/Examples/php4/value/example.c @@ -0,0 +1,15 @@ +/* File : example.c */ + +#include "example.h" + +double dot_product(Vector a, Vector b) { + return (a.x*b.x + a.y*b.y + a.z*b.z); +} + +Vector vector_add(Vector a, Vector b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} diff --git a/Examples/php4/value/example.h b/Examples/php4/value/example.h new file mode 100644 index 000000000..212cf4bdb --- /dev/null +++ b/Examples/php4/value/example.h @@ -0,0 +1,5 @@ +/* File : example.h */ + +typedef struct { + double x, y, z; +} Vector; diff --git a/Examples/php4/value/example.i b/Examples/php4/value/example.i new file mode 100644 index 000000000..db3d5b96b --- /dev/null +++ b/Examples/php4/value/example.i @@ -0,0 +1,31 @@ +// Tests SWIG's handling of pass-by-value for complex datatypes +%module example + +%{ +#include "example.h" +%} + +/* Some functions that manipulate Vectors by value */ +extern double dot_product(Vector a, Vector b); +extern Vector vector_add(Vector a, Vector b); + +/* Include this because the vector_add() function will leak memory */ +void free(void *); + +/* Some helper functions for our interface */ +%inline %{ + +Vector *new_Vector(double x, double y, double z) { + /* We use the Zend memory manager */ + Vector *v = (Vector *) emalloc(sizeof(Vector)); + v->x = x; + v->y = y; + v->z = z; + return v; +} + +void vector_print(Vector *v) { + printf("Vector %x = (%g, %g, %g)\n", v, v->x, v->y, v->z); +} +%} + diff --git a/Examples/php4/value/runme.php4 b/Examples/php4/value/runme.php4 new file mode 100644 index 000000000..80cb88408 --- /dev/null +++ b/Examples/php4/value/runme.php4 @@ -0,0 +1,35 @@ + + + diff --git a/Examples/php4/variables/BUILD.sh b/Examples/php4/variables/BUILD.sh new file mode 100755 index 000000000..881e5881f --- /dev/null +++ b/Examples/php4/variables/BUILD.sh @@ -0,0 +1,4 @@ +#! /bin/sh -e + +${SWIG:=swig} -php4 -phpfull -noproxy -withc example.c example.i +phpize && ./configure && make clean && make diff --git a/Examples/php4/variables/Makefile.old b/Examples/php4/variables/Makefile.old new file mode 100644 index 000000000..c48cc7bd5 --- /dev/null +++ b/Examples/php4/variables/Makefile.old @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = php_example +INTERFACE = example.i +SWIGOPT = -noproxy + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php4 + +clean:: + rm -f *_wrap* *.o core *~ *.so *.php php_example.h + +check: all diff --git a/Examples/php4/variables/example.c b/Examples/php4/variables/example.c new file mode 100644 index 000000000..856895951 --- /dev/null +++ b/Examples/php4/variables/example.c @@ -0,0 +1,90 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char *cstrvar = 0; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %x\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %x (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +int value_int(int *value) { + return *value; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/php4/variables/example.h b/Examples/php4/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/php4/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/php4/variables/example.i b/Examples/php4/variables/example.i new file mode 100644 index 000000000..fca392adf --- /dev/null +++ b/Examples/php4/variables/example.i @@ -0,0 +1,45 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char *cstrvar; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; + +/* Some read-only variables */ + +%immutable; +extern int status; +extern char path[256]; +%mutable; + +/* Some helper functions to make it easier to test */ +extern void print_vars(); +extern int *new_int(int value); +extern int value_ent(int *value); + +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); + + + + diff --git a/Examples/php4/variables/runme.php4 b/Examples/php4/variables/runme.php4 new file mode 100644 index 000000000..98e4ac6d2 --- /dev/null +++ b/Examples/php4/variables/runme.php4 @@ -0,0 +1,71 @@ + + diff --git a/Examples/php4/variables/runme.php4.old b/Examples/php4/variables/runme.php4.old new file mode 100644 index 000000000..9a6bfb386 --- /dev/null +++ b/Examples/php4/variables/runme.php4.old @@ -0,0 +1,80 @@ + + diff --git a/Examples/pike/check.list b/Examples/pike/check.list new file mode 100644 index 000000000..b6474884d --- /dev/null +++ b/Examples/pike/check.list @@ -0,0 +1,8 @@ +# see top-level Makefile.in +class +constants +enum +operator +overload +simple +template diff --git a/Examples/pike/class/.cvsignore b/Examples/pike/class/.cvsignore new file mode 100755 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/pike/class/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/pike/class/Makefile b/Examples/pike/class/Makefile new file mode 100755 index 000000000..c06d68011 --- /dev/null +++ b/Examples/pike/class/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp + +static: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static + +clean: + $(MAKE) -f $(TOP)/Makefile pike_clean + +check: all diff --git a/Examples/pike/class/example.cxx b/Examples/pike/class/example.cxx new file mode 100755 index 000000000..c1708aa90 --- /dev/null +++ b/Examples/pike/class/example.cxx @@ -0,0 +1,48 @@ +/* File : example.c */ + +#include "example.h" + +#include + +#define M_PI 3.14159265358979323846 + +// Static member initializer +int Shape::nshapes = 0; + +// Constructor +Shape::Shape() { + // printf("Shape::Shape(), this = 0x%08x\n", this); + nshapes++; +} + +// Move the shape to a new location +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +// Destructor +Shape::~Shape() { + // printf("Shape::~Shape(), this = 0x%08x\n", this); + nshapes--; +} + +// Circle area +double Circle::area() { + return M_PI*radius*radius; +} + +// Circle perimeter +double Circle::perimeter() { + return 2*M_PI*radius; +} + +// Square area +double Square::area() { + return width*width; +} + +// Square perimeter +double Square::perimeter() { + return 4*width; +} diff --git a/Examples/pike/class/example.h b/Examples/pike/class/example.h new file mode 100755 index 000000000..6f5ac06d9 --- /dev/null +++ b/Examples/pike/class/example.h @@ -0,0 +1,35 @@ +/* File : example.h */ + +class Shape { +public: + Shape(); + virtual ~Shape(); + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/Examples/pike/class/example.i b/Examples/pike/class/example.i new file mode 100755 index 000000000..75700b305 --- /dev/null +++ b/Examples/pike/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/pike/class/runme.pike b/Examples/pike/class/runme.pike new file mode 100755 index 000000000..dd334accb --- /dev/null +++ b/Examples/pike/class/runme.pike @@ -0,0 +1,61 @@ +import .example; + +int main() +{ + // ----- Object creation ----- + + write("Creating some objects:\n"); + Circle c = Circle(10.0); + // write(" Created circle " + (string) c + ".\n"); + write(" Created circle.\n"); + Square s = Square(10.0); + // write(" Created square " + (string) s + ".\n"); + write(" Created square.\n"); + + // ----- Access a static member ----- + + // write("\nA total of " + Shape->nshapes + " shapes were created\n"); + + // ----- Member data access ----- + + // Set the location of the object + + // c->x = 20.0; + // c->y = 30.0; + c->x_set(20.0); + c->y_set(30.0); + + // s->x = -10.0; + // s->y = 5.0; + s->x_set(-10.0); + s->y_set(5.0); + + write("\nHere is their current position:\n"); + // write(sprintf(" Circle = (%f, %f)\n", c->x, c->y)); + // write(sprintf(" Square = (%f, %f)\n", s->x, s->y)); + write(sprintf(" Circle = (%f, %f)\n", c->x_get(), c->y_get())); + write(sprintf(" Square = (%f, %f)\n", s->x_get(), s->y_get())); + + // ----- Call some methods ----- + + write("\nHere are some properties of the shapes:\n"); + write(" The circle:\n"); + write(sprintf(" area = %f.\n", c->area())); + write(sprintf(" perimeter = %f.\n", c->perimeter())); + // write(" " + (string) s + ".\n"); + write(" The square:\n"); + write(sprintf(" area = %f.\n", s->area())); + write(sprintf(" perimeter = %f.\n", s->perimeter())); + + write("\nGuess I'll clean up now\n"); + + // Note: this invokes the virtual destructor + // del c; + // del s; + + // s = 3; + // write(sprintf("%d shapes remain\n", Shape->nshapes)); + write("Goodbye\n"); + + return 0; +} diff --git a/Examples/pike/constants/.cvsignore b/Examples/pike/constants/.cvsignore new file mode 100755 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/pike/constants/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/pike/constants/Makefile b/Examples/pike/constants/Makefile new file mode 100755 index 000000000..bac67449f --- /dev/null +++ b/Examples/pike/constants/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypike' INTERFACE='$(INTERFACE)' pike_static + +clean:: + $(MAKE) -f $(TOP)/Makefile pike_clean + +check: all diff --git a/Examples/pike/constants/example.i b/Examples/pike/constants/example.i new file mode 100755 index 000000000..4f7b1a4d7 --- /dev/null +++ b/Examples/pike/constants/example.i @@ -0,0 +1,27 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; + + diff --git a/Examples/pike/constants/runme.pike b/Examples/pike/constants/runme.pike new file mode 100755 index 000000000..e5a894f1e --- /dev/null +++ b/Examples/pike/constants/runme.pike @@ -0,0 +1,24 @@ +int main() +{ + write(sprintf("ICONST = %d (should be 42)\n", .example.ICONST)); + write(sprintf("FCONST = %f (should be 2.1828)\n", .example.FCONST)); + write(sprintf("CCONST = %c (should be 'x')\n", .example.CCONST)); + write(sprintf("CCONST2 = %c (this should be on a new line)\n", .example.CCONST2)); + write(sprintf("SCONST = %s (should be 'Hello World')\n", .example.SCONST)); + write(sprintf("SCONST2 = %s (should be '\"Hello World\"')\n", .example.SCONST2)); + write(sprintf("EXPR = %f (should be 48.5484)\n", .example.EXPR)); + write(sprintf("iconst = %d (should be 37)\n", .example.iconst)); + write(sprintf("fconst = %f (should be 3.14)\n", .example.fconst)); + + if (search(indices(.example), "EXTERN") == -1) + write("EXTERN isn't defined (good)\n"); + else + write("EXTERN is defined (bad)\n"); + + if (search(indices(.example), "FOO") == -1) + write("FOO isn't defined (good)\n"); + else + write("FOO is defined (bad)\n"); + + return 0; +} diff --git a/Examples/pike/enum/.cvsignore b/Examples/pike/enum/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/pike/enum/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/pike/enum/Makefile b/Examples/pike/enum/Makefile new file mode 100644 index 000000000..34db27dff --- /dev/null +++ b/Examples/pike/enum/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile pike_clean + +check: all diff --git a/Examples/pike/enum/example.cxx b/Examples/pike/enum/example.cxx new file mode 100644 index 000000000..6785e57ac --- /dev/null +++ b/Examples/pike/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.c */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/pike/enum/example.h b/Examples/pike/enum/example.h new file mode 100644 index 000000000..525d62afc --- /dev/null +++ b/Examples/pike/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE, WARP, LUDICROUS }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/pike/enum/example.i b/Examples/pike/enum/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/pike/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/pike/enum/runme.pike b/Examples/pike/enum/runme.pike new file mode 100644 index 000000000..7cde8d839 --- /dev/null +++ b/Examples/pike/enum/runme.pike @@ -0,0 +1,27 @@ +int main() +{ + write("*** color ***\n"); + write(" RED = " + .example.RED + "\n"); + write(" BLUE = " + .example.BLUE + "\n"); + write(" GREEN = " + .example.GREEN + "\n"); + + write("\n*** Foo::speed ***\n"); + write(" Foo_IMPULSE = " + .example.Foo.IMPULSE + "\n"); + write(" Foo_WARP = " + .example.Foo.WARP + "\n"); + write(" Foo_LUDICROUS = " + .example.Foo.LUDICROUS + "\n"); + + write("\nTesting use of enums with functions\n\n"); + + .example.enum_test(.example.RED, .example.Foo.IMPULSE); + .example.enum_test(.example.BLUE, .example.Foo.WARP); + .example.enum_test(.example.GREEN, .example.Foo.LUDICROUS); + + write("\nTesting use of enum with class method\n"); + .example.Foo f = .example.Foo(); + + f->enum_test(.example.Foo.IMPULSE); + f->enum_test(.example.Foo.WARP); + f->enum_test(.example.Foo.LUDICROUS); + + return 0; +} diff --git a/Examples/pike/overload/.cvsignore b/Examples/pike/overload/.cvsignore new file mode 100644 index 000000000..138171619 --- /dev/null +++ b/Examples/pike/overload/.cvsignore @@ -0,0 +1,4 @@ +example.o +example.so +example_wrap.cxx +example_wrap.o diff --git a/Examples/pike/overload/Makefile b/Examples/pike/overload/Makefile new file mode 100644 index 000000000..a5a4eb3d4 --- /dev/null +++ b/Examples/pike/overload/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lstdc++ -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile pike_clean + +check: all diff --git a/Examples/pike/overload/example.cxx b/Examples/pike/overload/example.cxx new file mode 100755 index 000000000..3760fdd49 --- /dev/null +++ b/Examples/pike/overload/example.cxx @@ -0,0 +1,115 @@ +#include + +#include "example.h" + +// Overloaded constructors for class Bar +Bar::Bar() { + std::cout << "Called Bar::Bar()" << std::endl; +} + +Bar::Bar(const Bar&) { + std::cout << "Called Bar::Bar(const Bar&)" << std::endl; +} + +Bar::Bar(double x) { + std::cout << "Called Bar::Bar(double) with x = " << x << std::endl; +} + +Bar::Bar(double x, char *y) { + std::cout << "Called Bar::Bar(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl; +} + +Bar::Bar(int x, int y) { + std::cout << "Called Bar::Bar(int, int) with x, y = " << x << ", " << y << std::endl; +} + +Bar::Bar(char *x) { + std::cout << "Called Bar::Bar(char *) with x = \"" << x << "\"" << std::endl; +} + +Bar::Bar(int x) { + std::cout << "Called Bar::Bar(int) with x = " << x << std::endl; +} + +Bar::Bar(long x) { + std::cout << "Called Bar::Bar(long) with x = " << x << std::endl; +} + +Bar::Bar(Bar *x) { + std::cout << "Called Bar::Bar(Bar *) with x = " << x << std::endl; +} + +// Overloaded member functions +void Bar::foo(const Bar& x) { + std::cout << "Called Bar::foo(const Bar&) with &x = " << &x << std::endl; +} + +void Bar::foo(double x) { + std::cout << "Called Bar::foo(double) with x = " << x << std::endl; +} + +void Bar::foo(double x, char *y) { + std::cout << "Called Bar::foo(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl; +} + +void Bar::foo(int x, int y) { + std::cout << "Called Bar::foo(int, int) with x, y = " << x << ", " << y << std::endl; +} + +void Bar::foo(char *x) { + std::cout << "Called Bar::foo(char *) with x = \"" << x << "\"" << std::endl; +} + +void Bar::foo(int x) { + std::cout << "Called Bar::foo(int) with x = " << x << std::endl; +} + +void Bar::foo(long x) { + std::cout << "Called Bar::foo(long) with x = " << x << std::endl; +} + +void Bar::foo(Bar *x) { + std::cout << "Called Bar::foo(Bar *) with x = " << x << std::endl; +} + +void Bar::spam(int x, int y, int z) { + std::cout << "Called Bar::spam(int, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl; +} + +void Bar::spam(double x, int y, int z) { + std::cout << "Called Bar::spam(double, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl; +} + +// Overloaded global methods +void foo(const Bar& x) { + std::cout << "Called foo(const Bar& x) with &x = " << &x << std::endl; +} + +void foo(double x) { + std::cout << "Called foo(double) with x = " << x << std::endl; +} + +void foo(double x, char *y) { + std::cout << "Called foo(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl; +} + +void foo(int x, int y) { + std::cout << "Called foo(int, int) with x, y = " << x << ", " << y << std::endl; +} + +void foo(char *x) { + std::cout << "Called foo(char *) with x = \"" << x << "\"" << std::endl; +} + +void foo(int x) { + std::cout << "Called foo(int) with x = " << x << std::endl; +} + +void foo(long x) { + std::cout << "Called foo(long) with x = " << x << std::endl; +} + +void foo(Bar *x) { + std::cout << "Called foo(Bar *) with x = " << x << std::endl; +} + diff --git a/Examples/pike/overload/example.h b/Examples/pike/overload/example.h new file mode 100755 index 000000000..e47a122ee --- /dev/null +++ b/Examples/pike/overload/example.h @@ -0,0 +1,41 @@ +#ifndef EXAMPLE_H +#define EXAMPLE_H + +class Bar { +public: + Bar(); + Bar(const Bar&); + Bar(double); + Bar(double, char *); + Bar(int, int); + Bar(char *); + Bar(long); + Bar(int); + Bar(Bar *); + + void foo(const Bar&); + void foo(double); + void foo(double, char *); + void foo(int, int); + void foo(char *); + void foo(long); + void foo(int); + void foo(Bar *); + + void spam(int x, int y=2, int z=3); + void spam(double x, int y=2, int z=3); +}; + +void foo(const Bar&); +void foo(double); +void foo(double, char *); +void foo(int, int); +void foo(char *); +void foo(int); +void foo(long); +void foo(Bar *); + +void spam(int x, int y=2, int z=3); +void spam(double x, int y=2, int z=3); + +#endif diff --git a/Examples/pike/overload/example.i b/Examples/pike/overload/example.i new file mode 100644 index 000000000..ddcd006be --- /dev/null +++ b/Examples/pike/overload/example.i @@ -0,0 +1,28 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/** + * These overloaded declarations conflict with other overloads (as far as + * SWIG's Ruby module's implementation for overloaded methods is concerned). + * One option is use the %rename directive to rename the conflicting methods; + * here, we're just using %ignore to avoid wrapping some of the overloaded + * functions altogether. + */ + +%ignore Bar; + +%ignore Bar::Bar(Bar *); +%ignore Bar::Bar(long); + +%ignore Bar::foo(const Bar&); +%ignore Bar::foo(long); + +%ignore ::foo(const Bar&); +%ignore ::foo(int); + +/* Let's just grab the original header file here */ +%include "example.h" diff --git a/Examples/pike/overload/runme.pike b/Examples/pike/overload/runme.pike new file mode 100644 index 000000000..d30e947b3 --- /dev/null +++ b/Examples/pike/overload/runme.pike @@ -0,0 +1,83 @@ +// import .example; + +int main() +{ + // This should invoke foo(double) + .example.foo(3.14159); + + // This should invoke foo(double, char *) + .example.foo(3.14159, "Pi"); + + // This should invoke foo(int, int) + .example.foo(3, 4); + + // This should invoke foo(char *) + .example.foo("This is a test"); + + // This should invoke foo(long) + .example.foo(42); + + /* + // This should invoke Bar::Bar() followed by foo(Bar *) + foo(Bar.new); + + // Skip a line + write("\n"); + + // This should invoke Bar::Bar(double) + Bar.new(3.14159); + + // This should invoke Bar::Bar(double, char *) + Bar.new(3.14159, "Pi"); + + // This should invoke Bar::Bar(int, int) + Bar.new(3, 4); + + // This should invoke Bar::Bar(char *) + Bar.new("This is a test"); + + // This should invoke Bar::Bar(int) + Bar.new(42); + + // This should invoke Bar::Bar() for the input argument, + // followed by Bar::Bar(const Bar&). + Bar.new(Bar.new); + + // Skip a line + write("\n"); + */ + + // Construct a new Bar instance (invokes Bar::Bar()) + /* + bar = Bar.new; + + // This should invoke Bar::foo(double) + bar.foo(3.14159); + + // This should invoke Bar::foo(double, char *) + bar.foo(3.14159, "Pi"); + + // This should invoke Bar::foo(int, int) + bar.foo(3, 4); + + // This should invoke Bar::foo(char *) + bar.foo("This is a test"); + + // This should invoke Bar::foo(int) + bar.foo(42); + + // This should invoke Bar::Bar() to construct the input + // argument, followed by Bar::foo(Bar *). + bar.foo(Example::Bar.new); + + // This should invoke Bar::spam(int x, int y, int z) + bar.spam(1); + + // This should invoke Bar::spam(double x, int y, int z) + bar.spam(3.14159); + */ + + write("Goodbye\n"); + + return 0; +} diff --git a/Examples/pike/simple/.cvsignore b/Examples/pike/simple/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/pike/simple/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/pike/simple/Makefile b/Examples/pike/simple/Makefile new file mode 100644 index 000000000..10b8873e1 --- /dev/null +++ b/Examples/pike/simple/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypike' INTERFACE='$(INTERFACE)' pike_static + +clean:: + $(MAKE) -f $(TOP)/Makefile pike_clean + +check: all diff --git a/Examples/pike/simple/example.c b/Examples/pike/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/pike/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/pike/simple/example.i b/Examples/pike/simple/example.i new file mode 100644 index 000000000..e338cd54c --- /dev/null +++ b/Examples/pike/simple/example.i @@ -0,0 +1,5 @@ +/* File : example.i */ +%module example + +extern int gcd(int x, int y); +/* extern double Foo; */ diff --git a/Examples/pike/simple/runme.pike b/Examples/pike/simple/runme.pike new file mode 100644 index 000000000..be4033598 --- /dev/null +++ b/Examples/pike/simple/runme.pike @@ -0,0 +1,20 @@ +int main() +{ + /* Call our gcd() function */ + int x = 42; + int y = 105; + int g = .example.gcd(x, y); + write(sprintf("The gcd of %d and %d is %d\n", x, y, g)); + + /* Manipulate the Foo global variable */ + /* Output its current value */ + /* write(sprintf("Foo = %f\n", .example.Foo_get())); */ + + /* Change its value */ + /* .example.Foo_set(3.1415926); */ + + /* See if the change took effect */ + /* write(sprintf("Foo = %f\n", .example.Foo_get())); */ + + return 0; +} diff --git a/Examples/pike/template/.cvsignore b/Examples/pike/template/.cvsignore new file mode 100755 index 000000000..bd7dd8a57 --- /dev/null +++ b/Examples/pike/template/.cvsignore @@ -0,0 +1 @@ +example_wrap.cxx diff --git a/Examples/pike/template/Makefile b/Examples/pike/template/Makefile new file mode 100755 index 000000000..1bba9bb2f --- /dev/null +++ b/Examples/pike/template/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp + +static: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static + +clean: + $(MAKE) -f $(TOP)/Makefile pike_clean + +check: all diff --git a/Examples/pike/template/example.h b/Examples/pike/template/example.h new file mode 100755 index 000000000..4d9a58c54 --- /dev/null +++ b/Examples/pike/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return self->get(index); + } + void setitem(int index, T val) { + self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/pike/template/example.i b/Examples/pike/template/example.i new file mode 100755 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/pike/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/pike/template/runme.pike b/Examples/pike/template/runme.pike new file mode 100755 index 000000000..36825c3e3 --- /dev/null +++ b/Examples/pike/template/runme.pike @@ -0,0 +1,33 @@ +int main() +{ + // Call some templated functions + write(sprintf("%d\n", .example.maxint(3, 7))); + write(sprintf("%f\n", .example.maxdouble(3.14, 2.18))); + + // Create some objects + .example.vecint iv = .example.vecint(100); + .example.vecdouble dv = .example.vecdouble(1000); + + for (int i = 0; i < 100; i++) { + iv->setitem(i, 2*i); + } + + for (int i = 0; i < 1000; i++) { + dv->setitem(i, 1.0/(i+1)); + } + + int isum = 0; + for (int i = 0; i < 100; i++) { + isum += iv->getitem(i); + } + + write(sprintf("%d\n", isum)); + + float fsum = 0.0; + for (int i = 0; i < 1000; i++) { + fsum += dv->getitem(i); + } + write(sprintf("%f\n", fsum)); + + return 0; +} diff --git a/Examples/python/check.list b/Examples/python/check.list new file mode 100644 index 000000000..9577bf9b3 --- /dev/null +++ b/Examples/python/check.list @@ -0,0 +1,23 @@ +# see top-level Makefile.in +class +constants +enum +exceptshadow +funcattr +funcptr +funcptr2 +functor +import +import +template +mpointer +multimap +operator +pointer +reference +shadow +simple +smartptr +template +value +variables diff --git a/Examples/python/class/.cvsignore b/Examples/python/class/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/class/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/class/Makefile b/Examples/python/class/Makefile index 71af176f9..19580883e 100644 --- a/Examples/python/class/Makefile +++ b/Examples/python/class/Makefile @@ -14,6 +14,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/class/example.cxx b/Examples/python/class/example.cxx index 21582f4d1..1e8e203dd 100644 --- a/Examples/python/class/example.cxx +++ b/Examples/python/class/example.cxx @@ -1,7 +1,7 @@ /* File : example.c */ #include "example.h" -#include +#define M_PI 3.14159265358979323846 /* Move the shape to a new location */ void Shape::move(double dx, double dy) { @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area() { +double Circle::area(void) { return M_PI*radius*radius; } -double Circle::perimeter() { +double Circle::perimeter(void) { return 2*M_PI*radius; } -double Square::area() { +double Square::area(void) { return width*width; } -double Square::perimeter() { +double Square::perimeter(void) { return 4*width; } diff --git a/Examples/python/class/example.dsp b/Examples/python/class/example.dsp new file mode 100644 index 000000000..78bb44c81 --- /dev/null +++ b/Examples/python/class/example.dsp @@ -0,0 +1,152 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.cxx +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\example.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -c++ -python $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -c++ -python $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/python/class/example.h b/Examples/python/class/example.h index c0f9b1d57..46d901361 100644 --- a/Examples/python/class/example.h +++ b/Examples/python/class/example.h @@ -10,8 +10,8 @@ public: }; double x, y; void move(double dx, double dy); - virtual double area() = 0; - virtual double perimeter() = 0; + virtual double area(void) = 0; + virtual double perimeter(void) = 0; static int nshapes; }; @@ -20,17 +20,17 @@ private: double radius; public: Circle(double r) : radius(r) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; - + class Square : public Shape { private: double width; public: Square(double w) : width(w) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; diff --git a/Examples/python/class/example.py b/Examples/python/class/example.py deleted file mode 100644 index a8c80502a..000000000 --- a/Examples/python/class/example.py +++ /dev/null @@ -1,67 +0,0 @@ -# file: example.py - -# This file illustrates the low-level C++ interface -# created by SWIG. In this case, all of our C++ classes -# get converted into function calls. - -import example - -# ----- Object creation ----- - -print "Creating some objects:" -c = example.new_Circle(10) -print " Created circle", c -s = example.new_Square(10) -print " Created square", s - -# ----- Access a static member ----- - -print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" - -# ----- Member data access ----- - -# Set the location of the object - - -example.Shape_x_set(c, 20) -example.Shape_y_set(c, 30) -example.Shape_x_set(s,-10) -example.Shape_y_set(s,5) - -print "\nHere is their current position:" -print " Circle = (%f, %f)" % (example.Shape_x_get(c), example.Shape_y_get(c)) -print " Square = (%f, %f)" % (example.Shape_x_get(s), example.Shape_y_get(s)) - -# ----- Call some methods ----- - -print "\nHere are some properties of the shapes:" -for o in [c,s]: - print " ", o - print " area = ", example.Shape_area(o) - print " perimeter = ", example.Shape_perimeter(o) - -# Notice how the Shape_area() and Shape_perimeter() functions really -# invoke the appropriate virtual method on each object. - -# ----- Try to cause a type error ----- - -print "\nI'm going to try and break the type system" -try: - # Bad script! - Square_area(c) # Try to invoke Square method on a Circle - print " Bad bad SWIG!" -except: - print " Well, it didn't work. Good SWIG." - - -# ----- Delete everything ----- - -print "\nGuess I'll clean up now" - -# Note: this invokes the virtual destructor -example.delete_Shape(c) -example.delete_Shape(s) - -print example.cvar.Shape_nshapes,"shapes remain" -print "Goodbye" - diff --git a/Examples/python/class/index.html b/Examples/python/class/index.html index 3529b3ca9..2ec53b0bb 100644 --- a/Examples/python/class/index.html +++ b/Examples/python/class/index.html @@ -109,14 +109,14 @@ For example:
    -example.Circle_x_set(c,15)    # Set member data
    +example.Shape_x_set(c,15)    # Set member data
     x = example.Shape_x_get(c)    # Get member data
     
    -Note: when accessing member data, the name of the base class or the derived class can be -used in the function name as shown above. Of course, it would probably be more -proper to just use the base class version such as Shape_x_get() +Note: when accessing member data, the name of the class in which +the member data was must be used. In this case, Shape_x_get() +and Shape_x_set() are used since 'x' was defined in Shape.

  • To invoke a member function, you simply do this @@ -164,13 +164,14 @@ example.cvar.Shapes_nshapes = 13 # Set a static data member

    General Comments

      -
    • This low-level interface is not the only way to handle C++ code. Shadow classes -provide a much higher-level interface. +
    • This low-level interface is not the only way to handle C++ code. +Shadow classes provide a much higher-level interface.

      -

    • SWIG *does* know how to properly perform upcasting of objects in an inheritance -hierarchy (including multiple inheritance). Therefore it is perfectly safe to pass -an object of a derived class to any function involving a base class. +
    • SWIG *does* know how to properly perform upcasting of objects in +an inheritance hierarchy (including multiple inheritance). Therefore +it is perfectly safe to pass an object of a derived class to any +function involving a base class.

    • A wide variety of C++ features are not currently supported by SWIG. Here is the @@ -206,28 +207,6 @@ to write a helper function. For example:

    • Namespaces. Not supported at all. Won't be supported until SWIG2.0 (if at all). -

      -

    • Templates. Not supported at all. SWIG throws out anything that looks like a template. -You can work around the problem by aliasing a template class behind a typedef however. -For example: - -
      -
      -%{
      -typedef vector IntVector;
      -%}
      -
      -class IntVector {
      -public:
      -    ... methods ...
      -};
      -
      -
      -
    -

    -

  • There is no guarantee that an extremely complex C++ application will be able to compile -as a Python extension. Sorry. -

  • Dave's snide remark: Like a large bottle of strong Tequilla, it's better to use C++ in moderation. diff --git a/Examples/python/class/runme.py b/Examples/python/class/runme.py new file mode 100644 index 000000000..42a5aa363 --- /dev/null +++ b/Examples/python/class/runme.py @@ -0,0 +1,51 @@ +# file: runme.py + +# This file illustrates the shadow-class C++ interface generated +# by SWIG. + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +c = example.Circle(10) +print " Created circle", c +s = example.Square(10) +print " Created square", s + +# ----- Access a static member ----- + +print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" + +# ----- Member data access ----- + +# Set the location of the object + +c.x = 20 +c.y = 30 + +s.x = -10 +s.y = 5 + +print "\nHere is their current position:" +print " Circle = (%f, %f)" % (c.x,c.y) +print " Square = (%f, %f)" % (s.x,s.y) + +# ----- Call some methods ----- + +print "\nHere are some properties of the shapes:" +for o in [c,s]: + print " ", o + print " area = ", o.area() + print " perimeter = ", o.perimeter() + +print "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +del c +del s + +s = 3 +print example.cvar.Shape_nshapes,"shapes remain" +print "Goodbye" + diff --git a/Examples/python/constants/.cvsignore b/Examples/python/constants/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/constants/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/constants/Makefile b/Examples/python/constants/Makefile index 453bbc6ee..5b726c2b1 100644 --- a/Examples/python/constants/Makefile +++ b/Examples/python/constants/Makefile @@ -13,6 +13,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/constants/example.i b/Examples/python/constants/example.i index 7d69a4d47..4f7b1a4d7 100644 --- a/Examples/python/constants/example.i +++ b/Examples/python/constants/example.i @@ -19,19 +19,9 @@ /* Neither should this (BAR isn't defined) */ #define FOO (ICONST + BAR) -/* The following statements also produce constants */ -const int iconst = 37; -const double fconst = 3.14; - -%constant(double) PI = 3.14159; - -/* Test address of operator */ - -%{ -static double blah = 1.2345; -%} - -%constant(double *) blahptr = &blah; +/* The following directives also produce constants */ +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/python/constants/example.py b/Examples/python/constants/runme.py similarity index 94% rename from Examples/python/constants/example.py rename to Examples/python/constants/runme.py index 5c1b00154..f13c4c373 100644 --- a/Examples/python/constants/example.py +++ b/Examples/python/constants/runme.py @@ -11,7 +11,7 @@ print "SCONST2 =", example.SCONST2, "(should be '\"Hello World\"')" print "EXPR =", example.EXPR, "(should be 48.5484)" print "iconst =", example.iconst, "(should be 37)" print "fconst =", example.fconst, "(should be 3.14)" -print "PI =", example.PI, "(should be 3.14159)" + try: print "EXTERN = ", example.EXTERN, "(Arg! This shouldn't print anything)" except AttributeError: diff --git a/Examples/python/enum/.cvsignore b/Examples/python/enum/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/enum/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/enum/Makefile b/Examples/python/enum/Makefile index 71af176f9..19580883e 100644 --- a/Examples/python/enum/Makefile +++ b/Examples/python/enum/Makefile @@ -14,6 +14,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/enum/example.py b/Examples/python/enum/example.py deleted file mode 100644 index 92979783e..000000000 --- a/Examples/python/enum/example.py +++ /dev/null @@ -1,30 +0,0 @@ -# file: example.py - -import example - -# ----- Object creation ----- - -# Print out the value of some enums -print "*** color ***" -print " RED =", example.RED -print " BLUE =", example.BLUE -print " GREEN =", example.GREEN - -print "\n*** Foo::speed ***" -print " Foo_IMPULSE =", example.Foo_IMPULSE -print " Foo_WARP =", example.Foo_WARP -print " Foo_LUDICROUS =", example.Foo_LUDICROUS - -print "\nTesting use of enums with functions\n" - -example.enum_test(example.RED, example.Foo_IMPULSE) -example.enum_test(example.BLUE, example.Foo_WARP) -example.enum_test(example.GREEN, example.Foo_LUDICROUS) -example.enum_test(1234,5678) - -print "\nTesting use of enum with class method" -f = example.new_Foo() - -example.Foo_enum_test(f,example.Foo_IMPULSE) -example.Foo_enum_test(f,example.Foo_WARP) -example.Foo_enum_test(f,example.Foo_LUDICROUS) diff --git a/Examples/python/enum/runme.py b/Examples/python/enum/runme.py new file mode 100644 index 000000000..e90f5d66f --- /dev/null +++ b/Examples/python/enum/runme.py @@ -0,0 +1,31 @@ +# file: example.py + +import example + +# ----- Object creation ----- + +# Print out the value of some enums +print "*** color ***" +print " RED =", example.RED +print " BLUE =", example.BLUE +print " GREEN =", example.GREEN + +print "\n*** Foo::speed ***" +print " Foo_IMPULSE =", example.Foo.IMPULSE +print " Foo_WARP =", example.Foo.WARP +print " Foo_LUDICROUS =", example.Foo.LUDICROUS + +print "\nTesting use of enums with functions\n" + +example.enum_test(example.RED, example.Foo.IMPULSE) +example.enum_test(example.BLUE, example.Foo.WARP) +example.enum_test(example.GREEN, example.Foo.LUDICROUS) +example.enum_test(1234,5678) + +print "\nTesting use of enum with class method" +f = example.Foo() + +f.enum_test(example.Foo.IMPULSE) +f.enum_test(example.Foo.WARP) +f.enum_test(example.Foo.LUDICROUS) + diff --git a/Examples/python/exception/Makefile b/Examples/python/exception/Makefile new file mode 100644 index 000000000..3e5d97bb0 --- /dev/null +++ b/Examples/python/exception/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/exception/example.h b/Examples/python/exception/example.h new file mode 100644 index 000000000..47526434c --- /dev/null +++ b/Examples/python/exception/example.h @@ -0,0 +1,37 @@ +/* File : example.h */ + +#include + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +class Test { +public: + int simple() throw(int) { + throw(37); + } + int message() throw(const char *) { + throw("I died."); + } + int hosed() throw(Exc) { + throw(Exc(42,"Hosed")); + } + int multi(int x) throw(int, const char *, Exc) { + if (x == 1) throw(37); + if (x == 2) throw("Bleah!"); + if (x == 3) throw(Exc(42,"No-go-diggy-die")); + } +}; + + + + + + diff --git a/Examples/python/exception/example.i b/Examples/python/exception/example.i new file mode 100644 index 000000000..08672c3a8 --- /dev/null +++ b/Examples/python/exception/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/python/exception/runme.py b/Examples/python/exception/runme.py new file mode 100644 index 000000000..436958984 --- /dev/null +++ b/Examples/python/exception/runme.py @@ -0,0 +1,29 @@ +# file: runme.py + +# Throw a lot of exceptions + +import example + +t = example.Test() +try: + t.simple() +except RuntimeError,e: + print e.args[0] + +try: + t.message() +except RuntimeError,e: + print e.args[0] + +try: + t.hosed() +except example.Exc,e: + print e.code, e.msg + +for i in range(1,4): + try: + t.multi(i) + except RuntimeError,e: + print e.args[0] + except example.Exc,e: + print e.code, e.msg diff --git a/Examples/python/exceptshadow/.cvsignore b/Examples/python/exceptshadow/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/exceptshadow/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/exceptshadow/Makefile b/Examples/python/exceptshadow/Makefile new file mode 100644 index 000000000..f00af7dba --- /dev/null +++ b/Examples/python/exceptshadow/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/exceptshadow/example.h b/Examples/python/exceptshadow/example.h new file mode 100644 index 000000000..cd2f17214 --- /dev/null +++ b/Examples/python/exceptshadow/example.h @@ -0,0 +1,51 @@ +/* File : example.h */ + +// A simple exception +class EmptyError { }; +class FullError { + public: + int maxsize; + FullError(int m) : maxsize(m) { } +}; + +template class Queue { + int maxsize; + T *items; + int nitems; + int last; + public: + Queue(int size) { + maxsize = size; + items = new T[size]; + nitems = 0; + last = 0; + } + ~Queue() { + delete [] items; + } + void enqueue(T x) throw(FullError) { + if (nitems == maxsize) { + throw FullError(maxsize); + } + items[last] = x; + last = (last + 1) % maxsize; + nitems++; + } + T dequeue() throw(EmptyError) { + T x; + if (nitems == 0) throw EmptyError(); + x = items[(last + maxsize - nitems) % maxsize]; + nitems--; + return x; + } + int length() { + return nitems; + } +}; + + + + + + + diff --git a/Examples/python/exceptshadow/example.i b/Examples/python/exceptshadow/example.i new file mode 100644 index 000000000..34f1c8840 --- /dev/null +++ b/Examples/python/exceptshadow/example.i @@ -0,0 +1,83 @@ +/* This is a rather sophisticated example that illustrates exception handling, + templates, and shadow classes. + + (i) The %exception directive is used to attach exception handlers + to specific methods. + + (ii) Exception classes are automatically converted to shadow class + objects. + + (iii) The %template directive is used to expand the templates +*/ + +%module example + +%{ +#include "example.h" +%} + +/* Define some exception handlers for specific methods. In + the header file, the enqueue method throws FullError and + the dequeue method throws EmptyError. Since we don't + want to define an exception handler for everything, we + simply write a handler each method individually. + + Note: the *::enqueue syntax means that we simply define + the handler for any class with this method defined. +*/ + +%exception *::enqueue { + try { + $action + } catch(FullError e) { + FullError *ecopy = new FullError(e); + PyObject *err = SWIG_NewPointerObj(ecopy, SWIGTYPE_p_FullError, 1); + PyErr_SetObject((PyObject *) SWIGTYPE_p_FullError->clientdata, err); + return NULL; + } +} + +/* Some notes about the code above: + + (0) $action gets replaced with the actual method call. + + (1) We are going to return a copy of the exception object (FullError) + to pass back to the Python interpreter. This is why the copy + constructor is being called. + + (2) The SWIG_NewPointerObj() call automatically wraps the exception object + into a shadow class. The SWIGTYPE_p_FullError is the type-descriptor + used for type checking. The "1" indicates that Python will have + ownership of the resulting object. + + (3) The PyErr_SetObject call sets the Python exception. However, + the SWIGTYPE_p_FullError->clientdata reference may not be + obvious. This is actually the Python shadow class object + for FullError. Recall that in Python, exceptions are defined + as classes. Therefore, this works perfectly as the argument to + PyErr_SetObject()! A neat trick perhaps. +*/ + +%exception *::dequeue { + try { + $action + } catch(EmptyError e) { + EmptyError *ecopy = new EmptyError(e); + PyObject *err = SWIG_NewPointerObj(ecopy, SWIGTYPE_p_EmptyError, 1); + PyErr_SetObject((PyObject *) SWIGTYPE_p_EmptyError->clientdata, err); + return NULL; + } +} + +/* Grab the original header file */ +%include "example.h" + +/* Instantiate a few templates */ + +%template(intQueue) Queue; +%template(doubleQueue) Queue; + + + + + diff --git a/Examples/python/exceptshadow/runme.py b/Examples/python/exceptshadow/runme.py new file mode 100644 index 000000000..a2ae55584 --- /dev/null +++ b/Examples/python/exceptshadow/runme.py @@ -0,0 +1,45 @@ +# file: runme.py +import example + +q = example.intQueue(10) + +print "Inserting items into intQueue" + +try: + for i in range(0,100): + q.enqueue(i) +except example.FullError,e: + print "Maxsize is", e.maxsize + +print "Removing items" + +try: + while 1: + q.dequeue() +except example.EmptyError,e: + pass + + +q = example.doubleQueue(1000) + +print "Inserting items into doubleQueue" + +try: + for i in range(0,10000): + q.enqueue(i*1.5) +except example.FullError,e: + print "Maxsize is", e.maxsize + +print "Removing items" + +try: + while 1: + q.dequeue() +except example.EmptyError,e: + pass + + + + + + diff --git a/Examples/python/funcattr/.cvsignore b/Examples/python/funcattr/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/funcattr/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/funcattr/Makefile b/Examples/python/funcattr/Makefile new file mode 100644 index 000000000..f00af7dba --- /dev/null +++ b/Examples/python/funcattr/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/funcattr/example.i b/Examples/python/funcattr/example.i new file mode 100644 index 000000000..666ddff4d --- /dev/null +++ b/Examples/python/funcattr/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +/* Turn all data attributes into a pair of accessor functions. + In this case, a data attribute foo is accessed using + foo() and changed using set_foo(). The format strings + in %attributefunc() can be used to precisely determine + the format of the get/set functions */ + +%attributefunc(%s,set_%s) + +%inline %{ +class Vector { +public: + double x,y,z; +}; +%} diff --git a/Examples/python/funcattr/index.html b/Examples/python/funcattr/index.html new file mode 100644 index 000000000..f89f90ca6 --- /dev/null +++ b/Examples/python/funcattr/index.html @@ -0,0 +1,22 @@ + + +SWIG:Examples:python:funcattr + + + + + +SWIG/Examples/python/funcattr/ +
    + +

    Turning Attributes into Functions

    + +$Header$
    + +

    +This example shows how you can turn data attributes into member functions. + +


    + + + diff --git a/Examples/python/funcattr/runme.py b/Examples/python/funcattr/runme.py new file mode 100644 index 000000000..59432e142 --- /dev/null +++ b/Examples/python/funcattr/runme.py @@ -0,0 +1,17 @@ +# file: runme.py + +import example + +# Create an object +v = example.Vector() + +print "Setting some values" +# Set some values (using functions instead of attributes) +v.set_x(3.5) +v.set_y(4.0) +v.set_z(10.5) + +# Get some values +print v +print v.x(), v.y(), v.z() + diff --git a/Examples/python/funcptr/.cvsignore b/Examples/python/funcptr/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/funcptr/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/funcptr/Makefile b/Examples/python/funcptr/Makefile index e495cfa9a..754c4a029 100644 --- a/Examples/python/funcptr/Makefile +++ b/Examples/python/funcptr/Makefile @@ -13,6 +13,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/funcptr/example.c b/Examples/python/funcptr/example.c index 99583b72e..5c4a3dabf 100644 --- a/Examples/python/funcptr/example.c +++ b/Examples/python/funcptr/example.c @@ -15,3 +15,5 @@ int sub(int a, int b) { int mul(int a, int b) { return a*b; } + +int (*funcvar)(int,int) = add; diff --git a/Examples/python/funcptr/example.i b/Examples/python/funcptr/example.i index 73cc6eb8c..8b3bef678 100644 --- a/Examples/python/funcptr/example.i +++ b/Examples/python/funcptr/example.i @@ -8,8 +8,9 @@ extern int do_op(int a, int b, int (*op)(int, int)); /* Now install a bunch of "ops" as constants */ -%constant(int (*)(int,int)) ADD = add; -%constant(int (*)(int,int)) SUB = sub; -%constant(int (*)(int,int)) MUL = mul; +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; +extern int (*funcvar)(int,int); diff --git a/Examples/python/funcptr/example.py b/Examples/python/funcptr/runme.py similarity index 100% rename from Examples/python/funcptr/example.py rename to Examples/python/funcptr/runme.py diff --git a/Examples/python/funcptr2/.cvsignore b/Examples/python/funcptr2/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/funcptr2/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/funcptr2/Makefile b/Examples/python/funcptr2/Makefile new file mode 100644 index 000000000..754c4a029 --- /dev/null +++ b/Examples/python/funcptr2/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/funcptr2/example.c b/Examples/python/funcptr2/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/Examples/python/funcptr2/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/python/funcptr2/example.h b/Examples/python/funcptr2/example.h new file mode 100644 index 000000000..58989db79 --- /dev/null +++ b/Examples/python/funcptr2/example.h @@ -0,0 +1,7 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + diff --git a/Examples/python/funcptr2/example.i b/Examples/python/funcptr2/example.i new file mode 100644 index 000000000..81a66146a --- /dev/null +++ b/Examples/python/funcptr2/example.i @@ -0,0 +1,18 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%callback("%(upper)s") +int add(int, int); +int sub(int, int); +int mul(int, int); +%nocallback + +extern int (*funcvar)(int,int); + diff --git a/Examples/python/funcptr2/runme.py b/Examples/python/funcptr2/runme.py new file mode 100644 index 000000000..a85551bed --- /dev/null +++ b/Examples/python/funcptr2/runme.py @@ -0,0 +1,20 @@ +# file: example.py + +import example + +a = 37 +b = 42 + +# Now call our C function with a bunch of callbacks + +print "Trying some C callback functions" +print " a =", a +print " b =", b +print " ADD(a,b) =", example.do_op(a,b,example.ADD) +print " SUB(a,b) =", example.do_op(a,b,example.SUB) +print " MUL(a,b) =", example.do_op(a,b,example.MUL) + +print "Here is what the C callback function objects look like in Python" +print " ADD =", example.ADD +print " SUB =", example.SUB +print " MUL =", example.MUL diff --git a/Examples/python/functor/.cvsignore b/Examples/python/functor/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/functor/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/functor/Makefile b/Examples/python/functor/Makefile new file mode 100644 index 000000000..dbc78cd8d --- /dev/null +++ b/Examples/python/functor/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/functor/example.i b/Examples/python/functor/example.i new file mode 100644 index 000000000..2fd38176f --- /dev/null +++ b/Examples/python/functor/example.i @@ -0,0 +1,29 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +// Rename the application operator to __call__ for python. +// Note: this is normally automatic, but if you had to do it yourself +// you would use this directive: +// +// %rename(__call__) *::operator(); + +// Instantiate a few versions +%template(intSum) Sum; +%template(doubleSum) Sum; + + + + diff --git a/Examples/python/functor/runme.py b/Examples/python/functor/runme.py new file mode 100644 index 000000000..8fc0f2ff2 --- /dev/null +++ b/Examples/python/functor/runme.py @@ -0,0 +1,17 @@ +# Operator overloading example +import example +import math + +a = example.intSum(0) +b = example.doubleSum(100.0) + +# Use the objects. They should be callable just like a normal +# python function. + +for i in range(0,100): + a(i) # Note: function call + b(math.sqrt(i)) # Note: function call + +print a.result() +print b.result() + diff --git a/Examples/python/import/.cvsignore b/Examples/python/import/.cvsignore new file mode 100644 index 000000000..f5a4b68aa --- /dev/null +++ b/Examples/python/import/.cvsignore @@ -0,0 +1,13 @@ +bar.py +base.py +foo.py +spam.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/import/Makefile b/Examples/python/import/Makefile new file mode 100644 index 000000000..780c87e88 --- /dev/null +++ b/Examples/python/import/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SWIGOPT = -c +#If your system requires linking with the runtime libraries then set the directory location here +RUNTIMEDIR = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='base' INTERFACE='base.i' python_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' python_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' python_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' python_multi_cpp + + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + @rm -f foo.py bar.py spam.py base.py + +check: all diff --git a/Examples/python/import/README b/Examples/python/import/README new file mode 100644 index 000000000..2f6aa54d6 --- /dev/null +++ b/Examples/python/import/README @@ -0,0 +1,28 @@ +This example tests the SWIG run-time libraries and use of the +%import directive to work with multiple modules. + +Use 'python runme.py' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module used %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is working correctly, all of the modules will load +correctly and type checking will work correctly. The +example requires the use of the SWIG run-time libraries +which must be built and properly installed. + + + + diff --git a/Examples/python/import/bar.h b/Examples/python/import/bar.h new file mode 100644 index 000000000..fa4185f1f --- /dev/null +++ b/Examples/python/import/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual void A() { + printf("I'm Bar::A\n"); + } + void B() { + printf("I'm Bar::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast(b); + } + +}; + + diff --git a/Examples/python/import/bar.i b/Examples/python/import/bar.i new file mode 100644 index 000000000..5816cbe17 --- /dev/null +++ b/Examples/python/import/bar.i @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + diff --git a/Examples/python/import/base.h b/Examples/python/import/base.h new file mode 100644 index 000000000..be3cdef7d --- /dev/null +++ b/Examples/python/import/base.h @@ -0,0 +1,18 @@ +#include + +class Base { + public: + Base() { }; + ~Base() { }; + virtual void A() { + printf("I'm Base::A\n"); + } + void B() { + printf("I'm Base::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } +}; + + diff --git a/Examples/python/import/base.i b/Examples/python/import/base.i new file mode 100644 index 000000000..f6e19efd8 --- /dev/null +++ b/Examples/python/import/base.i @@ -0,0 +1,6 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h diff --git a/Examples/python/import/foo.h b/Examples/python/import/foo.h new file mode 100644 index 000000000..dd5184031 --- /dev/null +++ b/Examples/python/import/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual void A() { + printf("I'm Foo::A\n"); + } + void B() { + printf("I'm Foo::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/python/import/foo.i b/Examples/python/import/foo.i new file mode 100644 index 000000000..27feb2e6a --- /dev/null +++ b/Examples/python/import/foo.i @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + diff --git a/Examples/python/import/runme.py b/Examples/python/import/runme.py new file mode 100644 index 000000000..6b800ecb8 --- /dev/null +++ b/Examples/python/import/runme.py @@ -0,0 +1,111 @@ +# file: runme.py +# Test various properties of classes defined in separate modules + +print "Testing the %import directive" +import base +import foo +import bar +import spam + +# Create some objects + +print "Creating some objects" + +a = base.Base() +b = foo.Foo() +c = bar.Bar() +d = spam.Spam() + +# Try calling some methods +print "Testing some methods" +print "", +print "Should see 'Base::A' ---> ", +a.A() +print "Should see 'Base::B' ---> ", +a.B() + +print "Should see 'Foo::A' ---> ", +b.A() +print "Should see 'Foo::B' ---> ", +b.B() + +print "Should see 'Bar::A' ---> ", +c.A() +print "Should see 'Bar::B' ---> ", +c.B() + +print "Should see 'Spam::A' ---> ", +d.A() +print "Should see 'Spam::B' ---> ", +d.B() + +# Try some casts + +print "\nTesting some casts\n" +print "", + +x = a.toBase() +print "Should see 'Base::A' ---> ", +x.A() +print "Should see 'Base::B' ---> ", +x.B() + +x = b.toBase() +print "Should see 'Foo::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = c.toBase() +print "Should see 'Bar::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBase() +print "Should see 'Spam::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBar() +print "Should see 'Bar::B' ---> ", +x.B() + +print "\nTesting some dynamic casts\n" +x = d.toBase() + +print " Spam -> Base -> Foo : ", +y = foo.Foo_fromBase(x) +if y: + print "bad swig" +else: + print "good swig" + +print " Spam -> Base -> Bar : ", +y = bar.Bar_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Spam -> Base -> Spam : ", +y = spam.Spam_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Foo -> Spam : ", +y = spam.Spam_fromBase(b) +if y: + print "bad swig" +else: + print "good swig" + + + + diff --git a/Examples/python/import/spam.h b/Examples/python/import/spam.h new file mode 100644 index 000000000..b4e7a2646 --- /dev/null +++ b/Examples/python/import/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual void A() { + printf("I'm Spam::A\n"); + } + void B() { + printf("I'm Spam::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + virtual Bar *toBar() { + return static_cast(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/python/import/spam.i b/Examples/python/import/spam.i new file mode 100644 index 000000000..d3d9121db --- /dev/null +++ b/Examples/python/import/spam.i @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + diff --git a/Examples/python/import_template/.cvsignore b/Examples/python/import_template/.cvsignore new file mode 100644 index 000000000..457218f0d --- /dev/null +++ b/Examples/python/import_template/.cvsignore @@ -0,0 +1,10 @@ +base.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/import_template/Makefile b/Examples/python/import_template/Makefile new file mode 100644 index 000000000..780c87e88 --- /dev/null +++ b/Examples/python/import_template/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SWIGOPT = -c +#If your system requires linking with the runtime libraries then set the directory location here +RUNTIMEDIR = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='base' INTERFACE='base.i' python_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' python_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' python_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' python_multi_cpp + + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + @rm -f foo.py bar.py spam.py base.py + +check: all diff --git a/Examples/python/import_template/README b/Examples/python/import_template/README new file mode 100644 index 000000000..ec3d6ca49 --- /dev/null +++ b/Examples/python/import_template/README @@ -0,0 +1,30 @@ +This example tests the SWIG run-time libraries and use of the +%import directive to work with multiple modules. However, +unlike the import example, this uses templates to really +stress test the type-system. + +Use 'python runme.py' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module used %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is working correctly, all of the modules will load +correctly and type checking will work correctly. The +example requires the use of the SWIG run-time libraries +which must be built and properly installed. + + + + diff --git a/Examples/python/import_template/bar.h b/Examples/python/import_template/bar.h new file mode 100644 index 000000000..500b67a3c --- /dev/null +++ b/Examples/python/import_template/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +template class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual void A() { + printf("I'm Bar::A\n"); + } + void B() { + printf("I'm Bar::B\n"); + } + virtual Base *toBase() { + return static_cast *>(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast *>(b); + } + +}; + + diff --git a/Examples/python/import_template/bar.i b/Examples/python/import_template/bar.i new file mode 100644 index 000000000..155c08d34 --- /dev/null +++ b/Examples/python/import_template/bar.i @@ -0,0 +1,11 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + +%template(intBar) Bar; + + diff --git a/Examples/python/import_template/base.h b/Examples/python/import_template/base.h new file mode 100644 index 000000000..a56441e14 --- /dev/null +++ b/Examples/python/import_template/base.h @@ -0,0 +1,18 @@ +#include + +template class Base { + public: + Base() { }; + ~Base() { }; + virtual void A() { + printf("I'm Base::A\n"); + } + void B() { + printf("I'm Base::B\n"); + } + virtual Base *toBase() { + return static_cast *>(this); + } +}; + + diff --git a/Examples/python/import_template/base.i b/Examples/python/import_template/base.i new file mode 100644 index 000000000..a6da06339 --- /dev/null +++ b/Examples/python/import_template/base.i @@ -0,0 +1,7 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h +%template(intBase) Base; diff --git a/Examples/python/import_template/foo.h b/Examples/python/import_template/foo.h new file mode 100644 index 000000000..3df13d20d --- /dev/null +++ b/Examples/python/import_template/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +template class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual void A() { + printf("I'm Foo::A\n"); + } + void B() { + printf("I'm Foo::B\n"); + } + virtual Base *toBase() { + return static_cast *>(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast *>(b); + } +}; + + diff --git a/Examples/python/import_template/foo.i b/Examples/python/import_template/foo.i new file mode 100644 index 000000000..e271672cd --- /dev/null +++ b/Examples/python/import_template/foo.i @@ -0,0 +1,10 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + +%template(intFoo) Foo; + diff --git a/Examples/python/import_template/runme.py b/Examples/python/import_template/runme.py new file mode 100644 index 000000000..0d5aded14 --- /dev/null +++ b/Examples/python/import_template/runme.py @@ -0,0 +1,111 @@ +# file: runme.py +# Test various properties of classes defined in separate modules + +print "Testing the %import directive with templates" +import base +import foo +import bar +import spam + +# Create some objects + +print "Creating some objects" + +a = base.intBase() +b = foo.intFoo() +c = bar.intBar() +d = spam.intSpam() + +# Try calling some methods +print "Testing some methods" +print "", +print "Should see 'Base::A' ---> ", +a.A() +print "Should see 'Base::B' ---> ", +a.B() + +print "Should see 'Foo::A' ---> ", +b.A() +print "Should see 'Foo::B' ---> ", +b.B() + +print "Should see 'Bar::A' ---> ", +c.A() +print "Should see 'Bar::B' ---> ", +c.B() + +print "Should see 'Spam::A' ---> ", +d.A() +print "Should see 'Spam::B' ---> ", +d.B() + +# Try some casts + +print "\nTesting some casts\n" +print "", + +x = a.toBase() +print "Should see 'Base::A' ---> ", +x.A() +print "Should see 'Base::B' ---> ", +x.B() + +x = b.toBase() +print "Should see 'Foo::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = c.toBase() +print "Should see 'Bar::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBase() +print "Should see 'Spam::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBar() +print "Should see 'Bar::B' ---> ", +x.B() + +print "\nTesting some dynamic casts\n" +x = d.toBase() + +print " Spam -> Base -> Foo : ", +y = foo.intFoo_fromBase(x) +if y: + print "bad swig" +else: + print "good swig" + +print " Spam -> Base -> Bar : ", +y = bar.intBar_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Spam -> Base -> Spam : ", +y = spam.intSpam_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Foo -> Spam : ", +y = spam.intSpam_fromBase(b) +if y: + print "bad swig" +else: + print "good swig" + + + + diff --git a/Examples/python/import_template/spam.h b/Examples/python/import_template/spam.h new file mode 100644 index 000000000..c72f49a32 --- /dev/null +++ b/Examples/python/import_template/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +template class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual void A() { + printf("I'm Spam::A\n"); + } + void B() { + printf("I'm Spam::B\n"); + } + virtual Base *toBase() { + return static_cast *>(this); + } + virtual Bar *toBar() { + return static_cast *>(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast *>(b); + } +}; + + diff --git a/Examples/python/import_template/spam.i b/Examples/python/import_template/spam.i new file mode 100644 index 000000000..dd94b0350 --- /dev/null +++ b/Examples/python/import_template/spam.i @@ -0,0 +1,10 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + +%template(intSpam) Spam; + diff --git a/Examples/python/index.html b/Examples/python/index.html index fcf607895..dc0110716 100644 --- a/Examples/python/index.html +++ b/Examples/python/index.html @@ -35,7 +35,11 @@ certain C declarations are turned into constants.
  • -
  • The compilation of examples is done using the file Example/Makefile. This +
  • +Please see the Windows page in the main manual for information on using the examples on Windows.

    +

  • + +
  • On Unix the compilation of examples is done using the file Example/Makefile. This makefile performs a manual module compilation which is platform specific. Typically, the steps look like this (Linux): diff --git a/Examples/python/libffi/Makefile b/Examples/python/libffi/Makefile new file mode 100644 index 000000000..7a20396b8 --- /dev/null +++ b/Examples/python/libffi/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' LIBS='-L/usr/local/lib -lffi' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/libffi/example.i b/Examples/python/libffi/example.i new file mode 100644 index 000000000..9a29ec04e --- /dev/null +++ b/Examples/python/libffi/example.i @@ -0,0 +1,176 @@ +/* File : example.i */ +%module example + +%{ +#include +#include +%} + +/* A wrapper for execlp() using libffi to handle an arbitrary + number of arguments */ + +%typemap(in) (...) { + char **argv; + int argc; + int i; + + argc = PyTuple_Size(varargs); + argv = (char **) malloc(sizeof(char *)*(argc+1)); + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (!PyString_Check(o)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + return NULL; + } + argv[i] = PyString_AsString(o); + } + argv[i] = NULL; + $1 = (void *) argv; +} + +/* Rewrite the function call, using libffi */ +%feature("action") execlp { + int i, vc; + ffi_cif cif; + ffi_type **types; + void **values; + char **args; + + vc = PyTuple_Size(varargs); + types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *)); + values = (void **) malloc((vc+3)*sizeof(void *)); + args = (char **) arg3; + + /* Set up path parameter */ + types[0] = &ffi_type_pointer; + values[0] = &arg1; + + /* Set up first argument */ + types[1] = &ffi_type_pointer; + values[1] = &arg2; + + /* Set up rest of parameters */ + for (i = 0; i <= vc; i++) { + types[2+i] = &ffi_type_pointer; + values[2+i] = &args[i]; + } + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3, + &ffi_type_uint, types) == FFI_OK) { + ffi_call(&cif, (void (*)()) execlp, &result, values); + } else { + PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); + free(types); + free(values); + free(arg3); + return NULL; + } + free(types); + free(values); + free(arg3); +} + +int execlp(const char *path, const char *arg1, ...); + + +/* A wrapper for printf() using libffi */ + +%{ + typedef struct { + int type; + union { + int ivalue; + double dvalue; + void *pvalue; + } val; + } vtype; + enum { VT_INT, VT_DOUBLE, VT_POINTER }; + %} + +%typemap(in) (const char *fmt, ...) { + vtype *argv; + int argc; + int i; + + $1 = PyString_AsString($input); + + argc = PyTuple_Size(varargs); + argv = (vtype *) malloc(argc*sizeof(vtype)); + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (PyInt_Check(o)) { + argv[i].type = VT_INT; + argv[i].val.ivalue = PyInt_AsLong(o); + } else if (PyFloat_Check(o)) { + argv[i].type = VT_DOUBLE; + argv[i].val.dvalue = PyFloat_AsDouble(o); + } else if (PyString_Check(o)) { + argv[i].type = VT_POINTER; + argv[i].val.pvalue = (void *) PyString_AsString(o); + } else { + PyErr_SetString(PyExc_ValueError,"Unsupported argument type"); + free(argv); + return NULL; + } + } + + $2 = (void *) argv; +} + +/* Rewrite the function call, using libffi */ +%feature("action") printf { + int i, vc; + ffi_cif cif; + ffi_type **types; + void **values; + vtype *args; + + vc = PyTuple_Size(varargs); + types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *)); + values = (void **) malloc((vc+1)*sizeof(void *)); + args = (vtype *) arg2; + + /* Set up fmt parameter */ + types[0] = &ffi_type_pointer; + values[0] = &arg1; + + /* Set up rest of parameters */ + for (i = 0; i < vc; i++) { + switch(args[i].type) { + case VT_INT: + types[1+i] = &ffi_type_uint; + values[1+i] = &args[i].val.ivalue; + break; + case VT_DOUBLE: + types[1+i] = &ffi_type_double; + values[1+i] = &args[i].val.dvalue; + break; + case VT_POINTER: + types[1+i] = &ffi_type_pointer; + values[1+i] = &args[i].val.pvalue; + break; + default: + abort(); /* Whoa! We're seriously hosed */ + break; + } + } + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1, + &ffi_type_uint, types) == FFI_OK) { + ffi_call(&cif, (void (*)()) printf, &result, values); + } else { + PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); + free(types); + free(values); + free(args); + return NULL; + } + free(types); + free(values); + free(args); +} + +int printf(const char *fmt, ...); + + + + + diff --git a/Examples/python/mpointer/.cvsignore b/Examples/python/mpointer/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/mpointer/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/mpointer/Makefile b/Examples/python/mpointer/Makefile new file mode 100644 index 000000000..343f04f54 --- /dev/null +++ b/Examples/python/mpointer/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/mpointer/example.cxx b/Examples/python/mpointer/example.cxx new file mode 100644 index 000000000..1a6bb666a --- /dev/null +++ b/Examples/python/mpointer/example.cxx @@ -0,0 +1,45 @@ +/* File : example.c */ + +#include "example.h" +#include + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} + +double do_op(Shape *s, double (Shape::*m)(void)) { + return (s->*m)(); +} + +double (Shape::*areapt())(void) { + return &Shape::area; +} + +double (Shape::*perimeterpt())(void) { + return &Shape::perimeter; +} + +/* Member pointer variables */ +double (Shape::*areavar)(void) = &Shape::area; +double (Shape::*perimetervar)(void) = &Shape::perimeter; + diff --git a/Examples/python/mpointer/example.h b/Examples/python/mpointer/example.h new file mode 100644 index 000000000..110fe91c1 --- /dev/null +++ b/Examples/python/mpointer/example.h @@ -0,0 +1,50 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + double *z; + + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +extern double do_op(Shape *s, double (Shape::*m)(void)); + +/* Functions that return member pointers */ + +extern double (Shape::*areapt())(void); +extern double (Shape::*perimeterpt())(void); + +/* Global variables that are member pointers */ +extern double (Shape::*areavar)(void); +extern double (Shape::*perimetervar)(void); + + + diff --git a/Examples/python/mpointer/example.i b/Examples/python/mpointer/example.i new file mode 100644 index 000000000..238792be8 --- /dev/null +++ b/Examples/python/mpointer/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Some constants */ + +%constant double (Shape::*AREAPT)(void) = &Shape::area; +%constant double (Shape::*PERIMPT)(void) = &Shape::perimeter; +%constant double (Shape::*NULLPT)(void) = 0; + diff --git a/Examples/python/mpointer/runme.py b/Examples/python/mpointer/runme.py new file mode 100644 index 000000000..0d20093aa --- /dev/null +++ b/Examples/python/mpointer/runme.py @@ -0,0 +1,51 @@ +# Example using pointers to member functions + +import example + +# Get the pointers + +area_pt = example.areapt() +perim_pt = example.perimeterpt() + +print "area_pt =", area_pt +print "perim_pt = ", perim_pt + +# Create some objects + +c = example.Circle(4) +s = example.Square(10) + +# Do some calculations + +print "Circle area = ", example.do_op(c,area_pt) +print "Circle perim = ", example.do_op(c,perim_pt) +print "Square area = ", example.do_op(s,area_pt) +print "Square perim = ", example.do_op(s,perim_pt) + +print "cvar.areavar =", example.cvar.areavar +print "cvar.perimetervar =", example.cvar.perimetervar + +# Try the variables +print "Circle area = ", example.do_op(c,example.cvar.areavar) +print "Circle perim = ", example.do_op(c,example.cvar.perimetervar) +print "Square area = ", example.do_op(s,example.cvar.areavar) +print "Square perim = ", example.do_op(s,example.cvar.perimetervar) + +# Modify one of the variables +example.cvar.areavar = perim_pt + +print "Circle perimeter = ", example.do_op(c,example.cvar.areavar) + +# Try the constants + +print "example.AREAPT =", example.AREAPT +print "example.PERIMPT=", example.PERIMPT +print "example.NULLPT =", example.NULLPT + +print "Circle area = ", example.do_op(c,example.AREAPT) +print "Circle perim = ", example.do_op(c,example.PERIMPT) +print "Square area = ", example.do_op(s,example.AREAPT) +print "Square perim = ", example.do_op(s,example.PERIMPT) + + + diff --git a/Examples/python/multimap/.cvsignore b/Examples/python/multimap/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/multimap/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/multimap/Makefile b/Examples/python/multimap/Makefile new file mode 100644 index 000000000..754c4a029 --- /dev/null +++ b/Examples/python/multimap/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/multimap/example.c b/Examples/python/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/python/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/python/multimap/example.dsp b/Examples/python/multimap/example.dsp new file mode 100644 index 000000000..e905647a5 --- /dev/null +++ b/Examples/python/multimap/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PYTHON_LIB) /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(PYTHON_LIB) /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -python $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -python $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i new file mode 100644 index 000000000..d95b3b141 --- /dev/null +++ b/Examples/python/multimap/example.i @@ -0,0 +1,83 @@ +/* File : example.i */ +%module example +%include exception.i +%include typemaps.i + +extern int gcd(int x, int y); + +%typemap(in,fragment="t_output_helper") (int argc, char *argv[]) { + int i; + if (!PyList_Check($input)) { + SWIG_exception(SWIG_ValueError, "Expecting a list"); + return NULL; + } + $1 = PyList_Size($input); + if ($1 == 0) { + SWIG_exception(SWIG_ValueError, "List must contain at least 1 element"); + return NULL; + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + PyObject *s = PyList_GetItem($input,i); + if (!PyString_Check(s)) { + SWIG_exception(SWIG_ValueError, "List items must be strings"); + free($2); + return NULL; + } + $2[i] = PyString_AsString(s); + } + $2[i] = 0; +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(python,in) (char *bytes, int len) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + return NULL; + } + $1 = PyString_AsString($input); + $2 = PyString_Size($input); +} + +extern int count(char *bytes, int len, char c); + + +/* This example shows how to wrap a function that mutates a string */ + +/* Since str is modified, we make a copy of the Python object + so that we don't violate it's mutability */ + +%typemap(python,in) (char *str, int len) { + $2 = PyString_Size($input); + $1 = (char *) malloc($2+1); + memmove($1,PyString_AsString($input),$2); +} + +/* Return the mutated string as a new object. The t_output_helper + function takes an object and appends it to the output object + to create a tuple */ + +%typemap(python,argout) (char *str, int len) { + PyObject *o; + o = PyString_FromStringAndSize($1,$2); + $result = t_output_helper($result,o); + free($1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + return NULL; + } +} + +extern void circle(double cx, double cy); + + diff --git a/Examples/python/multimap/runme.py b/Examples/python/multimap/runme.py new file mode 100644 index 000000000..95669c4bb --- /dev/null +++ b/Examples/python/multimap/runme.py @@ -0,0 +1,27 @@ +# file: example.py + +import example + +# Call our gcd() function + +x = 42 +y = 105 +g = example.gcd(x,y) +print "The gcd of %d and %d is %d" % (x,y,g) + +# Call the gcdmain() function +example.gcdmain(["gcdmain","42","105"]) + +# Call the count function +print example.count("Hello World", "l") + +# Call the capitalize function + +print example.capitalize("hello world") + + + + + + + diff --git a/Examples/python/operator/.cvsignore b/Examples/python/operator/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/operator/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/operator/Makefile b/Examples/python/operator/Makefile new file mode 100644 index 000000000..dbc78cd8d --- /dev/null +++ b/Examples/python/operator/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/operator/example.h b/Examples/python/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/python/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/python/operator/example.i b/Examples/python/operator/example.i new file mode 100644 index 000000000..f46619501 --- /dev/null +++ b/Examples/python/operator/example.i @@ -0,0 +1,28 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(ComplexCopy) Complex::Complex(Complex const &); + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *__str__() { + static char temp[512]; + sprintf(temp,"(%g,%g)", self->re(), self->im()); + return temp; + } +}; + + diff --git a/Examples/python/operator/runme.py b/Examples/python/operator/runme.py new file mode 100644 index 000000000..3687a38de --- /dev/null +++ b/Examples/python/operator/runme.py @@ -0,0 +1,21 @@ +# Operator overloading example +import example + +a = example.Complex(2,3) +b = example.Complex(-5,10) + +print "a =",a +print "b =",b + +c = a + b +print "c =",c +print "a*b =",a*b +print "a-c =",a-c + +e = example.ComplexCopy(a-c) +print "e =",e + +# Big expression +f = ((a+b)*(c+b*e)) + (-a) +print "f =",f + diff --git a/Examples/python/overload_feature/.cvsignore b/Examples/python/overload_feature/.cvsignore new file mode 100644 index 000000000..572904d30 --- /dev/null +++ b/Examples/python/overload_feature/.cvsignore @@ -0,0 +1,2 @@ +example.py + diff --git a/Examples/python/pointer/.cvsignore b/Examples/python/pointer/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/pointer/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/pointer/Makefile b/Examples/python/pointer/Makefile index e495cfa9a..754c4a029 100644 --- a/Examples/python/pointer/Makefile +++ b/Examples/python/pointer/Makefile @@ -13,6 +13,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/pointer/example.i b/Examples/python/pointer/example.i index 2ed2b5bbf..4483b0f77 100644 --- a/Examples/python/pointer/example.i +++ b/Examples/python/pointer/example.i @@ -6,7 +6,8 @@ /* First we'll use the pointer library */ extern void add(int *x, int *y, int *result); -%include pointer.i +%include cpointer.i +%pointer_functions(int, intp); /* Next we'll use some typemaps */ diff --git a/Examples/python/pointer/example.py b/Examples/python/pointer/runme.py similarity index 75% rename from Examples/python/pointer/example.py rename to Examples/python/pointer/runme.py index c7363ab3a..1e405851e 100644 --- a/Examples/python/pointer/example.py +++ b/Examples/python/pointer/runme.py @@ -4,9 +4,11 @@ import example; # First create some objects using the pointer library. print "Testing the pointer library"; -a = example.ptrcreate("int",37); -b = example.ptrcreate("int",42); -c = example.ptrcreate("int"); +a = example.new_intp(); +b = example.new_intp(); +c = example.new_intp(); +example.intp_assign(a,37); +example.intp_assign(b,42); print " a =",a print " b =",b @@ -16,13 +18,13 @@ print " c =",c example.add(a,b,c) # Now get the result -r = example.ptrvalue(c) +r = example.intp_value(c) print " 37 + 42 =",r # Clean up the pointers -example.ptrfree(a) -example.ptrfree(b) -example.ptrfree(c) +example.delete_intp(a) +example.delete_intp(b) +example.delete_intp(c) # Now try the typemap library # This should be much easier. Now how it is no longer diff --git a/Examples/python/reference/.cvsignore b/Examples/python/reference/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/reference/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/reference/Makefile b/Examples/python/reference/Makefile index 71af176f9..19580883e 100644 --- a/Examples/python/reference/Makefile +++ b/Examples/python/reference/Makefile @@ -14,6 +14,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/reference/example.i b/Examples/python/reference/example.i index 8538326f6..5be92914f 100644 --- a/Examples/python/reference/example.i +++ b/Examples/python/reference/example.i @@ -8,6 +8,8 @@ #include "example.h" %} +%rename(cprint) print; + class Vector { public: Vector(double x, double y, double z); @@ -31,7 +33,7 @@ public: int size(); /* This wrapper provides an alternative to the [] operator */ - %addmethods { + %extend { Vector &get(int index) { return (*self)[index]; } diff --git a/Examples/python/reference/example.py b/Examples/python/reference/runme.py similarity index 58% rename from Examples/python/reference/example.py rename to Examples/python/reference/runme.py index dae49f181..10a2dee12 100644 --- a/Examples/python/reference/example.py +++ b/Examples/python/reference/runme.py @@ -8,11 +8,11 @@ import example # ----- Object creation ----- print "Creating some objects:" -a = example.new_Vector(3,4,5) -b = example.new_Vector(10,11,12) +a = example.Vector(3,4,5) +b = example.Vector(10,11,12) -print " Created",example.Vector_print(a) -print " Created",example.Vector_print(b) +print " Created",a.cprint() +print " Created",b.cprint() # ----- Call an overloaded operator ----- @@ -24,49 +24,41 @@ print " Created",example.Vector_print(b) print "Adding a+b" c = example.addv(a,b) -print " a+b =", example.Vector_print(c) +print " a+b =", c.cprint() # Note: Unless we free the result, a memory leak will occur -example.delete_Vector(c) +del c # ----- Create a vector array ----- # Note: Using the high-level interface here print "Creating an array of vectors" -va = example.new_VectorArray(10) +va = example.VectorArray(10) print " va = ",va # ----- Set some values in the array ----- # These operators copy the value of $a and $b to the vector array -example.VectorArray_set(va,0,a) -example.VectorArray_set(va,1,b) +va.set(0,a) +va.set(1,b) -# This will work, but it will cause a memory leak! - -example.VectorArray_set(va,2,example.addv(a,b)) - -# The non-leaky way to do it - -c = example.addv(a,b) -example.VectorArray_set(va,3,c) -example.delete_Vector(c) +va.set(2,example.addv(a,b)) # Get some values from the array print "Getting some array values" for i in range(0,5): - print " va(%d) = %s" % (i, example.Vector_print(example.VectorArray_get(va,i))) + print " va(%d) = %s" % (i, va.get(i).cprint()) # Watch under resource meter to check on this print "Making sure we don't leak memory." for i in xrange(0,1000000): - c = example.VectorArray_get(va,i % 10) + c = va.get(i % 10) # ----- Clean up ----- print "Cleaning up" -example.delete_VectorArray(va) -example.delete_Vector(a) -example.delete_Vector(b) +del va +del a +del b diff --git a/Examples/python/shadow/.cvsignore b/Examples/python/shadow/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/shadow/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/shadow/Makefile b/Examples/python/shadow/Makefile index 908edc992..343f04f54 100644 --- a/Examples/python/shadow/Makefile +++ b/Examples/python/shadow/Makefile @@ -1,19 +1,21 @@ TOP = ../.. -SWIG = $(TOP)/../swig -shadow +SWIG = $(TOP)/../swig CXXSRCS = example.cxx -TARGET = examplec +TARGET = example INTERFACE = example.i LIBS = -lm +SWIGOPT = all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp static:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/simple/.cvsignore b/Examples/python/simple/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/simple/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/simple/Makefile b/Examples/python/simple/Makefile index e495cfa9a..754c4a029 100644 --- a/Examples/python/simple/Makefile +++ b/Examples/python/simple/Makefile @@ -13,6 +13,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/simple/example.dsp b/Examples/python/simple/example.dsp new file mode 100644 index 000000000..9b0078861 --- /dev/null +++ b/Examples/python/simple/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -python $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo PYTHON_INCLUDE: %PYTHON_INCLUDE% + echo PYTHON_LIB: %PYTHON_LIB% + echo on + ..\..\..\swig -python $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/python/simple/example.py b/Examples/python/simple/runme.py similarity index 100% rename from Examples/python/simple/example.py rename to Examples/python/simple/runme.py diff --git a/Examples/python/smartptr/Makefile b/Examples/python/smartptr/Makefile new file mode 100644 index 000000000..343f04f54 --- /dev/null +++ b/Examples/python/smartptr/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/smartptr/example.cxx b/Examples/python/smartptr/example.cxx new file mode 100644 index 000000000..21582f4d1 --- /dev/null +++ b/Examples/python/smartptr/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#include + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area() { + return M_PI*radius*radius; +} + +double Circle::perimeter() { + return 2*M_PI*radius; +} + +double Square::area() { + return width*width; +} + +double Square::perimeter() { + return 4*width; +} diff --git a/Examples/python/smartptr/example.h b/Examples/python/smartptr/example.h new file mode 100644 index 000000000..c0f9b1d57 --- /dev/null +++ b/Examples/python/smartptr/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area() = 0; + virtual double perimeter() = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(); + virtual double perimeter(); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(); + virtual double perimeter(); +}; + + + + + diff --git a/Examples/python/smartptr/example.i b/Examples/python/smartptr/example.i new file mode 100644 index 000000000..83da4f144 --- /dev/null +++ b/Examples/python/smartptr/example.i @@ -0,0 +1,20 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +#include "smartptr.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Grab smart pointer template */ + +%include "smartptr.h" + +/* Instantiate smart-pointers */ + +%template(ShapePtr) SmartPtr; + + diff --git a/Examples/python/smartptr/runme.py b/Examples/python/smartptr/runme.py new file mode 100644 index 000000000..15e5232e2 --- /dev/null +++ b/Examples/python/smartptr/runme.py @@ -0,0 +1,55 @@ +# file: runme.py + +# This file illustrates the shadow-class C++ interface generated +# by SWIG. + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +cc = example.Circle(10) +c = example.ShapePtr(cc) +print " Created circle", c +ss = example.Square(10) +s = example.ShapePtr(ss) +print " Created square", s + +# ----- Access a static member ----- + +print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" + +# ----- Member data access ----- + +# Set the location of the object + +c.x = 20 +c.y = 30 + +s.x = -10 +s.y = 5 + +print "\nHere is their current position:" +print " Circle = (%f, %f)" % (c.x,c.y) +print " Square = (%f, %f)" % (s.x,s.y) + +# ----- Call some methods ----- + +print "\nHere are some properties of the shapes:" +for o in [c,s]: + print " ", o + print " area = ", o.area() + print " perimeter = ", o.perimeter() + +print "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +del c +del s +del cc +del ss + +s = 3 +print example.cvar.Shape_nshapes,"shapes remain" +print "Goodbye" + diff --git a/Examples/python/smartptr/smartptr.h b/Examples/python/smartptr/smartptr.h new file mode 100644 index 000000000..2ffa1ca0e --- /dev/null +++ b/Examples/python/smartptr/smartptr.h @@ -0,0 +1,13 @@ +template class SmartPtr { +public: + SmartPtr(T *realPtr = 0) { pointee = realPtr; } + T *operator->() const { + return pointee; + } + T &operator*() const { + return *pointee; + } +private: + T *pointee; +}; + diff --git a/Examples/python/std_vector/.cvsignore b/Examples/python/std_vector/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/std_vector/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/std_vector/Makefile b/Examples/python/std_vector/Makefile new file mode 100644 index 000000000..f00af7dba --- /dev/null +++ b/Examples/python/std_vector/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/std_vector/example.h b/Examples/python/std_vector/example.h new file mode 100644 index 000000000..4f0dac70d --- /dev/null +++ b/Examples/python/std_vector/example.h @@ -0,0 +1,25 @@ +/* File : example.h */ + +#include +#include +#include +#include + +double average(std::vector v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector half(const std::vector& v) { + std::vector w(v); + for (unsigned int i=0; i& v) { + // would you believe this is the same as the above? + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides(),2.0)); +} + + diff --git a/Examples/python/std_vector/example.i b/Examples/python/std_vector/example.i new file mode 100644 index 000000000..aa58b66e0 --- /dev/null +++ b/Examples/python/std_vector/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include stl.i +/* instantiate the required template specializations */ +namespace std { + %template(IntVector) vector; + %template(DoubleVector) vector; +} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/python/std_vector/runme.py b/Examples/python/std_vector/runme.py new file mode 100644 index 000000000..d248ccbbb --- /dev/null +++ b/Examples/python/std_vector/runme.py @@ -0,0 +1,36 @@ +# file: runme.py + +import example + +# Call average with a Python list... + +print example.average([1,2,3,4]) + +# ... or a wrapped std::vector + +v = example.IntVector(4) +for i in range(len(v)): + v[i] = i+1 +print example.average(v) + + +# half will return a Python list. +# Call it with a Python tuple... + +print example.half((1.0, 1.5, 2.0, 2.5, 3.0)) + +# ... or a wrapped std::vector + +v = example.DoubleVector() +for i in [1,2,3,4]: + v.append(i) +print example.half(v) + + +# now halve a wrapped std::vector in place + +example.halve_in_place(v) +for i in range(len(v)): + print v[i], "; ", +print + diff --git a/Examples/python/template/.cvsignore b/Examples/python/template/.cvsignore new file mode 100644 index 000000000..d29d3bb46 --- /dev/null +++ b/Examples/python/template/.cvsignore @@ -0,0 +1,10 @@ +example.py +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/template/Makefile b/Examples/python/template/Makefile new file mode 100644 index 000000000..f00af7dba --- /dev/null +++ b/Examples/python/template/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/template/example.h b/Examples/python/template/example.h new file mode 100644 index 000000000..4d9a58c54 --- /dev/null +++ b/Examples/python/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return self->get(index); + } + void setitem(int index, T val) { + self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/python/template/example.i b/Examples/python/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/python/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/python/template/runme.py b/Examples/python/template/runme.py new file mode 100644 index 000000000..05940bc67 --- /dev/null +++ b/Examples/python/template/runme.py @@ -0,0 +1,34 @@ +# file: runme.py + +import example + +# Call some templated functions +print example.maxint(3,7) +print example.maxdouble(3.14,2.18) + +# Create some class + +iv = example.vecint(100) +dv = example.vecdouble(1000) + +for i in range(0,100): + iv.setitem(i,2*i) + +for i in range(0,1000): + dv.setitem(i, 1.0/(i+1)) + +sum = 0 +for i in range(0,100): + sum = sum + iv.getitem(i) + +print sum + +sum = 0.0 +for i in range(0,1000): + sum = sum + dv.getitem(i) +print sum + +del iv +del dv + + diff --git a/Examples/python/value/.cvsignore b/Examples/python/value/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/value/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/value/Makefile b/Examples/python/value/Makefile index e495cfa9a..754c4a029 100644 --- a/Examples/python/value/Makefile +++ b/Examples/python/value/Makefile @@ -13,6 +13,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/varargs/Makefile b/Examples/python/varargs/Makefile new file mode 100644 index 000000000..5b726c2b1 --- /dev/null +++ b/Examples/python/varargs/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all diff --git a/Examples/python/varargs/example.i b/Examples/python/varargs/example.i new file mode 100644 index 000000000..323bb82ee --- /dev/null +++ b/Examples/python/varargs/example.i @@ -0,0 +1,65 @@ +/* File : example.i */ +%module example + +%{ +#include +%} + +/* This example illustrates SWIG's handling of varargs functions. + By default, variable length arguments are simply ignored. This + is generally appropriate for wrapping I/O functions like printf. + You can simply format a string in the scripting language, and + pass it directly */ + +int printf(const char *fmt, ...); + +/* Since passing a format string might be dangerous. Here is a slightly + different way of wrapping a printf style function */ + +#if 1 +/* Replace ... with char *. */ +%varargs(char *) fprintf; + +/* Ignore the format string, but set it to %s */ +%typemap(ignore) const char *fmt { + $1 = "%s"; +} +#else +/* An alternative approach using typemaps */ +%typemap(in) (const char *fmt, ...) { + $1 = "%s"; + $2 = (void *) PyString_AsString($input); +} +#endif + +/* Typemap just to make the example work */ +%typemap(in) FILE * "$1 = PyFile_AsFile($input);"; + +int fprintf(FILE *, const char *fmt, ...); + +/* Here is somewhat different example. A variable length argument + function that takes a NULL-terminated list of arguments. We + can use a slightly different form of %varargs that specifies + a default value and a maximum number of arguments. + */ + +/* Maximum of 20 arguments with default value NULL */ + +%varargs(20, char *x = NULL) printv; + +%inline %{ +void printv(char *s, ...) { + va_list ap; + char *x; + fputs(s,stdout); + fputc(' ',stdout); + va_start(ap, s); + while ((x = va_arg(ap, char *))) { + fputs(x,stdout); + fputc(' ',stdout); + } + va_end(ap); + fputc('\n',stdout); +} +%} + diff --git a/Examples/python/varargs/runme.py b/Examples/python/varargs/runme.py new file mode 100644 index 000000000..c79b8b120 --- /dev/null +++ b/Examples/python/varargs/runme.py @@ -0,0 +1,34 @@ +# file: example.py + +import sys +import example + +# Call printf +example.printf("Hello World. I'm printf\n") + +# Note: We call printf, but use *python* string formatting +for i in range(0,10): + example.printf("i is %d\n" % i) + +# This will probably be garbled because %d is interpreted by C +example.printf("The value is %d\n") + +# Call fprintf +example.fprintf(sys.stdout,"Hello World. I'm fprintf\n") +for i in range(0,10): + example.fprintf(sys.stdout,"i is %d\n" % i) + +# This won't be garbled since %d is not interpreted +example.fprintf(sys.stdout,"The value is %d\n") + +# This function calls our NULL-terminated function + +example.printv("Hello","World","this","is","a","test.") + + + + + + + + diff --git a/Examples/python/variables/.cvsignore b/Examples/python/variables/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/python/variables/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/python/variables/Makefile b/Examples/python/variables/Makefile index e495cfa9a..754c4a029 100644 --- a/Examples/python/variables/Makefile +++ b/Examples/python/variables/Makefile @@ -13,6 +13,7 @@ static:: TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: - rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py check: all diff --git a/Examples/python/variables/example.i b/Examples/python/variables/example.i index 35eafc2c0..91bd0679d 100644 --- a/Examples/python/variables/example.i +++ b/Examples/python/variables/example.i @@ -27,10 +27,10 @@ extern Point pt; /* Some read-only variables */ -%readonly { +%immutable; extern int status; extern char path[256]; -} +%mutable; /* Some helper functions to make it easier to test */ extern void print_vars(); diff --git a/Examples/python/variables/index.html b/Examples/python/variables/index.html index 12cacbf64..3bdf705f5 100644 --- a/Examples/python/variables/index.html +++ b/Examples/python/variables/index.html @@ -69,21 +69,21 @@ Getting the "value" returns a pointer to the global variable. Setting the value

    Creating read-only variables

    -The %readonly and %readwrite directives can be used to +The %immutable and %mutable directives can be used to specify a collection of read-only variables. For example:
    -%readonly
    +%immutable;
     int    status;
     double blah;
     ...
    -%readwrite
    +%mutable;
     
    -The %readonly directive remains in effect until it is explicitly disabled -using the %readwrite directive. +The %immutable directive remains in effect until it is explicitly disabled +using the %mutable directive.

    Comments

      diff --git a/Examples/python/variables/example.py b/Examples/python/variables/runme.py similarity index 100% rename from Examples/python/variables/example.py rename to Examples/python/variables/runme.py diff --git a/Examples/ruby/check.list b/Examples/ruby/check.list new file mode 100644 index 000000000..2041cd5c4 --- /dev/null +++ b/Examples/ruby/check.list @@ -0,0 +1,21 @@ +# see top-level Makefile.in +class +constants +enum +funcptr +funcptr2 +functor +hashargs +import +template +mpointer +multimap +operator +overloading +pointer +reference +simple +std_vector +template +value +variables diff --git a/Examples/ruby/class/.cvsignore b/Examples/ruby/class/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/class/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/class/Makefile b/Examples/ruby/class/Makefile index 01ce757ff..ab8928c0e 100644 --- a/Examples/ruby/class/Makefile +++ b/Examples/ruby/class/Makefile @@ -14,6 +14,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/class/example.cxx b/Examples/ruby/class/example.cxx index 21582f4d1..1e8e203dd 100644 --- a/Examples/ruby/class/example.cxx +++ b/Examples/ruby/class/example.cxx @@ -1,7 +1,7 @@ /* File : example.c */ #include "example.h" -#include +#define M_PI 3.14159265358979323846 /* Move the shape to a new location */ void Shape::move(double dx, double dy) { @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area() { +double Circle::area(void) { return M_PI*radius*radius; } -double Circle::perimeter() { +double Circle::perimeter(void) { return 2*M_PI*radius; } -double Square::area() { +double Square::area(void) { return width*width; } -double Square::perimeter() { +double Square::perimeter(void) { return 4*width; } diff --git a/Examples/ruby/class/example.dsp b/Examples/ruby/class/example.dsp new file mode 100644 index 000000000..d6afbb8b5 --- /dev/null +++ b/Examples/ruby/class/example.dsp @@ -0,0 +1,154 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(RUBY_INCLUDE)" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(RUBY_LIB)" /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept /EXPORT:Init_example +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(RUBY_INCLUDE)" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(RUBY_LIB)" /nologo /dll /machine:I386 /out:"example.dll" /EXPORT:Init_example +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.cxx +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\example.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo RUBY_INCLUDE: %RUBY_INCLUDE% + echo RUBY_LIB: %RUBY_LIB% + echo on + ..\..\..\swig -c++ -ruby $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo RUBY_INCLUDE: %RUBY_INCLUDE% + echo RUBY_LIB: %RUBY_LIB% + echo on + ..\..\..\swig -c++ -ruby $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/ruby/class/example.h b/Examples/ruby/class/example.h index c0f9b1d57..46d901361 100644 --- a/Examples/ruby/class/example.h +++ b/Examples/ruby/class/example.h @@ -10,8 +10,8 @@ public: }; double x, y; void move(double dx, double dy); - virtual double area() = 0; - virtual double perimeter() = 0; + virtual double area(void) = 0; + virtual double perimeter(void) = 0; static int nshapes; }; @@ -20,17 +20,17 @@ private: double radius; public: Circle(double r) : radius(r) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; - + class Square : public Shape { private: double width; public: Square(double w) : width(w) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; diff --git a/Examples/ruby/class/index.html b/Examples/ruby/class/index.html index 5e8e8c852..381bbd4f8 100644 --- a/Examples/ruby/class/index.html +++ b/Examples/ruby/class/index.html @@ -188,29 +188,9 @@ to write a helper function. For example:

    • Namespaces. Not supported at all. Won't be supported until SWIG2.0 (if at all). -

      -

    • Templates. Not supported at all. SWIG throws out anything that looks like a template. -You can work around the problem by aliasing a template class behind a typedef however. -For example: - -
      -
      -%{
      -typedef vector IntVector;
      -%}
      -
      -class IntVector {
      -public:
      -    ... methods ...
      -};
      -
      -

    -

  • There is no guarantee that an extremely complex C++ application will be able to compile -as a Ruby extension. Sorry. -

  • Dave's snide remark: Like a large bottle of strong Tequilla, it's better to use C++ in moderation. diff --git a/Examples/ruby/constants/.cvsignore b/Examples/ruby/constants/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/constants/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/constants/Makefile b/Examples/ruby/constants/Makefile index f6ec694b7..0dcb02f0d 100644 --- a/Examples/ruby/constants/Makefile +++ b/Examples/ruby/constants/Makefile @@ -13,6 +13,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/constants/example.i b/Examples/ruby/constants/example.i index 29a1a7f11..14eb23cad 100644 --- a/Examples/ruby/constants/example.i +++ b/Examples/ruby/constants/example.i @@ -19,8 +19,9 @@ /* Neither should this (BAR isn't defined) */ #define FOO (ICONST + BAR) -/* The following statements also produce constants */ -const int iconst = 37; -const double fconst = 3.14; +/* The following directives also produce constants */ + +%constant int Iconst = 37; +%constant double Fconst = 3.14; diff --git a/Examples/ruby/constants/run.rb b/Examples/ruby/constants/runme.rb old mode 100644 new mode 100755 similarity index 100% rename from Examples/ruby/constants/run.rb rename to Examples/ruby/constants/runme.rb diff --git a/Examples/ruby/enum/.cvsignore b/Examples/ruby/enum/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/enum/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/enum/Makefile b/Examples/ruby/enum/Makefile index 01ce757ff..ab8928c0e 100644 --- a/Examples/ruby/enum/Makefile +++ b/Examples/ruby/enum/Makefile @@ -14,6 +14,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/funcptr/.cvsignore b/Examples/ruby/funcptr/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/funcptr/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/funcptr/Makefile b/Examples/ruby/funcptr/Makefile index cd0fdf300..0a59614c4 100644 --- a/Examples/ruby/funcptr/Makefile +++ b/Examples/ruby/funcptr/Makefile @@ -13,6 +13,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/funcptr/example.i b/Examples/ruby/funcptr/example.i index 73cc6eb8c..39390da27 100644 --- a/Examples/ruby/funcptr/example.i +++ b/Examples/ruby/funcptr/example.i @@ -8,8 +8,8 @@ extern int do_op(int a, int b, int (*op)(int, int)); /* Now install a bunch of "ops" as constants */ -%constant(int (*)(int,int)) ADD = add; -%constant(int (*)(int,int)) SUB = sub; -%constant(int (*)(int,int)) MUL = mul; +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; diff --git a/Examples/ruby/funcptr2/.cvsignore b/Examples/ruby/funcptr2/.cvsignore new file mode 100644 index 000000000..c50c39e9f --- /dev/null +++ b/Examples/ruby/funcptr2/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +*.dll +*.dsw +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/ruby/funcptr2/Makefile b/Examples/ruby/funcptr2/Makefile new file mode 100644 index 000000000..0a59614c4 --- /dev/null +++ b/Examples/ruby/funcptr2/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/funcptr2/example.c b/Examples/ruby/funcptr2/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/Examples/ruby/funcptr2/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/ruby/funcptr2/example.h b/Examples/ruby/funcptr2/example.h new file mode 100644 index 000000000..58989db79 --- /dev/null +++ b/Examples/ruby/funcptr2/example.h @@ -0,0 +1,7 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + diff --git a/Examples/ruby/funcptr2/example.i b/Examples/ruby/funcptr2/example.i new file mode 100644 index 000000000..81a66146a --- /dev/null +++ b/Examples/ruby/funcptr2/example.i @@ -0,0 +1,18 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%callback("%(upper)s") +int add(int, int); +int sub(int, int); +int mul(int, int); +%nocallback + +extern int (*funcvar)(int,int); + diff --git a/Examples/ruby/funcptr2/runme.rb b/Examples/ruby/funcptr2/runme.rb new file mode 100644 index 000000000..9a2f65166 --- /dev/null +++ b/Examples/ruby/funcptr2/runme.rb @@ -0,0 +1,18 @@ +require 'example' + +a = 37 +b = 42 + +# Now call our C function with a bunch of callbacks + +puts "Trying some C callback functions" +puts " a = #{a}" +puts " b = #{b}" +puts " ADD(a,b) = #{Example.do_op(a,b,Example::ADD)}" +puts " SUB(a,b) = #{Example.do_op(a,b,Example::SUB)}" +puts " MUL(a,b) = #{Example.do_op(a,b,Example::MUL)}" + +puts "Here is what the C callback function objects look like in Ruby" +puts " ADD = #{Example::ADD}" +puts " SUB = #{Example::SUB}" +puts " MUL = #{Example::MUL}" diff --git a/Examples/ruby/functor/.cvsignore b/Examples/ruby/functor/.cvsignore new file mode 100644 index 000000000..f0cef3048 --- /dev/null +++ b/Examples/ruby/functor/.cvsignore @@ -0,0 +1,2 @@ +example_wrap.cxx +example.dll diff --git a/Examples/ruby/functor/Makefile b/Examples/ruby/functor/Makefile new file mode 100644 index 000000000..bac6f4dd3 --- /dev/null +++ b/Examples/ruby/functor/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/functor/example.i b/Examples/ruby/functor/example.i new file mode 100644 index 000000000..903c9786c --- /dev/null +++ b/Examples/ruby/functor/example.i @@ -0,0 +1,26 @@ +/* File : example.i */ +%module example + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +/** + * Rename the application operator to call() for Ruby. + * Note: this is normally automatic, but if you had to do it yourself + * you would use this directive: + * + * %rename(call) *::operator(); + */ + +// Instantiate a few versions +%template(IntSum) Sum; +%template(DoubleSum) Sum; diff --git a/Examples/ruby/functor/runme.rb b/Examples/ruby/functor/runme.rb new file mode 100644 index 000000000..3f78dcecc --- /dev/null +++ b/Examples/ruby/functor/runme.rb @@ -0,0 +1,17 @@ +# Operator overloading example +require 'example' + +a = Example::IntSum.new(0) +b = Example::DoubleSum.new(100.0) + +# Use the objects. They should be callable just like a normal +# Ruby function. + +(0..100).each do |i| + a.call(i) # note: function call + b.call(Math.sqrt(i)) # note: function call +end + +puts a.result +puts b.result + diff --git a/Examples/ruby/hashargs/.cvsignore b/Examples/ruby/hashargs/.cvsignore new file mode 100644 index 000000000..11550eb76 --- /dev/null +++ b/Examples/ruby/hashargs/.cvsignore @@ -0,0 +1 @@ +example_wrap.c diff --git a/Examples/ruby/hashargs/Makefile b/Examples/ruby/hashargs/Makefile new file mode 100755 index 000000000..4da07722f --- /dev/null +++ b/Examples/ruby/hashargs/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/hashargs/example.i b/Examples/ruby/hashargs/example.i new file mode 100755 index 000000000..159bbd32a --- /dev/null +++ b/Examples/ruby/hashargs/example.i @@ -0,0 +1,36 @@ +%module example + +%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_ary, int i, VALUE key, VALUE val) { + Check_Type($input, T_HASH); + $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL)); + $2 = NULL; + $3 = NULL; + if ($1 > 0) { + $2 = (char **) malloc($1*sizeof(char *)); + $3 = (int *) malloc($1*sizeof(int)); + keys_ary = rb_funcall($input, rb_intern("keys"), 0, NULL); + for (i = 0; i < $1; i++) { + key = rb_ary_entry(keys_ary, i); + val = rb_hash_aref($input, key); + Check_Type(key, T_STRING); + Check_Type(val, T_FIXNUM); + $2[i] = STR2CSTR(key); + $3[i] = NUM2INT(val); + } + } +} + +%typemap(freearg) (int nattributes, const char **names, const int *values) { + free((void *) $2); + free((void *) $3); +} + +%inline %{ +void setVitalStats(const char *person, int nattributes, const char **names, const int *values) { + int i; + printf("Name: %s\n", person); + for (i = 0; i < nattributes; i++) { + printf(" %s => %d\n", names[i], values[i]); + } +} +%} diff --git a/Examples/ruby/hashargs/runme.rb b/Examples/ruby/hashargs/runme.rb new file mode 100755 index 000000000..0b06f6934 --- /dev/null +++ b/Examples/ruby/hashargs/runme.rb @@ -0,0 +1,26 @@ +require 'example' + +include Example + +# Pass arguments in as one or more key-value pairs +setVitalStats("Fred", + 'age' => 42, + 'weight' => 270 + ) + +# The order doesn't matter +setVitalStats("Sally", + 'age' => 29, + 'weight' => 115, + 'height' => 72 + ) + +# Can also pass a hash directly +params = { + 'ears' => 2, + 'eyes' => 2 +} +setVitalStats("Bob", params) + +# An empty hash is fine too +setVitalStats("Joe", {}) diff --git a/Examples/ruby/import/.cvsignore b/Examples/ruby/import/.cvsignore new file mode 100644 index 000000000..02f077192 --- /dev/null +++ b/Examples/ruby/import/.cvsignore @@ -0,0 +1,4 @@ +bar_wrap.cxx +base_wrap.cxx +foo_wrap.cxx +spam_wrap.cxx diff --git a/Examples/ruby/import/Makefile b/Examples/ruby/import/Makefile new file mode 100644 index 000000000..68151eba1 --- /dev/null +++ b/Examples/ruby/import/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SWIGOPT = -c +#If your system requires linking with the runtime libraries then set the directory location here +RUNTIMEDIR = /usr/local/lib + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='base' INTERFACE='base.i' ruby_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' ruby_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' ruby_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' ruby_multi_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/import/README b/Examples/ruby/import/README new file mode 100644 index 000000000..0d18a2513 --- /dev/null +++ b/Examples/ruby/import/README @@ -0,0 +1,28 @@ +This example tests the SWIG run-time libraries and use of the +%import directive to work with multiple modules. + +Use 'ruby runme.rb' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module used %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is working correctly, all of the modules will load +correctly and type checking will work correctly. The +example requires the use of the SWIG run-time libraries +which must be built and properly installed. + + + + diff --git a/Examples/ruby/import/bar.h b/Examples/ruby/import/bar.h new file mode 100644 index 000000000..1c99f28e6 --- /dev/null +++ b/Examples/ruby/import/bar.h @@ -0,0 +1,21 @@ +#include "base.h" + +class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual const char * A() const { + return "Bar::A"; + } + const char * B() const { + return "Bar::B"; + } + virtual Base *toBase() { + return static_cast(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/ruby/import/bar.i b/Examples/ruby/import/bar.i new file mode 100644 index 000000000..5816cbe17 --- /dev/null +++ b/Examples/ruby/import/bar.i @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + diff --git a/Examples/ruby/import/base.h b/Examples/ruby/import/base.h new file mode 100644 index 000000000..44f98f747 --- /dev/null +++ b/Examples/ruby/import/base.h @@ -0,0 +1,16 @@ +class Base { + public: + Base() { }; + ~Base() { }; + virtual const char * A() const { + return "Base::A"; + } + const char * B() const { + return "Base::B"; + } + virtual Base *toBase() { + return static_cast(this); + } +}; + + diff --git a/Examples/ruby/import/base.i b/Examples/ruby/import/base.i new file mode 100644 index 000000000..f6e19efd8 --- /dev/null +++ b/Examples/ruby/import/base.i @@ -0,0 +1,6 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h diff --git a/Examples/ruby/import/foo.h b/Examples/ruby/import/foo.h new file mode 100644 index 000000000..1abe2c0d8 --- /dev/null +++ b/Examples/ruby/import/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual const char * A() const { + return "Foo::A"; + } + const char * B() const { + return "Foo::B"; + } + virtual Base *toBase() { + return static_cast(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/ruby/import/foo.i b/Examples/ruby/import/foo.i new file mode 100644 index 000000000..27feb2e6a --- /dev/null +++ b/Examples/ruby/import/foo.i @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + diff --git a/Examples/ruby/import/runme.rb b/Examples/ruby/import/runme.rb new file mode 100644 index 000000000..32ca482d6 --- /dev/null +++ b/Examples/ruby/import/runme.rb @@ -0,0 +1,90 @@ +# file: runme.rb +# Test various properties of classes defined in separate modules + +puts "Testing the %import directive" + +require 'base' +require 'foo' +require 'bar' +require 'spam' + +# Create some objects + +puts "Creating some objects" + +a = Base::Base.new +b = Foo::Foo.new +c = Bar::Bar.new +d = Spam::Spam.new + +# Try calling some methods +puts "Testing some methods" +puts "Should see 'Base::A' ---> #{a.A}" +puts "Should see 'Base::B' ---> #{a.B}" + +puts "Should see 'Foo::A' ---> #{b.A}" +puts "Should see 'Foo::B' ---> #{b.B}" + +puts "Should see 'Bar::A' ---> #{c.A}" +puts "Should see 'Bar::B' ---> #{c.B}" + +puts "Should see 'Spam::A' ---> #{d.A}" +puts "Should see 'Spam::B' ---> #{d.B}" + +# Try some casts + +puts "\nTesting some casts\n" + +x = a.toBase +puts "Should see 'Base::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = b.toBase +puts "Should see 'Foo::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = c.toBase +puts "Should see 'Bar::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = d.toBase +puts "Should see 'Spam::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = d.toBar +puts "Should see 'Bar::B' ---> #{x.B}" + +puts "\nTesting some dynamic casts\n" +x = d.toBase + +puts " Spam -> Base -> Foo : " +y = Foo::Foo.fromBase(x) +if y != nil + puts "bad swig" +else + puts "good swig" +end + +puts " Spam -> Base -> Bar : " +y = Bar::Bar.fromBase(x) +if y != nil + puts "good swig" +else + puts "bad swig" +end + +puts " Spam -> Base -> Spam : " +y = Spam::Spam.fromBase(x) +if y != nil + puts "good swig" +else + puts "bad swig" +end + +puts " Foo -> Spam : " +y = Spam::Spam.fromBase(b) +if y != nil + puts "bad swig" +else + puts "good swig" +end diff --git a/Examples/ruby/import/spam.h b/Examples/ruby/import/spam.h new file mode 100644 index 000000000..57db84563 --- /dev/null +++ b/Examples/ruby/import/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual const char * A() const { + return "Spam::A"; + } + const char * B() const { + return "Spam::B"; + } + virtual Base *toBase() { + return static_cast(this); + } + virtual Bar *toBar() { + return static_cast(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/ruby/import/spam.i b/Examples/ruby/import/spam.i new file mode 100644 index 000000000..d3d9121db --- /dev/null +++ b/Examples/ruby/import/spam.i @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + diff --git a/Examples/ruby/import_template/.cvsignore b/Examples/ruby/import_template/.cvsignore new file mode 100644 index 000000000..02f077192 --- /dev/null +++ b/Examples/ruby/import_template/.cvsignore @@ -0,0 +1,4 @@ +bar_wrap.cxx +base_wrap.cxx +foo_wrap.cxx +spam_wrap.cxx diff --git a/Examples/ruby/import_template/Makefile b/Examples/ruby/import_template/Makefile new file mode 100644 index 000000000..68151eba1 --- /dev/null +++ b/Examples/ruby/import_template/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SWIGOPT = -c +#If your system requires linking with the runtime libraries then set the directory location here +RUNTIMEDIR = /usr/local/lib + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='base' INTERFACE='base.i' ruby_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' ruby_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' ruby_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' ruby_multi_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/import_template/README b/Examples/ruby/import_template/README new file mode 100644 index 000000000..53c9f8309 --- /dev/null +++ b/Examples/ruby/import_template/README @@ -0,0 +1,30 @@ +This example tests the SWIG run-time libraries and use of the +%import directive to work with multiple modules. However, +unlike the import example, this uses templates to really +stress test the type-system. + +Use 'ruby runme.rb' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module used %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is working correctly, all of the modules will load +correctly and type checking will work correctly. The +example requires the use of the SWIG run-time libraries +which must be built and properly installed. + + + + diff --git a/Examples/ruby/import_template/bar.h b/Examples/ruby/import_template/bar.h new file mode 100644 index 000000000..1aa907dfc --- /dev/null +++ b/Examples/ruby/import_template/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +template class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual const char * A() const { + return "Bar::A"; + } + const char * B() const { + return "Bar::B"; + } + virtual Base *toBase() { + return static_cast *>(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast *>(b); + } + +}; + + diff --git a/Examples/ruby/import_template/bar.i b/Examples/ruby/import_template/bar.i new file mode 100644 index 000000000..357de0db9 --- /dev/null +++ b/Examples/ruby/import_template/bar.i @@ -0,0 +1,11 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + +%template(IntBar) Bar; + + diff --git a/Examples/ruby/import_template/base.h b/Examples/ruby/import_template/base.h new file mode 100644 index 000000000..4302aeda2 --- /dev/null +++ b/Examples/ruby/import_template/base.h @@ -0,0 +1,18 @@ +#include + +template class Base { + public: + Base() { }; + ~Base() { }; + virtual const char * A() const { + return "Base::A"; + } + const char * B() const { + return "Base::B"; + } + virtual Base *toBase() { + return static_cast *>(this); + } +}; + + diff --git a/Examples/ruby/import_template/base.i b/Examples/ruby/import_template/base.i new file mode 100644 index 000000000..bcf1a5f7d --- /dev/null +++ b/Examples/ruby/import_template/base.i @@ -0,0 +1,7 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h +%template(IntBase) Base; diff --git a/Examples/ruby/import_template/foo.h b/Examples/ruby/import_template/foo.h new file mode 100644 index 000000000..626257462 --- /dev/null +++ b/Examples/ruby/import_template/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +template class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual const char * A() const { + return "Foo::A"; + } + const char * B() const { + return "Foo::B"; + } + virtual Base *toBase() { + return static_cast *>(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast *>(b); + } +}; + + diff --git a/Examples/ruby/import_template/foo.i b/Examples/ruby/import_template/foo.i new file mode 100644 index 000000000..37e655ea2 --- /dev/null +++ b/Examples/ruby/import_template/foo.i @@ -0,0 +1,10 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + +%template(IntFoo) Foo; + diff --git a/Examples/ruby/import_template/runme.rb b/Examples/ruby/import_template/runme.rb new file mode 100644 index 000000000..b9ca19f77 --- /dev/null +++ b/Examples/ruby/import_template/runme.rb @@ -0,0 +1,92 @@ +# file: runme.rb +# Test various properties of classes defined in separate modules + +puts "Testing the %import directive with templates" + +require 'base' +require 'foo' +require 'bar' +require 'spam' + +# Create some objects + +puts "Creating some objects" + +a = Base::IntBase.new +b = Foo::IntFoo.new +c = Bar::IntBar.new +d = Spam::IntSpam.new + +# Try calling some methods +puts "Testing some methods" +puts "" +puts "Should see 'Base::A' ---> #{a.A}" +puts "Should see 'Base::B' ---> #{a.B}" + +puts "Should see 'Foo::A' ---> #{b.A}" +puts "Should see 'Foo::B' ---> #{b.B}" + +puts "Should see 'Bar::A' ---> #{c.A}" +puts "Should see 'Bar::B' ---> #{c.B}" + +puts "Should see 'Spam::A' ---> #{d.A}" +puts "Should see 'Spam::B' ---> #{d.B}" + +# Try some casts + +puts "\nTesting some casts\n" +puts "" + +x = a.toBase +puts "Should see 'Base::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = b.toBase +puts "Should see 'Foo::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = c.toBase +puts "Should see 'Bar::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = d.toBase +puts "Should see 'Spam::A' ---> #{x.A}" +puts "Should see 'Base::B' ---> #{x.B}" + +x = d.toBar +puts "Should see 'Bar::B' ---> #{x.B}" + +puts "\nTesting some dynamic casts\n" +x = d.toBase + +puts " Spam -> Base -> Foo : " +y = Foo::IntFoo.fromBase(x) +if y != nil + puts "bad swig" +else + puts "good swig" +end + +puts " Spam -> Base -> Bar : " +y = Bar::IntBar.fromBase(x) +if y != nil + puts "good swig" +else + puts "bad swig" +end + +puts " Spam -> Base -> Spam : " +y = Spam::IntSpam.fromBase(x) +if y != nil + puts "good swig" +else + puts "bad swig" +end + +puts " Foo -> Spam : " +y = Spam::IntSpam.fromBase(b) +if y != nil + puts "bad swig" +else + puts "good swig" +end diff --git a/Examples/ruby/import_template/spam.h b/Examples/ruby/import_template/spam.h new file mode 100644 index 000000000..a27b08829 --- /dev/null +++ b/Examples/ruby/import_template/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +template class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual const char * A() const { + return "Spam::A"; + } + const char * B() const { + return "Spam::B"; + } + virtual Base *toBase() { + return static_cast *>(this); + } + virtual Bar *toBar() { + return static_cast *>(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast *>(b); + } +}; + + diff --git a/Examples/ruby/import_template/spam.i b/Examples/ruby/import_template/spam.i new file mode 100644 index 000000000..ff0ca113e --- /dev/null +++ b/Examples/ruby/import_template/spam.i @@ -0,0 +1,10 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + +%template(IntSpam) Spam; + diff --git a/Examples/ruby/index.html b/Examples/ruby/index.html index 19d34d8c3..e6c752f1e 100644 --- a/Examples/ruby/index.html +++ b/Examples/ruby/index.html @@ -36,7 +36,11 @@ certain C declarations are turned into constants. -
  • The compilation of examples is done using the file Example/Makefile. This +
  • +Please see the Windows page in the main manual for information on using the examples on Windows.

    +

  • + +
  • On Unix the compilation of examples is done using the file Example/Makefile. This makefile performs a manual module compilation which is platform specific. Typically, the steps look like this (Linux): diff --git a/Examples/ruby/mpointer/.cvsignore b/Examples/ruby/mpointer/.cvsignore new file mode 100644 index 000000000..f0cef3048 --- /dev/null +++ b/Examples/ruby/mpointer/.cvsignore @@ -0,0 +1,2 @@ +example_wrap.cxx +example.dll diff --git a/Examples/ruby/mpointer/Makefile b/Examples/ruby/mpointer/Makefile new file mode 100644 index 000000000..27cb6d6bd --- /dev/null +++ b/Examples/ruby/mpointer/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/mpointer/example.cxx b/Examples/ruby/mpointer/example.cxx new file mode 100644 index 000000000..1a6bb666a --- /dev/null +++ b/Examples/ruby/mpointer/example.cxx @@ -0,0 +1,45 @@ +/* File : example.c */ + +#include "example.h" +#include + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} + +double do_op(Shape *s, double (Shape::*m)(void)) { + return (s->*m)(); +} + +double (Shape::*areapt())(void) { + return &Shape::area; +} + +double (Shape::*perimeterpt())(void) { + return &Shape::perimeter; +} + +/* Member pointer variables */ +double (Shape::*areavar)(void) = &Shape::area; +double (Shape::*perimetervar)(void) = &Shape::perimeter; + diff --git a/Examples/ruby/mpointer/example.h b/Examples/ruby/mpointer/example.h new file mode 100644 index 000000000..b90e14353 --- /dev/null +++ b/Examples/ruby/mpointer/example.h @@ -0,0 +1,47 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + double *z; + + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +extern double do_op(Shape *s, double (Shape::*m)(void)); + +/* Functions that return member pointers */ + +extern double (Shape::*areapt())(void); +extern double (Shape::*perimeterpt())(void); + +/* Global variables that are member pointers */ +extern double (Shape::*areavar)(void); +extern double (Shape::*perimetervar)(void); diff --git a/Examples/ruby/mpointer/example.i b/Examples/ruby/mpointer/example.i new file mode 100644 index 000000000..253a224dc --- /dev/null +++ b/Examples/ruby/mpointer/example.i @@ -0,0 +1,15 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Some constants */ + +%constant double (Shape::*AREAPT)(void) = &Shape::area; +%constant double (Shape::*PERIMPT)(void) = &Shape::perimeter; +%constant double (Shape::*NULLPT)(void) = 0; diff --git a/Examples/ruby/mpointer/runme.rb b/Examples/ruby/mpointer/runme.rb new file mode 100644 index 000000000..e11aa68cb --- /dev/null +++ b/Examples/ruby/mpointer/runme.rb @@ -0,0 +1,48 @@ +# Example using pointers to member functions + +require 'example' + +# Get the pointers + +area_pt = Example::areapt +perim_pt = Example::perimeterpt + +puts "area_pt = #{area_pt}" +puts "perim_pt = #{perim_pt}" + +# Create some objects + +c = Example::Circle.new(4) +s = Example::Square.new(10) + +# Do some calculations + +puts "Circle area = #{Example::do_op(c, area_pt)}" +puts "Circle perim = #{Example::do_op(c, perim_pt)}" +puts "Square area = #{Example::do_op(s, area_pt)}" +puts "Square perim = #{Example::do_op(s, perim_pt)}" + +puts "areavar = #{Example::areavar}" +puts "perimetervar = #{Example::perimetervar}" + +# Try the variables +puts "Circle area = #{Example::do_op(c, Example::areavar)}" +puts "Circle perim = #{Example::do_op(c, Example::perimetervar)}" +puts "Square area = #{Example::do_op(s, Example::areavar)}" +puts "Square perim = #{Example::do_op(s, Example::perimetervar)}" + +# Modify one of the variables +Example::areavar = perim_pt + +puts "Circle perimeter = #{Example::do_op(c, Example::areavar)}" + +# Try the constants + +puts "Example::AREAPT = #{Example::AREAPT}" +puts "Example::PERIMPT= #{Example::PERIMPT}" +puts "Example::NULLPT = #{Example::NULLPT}" + +puts "Circle area = #{Example::do_op(c, Example::AREAPT)}" +puts "Circle perim = #{Example::do_op(c, Example::PERIMPT)}" +puts "Square area = #{Example::do_op(s, Example::AREAPT)}" +puts "Square perim = #{Example::do_op(s, Example::PERIMPT)}" diff --git a/Examples/ruby/multimap/.cvsignore b/Examples/ruby/multimap/.cvsignore new file mode 100644 index 000000000..a52fc6147 --- /dev/null +++ b/Examples/ruby/multimap/.cvsignore @@ -0,0 +1,2 @@ +example_wrap.c +example.dll diff --git a/Examples/ruby/multimap/Makefile b/Examples/ruby/multimap/Makefile new file mode 100644 index 000000000..0a59614c4 --- /dev/null +++ b/Examples/ruby/multimap/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/multimap/example.c b/Examples/ruby/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/ruby/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/ruby/multimap/example.dsp b/Examples/ruby/multimap/example.dsp new file mode 100644 index 000000000..ece612973 --- /dev/null +++ b/Examples/ruby/multimap/example.dsp @@ -0,0 +1,150 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(RUBY_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(RUBY_LIB) /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(RUBY_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(RUBY_LIB) /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo RUBY_INCLUDE: %RUBY_INCLUDE% + echo RUBY_LIB: %RUBY_LIB% + echo **WARNING** I could not get Ruby (1.6.4) and SWIG to work under Visual Studio (6) + echo on + ..\..\..\swig -ruby $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo RUBY_INCLUDE: %RUBY_INCLUDE% + echo RUBY_LIB: %RUBY_LIB% + echo **WARNING** I could not get Ruby (1.6.4) and SWIG to work under Visual Studio (6) + echo on + ..\..\..\swig -ruby $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/ruby/multimap/example.i b/Examples/ruby/multimap/example.i new file mode 100644 index 000000000..48ee3d0b5 --- /dev/null +++ b/Examples/ruby/multimap/example.i @@ -0,0 +1,83 @@ +%module example + +%include exception.i +%include typemaps.i + +extern int gcd(int x, int y); + +%typemap(in) (int argc, char *argv[]) { + int i; + + if (TYPE($input) != T_ARRAY) { + SWIG_exception(SWIG_ValueError, "Expected an array"); + } + $1 = RARRAY($input)->len; + if ($1 == 0) { + SWIG_exception(SWIG_ValueError, "List must contain at least 1 element"); + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + VALUE s = rb_ary_entry($input,i); + if (TYPE(s) != T_STRING) { + free($2); + SWIG_exception(SWIG_ValueError, "List items must be strings"); + } + $2[i] = STR2CSTR(s); + } + $2[i] = 0; +} + +%typemap(freearg) (int argc, char *argv[]) { + free($2); +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(in) (char *bytes, int len) { + if (TYPE($input) != T_STRING) { + SWIG_exception(SWIG_ValueError, "Expected a string"); + } + $1 = STR2CSTR($input); + $2 = RSTRING($input)->len; +} + +extern int count(char *bytes, int len, char c); + + +/* This example shows how to wrap a function that mutates a string */ + +%typemap(in) (char *str, int len) { + char *temp; + if (TYPE($input) != T_STRING) { + SWIG_exception(SWIG_ValueError,"Expected a string"); + } + temp = STR2CSTR($input); + $2 = RSTRING($input)->len; + $1 = (char *) malloc($2+1); + memmove($1,temp,$2); +} + +/* Return the mutated string as a new object. */ + +%typemap(argout, fragment="output_helper") (char *str, int len) { + VALUE o; + o = rb_str_new($1,$2); + $result = output_helper($result,o); + free($1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + } +} + +extern void circle(double cx, double cy); + + diff --git a/Examples/ruby/multimap/runme.rb b/Examples/ruby/multimap/runme.rb new file mode 100755 index 000000000..3b2dfa05f --- /dev/null +++ b/Examples/ruby/multimap/runme.rb @@ -0,0 +1,22 @@ +# file: run.rb + +require 'example' + +# Call our gcd() function + +x = 42 +y = 105 +g = Example.gcd(x,y) +printf "The gcd of %d and %d is %d\n",x,y,g + +# Call the gcdmain() function +Example.gcdmain(["gcdmain","42","105"]) + +# Call the count function + +printf "%d\n",Example.count("Hello World","l") + +# Call the capitalize function + +printf "%s\n",Example.capitalize("hello world") + diff --git a/Examples/ruby/operator/.cvsignore b/Examples/ruby/operator/.cvsignore new file mode 100644 index 000000000..f0cef3048 --- /dev/null +++ b/Examples/ruby/operator/.cvsignore @@ -0,0 +1,2 @@ +example_wrap.cxx +example.dll diff --git a/Examples/ruby/operator/Makefile b/Examples/ruby/operator/Makefile new file mode 100644 index 000000000..43c0c1596 --- /dev/null +++ b/Examples/ruby/operator/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/operator/example.h b/Examples/ruby/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/ruby/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/ruby/operator/example.i b/Examples/ruby/operator/example.i new file mode 100644 index 000000000..8d86694b3 --- /dev/null +++ b/Examples/ruby/operator/example.i @@ -0,0 +1,23 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* Grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *__str__() { + static char temp[512]; + sprintf(temp,"(%g,%g)", self->re(), self->im()); + return temp; + } +}; + + diff --git a/Examples/ruby/operator/runme.rb b/Examples/ruby/operator/runme.rb new file mode 100644 index 000000000..518d91e9e --- /dev/null +++ b/Examples/ruby/operator/runme.rb @@ -0,0 +1,25 @@ +# Operator overloading example +require 'example' + +include Example + +a = Complex.new(2, 3) +b = Complex.new(-5, 10) + +puts "a = #{a}" +puts "b = #{b}" + +c = a + b +puts "c = #{c}" +puts "a*b = #{a*b}" +puts "a-c = #{a-c}" + +# This should invoke Complex's copy constructor +e = Complex.new(a-c) +e = a - c +puts "e = #{e}" + +# Big expression +f = ((a+b)*(c+b*e)) + (-a) +puts "f = #{f}" + diff --git a/Examples/ruby/overloading/.cvsignore b/Examples/ruby/overloading/.cvsignore new file mode 100644 index 000000000..bd7dd8a57 --- /dev/null +++ b/Examples/ruby/overloading/.cvsignore @@ -0,0 +1 @@ +example_wrap.cxx diff --git a/Examples/ruby/overloading/Makefile b/Examples/ruby/overloading/Makefile new file mode 100644 index 000000000..ab8928c0e --- /dev/null +++ b/Examples/ruby/overloading/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/overloading/example.cxx b/Examples/ruby/overloading/example.cxx new file mode 100644 index 000000000..49d998d5a --- /dev/null +++ b/Examples/ruby/overloading/example.cxx @@ -0,0 +1,125 @@ +#include + +#include "example.h" + +// Overloaded constructors for class Bar +Bar::Bar() { + std::cout << "Called Bar::Bar()" << std::endl; +} + +Bar::Bar(const Bar&) { + std::cout << "Called Bar::Bar(const Bar&)" << std::endl; +} + +Bar::Bar(double x) { + std::cout << "Called Bar::Bar(double) with x = " << x << std::endl; +} + +Bar::Bar(double x, char *y) { + std::cout << "Called Bar::Bar(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl; +} + +Bar::Bar(int x, int y) { + std::cout << "Called Bar::Bar(int, int) with x, y = " << x << ", " << y << std::endl; +} + +Bar::Bar(char *x) { + std::cout << "Called Bar::Bar(char *) with x = \"" << x << "\"" << std::endl; +} + +Bar::Bar(int x) { + std::cout << "Called Bar::Bar(int) with x = " << x << std::endl; +} + +Bar::Bar(long x) { + std::cout << "Called Bar::Bar(long) with x = " << x << std::endl; +} + +Bar::Bar(Bar *x) { + std::cout << "Called Bar::Bar(Bar *) with x = " << x << std::endl; +} + +// Overloaded member functions +void Bar::foo(const Bar& x) { + std::cout << "Called Bar::foo(const Bar&) with &x = " << &x << std::endl; +} + +void Bar::foo(double x) { + std::cout << "Called Bar::foo(double) with x = " << x << std::endl; +} + +void Bar::foo(double x, char *y) { + std::cout << "Called Bar::foo(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl; +} + +void Bar::foo(int x, int y) { + std::cout << "Called Bar::foo(int, int) with x, y = " << x << ", " << y << std::endl; +} + +void Bar::foo(char *x) { + std::cout << "Called Bar::foo(char *) with x = \"" << x << "\"" << std::endl; +} + +void Bar::foo(int x) { + std::cout << "Called Bar::foo(int) with x = " << x << std::endl; +} + +void Bar::foo(long x) { + std::cout << "Called Bar::foo(long) with x = " << x << std::endl; +} + +void Bar::foo(Bar *x) { + std::cout << "Called Bar::foo(Bar *) with x = " << x << std::endl; +} + +void Bar::spam(int x, int y, int z) { + std::cout << "Called Bar::spam(int, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl; +} + +void Bar::spam(double x, int y, int z) { + std::cout << "Called Bar::spam(double, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl; +} + +// Overloaded global methods +void foo(const Bar& x) { + std::cout << "Called foo(const Bar& x) with &x = " << &x << std::endl; +} + +void foo(double x) { + std::cout << "Called foo(double) with x = " << x << std::endl; +} + +void foo(double x, char *y) { + std::cout << "Called foo(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl; +} + +void foo(int x, int y) { + std::cout << "Called foo(int, int) with x, y = " << x << ", " << y << std::endl; +} + +void foo(char *x) { + std::cout << "Called foo(char *) with x = \"" << x << "\"" << std::endl; +} + +void foo(int x) { + std::cout << "Called foo(int) with x = " << x << std::endl; +} + +void foo(long x) { + std::cout << "Called foo(long) with x = " << x << std::endl; +} + +void foo(Bar *x) { + std::cout << "Called foo(Bar *) with x = " << x << std::endl; +} + +// Overloaded global spam() functions +void spam(int x, int y, int z) { + std::cout << "Called spam(int, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl; +} + +void spam(double x, int y, int z) { + std::cout << "Called spam(double, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl; +} + + diff --git a/Examples/ruby/overloading/example.h b/Examples/ruby/overloading/example.h new file mode 100644 index 000000000..e47a122ee --- /dev/null +++ b/Examples/ruby/overloading/example.h @@ -0,0 +1,41 @@ +#ifndef EXAMPLE_H +#define EXAMPLE_H + +class Bar { +public: + Bar(); + Bar(const Bar&); + Bar(double); + Bar(double, char *); + Bar(int, int); + Bar(char *); + Bar(long); + Bar(int); + Bar(Bar *); + + void foo(const Bar&); + void foo(double); + void foo(double, char *); + void foo(int, int); + void foo(char *); + void foo(long); + void foo(int); + void foo(Bar *); + + void spam(int x, int y=2, int z=3); + void spam(double x, int y=2, int z=3); +}; + +void foo(const Bar&); +void foo(double); +void foo(double, char *); +void foo(int, int); +void foo(char *); +void foo(int); +void foo(long); +void foo(Bar *); + +void spam(int x, int y=2, int z=3); +void spam(double x, int y=2, int z=3); + +#endif diff --git a/Examples/ruby/overloading/example.i b/Examples/ruby/overloading/example.i new file mode 100644 index 000000000..17ad66997 --- /dev/null +++ b/Examples/ruby/overloading/example.i @@ -0,0 +1,24 @@ +%module example + +%{ +#include "example.h" +%} + +/** + * These overloaded declarations conflict with other overloads (as far as + * SWIG's Ruby module's implementation for overloaded methods is concerned). + * One option is use the %rename directive to rename the conflicting methods; + * here, we're just using %ignore to avoid wrapping some of the overloaded + * functions altogether. + */ + +%ignore Bar::Bar(Bar *); +%ignore Bar::Bar(long); + +%ignore Bar::foo(const Bar&); +%ignore Bar::foo(long); + +%ignore ::foo(const Bar&); +%ignore ::foo(int); + +%include example.h diff --git a/Examples/ruby/overloading/runme.rb b/Examples/ruby/overloading/runme.rb new file mode 100644 index 000000000..9f1233347 --- /dev/null +++ b/Examples/ruby/overloading/runme.rb @@ -0,0 +1,88 @@ +require 'example' + +# This should invoke foo(double) +Example.foo(3.14159) + +# This should invoke foo(double, char *) +Example.foo(3.14159, "Pi") + +# This should invoke foo(int, int) +Example.foo(3, 4) + +# This should invoke foo(char *) +Example.foo("This is a test") + +# This should invoke foo(long) +Example.foo(42) + +# This should invoke Bar::Bar() followed by foo(Bar *) +Example.foo(Example::Bar.new) + +# Skip a line +puts "" + +# Each of the following three calls should invoke spam(int, int, int) +Example.spam(3) +Example.spam(3, 4) +Example.spam(3, 4, 5) + +# Skip a line +puts "" + +# Each of the following three calls should invoke spam(double, int, int) +Example.spam(3.0) +Example.spam(3.0, 4) +Example.spam(3.0, 4, 5) + +# Skip a line +puts "" + +# This should invoke Bar::Bar(double) +Example::Bar.new(3.14159) + +# This should invoke Bar::Bar(double, char *) +Example::Bar.new(3.14159, "Pi") + +# This should invoke Bar::Bar(int, int) +Example::Bar.new(3, 4) + +# This should invoke Bar::Bar(char *) +Example::Bar.new("This is a test") + +# This should invoke Bar::Bar(int) +Example::Bar.new(42) + +# This should invoke Bar::Bar() for the input argument, +# followed by Bar::Bar(const Bar&). +Example::Bar.new(Example::Bar.new) + +# Skip a line +puts "" + +# Construct a new Bar instance (invokes Bar::Bar()) +bar = Example::Bar.new + +# This should invoke Bar::foo(double) +bar.foo(3.14159) + +# This should invoke Bar::foo(double, char *) +bar.foo(3.14159, "Pi") + +# This should invoke Bar::foo(int, int) +bar.foo(3, 4) + +# This should invoke Bar::foo(char *) +bar.foo("This is a test") + +# This should invoke Bar::foo(int) +bar.foo(42) + +# This should invoke Bar::Bar() to construct the input +# argument, followed by Bar::foo(Bar *). +bar.foo(Example::Bar.new) + +# This should invoke Bar::spam(int x, int y, int z) +bar.spam(1) + +# This should invoke Bar::spam(double x, int y, int z) +bar.spam(3.14159) diff --git a/Examples/ruby/pointer/.cvsignore b/Examples/ruby/pointer/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/pointer/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/pointer/Makefile b/Examples/ruby/pointer/Makefile index cd0fdf300..0a59614c4 100644 --- a/Examples/ruby/pointer/Makefile +++ b/Examples/ruby/pointer/Makefile @@ -13,6 +13,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/pointer/example.i b/Examples/ruby/pointer/example.i index 2ed2b5bbf..4483b0f77 100644 --- a/Examples/ruby/pointer/example.i +++ b/Examples/ruby/pointer/example.i @@ -6,7 +6,8 @@ /* First we'll use the pointer library */ extern void add(int *x, int *y, int *result); -%include pointer.i +%include cpointer.i +%pointer_functions(int, intp); /* Next we'll use some typemaps */ diff --git a/Examples/ruby/pointer/runme.rb b/Examples/ruby/pointer/runme.rb index b1c3af4b3..d696b026f 100644 --- a/Examples/ruby/pointer/runme.rb +++ b/Examples/ruby/pointer/runme.rb @@ -4,9 +4,12 @@ require 'example' # First create some objects using the pointer library. print "Testing the pointer library\n" -a = Example::ptrcreate("int", 37) -b = Example::ptrcreate("int", 42) -c = Example::ptrcreate("int"); +a = Example::new_intp() +b = Example::new_intp() +c = Example::new_intp() + +Example::intp_assign(a,37) +Example::intp_assign(b,42) print " a = #{a}\n" print " b = #{b}\n" @@ -16,13 +19,13 @@ print " c = #{c}\n" Example::add(a, b, c) # Now get the result -r = Example::ptrvalue(c) +r = Example::intp_value(c) print " 37 + 42 = #{r}\n" # Clean up the pointers -Example::ptrfree(a) -Example::ptrfree(b) -Example::ptrfree(c) +Example::delete_intp(a) +Example::delete_intp(b) +Example::delete_intp(c) # Now try the typemap library # This should be much easier. Now how it is no longer diff --git a/Examples/ruby/reference/.cvsignore b/Examples/ruby/reference/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/reference/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/reference/Makefile b/Examples/ruby/reference/Makefile index 01ce757ff..ab8928c0e 100644 --- a/Examples/ruby/reference/Makefile +++ b/Examples/ruby/reference/Makefile @@ -14,6 +14,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/reference/example.i b/Examples/ruby/reference/example.i index 8538326f6..e71f297bf 100644 --- a/Examples/ruby/reference/example.i +++ b/Examples/ruby/reference/example.i @@ -31,7 +31,7 @@ public: int size(); /* This wrapper provides an alternative to the [] operator */ - %addmethods { + %extend { Vector &get(int index) { return (*self)[index]; } diff --git a/Examples/ruby/simple/.cvsignore b/Examples/ruby/simple/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/simple/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/simple/Makefile b/Examples/ruby/simple/Makefile index cd0fdf300..0a59614c4 100644 --- a/Examples/ruby/simple/Makefile +++ b/Examples/ruby/simple/Makefile @@ -13,6 +13,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/simple/example.dsp b/Examples/ruby/simple/example.dsp new file mode 100644 index 000000000..a68073c51 --- /dev/null +++ b/Examples/ruby/simple/example.dsp @@ -0,0 +1,150 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(RUBY_INCLUDE)" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(RUBY_LIB)" /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept /EXPORT:Init_example +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(RUBY_INCLUDE)" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(RUBY_LIB)" /nologo /dll /machine:I386 /out:"example.dll" /EXPORT:Init_example +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo RUBY_INCLUDE: %RUBY_INCLUDE% + echo RUBY_LIB: %RUBY_LIB% + echo on + ..\..\..\swig -ruby $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo RUBY_INCLUDE: %RUBY_INCLUDE% + echo RUBY_LIB: %RUBY_LIB% + echo on + ..\..\..\swig -ruby $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/ruby/simple/run.rb b/Examples/ruby/simple/runme.rb old mode 100644 new mode 100755 similarity index 100% rename from Examples/ruby/simple/run.rb rename to Examples/ruby/simple/runme.rb diff --git a/Examples/ruby/std_vector/.cvsignore b/Examples/ruby/std_vector/.cvsignore new file mode 100644 index 000000000..bd7dd8a57 --- /dev/null +++ b/Examples/ruby/std_vector/.cvsignore @@ -0,0 +1 @@ +example_wrap.cxx diff --git a/Examples/ruby/std_vector/Makefile b/Examples/ruby/std_vector/Makefile new file mode 100644 index 000000000..6b0d049a5 --- /dev/null +++ b/Examples/ruby/std_vector/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/std_vector/example.h b/Examples/ruby/std_vector/example.h new file mode 100644 index 000000000..4f0dac70d --- /dev/null +++ b/Examples/ruby/std_vector/example.h @@ -0,0 +1,25 @@ +/* File : example.h */ + +#include +#include +#include +#include + +double average(std::vector v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector half(const std::vector& v) { + std::vector w(v); + for (unsigned int i=0; i& v) { + // would you believe this is the same as the above? + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides(),2.0)); +} + + diff --git a/Examples/ruby/std_vector/example.i b/Examples/ruby/std_vector/example.i new file mode 100644 index 000000000..aa58b66e0 --- /dev/null +++ b/Examples/ruby/std_vector/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include stl.i +/* instantiate the required template specializations */ +namespace std { + %template(IntVector) vector; + %template(DoubleVector) vector; +} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/ruby/std_vector/runme.rb b/Examples/ruby/std_vector/runme.rb new file mode 100644 index 000000000..1529d38c6 --- /dev/null +++ b/Examples/ruby/std_vector/runme.rb @@ -0,0 +1,36 @@ +# file: runme.rb + +require 'example' + +# Call average with a Ruby array... + +puts Example::average([1,2,3,4]) + +# ... or a wrapped std::vector + +v = Example::IntVector.new(4) +0.upto(v.length-1) { |i| v[i] = i+1 } +puts Example::average(v) + + +# half will return a Ruby array. +# Call it with a Ruby array... + +w = Example::half([1.0, 1.5, 2.0, 2.5, 3.0]) +0.upto(w.length-1) { |i| print w[i],"; " } +puts + +# ... or a wrapped std::vector + +v = Example::DoubleVector.new +[1,2,3,4].each { |i| v.push(i) } +w = Example::half(v) +0.upto(w.length-1) { |i| print w[i],"; " } +puts + +# now halve a wrapped std::vector in place + +Example::halve_in_place(v) +0.upto(v.length-1) { |i| print v[i],"; " } +puts + diff --git a/Examples/ruby/template/.cvsignore b/Examples/ruby/template/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/template/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/template/Makefile b/Examples/ruby/template/Makefile new file mode 100644 index 000000000..6b0d049a5 --- /dev/null +++ b/Examples/ruby/template/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/template/example.h b/Examples/ruby/template/example.h new file mode 100644 index 000000000..4d9a58c54 --- /dev/null +++ b/Examples/ruby/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return self->get(index); + } + void setitem(int index, T val) { + self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/ruby/template/example.i b/Examples/ruby/template/example.i new file mode 100644 index 000000000..8036701ea --- /dev/null +++ b/Examples/ruby/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(Vecint) vector; +%template(Vecdouble) vector; + diff --git a/Examples/ruby/template/runme.rb b/Examples/ruby/template/runme.rb new file mode 100644 index 000000000..6c9c4ebc2 --- /dev/null +++ b/Examples/ruby/template/runme.rb @@ -0,0 +1,25 @@ +# file: runme.rb + +require 'example' + +# Call some templated functions +puts Example::maxint(3, 7) +puts Example::maxdouble(3.14, 2.18) + +# Create some class + +iv = Example::Vecint.new(100) +dv = Example::Vecdouble.new(1000) + +100.times { |i| iv.setitem(i, 2*i) } + +1000.times { |i| dv.setitem(i, 1.0/(i+1)) } + +sum = 0 +100.times { |i| sum = sum + iv.getitem(i) } + +puts sum + +sum = 0.0 +1000.times { |i| sum = sum + dv.getitem(i) } +puts sum diff --git a/Examples/ruby/value/.cvsignore b/Examples/ruby/value/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/value/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/value/Makefile b/Examples/ruby/value/Makefile index cd0fdf300..0a59614c4 100644 --- a/Examples/ruby/value/Makefile +++ b/Examples/ruby/value/Makefile @@ -13,6 +13,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/variables/.cvsignore b/Examples/ruby/variables/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/ruby/variables/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/ruby/variables/Makefile b/Examples/ruby/variables/Makefile index cd0fdf300..0a59614c4 100644 --- a/Examples/ruby/variables/Makefile +++ b/Examples/ruby/variables/Makefile @@ -13,6 +13,6 @@ static:: TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static clean:: - rm -f *_wrap* *.o *~ *.so myruby .~* core + $(MAKE) -f $(TOP)/Makefile ruby_clean check: all diff --git a/Examples/ruby/variables/example.i b/Examples/ruby/variables/example.i index d62f973da..91bd0679d 100644 --- a/Examples/ruby/variables/example.i +++ b/Examples/ruby/variables/example.i @@ -27,10 +27,10 @@ extern Point pt; /* Some read-only variables */ -%readonly +%immutable; extern int status; extern char path[256]; -%readwrite +%mutable; /* Some helper functions to make it easier to test */ extern void print_vars(); diff --git a/Examples/ruby/variables/index.html b/Examples/ruby/variables/index.html index df144d32b..d0dd76211 100644 --- a/Examples/ruby/variables/index.html +++ b/Examples/ruby/variables/index.html @@ -68,21 +68,21 @@ Getting the "value" returns a pointer to the global variable. Setting the value

    Creating read-only variables

    -The %readonly and %readwrite directives can be used to +The %immutable and %mutable directives can be used to specify a collection of read-only variables. For example:
    -%readonly
    +%immutable;
     int    status;
     double blah;
     ...
    -%readwrite
    +%mutable;
     
    -The %readonly directive remains in effect until it is explicitly disabled -using the %readwrite directive. +The %immutable directive remains in effect until it is explicitly disabled +using the %mutable directive.

    Comments

      diff --git a/Examples/ruby/variables/runme.rb b/Examples/ruby/variables/runme.rb index ab73a35e4..cbb6b0df7 100644 --- a/Examples/ruby/variables/runme.rb +++ b/Examples/ruby/variables/runme.rb @@ -25,23 +25,23 @@ Example.name = "Bill" puts "Variables (values printed from Ruby)" -print "ivar = ", Example.ivar, "\n" -print "svar = ", Example.svar, "\n" -print "lvar = ", Example.lvar, "\n" -print "uivar = ", Example.uivar, "\n" -print "usvar = ", Example.usvar, "\n" -print "ulvar = ", Example.ulvar, "\n" -print "scvar = ", Example.scvar, "\n" -print "ucvar = ", Example.ucvar, "\n" -print "fvar = ", Example.fvar, "\n" -print "dvar = ", Example.dvar, "\n" -print "cvar = ", Example.cvar, "\n" -print "strvar = ", Example.strvar, "\n" -print "cstrvar = ", Example.cstrvar, "\n" -print "iptrvar = ", Example.iptrvar, "\n" -print "name = ", Example.name, "\n" -print "ptptr = ", Example.ptptr, " ", Example.Point_print(Example.ptptr), "\n" -print "pt = ", Example.pt, " ", Example.Point_print(Example.pt), "\n" +puts "ivar = #{Example.ivar}" +puts "svar = #{Example.svar}" +puts "lvar = #{Example.lvar}" +puts "uivar = #{Example.uivar}" +puts "usvar = #{Example.usvar}" +puts "ulvar = #{Example.ulvar}" +puts "scvar = #{Example.scvar}" +puts "ucvar = #{Example.ucvar}" +puts "fvar = #{Example.fvar}" +puts "dvar = #{Example.dvar}" +puts "cvar = #{Example.cvar}" +puts "strvar = #{Example.strvar}" +puts "cstrvar = #{Example.cstrvar}" +puts "iptrvar = #{Example.iptrvar}" +puts "name = #{Example.name}" +puts "ptptr = #{Example.ptptr} (#{Example.Point_print(Example.ptptr)})" +puts "pt = #{Example.pt} (#{Example.Point_print(Example.pt)})" puts "\nVariables (values printed from C)" @@ -66,13 +66,13 @@ rescue NameError end -print "\nI'm going to try and update a structure variable.\n\n" +puts "\nI'm going to try and update a structure variable.\n" Example.pt = Example.ptptr puts "The new value is" Example.pt_print() -print "You should see the value ", Example.Point_print(Example.ptptr), "\n" +puts "You should see the value #{Example.Point_print(Example.ptptr)}" diff --git a/Examples/s-exp/uffi.lisp b/Examples/s-exp/uffi.lisp new file mode 100644 index 000000000..3869f10e4 --- /dev/null +++ b/Examples/s-exp/uffi.lisp @@ -0,0 +1,349 @@ +;;; This is experimental code that uses the s-expression +;;; representation of a C/C++ library interface to generate Foreign +;;; Function Interface definitions for use with Kevin Rosenberg's +;;; UFFI. +;;; +;;; Written by Matthias Koeppe + +(require 'port) ; from CLOCC + +(in-package :cl-user) + +(require 'uffi) + +;; Interaction with the SWIG binary + +(defvar *swig-source-directory* #p"/home/mkoeppe/s/swig1.3/") + +(defvar *swig-program* (merge-pathnames "swig-1.3" *swig-source-directory*)) + +(defun run-swig (swig-interface-file-name &key directory-search-list module + ignore-errors) + (setf (port:getenv :SWIG_LIB) + (namestring (merge-pathnames "Lib" *swig-source-directory*))) + (let ((temp-file-name "/tmp/swig.lsp")) + (let ((process + (port:run-prog (namestring *swig-program*) + :output t + :args `("-sexp" + ,@(mapcar (lambda (dir) + (concatenate 'string + "-I" (namestring dir))) + directory-search-list) + ,@(and module + `("-module" ,module)) + "-o" ,temp-file-name + ,(namestring swig-interface-file-name))))) + #+cmu (unless (or (zerop (ext:process-exit-code process)) + ignore-errors) + (error "Process swig exited abnormally")) + (with-open-file (s temp-file-name) + (read s))))) + +;; Type system + +(defun parse-swigtype (type-string &key start end junk-ok) + "Parse TYPE-STRING as SWIG's internal representation of C/C++ +types. Return two values: The type description (an improper list) and +the terminating index into TYPE-STRING." + ;; SWIG's internal representation is described in Source/Swig/stype.c + (unless start + (setq start 0)) + (unless end + (setq end (length type-string))) + (flet ((prefix-match (prefix) + (let ((position (mismatch prefix type-string :start2 start :end2 end))) + (or (not position) + (= position (length prefix))))) + (bad-type-error (reason) + (error "Bad SWIG type (~A): ~A" reason + (subseq type-string start end))) + (type-char (index) + (and (< index (length type-string)) + (char type-string index))) + (cons-and-recurse (prefix start end) + (multiple-value-bind (type-description index) + (parse-swigtype type-string :start start :end end + :junk-ok junk-ok) + (values (cons prefix type-description) + index)))) + (cond + ((prefix-match "p.") ; pointer + (cons-and-recurse '* (+ start 2) end)) + ((prefix-match "r.") ; C++ reference + (cons-and-recurse '& (+ start 2) end)) + ((prefix-match "a(") ; array + (let ((closing-paren (find #\) type-string + :start (+ start 2) + :end end))) + (unless closing-paren + (bad-type-error "missing right paren")) + (unless (eql (type-char (+ closing-paren 1)) #\.) + (bad-type-error "missing dot")) + (cons-and-recurse (list 'ARRAY (subseq type-string (+ start 2) closing-paren)) + (+ closing-paren 2) end))) + ((prefix-match "q(") ; qualifier (const, volatile) + (let ((closing-paren (find #\) type-string + :start (+ start 2) + :end end))) + (unless closing-paren + (bad-type-error "missing right paren")) + (unless (eql (type-char (+ closing-paren 1)) #\.) + (bad-type-error "missing dot")) + (cons-and-recurse (list 'QUALIFIER (subseq type-string (+ start 2) closing-paren)) + (+ closing-paren 2) end))) + ((prefix-match "m(") ; C++ member pointer + (multiple-value-bind (class-type class-end-index) + (parse-swigtype type-string :junk-ok t + :start (+ start 2) :end end) + (unless (eql (type-char class-end-index) #\)) + (bad-type-error "missing right paren")) + (unless (eql (type-char (+ class-end-index 1)) #\.) + (bad-type-error "missing dot")) + (cons-and-recurse (list 'MEMBER-POINTER class-type) + (+ class-end-index 2) end))) + ((prefix-match "f(") ; function + (loop with index = (+ start 2) + until (eql (type-char index) #\)) + collect (multiple-value-bind (arg-type arg-end-index) + (parse-swigtype type-string :junk-ok t + :start index :end end) + (case (type-char arg-end-index) + (#\, (setq index (+ arg-end-index 1))) + (#\) (setq index arg-end-index)) + (otherwise (bad-type-error "comma or right paren expected"))) + arg-type) + into arg-types + finally (unless (eql (type-char (+ index 1)) #\.) + (bad-type-error "missing dot")) + (return (cons-and-recurse (cons 'FUNCTION arg-types) + (+ index 2) end)))) + (t (let ((junk-position (position-if (lambda (char) + (member char '(#\, #\( #\) #\.))) + type-string + :start start :end end))) + (cond (junk-position ; found junk + (unless junk-ok + (bad-type-error "trailing junk")) + (values (subseq type-string start junk-position) + junk-position)) + (t + (values (subseq type-string start end) + end)))))))) + +(defun swigtype-function-p (swigtype) + "Check whether SWIGTYPE designates a function. If so, the second +value is the list of argument types, and the third value is the return +type." + (if (and (consp swigtype) + (consp (first swigtype)) + (eql (first (first swigtype)) 'FUNCTION)) + (values t (rest (first swigtype)) (rest swigtype)) + (values nil nil nil))) + + +;; UFFI + +(defvar *uffi-definitions* '()) + +(defconstant *uffi-default-primitive-type-alist* + '(("char" . :char) + ("unsigned char" . :unsigned-byte) + ("signed char" . :byte) + ("short" . :short) + ("signed short" . :short) + ("unsigned short" . :unsigned-short) + ("int" . :int) + ("signed int" . :int) + ("unsigned int" . :unsigned-int) + ("long" . :long) + ("signed long" . :long) + ("unsigned long" . :unsigned-long) + ("float" . :float) + ("double" . :double) + ((* . "char") . :cstring) + ((* . "void") . :pointer-void) + ("void" . :void))) + +(defvar *uffi-primitive-type-alist* *uffi-default-primitive-type-alist*) + +(defun uffi-type-spec (type-list) + "Return the UFFI type spec equivalent to TYPE-LIST, or NIL if there +is no representation." + (let ((primitive-type-pair + (assoc type-list *uffi-primitive-type-alist* :test 'equal))) + (cond + (primitive-type-pair + (cdr primitive-type-pair)) + ((and (consp type-list) + (eql (first type-list) '*)) + (let ((base-type-spec (uffi-type-spec (rest type-list)))) + (cond + ((not base-type-spec) + :pointer-void) + (t + (list '* base-type-spec))))) + (t nil)))) + +;; Parse tree + +(defvar *uffi-output* nil) + +(defun emit-uffi-definition (uffi-definition) + (format *uffi-output* "~&~S~%" uffi-definition) + (push uffi-definition *uffi-definitions*)) + +(defun make-cl-symbol (c-identifier) + (intern (substitute #\- #\_ (string-upcase c-identifier)))) + +(defvar *class-scope* '() "A stack of names of nested C++ classes.") + +(defvar *struct-fields* '()) + +(defgeneric handle-node (node-type &key &allow-other-keys) + (:documentation "Handle a node of SWIG's parse tree of a C/C++ program")) + +(defmethod handle-node ((node-type t) &key &allow-other-keys) + ;; do nothing for unknown node types + nil) + +(defmethod handle-node ((node-type (eql 'cdecl)) &key name decl storage parms type &allow-other-keys) + (let ((swigtype (parse-swigtype (concatenate 'string decl type)))) + (let ((*print-pretty* nil)) ; or FUNCTION would be printed as #' by cmucl + (format *uffi-output* "~&;; C Declaration: ~A ~A ~A ~A~%;; with-parms ~W~%;; of-type ~W~%" + storage type name decl parms swigtype)) + (multiple-value-bind (function-p arg-swigtype-list return-swigtype) + (swigtype-function-p swigtype) + (declare (ignore arg-swigtype-list)) + (cond + ((and (null *class-scope*) function-p) ; ordinary top-level function + (let ((uffi-arg-list + (mapcar (lambda (param) + (destructuring-bind (&key name type &allow-other-keys) param + (let ((uffi-type (uffi-type-spec (parse-swigtype type)))) + (unless uffi-type + (format *uffi-output* "~&;; Warning: Cannot handle type ~S of argument `~A'~%" + type name) + (return-from handle-node)) + `(,(make-cl-symbol name) ,uffi-type)))) + parms)) + (uffi-return-type + (uffi-type-spec return-swigtype))) + (unless uffi-return-type + (format *uffi-output* "~&;; Warning: Cannot handle return type `~S'~%" + return-swigtype) + (return-from handle-node)) + (emit-uffi-definition `(UFFI:DEF-FUNCTION ,name ,uffi-arg-list :RETURNING ,uffi-return-type)))) + + ((and (not (null *class-scope*)) (null (rest *class-scope*)) + (not function-p)) ; class/struct member (no nested structs) + (let ((uffi-type (uffi-type-spec swigtype))) + (unless uffi-type + (format *uffi-output* "~&;; Warning: Cannot handle type ~S of struct field `~A'~%" + type name) + (return-from handle-node)) + (push `(,(make-cl-symbol name) ,uffi-type) *struct-fields*))))))) + +(defmethod handle-node ((node-type (eql 'class)) &key name children kind &allow-other-keys) + (format *uffi-output* "~&;; Class ~A~%" name) + (let ((*class-scope* (cons name *class-scope*)) + (*struct-fields* '())) + (dolist (child children) + (apply 'handle-node child)) + (emit-uffi-definition `(,(if (string= kind "union") + 'UFFI:DEF-UNION + 'UFFI:DEF-STRUCT) + ,(make-cl-symbol name) ,@(nreverse *struct-fields*))))) + +(defmethod handle-node ((node-type (eql 'top)) &key children &allow-other-keys) + (dolist (child children) + (apply 'handle-node child))) + +(defmethod handle-node ((node-type (eql 'include)) &key name children &allow-other-keys) + (format *uffi-output* ";; INCLUDE ~A~%" name) + (dolist (child children) + (apply 'handle-node child))) + +;;(defun compute-uffi-definitions (swig-interface) +;; (let ((*uffi-definitions* '())) +;; (handle-node swig-interface) +;; *uffi-definitions*)) + +;; Test instances + +#+ignore +(defvar *gifplot-interface* + (run-swig (merge-pathnames "Examples/GIFPlot/Interface/gifplot.i" + *swig-source-directory*) + :directory-search-list (list (merge-pathnames "Examples/GIFPlot/Interface/" *swig-source-directory*)))) + +(defvar *simple-gifplot-interface* + (run-swig (merge-pathnames "Examples/GIFPlot/Include/gifplot.h" + *swig-source-directory*) + :directory-search-list (list (merge-pathnames "Examples/GIFPlot/Interface/" *swig-source-directory*)) + :module "gifplot")) + +(defvar *cplex-glue-directory* #p"/home/mkoeppe/cvs/cplex-glue/") + +(defvar *cplex-glue-interface* + (run-swig (merge-pathnames "cplex.i" *cplex-glue-directory*) + :directory-search-list (list (merge-pathnames "Lib/guile" + *swig-source-directory*) + *cplex-glue-directory*) + :ignore-errors t)) + + + +(require 'uffi) + +;;(let ((*uffi-primitive-type-alist* (cons '("Pixel" . :unsigned-int) *uffi-default-primitive-type-alist*))) +;; (eval (cons 'progn (compute-uffi-definitions *simple-gifplot-interface*)))) + + +(with-open-file (f "/tmp/swig-uffi.lisp" :direction :output) + (let ((*uffi-definitions* '()) + (*uffi-output* f) + (*uffi-primitive-type-alist* + (cons '("Pixel" . :unsigned-int) *uffi-default-primitive-type-alist*))) + (apply 'handle-node *simple-gifplot-interface*))) + +#+cplex +(with-open-file (f "/tmp/swig-uffi.lisp" :direction :output) + (let ((*uffi-definitions* '()) + (*uffi-output* f) + (*uffi-primitive-type-alist* + (cons '("Pixel" . :unsigned-int) *uffi-default-primitive-type-alist*))) + (apply 'handle-node *cplex-glue-interface*))) + +(compile-file "/tmp/swig-uffi.lisp") + +(load "/tmp/swig-uffi.lisp") + +(uffi:load-foreign-library (merge-pathnames "Examples/GIFPlot/libgifplot.a" + *swig-source-directory*)) + +(load (merge-pathnames "Examples/GIFPlot/Common-Lisp/full/runme.lisp" *swig-source-directory*)) + +(action (namestring (merge-pathnames "Examples/GIFPlot/Common-Lisp/full/cmap" + *swig-source-directory*))) + +;;;; TODO: + +;; * How to do type lookups? Is everything important that SWIG knows +;; about the types written out? What to make of typemaps? +;; +;; * Wrapped functions should probably automatically COERCE their +;; arguments (as of type DOUBLE-FLOAT), to make the functions more +;; flexible? +;; +;; * Why are the functions created by FFI interpreted? +;; +;; * We can't deal with more complicated structs and C++ classes +;; directly with the FFI; we have to emit SWIG wrappers that access +;; those classes. +;; +;; * A CLOS layer where structure fields are mapped as slots. It +;; looks like we need MOP functions to implement this. +;; +;; * Maybe modify SWIG so that key-value hashes are distinguished from +;; value-value hashes. diff --git a/Examples/tcl/check.list b/Examples/tcl/check.list new file mode 100644 index 000000000..7301d2f83 --- /dev/null +++ b/Examples/tcl/check.list @@ -0,0 +1,13 @@ +# see top-level Makefile.in +class +constants +enum +funcptr +import +multimap +operator +pointer +reference +simple +value +variables diff --git a/Examples/tcl/class/.cvsignore b/Examples/tcl/class/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/class/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/class/Makefile b/Examples/tcl/class/Makefile index 942f4cf8f..7d3d5f9cb 100644 --- a/Examples/tcl/class/Makefile +++ b/Examples/tcl/class/Makefile @@ -14,6 +14,6 @@ static:: TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mytclsh *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/class/example.cxx b/Examples/tcl/class/example.cxx index 21582f4d1..1e8e203dd 100644 --- a/Examples/tcl/class/example.cxx +++ b/Examples/tcl/class/example.cxx @@ -1,7 +1,7 @@ /* File : example.c */ #include "example.h" -#include +#define M_PI 3.14159265358979323846 /* Move the shape to a new location */ void Shape::move(double dx, double dy) { @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area() { +double Circle::area(void) { return M_PI*radius*radius; } -double Circle::perimeter() { +double Circle::perimeter(void) { return 2*M_PI*radius; } -double Square::area() { +double Square::area(void) { return width*width; } -double Square::perimeter() { +double Square::perimeter(void) { return 4*width; } diff --git a/Examples/tcl/class/example.dsp b/Examples/tcl/class/example.dsp new file mode 100644 index 000000000..0eeb9d4dd --- /dev/null +++ b/Examples/tcl/class/example.dsp @@ -0,0 +1,152 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(TCL_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(TCL_LIB)" /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(TCL_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(TCL_LIB)" /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.cxx +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\example.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo TCL_INCLUDE: %TCL_INCLUDE% + echo TCL_LIB: %TCL_LIB% + echo on + ..\..\..\swig -tcl8 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo TCL_INCLUDE: %TCL_INCLUDE% + echo TCL_LIB: %TCL_LIB% + echo on + ..\..\..\swig -c++ -tcl8 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/tcl/class/example.h b/Examples/tcl/class/example.h index 849071dd3..46d901361 100644 --- a/Examples/tcl/class/example.h +++ b/Examples/tcl/class/example.h @@ -10,8 +10,8 @@ public: }; double x, y; void move(double dx, double dy); - virtual double area() = 0; - virtual double perimeter() = 0; + virtual double area(void) = 0; + virtual double perimeter(void) = 0; static int nshapes; }; @@ -20,8 +20,8 @@ private: double radius; public: Circle(double r) : radius(r) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; class Square : public Shape { @@ -29,8 +29,8 @@ private: double width; public: Square(double w) : width(w) { }; - virtual double area(); - virtual double perimeter(); + virtual double area(void); + virtual double perimeter(void); }; diff --git a/Examples/tcl/class/example1.tcl b/Examples/tcl/class/example1.tcl index f766a4f92..358dbf143 100644 --- a/Examples/tcl/class/example1.tcl +++ b/Examples/tcl/class/example1.tcl @@ -22,11 +22,11 @@ puts "\nA total of $Shape_nshapes shapes were created" # ----- Member data access ----- # Set the location of the object +# Note: the base class must be used since that's where x and y +# were declared. Shape_x_set $c 20 Shape_y_set $c 30 - -# Now use the same functions in the base class Shape_x_set $s -10 Shape_y_set $s 5 @@ -69,6 +69,3 @@ delete_Shape $s puts "$Shape_nshapes shapes remain" puts "Goodbye" - - - diff --git a/Examples/tcl/class/example2.tcl b/Examples/tcl/class/example2.tcl index 6ea166df6..9f7a3b8f3 100644 --- a/Examples/tcl/class/example2.tcl +++ b/Examples/tcl/class/example2.tcl @@ -11,7 +11,7 @@ catch { load ./example.dll example} ;# Windows puts "Creating some objects:" Circle c 10 puts " Created circle [c cget -this]" -Circle s 10 +Square s 10 puts " Created square [s cget -this]" # ----- Access a static member ----- diff --git a/Examples/tcl/class/index.html b/Examples/tcl/class/index.html index 00bd4e870..c3069ced6 100644 --- a/Examples/tcl/class/index.html +++ b/Examples/tcl/class/index.html @@ -120,14 +120,13 @@ For example:
      -Circle_x_set $c 15       ;# Set member data
      +Shape_x_set $c 15        ;# Set member data
       set x [Shape_x_get $c]   ;# Get member data
       
      -Note: when accessing member data, the name of the base class or the derived class can be -used in the function name as shown above. Of course, it would probably be more -proper to just use the base class version such as Shape_x_get +Note: when accessing member data, the name of the base class must +be used such as Shape_x_get

    • To invoke a member function, you simply do this @@ -270,28 +269,6 @@ to write a helper function. For example:

    • Namespaces. Not supported at all. Won't be supported until SWIG2.0 (if at all). -

      -

    • Templates. Not supported at all. SWIG throws out anything that looks like a template. -You can work around the problem by aliasing a template class behind a typedef however. -For example: - -
      -
      -%{
      -typedef vector IntVector;
      -%}
      -
      -class IntVector {
      -public:
      -    ... methods ...
      -};
      -
      -
      -
    -

    -

  • There is no guarantee that an extremely complex C++ application will be able to compile -as a Python extension. Sorry. -
    diff --git a/Examples/tcl/constants/.cvsignore b/Examples/tcl/constants/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/constants/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/constants/Makefile b/Examples/tcl/constants/Makefile index bb509b03f..ef0486c0b 100644 --- a/Examples/tcl/constants/Makefile +++ b/Examples/tcl/constants/Makefile @@ -14,6 +14,6 @@ static:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/constants/example.i b/Examples/tcl/constants/example.i index 29a1a7f11..4f7b1a4d7 100644 --- a/Examples/tcl/constants/example.i +++ b/Examples/tcl/constants/example.i @@ -19,8 +19,9 @@ /* Neither should this (BAR isn't defined) */ #define FOO (ICONST + BAR) -/* The following statements also produce constants */ -const int iconst = 37; -const double fconst = 3.14; +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/tcl/enum/.cvsignore b/Examples/tcl/enum/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/enum/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/enum/Makefile b/Examples/tcl/enum/Makefile index 942f4cf8f..7d3d5f9cb 100644 --- a/Examples/tcl/enum/Makefile +++ b/Examples/tcl/enum/Makefile @@ -14,6 +14,6 @@ static:: TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mytclsh *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/funcptr/.cvsignore b/Examples/tcl/funcptr/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/funcptr/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/funcptr/Makefile b/Examples/tcl/funcptr/Makefile index fcb994d09..6efb6fb84 100644 --- a/Examples/tcl/funcptr/Makefile +++ b/Examples/tcl/funcptr/Makefile @@ -14,6 +14,6 @@ static:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/funcptr/example.c b/Examples/tcl/funcptr/example.c index 99583b72e..5c4a3dabf 100644 --- a/Examples/tcl/funcptr/example.c +++ b/Examples/tcl/funcptr/example.c @@ -15,3 +15,5 @@ int sub(int a, int b) { int mul(int a, int b) { return a*b; } + +int (*funcvar)(int,int) = add; diff --git a/Examples/tcl/funcptr/example.i b/Examples/tcl/funcptr/example.i index 73cc6eb8c..8b3bef678 100644 --- a/Examples/tcl/funcptr/example.i +++ b/Examples/tcl/funcptr/example.i @@ -8,8 +8,9 @@ extern int do_op(int a, int b, int (*op)(int, int)); /* Now install a bunch of "ops" as constants */ -%constant(int (*)(int,int)) ADD = add; -%constant(int (*)(int,int)) SUB = sub; -%constant(int (*)(int,int)) MUL = mul; +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; +extern int (*funcvar)(int,int); diff --git a/Examples/tcl/import/.cvsignore b/Examples/tcl/import/.cvsignore new file mode 100644 index 000000000..02f077192 --- /dev/null +++ b/Examples/tcl/import/.cvsignore @@ -0,0 +1,4 @@ +bar_wrap.cxx +base_wrap.cxx +foo_wrap.cxx +spam_wrap.cxx diff --git a/Examples/tcl/import/Makefile b/Examples/tcl/import/Makefile new file mode 100644 index 000000000..b0c0a8f0e --- /dev/null +++ b/Examples/tcl/import/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SWIGOPT = -c +#If your system requires linking with the runtime libraries then set the directory location here +RUNTIMEDIR = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='base' INTERFACE='base.i' tcl_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' tcl_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' tcl_multi_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' tcl_multi_cpp + + + +clean:: + $(MAKE) -f $(TOP)/Makefile tcl_clean + +check: all diff --git a/Examples/tcl/import/README b/Examples/tcl/import/README new file mode 100644 index 000000000..25d0e98ec --- /dev/null +++ b/Examples/tcl/import/README @@ -0,0 +1,28 @@ +This example tests the SWIG run-time libraries and use of the +%import directive to work with multiple modules. + +Use 'tclsh runme.tcl' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module used %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is working correctly, all of the modules will load +correctly and type checking will work correctly. The +example requires the use of the SWIG run-time libraries +which must be built and properly installed. + + + + diff --git a/Examples/tcl/import/bar.h b/Examples/tcl/import/bar.h new file mode 100644 index 000000000..fa4185f1f --- /dev/null +++ b/Examples/tcl/import/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual void A() { + printf("I'm Bar::A\n"); + } + void B() { + printf("I'm Bar::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast(b); + } + +}; + + diff --git a/Examples/tcl/import/bar.i b/Examples/tcl/import/bar.i new file mode 100644 index 000000000..5816cbe17 --- /dev/null +++ b/Examples/tcl/import/bar.i @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + diff --git a/Examples/tcl/import/base.h b/Examples/tcl/import/base.h new file mode 100644 index 000000000..be3cdef7d --- /dev/null +++ b/Examples/tcl/import/base.h @@ -0,0 +1,18 @@ +#include + +class Base { + public: + Base() { }; + ~Base() { }; + virtual void A() { + printf("I'm Base::A\n"); + } + void B() { + printf("I'm Base::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } +}; + + diff --git a/Examples/tcl/import/base.i b/Examples/tcl/import/base.i new file mode 100644 index 000000000..f6e19efd8 --- /dev/null +++ b/Examples/tcl/import/base.i @@ -0,0 +1,6 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h diff --git a/Examples/tcl/import/foo.h b/Examples/tcl/import/foo.h new file mode 100644 index 000000000..dd5184031 --- /dev/null +++ b/Examples/tcl/import/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual void A() { + printf("I'm Foo::A\n"); + } + void B() { + printf("I'm Foo::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/tcl/import/foo.i b/Examples/tcl/import/foo.i new file mode 100644 index 000000000..27feb2e6a --- /dev/null +++ b/Examples/tcl/import/foo.i @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + diff --git a/Examples/tcl/import/runme.tcl b/Examples/tcl/import/runme.tcl new file mode 100644 index 000000000..f69f82dec --- /dev/null +++ b/Examples/tcl/import/runme.tcl @@ -0,0 +1,121 @@ +# file: runme.py +# Test various properties of classes defined in separate modules + +puts "Testing the %import directive" +catch { load ./base.so base} +catch { load ./base.dll base} ;# Windows + +catch { load ./foo.so foo} +catch { load ./foo.dll foo} ;# Windows + +catch { load ./bar.so bar} +catch { load ./bar.dll bar} ;# Windows + +catch { load ./spam.so spam} +catch { load ./spam.dll spam} ;# Windows + +# Create some objects + +puts "Creating some objects" + +set a [Base] +set b [Foo] +set c [Bar] +set d [Spam] + +# Try calling some methods +puts "Testing some methods" +puts "Should see 'Base::A' ---> " +$a A +puts "Should see 'Base::B' ---> " +$a B + +puts "Should see 'Foo::A' ---> " +$b A +puts "Should see 'Foo::B' ---> " +$b B + +puts "Should see 'Bar::A' ---> " +$c A +puts "Should see 'Bar::B' ---> " +$c B + +puts "Should see 'Spam::A' ---> " +$d A +puts "Should see 'Spam::B' ---> " +$d B + +# Try some casts + +puts "\nTesting some casts\n" + +Base x -this [$a toBase] +puts "Should see 'Base::A' ---> " +x A +puts "Should see 'Base::B' ---> " +x B +rename x "" + +Base x -this [$b toBase] +puts "Should see 'Foo::A' ---> " +x A +puts "Should see 'Base::B' ---> " +x B +rename x "" + +Base x -this [$c toBase] +puts "Should see 'Bar::A' ---> " +x A +puts "Should see 'Base::B' ---> " +x B +rename x "" + +Base x -this [$d toBase] +puts "Should see 'Spam::A' ---> " +x A +puts "Should see 'Base::B' ---> " +x B +rename x "" + +Bar x -this [$d toBar] +puts "Should see 'Bar::B' ---> " +x B +rename x "" + +puts "\nTesting some dynamic casts\n" +Base x -this [$d toBase] + +puts "Spam -> Base -> Foo : " +set y [Foo_fromBase [x cget -this]] +if {$y != "NULL"} { + puts "bad swig" +} { + puts "good swig" +} + +puts "Spam -> Base -> Bar : " +set y [Bar_fromBase [x cget -this]] +if {$y != "NULL"} { + puts "good swig" +} { + puts "bad swig" +} + +puts "Spam -> Base -> Spam : " +set y [Spam_fromBase [x cget -this]] +if {$y != "NULL"} { + puts "good swig" +} { + puts "bad swig" +} + +puts "Foo -> Spam : " +set y [Spam_fromBase $b] +if {$y != "NULL"} { + puts "bad swig" +} { + puts "good swig" +} + + + diff --git a/Examples/tcl/import/spam.h b/Examples/tcl/import/spam.h new file mode 100644 index 000000000..b4e7a2646 --- /dev/null +++ b/Examples/tcl/import/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual void A() { + printf("I'm Spam::A\n"); + } + void B() { + printf("I'm Spam::B\n"); + } + virtual Base *toBase() { + return static_cast(this); + } + virtual Bar *toBar() { + return static_cast(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast(b); + } +}; + + diff --git a/Examples/tcl/import/spam.i b/Examples/tcl/import/spam.i new file mode 100644 index 000000000..d3d9121db --- /dev/null +++ b/Examples/tcl/import/spam.i @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + diff --git a/Examples/tcl/index.html b/Examples/tcl/index.html index 2fbb3c78e..2c1e0f98e 100644 --- a/Examples/tcl/index.html +++ b/Examples/tcl/index.html @@ -35,6 +35,10 @@ certain C declarations are turned into constants. +
  • +Please see the Windows page in the main manual for information on using the examples on Windows.

    +

  • +
  • The compilation of examples is done using the file Example/Makefile. This makefile performs a manual module compilation which is platform specific. Typically, the steps look like this (Linux): diff --git a/Examples/tcl/multimap/.cvsignore b/Examples/tcl/multimap/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/multimap/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/multimap/Makefile b/Examples/tcl/multimap/Makefile new file mode 100644 index 000000000..6efb6fb84 --- /dev/null +++ b/Examples/tcl/multimap/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = my_tclsh +DLTARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(DLTARGET)' INTERFACE='$(INTERFACE)' tcl + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh + +clean:: + $(MAKE) -f $(TOP)/Makefile tcl_clean + +check: all diff --git a/Examples/tcl/multimap/example.c b/Examples/tcl/multimap/example.c new file mode 100644 index 000000000..d135481af --- /dev/null +++ b/Examples/tcl/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/tcl/multimap/example.dsp b/Examples/tcl/multimap/example.dsp new file mode 100644 index 000000000..419d50f54 --- /dev/null +++ b/Examples/tcl/multimap/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(TCL_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(TCL_LIB) /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(TCL_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(TCL_LIB) /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo TCL_INCLUDE: %TCL_INCLUDE% + echo TCL_LIB: %TCL_LIB% + echo on + ..\..\..\swig -tcl8 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo TCL_INCLUDE: %TCL_INCLUDE% + echo TCL_LIB: %TCL_LIB% + echo on + ..\..\..\swig -tcl8 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/tcl/multimap/example.i b/Examples/tcl/multimap/example.i new file mode 100644 index 000000000..afe7ed7f9 --- /dev/null +++ b/Examples/tcl/multimap/example.i @@ -0,0 +1,68 @@ +/* File : example.i */ +%module example +%include exception.i + +extern int gcd(int x, int y); + +%typemap(tcl8,in) (int argc, char *argv[]) { + Tcl_Obj **listobjv = 0; + int i; + if (Tcl_ListObjGetElements(interp,$input, &$1, &listobjv) == TCL_ERROR) { + SWIG_exception(SWIG_ValueError,"Expected a list"); + return TCL_ERROR; + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + $2[i] = Tcl_GetStringFromObj(listobjv[i],0); + } + $2[i] = 0; +} + +%typemap(tcl8,freearg) char *argv[] { + if ($1) { + free($1); + } +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(tcl8,in) (char *bytes, int len) { + $1 = Tcl_GetStringFromObj($input,&$2); +} + +extern int count(char *bytes, int len, char c); + + +/* This example shows how to wrap a function that mutates a string */ + +%typemap(tcl8,in) (char *str, int len) { + char *temp; + temp = Tcl_GetStringFromObj($input,&$2); + $1 = (char *) malloc($2+1); + memmove($1,temp,$2); +} + +/* Return the mutated string as a new object. */ + +%typemap(tcl8,argout) (char *str, int len) { + Tcl_Obj *o; + o = Tcl_NewStringObj($1,$2); + Tcl_ListObjAppendElement(interp,$result,o); + free($1); +} + +extern void capitalize(char *str, int len); + + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + return TCL_ERROR; + } +} + +extern void circle(double cx, double cy); diff --git a/Examples/tcl/multimap/example.tcl b/Examples/tcl/multimap/example.tcl new file mode 100644 index 000000000..ae61ce7e8 --- /dev/null +++ b/Examples/tcl/multimap/example.tcl @@ -0,0 +1,25 @@ +# file: example.tcl +# Try to load as a dynamic module. + +catch { load ./example.so example} +catch { load ./example.dll example} ;# Windows + +# Call our gcd() function +set x 42 +set y 105 +set g [gcd $x $y] +puts "The gcd of $x and $y is $g" + +# call the gcdmain +gcdmain "gcdmain 42 105" + + +# call count +set c [count "Hello World" l] +puts $c + +# call capitalize + +set c [capitalize "helloworld"] +puts $c + diff --git a/Examples/tcl/operator/.cvsignore b/Examples/tcl/operator/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/operator/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/operator/Makefile b/Examples/tcl/operator/Makefile new file mode 100644 index 000000000..da2a152be --- /dev/null +++ b/Examples/tcl/operator/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tcl_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile tcl_clean + +check: all diff --git a/Examples/tcl/operator/example.h b/Examples/tcl/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/tcl/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/tcl/operator/example.i b/Examples/tcl/operator/example.i new file mode 100644 index 000000000..f108edb4b --- /dev/null +++ b/Examples/tcl/operator/example.i @@ -0,0 +1,28 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(ComplexCopy) Complex::Complex(Complex const &); + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *str() { + static char temp[512]; + sprintf(temp,"(%g,%g)", self->re(), self->im()); + return temp; + } +}; + + diff --git a/Examples/tcl/operator/runme.tcl b/Examples/tcl/operator/runme.tcl new file mode 100644 index 000000000..f76daffe1 --- /dev/null +++ b/Examples/tcl/operator/runme.tcl @@ -0,0 +1,31 @@ +# Operator overloading example + +catch { load ./example.so example} +catch { load ./example.dll example} ;# Windows + +set a [Complex -args 2 3] +set b [Complex -args -5 10] + +puts "a = $a [$a str]" +puts "b = $b [$b str]" + +set c [$a + $b] +Complex -this $c +puts "c = $c [$c str]" + +set d [$a * $b] +Complex -this $d +puts "a*b = [$d str]" + +# Alternative calling convention +set e [Complex_- $a $c] +puts "a-c = [Complex_str $e]" + +set f [new_ComplexCopy $e] +Complex -this $f +puts "f = [$f str]" + +# Call assignment operator +$c = $f +puts "c = [$c str]" + diff --git a/Examples/tcl/pointer/.cvsignore b/Examples/tcl/pointer/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/pointer/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/pointer/Makefile b/Examples/tcl/pointer/Makefile index fcb994d09..6efb6fb84 100644 --- a/Examples/tcl/pointer/Makefile +++ b/Examples/tcl/pointer/Makefile @@ -14,6 +14,6 @@ static:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/pointer/example.i b/Examples/tcl/pointer/example.i index 2ed2b5bbf..841a2de4c 100644 --- a/Examples/tcl/pointer/example.i +++ b/Examples/tcl/pointer/example.i @@ -6,7 +6,9 @@ /* First we'll use the pointer library */ extern void add(int *x, int *y, int *result); -%include pointer.i + +%include cpointer.i +%pointer_functions(int, intp); /* Next we'll use some typemaps */ diff --git a/Examples/tcl/pointer/example.tcl b/Examples/tcl/pointer/example.tcl index d953a55a5..b67583caf 100644 --- a/Examples/tcl/pointer/example.tcl +++ b/Examples/tcl/pointer/example.tcl @@ -5,9 +5,12 @@ catch { load ./example.dll example} ;# Windows # First create some objects using the pointer library. puts "Testing the pointer library" -set a [ptrcreate int 37] -set b [ptrcreate int 42] -set c [ptrcreate int] ;# Memory for result +set a [new_intp] +set b [new_intp] +set c [new_intp] ;# Memory for result + +intp_assign $a 37 +intp_assign $b 42 puts " a = $a" puts " b = $b" @@ -17,13 +20,13 @@ puts " c = $c" add $a $b $c # Now get the result -set r [ptrvalue $c] +set r [intp_value $c] puts " 37 + 42 = $r" # Clean up the pointers -ptrfree $a -ptrfree $b -ptrfree $c +delete_intp $a +delete_intp $b +delete_intp $c # Now try the typemap library # This should be much easier. Now how it is no longer diff --git a/Examples/tcl/reference/.cvsignore b/Examples/tcl/reference/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/reference/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/reference/Makefile b/Examples/tcl/reference/Makefile index 942f4cf8f..7d3d5f9cb 100644 --- a/Examples/tcl/reference/Makefile +++ b/Examples/tcl/reference/Makefile @@ -14,6 +14,6 @@ static:: TARGET='mytclsh' INTERFACE='$(INTERFACE)' tclsh_cpp_static clean:: - rm -f *_wrap* *.o *~ *.so mytclsh *.pyc .~* core + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/reference/example.i b/Examples/tcl/reference/example.i index 8538326f6..e71f297bf 100644 --- a/Examples/tcl/reference/example.i +++ b/Examples/tcl/reference/example.i @@ -31,7 +31,7 @@ public: int size(); /* This wrapper provides an alternative to the [] operator */ - %addmethods { + %extend { Vector &get(int index) { return (*self)[index]; } diff --git a/Examples/tcl/simple/.cvsignore b/Examples/tcl/simple/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/simple/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/simple/Makefile b/Examples/tcl/simple/Makefile index fcb994d09..6efb6fb84 100644 --- a/Examples/tcl/simple/Makefile +++ b/Examples/tcl/simple/Makefile @@ -14,6 +14,6 @@ static:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/simple/example.dsp b/Examples/tcl/simple/example.dsp new file mode 100644 index 000000000..0f83e360a --- /dev/null +++ b/Examples/tcl/simple/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=example - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(TCL_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(TCL_LIB)" /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(TCL_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(TCL_LIB)" /nologo /dll /machine:I386 /out:"example.dll" + +!ENDIF + +# Begin Target + +# Name "example - Win32 Debug" +# Name "example - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\example.c +# End Source File +# Begin Source File + +SOURCE=.\example_wrap.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\example.i + +!IF "$(CFG)" == "example - Win32 Debug" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo TCL_INCLUDE: %TCL_INCLUDE% + echo TCL_LIB: %TCL_LIB% + echo on + ..\..\..\swig -tcl8 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "example - Win32 Release" + +# Begin Custom Build +InputPath=.\example.i +InputName=example + +"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo In order to function correctly, please ensure the following environment variables are correctly set: + echo TCL_INCLUDE: %TCL_INCLUDE% + echo TCL_LIB: %TCL_LIB% + echo on + ..\..\..\swig -tcl8 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/Examples/tcl/value/.cvsignore b/Examples/tcl/value/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/value/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/value/Makefile b/Examples/tcl/value/Makefile index fcb994d09..6efb6fb84 100644 --- a/Examples/tcl/value/Makefile +++ b/Examples/tcl/value/Makefile @@ -14,6 +14,6 @@ static:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/variables/.cvsignore b/Examples/tcl/variables/.cvsignore new file mode 100644 index 000000000..5f25c5b9a --- /dev/null +++ b/Examples/tcl/variables/.cvsignore @@ -0,0 +1,9 @@ +*_wrap.c +*_wrap.cxx +example.dll +example.dsw +example.ncb +example.opt +example.plg +Release +Debug diff --git a/Examples/tcl/variables/Makefile b/Examples/tcl/variables/Makefile index fcb994d09..6efb6fb84 100644 --- a/Examples/tcl/variables/Makefile +++ b/Examples/tcl/variables/Makefile @@ -14,6 +14,6 @@ static:: TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh clean:: - rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl + $(MAKE) -f $(TOP)/Makefile tcl_clean check: all diff --git a/Examples/tcl/variables/example.i b/Examples/tcl/variables/example.i index c1e614cec..91bd0679d 100644 --- a/Examples/tcl/variables/example.i +++ b/Examples/tcl/variables/example.i @@ -27,10 +27,10 @@ extern Point pt; /* Some read-only variables */ -%readonly { - extern int status; - extern char path[256]; -} +%immutable; +extern int status; +extern char path[256]; +%mutable; /* Some helper functions to make it easier to test */ extern void print_vars(); diff --git a/Examples/tcl/variables/index.html b/Examples/tcl/variables/index.html index 368332b14..f299fbfa8 100644 --- a/Examples/tcl/variables/index.html +++ b/Examples/tcl/variables/index.html @@ -47,21 +47,21 @@ Getting the "value" returns a pointer to the global variable. Setting the value

    Creating read-only variables

    -The %readonly and %readwrite directives can be used to +The %immutable and %mutable directives can be used to specify a collection of read-only variables. For example:
    -%readonly
    +%immutable;
     int    status;
     double blah;
     ...
    -%readwrite
    +%mutable;
     
    -The %readonly directive remains in effect until it is explicitly disabled -using the %readwrite directive. +The %immutable directive remains in effect until it is explicitly disabled +using the %mutable directive.

    Comments

      diff --git a/Examples/test-suite/README b/Examples/test-suite/README new file mode 100644 index 000000000..96dea942c --- /dev/null +++ b/Examples/test-suite/README @@ -0,0 +1,42 @@ +SWIG testsuite README file +-------------------------- + +This testsuite is here to ensure SWIG can handle a wide range of c/c++ +syntax. The testsuite comprises many testcases in this directory. Each +test case is tested under each of the language modules thereby +thoroughly testing all of SWIG. It ensures that each of the language +modules are at a similar standard. + +Those modules that support shadow classes run the tests producing +shadow classes to test the full language module functionality. + +Some test cases need a runtime test. These need implementing in each +of the language modules. The language modules look for a file in the +language specific test-suite directory which has _runme appended after +the testcase name. If one is found it will be run as part of the test. + +Some language modules add to this common set of test cases for +language specific tests. These can be found in the appropriate +language test-suite directory. There is also a README in each of the +language module directories. + +For each testcase a message showing which testcase is being tested is +displayed. Nothing else is printed unless the test fails. + + +Some Developer Guidelines +------------------------- + +Note that the whole test suite need not be run each time a testcase is +modified. An individual testcase may be run by going to the language +module test-suite directory and using make testcasename.xxx where xxx +is the type of test (eg cpptest). See common.mk. make -s doesn't print +any junk on the screen and is useful for emulating the way make check +works from the SWIG root directory. + +If there are runtime tests needed, don't print anything unless there +is an error in which case stderr is suggested. + +Please set the name of the module to the same name as the testcase, +otherwise modules will not be found. + diff --git a/Examples/test-suite/abstract_inherit.i b/Examples/test-suite/abstract_inherit.i new file mode 100644 index 000000000..5610c72d3 --- /dev/null +++ b/Examples/test-suite/abstract_inherit.i @@ -0,0 +1,20 @@ +%module abstract_inherit + +%warnfilter(403) Spam; +%warnfilter(403) Bar; + +%inline %{ + +class Foo { +public: + virtual int blah() = 0; +}; + +class Bar : public Foo { }; + +class Spam: public Foo { +public: + Spam() { } +}; + +%} diff --git a/Examples/test-suite/abstract_inherit_ok.i b/Examples/test-suite/abstract_inherit_ok.i new file mode 100644 index 000000000..04715bad3 --- /dev/null +++ b/Examples/test-suite/abstract_inherit_ok.i @@ -0,0 +1,21 @@ +%module abstract_inherit_ok + +%feature("notabstract") Spam; +%warnfilter(403) Spam; + +%inline %{ + +class Foo { +public: + virtual int blah() = 0; +}; + +class Spam: public Foo { +public: + Spam() { } +#ifndef SWIG + int blah() { return 0; } +#endif +}; + +%} diff --git a/Examples/test-suite/abstract_signature.i b/Examples/test-suite/abstract_signature.i new file mode 100644 index 000000000..50ccbfc7a --- /dev/null +++ b/Examples/test-suite/abstract_signature.i @@ -0,0 +1,25 @@ +%module abstract_signature + +%warnfilter(801) abstract_foo; // Ruby, wrong class name +%warnfilter(801) abstract_bar; // Ruby, wrong class name + +%inline %{ +class abstract_foo +{ +public: + abstract_foo() { }; + virtual ~abstract_foo() { }; + virtual int meth(int meth_param) = 0; +}; + + +class abstract_bar : public abstract_foo +{ +public: + abstract_bar() { }; + + virtual ~abstract_bar() { }; + int meth(int meth_param_1, int meth_param_2) { return 0; } +}; + +%} diff --git a/Examples/test-suite/abstract_typedef.i b/Examples/test-suite/abstract_typedef.i new file mode 100644 index 000000000..89107dfc2 --- /dev/null +++ b/Examples/test-suite/abstract_typedef.i @@ -0,0 +1,52 @@ +%module abstract_typedef + + +%inline %{ + struct Engine + { + }; + + struct Object + { + virtual bool write(Engine& archive) const = 0; + }; + + typedef Engine PersEngine; + typedef Object PersClassBase; + + + class A : public PersClassBase + { + // This works always + // bool write(Engine& archive) const; + + // This doesn't with Swig 1.3.17. + // But it works fine with 1.3.16 + bool write(PersEngine& archive) const + { + return true; + } + + + }; + +%} + + +/* + +Problem related to the direct comparison of strings +in the file allocate.cxx (line 55) + + ...... + String *local_decl = Getattr(dn,"decl"); + if (local_decl && !Strcmp(local_decl, base_decl)) { + ...... + +with the direct string comparison, no equivalent types +are checked and the two 'write' functions appear to be +different because + + "q(const).f(r.bss::PersEngine)." != "q(const).f(r.bss::Engine)." + +*/ diff --git a/Examples/test-suite/add_link.i b/Examples/test-suite/add_link.i new file mode 100644 index 000000000..dfd4b376d --- /dev/null +++ b/Examples/test-suite/add_link.i @@ -0,0 +1,20 @@ +%module add_link + +%extend Foo { +Foo *blah() { + return new Foo(); +} +}; + + +%inline %{ +class Foo { +public: + Foo() { }; +}; + +%} + + + + diff --git a/Examples/test-suite/anonymous_arg.i b/Examples/test-suite/anonymous_arg.i new file mode 100644 index 000000000..b2417fda2 --- /dev/null +++ b/Examples/test-suite/anonymous_arg.i @@ -0,0 +1,12 @@ +/* This interface file checks whether the SWIG parses anonymous + arguments with default values. Bug reported by Annalisa Terracina + on 2001-07-03. +*/ + +%module anonymous_arg + +void foo(int = 7771); + +%{ + void foo(int x) {} +%} diff --git a/Examples/test-suite/argout.i b/Examples/test-suite/argout.i new file mode 100644 index 000000000..1584a9728 --- /dev/null +++ b/Examples/test-suite/argout.i @@ -0,0 +1,37 @@ +/* This interface file checks how well SWIG handles passing data back + through arguments WITHOUT returning it seperatly; for the cases where + maybe multiple values are passed by refernce and all want changing */ + +%module argout + +%include cpointer.i +%pointer_functions(int,intp); + +%inline %{ +// returns old value +int incp(int *value) { + return (*value)++; +} + +// returns old value +int incr(int &value) { + return value++; +} + +typedef int & IntRef; +// returns old value +int inctr(IntRef value) { + return value++; +} + +// example of the old DB login type routines where you keep +// a void* which it points to its opaque struct when you login +// So login function takes a void** +void voidhandle(void** handle) { + *handle=(void*)"Here it is"; +} +char * handle(void* handle) { + return (char *)handle; +} + +%} diff --git a/Examples/test-suite/arrayptr.i b/Examples/test-suite/arrayptr.i new file mode 100644 index 000000000..b7fe29af2 --- /dev/null +++ b/Examples/test-suite/arrayptr.i @@ -0,0 +1,12 @@ +// A module with a function that involves pointers to arrays + +%module arrayptr + +%inline %{ + +void foo(int (*x)[10]) { + +} +%} + + diff --git a/Examples/test-suite/arrays.i b/Examples/test-suite/arrays.i new file mode 100644 index 000000000..57912905d --- /dev/null +++ b/Examples/test-suite/arrays.i @@ -0,0 +1,52 @@ +/* +This test case tests that various types of arrays are working. +*/ + +%module arrays +%pragma make_default + +%inline %{ +#define ARRAY_LEN 2 + +typedef enum {One, Two, Three, Four, Five} finger; + +typedef struct { + double double_field; +} SimpleStruct; + +typedef struct { + char array_c [ARRAY_LEN]; + signed char array_sc[ARRAY_LEN]; + unsigned char array_uc[ARRAY_LEN]; + short array_s [ARRAY_LEN]; + unsigned short array_us[ARRAY_LEN]; + int array_i [ARRAY_LEN]; + unsigned int array_ui[ARRAY_LEN]; + long array_l [ARRAY_LEN]; + unsigned long array_ul[ARRAY_LEN]; + long long array_ll[ARRAY_LEN]; + float array_f [ARRAY_LEN]; + double array_d [ARRAY_LEN]; + SimpleStruct array_struct[ARRAY_LEN]; + SimpleStruct* array_structpointers[ARRAY_LEN]; + int* array_ipointers [ARRAY_LEN]; + finger array_enum[ARRAY_LEN]; + finger* array_enumpointers[ARRAY_LEN]; + const int array_const_i[ARRAY_LEN]; +} ArrayStruct; + +void fn_taking_arrays(SimpleStruct array_struct[ARRAY_LEN]) {} + +/* Pointer helper functions used in the Java run test */ +int* newintpointer() { + return (int*)malloc(sizeof(int)); +} +void setintfrompointer(int* intptr, int value) { + *intptr = value; +} +int getintfrompointer(int* intptr) { + return *intptr; +} + +%} + diff --git a/Examples/test-suite/arrays_global.i b/Examples/test-suite/arrays_global.i new file mode 100644 index 000000000..c5140acc8 --- /dev/null +++ b/Examples/test-suite/arrays_global.i @@ -0,0 +1,37 @@ +/* +This test case tests that various types of arrays are working. +*/ + +%module arrays_global +%pragma make_default + +%inline %{ +#define ARRAY_LEN 2 + +typedef enum {One, Two, Three, Four, Five} finger; + +typedef struct { + double double_field; +} SimpleStruct; + +char array_c [ARRAY_LEN]; +signed char array_sc[ARRAY_LEN]; +unsigned char array_uc[ARRAY_LEN]; +short array_s [ARRAY_LEN]; +unsigned short array_us[ARRAY_LEN]; +int array_i [ARRAY_LEN]; +unsigned int array_ui[ARRAY_LEN]; +long array_l [ARRAY_LEN]; +unsigned long array_ul[ARRAY_LEN]; +long long array_ll[ARRAY_LEN]; +float array_f [ARRAY_LEN]; +double array_d [ARRAY_LEN]; +SimpleStruct array_struct[ARRAY_LEN]; +SimpleStruct* array_structpointers[ARRAY_LEN]; +int* array_ipointers [ARRAY_LEN]; +finger array_enum[ARRAY_LEN]; +finger* array_enumpointers[ARRAY_LEN]; +const int array_const_i[ARRAY_LEN] = {10, 20}; + +%} + diff --git a/Examples/test-suite/arrays_global_twodim.i b/Examples/test-suite/arrays_global_twodim.i new file mode 100644 index 000000000..0cacceb3e --- /dev/null +++ b/Examples/test-suite/arrays_global_twodim.i @@ -0,0 +1,42 @@ +/* +Two dimension arrays +*/ + +%module arrays_global_twodim + +%inline %{ +#define ARRAY_LEN_X 2 +#define ARRAY_LEN_Y 4 + +typedef enum {One, Two, Three, Four, Five} finger; + +typedef struct { + double double_field; +} SimpleStruct; + +char array_c [ARRAY_LEN_X][ARRAY_LEN_Y]; +signed char array_sc[ARRAY_LEN_X][ARRAY_LEN_Y]; +unsigned char array_uc[ARRAY_LEN_X][ARRAY_LEN_Y]; +short array_s [ARRAY_LEN_X][ARRAY_LEN_Y]; +unsigned short array_us[ARRAY_LEN_X][ARRAY_LEN_Y]; +int array_i [ARRAY_LEN_X][ARRAY_LEN_Y]; +unsigned int array_ui[ARRAY_LEN_X][ARRAY_LEN_Y]; +long array_l [ARRAY_LEN_X][ARRAY_LEN_Y]; +unsigned long array_ul[ARRAY_LEN_X][ARRAY_LEN_Y]; +long long array_ll[ARRAY_LEN_X][ARRAY_LEN_Y]; +float array_f [ARRAY_LEN_X][ARRAY_LEN_Y]; +double array_d [ARRAY_LEN_X][ARRAY_LEN_Y]; +SimpleStruct array_struct[ARRAY_LEN_X][ARRAY_LEN_Y]; +SimpleStruct* array_structpointers[ARRAY_LEN_X][ARRAY_LEN_Y]; +int* array_ipointers [ARRAY_LEN_X][ARRAY_LEN_Y]; +finger array_enum[ARRAY_LEN_X][ARRAY_LEN_Y]; +finger* array_enumpointers[ARRAY_LEN_X][ARRAY_LEN_Y]; +const int array_const_i[ARRAY_LEN_X][ARRAY_LEN_Y] = { {10, 11, 12, 13}, {14, 15, 16, 17} }; + +void fn_taking_arrays(SimpleStruct array_struct[ARRAY_LEN_X][ARRAY_LEN_Y]) {} + +int get_2d_array(int (*array)[ARRAY_LEN_Y], int x, int y){ + return array[x][y]; +} +%} + diff --git a/Examples/test-suite/arrays_scope.i b/Examples/test-suite/arrays_scope.i new file mode 100644 index 000000000..164f7ec32 --- /dev/null +++ b/Examples/test-suite/arrays_scope.i @@ -0,0 +1,19 @@ +%module arrays_scope + +%inline %{ + +enum { ASIZE = 256 }; +namespace foo { + enum { BSIZE = 512 }; + class Bar { + public: + enum { CSIZE = 768 }; + int adata[ASIZE]; + int bdata[BSIZE]; + int cdata[CSIZE]; + void blah(int x[ASIZE], int y[BSIZE], int z[CSIZE]) { }; + }; +} + +%} + diff --git a/Examples/test-suite/bool_default.i b/Examples/test-suite/bool_default.i new file mode 100644 index 000000000..b04035c1a --- /dev/null +++ b/Examples/test-suite/bool_default.i @@ -0,0 +1,9 @@ +// [ 548272] Default arguments +%module bool_default + +%inline %{ + +bool foo(bool x = true) { + return !x; +} +%} diff --git a/Examples/test-suite/casts.i b/Examples/test-suite/casts.i new file mode 100644 index 000000000..4893756f0 --- /dev/null +++ b/Examples/test-suite/casts.i @@ -0,0 +1,21 @@ +%module casts + +%inline %{ + +class A { + public: + A() {} + + void hello() + { + } +}; + +class B : public A +{ + public: + B() {} + +}; + +%} diff --git a/Examples/test-suite/char_constant.i b/Examples/test-suite/char_constant.i new file mode 100644 index 000000000..bcbc0680d --- /dev/null +++ b/Examples/test-suite/char_constant.i @@ -0,0 +1,11 @@ +/* This interface file tests whether character constants are correctly + wrapped as procedures returning Scheme characters (rather than + Scheme strings). +*/ + +%module char_constant + +#define CHAR_CONSTANT 'x' + +#define STRING_CONSTANT "xyzzy" + diff --git a/Examples/test-suite/class_ignore.i b/Examples/test-suite/class_ignore.i new file mode 100644 index 000000000..4929fca68 --- /dev/null +++ b/Examples/test-suite/class_ignore.i @@ -0,0 +1,20 @@ +%module class_ignore + +%ignore Foo; + +%inline %{ +class Foo { +public: + virtual char *blah() = 0; +}; + +class Bar : public Foo { +public: + virtual char *blah() { return (char *) "Bar::blah"; } +}; + +char *do_blah(Foo *f) { + return f->blah(); +} +%} + diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk new file mode 100644 index 000000000..f2bf9b303 --- /dev/null +++ b/Examples/test-suite/common.mk @@ -0,0 +1,291 @@ +####################################################################### +# $Header$ +# +# SWIG test suite makefile. +# The test suite comprises many different test cases, which have +# typically produced bugs in the past. The aim is to have the test +# cases compiling for every language modules. Some testcase have +# a runtime test which is written in each of the module's language. +# +# This makefile runs SWIG on the testcases, compiles the c/c++ code +# then builds the object code for use by the language. +# To complete a test in a language follow these guidelines: +# 1) Add testcases to CPP_TEST_CASES (c++) or C_TEST_CASES (c) or +# MULTI_CPP_TEST_CASES (multi-module c++ tests) +# 2) If not already done, create a makefile which: +# a) Defines LANGUAGE matching a language rule in Examples/Makefile, +# for example LANGUAGE = java +# b) Define rules for %.ctest, %.cpptest, %.multicpptest and %.clean. +# +# The variables below can be overridden after including this makefile +####################################################################### + +####################################################################### +# Variables +####################################################################### +TOP = ../.. +SWIG = $(TOP)/../swig +SWIG_LIB = $(TOP)/../Lib +TEST_SUITE = test-suite +CXXSRCS = +CSRCS = +TARGETPREFIX = +TARGETSUFFIX = +SWIGOPT = -I$(TOP)/$(TEST_SUITE) +INCLUDES = -I$(TOP)/$(TEST_SUITE) +RUNTIMEDIR = ../$(TOP)/Runtime/.libs +DYNAMIC_LIB_PATH = $(RUNTIMEDIR):. + +# Please keep test cases in alphabetical order. +# +# EXCEPTION: PLEASE PUT BROKEN TEST CASES AT THE TOP OF THIS LIST. + +# C++ test cases. (Can be run individually using make testcase.cpptest.) + +CPP_TEST_BROKEN = \ + abstract_typedef \ + namespace_nested \ + template_default_arg \ + using_namespace + +CPP_TEST_CASES += $(CPP_TEST_BROKEN) + +CPP_TEST_CASES += \ + abstract_inherit \ + abstract_inherit_ok \ + abstract_signature \ + add_link \ + anonymous_arg \ + argout \ + arrays_global \ + arrays_global_twodim \ + arrays_scope \ + bool_default \ + casts \ + class_ignore \ + const_const_2 \ + constant_pointers \ + constover \ + constructor_exception \ + constructor_explicit \ + constructor_value \ + conversion \ + conversion_namespace \ + conversion_ns_template \ + cplusplus_throw \ + cpp_enum \ + cpp_enum_scope \ + cpp_enum_scope \ + cpp_namespace \ + cpp_nodefault \ + cpp_static \ + cpp_typedef \ + default_cast \ + default_constructor \ + default_ns \ + default_ref \ + dynamic_cast \ + enum_scope \ + enum_scope_template \ + enum_var \ + evil_diamond \ + evil_diamond_ns \ + evil_diamond_prop \ + explicit \ + extend_template \ + extend_template_ns \ + grouping \ + ignore_parameter \ + import_nomodule \ + inherit_missing \ + kind \ + lib_carrays \ + lib_cdata \ + lib_cpointer \ + lib_std_deque \ + lib_std_string \ + lib_std_vector \ + lib_typemaps \ + member_template \ + minherit \ + name_cxx \ + name_inherit \ + namespace_enum \ + namespace_extend \ + namespace_template \ + namespace_typemap \ + newobject1 \ + overload_complicated \ + overload_copy \ + overload_extend \ + overload_simple \ + overload_subtype \ + overload_template \ + pointer_reference \ + primitive_ref \ + private_assign \ + pure_virtual \ + rename_default \ + rename_default \ + rename_scope \ + return_value_scope \ + rname \ + smart_pointer_const \ + smart_pointer_multi \ + smart_pointer_multi_typedef \ + smart_pointer_not \ + smart_pointer_overload \ + smart_pointer_protected \ + smart_pointer_rename \ + smart_pointer_simple \ + smart_pointer_typedef \ + static_array_member \ + static_const_member \ + static_const_member_2 \ + struct_value \ + template \ + template_arg_scope \ + template_arg_typename \ + template_base_template \ + template_classes \ + template_const_ref \ + template_construct \ + template_default \ + template_default2 \ + template_default_inherit \ + template_default_qualify \ + template_enum \ + template_enum_ns_inherit \ + template_enum_typedef \ + template_forward \ + template_inherit \ + template_inherit_abstract \ + template_int_const \ + template_ns \ + template_ns2 \ + template_ns3 \ + template_ns4 \ + template_ns_enum \ + template_ns_enum2 \ + template_ns_inherit \ + template_ns_scope \ + template_qualifier \ + template_qualifier \ + template_rename \ + template_retvalue \ + template_specialization \ + template_static \ + template_tbase_template \ + template_type_namespace \ + template_typedef \ + template_typedef_cplx \ + template_typedef_cplx2 \ + template_typedef_cplx3 \ + template_typedef_cplx4 \ + template_virtual \ + template_whitespace \ + throw_exception \ + typedef_array_member \ + typedef_funcptr \ + typedef_inherit \ + typedef_mptr \ + typedef_reference \ + typedef_scope \ + typemap_namespace \ + typemap_ns_using \ + typename \ + union_scope \ + using1 \ + using2 \ + using_composition \ + using_extend \ + using_inherit \ + using_private \ + using_protected \ + valuewrapper_base \ + virtual_destructor \ + voidtest + +# C test cases. (Can be run individually using make testcase.ctest.) +C_TEST_CASES += \ + arrayptr \ + arrays \ + char_constant \ + const_const \ + defineop \ + defines \ + enum \ + lib_carrays \ + lib_cdata \ + lib_cmalloc \ + lib_constraints \ + lib_cpointer \ + lib_math \ + long_long \ + macro_2 \ + name \ + nested \ + newobject2 \ + overload_extendc \ + preproc_1 \ + preproc_2 \ + preproc_3 \ + ret_by_value \ + sizeof_pointer \ + sneaky1 \ + typemap_subst \ + unions + + +MULTI_CPP_TEST_CASES += \ + imports \ + template_typedef_import + +ALL_TEST_CASES = $(CPP_TEST_CASES:=.cpptest) \ + $(C_TEST_CASES:=.ctest) \ + $(MULTI_CPP_TEST_CASES:=.multicpptest) +ALL_CLEAN = $(CPP_TEST_CASES:=.clean) \ + $(C_TEST_CASES:=.clean) \ + $(MULTI_CPP_TEST_CASES:=.clean) + +####################################################################### +# The following applies for all module languages +####################################################################### +all: $(ALL_TEST_CASES) + +check: all + +swig_and_compile_cpp = \ + $(MAKE) -f $(TOP)/Makefile CXXSRCS="$(CXXSRCS)" SWIG_LIB="$(SWIG_LIB)" SWIG="$(SWIG)" \ + INCLUDES="$(INCLUDES)" SWIGOPT="$(SWIGOPT)" NOLINK=true \ + TARGET="$(TARGETPREFIX)$*$(TARGETSUFFIX)" INTERFACE="$*.i" \ + $(LANGUAGE)$(VARIANT)_cpp + +swig_and_compile_c = \ + $(MAKE) -f $(TOP)/Makefile CSRCS="$(CSRCS)" SWIG_LIB="$(SWIG_LIB)" SWIG="$(SWIG)" \ + INCLUDES="$(INCLUDES)" SWIGOPT="$(SWIGOPT)" NOLINK=true \ + TARGET="$(TARGETPREFIX)$*$(TARGETSUFFIX)" INTERFACE="$*.i" \ + $(LANGUAGE)$(VARIANT) + +swig_and_compile_multi_cpp = \ + for f in `cat $(TOP)/$(TEST_SUITE)/$*.list` ; do \ + $(MAKE) -f $(TOP)/Makefile CXXSRCS="$(CXXSRCS)" SWIG_LIB="$(SWIG_LIB)" SWIG="$(SWIG)" \ + INCLUDES="$(INCLUDES)" SWIGOPT="$(SWIGOPT)" RUNTIMEDIR="$(RUNTIMEDIR)" \ + TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACE="$$f.i" \ + NOLINK=true $(LANGUAGE)$(VARIANT)_multi_cpp; \ + done + +setup = \ + @if [ -f $(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ + echo "Checking testcase $* (with run test) under $(LANGUAGE)" ; \ + else \ + echo "Checking testcase $* under $(LANGUAGE)" ; \ + fi; + + + +####################################################################### +# Clean +####################################################################### +clean: $(ALL_CLEAN) + diff --git a/Examples/test-suite/const_const.i b/Examples/test-suite/const_const.i new file mode 100644 index 000000000..7c1c92d22 --- /dev/null +++ b/Examples/test-suite/const_const.i @@ -0,0 +1,13 @@ +/* This interface file tests whether SWIG handles types like + "const int *const" right. + + SWIG 1.3a5 signals a syntax error. +*/ + +%module const_const + +%typemap(in) const int *const { $1 = NULL; } + +%inline %{ +void foo(const int *const i) {} +%} diff --git a/Examples/test-suite/const_const_2.i b/Examples/test-suite/const_const_2.i new file mode 100644 index 000000000..9094262a6 --- /dev/null +++ b/Examples/test-suite/const_const_2.i @@ -0,0 +1,21 @@ +/* This interface file tests whether SWIG handles doubly constant + methods right. SF Bug #216057 against Swig 1.3a5, reported by + Mike Romberg +*/ + +%module const_const_2 + +%inline %{ +class Spam { +public: + Spam() {} +}; + +class Eggs { + public: + Eggs() {} + + const Spam *spam(void) const { return new Spam(); } +}; + + %} diff --git a/Examples/test-suite/constant_pointers.i b/Examples/test-suite/constant_pointers.i new file mode 100644 index 000000000..7edc6d4fd --- /dev/null +++ b/Examples/test-suite/constant_pointers.i @@ -0,0 +1,74 @@ +/* +This testcase primarily test constant pointers, eg int* const. Only a getter is expected to be produced when wrapping constant pointer variables. A number of other const issues are also tested. +*/ + +%module constant_pointers + +%inline %{ + +int GlobalInt; +const int ConstInt=2; +int* GlobalIntPtr=&GlobalInt; +int* const GlobalConstIntPtr=&GlobalInt; +#define ARRAY_SIZE 2 + +class ParametersTest { +public: + void param1(int* a) {} + void param2(const int* a) {} + void param3(int* const a) {} + void param4(int const a) {} + void param5(const int a) {} + void param6(int& a) {} + void param7(const int& a) {} + void param8(int const& a) {} + void param9(int*& a) {} + void param10(int* const& a) {} + void param11(const int* const a) {} + + void param_array1(int* a[ARRAY_SIZE]) {} + void param_array2(const int* a[ARRAY_SIZE]) {} + void param_array3(int* const a[ARRAY_SIZE]) {} + void param_array4(int const a[ARRAY_SIZE]) {} + void param_array5(const int a[ARRAY_SIZE]) {} + void param_array6(const int* const a[ARRAY_SIZE]) {} +}; + +class MemberVariablesTest { +public: + int* member1; + ParametersTest* member2; + int* const member3; + ParametersTest* const member4; + + int* array_member1[ARRAY_SIZE]; + ParametersTest* array_member2[ARRAY_SIZE]; + int* const array_member3[ARRAY_SIZE]; + ParametersTest* const array_member4[ARRAY_SIZE]; + MemberVariablesTest() : member3(NULL), member4(NULL) {} +}; +void foo(const int *const i) {} + +typedef int *typedef1, typedef2, *const typedef3; +int int1, int2=2, *int3, *const int4 = &GlobalInt; + +class ReturnValuesTest { +public: + typedef1 td1; + typedef2 td2; + int int1, int2, *const int3, *int4, array1[ARRAY_SIZE], *const array2[ARRAY_SIZE]; + int ret1() {return 5;} + const int ret2() {return 5;} + int ret3() {return 5;} + const int* ret4() {return &ConstInt;} + int* const ret5() {return &GlobalInt;} + + void ret6(int*& a) {} + int*& ret7() {return GlobalIntPtr;} + ReturnValuesTest() : int3(NULL) {} +}; + +const int* globalRet1() {return &GlobalInt;}; +int* const globalRet2() {return &GlobalInt;}; + +%} diff --git a/Examples/test-suite/constover.i b/Examples/test-suite/constover.i new file mode 100644 index 000000000..06f9ac7e2 --- /dev/null +++ b/Examples/test-suite/constover.i @@ -0,0 +1,38 @@ +// This test checks SWIG's code generation for C++ functions +// and methods that differ only in constness. + +%module constover + +%rename(test_pconst) test(const char *); +%rename(test_constm) test(char *) const; +%rename(test_pconstm) test(const char *) const; + +%inline %{ + +char *test(char *x) { + return (char *) "test"; +} + +char *test(const char *x) { + return (char *) "test_pconst"; +} + + class Foo { + public: + Foo() { } + char *test(char *x) { + return (char *) "test"; + } + char *test(const char *x) { + return (char *) "test_pconst"; + } + char *test(char *x) const { + return (char *) "test_constmethod"; + } + char *test(const char *x) const { + return (char *) "test_pconstmethod"; + } + }; + +%} + diff --git a/Examples/test-suite/constructor_exception.i b/Examples/test-suite/constructor_exception.i new file mode 100644 index 000000000..9904e4e1e --- /dev/null +++ b/Examples/test-suite/constructor_exception.i @@ -0,0 +1,27 @@ +%module constructor_exception + +%inline %{ +class Error { +}; + +class Object { +public: + Object(int x) { + if (x < 0) { + throw Error(); + } + } +}; + +class Test { + Object o; +public: + Test(int x) try : o(x) { } + catch (Error &e) { + } + catch (int y) { + } + catch (...) { + } +}; +%} diff --git a/Examples/test-suite/constructor_explicit.i b/Examples/test-suite/constructor_explicit.i new file mode 100644 index 000000000..f7fc534f2 --- /dev/null +++ b/Examples/test-suite/constructor_explicit.i @@ -0,0 +1,13 @@ +%module constructor_explicit +%inline %{ + +class Foo { +public: + explicit Foo() { } +}; + +Foo test(Foo x) { + return x; +} + +%} diff --git a/Examples/test-suite/constructor_value.i b/Examples/test-suite/constructor_value.i new file mode 100644 index 000000000..b5c56d031 --- /dev/null +++ b/Examples/test-suite/constructor_value.i @@ -0,0 +1,15 @@ +%module constructor_value +%inline %{ + +class Foo { +public: +Foo(int a) {}; +}; + +class Bar { +public: +Bar(Foo ci) {} +}; + +%} + diff --git a/Examples/test-suite/conversion.i b/Examples/test-suite/conversion.i new file mode 100644 index 000000000..bad6c147a --- /dev/null +++ b/Examples/test-suite/conversion.i @@ -0,0 +1,11 @@ +%module conversion +%rename(toFoo) Bar::operator Foo(); + +%inline %{ + struct Foo { + }; + struct Bar { + operator Foo () { return Foo(); } + }; +%} + diff --git a/Examples/test-suite/conversion_namespace.i b/Examples/test-suite/conversion_namespace.i new file mode 100644 index 000000000..70d4b9ebc --- /dev/null +++ b/Examples/test-suite/conversion_namespace.i @@ -0,0 +1,14 @@ +%module conversion_namespace +%rename(toFoo) oss::Bar::operator oss::Foo(); + +%inline %{ + namespace oss + { + struct Foo { + }; + struct Bar { + operator Foo () { return Foo(); } + }; + } +%} + diff --git a/Examples/test-suite/conversion_ns_template.i b/Examples/test-suite/conversion_ns_template.i new file mode 100644 index 000000000..34102f98f --- /dev/null +++ b/Examples/test-suite/conversion_ns_template.i @@ -0,0 +1,49 @@ +%module conversion_ns_template +%{ + namespace oss + { + enum Test {One, Two}; + template + struct Foo { + }; + template + struct Bar { + operator int() { return 0; } + operator int&() { static int num = 0; return num; } + operator Foo() { return Foo(); } + operator Foo&() { return *(new Foo()); } + }; + } +%} + + namespace oss + { + enum Test {One, Two}; + + template + struct Foo { + }; + + // these two works + %rename(hello1) Bar::operator int&(); + %ignore Bar::operator int(); + + // these don't + %rename(hello2) Bar::operator Foo&(); + %ignore Bar::operator Foo(); + + template + struct Bar { + operator int(); + operator int&(); + operator Foo(); + operator Foo&(); + }; + } + + +namespace oss +{ + %template(Foo_One) Foo; + %template(Bar_One) Bar; +} diff --git a/Examples/test-suite/cplusplus_throw.i b/Examples/test-suite/cplusplus_throw.i new file mode 100644 index 000000000..268ddc6d0 --- /dev/null +++ b/Examples/test-suite/cplusplus_throw.i @@ -0,0 +1,22 @@ +/* This interface file checks whether the SWIG parses the throw + directive in combination with the const directive. Bug reported by + Scott B. Drummonds, 08 June 2001. +*/ + +%module cplusplus_throw + +%pragma no_default + +%inline %{ + +class Foo { }; + +class Bar { +public: + void baz() const { }; + void foo() throw (Foo) { }; + void bazfoo() const throw (int) { }; +}; + +%} + diff --git a/Examples/test-suite/cpp_enum.i b/Examples/test-suite/cpp_enum.i new file mode 100644 index 000000000..a66cda1c8 --- /dev/null +++ b/Examples/test-suite/cpp_enum.i @@ -0,0 +1,27 @@ +/* +The primary purpose of this testcase is to ensure that enums used along with the 'enum' keyword compile under c++. +*/ + +%module cpp_enum + +%inline %{ + +enum SOME_ENUM {ENUM_ONE, ENUM_TWO}; + +struct StructWithEnums { + StructWithEnums() : some_enum(ENUM_ONE) {}; + enum SOME_ENUM some_enum; + void enum_test1(enum SOME_ENUM param1, enum SOME_ENUM* param2, enum SOME_ENUM& param3) {}; + void enum_test2(SOME_ENUM param1, SOME_ENUM* param2, SOME_ENUM& param3) {}; + + SOME_ENUM enum_test3() { return ENUM_ONE; }; + enum SOME_ENUM enum_test4() { return ENUM_TWO; }; + + SOME_ENUM* enum_test5() { return &some_enum; }; + enum SOME_ENUM* enum_test6() { return &some_enum; }; + + SOME_ENUM& enum_test7() { return some_enum; }; + enum SOME_ENUM& enum_test8() { return some_enum; }; +}; + +%} diff --git a/Examples/test-suite/cpp_enum_scope.i b/Examples/test-suite/cpp_enum_scope.i new file mode 100644 index 000000000..af3c96b70 --- /dev/null +++ b/Examples/test-suite/cpp_enum_scope.i @@ -0,0 +1,17 @@ +%module cpp_enum_scope + +// This tests to make sure default arguments are handled correctly +// when scoped. + +%inline %{ +enum flavor { BITTER, SWEET }; + +class Foo { +public: + enum speed { FAST, SLOW }; + + // Note: default values should be Foo::FAST and SWEET + void blah(speed s = FAST, flavor f = SWEET) {}; +}; + +%} diff --git a/Examples/test-suite/cpp_namespace.i b/Examples/test-suite/cpp_namespace.i new file mode 100644 index 000000000..39e506fe3 --- /dev/null +++ b/Examples/test-suite/cpp_namespace.i @@ -0,0 +1,104 @@ +// C++ namespace tests + +%module cpp_namespace + +%inline %{ + typedef int Bad; + + /* A very basic namespace */ + namespace example { + typedef char *Bad; + + int fact(int n) { + if (n <= 0) return 1; + else return n*fact(n-1); + } + int Foo = 42; + + class Test { + public: + Test() { }; + ~Test() { }; + char *method() { + return (char *) "Test::method"; + } + }; + typedef Test *TestPtr; + void weird(Bad x, ::Bad y) { }; + } + + char *do_method(example::TestPtr t) { + return t->method(); + } + + namespace ex = example; + + char *do_method2(ex::TestPtr t) { + return t->method(); + } + +%} + +// Some more complicated namespace examples + +%inline %{ +namespace Foo { + typedef int Integer; + class Test2 { + public: + virtual char *method() { + return (char *) "Test2::method"; + } + }; + typedef Test2 *Test2Ptr; +} + +namespace Foo2 { + using Foo::Integer; + using Foo::Test2; + class Test3 : public Test2 { + public: + virtual char *method() { + return (char *) "Test3::method"; + } + }; + typedef Test3 *Test3Ptr; + typedef Test3 Test3Alt; +} + +namespace Foo3 { + using namespace Foo2; + class Test4 : public Test3 { + public: + virtual char *method() { + return (char *) "Test4::method"; + } + }; + Integer foo3(Integer x) { return x; } + typedef Test4 *Test4Ptr; + +} + +using Foo2::Test3Alt; +using Foo3::Integer; + +class Test5 : public Test3Alt { +public: + virtual char *method() { + return (char *) "Test5::method"; + } +}; + +char *do_method3(Foo::Test2 *t, Integer x) { + return t->method(); +} + +%} + + + + + + + + diff --git a/Examples/test-suite/cpp_nodefault.i b/Examples/test-suite/cpp_nodefault.i new file mode 100644 index 000000000..fc2703618 --- /dev/null +++ b/Examples/test-suite/cpp_nodefault.i @@ -0,0 +1,42 @@ +// This file tests SWIG pass/return by value for +// a class with no default constructor + +%module cpp_nodefault + +%inline %{ + +class Foo { +public: + int a; + Foo(int x, int y) { } + ~Foo() { + printf("Destroying foo\n"); + } +}; + +Foo create(int x, int y) { + return Foo(x,y); +} + +typedef Foo Foo_t; + +void consume(Foo f, Foo_t g) {} + +class Bar { +public: + void consume(Foo f, Foo_t g) {} + Foo create(int x, int y) { + return Foo(x,y); + } +}; + + +%} + +%{ +Foo gvar = Foo(3,4); +%} + +Foo gvar; + + diff --git a/Examples/test-suite/cpp_static.i b/Examples/test-suite/cpp_static.i new file mode 100644 index 000000000..5009cf528 --- /dev/null +++ b/Examples/test-suite/cpp_static.i @@ -0,0 +1,24 @@ +/* +Testcase to test c++ static member variables and static functions. +Tests Sourceforge bug #444748. +*/ + +%module cpp_static + +%inline %{ + +class StaticMemberTest { +public: + static int static_int; +}; + +class StaticFunctionTest { +public: + static void static_func() {}; +}; + +%} + +%{ +int StaticMemberTest::static_int; +%} diff --git a/Examples/test-suite/cpp_typedef.i b/Examples/test-suite/cpp_typedef.i new file mode 100644 index 000000000..f869f4d9c --- /dev/null +++ b/Examples/test-suite/cpp_typedef.i @@ -0,0 +1,46 @@ +// This file tests SWIG's tracking of C++ typedef declarations + +%module cpp_typedef + +%{ + +class Bar { +public: +}; +%} + +%inline %{ +class Foo { +public: + typedef Bar SomeBar; + typedef SomeBar SomeOtherBar; + SomeOtherBar bar() { + SomeOtherBar b; + return b; + } + static SomeOtherBar sbar() { + SomeOtherBar b; + return b; + } +}; + +// Test that the correct types are used for typedef struct declarations +typedef struct { +} UnnamedStruct; + +typedef struct NamedStruct { +} TypedefNamedStruct; + +typedef TypedefNamedStruct DoubleTypedef; + +class Test { +public: + UnnamedStruct test1(UnnamedStruct a) {return a;}; + struct NamedStruct test2(struct NamedStruct a) {return a;}; + TypedefNamedStruct test3(TypedefNamedStruct a) {return a;}; + DoubleTypedef test4(DoubleTypedef a) {return a;}; +}; + +%} + + diff --git a/Examples/test-suite/default_cast.i b/Examples/test-suite/default_cast.i new file mode 100644 index 000000000..661e8bc7f --- /dev/null +++ b/Examples/test-suite/default_cast.i @@ -0,0 +1,6 @@ +%module default_cast + +%inline %{ +void foo(const char *m = (const char *) NULL) { }; +%} + diff --git a/Examples/test-suite/default_constructor.i b/Examples/test-suite/default_constructor.i new file mode 100644 index 000000000..3d9fe8bed --- /dev/null +++ b/Examples/test-suite/default_constructor.i @@ -0,0 +1,109 @@ +// This module tests default constructor generation under a +// number of different conditions + +%module default_constructor + +%warnfilter(802, 813) EB; /* Ruby, Java multiple inheritance */ +%warnfilter(802, 813) AD; /* Ruby, Java multiple inheritance */ +%warnfilter(510) F; /* friend function */ + +%inline %{ + +/* A class with a public default constructor */ +class A { +public: + A() { }; +}; + +/* This class should get default constructor/destructors */ +class AA : public A { +}; + +/* A class with a public constructor, but not default */ + +class B { +private: + B() { } +public: + B(int x, int y) { } +}; + +/* This class should get no default constructor, but a destructor */ +class BB : public B { +}; + +/* A class with a protected constructor */ +class C { +protected: + C() { }; +public: +}; + +/* This class does get a default constructor/destructor */ +class CC : public C { +}; + + +/* A class with a private constructor */ +class D { +private: + D() { }; +public: + void foo() { }; +}; + +/* This class does not get a default constructor */ +class DD: public D { + +}; + +/* No default constructor. A is okay, but D is not */ +class AD: public A, public D { + +}; + +/* This class has a default constructor because of optional arguments */ +class E { +public: + E(int x = 0, int y = 0) { } +}; + +/* This should get a default constructor */ +class EE : public E { +}; + +/* This class should not get a default constructor. B doesn't have one */ + +class EB : public E, public B { + +}; + +/* A class with a private destructor */ + +class F { +private: + ~F() { } +public: + void foo(int, int) { } + friend void bar(F *); +}; + +void bar(F *) { } + +class FFF : public F { +}; + +/* A class with a protected destructor */ +class G { +protected: + ~G() { } +}; + +class GG : public G { +}; + +%} + + + + diff --git a/Examples/test-suite/default_ns.i b/Examples/test-suite/default_ns.i new file mode 100644 index 000000000..3b03d9515 --- /dev/null +++ b/Examples/test-suite/default_ns.i @@ -0,0 +1,23 @@ +%module default_ns +%inline %{ +namespace AType +{ + enum AType + { + NoType + }; +} + +void dummy(AType::AType aType = AType::NoType) {} + + +namespace A { + namespace B { + int CONST_NUM = 10; + } + int function(int i = B::CONST_NUM) { return 0; } +} + +%} + + diff --git a/Examples/test-suite/default_ref.i b/Examples/test-suite/default_ref.i new file mode 100644 index 000000000..25d20cd69 --- /dev/null +++ b/Examples/test-suite/default_ref.i @@ -0,0 +1,12 @@ +%module default_ref + +%inline %{ +#include + +void test1(const int &x = 42) { +} + +void test2(const std::string &x = "hello") { +} +%} + diff --git a/Examples/test-suite/defineop.i b/Examples/test-suite/defineop.i new file mode 100644 index 000000000..d11ff3026 --- /dev/null +++ b/Examples/test-suite/defineop.i @@ -0,0 +1,22 @@ +/* +This testcase tests operators for defines +*/ + +%module defineop + +#define A1 1 + 2 +#define A2 3 - 4 +#define A3 5 * 6 +#define A4 7 / 8 +#define A5 9 >> 10 +#define A6 11 << 12 +#define A7 13 & 14 +#define A8 15 | 16 +#define A9 17 ^ 18 +#define A10 19 && 20 +#define A11 21 || 21 +#define A12 ~22 +#define A13 !23 + + + diff --git a/Examples/test-suite/defines.i b/Examples/test-suite/defines.i new file mode 100644 index 000000000..70a1db6df --- /dev/null +++ b/Examples/test-suite/defines.i @@ -0,0 +1,18 @@ +/* +This testcase tests for embedded defines and embedded %constants +*/ + +%module defines +%pragma make_default + +%inline %{ + +typedef struct EmbeddedDefines { + int dummy; +#define EMBEDDED_DEFINE 44 +#ifdef SWIG +%constant EMBEDDED_SWIG_CONSTANT = 55; +#endif +} EmbeddedDefines; + +%} diff --git a/Examples/test-suite/dynamic_cast.i b/Examples/test-suite/dynamic_cast.i new file mode 100644 index 000000000..bae28f3cf --- /dev/null +++ b/Examples/test-suite/dynamic_cast.i @@ -0,0 +1,65 @@ +/* File : example.i */ +%module dynamic_cast + +#ifndef SWIGJAVA +%apply SWIGTYPE *DYNAMIC { Foo * }; +#endif + +%inline %{ + +class Foo { +public: + virtual Foo *blah() { + return this; + } +}; +%} + +#ifdef SWIGJAVA +%typemap(out) Foo *blah { + Bar *downcast = dynamic_cast($1); + *(Bar **)&$result = downcast; +} + +%typemap(javaout) Foo * { + return new Bar($jnicall, $owner); + } +#endif + +%inline %{ + +class Bar : public Foo { +public: + virtual Foo *blah() { + return (Foo *) this; + } + virtual char * test() { + return (char *) "Bar::test"; + } +}; + +char *do_test(Bar *b) { + return b->test(); +} +%} + +#ifndef SWIGJAVA +// A general purpose function for dynamic casting of a Foo * +%{ +static swig_type_info * +Foo_dynamic(void **ptr) { + Bar *b; + b = dynamic_cast((Foo *) *ptr); + if (b) { + *ptr = (void *) b; + return SWIGTYPE_p_Bar; + } + return 0; +} +%} + +// Register the above casting function +DYNAMIC_CAST(SWIGTYPE_p_Foo, Foo_dynamic); + +#endif + diff --git a/Examples/test-suite/enum.i b/Examples/test-suite/enum.i new file mode 100644 index 000000000..bcd606c58 --- /dev/null +++ b/Examples/test-suite/enum.i @@ -0,0 +1,26 @@ +/* Test whether anonymous enums are supported well. */ + +%module "enum" + +%inline %{ + +typedef enum { + CSP_ITERATION_FWD, + CSP_ITERATION_BWD +} foo1; + +typedef enum foo2 { + ABCDE = 0, + FGHJI = 1 +} foo3; + +void +bar1(foo1 x) {} + +void +bar2(enum foo2 x) {} + +void +bar3(foo3 x) {} + +%} diff --git a/Examples/test-suite/enum_scope.i b/Examples/test-suite/enum_scope.i new file mode 100644 index 000000000..4afc231c6 --- /dev/null +++ b/Examples/test-suite/enum_scope.i @@ -0,0 +1,16 @@ +%module enum_scope + +#ifdef SWIGPHP +// php internal naming conflict +%rename (chops) chop; +#endif + +%inline %{ +class Tree { +public: +enum types {Oak, Fir, Cedar}; +void chop(enum types type) {} +}; +enum Tree::types chop(enum Tree::types type) { return type; } + +%} diff --git a/Examples/test-suite/enum_scope_template.i b/Examples/test-suite/enum_scope_template.i new file mode 100644 index 000000000..b6b156bd7 --- /dev/null +++ b/Examples/test-suite/enum_scope_template.i @@ -0,0 +1,20 @@ +%module enum_scope_template + +#ifdef SWIGPHP +// php internal naming conflict +%rename (chops) chop; +#endif + +%inline %{ + +template class Tree { +public: + enum types {Oak, Fir, Cedar}; + void chop(enum types type) {} +}; +enum Tree::types chop(enum Tree::types type) { return type; } + +%} + +%template(TreeInt) Tree; + diff --git a/Examples/test-suite/enum_var.i b/Examples/test-suite/enum_var.i new file mode 100644 index 000000000..c8626d803 --- /dev/null +++ b/Examples/test-suite/enum_var.i @@ -0,0 +1,8 @@ +%module enum_var + +%inline %{ + +enum Fruit { APPLE, PEAR }; +Fruit test; + +%} diff --git a/Examples/test-suite/errors/c_bad_name.i b/Examples/test-suite/errors/c_bad_name.i new file mode 100644 index 000000000..43ccb4d18 --- /dev/null +++ b/Examples/test-suite/errors/c_bad_name.i @@ -0,0 +1,4 @@ +%module xxx + +%name() int foo; + diff --git a/Examples/test-suite/errors/c_bad_native.i b/Examples/test-suite/errors/c_bad_native.i new file mode 100644 index 000000000..4d09e04b0 --- /dev/null +++ b/Examples/test-suite/errors/c_bad_native.i @@ -0,0 +1,5 @@ +%module xxx + +%native(foo) int foo; + + diff --git a/Examples/test-suite/errors/c_class.i b/Examples/test-suite/errors/c_class.i new file mode 100644 index 000000000..cd168f67b --- /dev/null +++ b/Examples/test-suite/errors/c_class.i @@ -0,0 +1,8 @@ +%module xxx + +int class(int x); + + + + + diff --git a/Examples/test-suite/errors/c_default_error.i b/Examples/test-suite/errors/c_default_error.i new file mode 100644 index 000000000..f6220e11d --- /dev/null +++ b/Examples/test-suite/errors/c_default_error.i @@ -0,0 +1,4 @@ +%module xxx + +int foo(int x = 42 || 3); + diff --git a/Examples/test-suite/errors/c_deprecated.i b/Examples/test-suite/errors/c_deprecated.i new file mode 100644 index 000000000..27e74397f --- /dev/null +++ b/Examples/test-suite/errors/c_deprecated.i @@ -0,0 +1,8 @@ +%module xxx + +int foo(%val int *x, %out int *y); + + + + + diff --git a/Examples/test-suite/errors/c_empty_char.i b/Examples/test-suite/errors/c_empty_char.i new file mode 100644 index 000000000..0a669af86 --- /dev/null +++ b/Examples/test-suite/errors/c_empty_char.i @@ -0,0 +1,4 @@ +%module xxx + +int foo(int x = ''); + diff --git a/Examples/test-suite/errors/c_enum_badvalue.i b/Examples/test-suite/errors/c_enum_badvalue.i new file mode 100644 index 000000000..8649c03e0 --- /dev/null +++ b/Examples/test-suite/errors/c_enum_badvalue.i @@ -0,0 +1,7 @@ +%module xxx + +enum stuff { + FOO = 'x', + BAR = 3.14159 +}; + diff --git a/Examples/test-suite/errors/c_extra_rblock.i b/Examples/test-suite/errors/c_extra_rblock.i new file mode 100644 index 000000000..3e8e86a19 --- /dev/null +++ b/Examples/test-suite/errors/c_extra_rblock.i @@ -0,0 +1,8 @@ +%module xxx + +int foo(int x); + +%} + + + diff --git a/Examples/test-suite/errors/c_extra_rbrace.i b/Examples/test-suite/errors/c_extra_rbrace.i new file mode 100644 index 000000000..0228f9b1d --- /dev/null +++ b/Examples/test-suite/errors/c_extra_rbrace.i @@ -0,0 +1,7 @@ +%module xxx + +int foo(int); + +} + + diff --git a/Examples/test-suite/errors/c_extra_unsigned.i b/Examples/test-suite/errors/c_extra_unsigned.i new file mode 100644 index 000000000..f5728cf0c --- /dev/null +++ b/Examples/test-suite/errors/c_extra_unsigned.i @@ -0,0 +1,6 @@ +%module xxx + +int foo(unsigned unsigned int x); +int bar(signed signed y); +int spam(unsigned signed int x); + diff --git a/Examples/test-suite/errors/c_insert_missing.i b/Examples/test-suite/errors/c_insert_missing.i new file mode 100644 index 000000000..35755ccd8 --- /dev/null +++ b/Examples/test-suite/errors/c_insert_missing.i @@ -0,0 +1,3 @@ +%module xxx + +%insert("header") "missing_file.i"; diff --git a/Examples/test-suite/errors/c_long_short.i b/Examples/test-suite/errors/c_long_short.i new file mode 100644 index 000000000..f05831a8f --- /dev/null +++ b/Examples/test-suite/errors/c_long_short.i @@ -0,0 +1,6 @@ +%module xxx + +int foo(long short x); +int bar(short long y); +int spam(long long long x); +int grok(short short int x); diff --git a/Examples/test-suite/errors/c_missing_rbrace.i b/Examples/test-suite/errors/c_missing_rbrace.i new file mode 100644 index 000000000..381d5008d --- /dev/null +++ b/Examples/test-suite/errors/c_missing_rbrace.i @@ -0,0 +1,10 @@ +%module xxx + +int foo(int x) { + int y; + + + + + + diff --git a/Examples/test-suite/errors/c_missing_semi.i b/Examples/test-suite/errors/c_missing_semi.i new file mode 100644 index 000000000..fc20e1db1 --- /dev/null +++ b/Examples/test-suite/errors/c_missing_semi.i @@ -0,0 +1,4 @@ +%module xxx +int foo(int) +int bar(int,int); + diff --git a/Examples/test-suite/errors/c_redefine.i b/Examples/test-suite/errors/c_redefine.i new file mode 100644 index 000000000..818d70722 --- /dev/null +++ b/Examples/test-suite/errors/c_redefine.i @@ -0,0 +1,20 @@ +%module xxx + +int foo(int x, int y); +int foo; + +int bar(int x); + +struct bar { + int y; +}; + +%rename(bar) spam; + +int spam(int); + + + + + + diff --git a/Examples/test-suite/errors/c_varargs.i b/Examples/test-suite/errors/c_varargs.i new file mode 100644 index 000000000..88f9c2e7d --- /dev/null +++ b/Examples/test-suite/errors/c_varargs.i @@ -0,0 +1,3 @@ +%module xxx + +int foo(int x, ...); diff --git a/Examples/test-suite/errors/c_varargs_neg.i b/Examples/test-suite/errors/c_varargs_neg.i new file mode 100644 index 000000000..a88d8b712 --- /dev/null +++ b/Examples/test-suite/errors/c_varargs_neg.i @@ -0,0 +1,7 @@ +%module xxx + +%varargs(0,int x = 0) foo; +int foo(int x, ...); + + + diff --git a/Examples/test-suite/errors/cpp_bad_extern.i b/Examples/test-suite/errors/cpp_bad_extern.i new file mode 100644 index 000000000..b6895a536 --- /dev/null +++ b/Examples/test-suite/errors/cpp_bad_extern.i @@ -0,0 +1,7 @@ +%module xxx + +extern "INTERCAL" { + int foo(int); +}; + +extern "INTERCAL" int blah(int); diff --git a/Examples/test-suite/errors/cpp_extend_redefine.i b/Examples/test-suite/errors/cpp_extend_redefine.i new file mode 100644 index 000000000..dfe8fe48a --- /dev/null +++ b/Examples/test-suite/errors/cpp_extend_redefine.i @@ -0,0 +1,23 @@ +%module xxx + +%extend foo { + int bar() { + } +}; + +struct foo { + int bar(); + int spam(); +}; + +%extend foo { + int spam(); +}; + + + + + + + + diff --git a/Examples/test-suite/errors/cpp_extend_undefined.i b/Examples/test-suite/errors/cpp_extend_undefined.i new file mode 100644 index 000000000..808a74878 --- /dev/null +++ b/Examples/test-suite/errors/cpp_extend_undefined.i @@ -0,0 +1,6 @@ +%module xxx + +%extend foo { + int bar() { + } +}; diff --git a/Examples/test-suite/errors/cpp_inline_namespace.i b/Examples/test-suite/errors/cpp_inline_namespace.i new file mode 100644 index 000000000..d92746ae0 --- /dev/null +++ b/Examples/test-suite/errors/cpp_inline_namespace.i @@ -0,0 +1,7 @@ +%module xxx + +namespace foo { +%inline %{ +int bar(int x) { } +%} +} diff --git a/Examples/test-suite/errors/cpp_missing_rtemplate.i b/Examples/test-suite/errors/cpp_missing_rtemplate.i new file mode 100644 index 000000000..2d87eecf1 --- /dev/null +++ b/Examples/test-suite/errors/cpp_missing_rtemplate.i @@ -0,0 +1,11 @@ +%module xxx + + +int foo(vector { +}; diff --git a/Examples/test-suite/errors/cpp_overload.i b/Examples/test-suite/errors/cpp_overload.i new file mode 100644 index 000000000..34fa3cc25 --- /dev/null +++ b/Examples/test-suite/errors/cpp_overload.i @@ -0,0 +1,15 @@ +%module xxx +int foo(int x); +int foo(double x); + +class Foo { +public: + int bar(int); + int bar(double); +}; + +class Spam { +public: + Spam(); + Spam(int); +}; diff --git a/Examples/test-suite/errors/cpp_private_defvalue.i b/Examples/test-suite/errors/cpp_private_defvalue.i new file mode 100644 index 000000000..15542c7bc --- /dev/null +++ b/Examples/test-suite/errors/cpp_private_defvalue.i @@ -0,0 +1,7 @@ +%module xxx + +class foo { +static const int BAR = 42; +public: + int blah(int x = BAR); +}; diff --git a/Examples/test-suite/errors/cpp_private_inherit.i b/Examples/test-suite/errors/cpp_private_inherit.i new file mode 100644 index 000000000..e8267e98f --- /dev/null +++ b/Examples/test-suite/errors/cpp_private_inherit.i @@ -0,0 +1,11 @@ +%module xxx + +class Foo { +}; + +class Bar : private Foo { +}; + +class Spam : protected Foo { +}; + diff --git a/Examples/test-suite/errors/cpp_template_argname.i b/Examples/test-suite/errors/cpp_template_argname.i new file mode 100644 index 000000000..b87c115c1 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_argname.i @@ -0,0 +1,8 @@ +%module xxx + +template T blah(T x); + + + + + diff --git a/Examples/test-suite/errors/cpp_template_nargs.i b/Examples/test-suite/errors/cpp_template_nargs.i new file mode 100644 index 000000000..1a4fbdc20 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_nargs.i @@ -0,0 +1,10 @@ +%module xxx + +template T blah(T x) { }; + +%template(blahi) blah; +%template(blahf) blah<>; + + + + diff --git a/Examples/test-suite/errors/cpp_template_not.i b/Examples/test-suite/errors/cpp_template_not.i new file mode 100644 index 000000000..c8df700b5 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_not.i @@ -0,0 +1,9 @@ +%module xxx + +int blah; + +%template(blahi) blah; + + + + diff --git a/Examples/test-suite/errors/cpp_template_partial.i b/Examples/test-suite/errors/cpp_template_partial.i new file mode 100644 index 000000000..04ae9055e --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_partial.i @@ -0,0 +1,4 @@ +%module xxx + +template class vector { +}; diff --git a/Examples/test-suite/errors/cpp_template_repeat.i b/Examples/test-suite/errors/cpp_template_repeat.i new file mode 100644 index 000000000..e63ffe8d9 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_repeat.i @@ -0,0 +1,7 @@ +%module xxx + +template T blah(T x) { }; + +%template(iblah) blah; +%template(iiblah) blah; + diff --git a/Examples/test-suite/errors/cpp_template_undef.i b/Examples/test-suite/errors/cpp_template_undef.i new file mode 100644 index 000000000..2c0afbecc --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_undef.i @@ -0,0 +1,7 @@ +%module xxx + +%template(blahi) blah; + + + + diff --git a/Examples/test-suite/errors/cpp_using_not.i b/Examples/test-suite/errors/cpp_using_not.i new file mode 100644 index 000000000..2d5b6bf61 --- /dev/null +++ b/Examples/test-suite/errors/cpp_using_not.i @@ -0,0 +1,9 @@ +%module xxx + +int blah; +using namespace blah; + + + + + diff --git a/Examples/test-suite/errors/cpp_using_undef.i b/Examples/test-suite/errors/cpp_using_undef.i new file mode 100644 index 000000000..bc0c8c797 --- /dev/null +++ b/Examples/test-suite/errors/cpp_using_undef.i @@ -0,0 +1,9 @@ +%module xxx + +using foo::bar; +using namespace foo; + + + + + diff --git a/Examples/test-suite/errors/make.sh b/Examples/test-suite/errors/make.sh new file mode 100755 index 000000000..0c9bd443e --- /dev/null +++ b/Examples/test-suite/errors/make.sh @@ -0,0 +1,103 @@ +#!/bin/sh +echo "---------------------------------------" +echo "Testing SWIG error and warning messages" +echo "---------------------------------------" + +SWIG='../../../swig -I../../../Lib' + +# Files run in C mode +CFILES=' +c_bad_name +c_bad_native +c_class +c_default_error +c_deprecated +c_empty_char +c_enum_badvalue +c_extra_rblock +c_extra_rbrace +c_extra_unsigned +c_insert_missing +c_long_short +c_missing_rbrace +c_missing_semi +c_redefine +c_varargs +c_varargs_neg +nomodule +pp_badeval +pp_defined +pp_macro_args +pp_macro_badchar +pp_macro_nargs +pp_macro_redef +pp_macro_rparen +pp_macro_unterminated +pp_misplaced_elif +pp_misplaced_else +pp_missing_enddef +pp_missing_endif +pp_missing_file +pp_missing_rblock +pp_unterm_char +pp_unterm_comment +pp_unterm_string +swig_apply_nargs +swig_identifier +swig_insert_bad +swig_typemap_copy +swig_typemap_old +' + +# Files run in C++ mode +CPPFILES=' +cpp_bad_extern +cpp_extend_redefine +cpp_extend_undefined +cpp_inline_namespace +cpp_missing_rtemplate +cpp_namespace_alias +cpp_namespace_aliasnot +cpp_namespace_aliasundef +cpp_nested +cpp_no_access +cpp_nobase +cpp_overload +cpp_private_defvalue +cpp_private_inherit +cpp_template_argname +cpp_template_nargs +cpp_template_not +cpp_template_partial +cpp_template_repeat +cpp_template_undef +cpp_using_not +cpp_using_undef +' + +LOGFILE='test.log' +SWIGOPT=$* + +rm -f ${LOGFILE} + +echo "SWIG error and warning test. opts=${SWIGOPT}" >> ${LOGFILE} +echo "-----------------------------------------------------------" >> ${LOGFILE} + +for i in ${CFILES}; do + echo " Testing : ${i}.i"; + echo "" >> ${LOGFILE}; + echo ":::::::::::::::::::::::::::::::: ${i}.i :::::::::::::::::::::::::::::::::::" >> ${LOGFILE}; + ${SWIG} -Wall ${SWIGOPT} ${i}.i >>${LOGFILE} 2>&1 +done + +for i in ${CPPFILES}; do + echo " Testing : ${i}.i"; + echo "" >> ${LOGFILE} + echo ":::::::::::::::::::::::::::::::: ${i}.i :::::::::::::::::::::::::::::::::::" >> ${LOGFILE}; + ${SWIG} -Wall -c++ ${SWIGOPT} ${i}.i >>${LOGFILE} 2>&1 +done + +echo "" +echo "Results written to '${LOGFILE}'" + + diff --git a/Examples/test-suite/errors/nomodule.i b/Examples/test-suite/errors/nomodule.i new file mode 100644 index 000000000..6341be3fd --- /dev/null +++ b/Examples/test-suite/errors/nomodule.i @@ -0,0 +1,2 @@ +/* No module name */ +int foo(int); diff --git a/Examples/test-suite/errors/pp_badeval.i b/Examples/test-suite/errors/pp_badeval.i new file mode 100644 index 000000000..aca397c7c --- /dev/null +++ b/Examples/test-suite/errors/pp_badeval.i @@ -0,0 +1,11 @@ +%module xxx + +#if FOO==4 +#elif FOO==4+ +#endif + + + + + + diff --git a/Examples/test-suite/errors/pp_defined.i b/Examples/test-suite/errors/pp_defined.i new file mode 100644 index 000000000..e2f343079 --- /dev/null +++ b/Examples/test-suite/errors/pp_defined.i @@ -0,0 +1,7 @@ +%module xxx + +#if defined() +#endif + +#if defined +#endif diff --git a/Examples/test-suite/errors/pp_macro_args.i b/Examples/test-suite/errors/pp_macro_args.i new file mode 100644 index 000000000..8bbbfb104 --- /dev/null +++ b/Examples/test-suite/errors/pp_macro_args.i @@ -0,0 +1,7 @@ +%module xxx + +#define foo(a,x) a x + +#if foo +#endif + diff --git a/Examples/test-suite/errors/pp_macro_badchar.i b/Examples/test-suite/errors/pp_macro_badchar.i new file mode 100644 index 000000000..276011559 --- /dev/null +++ b/Examples/test-suite/errors/pp_macro_badchar.i @@ -0,0 +1,5 @@ +%module xxx + +#define f@oo(a,x) a + x +#define foo(a@,x) a + x + diff --git a/Examples/test-suite/errors/pp_macro_nargs.i b/Examples/test-suite/errors/pp_macro_nargs.i new file mode 100644 index 000000000..15e434877 --- /dev/null +++ b/Examples/test-suite/errors/pp_macro_nargs.i @@ -0,0 +1,16 @@ +%module xxx + +#define foo(a,x) a x +#define bar(x) x +#define spam() /**/ + +foo(3) +foo(3,4,5) +bar() +bar(2,3) +spam(1) + + + + + diff --git a/Examples/test-suite/errors/pp_macro_redef.i b/Examples/test-suite/errors/pp_macro_redef.i new file mode 100644 index 000000000..e0910e60e --- /dev/null +++ b/Examples/test-suite/errors/pp_macro_redef.i @@ -0,0 +1,8 @@ +%module xxx + +#define foo(a,x) a+x +#define foo 4 + +/* Should not generate an error */ +#define foo 4 + diff --git a/Examples/test-suite/errors/pp_macro_rparen.i b/Examples/test-suite/errors/pp_macro_rparen.i new file mode 100644 index 000000000..cbb04fb87 --- /dev/null +++ b/Examples/test-suite/errors/pp_macro_rparen.i @@ -0,0 +1,3 @@ +%module xxx + +#define foo(a,x 3 diff --git a/Examples/test-suite/errors/pp_macro_unterminated.i b/Examples/test-suite/errors/pp_macro_unterminated.i new file mode 100644 index 000000000..d0e32d726 --- /dev/null +++ b/Examples/test-suite/errors/pp_macro_unterminated.i @@ -0,0 +1,7 @@ +%module xxx + +#define foo(a,x) a+x + +foo(3, + + diff --git a/Examples/test-suite/errors/pp_misplaced_elif.i b/Examples/test-suite/errors/pp_misplaced_elif.i new file mode 100644 index 000000000..5e656f020 --- /dev/null +++ b/Examples/test-suite/errors/pp_misplaced_elif.i @@ -0,0 +1,7 @@ +%module xxx + + +#elif foo == 3 +int x; +#endif + diff --git a/Examples/test-suite/errors/pp_misplaced_else.i b/Examples/test-suite/errors/pp_misplaced_else.i new file mode 100644 index 000000000..ad299466f --- /dev/null +++ b/Examples/test-suite/errors/pp_misplaced_else.i @@ -0,0 +1,7 @@ +%module xxx + + +#else +int x; +#endif + diff --git a/Examples/test-suite/errors/pp_missing_enddef.i b/Examples/test-suite/errors/pp_missing_enddef.i new file mode 100644 index 000000000..e13deef27 --- /dev/null +++ b/Examples/test-suite/errors/pp_missing_enddef.i @@ -0,0 +1,7 @@ +%module xxx + +%define FOO +int x; + + + diff --git a/Examples/test-suite/errors/pp_missing_endif.i b/Examples/test-suite/errors/pp_missing_endif.i new file mode 100644 index 000000000..e83496fb2 --- /dev/null +++ b/Examples/test-suite/errors/pp_missing_endif.i @@ -0,0 +1,6 @@ +%module xxx + +#ifdef FOO +int x; + + diff --git a/Examples/test-suite/errors/pp_missing_file.i b/Examples/test-suite/errors/pp_missing_file.i new file mode 100644 index 000000000..5e3f0ea27 --- /dev/null +++ b/Examples/test-suite/errors/pp_missing_file.i @@ -0,0 +1,3 @@ +%module test + +%include "missing_filename.i" diff --git a/Examples/test-suite/errors/pp_missing_rblock.i b/Examples/test-suite/errors/pp_missing_rblock.i new file mode 100644 index 000000000..55c3cc808 --- /dev/null +++ b/Examples/test-suite/errors/pp_missing_rblock.i @@ -0,0 +1,7 @@ +%module xxx + +%{ +int x; + + + diff --git a/Examples/test-suite/errors/pp_unterm_char.i b/Examples/test-suite/errors/pp_unterm_char.i new file mode 100644 index 000000000..9b028fd3d --- /dev/null +++ b/Examples/test-suite/errors/pp_unterm_char.i @@ -0,0 +1,7 @@ +%module xxx + + +const char x = 'H + + + diff --git a/Examples/test-suite/errors/pp_unterm_comment.i b/Examples/test-suite/errors/pp_unterm_comment.i new file mode 100644 index 000000000..f9cdb8257 --- /dev/null +++ b/Examples/test-suite/errors/pp_unterm_comment.i @@ -0,0 +1,6 @@ +%module xxx + +/* Hello + + + diff --git a/Examples/test-suite/errors/pp_unterm_string.i b/Examples/test-suite/errors/pp_unterm_string.i new file mode 100644 index 000000000..31ed8d4bb --- /dev/null +++ b/Examples/test-suite/errors/pp_unterm_string.i @@ -0,0 +1,6 @@ +%module xxx + + +const char *x = "Hello + + diff --git a/Examples/test-suite/errors/swig_apply_nargs.i b/Examples/test-suite/errors/swig_apply_nargs.i new file mode 100644 index 000000000..bb1519c1e --- /dev/null +++ b/Examples/test-suite/errors/swig_apply_nargs.i @@ -0,0 +1,6 @@ +%module xxx + +%typemap(in) (char *str, int len) { +} + +%apply (char *str, int len) { int x }; diff --git a/Examples/test-suite/errors/swig_identifier.i b/Examples/test-suite/errors/swig_identifier.i new file mode 100644 index 000000000..3ad07362d --- /dev/null +++ b/Examples/test-suite/errors/swig_identifier.i @@ -0,0 +1,6 @@ +%module xxx + +%rename("foo bar") foobar; + +int foobar(int); + diff --git a/Examples/test-suite/errors/swig_insert_bad.i b/Examples/test-suite/errors/swig_insert_bad.i new file mode 100644 index 000000000..e2dd8a93e --- /dev/null +++ b/Examples/test-suite/errors/swig_insert_bad.i @@ -0,0 +1,5 @@ +%module xxx + +%insert("foobar") %{ +some code +%} diff --git a/Examples/test-suite/errors/swig_typemap_copy.i b/Examples/test-suite/errors/swig_typemap_copy.i new file mode 100644 index 000000000..17607f2fb --- /dev/null +++ b/Examples/test-suite/errors/swig_typemap_copy.i @@ -0,0 +1,3 @@ +%module xxx + +%typemap(in) int = blah; diff --git a/Examples/test-suite/errors/swig_typemap_old.i b/Examples/test-suite/errors/swig_typemap_old.i new file mode 100644 index 000000000..c27ff5533 --- /dev/null +++ b/Examples/test-suite/errors/swig_typemap_old.i @@ -0,0 +1,6 @@ +%module xxx + +%typemap(in) int x { + $source; + $target; +} diff --git a/Examples/test-suite/evil_diamond.i b/Examples/test-suite/evil_diamond.i new file mode 100644 index 000000000..8644c24c9 --- /dev/null +++ b/Examples/test-suite/evil_diamond.i @@ -0,0 +1,23 @@ +%module evil_diamond + +%warnfilter(801) foo; // Ruby, wrong class name +%warnfilter(801) bar; // Ruby, wrong class name +%warnfilter(801) baz; // Ruby, wrong class name +%warnfilter(801,802,813) spam; // Ruby, wrong class name; Ruby & Java, multiple inheritance + +%inline %{ + +class foo { }; + +class bar : public foo { +}; + +class baz : public foo { +}; + +class spam : public bar, public baz { +}; + +foo *test(foo *f) { return f; } +%} + diff --git a/Examples/test-suite/evil_diamond_ns.i b/Examples/test-suite/evil_diamond_ns.i new file mode 100644 index 000000000..067805a79 --- /dev/null +++ b/Examples/test-suite/evil_diamond_ns.i @@ -0,0 +1,24 @@ +%module evil_diamond_ns + +%warnfilter(801) Blah::foo; // Ruby, wrong class name +%warnfilter(801) Blah::bar; // Ruby, wrong class name +%warnfilter(801) Blah::baz; // Ruby, wrong class name +%warnfilter(801,802,813) Blah::spam; // Ruby, wrong class name; Ruby & Java, multiple inheritance + +%inline %{ +namespace Blah { +class foo { }; + +class bar : public foo { +}; + +class baz : public foo { +}; + +class spam : public bar, public baz { +}; + +foo *test(foo *f) { return f; } +} +%} + diff --git a/Examples/test-suite/evil_diamond_prop.i b/Examples/test-suite/evil_diamond_prop.i new file mode 100644 index 000000000..d28a57ca2 --- /dev/null +++ b/Examples/test-suite/evil_diamond_prop.i @@ -0,0 +1,36 @@ +%module evil_diamond_prop + +%warnfilter(801) foo; // Ruby, wrong class name +%warnfilter(801) bar; // Ruby, wrong class name +%warnfilter(801) baz; // Ruby, wrong class name +%warnfilter(801,802,813) spam; // Ruby, wrong class name; Ruby & Java, multiple inheritance + +%inline %{ + +class foo { + public: + int _foo; + foo() : _foo(1) {} +}; + +class bar : public foo { + public: + int _bar; + bar() : _bar(2) {} +}; + +class baz : public foo { + public: + int _baz; + baz() : _baz(3) {} +}; + +class spam : public bar, public baz { + public: + int _spam; + spam() : _spam(4) {} +}; + +foo *test(foo *f) { return f; } +%} + diff --git a/Examples/test-suite/explicit.i b/Examples/test-suite/explicit.i new file mode 100644 index 000000000..738dffc41 --- /dev/null +++ b/Examples/test-suite/explicit.i @@ -0,0 +1,15 @@ +/* Swig 1.3.6 fails to understand the "explicit" keyword. + SF Bug #445233, reported by Krzysztof Kozminski + . +*/ + +%module "explicit" + +%inline %{ + +class A { + public: + explicit A(int) {}; +}; + +%} diff --git a/Examples/test-suite/extend_template.i b/Examples/test-suite/extend_template.i new file mode 100644 index 000000000..a39ac546d --- /dev/null +++ b/Examples/test-suite/extend_template.i @@ -0,0 +1,26 @@ +%module extend_template +%module xxx +namespace oss { // this doesn't + %extend Foo<0> { + int test1(int x) { return x; } + } +} + +%extend oss::Foo<0> { // this doesn't + int test2(int x) { return x; } +}; + + +%inline %{ + namespace oss + { + template + struct Foo { + }; + } +%} + +namespace oss +{ + %template(Foo_0) Foo<0>; +} diff --git a/Examples/test-suite/extend_template_ns.i b/Examples/test-suite/extend_template_ns.i new file mode 100644 index 000000000..3712f2c8f --- /dev/null +++ b/Examples/test-suite/extend_template_ns.i @@ -0,0 +1,32 @@ +%module extend_template_ns +%inline %{ +namespace oss +{ + enum Test {One, Two}; +} +%} + +namespace oss { + %extend Foo { //************ this doesn't work + int test1(int x) { return x; } + }; +} + +%extend oss::Foo { //******** this works +int test2(int x) { return x; } +}; + +%inline %{ +namespace oss +{ + template + struct Foo { + }; + } +%} + +namespace oss +{ +%template(Foo_One) Foo; +} + diff --git a/Examples/test-suite/grouping.i b/Examples/test-suite/grouping.i new file mode 100644 index 000000000..5632231d0 --- /dev/null +++ b/Examples/test-suite/grouping.i @@ -0,0 +1,31 @@ +%module grouping + +%inline %{ + +typedef int Integer; + +int (test1)(int x) { + return x; +} + +int *(test2)(int x) { + static int y; + y = x; + return &y; +} + +int (test3) = 37; + +typedef Integer (UnaryOp)(Integer); + +Integer do_unary(Integer x, UnaryOp *f) { + return (*f)(x); +} + +int negate(int x) { + return -x; +} + +%} + +%constant UnaryOp *NEGATE = negate; diff --git a/Examples/test-suite/guile/.cvsignore b/Examples/test-suite/guile/.cvsignore new file mode 100644 index 000000000..1242e8c7e --- /dev/null +++ b/Examples/test-suite/guile/.cvsignore @@ -0,0 +1,2 @@ +*wrap* +*-guile diff --git a/Examples/test-suite/guile/Makefile b/Examples/test-suite/guile/Makefile new file mode 100644 index 000000000..a39bcaf0e --- /dev/null +++ b/Examples/test-suite/guile/Makefile @@ -0,0 +1,44 @@ +####################################################################### +# $Header$ +# Makefile for guile test-suite +####################################################################### + +LANGUAGE = guile +VARIANT = _passive +SCRIPTSUFFIX = _runme.scm + +C_TEST_CASES = long_long list_vector pointer_in_out multivalue + +include ../common.mk + +# Overridden variables here + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.scm appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.scm ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH guile -l $*\_runme.scm;) \ + fi; + +# Clean +%.clean: + @rm -f $*-guile + +clean: + $(MAKE) -f $(TOP)/Makefile guile_clean diff --git a/Examples/test-suite/guile/README b/Examples/test-suite/guile/README new file mode 100644 index 000000000..37432ea4b --- /dev/null +++ b/Examples/test-suite/guile/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.scm appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/guile/casts_runme.scm b/Examples/test-suite/guile/casts_runme.scm new file mode 100644 index 000000000..17e7725f6 --- /dev/null +++ b/Examples/test-suite/guile/casts_runme.scm @@ -0,0 +1,13 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_test_module" (dynamic-link "./libcasts.so")) + +(define x (new-B)) + +;; This fails in 1.3a5 because the SWIG/Guile runtime code gets the +;; source and the target of a cast the wrong way around. + +(A-hello x) + +(exit 0) diff --git a/Examples/test-suite/guile/char_constant_runme.scm b/Examples/test-suite/guile/char_constant_runme.scm new file mode 100644 index 000000000..2cc89b051 --- /dev/null +++ b/Examples/test-suite/guile/char_constant_runme.scm @@ -0,0 +1,9 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_test_module" (dynamic-link "./libchar_constant.so")) + +(if (and (char? (CHAR-CONSTANT)) + (string? (STRING-CONSTANT))) + (exit 0) + (exit 1)) diff --git a/Examples/test-suite/guile/imports_runme.scm b/Examples/test-suite/guile/imports_runme.scm new file mode 100644 index 000000000..030fbfd61 --- /dev/null +++ b/Examples/test-suite/guile/imports_runme.scm @@ -0,0 +1,19 @@ +;;; This file is part of a test for SF bug #231619. +;;; It shows that the %import directive does not work properly in SWIG +;;; 1.3a5: Type information is not properly generated if a base class +;;; comes from an %import-ed file. + +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_imports_a_module" (dynamic-link "./libimports_a.so")) +(dynamic-call "scm_init_imports_b_module" (dynamic-link "./libimports_b.so")) + +(define x (new-B)) + +;; This fails in 1.3a5 because the SWIG runtime code does not know +;; that x (an instance of class B) can be passed to methods of class A. + +(A-hello x) + +(exit 0) diff --git a/Examples/test-suite/guile/list_vector_runme.scm b/Examples/test-suite/guile/list_vector_runme.scm new file mode 100644 index 000000000..1957c9a7f --- /dev/null +++ b/Examples/test-suite/guile/list_vector_runme.scm @@ -0,0 +1,28 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_test_module" (dynamic-link "./liblist_vector.so")) + +(define-macro (check form) + `(if (not ,form) + (error "Check failed: " ',form))) + +(check (= (sum-list '(1 3 4 6 7)) 21)) +(check (= (sum-vector #(2 4 6 7 9)) 28)) +(check (equal? (one-to-seven-list) '(1 2 3 4 5 6 7))) +(check (equal? (one-to-seven-vector) #(1 2 3 4 5 6 7))) + +(check (= (sum-list2 '(1 3 4 6 7)) 21)) +(check (= (sum-vector2 #(2 4 6 7 9)) 28)) +(check (equal? (one-to-seven-list2) '(1 2 3 4 5 6 7))) +(check (equal? (one-to-seven-vector2) #(1 2 3 4 5 6 7))) + +(check (= (sum-lists '(1 2 3) '(4 5 6) '(7 8 9)) 45)) +(check (= (sum-lists2 '(1 2 3) '(4 5 6) '(7 8 9)) 45)) +(check (equal? (call-with-values produce-lists list) + '(#(0 1 2 3 4) + #(0 1 4 9 16) + #(0.0 1.5 3.0 4.5 6.0)))) + + +(exit 0) diff --git a/Examples/test-suite/guile/multivalue_runme.scm b/Examples/test-suite/guile/multivalue_runme.scm new file mode 100644 index 000000000..910935801 --- /dev/null +++ b/Examples/test-suite/guile/multivalue_runme.scm @@ -0,0 +1,24 @@ +;;;; Automatic test of multiple return values + +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_test_module" (dynamic-link "./libmultivalue.so")) + +(let ((quotient/remainder (divide-l 37 5))) + (if (not (equal? quotient/remainder '(7 2))) + (exit 1))) + +(let ((quotient-remainder-vector (divide-v 41 7))) + (if (not (equal? quotient-remainder-vector #(5 6))) + (exit 1))) + +(call-with-values (lambda () + (divide-mv 91 13)) + (lambda (quotient remainder) + (if (not (and (= quotient 7) + (= remainder 0))) + (exit 1)))) + +(exit 0) + diff --git a/Examples/test-suite/guile/name_runme.scm b/Examples/test-suite/guile/name_runme.scm new file mode 100644 index 000000000..a7121b9d9 --- /dev/null +++ b/Examples/test-suite/guile/name_runme.scm @@ -0,0 +1,10 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_test_module" (dynamic-link "./libname.so")) + +(foo-2) +bar-2 +Baz-2 + +(exit 0) diff --git a/Examples/test-suite/guile/overload_complicated_runme.scm b/Examples/test-suite/guile/overload_complicated_runme.scm new file mode 100644 index 000000000..0423aafbd --- /dev/null +++ b/Examples/test-suite/guile/overload_complicated_runme.scm @@ -0,0 +1,18 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_overload_complicated_module" (dynamic-link "./liboverload_complicated.so")) + +(define-macro (check form) + `(if (not ,form) + (error "Check failed: " ',form))) + +;; Check first method +(check (= (foo 1 2 "bar" 4) 15)) + +;; Check second method +(check (= (foo 1 2) 4811.4)) +(check (= (foo 1 2 3.2) 4797.2)) +(check (= (foo 1 2 3.2 #\Q) 4798.2)) + +(exit 0) diff --git a/Examples/test-suite/guile/overload_simple_runme.scm b/Examples/test-suite/guile/overload_simple_runme.scm new file mode 100644 index 000000000..abe95069a --- /dev/null +++ b/Examples/test-suite/guile/overload_simple_runme.scm @@ -0,0 +1,56 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_overload_simple_module" (dynamic-link "./liboverload_simple.so")) + +(if (not (string=? (foo 3) "foo:int")) + (error "foo(int)")) + +(if (not (string=? (foo 3.01) "foo:double")) + (error "foo(double)")) + +(if (not (string=? (foo "hello") "foo:char *")) + (error "foo(char *)")) + +(let ((f (new-Foo)) + (b (new-Bar)) + (s (new-Spam))) + (if (not (string=? (foo f) "foo:Foo *")) + (error "foo(Foo *)")) + (if (not (string=? (foo b) "foo:Bar *")) + (error "foo(Bar *)")) + ;; Test member functions + (if (not (string=? (Spam-foo s 3) "foo:int")) + (error "Spam::foo(int)")) + (if (not (string=? (Spam-foo s 3.01) "foo:double")) + (error "Spam::foo(double)")) + (if (not (string=? (Spam-foo s "hello") "foo:char *")) + (error "Spam::foo(char *)")) + (if (not (string=? (Spam-foo s f) "foo:Foo *")) + (error "Spam::foo(Foo *)")) + (if (not (string=? (Spam-foo s b) "foo:Bar *")) + (error "Spam::foo(Bar *)")) + ;; Test static member functions + (if (not (string=? (Spam-bar 3) "bar:int")) + (error "Spam::bar(int)")) + (if (not (string=? (Spam-bar 3.01) "bar:double")) + (error "Spam::bar(double)")) + (if (not (string=? (Spam-bar "hello") "bar:char *")) + (error "Spam::bar(char *)")) + (if (not (string=? (Spam-bar f) "bar:Foo *")) + (error "Spam::bar(Foo *)")) + (if (not (string=? (Spam-bar b) "bar:Bar *")) + (error "Spam::bar(Bar *)")) + ;; Test constructors + (if (not (string=? (Spam-type-get (new-Spam)) "none")) + (error "Spam()")) + (if (not (string=? (Spam-type-get (new-Spam 3)) "int")) + (error "Spam(int)")) + (if (not (string=? (Spam-type-get (new-Spam 3.4)) "double")) + (error "Spam(double)")) + (if (not (string=? (Spam-type-get (new-Spam "hello")) "char *")) + (error "Spam(char *)")) + (if (not (string=? (Spam-type-get (new-Spam b)) "Bar *")) + (error "Spam(Bar *)"))) + +(exit 0) diff --git a/Examples/test-suite/guile/overload_subtype_runme.scm b/Examples/test-suite/guile/overload_subtype_runme.scm new file mode 100644 index 000000000..14737f144 --- /dev/null +++ b/Examples/test-suite/guile/overload_subtype_runme.scm @@ -0,0 +1,12 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_overload_subtype_module" (dynamic-link "./liboverload_subtype.so")) + +(if (not (= (spam (new-Foo)) 1)) + (error "foo")) + +(if (not (= (spam (new-Bar)) 2)) + (error "bar")) + +(exit 0) diff --git a/Examples/test-suite/guile/pointer_in_out_runme.scm b/Examples/test-suite/guile/pointer_in_out_runme.scm new file mode 100644 index 000000000..68ce0aa3b --- /dev/null +++ b/Examples/test-suite/guile/pointer_in_out_runme.scm @@ -0,0 +1,18 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_pointer_in_out_module" (dynamic-link "./libpointer_in_out.so")) + +(define-macro (check form) + `(if (not ,form) + (error "Check failed: " ',form))) + +(define p (produce-int-pointer 47 11)) + +(check (= (consume-int-pointer p) 47)) + +(define q (frobnicate-int-pointer p)) + +(check (= (consume-int-pointer q) 11)) + +(exit 0) diff --git a/Examples/test-suite/guile/unions_runme.scm b/Examples/test-suite/guile/unions_runme.scm new file mode 100644 index 000000000..ce2caa8b3 --- /dev/null +++ b/Examples/test-suite/guile/unions_runme.scm @@ -0,0 +1,41 @@ +;;; This is the union runtime testcase. It ensures that values within a +;;; union embedded within a struct can be set and read correctly. + +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(dynamic-call "scm_init_unions_module" (dynamic-link "./libunions.so")) + +;; Create new instances of SmallStruct and BigStruct for later use +(define small (new-SmallStruct)) +(SmallStruct-jill-set small 200) + +(define big (new-BigStruct)) +(BigStruct-smallstruct-set big small) +(BigStruct-jack-set big 300) + +;; Use SmallStruct then BigStruct to setup EmbeddedUnionTest. +;; Ensure values in EmbeddedUnionTest are set correctly for each. +(define eut (new-EmbeddedUnionTest)) + +;; First check the SmallStruct in EmbeddedUnionTest +(EmbeddedUnionTest-number-set eut 1) +(EmbeddedUnionTest-uni-small-set (EmbeddedUnionTest-uni-get eut) + small) +(let ((Jill1 (SmallStruct-jill-get + (EmbeddedUnionTest-uni-small-get + (EmbeddedUnionTest-uni-get eut))))) + (if (not (= Jill1 200)) + (begin + (display "Runtime test 1 failed.") + (exit 1)))) + +(let ((Num1 (EmbeddedUnionTest-number-get eut))) + (if (not (= Num1 1)) + (begin + (display "Runtime test 2 failed.") + (exit 1)))) + +;; that should do + +(exit 0) diff --git a/Examples/test-suite/ignore_parameter.i b/Examples/test-suite/ignore_parameter.i new file mode 100644 index 000000000..f64a4b32e --- /dev/null +++ b/Examples/test-suite/ignore_parameter.i @@ -0,0 +1,42 @@ +// Test for %typemap(ignore) + +%module ignore_parameter + +%typemap(in,numinputs=0) char* a "static char* hi = \"hello\"; $1 = hi;"; +%typemap(in,numinputs=0) int bb "$1 = 101;"; +%typemap(in,numinputs=0) double ccc "$1 = 8.8;"; + +%typemap(freearg) char* a ""; // ensure freearg is not generated (needed for Java at least) + +%inline %{ +// global function tests +char* jaguar(char* a, int b, double c) { return a; } +int lotus(char* aa, int bb, double cc) { return bb; } +double tvr(char* aaa, int bbb, double ccc) { return ccc; } +int ferrari(int bb) { return bb; } + +// member function tests +struct SportsCars { + char* daimler(char* a, int b, double c) { return a; } + int astonmartin(char* aa, int bb, double cc) { return bb; } + double bugatti(char* aaa, int bbb, double ccc) { return ccc; } + int lamborghini(int bb) { return bb; } +}; + +// constructor tests +struct MiniCooper { + MiniCooper(char* a, int b, double c) {} +}; +struct MorrisMinor { + MorrisMinor(char* aa, int bb, double cc) {} +}; +struct FordAnglia { + FordAnglia(char* aaa, int bbb, double ccc) {} +}; +struct AustinAllegro { + AustinAllegro(int bb) {} +}; +%} + + + diff --git a/Examples/test-suite/import_nomodule.h b/Examples/test-suite/import_nomodule.h new file mode 100644 index 000000000..2e80e72bb --- /dev/null +++ b/Examples/test-suite/import_nomodule.h @@ -0,0 +1,2 @@ +class Foo { }; +typedef int Integer; diff --git a/Examples/test-suite/import_nomodule.i b/Examples/test-suite/import_nomodule.i new file mode 100644 index 000000000..e280455f3 --- /dev/null +++ b/Examples/test-suite/import_nomodule.i @@ -0,0 +1,24 @@ +%module import_nomodule +%{ +#include "import_nomodule.h" +%} + +%import "import_nomodule.h" + +#ifndef SWIGJAVA +// The proxy class does not have Bar derived from Foo, yet an instance of Bar can successfully be passed to a proxy function taking a Foo pointer. +// This violation of the type system is not possible in Java due to its static type checking. +%inline %{ +Foo *create_Foo() { + return new Foo(); +} + +void test1(Foo *f, Integer x) { }; + +class Bar : public Foo { }; + +%} +#endif + + + diff --git a/Examples/test-suite/imports.list b/Examples/test-suite/imports.list new file mode 100644 index 000000000..36c0802fb --- /dev/null +++ b/Examples/test-suite/imports.list @@ -0,0 +1,2 @@ +imports_a +imports_b diff --git a/Examples/test-suite/imports_a.h b/Examples/test-suite/imports_a.h new file mode 100644 index 000000000..ea006b12c --- /dev/null +++ b/Examples/test-suite/imports_a.h @@ -0,0 +1,7 @@ +class A { + public: + A() {} + + void hello() + {} +}; diff --git a/Examples/test-suite/imports_a.i b/Examples/test-suite/imports_a.i new file mode 100644 index 000000000..56e1f0e5d --- /dev/null +++ b/Examples/test-suite/imports_a.i @@ -0,0 +1,12 @@ +/* This file is part of a test for SF bug #231619. + It shows that the %import directive does not work properly in SWIG + 1.3a5: Type information is not properly generated if a base class + comes from an %import-ed file. */ + +%module imports_a + +%{ + #include "imports_a.h" +%} + +%include "imports_a.h" diff --git a/Examples/test-suite/imports_b.h b/Examples/test-suite/imports_b.h new file mode 100644 index 000000000..ecc8d4e2f --- /dev/null +++ b/Examples/test-suite/imports_b.h @@ -0,0 +1,11 @@ +#include "imports_a.h" + +class B : public A +{ + public: + B() {}; + + void bye() + {} ; +}; + diff --git a/Examples/test-suite/imports_b.i b/Examples/test-suite/imports_b.i new file mode 100644 index 000000000..48c51c625 --- /dev/null +++ b/Examples/test-suite/imports_b.i @@ -0,0 +1,14 @@ +/* This file is part of a test for SF bug #231619. + It shows that the %import directive does not work properly in SWIG + 1.3a5: Type information is not properly generated if a base class + comes from an %import-ed file. */ + +%module imports_b + +%{ +#include "imports_b.h" +%} + +%import "imports_a.i" + +%include "imports_b.h" diff --git a/Examples/test-suite/inherit_missing.i b/Examples/test-suite/inherit_missing.i new file mode 100644 index 000000000..ecde360bf --- /dev/null +++ b/Examples/test-suite/inherit_missing.i @@ -0,0 +1,43 @@ +// Tests handling of inheritance when a base class isn't provided to SWIG +%module inherit_missing + +%warnfilter(402); + +%{ +/* Define the class internally, but don't tell SWIG about it */ +class Foo { +public: + virtual char *blah() { + return (char *) "Foo::blah"; + } +}; +%} + +/* Forward declaration. Says that Foo is a class, but doesn't provide a definition */ + +class Foo; + +%inline %{ + +class Bar : public Foo { + public: + virtual char *blah() { + return (char *) "Bar::blah"; + }; +}; + +class Spam : public Bar { + public: + virtual char *blah() { + return (char *) "Spam::blah"; + }; +}; + +Foo *new_Foo() { + return new Foo(); +} + +char *do_blah(Foo *f) { + return f->blah(); +} +%} diff --git a/Examples/test-suite/java/.cvsignore b/Examples/test-suite/java/.cvsignore new file mode 100644 index 000000000..f51eef359 --- /dev/null +++ b/Examples/test-suite/java/.cvsignore @@ -0,0 +1,185 @@ +abstract_inherit +abstract_inherit_ok +add_link +anonymous_arg +argout +arrayptr +arrays +arrays_global +arrays_global_twodim +arrays_scope +bool_default +casts +char_constant +class_ignore +constant_pointers +constover +constructor_exception +constructor_explicit +constructor_value +const_const +const_const_2 +conversion +conversion_namespace +conversion_ns_template +cplusplus_throw +cpp_enum +cpp_enum_scope +cpp_namespace +cpp_nodefault +cpp_static +cpp_typedef +CVS +default_cast +default_constructor +default_ns +default_ref +defineop +defines +dynamic_cast +enum +enum_scope +enum_scope_template +enum_var +evil_diamond +evil_diamond_ns +evil_diamond_prop +explicit +extend_template +extend_template_ns +grouping +ignore_parameter +imports +import_nomodule +inherit_missing +java_constants +java_pragmas +java_throws +java_typemaps_proxy +java_typemaps_typewrapper +kind +lib_carrays +lib_cdata +lib_cmalloc +lib_constraints +lib_cpointer +lib_math +lib_std_deque +lib_std_string +lib_std_vector +lib_typemaps +long_long +macro_2 +member_template +minherit +name +namespace_enum +namespace_extend +namespace_nested +namespace_template +namespace_typemap +name_cxx +name_inherit +nested +newobject1 +newobject2 +overload_complicated +overload_copy +overload_extend +overload_extendc +overload_simple +overload_subtype +overload_template +pointer_reference +preproc_1 +preproc_2 +preproc_3 +primitive_ref +private_assign +pure_virtual +rename_default +rename_scope +return_value_scope +ret_by_value +rname +sizeof_pointer +smart_pointer_const +smart_pointer_multi +smart_pointer_multi_typedef +smart_pointer_not +smart_pointer_overload +smart_pointer_protected +smart_pointer_rename +smart_pointer_simple +smart_pointer_typedef +sneaky1 +static_array_member +static_const_member +static_const_member_2 +struct_value +template +template_arg_scope +template_arg_typename +template_base_template +template_classes +template_construct +template_const_ref +template_default +template_default2 +template_default_inherit +template_default_qualify +template_enum +template_enum_ns_inherit +template_enum_typedef +template_forward +template_inherit +template_inherit_abstract +template_int_const +template_ns +template_ns2 +template_ns3 +template_ns4 +template_ns_enum +template_ns_enum2 +template_ns_inherit +template_ns_scope +template_qualifier +template_rename +template_retvalue +template_specialization +template_static +template_tbase_template +template_typedef +template_typedef_cplx +template_typedef_cplx2 +template_typedef_cplx3 +template_typedef_cplx4 +template_typedef_import +template_type_namespace +template_virtual +template_whitespace +throw_exception +typedef_funcptr +typedef_inherit +typedef_mptr +typedef_reference +typedef_scope +typemap_namespace +typemap_ns_using +typemap_subst +typename +unions +union_scope +using1 +using2 +using_composition +using_extend +using_inherit +using_namespace +using_private +using_protected +valuewrapper_base +virtual_destructor +voidtest + +*.class diff --git a/Examples/test-suite/java/Makefile b/Examples/test-suite/java/Makefile new file mode 100644 index 000000000..6cc4c6440 --- /dev/null +++ b/Examples/test-suite/java/Makefile @@ -0,0 +1,72 @@ +####################################################################### +# $Header$ +# Makefile for java test-suite +####################################################################### + +LANGUAGE = java +SCRIPTSUFFIX = _runme.java + +C_TEST_CASES = \ + java_lib_arrays + +CPP_TEST_CASES = \ + java_constants \ + java_jnitypes \ + java_pragmas \ + java_throws \ + java_typemaps_proxy \ + java_typemaps_typewrapper + +include ../common.mk + +# Overridden variables here +TOP = ../../.. +SWIGOPT = -I$(TOP)/$(TEST_SUITE) -package $* +#Target prefix cannot be used on Windows +#TARGETPREFIX = lib + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + (cd $*; $(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + (cd $*; $(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + (cd $*; $(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Makes a directory for the testcase if it does not exist +setup = \ + @if [ -f $(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ + echo "Checking testcase $* (with run test) under $(LANGUAGE)" ; \ + else \ + echo "Checking testcase $* under $(LANGUAGE)" ; \ + fi; \ + if [ ! -d $* ]; then \ + mkdir $*; \ + fi; + +# Compiles java files then runs the testcase. A testcase is only run if +# a file is found which has _runme.java appended after the testcase name. +# Note Java uses LD_LIBRARY_PATH under Unix and PATH under Cygwin. +run_testcase = \ + (cd $*; javac *.java; ); \ + if [ -f $*\_runme.java ]; then ( \ + javac $*\_runme.java; \ + env LD_LIBRARY_PATH="$*:$$LD_LIBRARY_PATH" PATH="$*:$$PATH" java $*\_runme;) \ + fi; + +# Clean: remove testcase directories +%.clean: + @if [ -d $* ]; then \ + rm -rf $*; \ + fi; + +clean: + @rm -f *.class diff --git a/Examples/test-suite/java/README b/Examples/test-suite/java/README new file mode 100644 index 000000000..b8b7416d9 --- /dev/null +++ b/Examples/test-suite/java/README @@ -0,0 +1,6 @@ +See ../README for common README file. + +The Java implementation of the test-suite is a little different to the other languages in that all of SWIGs output goes into a subdirectory named after the individual test case. This is so that all the shadow classes can be compiled as Java classes have to go into separate files. Otherwise the Makefile wouldn't know which .java files would be relevant to the testcase. For this to work the testcase must go into a Java package. + +Any testcases which have _runme.java appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/java/arrays_global_twodim_runme.java b/Examples/test-suite/java/arrays_global_twodim_runme.java new file mode 100644 index 000000000..2cbc0138a --- /dev/null +++ b/Examples/test-suite/java/arrays_global_twodim_runme.java @@ -0,0 +1,33 @@ +// Two dimension arrays test + +import arrays_global_twodim.*; + +public class arrays_global_twodim_runme { + static { + try { + System.loadLibrary("arrays_global_twodim"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + SWIGTYPE_p_a_4__int constintarray2d = arrays_global_twodim.getArray_const_i(); + SWIGTYPE_p_a_4__int intarray2d = arrays_global_twodim.getArray_i(); + + // Set all the non const int array members from the const int array members and check + arrays_global_twodim.setArray_i(constintarray2d); + + int count = 10; + for (int x=0; xExceptionClear(); + jclass excep = jenv->FindClass("java/lang/NoSuchFieldException"); + if (excep) + jenv->ThrowNew(excep, "Value of 10 not acceptable"); + } +} + +// Duplicate exceptions should be removed from the generated throws clause +%typemap(out, throws="IllegalAccessException, NoSuchFieldException, CloneNotSupportedException ") short { + $result = (jshort)$1; +} + +%inline %{ +short full_of_exceptions(int num) { + return 0; +} +%} + + +%typemap(throws, throws="IllegalAccessException") int { + jclass excep = jenv->FindClass("java/lang/IllegalAccessException"); + if (excep) + jenv->ThrowNew(excep, "Test exception"); + return $null; +} +%inline %{ +void throw_spec_function(int value) throw (int) { throw (int)0; } +%} + diff --git a/Examples/test-suite/java_typemaps_proxy.i b/Examples/test-suite/java_typemaps_proxy.i new file mode 100644 index 000000000..e5b317b0b --- /dev/null +++ b/Examples/test-suite/java_typemaps_proxy.i @@ -0,0 +1,53 @@ +/* Tests the Java specific directives */ + +%module java_typemaps_proxy + + +%typemap(javaimports) SWIGTYPE "import java.math.*;"; +%typemap(javacode) Farewell %{ + public void saybye(BigDecimal num_times) { + // BigDecimal requires the java.math library + } +%} +%typemap(javaclassmodifiers) Farewell "public final"; + +%typemap(javaimports) Greeting %{ +import java.util.*; // for EventListener +import java.lang.*; // for Exception +%}; + +%typemap(javabase) Greeting "Exception"; +%typemap(javainterfaces) Greeting "EventListener"; +%typemap(javacode) Greeting %{ + // Pure Java code generated using %typemap(javacode) + public void sayhello() { + hello(); + } + + public static void cheerio(EventListener e) { + } +%} + +// Create a new getCPtr() function which takes Java null +%typemap(javagetcptr) Greeting %{ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} + +// get rid of the finalize method for Farewell +%typemap(javafinalize) Farewell ""; + +// Make the pointer constructor public +%typemap(javaptrconstructormodifiers) Farewell "public"; + + +%inline %{ +class Greeting { +public: + void hello() {} + static void ciao(Greeting* g) {} +}; +class Farewell { +}; +%} diff --git a/Examples/test-suite/java_typemaps_typewrapper.i b/Examples/test-suite/java_typemaps_typewrapper.i new file mode 100644 index 000000000..b8fd4cb92 --- /dev/null +++ b/Examples/test-suite/java_typemaps_typewrapper.i @@ -0,0 +1,57 @@ +/* Contrived example to test the Java specific directives on the type wrapper classes */ + +%module java_typemaps_typewrapper + + +%typemap(javaimports) SWIGTYPE * "import java.math.*;"; +%typemap(javacode) Farewell * %{ + public static $javaclassname CreateNullPointer() { + return new $javaclassname(); + } + public void saybye(BigDecimal num_times) { + // BigDecimal requires the java.math library + } +%} +%typemap(javaclassmodifiers) Farewell * "public final"; + +%typemap(javaimports) Greeting * %{ +import java.util.*; // for EventListener +import java.lang.*; // for Exception +%}; + +%typemap(javabase) Greeting * "Exception"; +%typemap(javainterfaces) Greeting * "EventListener"; +%typemap(javacode) Greeting * %{ + // Pure Java code generated using %typemap(javacode) + public static $javaclassname CreateNullPointer() { + return new $javaclassname(); + } + + public void sayhello() { + $javaclassname.cheerio(new $javaclassname()); + } + + public static void cheerio(EventListener e) { + } +%} + +// Create a new getCPtr() function which takes Java null +%typemap(javagetcptr) Farewell * %{ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} + +// Make the pointer constructor public +%typemap(javaptrconstructormodifiers) Farewell * "public"; + + +%{ +class Greeting {}; +class Farewell {}; +%} + +%inline %{ + Greeting* solong(Farewell* f) { return NULL; } +%} + diff --git a/Examples/test-suite/kind.i b/Examples/test-suite/kind.i new file mode 100644 index 000000000..faaf4c369 --- /dev/null +++ b/Examples/test-suite/kind.i @@ -0,0 +1,34 @@ +/* + * This interface file tests whether the language modules handle the kind when declared + * with the function/member name, especially when used with shadow classes. +*/ + +%module kind + +%warnfilter(801) foo; /* Ruby, wrong class name */ +%warnfilter(801) bar; /* Ruby, wrong class name */ +%warnfilter(801) uni; /* Ruby, wrong class name */ +%warnfilter(801) test; /* Ruby, wrong class name */ + +%inline %{ + +class foo {}; +struct bar {}; +union uni {}; + +struct test { + void foofn(class foo myfoo1, foo myfoo2, class foo* myfoo3, foo* myfoo4, class foo& myfoo5, foo& myfoo6) {} + void barfn(struct bar mybar1, bar mybar2, struct bar* mybar3, bar* mybar4, struct bar& mybar5, bar& mybar6) {} + void unifn(union uni myuni1, uni myuni2, union uni* myuni3, uni* myuni4, union myuni& myuni5, myuni& myuni6) {} + + class foo myFooMember; + struct bar myBarMember; + union uni myUniMember; + + class foo* mypFooMember; + struct bar* mypBarMember; + union uni* mypUniMember; +}; + +%} + diff --git a/Examples/test-suite/lib_carrays.i b/Examples/test-suite/lib_carrays.i new file mode 100644 index 000000000..ef2f9abed --- /dev/null +++ b/Examples/test-suite/lib_carrays.i @@ -0,0 +1,9 @@ +%module lib_carrays + +%warnfilter(801) doubleArray; /* Ruby, wrong class name */ + +%include "carrays.i" + +%array_functions(int,intArray); +%array_class(double, doubleArray); + diff --git a/Examples/test-suite/lib_cdata.i b/Examples/test-suite/lib_cdata.i new file mode 100644 index 000000000..8a26d94b3 --- /dev/null +++ b/Examples/test-suite/lib_cdata.i @@ -0,0 +1,8 @@ +%module lib_cdata + +%include "cdata.i" + +%cdata(int); +%cdata(double); + + diff --git a/Examples/test-suite/lib_cmalloc.i b/Examples/test-suite/lib_cmalloc.i new file mode 100644 index 000000000..f37cf6373 --- /dev/null +++ b/Examples/test-suite/lib_cmalloc.i @@ -0,0 +1,12 @@ +%module lib_cmalloc + +%warnfilter(801) sizeof_int; /* Ruby, wrong constant name */ +%warnfilter(801) sizeof_double; /* Ruby, wrong constant name */ +%warnfilter(801) sizeof_intp; /* Ruby, wrong constant name */ + +%include "cmalloc.i" + +%allocators(int); +%allocators(double); +%allocators(void); +%allocators(int *, intp); diff --git a/Examples/test-suite/lib_constraints.i b/Examples/test-suite/lib_constraints.i new file mode 100644 index 000000000..4cef26700 --- /dev/null +++ b/Examples/test-suite/lib_constraints.i @@ -0,0 +1,32 @@ +%module lib_constraints +%include constraints.i + +%inline %{ +void test_nonnegative(double NONNEGATIVE) { +} + +void test_nonpositive(double NONPOSITIVE) { +} + +void test_positive(double POSITIVE) { +} + +void test_negative(double POSITIVE) { +} + +void test_nonzero(double NONZERO) { +} + +void test_nonnull(void *NONNULL) { +} + +void test_align8(void *ALIGN8) { +} + +void test_align4(void *ALIGN4) { +} + +void test_align2(void *ALIGN2) { +} +%} + diff --git a/Examples/test-suite/lib_cpointer.i b/Examples/test-suite/lib_cpointer.i new file mode 100644 index 000000000..e1e6f48f9 --- /dev/null +++ b/Examples/test-suite/lib_cpointer.i @@ -0,0 +1,10 @@ +%module lib_cpointer + +%warnfilter(801) doublep; /* Ruby, wrong class name */ + +%include "cpointer.i" + +%pointer_functions(int,intp); +%pointer_class(double,doublep); +%pointer_cast(int, unsigned int, int_to_uint); + diff --git a/Examples/test-suite/lib_cstring.i b/Examples/test-suite/lib_cstring.i new file mode 100644 index 000000000..4ddbe2920 --- /dev/null +++ b/Examples/test-suite/lib_cstring.i @@ -0,0 +1,88 @@ +%module lib_cstring + +%include "cstring.i" + +#ifndef _CSTRING_UNIMPL + +%cstring_input_binary(char *in, int n); +%cstring_bounded_output(char *out1, 512); +%cstring_chunk_output(char *out2, 128); +%cstring_bounded_mutable(char *out3, 512); +%cstring_mutable(char *out4, 32); +%cstring_output_maxsize(char *out5, int max); +%cstring_output_withsize(char *out6, int *size); +%cstring_output_allocate(char **out7, delete [] $1); +%cstring_output_allocate_size(char **out8, int *size, delete [] $1); + +%inline %{ + +int count(char *in, int n, char c) { + int r = 0; + while (n > 0) { + if (*in == c) { + r++; + } + in++; + } + return r; +} + +void test1(char *out1) { + strcpy(out1,"Hello World"); +} + +void test2(char *out2) { + int i; + for (i = 0; i < 128; i++) { + *out2 = (char) i; + out2++; + } +} + +void test3(char *out3) { + strcat(out3,"-suffix"); +} + +void test4(char *out4) { + strcat(out4,"-suffix"); +} + +void test5(char *out5, int max) { + int i; + for (i = strlen(out5); i < max; i++) { + out5[i] = 'x'; + } +} + +void test6(char *out6, int *size) { + int i; + for (i = 0; i < (*size/2); i++) { + out6[i] = 'x'; + } + *size = (*size/2); +} + +void test7(char **out7) { + *out7 = new char[64]; + strcat(*out7,"Hello world!"); +} + +void test8(char **out8, int *sz) { + int i; + *out8 = new char[128]; + for (i = 0; i < 128; i++) { + *out8[i] = (char) i; + } +} + +%} + +#endif + + + + + + + + diff --git a/Examples/test-suite/lib_math.i b/Examples/test-suite/lib_math.i new file mode 100644 index 000000000..8e5cd0db6 --- /dev/null +++ b/Examples/test-suite/lib_math.i @@ -0,0 +1,2 @@ +%module lib_math +%include math.i diff --git a/Examples/test-suite/lib_std_deque.i b/Examples/test-suite/lib_std_deque.i new file mode 100644 index 000000000..c0cfee020 --- /dev/null +++ b/Examples/test-suite/lib_std_deque.i @@ -0,0 +1,47 @@ +%module lib_std_deque + +%include "std_deque.i" + +%{ +#include +#include +#include +%} + +namespace std { + %template(IntDeque) deque; +} + +%template(DoubleDeque) std::deque; + +%inline %{ +typedef float Real; +%} + +namespace std { + %template(RealDeque) deque; +} + +%inline %{ + +double average(std::deque v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::deque half(const std::deque& v) { + std::deque w(v); + for (unsigned int i=0; i& v) { + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides(),2.0)); +} + +%} + + + + diff --git a/Examples/test-suite/lib_std_string.i b/Examples/test-suite/lib_std_string.i new file mode 100644 index 000000000..bcbf3ba75 --- /dev/null +++ b/Examples/test-suite/lib_std_string.i @@ -0,0 +1,20 @@ +%module lib_std_string +%include "std_string.i" + +%inline %{ + +std::string test_value(std::string x) { + return x; +} + +std::string *test_pointer(std::string *x) { + return x; +} + +std::string test_reference(std::string &x) { + return x; +} + +%} + + diff --git a/Examples/test-suite/lib_std_vector.i b/Examples/test-suite/lib_std_vector.i new file mode 100644 index 000000000..faff99b1f --- /dev/null +++ b/Examples/test-suite/lib_std_vector.i @@ -0,0 +1,47 @@ +%module lib_std_vector + +%include "std_vector.i" + +%{ +#include +#include +#include +%} + +namespace std { + %template(IntVector) vector; +} + +%template(DoubleVector) std::vector; + +%inline %{ +typedef float Real; +%} + +namespace std { + %template(RealVector) vector; +} + +%inline %{ + +double average(std::vector v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector half(const std::vector& v) { + std::vector w(v); + for (unsigned int i=0; i& v) { + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides(),2.0)); +} + +%} + + + + diff --git a/Examples/test-suite/lib_typemaps.i b/Examples/test-suite/lib_typemaps.i new file mode 100644 index 000000000..da4e48e28 --- /dev/null +++ b/Examples/test-suite/lib_typemaps.i @@ -0,0 +1,95 @@ +%module lib_typemaps + +%include "typemaps.i" + +%inline %{ + +bool in_bool(bool *INPUT) { return *INPUT; } +int in_int(int *INPUT) { return *INPUT; } +long in_long(long *INPUT) { return *INPUT; } +short in_short(short *INPUT) { return *INPUT; } +unsigned int in_uint(unsigned int *INPUT) { return *INPUT; } +unsigned short in_ushort(unsigned short *INPUT) { return *INPUT; } +unsigned long in_ulong(unsigned long *INPUT) { return *INPUT; } +unsigned char in_uchar(unsigned char *INPUT) { return *INPUT; } +signed char in_schar(signed char *INPUT) { return *INPUT; } +float in_float(float *INPUT) { return *INPUT; } +double in_double(double *INPUT) { return *INPUT; } +long long in_longlong(long long *INPUT) { return *INPUT; } +unsigned long long in_ulonglong(unsigned long long *INPUT) { return *INPUT; } + +bool inr_bool(bool &INPUT) { return INPUT; } +int inr_int(int &INPUT) { return INPUT; } +long inr_long(long &INPUT) { return INPUT; } +short inr_short(short &INPUT) { return INPUT; } +unsigned int inr_uint(unsigned int &INPUT) { return INPUT; } +unsigned short inr_ushort(unsigned short &INPUT) { return INPUT; } +unsigned long inr_ulong(unsigned long &INPUT) { return INPUT; } +unsigned char inr_uchar(unsigned char &INPUT) { return INPUT; } +signed char inr_schar(signed char &INPUT) { return INPUT; } +float inr_float(float &INPUT) { return INPUT; } +double inr_double(double &INPUT) { return INPUT; } +long long inr_longlong(long long &INPUT) { return INPUT; } +unsigned long long inr_ulonglong(unsigned long long &INPUT) { return INPUT; } + +void out_bool(bool x, bool *OUTPUT) { *OUTPUT = x; } +void out_int(int x, int *OUTPUT) { *OUTPUT = x; } +void out_short(short x, short *OUTPUT) { *OUTPUT = x; } +void out_long(long x, long *OUTPUT) { *OUTPUT = x; } +void out_uint(unsigned int x, unsigned int *OUTPUT) { *OUTPUT = x; } +void out_ushort(unsigned short x, unsigned short *OUTPUT) { *OUTPUT = x; } +void out_ulong(unsigned long x, unsigned long *OUTPUT) { *OUTPUT = x; } +void out_uchar(unsigned char x, unsigned char *OUTPUT) { *OUTPUT = x; } +void out_schar(signed char x, signed char *OUTPUT) { *OUTPUT = x; } +void out_float(float x, float *OUTPUT) { *OUTPUT = x; } +void out_double(double x, double *OUTPUT) { *OUTPUT = x; } +void out_longlong(long long x, long long *OUTPUT) { *OUTPUT = x; } +void out_ulonglong(unsigned long long x, unsigned long long *OUTPUT) { *OUTPUT = x; } + +void outr_bool(bool x, bool &OUTPUT) { OUTPUT = x; } +void outr_int(int x, int &OUTPUT) { OUTPUT = x; } +void outr_short(short x, short &OUTPUT) { OUTPUT = x; } +void outr_long(long x, long &OUTPUT) { OUTPUT = x; } +void outr_uint(unsigned int x, unsigned int &OUTPUT) { OUTPUT = x; } +void outr_ushort(unsigned short x, unsigned short &OUTPUT) { OUTPUT = x; } +void outr_ulong(unsigned long x, unsigned long &OUTPUT) { OUTPUT = x; } +void outr_uchar(unsigned char x, unsigned char &OUTPUT) { OUTPUT = x; } +void outr_schar(signed char x, signed char &OUTPUT) { OUTPUT = x; } +void outr_float(float x, float &OUTPUT) { OUTPUT = x; } +void outr_double(double x, double &OUTPUT) { OUTPUT = x; } +void outr_longlong(long long x, long long &OUTPUT) { OUTPUT = x; } +void outr_ulonglong(unsigned long long x, unsigned long long &OUTPUT) { OUTPUT = x; } + +void inout_bool(bool *INOUT) { *INOUT = *INOUT; } +void inout_int(int *INOUT) { *INOUT = *INOUT; } +void inout_short(short *INOUT) { *INOUT = *INOUT; } +void inout_long(long *INOUT) { *INOUT = *INOUT; } +void inout_uint(unsigned int *INOUT) { *INOUT = *INOUT; } +void inout_ushort(unsigned short *INOUT) { *INOUT = *INOUT; } +void inout_ulong(unsigned long *INOUT) { *INOUT = *INOUT; } +void inout_uchar(unsigned char *INOUT) { *INOUT = *INOUT; } +void inout_schar(signed char *INOUT) { *INOUT = *INOUT; } +void inout_float(float *INOUT) { *INOUT = *INOUT; } +void inout_double(double *INOUT) { *INOUT = *INOUT; } +void inout_longlong(long long *INOUT) { *INOUT = *INOUT; } +void inout_ulonglong(unsigned long long *INOUT) { *INOUT = *INOUT; } + +void inoutr_bool(bool &INOUT) { INOUT = INOUT; } +void inoutr_int(int &INOUT) { INOUT = INOUT; } +void inoutr_short(short &INOUT) { INOUT = INOUT; } +void inoutr_long(long &INOUT) { INOUT = INOUT; } +void inoutr_uint(unsigned int &INOUT) { INOUT = INOUT; } +void inoutr_ushort(unsigned short &INOUT) { INOUT = INOUT; } +void inoutr_ulong(unsigned long &INOUT) { INOUT = INOUT; } +void inoutr_uchar(unsigned char &INOUT) { INOUT = INOUT; } +void inoutr_schar(signed char &INOUT) { INOUT = INOUT; } +void inoutr_float(float &INOUT) { INOUT = INOUT; } +void inoutr_double(double &INOUT) { INOUT = INOUT; } +void inoutr_longlong(long long &INOUT) { INOUT = INOUT; } +void inoutr_ulonglong(unsigned long long &INOUT) { INOUT = INOUT; } + +%} + + + + diff --git a/Examples/test-suite/list_vector.i b/Examples/test-suite/list_vector.i new file mode 100644 index 000000000..5cc30e982 --- /dev/null +++ b/Examples/test-suite/list_vector.i @@ -0,0 +1,153 @@ +/* -*- c -*- */ + +%module test + +%include "list-vector.i" + +%multiple_values + +/* The ordinary, well behaved multi-typemap. */ +double sum_list(int LISTLENINPUT, double *LISTINPUT); +double sum_vector(int VECTORLENINPUT, double *VECTORINPUT); +void one_to_seven_list(int *LISTLENOUTPUT, int **LISTOUTPUT); +void one_to_seven_vector(int *VECTORLENOUTPUT, int **VECTOROUTPUT); + +/* Variants with `size_t' instead of `int' length. */ +double sum_list2(size_t LISTLENINPUT, double *LISTINPUT); +double sum_vector2(size_t VECTORLENINPUT, double *VECTORINPUT); +void one_to_seven_list2(size_t *LISTLENOUTPUT, int **LISTOUTPUT); +void one_to_seven_vector2(size_t *VECTORLENOUTPUT, int **VECTOROUTPUT); + +/* Parallel variants */ + +double sum_lists(int PARALLEL_LISTLENINPUT, + double *PARALLEL_LISTINPUT, + int *PARALLEL_LISTINPUT, + int *PARALLEL_LISTINPUT); +double sum_lists2(size_t PARALLEL_LISTLENINPUT, + double *PARALLEL_LISTINPUT, + int *PARALLEL_LISTINPUT, + int *PARALLEL_LISTINPUT); +void produce_lists(int *PARALLEL_VECTORLENOUTPUT, + int **PARALLEL_VECTOROUTPUT, + int **PARALLEL_VECTOROUTPUT, + double **PARALLEL_VECTOROUTPUT); + +%{ + double sum_list(int length, double *item) + { + int i; + double res = 0.0; + for (i = 0; i T max(T x, T y, T z) { return (x > y) ? x : y; } + +template class Foo { + public: + template S max(S x, S y) { return (x > y) ? x : y; } +}; + +%} + +%extend Foo { + %template(maxi) max; + %template(maxd) max; +}; + +%template(Fooint) Foo; +%template(Foodouble) Foo; + diff --git a/Examples/test-suite/memberin1.i b/Examples/test-suite/memberin1.i new file mode 100644 index 000000000..920323044 --- /dev/null +++ b/Examples/test-suite/memberin1.i @@ -0,0 +1,63 @@ +%module memberin1 + +%{ +class String { +private: + char *str; +public: + // Constructor + String(const char *s = 0) : str(0) { + if (s != 0) { + str = new char[strlen(s) + 1]; + strcpy(str, s); + } + } + + // Copy constructor + String(const String& other) { + delete [] str; + str = 0; + if (other.str != 0) { + str = new char[strlen(other.str) + 1]; + strcpy(str, other.str); + } + } + + // Assignment operator + String& operator=(const String& other) { + if (&other != this) { + delete [] str; + str = 0; + if (other.str != 0) { + str = new char[strlen(other.str) + 1]; + strcpy(str, other.str); + } + } + return *this; + } + + // String contents + const char *c_str() const { return str; } + + // Destructor + ~String() { delete [] str; } +}; +%} + +#ifdef SWIGRUBY +%typemap(in) String { + Check_Type($input, T_STRING); + $1 = String(STR2CSTR($input)); +} +#endif + +%typemap(memberin) String { + $1 = $input; +} + +%inline %{ +struct Person { + String name; +}; +%} + diff --git a/Examples/test-suite/minherit.i b/Examples/test-suite/minherit.i new file mode 100644 index 000000000..0300f7199 --- /dev/null +++ b/Examples/test-suite/minherit.i @@ -0,0 +1,80 @@ +// This module tests multiple inheritance, typedef handling, and some +// truly horrible parts of the SWIG type system. This is only tested +// for Python since not all language modules support multiple-inheritance. +// However, if it works for Python, things should be working for other +// modules. + +%module minherit + +#ifdef SWIGPYTHON + +%inline %{ + +class Foo { +private: + int x; +public: + Foo() { x = 1; } + virtual int xget() { return x; }; +}; +typedef Foo *FooPtr; + +FooPtr toFooPtr(Foo *f) { return f; } + +class Bar { +private: + int y; +public: + Bar() { y = 2; } + virtual int yget() { return y; } +}; + +typedef Bar *BarPtr; +BarPtr toBarPtr(Bar *f) { return f; } + +class FooBar : public Foo, public Bar { +private: + int z; +public: + FooBar() { z = 3; } + virtual int zget() { return z; } +}; + +typedef FooBar *FooBarPtr; +FooBarPtr toFooBarPtr(FooBar *f) { return f; } + +class Spam: public FooBar { +private: + int w; +public: + Spam() { w = 4; } + virtual int wget() { return w; } +}; + +typedef Spam *SpamPtr; +SpamPtr toSpamPtr(Spam *f) { return f; } + +int xget(FooPtr f) { + return f->xget(); +} + +int yget(BarPtr f) { + return f->yget(); +} + +int zget(FooBarPtr f) { + return f->zget(); +} + +int wget(SpamPtr f) { + return f->wget(); +} +%} + +#endif + + + + + + diff --git a/Examples/test-suite/multivalue.i b/Examples/test-suite/multivalue.i new file mode 100644 index 000000000..6cb3c3d7d --- /dev/null +++ b/Examples/test-suite/multivalue.i @@ -0,0 +1,52 @@ +/* -*- c -*- */ + +%module test + +#ifdef SWIGGUILE + +/* Multiple values as lists. By default, if more than one value is to +be returned, a list of the values is created and returned; to switch +back to this behavior, use: */ +%values_as_list; + +void divide_l(int a, int b, int *OUTPUT, int *OUTPUT); + +/* Multiple values as vectors. By issueing: */ +%values_as_vector; +/* vectors instead of lists will be used. */ + +void divide_v(int a, int b, int *OUTPUT, int *OUTPUT); + +/* Multiple values for multiple-value continuations. + (This is the most elegant way.) By issueing: */ +%multiple_values; +/* multiple values are passed to the multiple-value + continuation, as created by `call-with-values' or the + convenience macro `receive'. (See the Scheme file.) */ + +void divide_mv(int a, int b, int *OUTPUT, int *OUTPUT); + +#endif + +%{ + +void divide_l(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +void divide_v(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +void divide_mv(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +%} + diff --git a/Examples/test-suite/mzscheme/.cvsignore b/Examples/test-suite/mzscheme/.cvsignore new file mode 100644 index 000000000..597965c42 --- /dev/null +++ b/Examples/test-suite/mzscheme/.cvsignore @@ -0,0 +1 @@ +*wrap.c* diff --git a/Examples/test-suite/mzscheme/Makefile b/Examples/test-suite/mzscheme/Makefile new file mode 100644 index 000000000..ead394b57 --- /dev/null +++ b/Examples/test-suite/mzscheme/Makefile @@ -0,0 +1,40 @@ +####################################################################### +# $Header$ +# Makefile for mzscheme test-suite +####################################################################### + +LANGUAGE = mzscheme +SCRIPTSUFFIX = _runme.scm + +include ../common.mk + +# Overridden variables here + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.scm appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.scm ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH mzscheme -r $*\_runme.scm;) \ + fi; + +# Clean +%.clean: + +clean: + $(MAKE) -f $(TOP)/Makefile mzscheme_clean diff --git a/Examples/test-suite/mzscheme/README b/Examples/test-suite/mzscheme/README new file mode 100644 index 000000000..37432ea4b --- /dev/null +++ b/Examples/test-suite/mzscheme/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.scm appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/mzscheme/casts_runme.scm b/Examples/test-suite/mzscheme/casts_runme.scm new file mode 100644 index 000000000..3aaa62dc6 --- /dev/null +++ b/Examples/test-suite/mzscheme/casts_runme.scm @@ -0,0 +1,7 @@ +(load-extension "casts.so") + +(define x (new-B)) + +(A-hello x) + +(exit 0) diff --git a/Examples/test-suite/mzscheme/char_constant_runme.scm b/Examples/test-suite/mzscheme/char_constant_runme.scm new file mode 100644 index 000000000..4e3ed47ca --- /dev/null +++ b/Examples/test-suite/mzscheme/char_constant_runme.scm @@ -0,0 +1,6 @@ +(load-extension "char_constant.so") + +(if (and (char? (CHAR-CONSTANT)) + (string? (STRING-CONSTANT))) + (exit 0) + (exit 1)) diff --git a/Examples/test-suite/mzscheme/import_runme.scm b/Examples/test-suite/mzscheme/import_runme.scm new file mode 100644 index 000000000..8e8f27339 --- /dev/null +++ b/Examples/test-suite/mzscheme/import_runme.scm @@ -0,0 +1,16 @@ +;;; This file is part of a test for SF bug #231619. +;;; It shows that the %import directive does not work properly in SWIG +;;; 1.3a5: Type information is not properly generated if a base class +;;; comes from an %import-ed file. + +(load-extension "libimports_a.so") +(load-extension "libimports_b.so") + +(define x (new-B)) + +;; This fails in 1.3a5 because the SWIG runtime code does not know +;; that x (an instance of class B) can be passed to methods of class A. + +(A-hello x) + +(exit 0) diff --git a/Examples/test-suite/mzscheme/name_runme.scm b/Examples/test-suite/mzscheme/name_runme.scm new file mode 100644 index 000000000..1782c6481 --- /dev/null +++ b/Examples/test-suite/mzscheme/name_runme.scm @@ -0,0 +1,10 @@ +;; The SWIG modules have "passive" Linkage, i.e., they don't generate +;; Guile modules (namespaces) but simply put all the bindings into the +;; current module. That's enough for such a simple test. +(load-extension "./name.so") + +(foo-2) +bar-2 +Baz-2 + +(exit 0) diff --git a/Examples/test-suite/mzscheme/unions_runme.scm b/Examples/test-suite/mzscheme/unions_runme.scm new file mode 100644 index 000000000..c44847cfc --- /dev/null +++ b/Examples/test-suite/mzscheme/unions_runme.scm @@ -0,0 +1,38 @@ +;;; This is the union runtime testcase. It ensures that values within a +;;; union embedded within a struct can be set and read correctly. + +(load-extension "unions.so") + +;; Create new instances of SmallStruct and BigStruct for later use +(define small (new-SmallStruct)) +(SmallStruct-jill-set small 200) + +(define big (new-BigStruct)) +(BigStruct-smallstruct-set big small) +(BigStruct-jack-set big 300) + +;; Use SmallStruct then BigStruct to setup EmbeddedUnionTest. +;; Ensure values in EmbeddedUnionTest are set correctly for each. +(define eut (new-EmbeddedUnionTest)) + +;; First check the SmallStruct in EmbeddedUnionTest +(EmbeddedUnionTest-number-set eut 1) +(EmbeddedUnionTest-uni-small-set (EmbeddedUnionTest-uni-get eut) + small) +(let ((Jill1 (SmallStruct-jill-get + (EmbeddedUnionTest-uni-small-get + (EmbeddedUnionTest-uni-get eut))))) + (if (not (= Jill1 200)) + (begin + (display "Runtime test 1 failed.") + (exit 1)))) + +(let ((Num1 (EmbeddedUnionTest-number-get eut))) + (if (not (= Num1 1)) + (begin + (display "Runtime test 2 failed.") + (exit 1)))) + +;; that should do + +(exit 0) diff --git a/Examples/test-suite/name.i b/Examples/test-suite/name.i new file mode 100644 index 000000000..8af8cd68b --- /dev/null +++ b/Examples/test-suite/name.i @@ -0,0 +1,26 @@ +/* This interface file tests whether SWIG/Guile handle the %rename and + %name directives, which was not the case in 1.3a5. +*/ + +%module name + +#ifdef SWIGGUILE +%rename foo_1 "foo-2"; +#else +%rename foo_1 "foo_2"; +#endif +%inline %{ +void foo_1() {} +%} + +#ifdef SWIGGUILE +%name("bar-2") +#else +%name("bar_2") +#endif +%inline %{ +int bar_1 = 17; +%} + +%name("Baz_2") +%constant int Baz_1 = 47; diff --git a/Examples/test-suite/name_cxx.i b/Examples/test-suite/name_cxx.i new file mode 100644 index 000000000..3b6965487 --- /dev/null +++ b/Examples/test-suite/name_cxx.i @@ -0,0 +1,16 @@ +/* This interface files tests whether SWIG handles overloaded + renamed functions. +*/ + +%module name_cxx + +%name("bar_int") +%inline %{ +void bar(int i) {} +%} + +%name("bar_double") +%inline %{ +void bar(double i) {} +%} + diff --git a/Examples/test-suite/name_inherit.i b/Examples/test-suite/name_inherit.i new file mode 100644 index 000000000..3ce40d145 --- /dev/null +++ b/Examples/test-suite/name_inherit.i @@ -0,0 +1,13 @@ +%module name_inherit +%{ +class A { +}; + +class B : public A { +}; + +%} + +%name(AA) class A { }; +class B : public A { }; + diff --git a/Examples/test-suite/namespace_enum.i b/Examples/test-suite/namespace_enum.i new file mode 100644 index 000000000..82a97c630 --- /dev/null +++ b/Examples/test-suite/namespace_enum.i @@ -0,0 +1,24 @@ +%module namespace_enum + +%inline %{ + +namespace Foo { + enum Swig { + LAGER, + STOUT, + ALE + }; + + class Bar { + public: + enum Speed { + SLOW, + FAST + }; + }; +} + +%} + + + \ No newline at end of file diff --git a/Examples/test-suite/namespace_extend.i b/Examples/test-suite/namespace_extend.i new file mode 100644 index 000000000..52ec0fb57 --- /dev/null +++ b/Examples/test-suite/namespace_extend.i @@ -0,0 +1,34 @@ +%module namespace_extend + +%warnfilter(801) bar; /* Ruby, wrong class name */ + +%{ +namespace foo { + class bar { + public: + }; +} +foo::bar *new_foo_bar() { + return new foo::bar; +} +void delete_foo_bar(foo::bar *self) { + delete self; +} +int foo_bar_blah(foo::bar *self, int x) { + return x; +} +%} + +namespace foo { + class bar { + public: + %extend { + bar(); + ~bar(); + int blah(int x); + }; + }; +} + + + diff --git a/Examples/test-suite/namespace_nested.i b/Examples/test-suite/namespace_nested.i new file mode 100644 index 000000000..ec75c19a6 --- /dev/null +++ b/Examples/test-suite/namespace_nested.i @@ -0,0 +1,59 @@ +%module namespace_nested + +%warnfilter(801) hello::hi::hi0; /* Ruby, wrong class name */ +%warnfilter(801) oss::hi1; /* Ruby, wrong class name */ + +%inline %{ + namespace hello + { + namespace hi + { + struct hi0 + { + }; + } + + template + struct Hi : _T1 + { + }; + } + +%} + +namespace hello +{ + %template(Hi_hi0) Hi; +} + + +%inline %{ + + namespace hello + { + // + // This works + // + // typedef Hi Hi0; + + // + // This doesn't work + // + typedef Hi Hi0; + }; + + + namespace oss + { + template + struct hi1 : _T + { + }; + } + +%} + +namespace oss +{ + %template(hi1_hi0) hi1; +} diff --git a/Examples/test-suite/namespace_template.i b/Examples/test-suite/namespace_template.i new file mode 100644 index 000000000..1a0cfb6b2 --- /dev/null +++ b/Examples/test-suite/namespace_template.i @@ -0,0 +1,78 @@ +/* Tests the use of %template with namespaces */ + +%module namespace_template + +%warnfilter(801) vector; /* Ruby, wrong class name */ +%warnfilter(801) test2::vector; /* Ruby, wrong class name */ +%warnfilter(801) test3::vector; /* Ruby, wrong class name */ +%warnfilter(801) vector; /* Ruby, wrong class name */ + +%{ +namespace test { + template T max(T a, T b) { return (a > b) ? a : b; } + template class vector { + public: + vector() { } + ~vector() { } + char * blah(T x) { + return (char *) "vector::blah"; + } + }; +} + +namespace test2 { + using namespace test; +} + +namespace test3 { + using test::max; + using test::vector; +} + +using namespace test2; +namespace T4 = test; +%} + +namespace test { + template T max(T a, T b) { return (a > b) ? a : b; } + template class vector { + public: + vector() { } + ~vector() { } + char * blah(T x) { + return (char *) "vector::blah"; + } + }; +} + +using namespace test; +%template(maxint) max; +%template(vectorint) vector; + +namespace test2 { + using namespace test; + %template(maxshort) max; + %template(vectorshort) vector; +} + +namespace test3 { + using test::max; + using test::vector; + %template(maxlong) max; + %template(vectorlong) vector; +} + +%inline %{ + +namespace test4 { + using namespace test; + typedef int Integer; +} + +%} + +namespace test4 { + %template(maxInteger) max; + %template(vectorInteger) vector; +} + diff --git a/Examples/test-suite/namespace_typemap.i b/Examples/test-suite/namespace_typemap.i new file mode 100644 index 000000000..97af110c0 --- /dev/null +++ b/Examples/test-suite/namespace_typemap.i @@ -0,0 +1,229 @@ +// This tests SWIG's handling of typemaps and namespaces +%module namespace_typemap + +%{ +namespace test { + /* A minimalistic string class */ + class string { + char *data; + public: + string() { + data = 0; + } + string(const char *s) { + data = new char[strlen(s)+1]; + strcpy(data,s); + } + ~string() { + if (data) delete [] data; + } + char *c_str() { + return data; + }; + }; + + /* A minimalistic complex class */ + class complex { + double re; + double im; + public: + complex(double r = 0, double i = 0) { + re = r; + im = i; + } + double real() { + return re; + } + double imag() { + return im; + } + }; +} + %} + +/* SWIG interface tests */ + +#ifdef SWIGPYTHON +%typemap(in) test::complex * { + if (PyComplex_Check($input)) { + $1 = new complex(PyComplex_RealAsDouble($input), + PyComplex_ImagAsDouble($input)); + } else { + PyErr_SetString(PyExc_TypeError,"Expected complex.\n"); + return NULL; + } +} +%typemap(freearg) test::complex * { + delete $1; +} +#endif + +namespace test { + class string; +#ifdef SWIGPYTHON + %typemap(in) string * { + $1 = new string(PyString_AsString($input)); + } + %typemap(freearg) string * { + delete $1; + } +#endif +#ifdef SWIGRUBY + %typemap(in) string * { + $1 = new string(STR2CSTR($input)); + } + %typemap(freearg) string * { + delete $1; + } +#endif +} + +%inline %{ + namespace test { + class string; + class complex; + + /* Functions in the namespace itself */ + char *stest1(string *s) { + return s->c_str(); + } + double ctest1(complex *c) { + return c->real(); + } + } + + namespace test2 { + using test::string; + using test::complex; + + /* Functions in another namespace */ + char *stest2(string *s) { + return s->c_str(); + } + double ctest2(complex *c) { + return c->real(); + } + } + + namespace test3 { + using namespace test; + + char *stest3(string *s) { + return s->c_str(); + } + double ctest3(complex *c) { + return c->real(); + } + } + + namespace test4 { + using namespace test2; + + char *stest4(string *s) { + return s->c_str(); + } + double ctest4(complex *c) { + return c->real(); + } + } + + namespace test5 { + using namespace test3; + + char *stest5(string *s) { + return s->c_str(); + } + double ctest5(complex *c) { + return c->real(); + } + } + + char *stest6(test::string *s) { + return s->c_str(); + } + double ctest6(test::complex *c) { + return c->real(); + } + + char *stest7(test2::string *s) { + return s->c_str(); + } + double ctest7(test2::complex *c) { + return c->real(); + } + + char *stest8(test3::string *s) { + return s->c_str(); + } + double ctest8(test3::complex *c) { + return c->real(); + } + + char *stest9(test4::string *s) { + return s->c_str(); + } + double ctest9(test4::complex *c) { + return c->real(); + } + + char *stest10(test5::string *s) { + return s->c_str(); + } + double ctest10(test5::complex *c) { + return c->real(); + } + + namespace test11 = test; + + char *stest11(test11::string *s) { + return s->c_str(); + } + double ctest11(test11::complex *c) { + return c->real(); + } + + using namespace test2; + using test::complex; + + char *stest12(string *s) { + return s->c_str(); + } + double ctest12(complex *c) { + return c->real(); + } +%} + +namespace Split { +#ifdef SWIGPYTHON + %typemap(in) PosInteger { + $1 = PyInt_AsLong($input); + if ($1 < 0) { + PyErr_SetString(PyExc_ValueError,"domain error\n"); + return NULL; + } + } +#endif +#ifdef SWIGRUBY + %typemap(in) PosInteger { + $1 = NUM2INT($input); + if ($1 < 0) { + rb_raise(rb_eRangeError, "domain error"); + } + } +#endif +}; + +%inline %{ + namespace Split { + typedef int PosInteger; + PosInteger ttest1(PosInteger x) { + return x; + }; + } +%} + + + + + + diff --git a/Examples/test-suite/nested.i b/Examples/test-suite/nested.i new file mode 100644 index 000000000..7771fe7be --- /dev/null +++ b/Examples/test-suite/nested.i @@ -0,0 +1,34 @@ +/* +This testcase tests that nested structs/unions work. Named structs/unions declared within +a struct produced redefinition errors in SWIG 1.3.6 as reported by SF bug #447488. +Also tests reported error when a #define placed in a deeply embedded struct/union. +*/ + +%module nested +%pragma make_default + +%inline %{ + +struct TestStruct { + int a; +}; + +typedef struct OuterStruct { + union { + + struct outer_nested_struct { + union inner_nested_union { +#define BAD_STYLE 1 + int red; + struct TestStruct green; + } InnerNestedUnion; + + struct inner_nested_struct { + int blue; + } InnerNestedStruct; + } OuterNestedStruct; + + } EmbeddedUnion; +} OuterStruct; + +%} diff --git a/Examples/test-suite/newobject1.i b/Examples/test-suite/newobject1.i new file mode 100644 index 000000000..b5b018b2f --- /dev/null +++ b/Examples/test-suite/newobject1.i @@ -0,0 +1,51 @@ +/** + * The purpose of this test is to confirm that a language module + * correctly handles the case when C++ class member functions (of both + * the static and non-static persuasion) have been tagged with the + * %newobject directive. + */ + +%module newobject1 + +%newobject Foo::makeFoo(); +%newobject Foo::makeMore(); + +%inline %{ +class Foo +{ +private: + Foo(const Foo&); + Foo& operator=(const Foo&); +private: + static int m_fooCount; +protected: + Foo() { + m_fooCount++; + } +public: + // Factory function (static) + static Foo *makeFoo() { + return new Foo; + } + + // Factory function (regular) + Foo *makeMore() { + return new Foo; + } + + // Return the number of instances + static int fooCount() { + return m_fooCount; + } + + // Destructor + ~Foo() { + m_fooCount--; + } +}; +%} + +%{ +// Static member initialization (not wrapped) +int Foo::m_fooCount = 0; +%} diff --git a/Examples/test-suite/newobject2.i b/Examples/test-suite/newobject2.i new file mode 100644 index 000000000..bbe94a50e --- /dev/null +++ b/Examples/test-suite/newobject2.i @@ -0,0 +1,38 @@ +/** + * The purpose of this test is to confirm that a language module + * correctly handles the case when a C function has been tagged with the + * %newobject directive. + */ + +%module newobject2 + +%{ +/* Global initialization (not wrapped) */ +int g_fooCount = 0; +%} + +%newobject makeFoo(); + +%inline %{ +/* Struct definition */ +typedef struct {} Foo; + +/* Make one */ +Foo *makeFoo() { + Foo *foo = (Foo *) malloc(sizeof(Foo)); + g_fooCount++; + return foo; +} + +/* Return the number of instances */ +int fooCount() { + return g_fooCount; +} +%} + +%extend Foo { + ~Foo() { + free((void *) self); + g_fooCount--; + } +} diff --git a/Examples/test-suite/ocaml/Makefile b/Examples/test-suite/ocaml/Makefile new file mode 100644 index 000000000..9c9a182bf --- /dev/null +++ b/Examples/test-suite/ocaml/Makefile @@ -0,0 +1,64 @@ +LANGUAGE = ocaml +VARIANT = _static +SCRIPTSUFFIX = _runme.ml + +C_TEST_CASES = + +run_testcase = \ + if [ -f $*\_runme.ml ] ; then \ + (ocamlc -c $*\_runme.ml ; \ + ocamlc -custom -g -o runme $*\.cmo $*\_runme.cmo $*\_wrap.o ; \ + ./runme) ; \ + fi ; + +check_quant: + cat /dev/null > testing + cat /dev/null > success + cat /dev/null > results + $(MAKE) check + echo "Failed:" >> results + for element in `cat testing` ; do \ + if grep $$element success >/dev/null 2>/dev/null ; then \ + : ; \ + else \ + echo $$element >> results ; \ + fi ; \ + done + echo "Success:" >> results + cat success >> results + +include ../common.mk + +%.cpptest: + echo $@ >> testing + $(setup) \ + ($(swig_and_compile_cpp); ) ; \ + $(run_testcase) \ + if [ -f $(@:%.cpptest=%_wrap.o) ] ; then \ + echo $@ >> success ; \ + fi + +%.ctest: + echo $@ >> testing + $(setup) \ + ($(swig_and_compile_c); ) ; \ + $(run_testcase) \ + if [ -f $(@:%.ctest=%_wrap.o) ] ; then \ + echo $@ >> success ; \ + fi + +%.multicpptest: + echo $@ >> testing + $(setup) \ + ($(swig_and_compile_multi_cpp); ) ; \ + $(run_testcase) \ + if [ -f $(@:%.multicpptest=%_a_wrap.o) ] ; then \ + echo $@ >> success ; \ + fi + +%.clean: + @rm -f $*.ml $*.mli; + +clean: + $(MAKE) -f $(TOP)/Makefile ocaml_clean + diff --git a/Examples/test-suite/ocaml/README b/Examples/test-suite/ocaml/README new file mode 100644 index 000000000..3fdea6252 --- /dev/null +++ b/Examples/test-suite/ocaml/README @@ -0,0 +1,2 @@ +I stole most of these runme's from the ruby runme scripts, since the current +ocaml interface mirrors the ruby interface in many ways. diff --git a/Examples/test-suite/ocaml/class_ignore_runme.ml b/Examples/test-suite/ocaml/class_ignore_runme.ml new file mode 100644 index 000000000..846643aa8 --- /dev/null +++ b/Examples/test-suite/ocaml/class_ignore_runme.ml @@ -0,0 +1,6 @@ +open Class_ignore + +let a = new_Bar C_void +let _ = (if _do_blah a <> C_string "Bar::blah" then + raise (Failure "We didn't really get a bar object.")) + diff --git a/Examples/test-suite/ocaml/makedebugtop b/Examples/test-suite/ocaml/makedebugtop new file mode 100755 index 000000000..8d712801c --- /dev/null +++ b/Examples/test-suite/ocaml/makedebugtop @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Usage: makedebugtop test_name.c[pp]test +# +# Creates an ocaml toplevel for debugging based on a .cpptest or .ctest +# file. +# + +OCAMLINC=/usr/local/lib/ocaml +swigtest=$1 +thetest=`echo $1 | sed -e 's/\.c[p]*test//g'` +cppopt="" +if echo $swigtest | grep -s cpptest ; then + cppopt=-xc++ +fi + +echo "Making the test" +make $swigtest +echo "Building ${thetest}_top" +gcc -c -g $cppopt -I$OCAMLINC ${thetest}_wrap.c +ocamlmktop -cclib -g -custom ${thetest}_wrap.o ${thetest}.cmo -o ${thetest}_top diff --git a/Examples/test-suite/ocaml/newobject1_runme.ml b/Examples/test-suite/ocaml/newobject1_runme.ml new file mode 100644 index 000000000..247545690 --- /dev/null +++ b/Examples/test-suite/ocaml/newobject1_runme.ml @@ -0,0 +1,25 @@ +open Newobject1 + +exception RuntimeError of string * int + +let foo1 = ref (_Foo_makeFoo C_void) +let _ = if get_int (_Foo_fooCount C_void) != 1 then + raise (RuntimeError ("(1) Foo.fooCount != 1", + get_int (_Foo_fooCount C_void))) + +let foo2 = ref ((invoke !foo1) "makeMore" C_void) +let _ = if get_int (_Foo_fooCount C_void) != 2 then + raise (RuntimeError ("(2) Foo.fooCount != 2", + get_int (_Foo_fooCount C_void))) + +let _ = begin + foo1 := C_void ; Gc.full_major () ; + (if get_int (_Foo_fooCount C_void) != 1 then + raise (RuntimeError ("(3) Foo.fooCount != 1", + get_int (_Foo_fooCount C_void)))) ; + + foo2 := C_void ; Gc.full_major () ; + (if get_int (_Foo_fooCount C_void) != 0 then + raise (RuntimeError ("(4) Foo.fooCount != 0", + get_int (_Foo_fooCount C_void)))) ; +end diff --git a/Examples/test-suite/ocaml/overload_copy_runme.ml b/Examples/test-suite/ocaml/overload_copy_runme.ml new file mode 100644 index 000000000..c48f15b17 --- /dev/null +++ b/Examples/test-suite/ocaml/overload_copy_runme.ml @@ -0,0 +1,4 @@ +open Overload_copy + +let f = new_Foo C_void +let g = new_Foo f diff --git a/Examples/test-suite/ocaml/results b/Examples/test-suite/ocaml/results new file mode 100644 index 000000000..7ee0f1a9c --- /dev/null +++ b/Examples/test-suite/ocaml/results @@ -0,0 +1,180 @@ +Failed: +template_typedef_import.multicpptest +Success: +template_specialization.cpptest +default_cast.cpptest +import_nomodule.cpptest +struct_value.cpptest +abstract_inherit.cpptest +abstract_inherit_ok.cpptest +add_link.cpptest +anonymous_arg.cpptest +argout.cpptest +arrays_global.cpptest +arrays_global_twodim.cpptest +arrays_scope.cpptest +bool_default.cpptest +casts.cpptest +class_ignore.cpptest +const_const_2.cpptest +constant_pointers.cpptest +constover.cpptest +constructor_exception.cpptest +constructor_explicit.cpptest +constructor_value.cpptest +conversion.cpptest +conversion_namespace.cpptest +conversion_ns_template.cpptest +cplusplus_throw.cpptest +cpp_enum.cpptest +cpp_enum_scope.cpptest +cpp_namespace.cpptest +cpp_nodefault.cpptest +cpp_static.cpptest +cpp_typedef.cpptest +default_constructor.cpptest +default_ns.cpptest +default_ref.cpptest +dynamic_cast.cpptest +enum_scope.cpptest +enum_scope_template.cpptest +enum_var.cpptest +evil_diamond.cpptest +evil_diamond_ns.cpptest +evil_diamond_prop.cpptest +explicit.cpptest +extend_template.cpptest +extend_template_ns.cpptest +grouping.cpptest +ignore_parameter.cpptest +inherit_missing.cpptest +kind.cpptest +lib_carrays.cpptest +lib_cdata.cpptest +lib_cpointer.cpptest +lib_std_deque.cpptest +lib_std_string.cpptest +lib_std_vector.cpptest +lib_typemaps.cpptest +member_template.cpptest +minherit.cpptest +name_cxx.cpptest +name_inherit.cpptest +namespace_enum.cpptest +namespace_extend.cpptest +namespace_template.cpptest +namespace_typemap.cpptest +newobject1.cpptest +overload_complicated.cpptest +overload_copy.cpptest +overload_extend.cpptest +overload_simple.cpptest +overload_subtype.cpptest +overload_template.cpptest +pointer_reference.cpptest +primitive_ref.cpptest +private_assign.cpptest +pure_virtual.cpptest +rename_default.cpptest +rename_scope.cpptest +return_value_scope.cpptest +rname.cpptest +smart_pointer_const.cpptest +smart_pointer_multi.cpptest +smart_pointer_multi_typedef.cpptest +smart_pointer_not.cpptest +smart_pointer_overload.cpptest +smart_pointer_protected.cpptest +smart_pointer_rename.cpptest +smart_pointer_simple.cpptest +smart_pointer_typedef.cpptest +static_array_member.cpptest +static_const_member.cpptest +static_const_member_2.cpptest +template.cpptest +template_arg_scope.cpptest +template_arg_typename.cpptest +template_base_template.cpptest +template_classes.cpptest +template_const_ref.cpptest +template_construct.cpptest +template_default.cpptest +template_default2.cpptest +template_default_inherit.cpptest +template_default_qualify.cpptest +template_enum.cpptest +template_enum_ns_inherit.cpptest +template_enum_typedef.cpptest +template_forward.cpptest +template_inherit.cpptest +template_inherit_abstract.cpptest +template_int_const.cpptest +template_ns.cpptest +template_ns2.cpptest +template_ns3.cpptest +template_ns4.cpptest +template_ns_enum.cpptest +template_ns_enum2.cpptest +template_ns_inherit.cpptest +template_ns_scope.cpptest +template_qualifier.cpptest +template_rename.cpptest +template_retvalue.cpptest +template_static.cpptest +template_tbase_template.cpptest +template_type_namespace.cpptest +template_typedef.cpptest +template_typedef_cplx.cpptest +template_typedef_cplx2.cpptest +template_typedef_cplx3.cpptest +template_typedef_cplx4.cpptest +template_virtual.cpptest +template_whitespace.cpptest +throw_exception.cpptest +typedef_funcptr.cpptest +typedef_inherit.cpptest +typedef_mptr.cpptest +typedef_reference.cpptest +typedef_scope.cpptest +typemap_namespace.cpptest +typemap_ns_using.cpptest +typename.cpptest +union_scope.cpptest +using1.cpptest +using2.cpptest +using_composition.cpptest +using_extend.cpptest +using_inherit.cpptest +using_private.cpptest +using_protected.cpptest +valuewrapper_base.cpptest +virtual_destructor.cpptest +voidtest.cpptest +arrayptr.ctest +arrays.ctest +char_constant.ctest +const_const.ctest +defineop.ctest +defines.ctest +enum.ctest +lib_carrays.ctest +lib_cdata.ctest +lib_cmalloc.ctest +lib_constraints.ctest +lib_cpointer.ctest +lib_math.ctest +long_long.ctest +macro_2.ctest +name.ctest +nested.ctest +newobject2.ctest +overload_extendc.ctest +preproc_1.ctest +preproc_2.ctest +preproc_3.ctest +ret_by_value.ctest +sizeof_pointer.ctest +sneaky1.ctest +typemap_subst.ctest +unions.ctest +imports.multicpptest diff --git a/Examples/test-suite/ocaml/sneaky1_runme.ml b/Examples/test-suite/ocaml/sneaky1_runme.ml new file mode 100644 index 000000000..37678b38e --- /dev/null +++ b/Examples/test-suite/ocaml/sneaky1_runme.ml @@ -0,0 +1,8 @@ +(* Stolen from ruby test cases *) + +open Sneaky1 + +let x = Sneaky1._add (C_list [ C_int 3; C_int 4 ]) +let y = Sneaky1._sub (C_list [ C_int 3; C_int 4 ]) +let z = Sneaky1._mul (C_list [ C_int 3; C_int 4 ]) +let w = Sneaky1._divide (C_list [ C_int 3; C_int 4 ]) diff --git a/Examples/test-suite/ocaml/throw_exception_runme.ml b/Examples/test-suite/ocaml/throw_exception_runme.ml new file mode 100644 index 000000000..49ce884c4 --- /dev/null +++ b/Examples/test-suite/ocaml/throw_exception_runme.ml @@ -0,0 +1,27 @@ +(* Throw exception test *) + +open Throw_exception + +let x = new_Foo C_void ;; +let _ = + try + (invoke x) "test_int" C_void + with (Failure "Exception(37): Thrown exception from C++ (int)\n") -> + try + (invoke x) "test_msg" C_void + with (Failure "Exception(0): Dead\n") -> + try + (invoke x) "test_cls" C_void + with (Failure "Exception(0): Thrown exception from C++ (unknown)\n") -> + try + (invoke x) "test_multi" (C_int 1) + with (Failure "Exception(37): Thrown exception from C++ (int)\n") -> + try + (invoke x) "test_multi" (C_int 2) + with (Failure "Exception(0): Dead\n") -> + try + (invoke x) "test_multi" (C_int 3) + with (Failure "Exception(0): Thrown exception from C++ (unknown)\n") -> + exit 0 + +let _ = exit 1 diff --git a/Examples/test-suite/ocaml/typename_runme.ml b/Examples/test-suite/ocaml/typename_runme.ml new file mode 100644 index 000000000..15b5eac25 --- /dev/null +++ b/Examples/test-suite/ocaml/typename_runme.ml @@ -0,0 +1,11 @@ +(* Fun with type names -- stolen from the ruby runme *) + +open Typename + +let f = new_Foo C_void +let b = new_Bar C_void + +let x = _twoFoo f +let _ = match x with C_double f -> () | _ -> raise (Failure "not a float") +let y = _twoBar b +let _ = match y with C_int i -> () | _ -> raise (Failure "not an int") diff --git a/Examples/test-suite/ocaml/unions_runme.ml b/Examples/test-suite/ocaml/unions_runme.ml new file mode 100644 index 000000000..b1ddf3fce --- /dev/null +++ b/Examples/test-suite/ocaml/unions_runme.ml @@ -0,0 +1,27 @@ +(* Test the unions example... *) + +open Unions + +let a = new_SmallStruct C_void +let b = new_BigStruct C_void +let c = new_UnionTest C_void +let d = new_EmbeddedUnionTest C_void + +let _ = (invoke a) "jill_set" (C_short 3) +let _ = (invoke b) "jack_set" (C_char 'a') (* Int conversion *) +let _ = (invoke b) "smallstruct_set" a (* Put a in b *) +let _ = (invoke c) "bs_set" b + +let _ = if get_int ((invoke a) "jill_get" C_void) != 3 then + raise (Failure "jill value is not preserved") +let _ = if get_int ((invoke b) "jack_get" C_void) != (int_of_char 'a') then + raise (Failure "jack value is not preserved") +let _ = if get_int ((invoke ((invoke b) "smallstruct_get" C_void)) + "jill_get" C_void) != 3 then + raise (Failure "jill value is not embedded in bigstruct") +let _ = if get_int ((invoke ((invoke c) "bs_get" C_void)) + "jack_get" C_void) != (int_of_char 'a') then + raise (Failure "union set of bigstruct did not take") +let _ = if get_int ((invoke ((invoke c) "ss_get" C_void)) + "jill_get" C_void) != (int_of_char 'a') then + raise (Failure "corresponding union values are not the same") diff --git a/Examples/test-suite/overload_complicated.i b/Examples/test-suite/overload_complicated.i new file mode 100644 index 000000000..2050e1945 --- /dev/null +++ b/Examples/test-suite/overload_complicated.i @@ -0,0 +1,21 @@ +// A complicated test of overloaded functions +%module overload_complicated + +#ifndef SWIG_NO_OVERLOAD + +%typemap(in, numinputs=0) int l { $1 = 4711; } + +%inline %{ + +double foo(int, int, char *, int) { + return 15; +} + +double foo(int i, int j, double k = 17.4, int l = 18, char m = 'P') { + return i + j + k + l + (int) m; +} + +%} + +#endif + diff --git a/Examples/test-suite/overload_copy.i b/Examples/test-suite/overload_copy.i new file mode 100644 index 000000000..a685f76e2 --- /dev/null +++ b/Examples/test-suite/overload_copy.i @@ -0,0 +1,16 @@ +// Tests copy constructor +%module overload_copy + +#ifndef SWIG_NO_OVERLOAD +%inline %{ + +class Foo { +public: + Foo() { } + Foo(const Foo &) { } +}; + +%} + +#endif + diff --git a/Examples/test-suite/overload_extend.i b/Examples/test-suite/overload_extend.i new file mode 100644 index 000000000..0498bde1b --- /dev/null +++ b/Examples/test-suite/overload_extend.i @@ -0,0 +1,16 @@ +%module overload_extend + +%inline %{ +struct Foo { +}; +%} + +%extend Foo { + int test(int x) { x = 0; return 1; } + int test(char *s) { s = 0; return 2; } + int test(double x, double y) { x = 0; y = 0; return 3; } +}; + + + + diff --git a/Examples/test-suite/overload_extendc.i b/Examples/test-suite/overload_extendc.i new file mode 100644 index 000000000..e03b3f160 --- /dev/null +++ b/Examples/test-suite/overload_extendc.i @@ -0,0 +1,16 @@ +%module overload_extendc + +%inline %{ +typedef struct Foo { +} Foo; +%} + +%extend Foo { + int test(int x) { x = 0; return 1; } + int test(char *s) { s = 0; return 2; } + int test(double x, double y) { x = 0; y = 0; return 3; } +}; + + + + diff --git a/Examples/test-suite/overload_simple.i b/Examples/test-suite/overload_simple.i new file mode 100644 index 000000000..27df10911 --- /dev/null +++ b/Examples/test-suite/overload_simple.i @@ -0,0 +1,92 @@ +// Simple tests of overloaded functions +%module overload_simple + +#ifndef SWIG_NO_OVERLOAD +%immutable Spam::type; + +%inline %{ + +struct Foo { +}; + +struct Bar { +}; + +char *foo(int) { + return (char*) "foo:int"; +} + +char *foo(double) { + return (char*) "foo:double"; +} + +char *foo(char *) { + return (char*) "foo:char *"; +} + +char *foo(Foo *) { + return (char*) "foo:Foo *"; +} +char *foo(Bar *) { + return (char *) "foo:Bar *"; +} +char *foo(void *) { + return (char *) "foo:void *"; +} + +class Spam { +public: + Spam() { type = "none"; } + Spam(int) { type = "int"; } + Spam(double) { type = "double"; } + Spam(char *) { type = "char *"; } + Spam(Foo *) { type = "Foo *"; } + Spam(Bar *) { type = "Bar *"; } + Spam(void *) { type = "void *"; } + const char *type; + +char *foo(int) { + return (char*) "foo:int"; +} +char *foo(double) { + return (char*) "foo:double"; +} +char *foo(char *) { + return (char*) "foo:char *"; +} +char *foo(Foo *) { + return (char*) "foo:Foo *"; +} +char *foo(Bar *) { + return (char *) "foo:Bar *"; +} +char *foo(void *) { + return (char *) "foo:void *"; +} + +static char *bar(int) { + return (char*) "bar:int"; +} +static char *bar(double) { + return (char*) "bar:double"; +} +static char *bar(char *) { + return (char*) "bar:char *"; +} +static char *bar(Foo *) { + return (char*) "bar:Foo *"; +} +static char *bar(Bar *) { + return (char *) "bar:Bar *"; +} +static char *bar(void *) { + return (char *) "bar:void *"; +} +}; +%} + +%include cmalloc.i +%malloc(void); + +#endif + diff --git a/Examples/test-suite/overload_subtype.i b/Examples/test-suite/overload_subtype.i new file mode 100644 index 000000000..3d9645d7b --- /dev/null +++ b/Examples/test-suite/overload_subtype.i @@ -0,0 +1,17 @@ +%module overload_subtype + +%inline %{ + +class Foo {}; +class Bar : public Foo {}; + + +int spam(Foo *f) { + return 1; +} + +int spam(Bar *b) { + return 2; +} + +%} diff --git a/Examples/test-suite/overload_template.i b/Examples/test-suite/overload_template.i new file mode 100644 index 000000000..01a1dd633 --- /dev/null +++ b/Examples/test-suite/overload_template.i @@ -0,0 +1,19 @@ +%module overload_template +%inline %{ + +int foo() { + return 3; +} +template + int foo(int x) { + return x; + } + +template + T max(T a, T b) { return (a > b) ? a : b; } +%} + + +%template(max) max; +%template(max) max; + diff --git a/Examples/test-suite/perl5/.cvsignore b/Examples/test-suite/perl5/.cvsignore new file mode 100644 index 000000000..e32f11c0b --- /dev/null +++ b/Examples/test-suite/perl5/.cvsignore @@ -0,0 +1,4 @@ +*wrap* +*.pm +*.so +*.dll diff --git a/Examples/test-suite/perl5/Makefile b/Examples/test-suite/perl5/Makefile new file mode 100644 index 000000000..d8ee34446 --- /dev/null +++ b/Examples/test-suite/perl5/Makefile @@ -0,0 +1,42 @@ +####################################################################### +# $Header$ +# Makefile for perl5 test-suite +####################################################################### + +LANGUAGE = perl5 +SCRIPTSUFFIX = _runme.pl + +include ../common.mk + +# Overridden variables here +SWIGOPT = -shadow -I$(TOP)/$(TEST_SUITE) + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.pl appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.pl ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH perl $*\_runme.pl;) \ + fi; + +# Clean: remove the generated .pm file +%.clean: + @rm -f $*.pm; + +clean: + $(MAKE) -f $(TOP)/Makefile perl5_clean diff --git a/Examples/test-suite/perl5/README b/Examples/test-suite/perl5/README new file mode 100644 index 000000000..649cca90a --- /dev/null +++ b/Examples/test-suite/perl5/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.pl appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/perl5/import_nomodule_runme.pl b/Examples/test-suite/perl5/import_nomodule_runme.pl new file mode 100644 index 000000000..965d10582 --- /dev/null +++ b/Examples/test-suite/perl5/import_nomodule_runme.pl @@ -0,0 +1,7 @@ +use import_nomodule; + +$f = import_nomodule::create_Foo(); +import_nomodule::test1($f,42); + +$b = new import_nomodule::Bar(); +import_nomodule::test1($b,37); diff --git a/Examples/test-suite/perl5/imports_runme.pl b/Examples/test-suite/perl5/imports_runme.pl new file mode 100644 index 000000000..fd730fedf --- /dev/null +++ b/Examples/test-suite/perl5/imports_runme.pl @@ -0,0 +1,5 @@ +use imports_b; +use imports_a; + +$x = imports_bc::new_B(); +imports_ac::A_hello($x); diff --git a/Examples/test-suite/perl5/overload_copy_runme.pl b/Examples/test-suite/perl5/overload_copy_runme.pl new file mode 100644 index 000000000..06d03f5e6 --- /dev/null +++ b/Examples/test-suite/perl5/overload_copy_runme.pl @@ -0,0 +1,5 @@ + +use overload_copy; + +$f = new overload_copy::Foo(); +$g = new overload_copy::Foo($f); diff --git a/Examples/test-suite/perl5/overload_simple_runme.pl b/Examples/test-suite/perl5/overload_simple_runme.pl new file mode 100644 index 000000000..5e348fba1 --- /dev/null +++ b/Examples/test-suite/perl5/overload_simple_runme.pl @@ -0,0 +1,120 @@ +use overload_simple; + +$f = new overload_simple::Foo(); +$b = new overload_simple::Bar(); +$v = overload_simple::malloc_void(32); + +if (overload_simple::foo(3) != "foo:int") { + die("foo(int)"); +} + +if (overload_simple::foo(3.0) != "foo:double") { + die("foo(double)"); +} + +if (overload_simple::foo("hello") != "foo:char *") { + die("foo(char *)"); +} + +if (overload_simple::foo($f) != "foo:Foo *") { + die("foo(Foo *)"); +} + +if (overload_simple::foo($b) != "foo:Bar *") { + die("foo(Bar *)"); +} + +if (overload_simple::foo($v) != "foo:void *") { + die("foo(void *)"); +} + +$s = new overload_simple::Spam(); + +if ($s->foo(3) != "foo:int") { + die("Spam::foo(int)"); +} + +if ($s->foo(3.0) != "foo:double") { + die("Spam::foo(double)"); +} + +if ($s->foo("hello") != "foo:char *") { + die("Spam::foo(char *)"); +} + +if ($s->foo($f) != "foo:Foo *") { + die("Spam::foo(Foo *)"); +} + +if ($s->foo($b) != "foo:Bar *") { + die("Spam::foo(Bar *)"); +} + +if ($s->foo($v) != "foo:void *") { + die("Spam::foo(void *)"); +} + +if (overload_simple::Spam::bar(3) != "bar:int") { + die("Spam::bar(int)"); +} + +if (overload_simple::Spam::bar(3.0) != "bar:double") { + die("Spam::bar(double)"); +} + +if (overload_simple::Spam::bar("hello") != "bar:char *") { + die("Spam::bar(char *)"); +} + +if (overload_simple::Spam::bar($f) != "bar:Foo *") { + die("Spam::bar(Foo *)"); +} + +if (overload_simple::Spam::bar($b) != "bar:Bar *") { + die("Spam::bar(Bar *)"); +} + +if (overload_simple::Spam::bar($v) != "bar:void *") { + die("Spam::bar(void *)"); +} + +# Test constructors + +$s = new overload_simple::Spam(); +if ($s->{type} != "none") { + die("Spam()"); +} + +$s = new overload_simple::Spam(3); +if ($s->{type} != "int") { + die("Spam(int)"); +} + +$s = new overload_simple::Spam(3.0); +if ($s->{type} != "double") { + die("Spam(double)"); +} + +$s = new overload_simple::Spam("hello"); +if ($s->{type} != "char *") { + die("Spam(char *)"); +} + +$s = new overload_simple::Spam($f); +if ($s->{type} != "Foo *") { + die("Spam(Foo *)"); +} + +$s = new overload_simple::Spam($b); +if ($s->{type} != "Bar *") { + die("Spam(Bar *)"); +} + +$s = new overload_simple::Spam($v); +if ($s->{type} != "void *") { + die("Spam(void *)"); +} + + + + diff --git a/Examples/test-suite/perl5/primitive_ref_runme.pl b/Examples/test-suite/perl5/primitive_ref_runme.pl new file mode 100644 index 000000000..727b3ec6e --- /dev/null +++ b/Examples/test-suite/perl5/primitive_ref_runme.pl @@ -0,0 +1,38 @@ +use primitive_ref; + +if (primitive_ref::ref_int(3) != 3) { + print "ref_int failed!\n"; +} +if (primitive_ref::ref_uint(3) != 3) { + print "ref_uint failed!\n"; +} +if (primitive_ref::ref_short(3) != 3) { + print "ref_short failed!\n"; +} +if (primitive_ref::ref_ushort(3) != 3) { + print "ref_ushort failed!\n"; +} +if (primitive_ref::ref_long(3) != 3) { + print "ref_long failed!\n"; +} +if (primitive_ref::ref_ulong(3) != 3) { + print "ref_ulong failed!\n"; +} +if (primitive_ref::ref_schar(3) != 3) { + print "ref_schar failed!\n"; +} +if (primitive_ref::ref_uchar(3) != 3) { + print "ref_uchar failed!\n"; +} +if (primitive_ref::ref_bool(1) != 1) { + print "ref_bool failed!\n"; +} +if (primitive_ref::ref_float(3.5) != 3.5) { + print "ref_float failed!\n"; +} +if (primitive_ref::ref_double(3.5) != 3.5) { + print "ref_double failed!\n"; +} +if (primitive_ref::ref_char('x') != 'x') { + print "ref_char failed!\n"; +} diff --git a/Examples/test-suite/perl5/unions_runme.pl b/Examples/test-suite/perl5/unions_runme.pl new file mode 100644 index 000000000..fca499f0e --- /dev/null +++ b/Examples/test-suite/perl5/unions_runme.pl @@ -0,0 +1,54 @@ + +# This is the union runtime testcase. It ensures that values within a +# union embedded within a struct can be set and read correctly. + +use unions; + +# Create new instances of SmallStruct and BigStruct for later use +$small = new unions::SmallStruct(); +$small->{jill} = 200; + +$big = new unions::BigStruct(); +$big->{smallstruct} = $small; +$big->{jack} = 300; + +# Use SmallStruct then BigStruct to setup EmbeddedUnionTest. +# Ensure values in EmbeddedUnionTest are set correctly for each. +$eut = new unions::EmbeddedUnionTest(); + +# First check the SmallStruct in EmbeddedUnionTest +$eut->{number} = 1; +$eut->{uni}->{small} = $small; +$Jill1 = $eut->{uni}->{small}->{jill}; +if ($Jill1 != 200) { + print "Runtime test1 failed. eut.uni.small.jill=" , $Jill1, "\n"; + exit 1; +} + +$Num1 = $eut->{number}; +if ($Num1 != 1) { + print "Runtime test2 failed. eut.number=" , $Num1, "\n"; + exit 1; +} + +# Secondly check the BigStruct in EmbeddedUnionTest +$eut->{number} = 2; +$eut->{uni}->{big} = $big; +$Jack1 = $eut->{uni}->{big}->{jack}; +if ($Jack1 != 300) { + print "Runtime test3 failed. eut.uni.big.jack=" , $Jack1, "\n"; + exit 1; +} + +$Jill2 = $eut->{uni}->{big}->{smallstruct}->{jill}; +if ($Jill2 != 200) { + print "Runtime test4 failed. eut.uni.big.smallstruct.jill=" , $Jill2, "\n"; + exit 1; +} + +$Num2 = $eut->{number}; +if ($Num2 != 2) { + print "Runtime test5 failed. eut.number=" , $Num2, "\n"; + exit 1; +} + diff --git a/Examples/test-suite/php4/Makefile b/Examples/test-suite/php4/Makefile new file mode 100644 index 000000000..e286f9d5e --- /dev/null +++ b/Examples/test-suite/php4/Makefile @@ -0,0 +1,67 @@ +####################################################################### +# Makefile for php4 test-suite +####################################################################### + +LANGUAGE = php4 +SCRIPTSUFFIX = _runme.php4 + +include ../common.mk + +# Overridden variables here +SWIGOPT = -I$(TOP)/../Lib -I$(TOP)/$(TEST_SUITE) +TARGETPREFIX = php_ + +makecpptests: + @bash -ec 'for test in $(CPP_TEST_CASES) ; do make clean && make $${test}.cpptest; done' + +maketests: makecpptests makectests + +makectests: + @bash -ec 'for test in $(C_TEST_CASES) ; do make clean && make $${test}.cpptest; done' + +runcpptests: + @bash -ec 'for test in $(CPP_TEST_CASES) ; do if [ -f $${test}_runme.php4 ] ; then make clean && make $${test}.cpptest; fi ; done' + +runctests: + @bash -ec 'for test in $(C_TEST_CASES) ; do if [ -f $${test}_runme.php4 ] ; then make clean && make $${test}.cpptest; fi; done' + +runtests: runcpptests runctests + +# write out tests without a _runme.php4 +missingcpptests: + @bash -ec 'for test in $(CPP_TEST_CASES) ; do test -f $${test}_runme.php4 || echo $${test}; done' + +missingctests: + @bash -ec 'for test in $(C_TEST_CASES) ; do test -f $${test}_runme.php4 || echo $${test}; done' + +missingtests: missingcpptests missingctests + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.php4 appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.php4 ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH php -q -d extension_dir=. $*\_runme.php4;) \ + fi; + +# Clean: remove the generated .php file +%.clean: + @rm -f $*.php; + +clean: + $(MAKE) -f $(TOP)/Makefile php4_clean diff --git a/Examples/test-suite/php4/abstract_inherit_ok_runme.php4 b/Examples/test-suite/php4/abstract_inherit_ok_runme.php4 new file mode 100644 index 000000000..b03755a00 --- /dev/null +++ b/Examples/test-suite/php4/abstract_inherit_ok_runme.php4 @@ -0,0 +1,13 @@ +blah(),"spam object method"); +check::equal(0,Spam::blah($spam),"spam class method"); + +check::done(); +?> diff --git a/Examples/test-suite/php4/abstract_inherit_runme.php4 b/Examples/test-suite/php4/abstract_inherit_runme.php4 new file mode 100644 index 000000000..358d2741f --- /dev/null +++ b/Examples/test-suite/php4/abstract_inherit_runme.php4 @@ -0,0 +1,14 @@ +blah(),"spam object method"); +//check::equal(0,Spam::blah($spam),"spam class method"); + +check::done(); +?> diff --git a/Examples/test-suite/php4/add_link_runme.php4 b/Examples/test-suite/php4/add_link_runme.php4 new file mode 100644 index 000000000..aca3267b6 --- /dev/null +++ b/Examples/test-suite/php4/add_link_runme.php4 @@ -0,0 +1,23 @@ +blah(); +check::is_a($foo_blah,foo); + +//fails, can't be called as a class method, should allow and make it nil? +//$class_foo_blah=foo::blah(); +//check::is_a($class_foo_blah,foo); + +check::done(); +?> diff --git a/Examples/test-suite/php4/anonymous_arg_runme.php4 b/Examples/test-suite/php4/anonymous_arg_runme.php4 new file mode 100644 index 000000000..6d9d9670b --- /dev/null +++ b/Examples/test-suite/php4/anonymous_arg_runme.php4 @@ -0,0 +1,13 @@ + diff --git a/Examples/test-suite/php4/argout_runme.php4 b/Examples/test-suite/php4/argout_runme.php4 new file mode 100644 index 000000000..adb9dfbc2 --- /dev/null +++ b/Examples/test-suite/php4/argout_runme.php4 @@ -0,0 +1,37 @@ + diff --git a/Examples/test-suite/php4/arrayptr_runme.php4 b/Examples/test-suite/php4/arrayptr_runme.php4 new file mode 100644 index 000000000..c057a6772 --- /dev/null +++ b/Examples/test-suite/php4/arrayptr_runme.php4 @@ -0,0 +1,15 @@ + diff --git a/Examples/test-suite/php4/arrays_global_runme.php4 b/Examples/test-suite/php4/arrays_global_runme.php4 new file mode 100644 index 000000000..07d3be6ef --- /dev/null +++ b/Examples/test-suite/php4/arrays_global_runme.php4 @@ -0,0 +1,16 @@ + diff --git a/Examples/test-suite/php4/arrays_global_twodim_runme.php4 b/Examples/test-suite/php4/arrays_global_twodim_runme.php4 new file mode 100644 index 000000000..799dfdc2d --- /dev/null +++ b/Examples/test-suite/php4/arrays_global_twodim_runme.php4 @@ -0,0 +1,25 @@ + diff --git a/Examples/test-suite/php4/arrays_runme.php4 b/Examples/test-suite/php4/arrays_runme.php4 new file mode 100644 index 000000000..ee240e58f --- /dev/null +++ b/Examples/test-suite/php4/arrays_runme.php4 @@ -0,0 +1,22 @@ +array_c="abc"; +check::equal($as->array_c,"ab",'$as->array_c=="ab"'); + +check::done(); +?> diff --git a/Examples/test-suite/php4/arrays_scope_runme.php4 b/Examples/test-suite/php4/arrays_scope_runme.php4 new file mode 100644 index 000000000..7d2172c72 --- /dev/null +++ b/Examples/test-suite/php4/arrays_scope_runme.php4 @@ -0,0 +1,17 @@ + diff --git a/Examples/test-suite/php4/bool_default_runme.php4 b/Examples/test-suite/php4/bool_default_runme.php4 new file mode 100644 index 000000000..42eadea4f --- /dev/null +++ b/Examples/test-suite/php4/bool_default_runme.php4 @@ -0,0 +1,20 @@ + diff --git a/Examples/test-suite/php4/casts_runme.php4 b/Examples/test-suite/php4/casts_runme.php4 new file mode 100644 index 000000000..bcda296af --- /dev/null +++ b/Examples/test-suite/php4/casts_runme.php4 @@ -0,0 +1,19 @@ +hello(); + +check::done(); +?> diff --git a/Examples/test-suite/php4/class_ignore_runme.php4 b/Examples/test-suite/php4/class_ignore_runme.php4 new file mode 100644 index 000000000..2a202fe1b --- /dev/null +++ b/Examples/test-suite/php4/class_ignore_runme.php4 @@ -0,0 +1,19 @@ + diff --git a/Examples/test-suite/php4/conversion_namespace_runme.php4 b/Examples/test-suite/php4/conversion_namespace_runme.php4 new file mode 100644 index 000000000..50f1539ec --- /dev/null +++ b/Examples/test-suite/php4/conversion_namespace_runme.php4 @@ -0,0 +1,14 @@ +toFoo(); +check::classname("foo",$foo); + +check::done(); +?> diff --git a/Examples/test-suite/php4/conversion_ns_template_runme.php4 b/Examples/test-suite/php4/conversion_ns_template_runme.php4 new file mode 100644 index 000000000..3493a3521 --- /dev/null +++ b/Examples/test-suite/php4/conversion_ns_template_runme.php4 @@ -0,0 +1,10 @@ + diff --git a/Examples/test-suite/php4/conversion_runme.php4 b/Examples/test-suite/php4/conversion_runme.php4 new file mode 100644 index 000000000..ef2a11c9d --- /dev/null +++ b/Examples/test-suite/php4/conversion_runme.php4 @@ -0,0 +1,14 @@ +toFoo(); +check::classname("foo",$foo); + +check::done(); +?> diff --git a/Examples/test-suite/php4/cpp_static_runme.php4 b/Examples/test-suite/php4/cpp_static_runme.php4 new file mode 100644 index 000000000..da42efd91 --- /dev/null +++ b/Examples/test-suite/php4/cpp_static_runme.php4 @@ -0,0 +1,15 @@ + diff --git a/Examples/test-suite/php4/enum_scope_runme.php4 b/Examples/test-suite/php4/enum_scope_runme.php4 new file mode 100644 index 000000000..eaa0c0179 --- /dev/null +++ b/Examples/test-suite/php4/enum_scope_runme.php4 @@ -0,0 +1,17 @@ + diff --git a/Examples/test-suite/php4/enum_scope_template_runme.php4 b/Examples/test-suite/php4/enum_scope_template_runme.php4 new file mode 100644 index 000000000..5f5d53540 --- /dev/null +++ b/Examples/test-suite/php4/enum_scope_template_runme.php4 @@ -0,0 +1,17 @@ + diff --git a/Examples/test-suite/php4/evil_diamond_ns_runme.php4 b/Examples/test-suite/php4/evil_diamond_ns_runme.php4 new file mode 100644 index 000000000..ba24e9b00 --- /dev/null +++ b/Examples/test-suite/php4/evil_diamond_ns_runme.php4 @@ -0,0 +1,19 @@ + diff --git a/Examples/test-suite/php4/evil_diamond_prop_runme.php4 b/Examples/test-suite/php4/evil_diamond_prop_runme.php4 new file mode 100644 index 000000000..971f98c10 --- /dev/null +++ b/Examples/test-suite/php4/evil_diamond_prop_runme.php4 @@ -0,0 +1,38 @@ +_foo,"1==foo->_foo"); + +$bar=new bar(); +check::is_a($bar,"bar"); +check::equal(1,$bar->_foo,"1==bar->_foo"); +check::equal(2,$bar->_bar,"2==bar->_bar"); + +$baz=new baz(); +check::is_a($baz,"baz"); +check::equal(1,$baz->_foo,"1==baz->_foo"); +check::equal(3,$baz->_baz,"3==baz->_baz"); + +$spam=new spam(); +check::is_a($spam,"spam"); +check::equal(1,$spam->_foo,"1==spam->_foo"); +check::equal(2,$spam->_bar,"2==spam->_bar"); +check::equal(3,$spam->_baz,"3==spam->_baz"); +check::equal(4,$spam->_spam,"4==spam->_spam"); + +check::done(); +?> diff --git a/Examples/test-suite/php4/evil_diamond_runme.php4 b/Examples/test-suite/php4/evil_diamond_runme.php4 new file mode 100644 index 000000000..45da10115 --- /dev/null +++ b/Examples/test-suite/php4/evil_diamond_runme.php4 @@ -0,0 +1,17 @@ + diff --git a/Examples/test-suite/php4/extend_template_ns_runme.php4 b/Examples/test-suite/php4/extend_template_ns_runme.php4 new file mode 100644 index 000000000..e15170e7e --- /dev/null +++ b/Examples/test-suite/php4/extend_template_ns_runme.php4 @@ -0,0 +1,13 @@ +test1(2),"test1"); +check::equal(3,$foo->test2(3),"test2"); + +check::done(); +?> diff --git a/Examples/test-suite/php4/extend_template_runme.php4 b/Examples/test-suite/php4/extend_template_runme.php4 new file mode 100644 index 000000000..93944f616 --- /dev/null +++ b/Examples/test-suite/php4/extend_template_runme.php4 @@ -0,0 +1,13 @@ +test1(2),"test1"); +check::equal(3,$foo->test2(3),"test2"); + +check::done(); +?> diff --git a/Examples/test-suite/php4/grouping_runme.php4 b/Examples/test-suite/php4/grouping_runme.php4 new file mode 100644 index 000000000..832b3df0e --- /dev/null +++ b/Examples/test-suite/php4/grouping_runme.php4 @@ -0,0 +1,24 @@ + diff --git a/Examples/test-suite/php4/ignore_parameter_runme.php4 b/Examples/test-suite/php4/ignore_parameter_runme.php4 new file mode 100644 index 000000000..8a2bf899e --- /dev/null +++ b/Examples/test-suite/php4/ignore_parameter_runme.php4 @@ -0,0 +1,39 @@ +daimler(2,3.4),"hello",'$sc->daimler(2,3.4)=="hello"'); +check::equal($sc->astonmartin("eek",3.4),101,'$sc->mastonmartin("eek",3.4)==101'); +check::equal($sc->bugatti("eek",2),8.8,'$sc->bugatti("eek",2)==8.8'); +check::equal($sc->lamborghini(),101,'$sc->lamborghini(2)==101'); + +$mc=new minicooper(2,3.4); +check::classname("minicooper",$mc); + +$mm=new morrisminor("eek",3.4); +check::classname("morrisminor",$mm); + +$fa=new fordanglia("eek",2); +check::classname("fordanglia",$fa); + +$aa=new austinallegro(); +check::classname("austinallegro",$aa); + +check::done(); +?> diff --git a/Examples/test-suite/php4/lib_carrays_runme.php4 b/Examples/test-suite/php4/lib_carrays_runme.php4 new file mode 100644 index 000000000..134dbc251 --- /dev/null +++ b/Examples/test-suite/php4/lib_carrays_runme.php4 @@ -0,0 +1,15 @@ + diff --git a/Examples/test-suite/php4/rename_scope_runme.php4 b/Examples/test-suite/php4/rename_scope_runme.php4 new file mode 100644 index 000000000..0be22ee96 --- /dev/null +++ b/Examples/test-suite/php4/rename_scope_runme.php4 @@ -0,0 +1,17 @@ + diff --git a/Examples/test-suite/php4/skel.php4 b/Examples/test-suite/php4/skel.php4 new file mode 100644 index 000000000..d6f33758d --- /dev/null +++ b/Examples/test-suite/php4/skel.php4 @@ -0,0 +1,15 @@ + diff --git a/Examples/test-suite/php4/smart_pointer_rename_runme.php4 b/Examples/test-suite/php4/smart_pointer_rename_runme.php4 new file mode 100644 index 000000000..a8b600ab2 --- /dev/null +++ b/Examples/test-suite/php4/smart_pointer_rename_runme.php4 @@ -0,0 +1,28 @@ +ftest1(1),"foo->ftest1"); +check::equal(2,$foo->ftest2(1,2),"foo->ftest2"); + +# check bar's ftest1, ftest2, ftest +check::equal(1,$bar->ftest1(1),"bar->ftest1"); +check::equal(2,$bar->ftest2(1,2),"bar->ftest2"); +check::equal(3,$bar->test(),"bar->test"); + +# check deref returns foo +check::classname("foo",$bar->__deref__()); + +check::done(); +?> diff --git a/Examples/test-suite/php4/sym_runme.php4 b/Examples/test-suite/php4/sym_runme.php4 new file mode 100644 index 000000000..ce89ea4b2 --- /dev/null +++ b/Examples/test-suite/php4/sym_runme.php4 @@ -0,0 +1,23 @@ +hulahoops(),"flim-jam","flim()->hulahoops==flim-jam"); +check::equal($flim->jar(),"flim-jar","flim()->jar==flim-jar"); +check::equal($flam->jam(),"flam-jam","flam()->jam==flam-jam"); +check::equal($flam->jar(),"flam-jar","flam()->jar==flam-jar"); + +check::done(); +?> diff --git a/Examples/test-suite/php4/template_arg_typename_runme.php4 b/Examples/test-suite/php4/template_arg_typename_runme.php4 new file mode 100644 index 000000000..eb83badb6 --- /dev/null +++ b/Examples/test-suite/php4/template_arg_typename_runme.php4 @@ -0,0 +1,19 @@ + diff --git a/Examples/test-suite/php4/template_construct_runme.php4 b/Examples/test-suite/php4/template_construct_runme.php4 new file mode 100644 index 000000000..95316832d --- /dev/null +++ b/Examples/test-suite/php4/template_construct_runme.php4 @@ -0,0 +1,11 @@ + diff --git a/Examples/test-suite/php4/tests.php4 b/Examples/test-suite/php4/tests.php4 new file mode 100644 index 000000000..13c732042 --- /dev/null +++ b/Examples/test-suite/php4/tests.php4 @@ -0,0 +1,217 @@ + diff --git a/Examples/test-suite/php4/typedef_reference_runme.php4 b/Examples/test-suite/php4/typedef_reference_runme.php4 new file mode 100644 index 000000000..2c64efce6 --- /dev/null +++ b/Examples/test-suite/php4/typedef_reference_runme.php4 @@ -0,0 +1,13 @@ + diff --git a/Examples/test-suite/php4/typemap_ns_using_runme.php4 b/Examples/test-suite/php4/typemap_ns_using_runme.php4 new file mode 100644 index 000000000..44403d138 --- /dev/null +++ b/Examples/test-suite/php4/typemap_ns_using_runme.php4 @@ -0,0 +1,9 @@ + diff --git a/Examples/test-suite/php4/using1_runme.php4 b/Examples/test-suite/php4/using1_runme.php4 new file mode 100644 index 000000000..ed7e32b06 --- /dev/null +++ b/Examples/test-suite/php4/using1_runme.php4 @@ -0,0 +1,9 @@ + diff --git a/Examples/test-suite/php4/using2_runme.php4 b/Examples/test-suite/php4/using2_runme.php4 new file mode 100644 index 000000000..e57f0ce9a --- /dev/null +++ b/Examples/test-suite/php4/using2_runme.php4 @@ -0,0 +1,9 @@ + diff --git a/Examples/test-suite/php4/valuewrapper_base_runme.php4 b/Examples/test-suite/php4/valuewrapper_base_runme.php4 new file mode 100644 index 000000000..3cbef0dbb --- /dev/null +++ b/Examples/test-suite/php4/valuewrapper_base_runme.php4 @@ -0,0 +1,14 @@ + diff --git a/Examples/test-suite/pike/Makefile b/Examples/test-suite/pike/Makefile new file mode 100644 index 000000000..477230808 --- /dev/null +++ b/Examples/test-suite/pike/Makefile @@ -0,0 +1,44 @@ +####################################################################### +# $Header$ +# Makefile for Pike test-suite +####################################################################### + +LANGUAGE = pike +SCRIPTSUFFIX = _runme.pike + +include ../common.mk + +# Overridden variables here +TARGETSUFFIX = +SWIGOPT = -I$(TOP)/$(TEST_SUITE) + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.pike appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.pike ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH pike $*\_runme.pike;) \ + fi; + +# Clean: remove the generated .pike file +%.clean: + @rm -f $*.pike; + +clean: + $(MAKE) -f $(TOP)/Makefile pike_clean + diff --git a/Examples/test-suite/pointer_in_out.i b/Examples/test-suite/pointer_in_out.i new file mode 100644 index 000000000..f4b1ed440 --- /dev/null +++ b/Examples/test-suite/pointer_in_out.i @@ -0,0 +1,35 @@ +/* This file tests the pointer-in-out typemap library, + currently only available for Guile. */ + +%module pointer_in_out + +%include "pointer-in-out.i" + +TYPEMAP_POINTER_INPUT_OUTPUT(int *, int-pointer); + +int consume_int_pointer(int **INPUT); +void produce_int_pointer(int **OUTPUT, int value1, int value2); +void frobnicate_int_pointer(int **INOUT); + +%{ + +int consume_int_pointer(int **INPUT) +{ + return **INPUT; +} + +void produce_int_pointer(int **OUTPUT, int value1, int value2) +{ + int *foo = malloc(2 * sizeof(int)); + foo[0] = value1; + foo[1] = value2; + *OUTPUT = foo; +} + +void frobnicate_int_pointer(int **INOUT) +{ + /* advance the pointer */ + (*INOUT)++; +} + +%} diff --git a/Examples/test-suite/pointer_reference.i b/Examples/test-suite/pointer_reference.i new file mode 100644 index 000000000..5d233e5a7 --- /dev/null +++ b/Examples/test-suite/pointer_reference.i @@ -0,0 +1,17 @@ +/* This interface file tests whether SWIG handles pointer-reference + (*&) arguments. + + SWIG 1.3a5 signals a syntax error. +*/ + +%module pointer_reference + +#ifdef SWIGGUILE +/* A silly testing typemap for feeding a doubly indirect integer */ +%typemap(in) int *&XYZZY (int temp1, int *temp2) + "temp1 = gh_scm2int($input); temp2 = &temp1; $1 = &temp2;"; +#endif + +%inline %{ +void foo(int *&XYZZY) {} +%} diff --git a/Examples/test-suite/preproc_1.i b/Examples/test-suite/preproc_1.i new file mode 100644 index 000000000..134cae666 --- /dev/null +++ b/Examples/test-suite/preproc_1.i @@ -0,0 +1,10 @@ +/* This interface file tests whether SWIG's extended C + preprocessor is working right. + + In this example, SWIG 1.3.6 chokes on "//" in a #define with a + syntax error. +*/ + +%module preproc_1 + +#define SLASHSLASH "//" diff --git a/Examples/test-suite/preproc_2.i b/Examples/test-suite/preproc_2.i new file mode 100644 index 000000000..ca5e4c1cb --- /dev/null +++ b/Examples/test-suite/preproc_2.i @@ -0,0 +1,22 @@ +/* This SWIG -*- c -*- interface is to test for some strange + preprocessor bug. + + I get syntax errors unless I remove the apostrophe in the comment + or the sharp-sign substitution. (The apostrophe seems to disable + sharp-sign substitution.) +*/ + +%module preproc_2; + +%define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(SCM_TYPE) + + /* Don't check for NULL pointers (override checks). */ + + %typemap(argout, doc="($arg >)") + int *VECTORLENOUTPUT + { + } + +%enddef + +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(boolean) diff --git a/Examples/test-suite/preproc_3.i b/Examples/test-suite/preproc_3.i new file mode 100644 index 000000000..f6135f3a2 --- /dev/null +++ b/Examples/test-suite/preproc_3.i @@ -0,0 +1,6 @@ +%module preproc_3 + +#define Sum( A, B, \ + C) \ + A + B + C + diff --git a/Examples/test-suite/primitive_ref.i b/Examples/test-suite/primitive_ref.i new file mode 100644 index 000000000..f6a7070c8 --- /dev/null +++ b/Examples/test-suite/primitive_ref.i @@ -0,0 +1,26 @@ +// Tests passing of references to primitive datatypes +%module primitive_ref + +%define ref(type,name) +%inline %{ +const type &ref_##name(const type &x) { + static type y = x; + return y; +} +%} +%enddef + +ref(int,int); +ref(unsigned int, uint); +ref(short, short); +ref(unsigned short, ushort); +ref(long,long); +ref(unsigned long, ulong); +ref(signed char, schar); +ref(unsigned char, uchar); +ref(char, char); +ref(float, float); +ref(double, double); +ref(bool, bool); +ref(long long, longlong); +ref(unsigned long long, ulonglong); diff --git a/Examples/test-suite/private_assign.i b/Examples/test-suite/private_assign.i new file mode 100644 index 000000000..6f95df0fb --- /dev/null +++ b/Examples/test-suite/private_assign.i @@ -0,0 +1,21 @@ +// A class with a private assignment operator. +// This is rare, but sometimes used with singletons and +// objects that have complicated state. + +%module private_assign + +%inline %{ + class Foo { + private: + Foo &operator=(const Foo &f) { + return *this; + } + public: + void bar() { } + }; + + Foo blah() { + return Foo(); + }; +%} + diff --git a/Examples/test-suite/pure_virtual.i b/Examples/test-suite/pure_virtual.i new file mode 100644 index 000000000..1dd148041 --- /dev/null +++ b/Examples/test-suite/pure_virtual.i @@ -0,0 +1,74 @@ +/* SF Bug #445219, submitted by Krzysztof Kozminski + . + + Swig 1.3.6 gets confused by pure virtual destructors, + as in this file: +*/ + +%module pure_virtual + +%warnfilter(802) E; /* Ruby, multiple inheritance */ + +%nodefault C; +%nodefault E; + +%inline %{ + +class A { + public: + A() { }; + virtual ~A() = 0; + virtual void something() = 0; + virtual void method() = 0; +}; + +class B : public A { +public: + B() {}; + virtual ~B() { }; + virtual void something() { }; + virtual void method() { }; +}; + +/* class C is abstract because it doesn't define all methods in A */ +class C : public A { + public: + virtual ~C() { }; + virtual void method() { }; +} +; + +/* class D is not abstract, it defines everything */ +class D : public C { + public: + virtual ~D() { }; + virtual void something() { }; +} +; + +/* Another abstract class */ +class AA { + public: + virtual void method2() = 0; +}; + +/* Multiple inheritance between two abstract classes */ +#ifndef SWIGJAVA +class E : public C, public AA { +public: + virtual void something() { }; +}; + +/* Fill in method from AA. This class should be constructable */ +class F : public E { + public: + virtual void method2() { } +}; +#endif + +%} + +%{ +A::~A() {} +%} + diff --git a/Examples/test-suite/python/.cvsignore b/Examples/test-suite/python/.cvsignore new file mode 100644 index 000000000..0e238873e --- /dev/null +++ b/Examples/test-suite/python/.cvsignore @@ -0,0 +1,5 @@ +*wrap* +*.py +*.pyc +*.so +*.dll diff --git a/Examples/test-suite/python/Makefile b/Examples/test-suite/python/Makefile new file mode 100644 index 000000000..6c563548c --- /dev/null +++ b/Examples/test-suite/python/Makefile @@ -0,0 +1,44 @@ +####################################################################### +# $Header$ +# Makefile for python test-suite +####################################################################### + +LANGUAGE = python +SCRIPTSUFFIX = _runme.py + +include ../common.mk + +# Overridden variables here +TARGETSUFFIX = +SWIGOPT = -I$(TOP)/$(TEST_SUITE) + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.py appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.py ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH python $*\_runme.py;) \ + fi; + +# Clean: remove the generated .py file +%.clean: + @rm -f $*.py; + +clean: + $(MAKE) -f $(TOP)/Makefile python_clean + diff --git a/Examples/test-suite/python/README b/Examples/test-suite/python/README new file mode 100644 index 000000000..b86ec5289 --- /dev/null +++ b/Examples/test-suite/python/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.py appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/python/abstract_typedef_runme.py b/Examples/test-suite/python/abstract_typedef_runme.py new file mode 100644 index 000000000..15d70aa42 --- /dev/null +++ b/Examples/test-suite/python/abstract_typedef_runme.py @@ -0,0 +1,11 @@ +from abstract_typedef import * +e = Engine() + +a = A() + + +if a.write(e) != 1: + raise RuntimeError + + + diff --git a/Examples/test-suite/python/class_ignore_runme.py b/Examples/test-suite/python/class_ignore_runme.py new file mode 100644 index 000000000..782fc07e1 --- /dev/null +++ b/Examples/test-suite/python/class_ignore_runme.py @@ -0,0 +1,6 @@ +import class_ignore + +a = class_ignore.Bar() + +if class_ignore.do_blah(a) != "Bar::blah": + raise RuntimeError diff --git a/Examples/test-suite/python/constover_runme.py b/Examples/test-suite/python/constover_runme.py new file mode 100644 index 000000000..5c5419706 --- /dev/null +++ b/Examples/test-suite/python/constover_runme.py @@ -0,0 +1,38 @@ +import constover +import sys +error = 0 + +p = constover.test("test") +if p != "test": + print "test failed!" + error = 1 + +p = constover.test_pconst("test") +if p != "test_pconst": + print "test_pconst failed!" + error = 1 + +f = constover.Foo() +p = f.test("test") +if p != "test": + print "member-test failed!" + error = 1 + +p = f.test_pconst("test") +if p != "test_pconst": + print "member-test_pconst failed!" + error = 1 + +p = f.test_constm("test") +if p != "test_constmethod": + print "member-test_constm failed!" + error = 1 + +p = f.test_pconstm("test") +if p != "test_pconstmethod": + print "member-test_pconstm failed!" + error = 1 + +sys.exit(error) + + diff --git a/Examples/test-suite/python/cpp_namespace_runme.py b/Examples/test-suite/python/cpp_namespace_runme.py new file mode 100644 index 000000000..3108b4f47 --- /dev/null +++ b/Examples/test-suite/python/cpp_namespace_runme.py @@ -0,0 +1,45 @@ +# Note: This example assumes that namespaces are flattened +import cpp_namespace + +n = cpp_namespace.fact(4) +if n != 24: + raise "Bad return value!" + +if cpp_namespace.cvar.Foo != 42: + raise "Bad variable value!" + +t = cpp_namespace.Test() +if t.method() != "Test::method": + raise "Bad method return value!" + +if cpp_namespace.do_method(t) != "Test::method": + raise "Bad return value!" + +if cpp_namespace.do_method2(t) != "Test::method": + raise "Bad return value!" + +cpp_namespace.weird("hello", 4) + +del t + +t2 = cpp_namespace.Test2() +t3 = cpp_namespace.Test3() +t4 = cpp_namespace.Test4() +t5 = cpp_namespace.Test5() + +if cpp_namespace.foo3(42) != 42: + raise "Bad return value!" + +if cpp_namespace.do_method3(t2,40) != "Test2::method": + raise "Bad return value!" + +if cpp_namespace.do_method3(t3,40) != "Test3::method": + raise "Bad return value!" + +if cpp_namespace.do_method3(t4,40) != "Test4::method": + raise "Bad return value!" + +if cpp_namespace.do_method3(t5,40) != "Test5::method": + raise "Bad return value!" + + diff --git a/Examples/test-suite/python/default_constructor_runme.py b/Examples/test-suite/python/default_constructor_runme.py new file mode 100644 index 000000000..d7d811d4c --- /dev/null +++ b/Examples/test-suite/python/default_constructor_runme.py @@ -0,0 +1,96 @@ +import _default_constructor + +dc = _default_constructor + +a = dc.new_A +del_a = dc.delete_A + +aa = dc.new_AA +del_aa = dc.delete_AA + +b = dc.new_B +del_b = dc.delete_B + +try: + bb = dc.new_BB; + print "Whoa. new_BB created." +except AttributeError: + pass + +del_bb = dc.delete_BB + +try: + c = dc.new_C + print "Whoa. new_C created." +except AttributeError: + pass + +del_c = dc.delete_C + +cc = dc.new_CC +del_cc = dc.delete_CC + +try: + d = dc.new_D; + print "Whoa. new_D created" +except AttributeError: + pass + +del_d = dc.delete_D + +try: + dd = dc.new_DD + print "Whoa. new_DD created" +except AttributeError: + pass + +dd = dc.delete_DD + +try: + ad = dc.new_AD + print "Whoa. new_AD created" +except AttributeError: + pass + +del_ad = dc.delete_AD + +e = dc.new_E +del_e = dc.delete_E + +ee = dc.new_EE +del_ee = dc.delete_EE + +try: + eb = dc.new_EB + print "Whoa. new_EB created" +except AttributeError: + pass + +del_eb = dc.delete_EB + +f = dc.new_F + +try: + del_f = dc.delete_F + print "Whoa. delete_F created" +except AttributeError: + pass + +ff = dc.new_FFF +try: + del_ff = dc.delete_FFF + print "Whoa. delete_FFF created" +except AttributeError: + pass + +g = dc.new_G + +try: + del_g = dc.delete_G + print "Whoa. delete_G created" +except AttributeError: + pass + +gg = dc.new_GG +del_gg = dc.delete_GG + diff --git a/Examples/test-suite/python/dynamic_cast_runme.py b/Examples/test-suite/python/dynamic_cast_runme.py new file mode 100644 index 000000000..68b06db50 --- /dev/null +++ b/Examples/test-suite/python/dynamic_cast_runme.py @@ -0,0 +1,12 @@ +import dynamic_cast + +f = dynamic_cast.Foo() +b = dynamic_cast.Bar() + +x = f.blah() +y = b.blah() + +a = dynamic_cast.do_test(y) +if a != "Bar::test": + print "Failed!!" + diff --git a/Examples/test-suite/python/enum_runme.py b/Examples/test-suite/python/enum_runme.py new file mode 100644 index 000000000..6581167de --- /dev/null +++ b/Examples/test-suite/python/enum_runme.py @@ -0,0 +1,7 @@ + +import _enum + +_enum.bar2(1) +_enum.bar3(1) +_enum.bar1(1) + diff --git a/Examples/test-suite/python/extend_template_ns_runme.py b/Examples/test-suite/python/extend_template_ns_runme.py new file mode 100644 index 000000000..5c5feac66 --- /dev/null +++ b/Examples/test-suite/python/extend_template_ns_runme.py @@ -0,0 +1,7 @@ +from extend_template_ns import * +f = Foo_One() +if f.test1(37) != 37: + raise RuntimeError + +if f.test2(42) != 42: + raise RuntimeError diff --git a/Examples/test-suite/python/extend_template_runme.py b/Examples/test-suite/python/extend_template_runme.py new file mode 100644 index 000000000..be6e2fc98 --- /dev/null +++ b/Examples/test-suite/python/extend_template_runme.py @@ -0,0 +1,8 @@ +import extend_template + +f = extend_template.Foo_0() +if f.test1(37) != 37: + raise RuntimeError + +if f.test2(42) != 42: + raise RuntimeError diff --git a/Examples/test-suite/python/grouping_runme.py b/Examples/test-suite/python/grouping_runme.py new file mode 100644 index 000000000..13f8c8c92 --- /dev/null +++ b/Examples/test-suite/python/grouping_runme.py @@ -0,0 +1,13 @@ +import grouping + +x = grouping.test1(42) +if x != 42: + raise RuntimeError + +grouping.test2(42) + +x = grouping.do_unary(37, grouping.NEGATE) +if x != -37: + raise RuntimeError + +grouping.cvar.test3 = 42 diff --git a/Examples/test-suite/python/import_nomodule_runme.py b/Examples/test-suite/python/import_nomodule_runme.py new file mode 100644 index 000000000..41fc9d5ba --- /dev/null +++ b/Examples/test-suite/python/import_nomodule_runme.py @@ -0,0 +1,7 @@ +from import_nomodule import * + +f = create_Foo() +test1(f,42) + +b = Bar() +test1(b,37) diff --git a/Examples/test-suite/python/imports_runme.py b/Examples/test-suite/python/imports_runme.py new file mode 100644 index 000000000..db2d32d3a --- /dev/null +++ b/Examples/test-suite/python/imports_runme.py @@ -0,0 +1,9 @@ +# This is the import runtime testcase. + +import _imports_a +import _imports_b +import sys + +x = _imports_b.new_B() +_imports_a.A_hello(x) + diff --git a/Examples/test-suite/python/inherit_missing_runme.py b/Examples/test-suite/python/inherit_missing_runme.py new file mode 100644 index 000000000..60e606401 --- /dev/null +++ b/Examples/test-suite/python/inherit_missing_runme.py @@ -0,0 +1,17 @@ +import inherit_missing + +a = inherit_missing.new_Foo() +b = inherit_missing.Bar() +c = inherit_missing.Spam() + +x = inherit_missing.do_blah(a) +if x != "Foo::blah": + print "Whoa! Bad return", x + +x = inherit_missing.do_blah(b) +if x != "Bar::blah": + print "Whoa! Bad return", x + +x = inherit_missing.do_blah(c) +if x != "Spam::blah": + print "Whoa! Bad return", x diff --git a/Examples/test-suite/python/lib_std_vector_runme.py b/Examples/test-suite/python/lib_std_vector_runme.py new file mode 100644 index 000000000..1b196f550 --- /dev/null +++ b/Examples/test-suite/python/lib_std_vector_runme.py @@ -0,0 +1,17 @@ +from lib_std_vector import * + +iv = IntVector(4) +for i in range(0,4): + iv[i] = i + +x = average(iv) +y = average([1,2,3,4]) + +a = half([10,10.5,11,11.5]) + +dv = DoubleVector(10) +for i in range(0,10): + dv[i] = i/2.0 + +halve_in_place(dv) + diff --git a/Examples/test-suite/python/minherit_runme.py b/Examples/test-suite/python/minherit_runme.py new file mode 100644 index 000000000..d7ad0b36b --- /dev/null +++ b/Examples/test-suite/python/minherit_runme.py @@ -0,0 +1,71 @@ + +import minherit + +a = minherit.Foo() +b = minherit.Bar() +c = minherit.FooBar() +d = minherit.Spam() + +if a.xget() != 1: + raise RuntimeError, "Bad attribute value" + +if b.yget() != 2: + raise RuntimeError, "Bad attribute value" + +if c.xget() != 1 or c.yget() != 2 or c.zget() != 3: + raise RuntimeError, "Bad attribute value" + +if d.xget() != 1 or d.yget() != 2 or d.zget() != 3 or d.wget() != 4: + raise RuntimeError, "Bad attribute value" + + +if minherit.xget(a) != 1: + raise RuntimeError, "Bad attribute value %d" % (minherit.xget(a)) + +if minherit.yget(b) != 2: + raise RuntimeError, "Bad attribute value %d" % (minherit.yget(b)) + +if minherit.xget(c) != 1 or minherit.yget(c) != 2 or minherit.zget(c) != 3: + raise RuntimeError, "Bad attribute value %d %d %d" % (minherit.xget(c), minherit.yget(c), minherit.zget(c)) + +if minherit.xget(d) != 1 or minherit.yget(d) != 2 or minherit.zget(d) != 3 or minherit.wget(d) != 4: + raise RuntimeError, "Bad attribute value %d %d %d %d" % (minherit.xget(d), minherit.yget(d), minherit.zget(d), minherit.wget(d)) + +# Cleanse all of the pointers and see what happens + +aa = minherit.toFooPtr(a) +bb = minherit.toBarPtr(b) +cc = minherit.toFooBarPtr(c) +dd = minherit.toSpamPtr(d) + +if aa.xget() != 1: + raise RuntimeError, "Bad attribute value" + +if bb.yget() != 2: + raise RuntimeError, "Bad attribute value" + +if cc.xget() != 1 or cc.yget() != 2 or cc.zget() != 3: + raise RuntimeError, "Bad attribute value" + +if dd.xget() != 1 or dd.yget() != 2 or dd.zget() != 3 or dd.wget() != 4: + raise RuntimeError, "Bad attribute value" + +if minherit.xget(aa) != 1: + raise RuntimeError, "Bad attribute value %d" % (minherit.xget(aa)) + +if minherit.yget(bb) != 2: + raise RuntimeError, "Bad attribute value %d" % (minherit.yget(bb)) + +if minherit.xget(cc) != 1 or minherit.yget(cc) != 2 or minherit.zget(cc) != 3: + raise RuntimeError, "Bad attribute value %d %d %d" % (minherit.xget(cc), minherit.yget(cc), minherit.zget(cc)) + +if minherit.xget(dd) != 1 or minherit.yget(dd) != 2 or minherit.zget(dd) != 3 or minherit.wget(dd) != 4: + raise RuntimeError, "Bad attribute value %d %d %d %d" % (minherit.xget(dd), minherit.yget(dd), minherit.zget(dd), minherit.wget(dd)) + + + + + + + + diff --git a/Examples/test-suite/python/namespace_typemap_runme.py b/Examples/test-suite/python/namespace_typemap_runme.py new file mode 100644 index 000000000..682ad3bb1 --- /dev/null +++ b/Examples/test-suite/python/namespace_typemap_runme.py @@ -0,0 +1,82 @@ +from namespace_typemap import * + +if stest1("hello") != "hello": + raise RuntimeError + +if stest2("hello") != "hello": + raise RuntimeError + +if stest3("hello") != "hello": + raise RuntimeError + +if stest4("hello") != "hello": + raise RuntimeError + +if stest5("hello") != "hello": + raise RuntimeError + +if stest6("hello") != "hello": + raise RuntimeError + +if stest7("hello") != "hello": + raise RuntimeError + +if stest8("hello") != "hello": + raise RuntimeError + +if stest9("hello") != "hello": + raise RuntimeError + +if stest10("hello") != "hello": + raise RuntimeError + +if stest11("hello") != "hello": + raise RuntimeError + +if stest12("hello") != "hello": + raise RuntimeError + +c = complex(2,3) +r = c.real + +if ctest1(c) != r: + raise RuntimeError + +if ctest2(c) != r: + raise RuntimeError + +if ctest3(c) != r: + raise RuntimeError + +if ctest4(c) != r: + raise RuntimeError + +if ctest5(c) != r: + raise RuntimeError + +if ctest6(c) != r: + raise RuntimeError + +if ctest7(c) != r: + raise RuntimeError + +if ctest8(c) != r: + raise RuntimeError + +if ctest9(c) != r: + raise RuntimeError + +if ctest10(c) != r: + raise RuntimeError + +if ctest11(c) != r: + raise RuntimeError + +if ctest12(c) != r: + raise RuntimeError + +try: + ttest1(-14) + raise RuntimeError +except ValueError: + pass diff --git a/Examples/test-suite/python/overload_copy_runme.py b/Examples/test-suite/python/overload_copy_runme.py new file mode 100644 index 000000000..6ccf4013e --- /dev/null +++ b/Examples/test-suite/python/overload_copy_runme.py @@ -0,0 +1,3 @@ +from overload_copy import * +f = Foo() +g = Foo(f) diff --git a/Examples/test-suite/python/overload_extend_runme.py b/Examples/test-suite/python/overload_extend_runme.py new file mode 100644 index 000000000..9fb6920c3 --- /dev/null +++ b/Examples/test-suite/python/overload_extend_runme.py @@ -0,0 +1,11 @@ +import overload_extend + +f = overload_extend.Foo() +if f.test(3) != 1: + raise RuntimeError +if f.test("hello") != 2: + raise RuntimeError +if f.test(3.5,2.5) != 3: + raise RuntimeError + + diff --git a/Examples/test-suite/python/overload_extendc_runme.py b/Examples/test-suite/python/overload_extendc_runme.py new file mode 100644 index 000000000..9fb6920c3 --- /dev/null +++ b/Examples/test-suite/python/overload_extendc_runme.py @@ -0,0 +1,11 @@ +import overload_extend + +f = overload_extend.Foo() +if f.test(3) != 1: + raise RuntimeError +if f.test("hello") != 2: + raise RuntimeError +if f.test(3.5,2.5) != 3: + raise RuntimeError + + diff --git a/Examples/test-suite/python/overload_simple_runme.py b/Examples/test-suite/python/overload_simple_runme.py new file mode 100644 index 000000000..737ed23eb --- /dev/null +++ b/Examples/test-suite/python/overload_simple_runme.py @@ -0,0 +1,97 @@ +from overload_simple import * + +if foo(3) != "foo:int": + raise RuntimeError, "foo(int)" + +if foo(3.0) != "foo:double": + raise RuntimeError, "foo(double)" + +if foo("hello") != "foo:char *": + raise RuntimeError, "foo(char *)" + +f = Foo() +b = Bar() + +if foo(f) != "foo:Foo *": + raise RuntimeError, "foo(Foo *)" + +if foo(b) != "foo:Bar *": + raise RuntimeError, "foo(Bar *)" + +v = malloc_void(32) + +if foo(v) != "foo:void *": + raise RuntimeError, "foo(void *)" + +s = Spam() + +if s.foo(3) != "foo:int": + raise RuntimeError, "Spam::foo(int)" + +if s.foo(3.0) != "foo:double": + raise RuntimeError, "Spam::foo(double)" + +if s.foo("hello") != "foo:char *": + raise RuntimeError, "Spam::foo(char *)" + +if s.foo(f) != "foo:Foo *": + raise RuntimeError, "Spam::foo(Foo *)" + +if s.foo(b) != "foo:Bar *": + raise RuntimeError, "Spam::foo(Bar *)" + +if s.foo(v) != "foo:void *": + raise RuntimeError, "Spam::foo(void *)" + +if Spam_bar(3) != "bar:int": + raise RuntimeError, "Spam::bar(int)" + +if Spam_bar(3.0) != "bar:double": + raise RuntimeError, "Spam::bar(double)" + +if Spam_bar("hello") != "bar:char *": + raise RuntimeError, "Spam::bar(char *)" + +if Spam_bar(f) != "bar:Foo *": + raise RuntimeError, "Spam::bar(Foo *)" + +if Spam_bar(b) != "bar:Bar *": + raise RuntimeError, "Spam::bar(Bar *)" + +if Spam_bar(v) != "bar:void *": + raise RuntimeError, "Spam::bar(void *)" + +# Test constructors + +s = Spam() +if s.type != "none": + raise RuntimeError, "Spam()" + +s = Spam(3) +if s.type != "int": + raise RuntimeError, "Spam(int)" + +s = Spam(3.4) +if s.type != "double": + raise RuntimeError, "Spam(double)" + +s = Spam("hello") +if s.type != "char *": + raise RuntimeError, "Spam(char *)" + +s = Spam(f) +if s.type != "Foo *": + raise RuntimeError, "Spam(Foo *)" + +s = Spam(b) +if s.type != "Bar *": + raise RuntimeError, "Spam(Bar *)" + +s = Spam(v) +if s.type != "void *": + raise RuntimeError, "Spam(void *)" + + + + + diff --git a/Examples/test-suite/python/overload_subtype_runme.py b/Examples/test-suite/python/overload_subtype_runme.py new file mode 100644 index 000000000..6bf77dc59 --- /dev/null +++ b/Examples/test-suite/python/overload_subtype_runme.py @@ -0,0 +1,11 @@ +from overload_subtype import * + +f = Foo() +b = Bar() + +if spam(f) != 1: + raise RuntimeError, "foo" + +if spam(b) != 2: + raise RuntimeError, "bar" + diff --git a/Examples/test-suite/python/overload_template_runme.py b/Examples/test-suite/python/overload_template_runme.py new file mode 100644 index 000000000..1398dd739 --- /dev/null +++ b/Examples/test-suite/python/overload_template_runme.py @@ -0,0 +1,5 @@ +from overload_template import * +f = foo() + +a = max(3,4) +b = max(3.4,5.2) diff --git a/Examples/test-suite/python/primitive_ref_runme.py b/Examples/test-suite/python/primitive_ref_runme.py new file mode 100644 index 000000000..236019b7c --- /dev/null +++ b/Examples/test-suite/python/primitive_ref_runme.py @@ -0,0 +1,37 @@ +from primitive_ref import * + +if ref_int(3) != 3: + raise RuntimeError + +if ref_uint(3) != 3: + raise RuntimeError + +if ref_short(3) != 3: + raise RuntimeError + +if ref_ushort(3) != 3: + raise RuntimeError + +if ref_long(3) != 3: + raise RuntimeError + +if ref_ulong(3) != 3: + raise RuntimeError + +if ref_schar(3) != 3: + raise RuntimeError + +if ref_uchar(3) != 3: + raise RuntimeError + +if ref_float(3.5) != 3.5: + raise RuntimeError + +if ref_double(3.5) != 3.5: + raise RuntimeError + +if ref_bool(1) != 1: + raise RuntimeError + +if ref_char('x') != 'x': + raise RuntimeError diff --git a/Examples/test-suite/python/rename_scope_runme.py b/Examples/test-suite/python/rename_scope_runme.py new file mode 100644 index 000000000..75521d38b --- /dev/null +++ b/Examples/test-suite/python/rename_scope_runme.py @@ -0,0 +1,10 @@ +from rename_scope import * + +a = Natural_UP() +b = Natural_BP() + +if a.rtest() != 1: + raise RuntimeError + +if b.rtest() != 1: + raise RuntimeError diff --git a/Examples/test-suite/python/smart_pointer_multi_runme.py b/Examples/test-suite/python/smart_pointer_multi_runme.py new file mode 100644 index 000000000..c17053055 --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_multi_runme.py @@ -0,0 +1,15 @@ +from smart_pointer_multi import * + +f = Foo() +b = Bar(f) +s = Spam(b) +g = Grok(b) + +s.x = 3 +if s.getx() != 3: + raise RuntimeError + +g.x = 4 +if g.getx() != 4: + raise RuntimeError + diff --git a/Examples/test-suite/python/smart_pointer_multi_typedef_runme.py b/Examples/test-suite/python/smart_pointer_multi_typedef_runme.py new file mode 100644 index 000000000..ebf4c9b09 --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_multi_typedef_runme.py @@ -0,0 +1,15 @@ +from smart_pointer_multi_typedef import * + +f = Foo() +b = Bar(f) +s = Spam(b) +g = Grok(b) + +s.x = 3 +if s.getx() != 3: + raise RuntimeError + +g.x = 4 +if g.getx() != 4: + raise RuntimeError + diff --git a/Examples/test-suite/python/smart_pointer_not_runme.py b/Examples/test-suite/python/smart_pointer_not_runme.py new file mode 100644 index 000000000..4c90b376b --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_not_runme.py @@ -0,0 +1,42 @@ +from smart_pointer_not import * + +f = Foo() +b = Bar(f) +s = Spam(f) +g = Grok(f) + +try: + x = b.x + print "Error! b.x" +except: + pass + +try: + x = s.x + print "Error! s.x" +except: + pass + +try: + x = g.x + print "Error! g.x" +except: + pass + +try: + x = b.getx() + print "Error! b.getx()" +except: + pass + +try: + x = s.getx() + print "Error! s.getx()" +except: + pass + +try: + x = g.getx() + print "Error! g.getx()" +except: + pass diff --git a/Examples/test-suite/python/smart_pointer_overload_runme.py b/Examples/test-suite/python/smart_pointer_overload_runme.py new file mode 100644 index 000000000..c9fd3a5b0 --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_overload_runme.py @@ -0,0 +1,21 @@ +from smart_pointer_overload import * + +f = Foo() +b = Bar(f) + + +if f.test(3) != 1: + raise RuntimeError +if f.test(3.5) != 2: + raise RuntimeError +if f.test("hello") != 3: + raise RuntimeError + +if b.test(3) != 1: + raise RuntimeError +if b.test(3.5) != 2: + raise RuntimeError +if b.test("hello") != 3: + raise RuntimeError + + diff --git a/Examples/test-suite/python/smart_pointer_rename_runme.py b/Examples/test-suite/python/smart_pointer_rename_runme.py new file mode 100644 index 000000000..c6d22273c --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_rename_runme.py @@ -0,0 +1,13 @@ +from smart_pointer_rename import * + +f = Foo() +b = Bar(f) + +if b.test() != 3: + raise RuntimeError + +if b.ftest1(1) != 1: + raise RuntimeError + +if b.ftest2(2,3) != 2: + raise RuntimeError diff --git a/Examples/test-suite/python/smart_pointer_simple_runme.py b/Examples/test-suite/python/smart_pointer_simple_runme.py new file mode 100644 index 000000000..95b678aae --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_simple_runme.py @@ -0,0 +1,13 @@ +from smart_pointer_simple import * + +f = Foo() +b = Bar(f) + +b.x = 3 +if b.getx() != 3: + raise RuntimeError + +fp = b.__deref__() +fp.x = 4 +if fp.getx() != 4: + raise RuntimeError diff --git a/Examples/test-suite/python/smart_pointer_typedef_runme.py b/Examples/test-suite/python/smart_pointer_typedef_runme.py new file mode 100644 index 000000000..eee0537f4 --- /dev/null +++ b/Examples/test-suite/python/smart_pointer_typedef_runme.py @@ -0,0 +1,13 @@ +from smart_pointer_typedef import * + +f = Foo() +b = Bar(f) + +b.x = 3 +if b.getx() != 3: + raise RuntimeError + +fp = b.__deref__() +fp.x = 4 +if fp.getx() != 4: + raise RuntimeError diff --git a/Examples/test-suite/python/sneaky1_runme.py b/Examples/test-suite/python/sneaky1_runme.py new file mode 100644 index 000000000..7823e77ea --- /dev/null +++ b/Examples/test-suite/python/sneaky1_runme.py @@ -0,0 +1,5 @@ +import sneaky1 +x = sneaky1.add(3,4) +y = sneaky1.sub(3,4) +z = sneaky1.mul(3,4) +w = sneaky1.divide(3,4) diff --git a/Examples/test-suite/python/static_const_member_2_runme.py b/Examples/test-suite/python/static_const_member_2_runme.py new file mode 100644 index 000000000..738daf465 --- /dev/null +++ b/Examples/test-suite/python/static_const_member_2_runme.py @@ -0,0 +1,15 @@ +from static_const_member_2 import * + +c = Test_int() +try: + a = c.forward_field + a = c.current_profile + a = c.RightIndex + a = Test_int.backward_field + a = Test_int.LeftIndex + a = Test_int.cavity_flags +except: + print "Failed!!" + + + diff --git a/Examples/test-suite/python/struct_value_runme.py b/Examples/test-suite/python/struct_value_runme.py new file mode 100644 index 000000000..727996f53 --- /dev/null +++ b/Examples/test-suite/python/struct_value_runme.py @@ -0,0 +1,9 @@ +import struct_value + +b = struct_value.Bar() + +b.a.x = 3 +if b.a.x != 3: raise RuntimeError + +b.b.x = 3 +if b.b.x != 3: raise RuntimeError diff --git a/Examples/test-suite/python/template_construct_runme.py b/Examples/test-suite/python/template_construct_runme.py new file mode 100644 index 000000000..3409fdd62 --- /dev/null +++ b/Examples/test-suite/python/template_construct_runme.py @@ -0,0 +1 @@ +import template_construct diff --git a/Examples/test-suite/python/template_inherit_runme.py b/Examples/test-suite/python/template_inherit_runme.py new file mode 100644 index 000000000..bb1465a2b --- /dev/null +++ b/Examples/test-suite/python/template_inherit_runme.py @@ -0,0 +1,53 @@ +from template_inherit import * +a = FooInt() +b = FooDouble() +c = BarInt() +d = BarDouble() +e = FooUInt() +f = BarUInt() + +if a.blah() != "Foo": + raise ValueError + +if b.blah() != "Foo": + raise ValueError + +if e.blah() != "Foo": + raise ValueError + +if c.blah() != "Bar": + raise ValueError + +if d.blah() != "Bar": + raise ValueError + +if f.blah() != "Bar": + raise ValueError + +if c.foomethod() != "foomethod": + raise ValueError + +if d.foomethod() != "foomethod": + raise ValueError + +if f.foomethod() != "foomethod": + raise ValueError + +if invoke_blah_int(a) != "Foo": + raise ValueError + +if invoke_blah_int(c) != "Bar": + raise ValueError + +if invoke_blah_double(b) != "Foo": + raise ValueError + +if invoke_blah_double(d) != "Bar": + raise ValueError + +if invoke_blah_uint(e) != "Foo": + raise ValueError + +if invoke_blah_uint(f) != "Bar": + raise ValueError + diff --git a/Examples/test-suite/python/template_ns4_runme.py b/Examples/test-suite/python/template_ns4_runme.py new file mode 100644 index 000000000..81107b493 --- /dev/null +++ b/Examples/test-suite/python/template_ns4_runme.py @@ -0,0 +1,5 @@ +from template_ns4 import * + +d = make_Class_DD(); +if d.test() != "test": + raise RuntimeError diff --git a/Examples/test-suite/python/template_ns_runme.py b/Examples/test-suite/python/template_ns_runme.py new file mode 100644 index 000000000..20cc9b99c --- /dev/null +++ b/Examples/test-suite/python/template_ns_runme.py @@ -0,0 +1,17 @@ +from template_ns import * +p1 = pairii(2,3) +p2 = pairii(p1) + +if p2.first != 2: + raise RuntimeError +if p2.second != 3: + raise RuntimeError + +p3 = pairdd(3.5,2.5) +p4 = pairdd(p3) + +if p4.first != 3.5: + raise RuntimeError + +if p4.second != 2.5: + raise RuntimeError diff --git a/Examples/test-suite/python/template_rename_runme.py b/Examples/test-suite/python/template_rename_runme.py new file mode 100644 index 000000000..1fd45ba03 --- /dev/null +++ b/Examples/test-suite/python/template_rename_runme.py @@ -0,0 +1,12 @@ +import template_rename + +i = template_rename.iFoo() +d = template_rename.dFoo() + +a = i.blah_test(4) +b = i.spam_test(5) +c = i.grok_test(6) + +x = d.blah_test(7) +y = d.spam(8) +z = d.grok_test(9) diff --git a/Examples/test-suite/python/template_tbase_template_runme.py b/Examples/test-suite/python/template_tbase_template_runme.py new file mode 100644 index 000000000..d13c5f2c2 --- /dev/null +++ b/Examples/test-suite/python/template_tbase_template_runme.py @@ -0,0 +1,5 @@ +from template_tbase_template import * + +a = make_Class_dd() +if a.test() != "test": + raise RuntimeError diff --git a/Examples/test-suite/python/template_type_namespace_runme.py b/Examples/test-suite/python/template_type_namespace_runme.py new file mode 100644 index 000000000..19ea5f5ce --- /dev/null +++ b/Examples/test-suite/python/template_type_namespace_runme.py @@ -0,0 +1,5 @@ +from template_type_namespace import * + +if type(foo()[0]) != type(""): + raise RuntimeError + diff --git a/Examples/test-suite/python/template_typedef_cplx2_runme.py b/Examples/test-suite/python/template_typedef_cplx2_runme.py new file mode 100644 index 000000000..51a1d4e97 --- /dev/null +++ b/Examples/test-suite/python/template_typedef_cplx2_runme.py @@ -0,0 +1,95 @@ +import string +from template_typedef_cplx2 import * + +# +# double case +# + +try: + d = make_Identity_double() + a = d.this +except: + print d, "is not an instance" + raise RuntimeError + +s = string.split('%s' % d)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print d, "is not an ArithUnaryFunction" + raise RuntimeError + +try: + e = make_Multiplies_double_double_double_double(d, d) + a = e.this +except: + print e, "is not an instance" + raise RuntimeError + +s = string.split('%s' % e)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print e, "is not an ArithUnaryFunction" + raise RuntimeError + + +# +# complex case +# + +try: + c = make_Identity_complex() + a = c.this +except: + print c, "is not an instance" + raise RuntimeError + +s = string.split('%s' % c)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print c, "is not an ArithUnaryFunction" + raise RuntimeError + +try: + f = make_Multiplies_complex_complex_complex_complex(c, c) + a = f.this +except: + print f, "is not an instance" + raise RuntimeError + +s = string.split('%s' % f)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print f, "is not an ArithUnaryFunction" + raise RuntimeError + +# +# Mix case +# + +try: + g = make_Multiplies_double_double_complex_complex(d, c) + a = g.this +except: + print g, "is not an instance" + raise RuntimeError + +s = string.split('%s' % g)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print g, "is not an ArithUnaryFunction" + raise RuntimeError + + +try: + h = make_Multiplies_complex_complex_double_double(c, d) + a = h.this +except: + print h, "is not an instance" + raise RuntimeError + +s = string.split('%s' % g)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print g, "is not an ArithUnaryFunction" + raise RuntimeError + +try: + a = g.get_value() +except: + print g, "has not get_value() method" + raise RuntimeError + diff --git a/Examples/test-suite/python/template_typedef_cplx3_runme.py b/Examples/test-suite/python/template_typedef_cplx3_runme.py new file mode 100644 index 000000000..b8ac1b6ef --- /dev/null +++ b/Examples/test-suite/python/template_typedef_cplx3_runme.py @@ -0,0 +1,34 @@ +import string +from template_typedef_cplx3 import * + +# +# this is OK +# + + +s = Sin() +s.get_base_value() +s.get_value() +s.get_arith_value() +my_func_r(s) +make_Multiplies_double_double_double_double(s,s) + +z = CSin() +z.get_base_value() +z.get_value() +z.get_arith_value() +my_func_c(z) +make_Multiplies_complex_complex_complex_complex(z,z) + +# +# Here we fail +# +d = make_Identity_double() +my_func_r(d) + +c = make_Identity_complex() +my_func_c(c) + + + + diff --git a/Examples/test-suite/python/template_typedef_cplx4_runme.py b/Examples/test-suite/python/template_typedef_cplx4_runme.py new file mode 100644 index 000000000..faeca219f --- /dev/null +++ b/Examples/test-suite/python/template_typedef_cplx4_runme.py @@ -0,0 +1,34 @@ +import string +from template_typedef_cplx4 import * + +# +# this is OK +# + + +s = Sin() +s.get_base_value() +s.get_value() +s.get_arith_value() +my_func_r(s) +make_Multiplies_double_double_double_double(s,s) + +z = CSin() +z.get_base_value() +z.get_value() +z.get_arith_value() +my_func_c(z) +make_Multiplies_complex_complex_complex_complex(z,z) + +# +# Here we fail +# +d = make_Identity_double() +my_func_r(d) + +c = make_Identity_complex() +my_func_c(c) + + + + diff --git a/Examples/test-suite/python/template_typedef_cplx_runme.py b/Examples/test-suite/python/template_typedef_cplx_runme.py new file mode 100644 index 000000000..baf9fad01 --- /dev/null +++ b/Examples/test-suite/python/template_typedef_cplx_runme.py @@ -0,0 +1,88 @@ +import string +from template_typedef_cplx import * + +# +# double case +# + +try: + d = make_Identity_double() + a = d.this +except: + print d, "is not an instance" + raise RuntimeError + +s = string.split('%s' % d)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print d, "is not an ArithUnaryFunction" + raise RuntimeError + +try: + e = make_Multiplies_double_double_double_double(d, d) + a = e.this +except: + print e, "is not an instance" + raise RuntimeError + +s = string.split('%s' % e)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print e, "is not an ArithUnaryFunction" + raise RuntimeError + + +# +# complex case +# + +try: + c = make_Identity_complex() + a = c.this +except: + print c, "is not an instance" + raise RuntimeError + +s = string.split('%s' % c)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print c, "is not an ArithUnaryFunction" + raise RuntimeError + +try: + f = make_Multiplies_complex_complex_complex_complex(c, c) + a = f.this +except: + print f, "is not an instance" + raise RuntimeError + +s = string.split('%s' % f)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print f, "is not an ArithUnaryFunction" + raise RuntimeError + +# +# Mix case +# + +try: + g = make_Multiplies_double_double_complex_complex(d, c) + a = g.this +except: + print g, "is not an instance" + raise RuntimeError + +s = string.split('%s' % g)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print g, "is not an ArithUnaryFunction" + raise RuntimeError + + +try: + h = make_Multiplies_complex_complex_double_double(c, d) + a = h.this +except: + print h, "is not an instance" + raise RuntimeError + +s = string.split('%s' % g)[1] +if string.find(s, 'ArithUnaryFunction') == -1: + print g, "is not an ArithUnaryFunction" + raise RuntimeError diff --git a/Examples/test-suite/python/template_typedef_import_runme.py b/Examples/test-suite/python/template_typedef_import_runme.py new file mode 100644 index 000000000..48d88eda0 --- /dev/null +++ b/Examples/test-suite/python/template_typedef_import_runme.py @@ -0,0 +1,35 @@ +import string +from template_typedef_cplx2 import * +from template_typedef_import import * + +# +# this is OK +# + + +s = Sin() +s.get_base_value() +s.get_value() +s.get_arith_value() +my_func_r(s) +make_Multiplies_double_double_double_double(s,s) + +z = CSin() +z.get_base_value() +z.get_value() +z.get_arith_value() +my_func_c(z) +make_Multiplies_complex_complex_complex_complex(z,z) + +# +# Here we fail +# +d = make_Identity_double() +my_func_r(d) + +c = make_Identity_complex() +my_func_c(c) + + + + diff --git a/Examples/test-suite/python/template_typedef_runme.py b/Examples/test-suite/python/template_typedef_runme.py new file mode 100644 index 000000000..cf73d5919 --- /dev/null +++ b/Examples/test-suite/python/template_typedef_runme.py @@ -0,0 +1,33 @@ +from template_typedef import * + +d = make_Identity_float() +c = make_Identity_real() + + +try: + a = d.this + a = c.this +except: + raise RuntimeError + +try: + e = make_Multiplies_float_float_float_float(d, d) + a = e.this +except: + print e, "is not an instance" + raise RuntimeError + +try: + f = make_Multiplies_real_real_real_real(c, c) + a = f.this +except: + print f, "is not an instance" + raise RuntimeError + +try: + g = make_Multiplies_float_float_real_real(d, c) + a = g.this +except: + print g, "is not an instance" + raise RuntimeError + diff --git a/Examples/test-suite/python/typedef_inherit_runme.py b/Examples/test-suite/python/typedef_inherit_runme.py new file mode 100644 index 000000000..6b7f2d872 --- /dev/null +++ b/Examples/test-suite/python/typedef_inherit_runme.py @@ -0,0 +1,23 @@ +import typedef_inherit + +a = typedef_inherit.Foo() +b = typedef_inherit.Bar() + +x = typedef_inherit.do_blah(a) +if x != "Foo::blah": + print "Whoa! Bad return", x + +x = typedef_inherit.do_blah(b) +if x != "Bar::blah": + print "Whoa! Bad return", x + +c = typedef_inherit.Spam() +d = typedef_inherit.Grok() + +x = typedef_inherit.do_blah2(c) +if x != "Spam::blah": + print "Whoa! Bad return", x + +x = typedef_inherit.do_blah2(d) +if x != "Grok::blah": + print "Whoa! Bad return", x diff --git a/Examples/test-suite/python/typedef_scope_runme.py b/Examples/test-suite/python/typedef_scope_runme.py new file mode 100644 index 000000000..37bfc97b1 --- /dev/null +++ b/Examples/test-suite/python/typedef_scope_runme.py @@ -0,0 +1,12 @@ +import typedef_scope + +b = typedef_scope.Bar() +x = b.test1(42,"hello") +if x != 42: + print "Failed!!" + +x = b.test2(42,"hello") +if x != "hello": + print "Failed!!" + + diff --git a/Examples/test-suite/python/typemap_namespace_runme.py b/Examples/test-suite/python/typemap_namespace_runme.py new file mode 100644 index 000000000..581a0f437 --- /dev/null +++ b/Examples/test-suite/python/typemap_namespace_runme.py @@ -0,0 +1,8 @@ +from typemap_namespace import * + +if test1("hello") != "hello": + raise RuntimeError + +if test2("hello") != "hello": + raise RuntimeError + diff --git a/Examples/test-suite/python/typemap_ns_using_runme.py b/Examples/test-suite/python/typemap_ns_using_runme.py new file mode 100644 index 000000000..802ea7f56 --- /dev/null +++ b/Examples/test-suite/python/typemap_ns_using_runme.py @@ -0,0 +1,4 @@ +import typemap_ns_using + +if typemap_ns_using.spam(37) != 37: + raise RuntimeError diff --git a/Examples/test-suite/python/typename_runme.py b/Examples/test-suite/python/typename_runme.py new file mode 100644 index 000000000..59a0f1f76 --- /dev/null +++ b/Examples/test-suite/python/typename_runme.py @@ -0,0 +1,12 @@ +import typename +import types +f = typename.Foo() +b = typename.Bar() + +x = typename.twoFoo(f) +if not isinstance(x,types.FloatType): + print "Wrong return type!" +y = typename.twoBar(b) +if not isinstance(y,types.IntType): + print "Wrong return type!" + diff --git a/Examples/test-suite/python/unions_runme.py b/Examples/test-suite/python/unions_runme.py new file mode 100644 index 000000000..d59e2429e --- /dev/null +++ b/Examples/test-suite/python/unions_runme.py @@ -0,0 +1,51 @@ + +# This is the union runtime testcase. It ensures that values within a +# union embedded within a struct can be set and read correctly. + +import unions +import sys +import string + +# Create new instances of SmallStruct and BigStruct for later use +small = unions.SmallStruct() +small.jill = 200 + +big = unions.BigStruct() +big.smallstruct = small +big.jack = 300 + +# Use SmallStruct then BigStruct to setup EmbeddedUnionTest. +# Ensure values in EmbeddedUnionTest are set correctly for each. +eut = unions.EmbeddedUnionTest() + +# First check the SmallStruct in EmbeddedUnionTest +eut.number = 1 +eut.uni.small = small +Jill1 = eut.uni.small.jill +if (Jill1 != 200): + print "Runtime test1 failed. eut.uni.small.jill=" , Jill1 + sys.exit(1) + +Num1 = eut.number +if (Num1 != 1): + print "Runtime test2 failed. eut.number=" , Num1 + sys.exit(1) + +# Secondly check the BigStruct in EmbeddedUnionTest +eut.number = 2 +eut.uni.big = big +Jack1 = eut.uni.big.jack +if (Jack1 != 300): + print "Runtime test3 failed. eut.uni.big.jack=" , Jack1 + sys.exit(1) + +Jill2 = eut.uni.big.smallstruct.jill +if (Jill2 != 200): + print "Runtime test4 failed. eut.uni.big.smallstruct.jill=" , Jill2 + sys.exit(1) + +Num2 = eut.number +if (Num2 != 2): + print "Runtime test5 failed. eut.number=" , Num2 + sys.exit(1) + diff --git a/Examples/test-suite/python/using1_runme.py b/Examples/test-suite/python/using1_runme.py new file mode 100644 index 000000000..5556c1b6a --- /dev/null +++ b/Examples/test-suite/python/using1_runme.py @@ -0,0 +1,4 @@ +import using1 + +if using1.spam(37) != 37: + raise RuntimeError diff --git a/Examples/test-suite/python/using2_runme.py b/Examples/test-suite/python/using2_runme.py new file mode 100644 index 000000000..cf657d734 --- /dev/null +++ b/Examples/test-suite/python/using2_runme.py @@ -0,0 +1,4 @@ +import using2 + +if using2.spam(37) != 37: + raise RuntimeError diff --git a/Examples/test-suite/python/using_composition_runme.py b/Examples/test-suite/python/using_composition_runme.py new file mode 100644 index 000000000..866453a2a --- /dev/null +++ b/Examples/test-suite/python/using_composition_runme.py @@ -0,0 +1,11 @@ +from using_composition import * + +f = FooBar() +if f.blah(3) != 3: + raise RuntimeError,"blah(int)" + +if f.blah(3.5) != 3.5: + raise RuntimeError,"blah(double)" + +if f.blah("hello") != "hello": + raise RuntimeError,"blah(char *)" diff --git a/Examples/test-suite/python/using_extend_runme.py b/Examples/test-suite/python/using_extend_runme.py new file mode 100644 index 000000000..1ddc4baa1 --- /dev/null +++ b/Examples/test-suite/python/using_extend_runme.py @@ -0,0 +1,17 @@ +from using_extend import * + +f = FooBar() +if f.blah(3) != 3: + raise RuntimeError,"blah(int)" + +if f.blah(3.5) != 3.5: + raise RuntimeError,"blah(double)" + +if f.blah("hello") != "hello": + raise RuntimeError,"blah(char *)" + +if f.blah(3,4) != 7: + raise RuntimeError,"blah(int,int)" + +if f.blah(3.5,7.5) != (3.5+7.5): + raise RuntimeError,"blah(double,double)" diff --git a/Examples/test-suite/python/using_inherit_runme.py b/Examples/test-suite/python/using_inherit_runme.py new file mode 100644 index 000000000..15fee6698 --- /dev/null +++ b/Examples/test-suite/python/using_inherit_runme.py @@ -0,0 +1,8 @@ +from using_inherit import * + +b = Bar() +if b.test(3) != 3: + raise RuntimeError,"test(int)" + +if b.test(3.5) != 3.5: + raise RuntimeError, "test(double)" diff --git a/Examples/test-suite/python/using_private_runme.py b/Examples/test-suite/python/using_private_runme.py new file mode 100644 index 000000000..3d33ed985 --- /dev/null +++ b/Examples/test-suite/python/using_private_runme.py @@ -0,0 +1,7 @@ +from using_private import * + +f = FooBar() +f.x = 3 + +if f.blah(4) != 4: + raise RuntimeError, "blah(int)" diff --git a/Examples/test-suite/python/using_protected_runme.py b/Examples/test-suite/python/using_protected_runme.py new file mode 100644 index 000000000..525a1cde4 --- /dev/null +++ b/Examples/test-suite/python/using_protected_runme.py @@ -0,0 +1,7 @@ +from using_protected import * + +f = FooBar() +f.x = 3 + +if f.blah(4) != 4: + raise RuntimeError, "blah(int)" diff --git a/Examples/test-suite/python/voidtest_runme.py b/Examples/test-suite/python/voidtest_runme.py new file mode 100644 index 000000000..e1f46b176 --- /dev/null +++ b/Examples/test-suite/python/voidtest_runme.py @@ -0,0 +1,7 @@ +import voidtest + +voidtest.globalfunc() +f = voidtest.Foo() +f.memberfunc() + +voidtest.Foo_staticmemberfunc() diff --git a/Examples/test-suite/rename_default.i b/Examples/test-suite/rename_default.i new file mode 100644 index 000000000..67094660e --- /dev/null +++ b/Examples/test-suite/rename_default.i @@ -0,0 +1,27 @@ +// Here's a nice little test for renaming, symbol table management, and default arguments + +%module rename_default + +// Rename a class member +%rename(bar2) Foo::bar; + +%inline %{ + +// Define a class +class Foo { +public: + static int bar; + static int spam; + + // Use a renamed member as a default argument. SWIG has to resolve + // bar to Foo::bar and not Foo::spam. SWIG-1.3.11 got this wrong. + + void method1(int x = bar) {} + + // Use unrenamed member as default + void method2(int x = spam) {} +}; +int Foo::bar = 1; +int Foo::spam = 2; +%} + diff --git a/Examples/test-suite/rename_scope.i b/Examples/test-suite/rename_scope.i new file mode 100644 index 000000000..adcf2be05 --- /dev/null +++ b/Examples/test-suite/rename_scope.i @@ -0,0 +1,49 @@ +%module rename_scope + +%inline +%{ + namespace oss + { + enum Polarization { UnaryPolarization, BinaryPolarization }; + + template + struct Interface + { + }; + } +%} + +namespace oss +{ + // Interface + %template(Interface_UP) Interface; + %template(Interface_BP) Interface; + +} +%inline +%{ + namespace oss + { + namespace interfaces + { + template + struct Natural : Interface

      + { + int test(void) { return 1; } + }; + } + } +%} + +namespace oss +{ + namespace interfaces + { + %rename(rtest) Natural::test; + %rename(rtest) Natural::test; + + // Natural + %template(Natural_UP) Natural; + %template(Natural_BP) Natural; + } +} diff --git a/Examples/test-suite/ret_by_value.i b/Examples/test-suite/ret_by_value.i new file mode 100644 index 000000000..273336e00 --- /dev/null +++ b/Examples/test-suite/ret_by_value.i @@ -0,0 +1,19 @@ +/* Simple test to check SWIG's handling of return by value */ + +%module ret_by_value + +%warnfilter(801) test; /* Ruby, wrong class name */ + +%inline %{ + +typedef struct { + int myInt; + short myShort; +} test; + +test get_test() { + test myTest = {100, 200}; + return myTest; +} + +%} diff --git a/Examples/test-suite/return_value_scope.i b/Examples/test-suite/return_value_scope.i new file mode 100644 index 000000000..d7d97a10a --- /dev/null +++ b/Examples/test-suite/return_value_scope.i @@ -0,0 +1,28 @@ +%module return_value_scope +%inline %{ + +namespace Hell { +class Foo { +public: + Foo(int) { }; +}; + +class Bar { +public: + typedef Foo fooref; +}; + +class Spam { +public: + typedef Bar base; + typedef base::fooref rettype; + rettype test() { + return rettype(1); + } +}; +} +%} + + + + diff --git a/Examples/test-suite/rname.i b/Examples/test-suite/rname.i new file mode 100644 index 000000000..ad0a75d19 --- /dev/null +++ b/Examples/test-suite/rname.i @@ -0,0 +1,48 @@ +// This module tests various facets of the %rename directive + +%module rname + +/* Applied everywhere */ +%rename(foo_i) foo(int); +%rename(foo_d) foo(double); + +/* Applied only to global scope */ + +%rename(foo_s) ::foo(short); + +/* Applied only to class scope */ + +%rename(foo_u) *::foo(unsigned); + +/* Rename classes in a class hierarchy */ +%rename (RenamedBase) Base; +%rename (RenamedDerived) Derived; + +%inline %{ +class Bar { +public: + char *foo(int) { return (char *) "Bar::foo-int"; } + char *foo(double) { return (char *) "Bar::foo-double"; } + char *foo(short) { return (char *) "Bar::foo-short"; } + char *foo(unsigned) { return (char *) "Bar::foo-unsigned"; } +}; + +char *foo(int) { return (char *) "foo-int"; } +char *foo(double) { return (char *) "foo-double"; } +char *foo(short) { return (char *) "foo-short"; } +char *foo(unsigned) { return (char *) "foo-unsigned"; } + +class Base { +public: + Base(){}; + virtual ~Base(){}; +}; +class Derived : public Base { +public: + Derived(){} + ~Derived(){} + void fn(Derived derived, Base* basePtr, Base& baseRef){} // test renamed classes in a function +}; + + +%} diff --git a/Examples/test-suite/ruby/.cvsignore b/Examples/test-suite/ruby/.cvsignore new file mode 100644 index 000000000..09e0b6c2e --- /dev/null +++ b/Examples/test-suite/ruby/.cvsignore @@ -0,0 +1,3 @@ +*wrap* +*.so +*.dll diff --git a/Examples/test-suite/ruby/Makefile b/Examples/test-suite/ruby/Makefile new file mode 100644 index 000000000..eec1f10a4 --- /dev/null +++ b/Examples/test-suite/ruby/Makefile @@ -0,0 +1,41 @@ +####################################################################### +# $Header$ +# Makefile for ruby test-suite +####################################################################### + +LANGUAGE = ruby +SCRIPTSUFFIX = _runme.rb + +include ../common.mk + +# Overridden variables here + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.rb appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.rb ]; then ( \ + ruby $*\_runme.rb;) \ + fi; + +# Clean +%.clean: + + +clean: + $(MAKE) -f $(TOP)/Makefile ruby_clean diff --git a/Examples/test-suite/ruby/README b/Examples/test-suite/ruby/README new file mode 100644 index 000000000..c4ace93e6 --- /dev/null +++ b/Examples/test-suite/ruby/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.rb appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/ruby/class_ignore_runme.rb b/Examples/test-suite/ruby/class_ignore_runme.rb new file mode 100755 index 000000000..0b47a7fad --- /dev/null +++ b/Examples/test-suite/ruby/class_ignore_runme.rb @@ -0,0 +1,10 @@ +require 'class_ignore' + +a = Class_ignore::Bar.new + +# Even though we didn't wrap the Foo class, this call +# to do_blah() should succeed. + +if Class_ignore.do_blah(a) != "Bar::blah" + raise RuntimeError +end diff --git a/Examples/test-suite/ruby/constover_runme.rb b/Examples/test-suite/ruby/constover_runme.rb new file mode 100755 index 000000000..04d516b75 --- /dev/null +++ b/Examples/test-suite/ruby/constover_runme.rb @@ -0,0 +1,44 @@ +require 'constover' + +error = 0 + +p = Constover.test("test") +if p != "test" + puts "test failed!" + error = 1 +end + +p = Constover.test_pconst("test") +if p != "test_pconst" + puts "test_pconst failed!" + error = 1 +end + +f = Constover::Foo.new +p = f.test("test") +if p != "test" + print "member-test failed!" + error = 1 +end + +p = f.test_pconst("test") +if p != "test_pconst" + print "member-test_pconst failed!" + error = 1 +end + +p = f.test_constm("test") +if p != "test_constmethod" + print "member-test_constm failed!" + error = 1 +end + +p = f.test_pconstm("test") +if p != "test_pconstmethod" + print "member-test_pconstm failed!" + error = 1 +end + +exit(error) + + diff --git a/Examples/test-suite/ruby/cpp_namespace_runme.rb b/Examples/test-suite/ruby/cpp_namespace_runme.rb new file mode 100755 index 000000000..db44b45f0 --- /dev/null +++ b/Examples/test-suite/ruby/cpp_namespace_runme.rb @@ -0,0 +1,51 @@ +# Note: This example assumes that namespaces are flattened +require 'cpp_namespace' + +n = Cpp_namespace.fact(4) +if n != 24 + raise "Bad return value!" +end + +if Cpp_namespace.Foo != 42 + raise "Bad variable value!" +end + +t = Cpp_namespace::Test.new +if t.method() != "Test::method" + raise "Bad method return value!" +end + +if Cpp_namespace.do_method(t) != "Test::method" + raise "Bad return value!" +end + +if Cpp_namespace.do_method2(t) != "Test::method" + raise "Bad return value!" +end + +Cpp_namespace.weird("hello", 4) + +t2 = Cpp_namespace::Test2.new +t3 = Cpp_namespace::Test3.new +t4 = Cpp_namespace::Test4.new +t5 = Cpp_namespace::Test5.new + +if Cpp_namespace.foo3(42) != 42 + raise "Bad return value!" +end + +if Cpp_namespace.do_method3(t2, 40) != "Test2::method" + raise "Bad return value!" +end + +if Cpp_namespace.do_method3(t3, 40) != "Test3::method" + raise "Bad return value!" +end + +if Cpp_namespace.do_method3(t4, 40) != "Test4::method" + raise "Bad return value!" +end + +if Cpp_namespace.do_method3(t5, 40) != "Test5::method" + raise "Bad return value!" +end diff --git a/Examples/test-suite/ruby/default_constructor_runme.rb b/Examples/test-suite/ruby/default_constructor_runme.rb new file mode 100755 index 000000000..fc1f42937 --- /dev/null +++ b/Examples/test-suite/ruby/default_constructor_runme.rb @@ -0,0 +1,94 @@ +require 'default_constructor' + +include Default_constructor + +# Ruby 1.6 raises NameError if you try to call Class.new where no constructor +# is defined; Ruby 1.7 changed this to NoMethodError + +NoConstructorError = Kernel.const_defined?("NoMethodError") ? NoMethodError : NameError + +# This should be no problem +a = A.new + +# Nor should this +aa = AA.new + +# The default constructor for B is private, so this should raise an exception +begin + b = B.new +rescue ArgumentError + # pass +end + +# The two-argument constructor for B should work +b = B.new(3, 4) + +# BB shouldn't inherit B's default constructor, so this should raise an exception +begin + bb = BB.new + puts "Whoa. new BB created." +rescue NoConstructorError + # pass +end + +# C's constructor is protected, so this should raise an exception +begin + c = C.new + print "Whoa. new C created." +rescue NoConstructorError + # pass +end + +# CC gets a default constructor, so no problem here +cc = CC.new + +# D's constructor is private, so this should fail +begin + d = D.new + puts "Whoa. new D created" +rescue NoConstructorError + # pass +end + +# DD shouldn't get a default constructor, so this should fail +begin + dd = DD.new + puts "Whoa. new DD created" +rescue NoConstructorError + # pass +end + +# AD shouldn't get a default constructor, so this should fail +begin + ad = AD.new + puts "Whoa. new AD created" +rescue NoConstructorError + # pass +end + +# Both of the arguments to E's constructor have default values, +# so this should be fine. +e = E.new + +# EE should get a default constructor +ee = EE.new + +# EB should not get a default constructor (because B doesn't have one) +begin + eb = EB.new + puts "Whoa. new EB created" +rescue NoConstructorError + # pass +end + +# This should work fine +f = F.new + +# This should work fine +ff = FFF.new + +# This should work fine +g = G.new + +# This should work fine +gg = GG.new diff --git a/Examples/test-suite/ruby/dynamic_cast_runme.rb b/Examples/test-suite/ruby/dynamic_cast_runme.rb new file mode 100755 index 000000000..a7f327bb6 --- /dev/null +++ b/Examples/test-suite/ruby/dynamic_cast_runme.rb @@ -0,0 +1,13 @@ +require 'dynamic_cast' + +f = Dynamic_cast::Foo.new +b = Dynamic_cast::Bar.new + +x = f.blah +y = b.blah + +a = Dynamic_cast.do_test(y) +if a != "Bar::test" + puts "Failed!!" +end + diff --git a/Examples/test-suite/ruby/enum_runme.rb b/Examples/test-suite/ruby/enum_runme.rb new file mode 100755 index 000000000..9ea9a29e2 --- /dev/null +++ b/Examples/test-suite/ruby/enum_runme.rb @@ -0,0 +1,6 @@ +require 'enum' + +Enum.bar2(1) +Enum.bar3(1) +Enum.bar1(1) + diff --git a/Examples/test-suite/ruby/extend_template_ns_runme.rb b/Examples/test-suite/ruby/extend_template_ns_runme.rb new file mode 100644 index 000000000..a30959bb2 --- /dev/null +++ b/Examples/test-suite/ruby/extend_template_ns_runme.rb @@ -0,0 +1,12 @@ +require 'extend_template_ns' + +include Extend_template_ns + +f = Foo_One.new +if f.test1(37) != 37 + raise RuntimeError +end + +if f.test2(42) != 42 + raise RuntimeError +end diff --git a/Examples/test-suite/ruby/extend_template_runme.rb b/Examples/test-suite/ruby/extend_template_runme.rb new file mode 100644 index 000000000..8787de7dc --- /dev/null +++ b/Examples/test-suite/ruby/extend_template_runme.rb @@ -0,0 +1,10 @@ +require 'extend_template' + +f = Extend_template::Foo_0.new +if f.test1(37) != 37 + raise RuntimeError +end + +if f.test2(42) != 42 + raise RuntimeError +end diff --git a/Examples/test-suite/ruby/grouping_runme.rb b/Examples/test-suite/ruby/grouping_runme.rb new file mode 100644 index 000000000..13cf48943 --- /dev/null +++ b/Examples/test-suite/ruby/grouping_runme.rb @@ -0,0 +1,15 @@ +require 'grouping' + +x = Grouping.test1(42) +if x != 42 + raise RuntimeError +end + +Grouping.test2(42) + +x = Grouping.do_unary(37, Grouping::NEGATE) +if x != -37 + raise RuntimeError +end + +Grouping.test3 = 42 diff --git a/Examples/test-suite/ruby/imports_runme.rb b/Examples/test-suite/ruby/imports_runme.rb new file mode 100755 index 000000000..0290bbad2 --- /dev/null +++ b/Examples/test-suite/ruby/imports_runme.rb @@ -0,0 +1,9 @@ +# This is the import runtime testcase. + +require 'imports_a' +require 'imports_b' + +x = Imports_b::B.new + +x.hello + diff --git a/Examples/test-suite/ruby/inherit_missing_runme.rb b/Examples/test-suite/ruby/inherit_missing_runme.rb new file mode 100644 index 000000000..476ef0f7c --- /dev/null +++ b/Examples/test-suite/ruby/inherit_missing_runme.rb @@ -0,0 +1,20 @@ +require 'inherit_missing' + +a = Inherit_missing.new_Foo() +b = Inherit_missing::Bar.new +c = Inherit_missing::Spam.new + +x = Inherit_missing.do_blah(a) +if x != "Foo::blah" + puts "Whoa! Bad return #{x}" +end + +x = Inherit_missing.do_blah(b) +if x != "Bar::blah" + puts "Whoa! Bad return #{x}" +end + +x = Inherit_missing.do_blah(c) +if x != "Spam::blah" + puts "Whoa! Bad return #{x}" +end diff --git a/Examples/test-suite/ruby/lib_std_vector_runme.rb b/Examples/test-suite/ruby/lib_std_vector_runme.rb new file mode 100755 index 000000000..587495f8d --- /dev/null +++ b/Examples/test-suite/ruby/lib_std_vector_runme.rb @@ -0,0 +1,17 @@ +require 'lib_std_vector' + +include Lib_std_vector + +iv = IntVector.new(4) +0.upto(3) { |i| iv[i] = i } + +x = average(iv) +y = average([1, 2, 3, 4]) + +a = half([10, 10.5, 11, 11.5]) + +dv = DoubleVector.new(10) +0.upto(9) { |i| dv[i] = i/2.0 } + +halve_in_place(dv) + diff --git a/Examples/test-suite/ruby/namespace_typemap_runme.rb b/Examples/test-suite/ruby/namespace_typemap_runme.rb new file mode 100755 index 000000000..6416d615a --- /dev/null +++ b/Examples/test-suite/ruby/namespace_typemap_runme.rb @@ -0,0 +1,33 @@ +require 'namespace_typemap' + +include Namespace_typemap + +raise RuntimeError if stest1("hello") != "hello" + +raise RuntimeError if stest2("hello") != "hello" + +raise RuntimeError if stest3("hello") != "hello" + +raise RuntimeError if stest4("hello") != "hello" + +raise RuntimeError if stest5("hello") != "hello" + +raise RuntimeError if stest6("hello") != "hello" + +raise RuntimeError if stest7("hello") != "hello" + +raise RuntimeError if stest8("hello") != "hello" + +raise RuntimeError if stest9("hello") != "hello" + +raise RuntimeError if stest10("hello") != "hello" + +raise RuntimeError if stest11("hello") != "hello" + +raise RuntimeError if stest12("hello") != "hello" + +begin + ttest1(-14) + raise RuntimeError +rescue RangeError +end diff --git a/Examples/test-suite/ruby/newobject1_runme.rb b/Examples/test-suite/ruby/newobject1_runme.rb new file mode 100644 index 000000000..35f77faa2 --- /dev/null +++ b/Examples/test-suite/ruby/newobject1_runme.rb @@ -0,0 +1,15 @@ +require 'newobject1' + +include Newobject1 + +foo1 = Foo.makeFoo +raise RuntimeError if Foo.fooCount != 1 + +foo2 = foo1.makeMore +raise RuntimeError if Foo.fooCount != 2 + +foo1 = nil ; GC.start +raise RuntimeError if Foo.fooCount != 1 + +foo2 = nil ; GC.start +raise RuntimeError if Foo.fooCount != 0 diff --git a/Examples/test-suite/ruby/newobject2_runme.rb b/Examples/test-suite/ruby/newobject2_runme.rb new file mode 100644 index 000000000..4519b123e --- /dev/null +++ b/Examples/test-suite/ruby/newobject2_runme.rb @@ -0,0 +1,15 @@ +require 'newobject2' + +include Newobject2 + +foo1 = makeFoo +raise RuntimeError if fooCount != 1 + +foo2 = makeFoo +raise RuntimeError if fooCount != 2 + +foo1 = nil ; GC.start +raise RuntimeError if fooCount != 1 + +foo2 = nil ; GC.start +raise RuntimeError if fooCount != 0 diff --git a/Examples/test-suite/ruby/overload_copy_runme.rb b/Examples/test-suite/ruby/overload_copy_runme.rb new file mode 100755 index 000000000..2c555a62b --- /dev/null +++ b/Examples/test-suite/ruby/overload_copy_runme.rb @@ -0,0 +1,6 @@ +require 'overload_copy' + +include Overload_copy + +f = Foo.new +g = Foo.new(f) diff --git a/Examples/test-suite/ruby/overload_extend_runme.rb b/Examples/test-suite/ruby/overload_extend_runme.rb new file mode 100755 index 000000000..2d252a62a --- /dev/null +++ b/Examples/test-suite/ruby/overload_extend_runme.rb @@ -0,0 +1,8 @@ +require 'overload_extend' + +f = Overload_extend::Foo.new + +raise RuntimeError if f.test(3) != 1 +raise RuntimeError if f.test("hello") != 2 +raise RuntimeError if f.test(3.5,2.5) != 3 + diff --git a/Examples/test-suite/ruby/overload_extendc_runme.rb b/Examples/test-suite/ruby/overload_extendc_runme.rb new file mode 100755 index 000000000..354062a5d --- /dev/null +++ b/Examples/test-suite/ruby/overload_extendc_runme.rb @@ -0,0 +1,7 @@ +require 'overload_extend' + +f = Overload_extend::Foo.new + +raise RuntimeError if f.test(3) != 1 +raise RuntimeError if f.test("hello") != 2 +raise RuntimeError if f.test(3.5,2.5) != 3 diff --git a/Examples/test-suite/ruby/overload_simple_runme.rb b/Examples/test-suite/ruby/overload_simple_runme.rb new file mode 100755 index 000000000..3fd292a76 --- /dev/null +++ b/Examples/test-suite/ruby/overload_simple_runme.rb @@ -0,0 +1,119 @@ +require 'overload_simple' + +include Overload_simple + +if foo(3) != "foo:int" + raise RuntimeError, "foo(int)" +end + +if foo(3.0) != "foo:double" + raise RuntimeError, "foo(double)" +end + +if foo("hello") != "foo:char *" + raise RuntimeError, "foo(char *)" +end + +f = Foo.new +b = Bar.new + +if foo(f) != "foo:Foo *" + raise RuntimeError, "foo(Foo *)" +end + +if foo(b) != "foo:Bar *" + raise RuntimeError, "foo(Bar *)" +end + +v = malloc_void(32) + +if foo(v) != "foo:void *" + raise RuntimeError, "foo(void *)" +end + +s = Spam.new + +if s.foo(3) != "foo:int" + raise RuntimeError, "Spam::foo(int)" +end + +if s.foo(3.0) != "foo:double" + raise RuntimeError, "Spam::foo(double)" +end + +if s.foo("hello") != "foo:char *" + raise RuntimeError, "Spam::foo(char *)" +end + +if s.foo(f) != "foo:Foo *" + raise RuntimeError, "Spam::foo(Foo *)" +end + +if s.foo(b) != "foo:Bar *" + raise RuntimeError, "Spam::foo(Bar *)" +end + +if s.foo(v) != "foo:void *" + raise RuntimeError, "Spam::foo(void *)" +end + +if Spam.bar(3) != "bar:int" + raise RuntimeError, "Spam::bar(int)" +end + +if Spam.bar(3.0) != "bar:double" + raise RuntimeError, "Spam::bar(double)" +end + +if Spam.bar("hello") != "bar:char *" + raise RuntimeError, "Spam::bar(char *)" +end + +if Spam.bar(f) != "bar:Foo *" + raise RuntimeError, "Spam::bar(Foo *)" +end + +if Spam.bar(b) != "bar:Bar *" + raise RuntimeError, "Spam::bar(Bar *)" +end + +if Spam.bar(v) != "bar:void *" + raise RuntimeError, "Spam::bar(void *)" +end + +# Test constructors + +s = Spam.new +if s.type != "none" + raise RuntimeError, "Spam()" +end + +s = Spam.new(3) +if s.type != "int" + raise RuntimeError, "Spam(int)" +end + +s = Spam.new(3.4) +if s.type != "double" + raise RuntimeError, "Spam(double)" +end + +s = Spam.new("hello") +if s.type != "char *" + raise RuntimeError, "Spam(char *)" +end + +s = Spam.new(f) +if s.type != "Foo *" + raise RuntimeError, "Spam(Foo *)" +end + +s = Spam.new(b) +if s.type != "Bar *" + raise RuntimeError, "Spam(Bar *)" +end + +s = Spam.new(v) +if s.type != "void *" + raise RuntimeError, "Spam(void *)" +end diff --git a/Examples/test-suite/ruby/overload_subtype_runme.rb b/Examples/test-suite/ruby/overload_subtype_runme.rb new file mode 100644 index 000000000..9737c851c --- /dev/null +++ b/Examples/test-suite/ruby/overload_subtype_runme.rb @@ -0,0 +1,15 @@ +require 'overload_subtype' + +include Overload_subtype + +f = Foo.new +b = Bar.new + +if spam(f) != 1 + raise RuntimeError, "foo" +end + +if spam(b) != 2 + raise RuntimeError, "bar" +end + diff --git a/Examples/test-suite/ruby/overload_template_runme.rb b/Examples/test-suite/ruby/overload_template_runme.rb new file mode 100755 index 000000000..d01887bf4 --- /dev/null +++ b/Examples/test-suite/ruby/overload_template_runme.rb @@ -0,0 +1,6 @@ +require 'overload_template' + +f = Overload_template.foo() + +a = Overload_template.max(3,4) +b = Overload_template.max(3.4,5.2) diff --git a/Examples/test-suite/ruby/primitive_ref_runme.rb b/Examples/test-suite/ruby/primitive_ref_runme.rb new file mode 100755 index 000000000..11bf37439 --- /dev/null +++ b/Examples/test-suite/ruby/primitive_ref_runme.rb @@ -0,0 +1,27 @@ +require 'primitive_ref' + +include Primitive_ref + +raise RuntimeError if ref_int(3) != 3 + +raise RuntimeError if ref_uint(3) != 3 + +raise RuntimeError if ref_short(3) != 3 + +raise RuntimeError if ref_ushort(3) != 3 + +raise RuntimeError if ref_long(3) != 3 + +raise RuntimeError if ref_ulong(3) != 3 + +raise RuntimeError if ref_schar(3) != 3 + +raise RuntimeError if ref_uchar(3) != 3 + +raise RuntimeError if ref_float(3.5) != 3.5 + +raise RuntimeError if ref_double(3.5) != 3.5 + +raise RuntimeError if ref_bool(true) != true + +raise RuntimeError if ref_char('x') != 'x' diff --git a/Examples/test-suite/ruby/rename_scope_runme.rb b/Examples/test-suite/ruby/rename_scope_runme.rb new file mode 100644 index 000000000..ea4fa94a6 --- /dev/null +++ b/Examples/test-suite/ruby/rename_scope_runme.rb @@ -0,0 +1,10 @@ +require 'rename_scope' + +include Rename_scope + +a = Natural_UP.new +b = Natural_BP.new + +raise RuntimeError if a.rtest() != 1 + +raise RuntimeError if b.rtest() != 1 diff --git a/Examples/test-suite/ruby/smart_pointer_const_runme.rb b/Examples/test-suite/ruby/smart_pointer_const_runme.rb new file mode 100644 index 000000000..cb852cfe0 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_const_runme.rb @@ -0,0 +1,13 @@ +require 'smart_pointer_const' + +include Smart_pointer_const + +f = Foo.new +b = Bar.new(f) + +b.x = 3 +raise RuntimeError if b.getx() != 3 + +fp = b.__deref__() +fp.x = 4 +raise RuntimeError if fp.getx() != 4 diff --git a/Examples/test-suite/ruby/smart_pointer_multi_runme.rb b/Examples/test-suite/ruby/smart_pointer_multi_runme.rb new file mode 100644 index 000000000..96b937a85 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_multi_runme.rb @@ -0,0 +1,15 @@ +require 'smart_pointer_multi' + +include Smart_pointer_multi + +f = Foo.new +b = Bar.new(f) +s = Spam.new(b) +g = Grok.new(b) + +s.x = 3 +raise RuntimeError if s.getx() != 3 + +g.x = 4 +raise RuntimeError if g.getx() != 4 + diff --git a/Examples/test-suite/ruby/smart_pointer_multi_typedef_runme.rb b/Examples/test-suite/ruby/smart_pointer_multi_typedef_runme.rb new file mode 100644 index 000000000..52ddb44f4 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_multi_typedef_runme.rb @@ -0,0 +1,14 @@ +require 'smart_pointer_multi_typedef' + +include Smart_pointer_multi_typedef + +f = Foo.new +b = Bar.new(f) +s = Spam.new(b) +g = Grok.new(b) + +s.x = 3 +raise RuntimeError if s.getx() != 3 + +g.x = 4 +raise RuntimeError if g.getx() != 4 diff --git a/Examples/test-suite/ruby/smart_pointer_not_runme.rb b/Examples/test-suite/ruby/smart_pointer_not_runme.rb new file mode 100644 index 000000000..fcc306115 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_not_runme.rb @@ -0,0 +1,44 @@ +require 'smart_pointer_not' + +include Smart_pointer_not + +f = Foo.new +b = Bar.new(f) +s = Spam.new(f) +g = Grok.new(f) + +begin + x = b.x + puts "Error! b.x" +rescue NameError +end + +begin + x = s.x + puts "Error! s.x" +rescue NameError +end + +begin + x = g.x + puts "Error! g.x" +rescue NameError +end + +begin + x = b.getx() + puts "Error! b.getx()" +rescue NameError +end + +begin + x = s.getx() + puts "Error! s.getx()" +rescue NameError +end + +begin + x = g.getx() + puts "Error! g.getx()" +rescue NameError +end diff --git a/Examples/test-suite/ruby/smart_pointer_overload_runme.rb b/Examples/test-suite/ruby/smart_pointer_overload_runme.rb new file mode 100644 index 000000000..c32991331 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_overload_runme.rb @@ -0,0 +1,16 @@ +require 'smart_pointer_overload' + +include Smart_pointer_overload + +f = Foo.new +b = Bar.new(f) + + +raise RuntimeError if f.test(3) != 1 +raise RuntimeError if f.test(3.5) != 2 +raise RuntimeError if f.test("hello") != 3 + +raise RuntimeError if b.test(3) != 1 +raise RuntimeError if b.test(3.5) != 2 +raise RuntimeError if b.test("hello") != 3 + diff --git a/Examples/test-suite/ruby/smart_pointer_rename_runme.rb b/Examples/test-suite/ruby/smart_pointer_rename_runme.rb new file mode 100644 index 000000000..0ff378a4c --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_rename_runme.rb @@ -0,0 +1,12 @@ +require 'smart_pointer_rename' + +include Smart_pointer_rename + +f = Foo.new +b = Bar.new(f) + +raise RuntimeError if b.test() != 3 + +raise RuntimeError if b.ftest1(1) != 1 + +raise RuntimeError if b.ftest2(2,3) != 2 diff --git a/Examples/test-suite/ruby/smart_pointer_simple_runme.rb b/Examples/test-suite/ruby/smart_pointer_simple_runme.rb new file mode 100644 index 000000000..b2a54b819 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_simple_runme.rb @@ -0,0 +1,13 @@ +require 'smart_pointer_simple' + +include Smart_pointer_simple + +f = Foo.new +b = Bar.new(f) + +b.x = 3 +raise RuntimeError if b.getx() != 3 + +fp = b.__deref__() +fp.x = 4 +raise RuntimeError if fp.getx() != 4 diff --git a/Examples/test-suite/ruby/smart_pointer_typedef_runme.rb b/Examples/test-suite/ruby/smart_pointer_typedef_runme.rb new file mode 100644 index 000000000..137723078 --- /dev/null +++ b/Examples/test-suite/ruby/smart_pointer_typedef_runme.rb @@ -0,0 +1,13 @@ +require 'smart_pointer_typedef' + +include Smart_pointer_typedef + +f = Foo.new +b = Bar.new(f) + +b.x = 3 +raise RuntimeError if b.getx() != 3 + +fp = b.__deref__() +fp.x = 4 +raise RuntimeError if fp.getx() != 4 diff --git a/Examples/test-suite/ruby/sneaky1_runme.rb b/Examples/test-suite/ruby/sneaky1_runme.rb new file mode 100755 index 000000000..731e27b97 --- /dev/null +++ b/Examples/test-suite/ruby/sneaky1_runme.rb @@ -0,0 +1,6 @@ +require 'sneaky1' + +x = Sneaky1.add(3, 4) +y = Sneaky1.sub(3, 4) +z = Sneaky1.mul(3, 4) +w = Sneaky1.divide(3, 4) diff --git a/Examples/test-suite/ruby/template_inherit_runme.rb b/Examples/test-suite/ruby/template_inherit_runme.rb new file mode 100755 index 000000000..e2c947495 --- /dev/null +++ b/Examples/test-suite/ruby/template_inherit_runme.rb @@ -0,0 +1,40 @@ +require 'template_inherit' + +include Template_inherit + +a = FooInt.new +b = FooDouble.new +c = BarInt.new +d = BarDouble.new +e = FooUInt.new +f = BarUInt.new + +raise ValueError if a.blah() != "Foo" + +raise ValueError if b.blah() != "Foo" + +raise ValueError if e.blah() != "Foo" + +raise ValueError if c.blah() != "Bar" + +raise ValueError if d.blah() != "Bar" + +raise ValueError if f.blah() != "Bar" + +raise ValueError if c.foomethod() != "foomethod" + +raise ValueError if d.foomethod() != "foomethod" + +raise ValueError if f.foomethod() != "foomethod" + +raise ValueError if invoke_blah_int(a) != "Foo" + +raise ValueError if invoke_blah_int(c) != "Bar" + +raise ValueError if invoke_blah_double(b) != "Foo" + +raise ValueError if invoke_blah_double(d) != "Bar" + +raise ValueError if invoke_blah_uint(e) != "Foo" + +raise ValueError if invoke_blah_uint(f) != "Bar" diff --git a/Examples/test-suite/ruby/template_ns4_runme.rb b/Examples/test-suite/ruby/template_ns4_runme.rb new file mode 100755 index 000000000..5c55ff94f --- /dev/null +++ b/Examples/test-suite/ruby/template_ns4_runme.rb @@ -0,0 +1,4 @@ +require 'template_ns4' + +d = Template_ns4.make_Class_DD() +raise RuntimeError if d.test() != "test" diff --git a/Examples/test-suite/ruby/template_ns_runme.rb b/Examples/test-suite/ruby/template_ns_runme.rb new file mode 100755 index 000000000..d69e8e3d4 --- /dev/null +++ b/Examples/test-suite/ruby/template_ns_runme.rb @@ -0,0 +1,15 @@ +require 'template_ns' + +include Template_ns + +p1 = Pairii.new(2, 3) +p2 = Pairii.new(p1) + +raise RuntimeError if p2.first != 2 +raise RuntimeError if p2.second != 3 + +p3 = Pairdd.new(3.5, 2.5) +p4 = Pairdd.new(p3) + +raise RuntimeError if p4.first != 3.5 +raise RuntimeError if p4.second != 2.5 diff --git a/Examples/test-suite/ruby/template_rename_runme.rb b/Examples/test-suite/ruby/template_rename_runme.rb new file mode 100755 index 000000000..04be6c94d --- /dev/null +++ b/Examples/test-suite/ruby/template_rename_runme.rb @@ -0,0 +1,12 @@ +require 'template_rename' + +i = Template_rename::IFoo.new +d = Template_rename::DFoo.new + +a = i.blah_test(4) +b = i.spam_test(5) +c = i.grok_test(6) + +x = d.blah_test(7) +y = d.spam(8) +z = d.grok_test(9) diff --git a/Examples/test-suite/ruby/typedef_inherit_runme.rb b/Examples/test-suite/ruby/typedef_inherit_runme.rb new file mode 100755 index 000000000..591b9efdb --- /dev/null +++ b/Examples/test-suite/ruby/typedef_inherit_runme.rb @@ -0,0 +1,27 @@ +require 'typedef_inherit' + +a = Typedef_inherit::Foo.new +b = Typedef_inherit::Bar.new + +x = Typedef_inherit.do_blah(a) +if x != "Foo::blah" + puts "Whoa! Bad return #{x}" +end + +x = Typedef_inherit.do_blah(b) +if x != "Bar::blah" + puts "Whoa! Bad return #{x}" +end + +c = Typedef_inherit::Spam.new +d = Typedef_inherit::Grok.new + +x = Typedef_inherit.do_blah2(c) +if x != "Spam::blah" + puts "Whoa! Bad return #{x}" +end + +x = Typedef_inherit.do_blah2(d) +if x != "Grok::blah" + puts "Whoa! Bad return #{x}" +end diff --git a/Examples/test-suite/ruby/typedef_scope_runme.rb b/Examples/test-suite/ruby/typedef_scope_runme.rb new file mode 100755 index 000000000..db7a9f2c9 --- /dev/null +++ b/Examples/test-suite/ruby/typedef_scope_runme.rb @@ -0,0 +1,13 @@ +require 'typedef_scope' + +b = Typedef_scope::Bar.new + +x = b.test1(42, "hello") +if x != 42 + puts "Failed!!" +end + +x = b.test2(42, "hello") +if x != "hello" + puts "Failed!!" +end diff --git a/Examples/test-suite/ruby/typemap_namespace_runme.rb b/Examples/test-suite/ruby/typemap_namespace_runme.rb new file mode 100755 index 000000000..57986348d --- /dev/null +++ b/Examples/test-suite/ruby/typemap_namespace_runme.rb @@ -0,0 +1,7 @@ +require 'typemap_namespace' + +include Typemap_namespace + +raise RuntimeError if test1("hello") != "hello" + +raise RuntimeError if test2("hello") != "hello" diff --git a/Examples/test-suite/ruby/typename_runme.rb b/Examples/test-suite/ruby/typename_runme.rb new file mode 100755 index 000000000..689499f12 --- /dev/null +++ b/Examples/test-suite/ruby/typename_runme.rb @@ -0,0 +1,14 @@ +require 'typename' + +f = Typename::Foo.new +b = Typename::Bar.new + +x = Typename.twoFoo(f) +unless x.is_a? Float + puts "Wrong return type!" +end + +y = Typename.twoBar(b) +unless y.is_a? Integer + puts "Wrong return type!" +end diff --git a/Examples/test-suite/ruby/unions_runme.rb b/Examples/test-suite/ruby/unions_runme.rb new file mode 100644 index 000000000..17344f7e5 --- /dev/null +++ b/Examples/test-suite/ruby/unions_runme.rb @@ -0,0 +1,54 @@ + +# This is the union runtime testcase. It ensures that values within a +# union embedded within a struct can be set and read correctly. + +require 'unions' + +# Create new instances of SmallStruct and BigStruct for later use +small = Unions::SmallStruct.new() +small.jill = 200 + +big = Unions::BigStruct.new() +big.smallstruct = small +big.jack = 300 + +# Use SmallStruct then BigStruct to setup EmbeddedUnionTest. +# Ensure values in EmbeddedUnionTest are set correctly for each. +eut = Unions::EmbeddedUnionTest.new() + +# First check the SmallStruct in EmbeddedUnionTest +eut.number = 1 +eut.uni.small = small +Jill1 = eut.uni.small.jill +if (Jill1 != 200) + print "Runtime test1 failed. eut.uni.small.jill=" , Jill1 , "\n" + exit 1 +end + +Num1 = eut.number +if (Num1 != 1) + print "Runtime test2 failed. eut.number=" , Num1 , "\n" + exit 1 +end + +# Secondly check the BigStruct in EmbeddedUnionTest +eut.number = 2 +eut.uni.big = big +Jack1 = eut.uni.big.jack +if (Jack1 != 300) + print "Runtime test3 failed. eut.uni.big.jack=" , Jack1 , "\n" + exit 1 +end + +Jill2 = eut.uni.big.smallstruct.jill +if (Jill2 != 200) + print "Runtime test4 failed. eut.uni.big.smallstruct.jill=" , Jill2 , "\n" + exit 1 +end + +Num2 = eut.number +if (Num2 != 2) + print "Runtime test5 failed. eut.number=" , Num2 , "\n" + exit 1 +end + diff --git a/Examples/test-suite/sizeof_pointer.i b/Examples/test-suite/sizeof_pointer.i new file mode 100644 index 000000000..993ba4de5 --- /dev/null +++ b/Examples/test-suite/sizeof_pointer.i @@ -0,0 +1,19 @@ +/* +This testcase tests whether the sizeof operator on a pointer is working. +*/ + +%module sizeof_pointer + +%inline %{ + +#define NO_PROBLEM sizeof(char) +#define STAR_PROBLEM sizeof(char*) +#define STAR_STAR_PROBLEM sizeof(char**) + +typedef struct SizeofPointerTest { + unsigned char array1[NO_PROBLEM]; + unsigned char array2[STAR_PROBLEM]; + unsigned char array3[STAR_STAR_PROBLEM]; +} SizeofPointerTest; + +%} diff --git a/Examples/test-suite/smart_pointer_const.i b/Examples/test-suite/smart_pointer_const.i new file mode 100644 index 000000000..3100a021e --- /dev/null +++ b/Examples/test-suite/smart_pointer_const.i @@ -0,0 +1,19 @@ +%module smart_pointer_const + +%inline %{ +struct Foo { + int x; + int getx() const { return x; } +}; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + Foo *operator->() { + return f; + } +}; +%} + + diff --git a/Examples/test-suite/smart_pointer_multi.i b/Examples/test-suite/smart_pointer_multi.i new file mode 100644 index 000000000..4b0aa0e4b --- /dev/null +++ b/Examples/test-suite/smart_pointer_multi.i @@ -0,0 +1,39 @@ +// Test cases for classes that do *NOT* result in smart-pointer wrapping +%module smart_pointer_multi + +%inline %{ +struct Foo { + int x; + int getx() { return x; } +}; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + Foo *operator->() { + return f; + } +}; + +class Spam { + Bar *b; +public: + Spam(Bar *b) : b(b) { } + Bar operator->() { + return *b; + } +}; + +class Grok { + Bar *b; +public: + Grok(Bar *b) : b(b) { } + Bar &operator->() { + return *b; + } +}; + +%} + + diff --git a/Examples/test-suite/smart_pointer_multi_typedef.i b/Examples/test-suite/smart_pointer_multi_typedef.i new file mode 100644 index 000000000..ed32b703a --- /dev/null +++ b/Examples/test-suite/smart_pointer_multi_typedef.i @@ -0,0 +1,45 @@ +// Test cases for classes that do *NOT* result in smart-pointer wrapping +%module smart_pointer_multi_typedef + +%inline %{ +struct Foo { + int x; + int getx() { return x; } +}; + +typedef Foo FooObj; +typedef FooObj *FooPtr; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + FooPtr operator->() { + return f; + } +}; + +typedef Bar BarObj; +typedef Bar &BarRef; + +class Spam { + Bar *b; +public: + Spam(Bar *b) : b(b) { } + BarObj operator->() { + return *b; + } +}; + +class Grok { + Bar *b; +public: + Grok(Bar *b) : b(b) { } + BarRef operator->() { + return *b; + } +}; + +%} + + diff --git a/Examples/test-suite/smart_pointer_not.i b/Examples/test-suite/smart_pointer_not.i new file mode 100644 index 000000000..712aa48fb --- /dev/null +++ b/Examples/test-suite/smart_pointer_not.i @@ -0,0 +1,39 @@ +// Test cases for classes that do *NOT* result in smart-pointer wrapping +%module smart_pointer_not + +%inline %{ +struct Foo { + int x; + int getx() { return x; } +}; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + Foo operator->() { + return *f; + } +}; + +class Spam { + Foo *f; +public: + Spam(Foo *f) : f(f) { } + Foo &operator->() { + return *f; + } +}; + +class Grok { + Foo *f; +public: + Grok(Foo *f) : f(f) { } + Foo **operator->() { + return &f; + } +}; + +%} + + diff --git a/Examples/test-suite/smart_pointer_overload.i b/Examples/test-suite/smart_pointer_overload.i new file mode 100644 index 000000000..ffc2097be --- /dev/null +++ b/Examples/test-suite/smart_pointer_overload.i @@ -0,0 +1,24 @@ +%module smart_pointer_overload + +#ifndef SWIG_NO_OVERLOAD + +%inline %{ +struct Foo { + int x; + int test(int x) { x = 0; return 1; } + int test(double x) { x = 0; return 2; } + int test(char *s) { s = 0; return 3; } +}; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + Foo *operator->() { + return f; + } +}; +%} + +#endif + diff --git a/Examples/test-suite/smart_pointer_protected.i b/Examples/test-suite/smart_pointer_protected.i new file mode 100644 index 000000000..8f33d9484 --- /dev/null +++ b/Examples/test-suite/smart_pointer_protected.i @@ -0,0 +1,29 @@ +%module smart_pointer_protected + +%inline %{ + + namespace hi + { + struct A + { + virtual int value(A*) = 0; + }; + + struct B : A + { + protected: + int value(A*) + { + return 1; + } + }; + + struct C + { + hi::B* operator->() const { return new hi::B(); } + }; + } + + +%} + diff --git a/Examples/test-suite/smart_pointer_rename.i b/Examples/test-suite/smart_pointer_rename.i new file mode 100644 index 000000000..b137ffe71 --- /dev/null +++ b/Examples/test-suite/smart_pointer_rename.i @@ -0,0 +1,25 @@ +%module smart_pointer_rename + +%rename(ftest1) Foo::test(int); +%rename(ftest2) Foo::test(int,int); + +%inline %{ + +class Foo { +public: + int test(int) { return 1; } + int test(int,int) { return 2; } +}; + +class Bar { + Foo *f; +public: + Bar(Foo *_f) : f(_f) { } + Foo *operator->() { return f; } + int test() { return 3; } +}; + +%} + + + diff --git a/Examples/test-suite/smart_pointer_simple.i b/Examples/test-suite/smart_pointer_simple.i new file mode 100644 index 000000000..ceb499c41 --- /dev/null +++ b/Examples/test-suite/smart_pointer_simple.i @@ -0,0 +1,19 @@ +%module smart_pointer_simple + +%inline %{ +struct Foo { + int x; + int getx() { return x; } +}; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + Foo *operator->() { + return f; + } +}; +%} + + diff --git a/Examples/test-suite/smart_pointer_typedef.i b/Examples/test-suite/smart_pointer_typedef.i new file mode 100644 index 000000000..d4e874f5c --- /dev/null +++ b/Examples/test-suite/smart_pointer_typedef.i @@ -0,0 +1,21 @@ +%module smart_pointer_typedef + +%inline %{ +struct Foo { + int x; + int getx() { return x; } +}; + +typedef Foo *FooPtr; + +class Bar { + Foo *f; +public: + Bar(Foo *f) : f(f) { } + FooPtr operator->() { + return f; + } +}; +%} + + diff --git a/Examples/test-suite/sneaky1.i b/Examples/test-suite/sneaky1.i new file mode 100644 index 000000000..bacf4a978 --- /dev/null +++ b/Examples/test-suite/sneaky1.i @@ -0,0 +1,29 @@ +%module sneaky1 + +%{ +int add(int x, int y) { + return x+y; +} + +int sub(int x, int y) { + return x-y; +} +int mul(int x, int y) { + return x*y; +} + +int divide(int x, int y) { + return x/y; +} +%} + +%inline %{ +typedef int binop(int,int); +%} + +binop add,sub,mul,divide; + + + + + diff --git a/Examples/test-suite/static_array_member.i b/Examples/test-suite/static_array_member.i new file mode 100644 index 000000000..8a7cfefae --- /dev/null +++ b/Examples/test-suite/static_array_member.i @@ -0,0 +1,12 @@ +/* This interface file checks whether the SWIG parser handles static + array members of classes. Bug reported by Annalisa Terracina + on 2001-07-03. +*/ + +%module static_array_member + +%pragma no_default +class RB { + static char *rberror[]; +}; + diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i new file mode 100644 index 000000000..99dc89bd1 --- /dev/null +++ b/Examples/test-suite/static_const_member.i @@ -0,0 +1,17 @@ +/* Swig 1.3.6 does not understand initialization of static class + constants like this. SF Bug #445221, reported by Krzysztof + Kozminski . +*/ + +%module static_const_member + +%inline %{ + +class X { +public: + static const int PN = 0; + static const int CN = 1; + static const int EN = 2; +}; + +%} diff --git a/Examples/test-suite/static_const_member_2.i b/Examples/test-suite/static_const_member_2.i new file mode 100644 index 000000000..3bd08b820 --- /dev/null +++ b/Examples/test-suite/static_const_member_2.i @@ -0,0 +1,53 @@ +%module static_const_member_2 + +%warnfilter(801) oss::modules::CavityPackFlags::forward_field; +%warnfilter(801) oss::modules::CavityPackFlags::backward_field; +%warnfilter(801) oss::modules::Test::current_profile; + +%inline %{ + namespace oss + { + namespace modules + { + struct CavityPackFlags + { + typedef unsigned int viewflags; + static const viewflags forward_field = 1 << 0; + static const viewflags backward_field = 1 << 1; + static const viewflags cavity_flags; + static viewflags flags; + static const int &reftest; + }; + + template + struct Test : CavityPackFlags + { + enum {LeftIndex, RightIndex}; + static const viewflags current_profile = 1 << 2; + }; + } + } + +%} + +%{ + +int refvalue = 42; +const int &oss::modules::CavityPackFlags::reftest = refvalue; + +%} + +%{ + using oss::modules::CavityPackFlags; + + const CavityPackFlags::viewflags + CavityPackFlags::cavity_flags = + CavityPackFlags::forward_field | CavityPackFlags::backward_field; + + CavityPackFlags::viewflags + CavityPackFlags::flags = 0; + +%} + +%template(Test_int) oss::modules::Test; + diff --git a/Examples/test-suite/struct_value.i b/Examples/test-suite/struct_value.i new file mode 100644 index 000000000..bf944e2c5 --- /dev/null +++ b/Examples/test-suite/struct_value.i @@ -0,0 +1,14 @@ +%module struct_value + +%inline %{ + +struct Foo { + int x; +}; + +struct Bar { + Foo a; + struct Foo b; +}; + +%} diff --git a/Examples/test-suite/sym.i b/Examples/test-suite/sym.i new file mode 100644 index 000000000..83226cbaa --- /dev/null +++ b/Examples/test-suite/sym.i @@ -0,0 +1,24 @@ +%module sym +// make sure different classes are allowed to have methods of the same name +// that we properly qualify wrappers in the C namespace to avoid collisions + +%rename(hulahoops) Flim::Jam(); + +%inline %{ + +class Flim { +public: + Flim() { } + const char * Jam() { return "flim-jam"; } + const char * Jar() { return "flim-jar"; } +}; + +class Flam { +public: + Flam() { } + const char * Jam() { return "flam-jam"; } + const char * Jar() { return "flam-jar"; } +}; + +%} + diff --git a/Examples/test-suite/tcl/.cvsignore b/Examples/test-suite/tcl/.cvsignore new file mode 100644 index 000000000..09e0b6c2e --- /dev/null +++ b/Examples/test-suite/tcl/.cvsignore @@ -0,0 +1,3 @@ +*wrap* +*.so +*.dll diff --git a/Examples/test-suite/tcl/Makefile b/Examples/test-suite/tcl/Makefile new file mode 100644 index 000000000..4e54379e0 --- /dev/null +++ b/Examples/test-suite/tcl/Makefile @@ -0,0 +1,41 @@ +####################################################################### +# $Header$ +# Makefile for tcl test-suite +####################################################################### + +LANGUAGE = tcl +SCRIPTSUFFIX = _runme.tcl + +include ../common.mk + +# Overridden variables here + +# Rules for the different types of tests +%.cpptest: + $(setup) \ + ($(swig_and_compile_cpp); ); \ + $(run_testcase) + +%.ctest: + $(setup) \ + ($(swig_and_compile_c); ); \ + $(run_testcase) + +%.multicpptest: + $(setup) \ + ($(swig_and_compile_multi_cpp); ); \ + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.tcl appended after the testcase name. +run_testcase = \ + if [ -f $*\_runme.tcl ]; then ( \ + env LD_LIBRARY_PATH=$(DYNAMIC_LIB_PATH):$$LD_LIBRARY_PATH tclsh $*\_runme.tcl;) \ + fi; + +# Clean +%.clean: + + +clean: + $(MAKE) -f $(TOP)/Makefile tcl_clean diff --git a/Examples/test-suite/tcl/README b/Examples/test-suite/tcl/README new file mode 100644 index 000000000..c36c3aa9a --- /dev/null +++ b/Examples/test-suite/tcl/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.tcl appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/tcl/import_nomodule_runme.tcl b/Examples/test-suite/tcl/import_nomodule_runme.tcl new file mode 100644 index 000000000..f53429b55 --- /dev/null +++ b/Examples/test-suite/tcl/import_nomodule_runme.tcl @@ -0,0 +1,10 @@ + +if { [ string match $tcl_platform(platform) "windows" ] == 1 } { + if [ catch { load ./import_nomodule.dll import_nomodule} err_msg ] { + puts stderr "Could not load dll:\n$err_msg" + } +} else { + if [ catch { load ./import_nomodule.so import_nomodule} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + } +} diff --git a/Examples/test-suite/tcl/imports_runme.tcl b/Examples/test-suite/tcl/imports_runme.tcl new file mode 100644 index 000000000..c20cbad84 --- /dev/null +++ b/Examples/test-suite/tcl/imports_runme.tcl @@ -0,0 +1,26 @@ + +# This is the imports runtime testcase. + +if { [ string match $tcl_platform(os) Windows* ] == 1 } { + if [ catch { load ./imports_a.dll imports_a} err_msg ] { ;# Windows + puts stderr "Could not load dll:\n$err_msg" + exit 1 + } + if [ catch { load ./imports_b.dll imports_b} err_msg ] { ;# Windows + puts stderr "Could not load dll:\n$err_msg" + exit 1 + } +} else { + if [ catch { load ./imports_a.so imports_a} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + exit 1 + } + if [ catch { load ./imports_b.so imports_b} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + exit 1 + } +} + +set x [new_B] +A_hello $x + diff --git a/Examples/test-suite/tcl/overload_copy_runme.tcl b/Examples/test-suite/tcl/overload_copy_runme.tcl new file mode 100644 index 000000000..32b62f2a9 --- /dev/null +++ b/Examples/test-suite/tcl/overload_copy_runme.tcl @@ -0,0 +1,18 @@ + +if { [ string match $tcl_platform(platform) "windows" ] == 1 } { + if [ catch { load ./overload_copy.dll overload_copy} err_msg ] { + puts stderr "Could not load dll:\n$err_msg" + } +} else { + if [ catch { load ./overload_copy.so overload_copy} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + } +} + +Foo f +Foo g [f cget -this] + + + + + diff --git a/Examples/test-suite/tcl/overload_simple_runme.tcl b/Examples/test-suite/tcl/overload_simple_runme.tcl new file mode 100644 index 000000000..b8fa63553 --- /dev/null +++ b/Examples/test-suite/tcl/overload_simple_runme.tcl @@ -0,0 +1,172 @@ + +if { [ string match $tcl_platform(platform) "windows" ] == 1 } { + if [ catch { load ./overload_simple.dll overload_simple} err_msg ] { + puts stderr "Could not load dll:\n$err_msg" + } +} else { + if [ catch { load ./overload_simple.so overload_simple} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + } +} + +set f [new_Foo] +set b [new_Bar] +set v [malloc_void 32] + +set x [foo 3] +if {$x != "foo:int"} { + puts stderr "foo(int) test failed" + exit 1 +} + +set x [foo 3.4] +if {$x != "foo:double"} { + puts stderr "foo(double) test failed" + exit 1 +} + +set x [foo hello] +if {$x != "foo:char *"} { + puts stderr "foo(char *) test failed" + exit 1 +} + +set x [foo $f] +if {$x != "foo:Foo *"} { + puts stderr "foo(Foo *) test failed" + exit 1 +} + +set x [foo $b] +if {$x != "foo:Bar *"} { + puts stderr "foo(Bar *) test failed" + exit 1 +} + +set x [foo $v] +if {$x != "foo:void *"} { + puts stderr "foo(void *) test failed" + exit 1 +} + +Spam s + +set x [s foo 3] +if {$x != "foo:int"} { + puts stderr "Spam::foo(int) test failed" + exit 1 +} + +set x [s foo 3.4] +if {$x != "foo:double"} { + puts stderr "Spam::foo(double) test failed" + exit 1 +} + +set x [s foo hello] +if {$x != "foo:char *"} { + puts stderr "Spam::foo(char *) test failed" + exit 1 +} + +set x [s foo $f] +if {$x != "foo:Foo *"} { + puts stderr "Spam::foo(Foo *) test failed" + exit 1 +} + +set x [s foo $b] +if {$x != "foo:Bar *"} { + puts stderr "Spam::foo(Bar *) test failed" + exit 1 +} + +set x [s foo $v] +if {$x != "foo:void *"} { + puts stderr "Spam::foo(void *) test failed" + exit 1 +} + + +set x [Spam_bar 3] +if {$x != "bar:int"} { + puts stderr "Spam::bar(int) test failed" + exit 1 +} + +set x [Spam_bar 3.4] +if {$x != "bar:double"} { + puts stderr "Spam::bar(double) test failed" + exit 1 +} + +set x [Spam_bar hello] +if {$x != "bar:char *"} { + puts stderr "Spam::bar(char *) test failed" + exit 1 +} + +set x [Spam_bar $f] +if {$x != "bar:Foo *"} { + puts stderr "Spam::bar(Foo *) test failed" + exit 1 +} + +set x [Spam_bar $b] +if {$x != "bar:Bar *"} { + puts stderr "Spam::bar(Bar *) test failed" + exit 1 +} + +set x [Spam_bar $v] +if {$x != "bar:void *"} { + puts stderr "Spam::bar(void *) test failed" + exit 1 +} + +Spam s +set x [s cget -type] +if {$x != "none"} { + puts stderr "Spam() test failed" +} + +Spam s 3 +set x [s cget -type] +if {$x != "int"} { + puts stderr "Spam(int) test failed" +} + +Spam s 3.4 +set x [s cget -type] +if {$x != "double"} { + puts stderr "Spam(double) test failed" +} + +Spam s hello +set x [s cget -type] +if {$x != "char *"} { + puts stderr "Spam(char *) test failed" +} + +Spam s $f +set x [s cget -type] +if {$x != "Foo *"} { + puts stderr "Spam(Foo *) test failed" +} + +Spam s $b +set x [s cget -type] +if {$x != "Bar *"} { + puts stderr "Spam(Bar *) test failed" +} + +Spam s $v +set x [s cget -type] +if {$x != "void *"} { + puts stderr "Spam(void *) test failed" +} + + + + + diff --git a/Examples/test-suite/tcl/primitive_ref_runme.tcl b/Examples/test-suite/tcl/primitive_ref_runme.tcl new file mode 100644 index 000000000..b4de97fd1 --- /dev/null +++ b/Examples/test-suite/tcl/primitive_ref_runme.tcl @@ -0,0 +1,25 @@ +# Primitive ref testcase. Tests to make sure references to +# primitive types are passed by value + +if { [ string match $tcl_platform(platform) "windows" ] == 1 } { + if [ catch { load ./primitive_ref.dll primitive_ref} err_msg ] { + puts stderr "Could not load dll:\n$err_msg" + } +} else { + if [ catch { load ./primitive_ref.so primitive_ref} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + } +} + +if { [ref_int 3] != 3 } { puts stderr "ref_int failed" } +if { [ref_uint 3] != 3 } { puts stderr "ref_uint failed" } +if { [ref_short 3] != 3 } { puts stderr "ref_short failed" } +if { [ref_ushort 3] != 3 } { puts stderr "ref_ushort failed" } +if { [ref_long 3] != 3 } { puts stderr "ref_long failed" } +if { [ref_ulong 3] != 3 } { puts stderr "ref_ulong failed" } +if { [ref_schar 3] != 3 } { puts stderr "ref_schar failed" } +if { [ref_uchar 3] != 3 } { puts stderr "ref_uchar failed" } +if { [ref_float 3.5] != 3.5 } { puts stderr "ref_float failed" } +if { [ref_double 3.5] != 3.5 } { puts stderr "ref_double failed" } +if { [ref_char x] != "x" } { puts stderr "ref_char failed" } + diff --git a/Examples/test-suite/tcl/unions_runme.tcl b/Examples/test-suite/tcl/unions_runme.tcl new file mode 100644 index 000000000..7238698f5 --- /dev/null +++ b/Examples/test-suite/tcl/unions_runme.tcl @@ -0,0 +1,69 @@ + +# This is the union runtime testcase. It ensures that values within a +# union embedded within a struct can be set and read correctly. + +if { [ string match $tcl_platform(platform) "windows" ] == 1 } { + if [ catch { load ./unions.dll unions} err_msg ] { + puts stderr "Could not load dll:\n$err_msg" + } +} else { + if [ catch { load ./unions.so unions} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" + } +} + +# Create new instances of SmallStruct and BigStruct for later use +SmallStruct small +small configure -jill 200 + +BigStruct big +big configure -smallstruct [small cget -this] +big configure -jack 300 + +# Use SmallStruct then BigStruct to setup EmbeddedUnionTest. +# Ensure values in EmbeddedUnionTest are set correctly for each. +EmbeddedUnionTest eut + +# First check the SmallStruct in EmbeddedUnionTest +eut configure -number 1 + +#eut.uni.small = small +EmbeddedUnionTest_uni_small_set [EmbeddedUnionTest_uni_get [eut cget -this] ] [small cget -this] + +#Jill1 = eut.uni.small.jill +set Jill1 [SmallStruct_jill_get [EmbeddedUnionTest_uni_small_get [EmbeddedUnionTest_uni_get [eut cget -this] ] ] ] +if {$Jill1 != 200} { + puts stderr "Runtime test1 failed. eut.uni.small.jill=$Jill1" + exit 1 +} + +set Num1 [eut cget -number] +if {$Num1 != 1} { + puts stderr "Runtime test2 failed. eut.number=$Num1" + exit 1 +} + +# Secondly check the BigStruct in EmbeddedUnionTest +eut configure -number 2 +#eut.uni.big = big +EmbeddedUnionTest_uni_big_set [EmbeddedUnionTest_uni_get [eut cget -this] ] [big cget -this] +#Jack1 = eut.uni.big.jack +set Jack1 [BigStruct_jack_get [EmbeddedUnionTest_uni_big_get [EmbeddedUnionTest_uni_get [eut cget -this] ] ] ] +if {$Jack1 != 300} { + puts stderr "Runtime test3 failed. eut.uni.big.jack=$Jack1" + exit 1 +} + +#Jill2 = eut.uni.big.smallstruct.jill +set Jill2 [SmallStruct_jill_get [BigStruct_smallstruct_get [EmbeddedUnionTest_uni_big_get [EmbeddedUnionTest_uni_get [eut cget -this] ] ] ] ] +if {$Jill2 != 200} { + puts stderr "Runtime test4 failed. eut.uni.big.smallstruct.jill=$Jill2" + exit 1 +} + +set Num2 [eut cget -number] +if {$Num2 != 2} { + puts stderr "Runtime test5 failed. eut.number=$Num2" + exit 1 +} + diff --git a/Examples/test-suite/template.i b/Examples/test-suite/template.i new file mode 100644 index 000000000..68a9aadd1 --- /dev/null +++ b/Examples/test-suite/template.i @@ -0,0 +1,46 @@ +/* File : example.i */ +%module "template" + +%warnfilter(801) vector; /* Ruby, wrong class name */ +%warnfilter(801) vector; /* Ruby, wrong class name */ +%warnfilter(801) vector; /* Ruby, wrong class name */ + +/* Let's just grab the original header file here */ + +%inline %{ + +template T max(const T a, const T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } + // This really doesn't do anything except test const handling + void testconst(const T x) { } +}; + +%} + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + +/* Now try to break constness */ + +%template(maxintp) max; +%template(vecintp) vector; + + diff --git a/Examples/test-suite/template_arg_scope.i b/Examples/test-suite/template_arg_scope.i new file mode 100644 index 000000000..36b593c3d --- /dev/null +++ b/Examples/test-suite/template_arg_scope.i @@ -0,0 +1,16 @@ +%module template_arg_scope +%inline %{ + +template class Foo { +}; + +class Bar { +public: + Bar(); + void spam(Foo *x); +}; +Bar::Bar() {} +void Bar::spam(Foo *x) {} + +%} + diff --git a/Examples/test-suite/template_arg_typename.i b/Examples/test-suite/template_arg_typename.i new file mode 100644 index 000000000..0f4c88793 --- /dev/null +++ b/Examples/test-suite/template_arg_typename.i @@ -0,0 +1,26 @@ +%module template_arg_typename + +%inline %{ + + + template + struct UnaryFunction + { + typedef void* vptr_type; + }; + + template + struct BoolUnaryFunction : UnaryFunction + + { + typedef UnaryFunction base; + BoolUnaryFunction(const typename base::vptr_type* vptrf) {} + + }; + + +%} + + +%template(UnaryFunction_bool_bool) UnaryFunction; +%template(BoolUnaryFunction_bool) BoolUnaryFunction; diff --git a/Examples/test-suite/template_base_template.i b/Examples/test-suite/template_base_template.i new file mode 100644 index 000000000..846240fc8 --- /dev/null +++ b/Examples/test-suite/template_base_template.i @@ -0,0 +1,35 @@ +%module template_base_template + +%warnfilter(801) traits; /* Ruby, wrong class name */ + +%inline %{ + template + struct traits + { + typedef ArgType arg_type; + typedef ResType res_type; + }; + + template + struct Function + { + }; + + // Egad! + template + struct Class + : Function::arg_type, + typename traits::res_type> + { + }; + +%} + +%template(traits_dd) traits ; +%template(Function_dd) Function ; +%template(Class_dd) Class ; + + + + + diff --git a/Examples/test-suite/template_classes.i b/Examples/test-suite/template_classes.i new file mode 100644 index 000000000..346fc0d23 --- /dev/null +++ b/Examples/test-suite/template_classes.i @@ -0,0 +1,30 @@ +/* File : template_classes.i */ +/* Tests the use of one templated class within another */ + +%module template_classes + +%inline %{ + +template +class Point { +public: + T getX() {return x;} +private: + T x; +}; + +template +class Rectangle { +public: + Point& getPoint() {return point;} + void setPoint(Point& value) {point = value;} +private: + Point point; +}; + +%} + +%template(PointInt) Point; +%template(RectangleInt) Rectangle; + + diff --git a/Examples/test-suite/template_const_ref.i b/Examples/test-suite/template_const_ref.i new file mode 100644 index 000000000..196ca9005 --- /dev/null +++ b/Examples/test-suite/template_const_ref.i @@ -0,0 +1,14 @@ +%module template_const_ref +%inline %{ +template class Foo { +public: + char *bar(const T &obj) { + return (char *) "Foo::bar"; + } +}; +class Bar { }; +%} + +%template(Foob) Foo; +%template(Fooi) Foo; + diff --git a/Examples/test-suite/template_construct.i b/Examples/test-suite/template_construct.i new file mode 100644 index 000000000..a6e8c3c33 --- /dev/null +++ b/Examples/test-suite/template_construct.i @@ -0,0 +1,15 @@ +%module template_construct + +// Tests templates to make sure an extra <> in a constructor is ok. + +%inline %{ +template +class Foo { + T y; +public: + Foo(T x) : y(x) { } +}; + +%} + +%template(Foo_int) Foo; diff --git a/Examples/test-suite/template_default.i b/Examples/test-suite/template_default.i new file mode 100644 index 000000000..9de4eab38 --- /dev/null +++ b/Examples/test-suite/template_default.i @@ -0,0 +1,10 @@ +%module template_default +%inline %{ +template +class A +{ +}; + %} + +%template(A_ii) A; +%template(A_d) A; diff --git a/Examples/test-suite/template_default2.i b/Examples/test-suite/template_default2.i new file mode 100644 index 000000000..0bcd47652 --- /dev/null +++ b/Examples/test-suite/template_default2.i @@ -0,0 +1,44 @@ +%module template_default2 + +%warnfilter(801) oss::traits; // Ruby, wrong class name + +%inline %{ + namespace oss + { + enum Polarization { UnaryPolarization, BinaryPolarization }; + + template + struct Interface + { + }; + + struct traits + { + static const Polarization pmode = UnaryPolarization; + }; + + template > // **** problem here ***** + struct Module : Base + { + }; + + } +%} + +namespace oss +{ + %template(Interface_UP) Interface; + + // This works + %template(Module_UP1) Module >; + + // These don't + %template(Module_UP2) Module; + %template(Module_UP3) Module; +} + + diff --git a/Examples/test-suite/template_default_arg.i b/Examples/test-suite/template_default_arg.i new file mode 100644 index 000000000..1b3612f73 --- /dev/null +++ b/Examples/test-suite/template_default_arg.i @@ -0,0 +1,34 @@ +%module template_default_arg + +%warnfilter(801) hi; /* Ruby, wrong class name */ + +%inline %{ + template + struct Hello + { + typedef unsigned int size_type; + + // This works + // Hello(size_type n = Hello::size_type(0) ) { } + + // This doesn't + Hello(size_type n = size_type(0) ) { } + + }; +%} + +%template(Hello_int) Hello; + +%inline %{ + + struct hi : Hello + { + hi(size_type n) : Hello(n) + { + } + + }; +%} + + + diff --git a/Examples/test-suite/template_default_inherit.i b/Examples/test-suite/template_default_inherit.i new file mode 100644 index 000000000..442ac77c6 --- /dev/null +++ b/Examples/test-suite/template_default_inherit.i @@ -0,0 +1,25 @@ +%module template_default_inherit + +%warnfilter(801) A::nindex; /* Ruby, wrong constant name */ + +%inline %{ + template + struct A + { + typedef unsigned int size_type; + static const size_type nindex = static_cast(-1); + + }; + + template + struct B : A + { + typedef typename A::size_type size_type; + void say_hi(size_type index = nindex) {} + }; + +%} + +%template(A_int) A; +%template(B_int) B; + diff --git a/Examples/test-suite/template_default_qualify.i b/Examples/test-suite/template_default_qualify.i new file mode 100644 index 000000000..7a411d130 --- /dev/null +++ b/Examples/test-suite/template_default_qualify.i @@ -0,0 +1,56 @@ +// Tests typename qualification and constant resolution in default +// template arguments. Another Marcelo special.. :-). + +%module template_default_qualify + +%warnfilter(801) etraits; /* Ruby, wrong class name */ + +%inline %{ + namespace oss + { + + enum Polarization { UnaryPolarization, BinaryPolarization }; + + template + struct Interface + { + }; + + namespace modules + { + + template > + // *** problem here **** + struct Module : base + { + }; + } + } + struct etraits + { + static const oss::Polarization pmode = oss::UnaryPolarization; + }; + +%} + +namespace oss +{ + %template(Interface_UP) Interface; + namespace modules + { + %template(Module_etraits) Module; + } +} + +%inline %{ + namespace oss + { + namespace modules + { + struct HModule1 : Module + { + }; + } + } +%} + diff --git a/Examples/test-suite/template_enum.i b/Examples/test-suite/template_enum.i new file mode 100644 index 000000000..9f6eeeb6f --- /dev/null +++ b/Examples/test-suite/template_enum.i @@ -0,0 +1,15 @@ +%module template_enum + +%warnfilter(801) foo; /* Ruby, wrong class name */ +%warnfilter(801) foo; /* Ruby, wrong class name */ + +%inline %{ +template class foo { +public: + enum { FOO, BAR }; +}; +%} + +%template(foo_i) foo; +%template(foo_d) foo; + diff --git a/Examples/test-suite/template_enum_ns_inherit.i b/Examples/test-suite/template_enum_ns_inherit.i new file mode 100644 index 000000000..8992eef6d --- /dev/null +++ b/Examples/test-suite/template_enum_ns_inherit.i @@ -0,0 +1,48 @@ +%module template_enum_ns_inherit +%inline %{ + + namespace oss + { + enum Polarization { UnaryPolarization, BinaryPolarization }; + + template + struct Interface + { + }; + + template + struct Module + { + }; + + } + +%} + +namespace oss +{ + %template(Interface_UP) Interface; + %template(Module_UPIUP) Module >; +} + +%inline %{ + namespace oss + { + namespace hello + { + struct HInterface1 : + Interface // this works (with fullns qualification) + { + }; + + struct HInterface2 : + Interface // this doesn't work + { + }; + + struct HModule1 : Module > { + }; + + } + } +%} \ No newline at end of file diff --git a/Examples/test-suite/template_enum_typedef.i b/Examples/test-suite/template_enum_typedef.i new file mode 100644 index 000000000..f1c15f182 --- /dev/null +++ b/Examples/test-suite/template_enum_typedef.i @@ -0,0 +1,39 @@ +%module template_enum_typedef + +%warnfilter(801) oss::etraits; /* Ruby, wrong class name */ + +%inline %{ + + namespace oss + { + enum Polarization { UnaryPolarization, BinaryPolarization }; + + template + struct Interface + { + }; + + struct etraits + { + static const Polarization pmode = UnaryPolarization; + }; + + + template + struct Module + { + typedef Traits traits; + static const Polarization P = traits::pmode; + + void get(Interface

      arg) { }; // Here P is only replace by traits::pmode + + }; + } + +%} + +namespace oss +{ + %template(Interface_UP) Interface; + %template(Module_UP) Module; +} diff --git a/Examples/test-suite/template_forward.i b/Examples/test-suite/template_forward.i new file mode 100644 index 000000000..edf679568 --- /dev/null +++ b/Examples/test-suite/template_forward.i @@ -0,0 +1,20 @@ +%module template_forward + +%{ +namespace foo { +template class bar { }; +} +%} + +namespace foo { + template class bar; +}; + +%inline %{ +namespace foo { + double test1(const bar &x) { return 0; } + bar test2() { + return bar(); + } +} +%} diff --git a/Examples/test-suite/template_inherit.i b/Examples/test-suite/template_inherit.i new file mode 100644 index 000000000..e02ec5233 --- /dev/null +++ b/Examples/test-suite/template_inherit.i @@ -0,0 +1,40 @@ +/* File : example.i */ +%module template_inherit + +/* This example tests template inheritance to see if it actually works */ + +%inline %{ + +template class Foo { +public: + virtual char *blah() { + return (char *) "Foo"; + } + virtual char *foomethod() { + return (char *) "foomethod"; + } +}; + +template class Bar : public Foo { +public: + virtual char *blah() { + return (char *) "Bar"; + } +}; + +template char *invoke_blah(Foo *x) { + return x->blah(); +} +%} + +%template(FooInt) Foo; +%template(FooDouble) Foo; +%template(FooUInt) Foo; +%template(BarInt) Bar; +%template(BarDouble) Bar; +%template(BarUInt) Bar; +%template(invoke_blah_int) invoke_blah; +%template(invoke_blah_double) invoke_blah; +%template(invoke_blah_uint) invoke_blah; + + diff --git a/Examples/test-suite/template_inherit_abstract.i b/Examples/test-suite/template_inherit_abstract.i new file mode 100644 index 000000000..8cd0b998d --- /dev/null +++ b/Examples/test-suite/template_inherit_abstract.i @@ -0,0 +1,59 @@ +%module template_inherit_abstract + +%warnfilter(801) oss::test; /* Ruby, wrong class name */ +%warnfilter(802, 813) oss::Module; /* Ruby & Java, multiple inheritance */ + +%inline %{ + + namespace oss + { + template + struct Wrap + { + }; + + struct ModuleBase + { + virtual ~ModuleBase() {} + virtual int get() = 0; + }; + + template + struct Module : C, ModuleBase + { + protected: + Module() {} + }; + + template + struct HModule : Module > + { + // virtual int get(); // declaration here works + + protected: + HModule() {} + }; + } + + struct B + { + }; + +%} + +namespace oss +{ + %template(Wrap_B) Wrap; + %template(Module_B) Module >; + %template(HModule_B) HModule; +} + +%inline %{ + namespace oss + { + struct test : HModule + { + virtual int get() {return 0;} // declaration here breaks swig + }; + } +%} diff --git a/Examples/test-suite/template_int_const.i b/Examples/test-suite/template_int_const.i new file mode 100644 index 000000000..7b9eea5f8 --- /dev/null +++ b/Examples/test-suite/template_int_const.i @@ -0,0 +1,50 @@ +%module template_int_const + +%warnfilter(801) interface_traits; /* Ruby, wrong class name */ +%warnfilter(801) module_traits; /* Ruby, wrong class name */ + +%inline %{ + enum Polarization { UnaryPolarization, BinaryPolarization }; + struct interface_traits + { + static const Polarization polarization = UnaryPolarization; + }; + template + struct Interface + { + }; + + typedef unsigned int Category; + struct module_traits + { + static const Category category = 1; + }; + + template + struct Module + { + }; +%} + +%template(Interface_UP) Interface; +%template(Module_1) Module<1>; + +%inline %{ + struct ExtInterface1 : + Interface // works + { + }; + struct ExtInterface2 : + Interface // doesn't work + { + }; + struct ExtModule1 : + Module<1> // works + { + }; + struct ExtModule2 : + Module // doesn't work + { + }; +%} + diff --git a/Examples/test-suite/template_ns.i b/Examples/test-suite/template_ns.i new file mode 100644 index 000000000..90af05fac --- /dev/null +++ b/Examples/test-suite/template_ns.i @@ -0,0 +1,35 @@ +// Tests the use of the %template directive with fully +// qualified scope names + +%module template_ns + +%warnfilter(801) std::pair; /* Ruby, wrong class name */ +%warnfilter(801) std::pair; /* Ruby, wrong class name */ + +%ignore std::pair::pair(); + +%inline %{ +namespace std +{ +template +struct pair { + typedef _T1 first_type; + typedef _T2 second_type; + + _T1 first; + _T2 second; + pair() : first(_T1()), second(_T2()) {} + pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} + template + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} +}; +} +%} + +// Add copy constructor +%extend std::pair { + %template(pair) pair<_T1,_T2>; +}; + +%template(pairii) std::pair; +%template(pairdd) std::pair; diff --git a/Examples/test-suite/template_ns2.i b/Examples/test-suite/template_ns2.i new file mode 100644 index 000000000..f35d32654 --- /dev/null +++ b/Examples/test-suite/template_ns2.i @@ -0,0 +1,16 @@ +// Tests compilation of uninstantiated templates in a namespace + +%module template_ns2 + +%inline %{ + +namespace foo { + template class bar { + }; + bar *test1(bar *x) { return x; } + typedef int Integer; + + bar *test2(bar *x) { return x; } +} +%} + diff --git a/Examples/test-suite/template_ns3.i b/Examples/test-suite/template_ns3.i new file mode 100644 index 000000000..0cc08b551 --- /dev/null +++ b/Examples/test-suite/template_ns3.i @@ -0,0 +1,21 @@ +%module template_ns3 + +%warnfilter(801) foo::bar; /* Ruby, wrong class name */ + +%inline %{ +namespace foo { + typedef int Integer; + + template class bar { + public: + Integer test(Integer x) { return x; } + }; + +} +%} + +%template(bari) foo::bar; + + + + diff --git a/Examples/test-suite/template_ns4.i b/Examples/test-suite/template_ns4.i new file mode 100644 index 000000000..3769f8d0b --- /dev/null +++ b/Examples/test-suite/template_ns4.i @@ -0,0 +1,66 @@ +%module template_ns4 + +%inline %{ + namespace hello { + + class Double { + }; + + template + struct Function + { + char *test() { return (char *) "test"; } + }; + + template + struct ArithFunction : Function + { + }; + + template + struct traits + { + }; + + template + struct traits + { + typedef ArgType arg_type; + typedef double res_type; + typedef ArithFunction base; + }; + + template + struct traits + { + typedef ArgType arg_type; + typedef Double res_type; + typedef ArithFunction base; + }; + + template + class Class : public ArithFunction< typename traits::arg_type, + typename traits::res_type > + { + }; + + template + typename traits::base + make_Class() + { + return Class(); + } + + } +%} + namespace hello { + // + // This complains only when using a namespace + // + %template() traits; + %template(Function_DD) Function ; + %template(ArithFunction_DD) ArithFunction ; + %template(Class_DD) Class ; + %template(make_Class_DD) make_Class ; + } + diff --git a/Examples/test-suite/template_ns_enum.i b/Examples/test-suite/template_ns_enum.i new file mode 100644 index 000000000..4c73e5067 --- /dev/null +++ b/Examples/test-suite/template_ns_enum.i @@ -0,0 +1,18 @@ +%module template_ns_enum +%inline %{ + namespace hello { + enum Hello { Hi, Hola }; + + template + struct traits + { + typedef double value_type; + }; + + traits::value_type say_hi() + { + return traits::value_type(1); + } + + } +%} diff --git a/Examples/test-suite/template_ns_enum2.i b/Examples/test-suite/template_ns_enum2.i new file mode 100644 index 000000000..616100423 --- /dev/null +++ b/Examples/test-suite/template_ns_enum2.i @@ -0,0 +1,38 @@ +%module template_ns_enum2 + +%inline %{ + + namespace hi + { + enum Hello { Hi, Hola }; + + template + struct traits + { + }; + + template <> + struct traits + { + typedef int value_type; + }; + + template <> + struct traits + { + typedef double value_type; + }; + + struct B + { + const traits::value_type& + eval(const traits::value_type& e) const; + + }; + const traits::value_type& + B::eval(const traits::value_type& e) const { + return e; + } + } + +%} diff --git a/Examples/test-suite/template_ns_inherit.i b/Examples/test-suite/template_ns_inherit.i new file mode 100644 index 000000000..fb336541a --- /dev/null +++ b/Examples/test-suite/template_ns_inherit.i @@ -0,0 +1,30 @@ +// Submitted by Marcelo Matus +%module template_ns_inherit + +%inline %{ + namespace hello { + typedef double Double; + } + namespace hello + { + template + class VUnaryFunction + {}; + + template + class UnaryFunction : public VUnaryFunction + {}; + } + +%} + +namespace hello +{ + %template(VUnaryFunction_id) VUnaryFunction; + %template(UnaryFunction_id) UnaryFunction; +} + + + + + diff --git a/Examples/test-suite/template_ns_scope.i b/Examples/test-suite/template_ns_scope.i new file mode 100644 index 000000000..928f628d2 --- /dev/null +++ b/Examples/test-suite/template_ns_scope.i @@ -0,0 +1,38 @@ +%module template_ns_scope +// Tests a scoping bug reported by Marcelo Matus. + +%inline %{ + namespace hi { + enum Hello { Hi, Hola }; + + template + struct A + { + public: + A() {} // *** Here, the const. breaks swig *** + // *** swig works without it *** + }; + + namespace hello + { + template + struct B : A + { + int say_hi() { return 0; } + }; + } + } + +%} +namespace hi +{ + %template(A_Hi) A; + namespace hello + { + %template(B_Hi) B; + } +} + + + + diff --git a/Examples/test-suite/template_qualifier.i b/Examples/test-suite/template_qualifier.i new file mode 100644 index 000000000..1c3b46fbc --- /dev/null +++ b/Examples/test-suite/template_qualifier.i @@ -0,0 +1,15 @@ +%module template_qualifier + +/* Stroustruo, 3rd Ed, C.13.6 */ +%inline %{ +class X { +public: + template X *xalloc() { return new X(); } +}; + +%} + +%extend X { +%template(xalloc_int) xalloc<200>; +}; + diff --git a/Examples/test-suite/template_rename.i b/Examples/test-suite/template_rename.i new file mode 100644 index 000000000..8d3574e81 --- /dev/null +++ b/Examples/test-suite/template_rename.i @@ -0,0 +1,24 @@ +%module template_rename + +%warnfilter(801) Foo; /* Ruby, wrong class name */ +%warnfilter(801) Foo; /* Ruby, wrong class name */ + +%rename(blah_test) Foo::blah(int); +%rename(spam_test) Foo::spam(int); +%rename(grok_test) Foo::grok(int); +%rename(groki_test) Foo::grok(int); + +%inline %{ + +template class Foo { +public: + int blah(int x) { return x; } + int spam(int x) { return x; } + int grok(int x) { return x; } +}; + +%} + +%template(iFoo) Foo; +%template(dFoo) Foo; + diff --git a/Examples/test-suite/template_retvalue.i b/Examples/test-suite/template_retvalue.i new file mode 100644 index 000000000..9c15fea65 --- /dev/null +++ b/Examples/test-suite/template_retvalue.i @@ -0,0 +1,32 @@ +%module template_retvalue +%inline %{ + + enum Hello + { + Hi, Hola + }; + + struct C + { + C(int) {} + }; + + template + class A + { + public: + A(int) {} + }; + + + template + struct B + { + C get_c() { return C(0); } // this works + A get_a() { return A(0); } // this doesn't + }; + + %} + +%template(A_Hi) A; +%template(B_Hola) B; diff --git a/Examples/test-suite/template_specialization.i b/Examples/test-suite/template_specialization.i new file mode 100644 index 000000000..b14cbb939 --- /dev/null +++ b/Examples/test-suite/template_specialization.i @@ -0,0 +1,40 @@ +%module template_specialization + +%rename(__not__) *::operator!() const; + +#ifdef SWIGJAVA +%rename(negate) *::operator-() const; +#endif + +%inline %{ + + namespace vfncs { + + template + struct UnaryFunction + { + UnaryFunction operator-() const { return *this; } + }; + + template <> + struct UnaryFunction + { + // This works + // UnaryFunction operator!() const; + + // This doesn't + UnaryFunction operator!() const { return *this; } + + // Does this? + void foo(UnaryFunction) { } + + }; + + } +%} + +namespace vfncs { + + %template(UnaryFunction_double) UnaryFunction; + %template(UnaryFunction_bool) UnaryFunction; +} diff --git a/Examples/test-suite/template_static.i b/Examples/test-suite/template_static.i new file mode 100644 index 000000000..087cb3db2 --- /dev/null +++ b/Examples/test-suite/template_static.i @@ -0,0 +1,16 @@ +%module template_static + +%warnfilter(801) foo; /* Ruby, wrong class name */ +%warnfilter(801) foo; /* Ruby, wrong class name */ + +%inline %{ +template class foo { +public: + static int test; +}; +template int foo::test = 0; +%} + +%template(foo_i) foo; +%template(foo_d) foo; + diff --git a/Examples/test-suite/template_tbase_template.i b/Examples/test-suite/template_tbase_template.i new file mode 100644 index 000000000..1d57ca070 --- /dev/null +++ b/Examples/test-suite/template_tbase_template.i @@ -0,0 +1,43 @@ +%module template_tbase_template + +%warnfilter(801) traits; /* Ruby, wrong class name */ + +%inline %{ + typedef double Double; + + + template + struct Function + { + char *test() { return (char *) "test"; } + }; + + template + struct traits + { + typedef ArgType arg_type; + typedef ResType res_type; + typedef Function base; + }; + + // Egad! + template + struct Class + : Function::arg_type, + typename traits::res_type> + { + }; + + template + typename traits::base + make_Class() + { + return Class(); + } + +%} + +%template(traits_dd) traits ; +%template(Function_dd) Function ; +%template(Class_dd) Class ; +%template(make_Class_dd) make_Class; diff --git a/Examples/test-suite/template_type_namespace.i b/Examples/test-suite/template_type_namespace.i new file mode 100644 index 000000000..719647361 --- /dev/null +++ b/Examples/test-suite/template_type_namespace.i @@ -0,0 +1,14 @@ +%module template_type_namespace + +%warnfilter(801) std::vector; // Ruby, wrong class name + +%include std_string.i +%include std_vector.i + +%template(string_vector) std::vector; + +%inline %{ + std::vector foo() { + return std::vector(1,"foo"); + } +%} diff --git a/Examples/test-suite/template_typedef.i b/Examples/test-suite/template_typedef.i new file mode 100644 index 000000000..1d58d53bd --- /dev/null +++ b/Examples/test-suite/template_typedef.i @@ -0,0 +1,156 @@ +%module template_typedef + +// +// Change this to #if 1 to test the 'test' +// +#if 0 + +#define real double +%{ +#define real double +%} + +#else + +%inline %{ + typedef double real; +%} + +#endif + + +%inline %{ + + // typedef double real; + + namespace vfncs { + + struct UnaryFunctionBase + { + }; + + template + class UnaryFunction; + + template + class ArithUnaryFunction; + + template + struct UnaryFunction : UnaryFunctionBase + { + }; + + template + struct ArithUnaryFunction : UnaryFunction + { + }; + + template + struct unary_func_traits + { + typedef ArithUnaryFunction base; + }; + + template + inline + typename unary_func_traits< ArgType, ArgType >::base + make_Identity() + { + return typename unary_func_traits< ArgType, ArgType >::base(); + } + + template + struct arith_traits + { + }; + + template<> + struct arith_traits< float, float > + { + + typedef float argument_type; + typedef float result_type; + static const char* const arg_type = "float"; + static const char* const res_type = "float"; + }; + + template<> + struct arith_traits< real, real > + { + + typedef real argument_type; + typedef real result_type; + static const char* const arg_type = "real"; + static const char* const res_type = "real"; + }; + + template<> + struct arith_traits< real, float > + { + typedef float argument_type; + typedef real result_type; + static const char* const arg_type = "float"; + static const char* const res_type = "real"; + }; + + template<> + struct arith_traits< float, real > + { + typedef float argument_type; + typedef real result_type; + static const char* const arg_type = "float"; + static const char* const res_type = "real"; + }; + + template + inline + ArithUnaryFunction::argument_type, + typename arith_traits< RF, RG >::result_type > + make_Multiplies(const ArithUnaryFunction& f, + const ArithUnaryFunction& g) + { + return + ArithUnaryFunction::argument_type, + typename arith_traits< RF, RG >::result_type>(); + } + + } + +%} + +namespace vfncs { + %template(UnaryFunction_float_float) UnaryFunction; + %template(ArithUnaryFunction_float_float) ArithUnaryFunction; + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_float) make_Identity; + + %template(UnaryFunction_real_real) UnaryFunction; + %template(ArithUnaryFunction_real_real) ArithUnaryFunction; + + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_real) make_Identity; + + /* [beazley] Added this part */ + %template() unary_func_traits; + %template(UnaryFunction_float_real) UnaryFunction; + %template(ArithUnaryFunction_float_real) ArithUnaryFunction; + + /* */ + + %template() arith_traits; + %template() arith_traits; + %template() arith_traits; + + %template(make_Multiplies_float_float_real_real) + make_Multiplies; + + %template(make_Multiplies_float_float_float_float) + make_Multiplies; + + %template(make_Multiplies_real_real_real_real) + make_Multiplies; + +} + diff --git a/Examples/test-suite/template_typedef_cplx.i b/Examples/test-suite/template_typedef_cplx.i new file mode 100644 index 000000000..104e59910 --- /dev/null +++ b/Examples/test-suite/template_typedef_cplx.i @@ -0,0 +1,159 @@ +%module template_typedef_cplx + +// +// Change this to #if 1 to test the 'test' +// +#if 0 + +%{ +#include +typedef std::complex cmplx; +%} + +%inline %{ + typedef cmplx Complex; +%} + +#else + +%inline %{ +#include + typedef std::complex Complex; +%} + +#endif + + +%inline %{ + + namespace vfncs { + + struct UnaryFunctionBase + { + }; + + template + class UnaryFunction; + + template + class ArithUnaryFunction; + + template + struct UnaryFunction : UnaryFunctionBase + { + }; + + template + struct ArithUnaryFunction : UnaryFunction + { + }; + + template + struct unary_func_traits + { + typedef ArithUnaryFunction base; + }; + + template + inline + typename unary_func_traits< ArgType, ArgType >::base + make_Identity() + { + return typename unary_func_traits< ArgType, ArgType >::base(); + } + + template + struct arith_traits + { + }; + + template<> + struct arith_traits< double, double > + { + + typedef double argument_type; + typedef double result_type; + static const char* const arg_type = "double"; + static const char* const res_type = "double"; + }; + + template<> + struct arith_traits< Complex, Complex > + { + + typedef Complex argument_type; + typedef Complex result_type; + static const char* const arg_type = "complex"; + static const char* const res_type = "complex"; + }; + + template<> + struct arith_traits< Complex, double > + { + typedef double argument_type; + typedef Complex result_type; + static const char* const arg_type = "double"; + static const char* const res_type = "complex"; + }; + + template<> + struct arith_traits< double, Complex > + { + typedef double argument_type; + typedef Complex result_type; + static const char* const arg_type = "double"; + static const char* const res_type = "complex"; + }; + + template + inline + ArithUnaryFunction::argument_type, + typename arith_traits< RF, RG >::result_type > + make_Multiplies(const ArithUnaryFunction& f, + const ArithUnaryFunction& g) + { + return + ArithUnaryFunction::argument_type, + typename arith_traits< RF, RG >::result_type>(); + } + } +%} + +namespace vfncs { + %template(UnaryFunction_double_double) UnaryFunction; + %template(ArithUnaryFunction_double_double) ArithUnaryFunction; + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_double) make_Identity; + + %template(UnaryFunction_complex_complex) UnaryFunction; + %template(ArithUnaryFunction_complex_complex) ArithUnaryFunction; + + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_complex) make_Identity; + + /* [beazley] Added this part */ + %template() unary_func_traits; + %template(UnaryFunction_double_complex) UnaryFunction; + %template(ArithUnaryFunction_double_complex) ArithUnaryFunction; + + /* */ + + %template() arith_traits; + %template() arith_traits; + + %template(make_Multiplies_double_double_complex_complex) + make_Multiplies; + + %template(make_Multiplies_double_double_double_double) + make_Multiplies; + + %template(make_Multiplies_complex_complex_complex_complex) + make_Multiplies; + + %template(make_Multiplies_complex_complex_double_double) + make_Multiplies; + +} + diff --git a/Examples/test-suite/template_typedef_cplx2.h b/Examples/test-suite/template_typedef_cplx2.h new file mode 100644 index 000000000..df19e5ad6 --- /dev/null +++ b/Examples/test-suite/template_typedef_cplx2.h @@ -0,0 +1,156 @@ +#ifndef ___typedef_import_h__ +#define ___typedef_import_h__ + +#ifdef SWIG +%module template_typedef_cplx2; +#endif + +#include +typedef std::complex Complex; + +namespace vfncs { + + struct UnaryFunctionBase + { + int get_base_value() + { + return 0; + } + }; + + template + class UnaryFunction; + + template + class ArithUnaryFunction; + + template + struct UnaryFunction : UnaryFunctionBase + { + int get_value() + { + return 1; + } + }; + + template + struct ArithUnaryFunction : UnaryFunction + { + int get_arith_value() + { + return 2; + } + }; + + template + struct unary_func_traits + { + typedef ArithUnaryFunction base; + }; + + template + inline + typename unary_func_traits< ArgType, ArgType >::base + make_Identity() + { + return typename unary_func_traits< ArgType, ArgType >::base(); + } + + template + struct arith_traits + { + }; + + template<> + struct arith_traits< double, double > + { + typedef double argument_type; + typedef double result_type; + static const char* const arg_type = "double"; + static const char* const res_type = "double"; + }; + + template<> + struct arith_traits< Complex, Complex > + { + + typedef Complex argument_type; + typedef Complex result_type; + static const char* const arg_type = "complex"; + static const char* const res_type = "complex"; + }; + + template<> + struct arith_traits< Complex, double > + { + typedef double argument_type; + typedef Complex result_type; + static const char* const arg_type = "double"; + static const char* const res_type = "complex"; + }; + + template<> + struct arith_traits< double, Complex > + { + typedef double argument_type; + typedef Complex result_type; + static const char* const arg_type = "double"; + static const char* const res_type = "complex"; + }; + + template + inline + ArithUnaryFunction::argument_type, + typename arith_traits< RF, RG >::result_type > + make_Multiplies(const ArithUnaryFunction& f, + const ArithUnaryFunction& g) + { + return + ArithUnaryFunction::argument_type, + typename arith_traits< RF, RG >::result_type>(); + } +} + +#ifdef SWIG + +namespace vfncs { + %template(UnaryFunction_double_double) UnaryFunction; + %template(ArithUnaryFunction_double_double) ArithUnaryFunction; + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_double) make_Identity; + + %template(UnaryFunction_complex_complex) UnaryFunction; + %template(ArithUnaryFunction_complex_complex) ArithUnaryFunction; + + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_complex) make_Identity; + + /* [beazley] Added this part */ + %template() unary_func_traits; + %template(UnaryFunction_double_complex) UnaryFunction; + %template(ArithUnaryFunction_double_complex) ArithUnaryFunction; + + /* */ + + %template() arith_traits; + %template() arith_traits; + + %template(make_Multiplies_double_double_complex_complex) + make_Multiplies; + + %template(make_Multiplies_double_double_double_double) + make_Multiplies; + + %template(make_Multiplies_complex_complex_complex_complex) + make_Multiplies; + + %template(make_Multiplies_complex_complex_double_double) + make_Multiplies; + +} + +#endif + +#endif //___template_typedef_h__ diff --git a/Examples/test-suite/template_typedef_cplx2.i b/Examples/test-suite/template_typedef_cplx2.i new file mode 100644 index 000000000..6f99e8996 --- /dev/null +++ b/Examples/test-suite/template_typedef_cplx2.i @@ -0,0 +1,7 @@ +%module template_typedef_cplx2 + +%{ +#include "template_typedef_cplx2.h" +%} + +%include "template_typedef_cplx2.h" diff --git a/Examples/test-suite/template_typedef_cplx3.i b/Examples/test-suite/template_typedef_cplx3.i new file mode 100644 index 000000000..71fcf5e3e --- /dev/null +++ b/Examples/test-suite/template_typedef_cplx3.i @@ -0,0 +1,37 @@ +%module template_typedef_cplx3 +%{ +#include "template_typedef_cplx2.h" +%} + +%include "template_typedef_cplx2.h" + +%inline %{ + + typedef vfncs::ArithUnaryFunction RFunction; + typedef vfncs::ArithUnaryFunction CFunction; + + + int my_func_r(RFunction* hello) + { + return 0; + } + + int my_func_c(CFunction* hello) + { + return 1; + } + + struct Sin : RFunction + { + }; + + struct CSin : CFunction + { + }; + +%} + + + + + diff --git a/Examples/test-suite/template_typedef_cplx4.i b/Examples/test-suite/template_typedef_cplx4.i new file mode 100644 index 000000000..a2457acdf --- /dev/null +++ b/Examples/test-suite/template_typedef_cplx4.i @@ -0,0 +1,44 @@ +%module template_typedef_cplx4 +%{ +#include "template_typedef_cplx2.h" +%} + +%include "template_typedef_cplx2.h" + +%inline %{ + + typedef vfncs::ArithUnaryFunction RFunction; + // **** these two work **** + // typedef vfncs::ArithUnaryFunction CFunction; + // typedef vfncs::ArithUnaryFunction, std::complex > CFunction; + + // **** these ones don't *** + // typedef vfncs::ArithUnaryFunction > CFunction; + typedef vfncs::ArithUnaryFunction, Complex > CFunction; + + + + int my_func_r(RFunction* hello) + { + return 0; + } + + int my_func_c(CFunction* hello) + { + return 1; + } + + struct Sin : RFunction + { + }; + + struct CSin : CFunction + { + }; + +%} + + + + + diff --git a/Examples/test-suite/template_typedef_import.i b/Examples/test-suite/template_typedef_import.i new file mode 100644 index 000000000..10bc61763 --- /dev/null +++ b/Examples/test-suite/template_typedef_import.i @@ -0,0 +1,37 @@ +%module template_typedef_import +%{ +#include "template_typedef_cplx2.h" +%} + +%import "template_typedef_cplx2.h" + +%inline %{ + + typedef vfncs::ArithUnaryFunction RFunction; + typedef vfncs::ArithUnaryFunction CFunction; + + + int my_func_r(RFunction* hello) + { + return 0; + } + + int my_func_c(CFunction* hello) + { + return 1; + } + + struct Sin : RFunction + { + }; + + struct CSin : CFunction + { + }; + +%} + + + + + diff --git a/Examples/test-suite/template_typedef_import.list b/Examples/test-suite/template_typedef_import.list new file mode 100644 index 000000000..c7622b4da --- /dev/null +++ b/Examples/test-suite/template_typedef_import.list @@ -0,0 +1,2 @@ +template_typedef_cplx2 +template_typedef_import diff --git a/Examples/test-suite/template_virtual.i b/Examples/test-suite/template_virtual.i new file mode 100644 index 000000000..cc5949a4f --- /dev/null +++ b/Examples/test-suite/template_virtual.i @@ -0,0 +1,32 @@ +%module template_virtual + +// Submitted by Marcelo Matus +// assertion emmitted with templates + derivation + pure virtual member +// allocate.cxx:47: int Allocate::is_abstract_inherit(Node*, Node*): +// Assertion `dn' failed. + +%inline %{ + + template + class A + { + public: + virtual void say_hi() = 0; // only fails with pure virtual methods + + virtual void say_hello(); // this works fine + + protected: + A() { } // defined protected as swig generates constructor by default + }; + + template + class B : public A + { + protected: + B() { } // defined protected as swig generates constructor by default + }; + +%} + +%template(A_int) A; +%template(B_int) B; // !!!! it crashes right here !!!!! diff --git a/Examples/test-suite/template_whitespace.i b/Examples/test-suite/template_whitespace.i new file mode 100644 index 000000000..ea3d28a1a --- /dev/null +++ b/Examples/test-suite/template_whitespace.i @@ -0,0 +1,22 @@ +/* This interface file tests whether whitespace in angle brackets + effects the SWIG types. SF Bug #221917, reported by + burchanb@cs.tamu.edu. */ + +%module template_whitespace + +%{ +template class vector { +}; +template class map { +}; +%} + +//%typemap(in) vector "$target = new vector();"; +//%typemap(in) vector "$target = new vector();"; +//%typemap(in) map "$target = new map();"; + +%inline %{ +void foo(vector v) {} +void var(vector v) {} +void baz(map < int , int > p) {} +%} diff --git a/Examples/test-suite/throw_exception.i b/Examples/test-suite/throw_exception.i new file mode 100644 index 000000000..0c170a5f3 --- /dev/null +++ b/Examples/test-suite/throw_exception.i @@ -0,0 +1,29 @@ +%module throw_exception + +// Tests SWIG's automatic exception mechanism + +%inline %{ + +class Error { +}; + +class Foo { +public: + void test_int() throw(int) { + throw 37; + } + void test_msg() throw(const char *) { + throw "Dead"; + } + void test_cls() throw(Error) { + throw Error(); + } + void test_multi(int x) throw(int, const char *, Error) { + if (x == 1) throw 37; + if (x == 2) throw "Dead"; + if (x == 3) throw Error(); + } +}; + + %} + diff --git a/Examples/test-suite/typedef_array_member.i b/Examples/test-suite/typedef_array_member.i new file mode 100644 index 000000000..8663fd335 --- /dev/null +++ b/Examples/test-suite/typedef_array_member.i @@ -0,0 +1,10 @@ +%module typedef_array_member +%inline %{ + +typedef char amember[20]; + +struct Foo { + amember x; +}; + +%} diff --git a/Examples/test-suite/typedef_funcptr.i b/Examples/test-suite/typedef_funcptr.i new file mode 100644 index 000000000..9ef220282 --- /dev/null +++ b/Examples/test-suite/typedef_funcptr.i @@ -0,0 +1,26 @@ +// Tests typedef through function pointers + +%module typedef_funcptr + +%warnfilter(801) addf; /* Ruby, wrong constant name */ +%warnfilter(801) subf; /* Ruby, wrong constant name */ + +%{ +int addf(int x, int y) { + return x+y; +} +int subf(int x, int y) { + return x-y; +} +%} + +%inline %{ +typedef int Integer; + +Integer do_op(Integer x, Integer y, Integer (*op)(Integer, Integer)) { + return (*op)(x,y); +} +%} + +%constant int addf(int x, int y); +%constant Integer subf(Integer x, Integer y); diff --git a/Examples/test-suite/typedef_inherit.i b/Examples/test-suite/typedef_inherit.i new file mode 100644 index 000000000..c22253a32 --- /dev/null +++ b/Examples/test-suite/typedef_inherit.i @@ -0,0 +1,41 @@ +// Inheritance through a typedef name +%module typedef_inherit + +%inline %{ +class Foo { +public: + virtual char *blah() { + return (char *) "Foo::blah"; + } +}; + +typedef Foo FooObj; + +class Bar : public FooObj { + public: + virtual char *blah() { + return (char *) "Bar::blah"; + }; +}; + +char *do_blah(FooObj *f) { + return f->blah(); +} + +typedef struct { + virtual char *blah() { + return (char *) "Spam::blah"; + } +} Spam; + +struct Grok : public Spam { + virtual char *blah() { + return (char *) "Grok::blah"; + } +}; + +char *do_blah2(Spam *s) { + return s->blah(); +} +%} + diff --git a/Examples/test-suite/typedef_mptr.i b/Examples/test-suite/typedef_mptr.i new file mode 100644 index 000000000..5e64c8ac7 --- /dev/null +++ b/Examples/test-suite/typedef_mptr.i @@ -0,0 +1,34 @@ +// Tests typedef through member pointers + +%module typedef_mptr + +#ifdef SWIGPYTHON + +%inline %{ + +class Foo { +public: + int add(int x, int y) { + return x+y; + } + int sub(int x, int y) { + return x-y; + } + int do_op(int x, int y, int (Foo::*op)(int, int)) { + return (this->*op)(x,y); + } +}; + +typedef Foo FooObj; +typedef int Integer; + +Integer do_op(Foo *f, Integer x, Integer y, Integer (FooObj::*op)(Integer, Integer)) { + return f->do_op(x,y,op); +} +%} +#endif + +#ifdef SWIGPYTHON +%constant int (Foo::*add)(int,int) = &Foo::add; +%constant Integer (FooObj::*sub)(Integer,Integer) = &FooObj::sub; +#endif diff --git a/Examples/test-suite/typedef_reference.i b/Examples/test-suite/typedef_reference.i new file mode 100644 index 000000000..5146317a1 --- /dev/null +++ b/Examples/test-suite/typedef_reference.i @@ -0,0 +1,10 @@ +%module typedef_reference + +%include cpointer.i +%pointer_functions(int, intp); + +%inline %{ + typedef int & IntRef; + int somefunc(IntRef i) { return i; } + int otherfunc(int &i) { return i; } +%} diff --git a/Examples/test-suite/typedef_scope.i b/Examples/test-suite/typedef_scope.i new file mode 100644 index 000000000..65adc8df8 --- /dev/null +++ b/Examples/test-suite/typedef_scope.i @@ -0,0 +1,21 @@ +// Tests some subtle issues of typedef scoping in C++ + +%module typedef_scope + +%inline %{ + +typedef char * FooType; +class Bar { +public: + typedef int FooType; + FooType test1(FooType n, ::FooType data) { + return n; + } + ::FooType test2(FooType n, ::FooType data) { + return data; + } +}; +%} + + + diff --git a/Examples/test-suite/typemap_namespace.i b/Examples/test-suite/typemap_namespace.i new file mode 100644 index 000000000..1c312bcfa --- /dev/null +++ b/Examples/test-suite/typemap_namespace.i @@ -0,0 +1,39 @@ +%module typemap_namespace + +/* Secret typedefs */ +%{ +namespace Foo { + typedef char Str1; + typedef char Str2; +} +%} + +namespace Foo { + struct Str1; + struct Str2; + +#ifdef SWIGJAVA + %typemap(jni) Str1 * = char *; + %typemap(jtype) Str1 * = char *; + %typemap(jstype) Str1 * = char *; + %typemap(freearg) Str1 * = char *; + %typemap(javain) Str1 * = char *; + %typemap(javaout) Str1 * = char *; +#endif + %typemap(in) Str1 * = char *; + %apply char * { Str2 * }; +} + +%inline %{ +namespace Foo { + char *test1(Str1 *s) { + return s; + } + char *test2(Str2 *s) { + return s; + } +} +%} + + + diff --git a/Examples/test-suite/typemap_ns_using.i b/Examples/test-suite/typemap_ns_using.i new file mode 100644 index 000000000..6f3357016 --- /dev/null +++ b/Examples/test-suite/typemap_ns_using.i @@ -0,0 +1,21 @@ +%module typemap_ns_using + +%warnfilter(801) X::_FooImpl; /* Ruby, wrong class name */ + +%inline %{ +namespace X { + typedef int Integer; + + class _FooImpl { + public: + typedef Integer value_type; + }; + typedef _FooImpl Foo; +} + +using X::Foo; + +int spam(Foo::value_type x) { return x; } + +%} + diff --git a/Examples/test-suite/typemap_subst.i b/Examples/test-suite/typemap_subst.i new file mode 100644 index 000000000..f9bc8dd6e --- /dev/null +++ b/Examples/test-suite/typemap_subst.i @@ -0,0 +1,54 @@ +/* This interface file tests for type-related typemap substitutions. + */ + +%module typemap_subst + +%warnfilter(801) xyzzy; /* Ruby, wrong class name */ + +%inline %{ + struct xyzzy { + int member; + }; +%} + +%typemap(in) const struct xyzzy **TEST + ($type temp, $*type startemp, $&type amptemp, $basetype basetemp) +{ + { /* Test C type name substitutions */ + $ltype a = (struct xyzzy **) NULL; + const struct xyzzy **b = ($type) NULL; + $<ype c = (struct xyzzy ***) NULL; + const struct xyzzy ***d = ($&type) NULL; + $*ltype e = *a; + $basetype f; + f.member = 42; + } + { /* Test locals */ + basetemp.member = 0; + startemp = &basetemp; + temp = &startemp; + amptemp = &temp; + } + /* Java module doesn't seem to use SWIG's type system? */ + { /* Test descriptors */ + void *desc = $descriptor; + void *stardesc = $*descriptor; + void *ampdesc = $&descriptor; + } + { /* Test mangled names */ + void *desc = SWIGTYPE$mangle; + void *stardesc = SWIGTYPE$*mangle; + void *ampdesc = SWIGTYPE$&mangle; + } + $1 = ($ltype) temp; +} + +#ifndef SWIGJAVA +%inline %{ + void foo(const struct xyzzy **TEST) {} +%} +#endif + + + + diff --git a/Examples/test-suite/typename.i b/Examples/test-suite/typename.i new file mode 100644 index 000000000..4253e0846 --- /dev/null +++ b/Examples/test-suite/typename.i @@ -0,0 +1,34 @@ +%module "typename" + +// Tests the typename handling in templates. + +%inline %{ +class Foo { +public: + typedef double Number; + Number blah() { + return 2.1828; + } +}; + +class Bar { +public: + typedef int Number; + Number blah() { + return 42; + } +}; + +template typename T::Number twoblah(T &obj) { + return 2*(obj.blah()); +} + +Bar::Number spam() { return 3; } + +%} + +%template(twoFoo) twoblah; +%template(twoBar) twoblah; + + + \ No newline at end of file diff --git a/Examples/test-suite/union_scope.i b/Examples/test-suite/union_scope.i new file mode 100644 index 000000000..b58585c2a --- /dev/null +++ b/Examples/test-suite/union_scope.i @@ -0,0 +1,13 @@ +%module union_scope + +%warnfilter(801) nRState; // Ruby, wrong class name +%warnfilter(801) nRState_rstate; // Ruby, wrong class name + +%inline %{ +class nRState { +public: + union { + int i; + } rstate; +}; +%} diff --git a/Examples/test-suite/unions.i b/Examples/test-suite/unions.i new file mode 100644 index 000000000..b5f162b89 --- /dev/null +++ b/Examples/test-suite/unions.i @@ -0,0 +1,35 @@ +/* +This testcase checks that unions can be set and read. +*/ + +%module unions +%pragma make_default + +%inline %{ + +typedef struct SmallStruct { + short jill; +} SmallStruct; + +typedef struct BigStruct { + int jack; + SmallStruct smallstruct; +} BigStruct; + +/* This union is just to check the parser */ +typedef union { + BigStruct bs; + SmallStruct ss; +} UnionTest; + +/* This union checks the parser and will be used in a runtime test */ +typedef struct { + union + { + BigStruct big; + SmallStruct small; + } uni; + int number; +} EmbeddedUnionTest; + +%} diff --git a/Examples/test-suite/using1.i b/Examples/test-suite/using1.i new file mode 100644 index 000000000..cd1fe8aac --- /dev/null +++ b/Examples/test-suite/using1.i @@ -0,0 +1,22 @@ +%module using1 + +%warnfilter(801) X::_FooImpl; /* Ruby, wrong class name */ + +%inline %{ + +namespace X { + typedef int Integer; + + class _FooImpl { + public: + typedef Integer value_type; + }; + typedef _FooImpl Foo; +} + +namespace Y = X; +using namespace Y; + +int spam(Foo::value_type x) { return x; } + +%} diff --git a/Examples/test-suite/using2.i b/Examples/test-suite/using2.i new file mode 100644 index 000000000..29fee1b1c --- /dev/null +++ b/Examples/test-suite/using2.i @@ -0,0 +1,22 @@ +%module using2 + +%warnfilter(801) X::_FooImpl; /* Ruby, wrong class name */ + +%inline %{ + +namespace X { + typedef int Integer; + + class _FooImpl { + public: + typedef Integer value_type; + }; + typedef _FooImpl Foo; +} + +namespace Y = X; +using Y::Foo; + +int spam(Foo::value_type x) { return x; } + +%} diff --git a/Examples/test-suite/using_composition.i b/Examples/test-suite/using_composition.i new file mode 100644 index 000000000..c7cff1d9d --- /dev/null +++ b/Examples/test-suite/using_composition.i @@ -0,0 +1,24 @@ +%module using_composition + +%warnfilter(802, 813) FooBar; // Ruby, Java multiple inheritance + +%inline %{ +class Foo { +public: + int blah(int x) { return x; } + char *blah(char *x) { return x; } +}; + +class Bar { +public: + double blah(double x) { return x; } +}; + +class FooBar : public Foo, public Bar { +public: + using Foo::blah; + using Bar::blah; + char *blah(char *x) { return x; } +}; + +%} diff --git a/Examples/test-suite/using_extend.i b/Examples/test-suite/using_extend.i new file mode 100644 index 000000000..8bc670e83 --- /dev/null +++ b/Examples/test-suite/using_extend.i @@ -0,0 +1,37 @@ +%module using_extend + +%warnfilter(802, 813) FooBar; // Ruby, Java multiple inheritance + +%extend Foo { + int blah(int x, int y) { + return x+y; + } +}; + +%extend Bar { + double blah(double x, double y) { + return x+y; + } +}; + +%inline %{ +class Foo { +public: + int blah(int x) { return x; } + char *blah(char *x) { return x; } +}; + +class Bar { +public: + double blah(double x) { return x; } +}; + +class FooBar : public Foo, public Bar { +public: + using Foo::blah; + using Bar::blah; + char *blah(char *x) { return x; } +}; + +%} + diff --git a/Examples/test-suite/using_inherit.i b/Examples/test-suite/using_inherit.i new file mode 100644 index 000000000..d4eca3707 --- /dev/null +++ b/Examples/test-suite/using_inherit.i @@ -0,0 +1,17 @@ +%module using_inherit + +%inline %{ + +class Foo { +public: + int test(int x) { return x; } + double test(double x) { return x; }; +}; + +class Bar : public Foo { +public: + using Foo::test; +}; + +%} + diff --git a/Examples/test-suite/using_namespace.i b/Examples/test-suite/using_namespace.i new file mode 100644 index 000000000..886dd2a3e --- /dev/null +++ b/Examples/test-suite/using_namespace.i @@ -0,0 +1,56 @@ +%module using_namespace + +%warnfilter(801) hi::hi0; /* Ruby, wrong class name */ +%warnfilter(801) hi::hi1; /* Ruby, wrong class name */ + +%warnfilter(802, 813) Hi; // Ruby, Java multiple inheritance + +%inline %{ + namespace hello + { + struct Hello + { + }; + + template + struct Hi : _T1, _T2 + { + int value1() const + { + return 1; + } + }; + } + + namespace hi + { + + struct hi0 + { + }; + + } +%} + +namespace hello +{ + %template(Hi_hi0) Hi; +} + + +%inline %{ + namespace hi + { + struct hi1 : private hello::Hi< hello::Hello, hi0 > + { + // This works + // using hello::Hi< hello::Hello, hi::hi0 >::value1; + + // This doesn't + using hello::Hi< hello::Hello, hi0 >::value1; + + }; + + } + +%} diff --git a/Examples/test-suite/using_private.i b/Examples/test-suite/using_private.i new file mode 100644 index 000000000..cd5a7974b --- /dev/null +++ b/Examples/test-suite/using_private.i @@ -0,0 +1,17 @@ +%module using_private + +%inline %{ +class Foo { +public: + int x; + int blah(int x) { return x; } +}; + +class FooBar : private Foo { +public: + using Foo::blah; + using Foo::x; +}; + +%} + diff --git a/Examples/test-suite/using_protected.i b/Examples/test-suite/using_protected.i new file mode 100644 index 000000000..93d48cb49 --- /dev/null +++ b/Examples/test-suite/using_protected.i @@ -0,0 +1,17 @@ +%module using_protected + +%inline %{ +class Foo { +protected: + int x; + int blah(int x) { return x; } +}; + +class FooBar : public Foo { +public: + using Foo::blah; + using Foo::x; +}; + +%} + diff --git a/Examples/test-suite/valuewrapper_base.i b/Examples/test-suite/valuewrapper_base.i new file mode 100644 index 000000000..1698c3e03 --- /dev/null +++ b/Examples/test-suite/valuewrapper_base.i @@ -0,0 +1,28 @@ +%module valuewrapper_base +%inline +%{ + namespace oss + { + enum Polarization { UnaryPolarization, BinaryPolarization }; + + struct Base + { + }; + + template + struct Interface : Base + { + Interface(const Base& b) { }; + }; + + template + Result make() { return Result(*new Base()); } + } +%} + +namespace oss +{ + // Interface + %template(Interface_BP) Interface; + %template(make_Interface_BP) make >; +} diff --git a/Examples/test-suite/virtual_destructor.i b/Examples/test-suite/virtual_destructor.i new file mode 100644 index 000000000..da357c4a3 --- /dev/null +++ b/Examples/test-suite/virtual_destructor.i @@ -0,0 +1,16 @@ +/* +This testcase checks that a virtual destructor with void as a parameter is +correctly handled. +*/ + +%module virtual_destructor + +%inline %{ + +class VirtualVoidDestructor { +public: + VirtualVoidDestructor() {}; + virtual ~VirtualVoidDestructor(void) { }; +}; + +%} diff --git a/Examples/test-suite/voidtest.i b/Examples/test-suite/voidtest.i new file mode 100644 index 000000000..37d6d9fc5 --- /dev/null +++ b/Examples/test-suite/voidtest.i @@ -0,0 +1,16 @@ +%module voidtest + +%inline %{ + +void globalfunc(void) { +}; + +class Foo { +public: + Foo() { }; + void memberfunc(void) { }; + static void staticmemberfunc(void) { }; +}; + +%} + \ No newline at end of file diff --git a/FUTURE b/FUTURE new file mode 100644 index 000000000..eebb0fa87 --- /dev/null +++ b/FUTURE @@ -0,0 +1,335 @@ +SWIG-1.3.12, SWIG 2.0, and Beyond +================================= + +With the release of SWIG-1.3.12, I thought I'd take a few moments of +everyone's time to talk about the past, the present, and the future of +SWIG development. I'm really quite excited about the current release +because I think it represents a huge turning point in SWIG's +development. Furthermore, it is only the beginning of bigger and +better things to come. However, we definitely need your help. + +To put a little perspective on the discussion, I'd start with a few +development statistics. In the last 12 months, there have been over +300 entries added to the CHANGES log and over 4000 CVS commits. +Although that may not sound like a lot compared to a huge software +project, it is significant in the context of SWIG. As a point of +comparison, there has been more SWIG development this year than in any +other year of the project and more than in the previous three years +combined. This even includes the first few years of development in +which there was also a lot of activity. Furthermore, many of the +recent changes have been extremely non-trivial (e.g., templates, +namespaces, type system, operators, etc.). As a result, SWIG is more +capable than I ever imagined possible. + +Regrettably, I must admit that I've been a little negligent in +discussing the roadmap for where I thought this flurry of SWIG +development was actually headed. In part, this is because I've been +buried in work. However, the real reason is that I didn't really know +where we were going---except that in a time far far far away in the +future, we might arrive at some kind of "stable" release with a +version number other than "1.3.x". Needless to say, that's not a very +compelling story. + +That said, I've spent a lot of time thinking about SWIG and trying to +wrap my brain around it. Specifically, just what is (or should be) +the primary focus of this project and what are we really trying to do? +That's what the rest of this message is about. + +SWIG Prehistory +--------------- +The first version of SWIG was written in 1995. The original system +was developed to help with some software wrapping problems I +encountered while writing molecular dynamics software at Los +Alamos. Later that year, I became interested in extending the wrapper +generator to support other scripting languages so it was rewritten in +C++ and modified with multiple backends (Tcl, Perl, and Guile). This +led to a first public release in February, 1996. Feedback from this +release led to a series of enhancements and the release of SWIG 1.0 in +September 1996. Throughout this process, my intent was to create a +tool that I would want to use---I never viewed the project as an +CS experiment in programming languages or software engineering. + +SWIG 1.1 +-------- +SWIG-1.1 (June, 1997) represented a series of enhancements that were +added in response to feedback at conferences and from users. Shadow +classes, exception handling, typemaps, and a number of more useful +features were added. However, the overall structure of the system was +relatively unchanged from the initial version. Following the release +of 1.1, a series of minor patch releases were made. This resulted in +the release of SWIG-1.1p5 in February, 1998. Unfortunately, this +release would remain the last "stable" release for quite a long +time---in fact, it is still listed as the last "stable" release on the +SWIG web page! + +SWIG Hell +--------- +Even during the development of SWIG-1.1, it was clear that the whole +design of the system was deeply flawed. The implementation was a mess +and the C/C++ support was full of holes and nasty corner cases. +Furthermore, there was no unifying principle that tied all of the +different SWIG directives together. Not only that, fixing these +problems appeared to be nothing short of impossible---requiring a +total ground-up rewrite at best. The only redeeming quality was that +the system basically worked "well enough," it was extensively +documented, and its flaws mostly known. People could use it and there +were work-arounds for most common problems. + +To deal with the design problem, there were at least four attempts to +completely rewrite SWIG, some of which were attempted in parallel with +the work on SWIG-1.1. Unfortunately, none of these were ever +completed. The primary problem was a strong "second system" effect and +a desire to make SWIG do everything that one might conceivably want to +do with a wrapper generator (somehow). Clearly, this was a recipe for +disaster. In fact, all such attempts to rewrite SWIG were eventually +abandoned several years ago. In hindsight, I think the real problem +was that these rewrite efforts focused far too much attention on +implementation technique rather than principles. In short, the +failure of these efforts was due to a lack of clarity in understanding +how SWIG ought to work (regardless of how it was actually +implemented). + +SWIG Restart (1.3a1-1.3a5) +-------------------------- +Having languished for several years, the SWIG1.1p5 release had a +growing pile of maintenance issues. It didn't work for newer versions +of certain language modules and a lot of minor bug reports and feature +requests had been building up. With a lot of help from Loic Dachary and +Thien-Thi Nguyen, we put together the 1.3a1 release (February, +2000). This was mostly a bug fix release to 1.1p5 except that the +preprocessor module from SWIG1.2 was added and a lot of minor +enhancements were added. + +For the next six months, a massive effort was made to rewrite all of +SWIG's internal data structures (strings, lists, hashes, etc.). This +work was all going on underneath the covers while we tried to keep +SWIG in an operational state. The primary focus of this work was +really one of cleanup. Having given up on a total rewrite, perhaps +we could settle with making the implementation incrementally better +than before. In addition this, Matthias Koppe jumped on board to +reimplement the Guile module and to make other improvements to the system. + +An important aspect of these releases was that many parts of the +system not directly related to wrapper code generation were removed. +This included the documentation system and Objective-C support. These +were not removed because they weren't useful. Instead, the +documentation system was removed because it accounted for nearly half +of the special SWIG directives, yet had no direct bearing on what SWIG +actually did. Obective-C support was removed because it was tangled +with C++ support in a way that was very difficult to understand and +maintain. The removal of these features was seen as a way to vastly +simplify cleanup--and to buy some time where we could rethink their +role in a future release. + +SWIG Redux (1.3.6-1.3.11) +------------------------- +This work, started in February 2001, is the beginning of the current +SWIG implementation. With the help of William Fulton, Matthias Koppe, +Lyle Johnson, Luigi Ballabio, Jason Stewart, Richard Palmer, Sam +Liddicot, and others, this work can best be described as the wholesale +destruction of everything remaining from SWIG-1.1. The language +module API, type system, the parser, numerous SWIG directives, and +SWIG library files---all destroyed or rewritten. Not only that, we +started introducing significant incompatibilities with +SWIG-1.1---mostly in an effort to correct past wrongs and get +ourselves out of the tangled mess of earlier versions. A huge number +of long-standing bugs and difficult feature requests have also been +resolved. + +The general goal of this development could best be described as an +attempt to reduce SWIG to an easily described set of general "ideas" +about how it should operate. Special SWIG directives have been +eliminated or combined with others. Different parts of the system have +been better integrated. Features not directly related to wrapper code +generation have been removed and the system has become more +focused. Changes in internal data structures and APIs have allowed +SWIG to capture more information from interface files and to resolve +hard corner cases. More often than not, these are things that you +never notice unless you are an old user and you suddenly realize that +a problem you had several years back has disappeared. + +Along with the destruction of old code, this work has quietly +introduced a new core--the most significant features of which are a +new C++ type system and multi-pass compilation. More importantly, +this work has really tried to provide a more principled foundation for +future SWIG development. However, just what is this "more principled +foundation?" + +Convergence (1.3.12) +-------------------- +With the upcoming 1.3.12 release, SWIG is about to take a big leap +forward. Almost all of this is due to one realization---that almost +every hard problem in past SWIG releases has been directly related to +errors and limitations in its type system. Types are the key to +understanding the structure of C and C++ code. They are at the heart +of understanding advanced language features like namespaces, nested +classes, and templates. They are directly related to the data +marshalling that occurs in wrappers. Not only that, they interact +with nearly every SWIG directive. A proper type system *is* the +necessary foundation for moving SWIG forward. + +To be honest, I don't think that the emphasis on types is entirely +obvious. In fact, a great deal of work in past SWIG rewrites has +focused on the problem of C++ parsing. For instance, modifying the +parser to handle more advanced C++ code or representing parse trees as +XML. Furthermore, if one looks at the SWIG mailing list, you can find +a *lot* of messages related to issues of C++ parsing whereas almost no +one ever talks about types (well, other than typemaps). Even other +wrapper generation tools seems to spend a lot of time dealing with the +parsing issue. Although parsing is clearly important, I don't think it +has ever been the real problem in SWIG. This is because even though a +parser can tell you what's in a header file, it doesn't tell you +anything about how the different pieces of the system behave or how +they might interact. To do that, you need to do a lot more than just +parsing--and that's really the whole point. + +Although earlier 1.3 releases have made big improvements to the type +system, SWIG-1.3.12 is the first release that really tries to tackle +the type-system issue in a major way. We have patched nearly all +remaining holes in the type system and we have added full support for +C++ namespaces. Not only that, we have completely reimplemented C++ +template support in a way that supports templates, member templates, +and template specialization. Luigi and I are currently using this to +work on proper SWIG library support for parts of the C++ standard +library and the Standard Template Library (STL). Although some crusty +C programmers (present company excepted), might balk at such apparent +insanity, this work has impacted all parts of SWIG at all levels. +Even a variety of subtle errors in C support have been fixed by this +work. + +In addition to the type system work, SWIG-1.3.12 contains continued +reduction in the implementation. Directives have been removed, +refined, renamed, or consolidated. We're still narrowing the focus of +the system and working towards some kind of convergence. "Convergence +to what?!?", you ask. + +So, what is SWIG? +----------------- +In a nutshell, SWIG is a C/C++ declaration compiler that generates +wrapper code (okay, so you knew that much). However, to really +understand what SWIG is doing and where SWIG-1.3.x is headed, it is +useful to know that the whole system is essentially being built around +three extensions to the C++ type system: + + - Typemaps. Typemaps are rules that define the process by which + data is converted between languages. They are fully integrated + with the C++ type system and they are applied using a type-based + pattern matching mechanism. All data conversion SWIG is + defined by typemaps and is fully reconfigurable. + + - Declaration annotation. There are special directives that modify + the wrapping behavior of individual declarations. Declarations + can be selectively identified and decorated with arbitrary + attributes that affect wrapper generation. Like typemaps, + declaration matching is fully integrated with the C++ type system. + Almost all SWIG customization directives are a form of declaration + annotation. + + - Class extension. The ability to extend classes and structures + with new methods/attributes when building wrappers. Classes + are part of the type system so class extension is naturally + integrated with the C++ type system as well (big surprise). + +And that's it--this is the end-game of SWIG-1.3.x development. When +stabilized and documented it will become SWIG-2.0. + +The Bigger Picture +------------------ +I really want to emphasize that all of this work is part of a much +bigger picture. SWIG is used by a surprising number of people in +industry, government, and academia. It's used to build systems used +by millions of people every day. It has even shown up in video games +and other unlikely settings. Although SWIG doesn't have the same +visibility as many large software projects, over 12000 people have +downloaded SWIG-1.3.11 in the last 4 months. Clearly someone is using +it for something! Because of this, I think it is important for us to +work on moving SWIG towards a more solid foundation. Doing so will +give the system more credibility and long term viability---and it will +be a lot more fun to use! + +It's also worth noting that there are some rather interesting CS +connections at work here. Extensions to the type system and typemaps +have some interesting relations to work in programming languages. The +SWIG declaration annotation system and class extension feature seem +oddly similar to work in the emerging area of Aspect Oriented +Programming (AOP). There are undoubtedly connections to other areas +of software engineering and architecture. + +The key point is that SWIG isn't going to connect to anything if +no-one can quite describe what it is or how it works. + +SWIG-2.0 and the Future +----------------------- +SWIG-1.3.12 still represents work in progress. There are bugs, the +documentation is still incomplete, and there are parts of the +implementation that are rather ugly. We are also still working out a +few very hard problems like nested classes, callback functions, and +overloading. A few old features are still missing (Objective-C, +documentation). However, I believe the end of the 1.3.x series is +near and achievable. + +Over the summer, a few more 1.3.x releases may appear but the current +plan is to aim for a SWIG-2.0 release in September. This release is +really moving towards the design principles described above and will +be a very major enhancement over SWIG-1.1. + +As for the future, a number of interesting ideas are on the table. I +want to add support for contracts/assertions in order to solve some +reliability issues that arise when retrofitting legacy codes with a +scripting interface. Support for an extension language has been +promoted by David Fletcher and was suggested by someone else on the +mailing list rather recently. I have a graduate student working on +SWIG support for the Microsoft CLR and .NET languages. Other work +might include support for alternative parsers, dynamically loadable +language modules, and so forth. However, none of this is really going +to materialize if we can't get the 2.0 release stablized. In fact, I +see SWIG-2.0 as a necessary step for moving forward with these ideas. + +We need your help! Yes, you. +---------------------------- +Nobody gets paid to work on SWIG. The developers are volunteers who +work in their spare time. Furthermore, SWIG is not supported by +investors, a large corporation, or research grants. I work on it +because it's fun, challenging, and useful. I presume that other +developers do the same. However, we only have limited resources and +we need your help. + +- If you like SWIG and find it useful, we need you to try new versions. + We want you to torture test the releases and to break them. We need + bug reports. No bug is too obscure or unimportant---we *will* fix it + if we can. We also need feedback about things that are annoying or + compatibility features that might help in going from 1.1 to 2.0. + +- We need help with documentation, examples, testing, libraries, and all + sorts of other aspects of the release. Even if you have never + written a SWIG language module or dived into its implementation, + there are many ways that you can help. Consider writing a case study + about how you wrapped a big library. Contribute tests that break the + implementation in horrible ways. Help with the web page or FAQ. + +- Most of the SWIG-1.3.x work has focused on the SWIG core. However, as + the 2.0 release nears, we will be working on a variety of enhancements + to the language modules. If there are things you would like to see + in any of the language modules, you need to let us know. + +- There are SWIG language modules that have not made it into the + distribution. Examples that I know about include ITCL, Swig-Eiffel, + and Swig-Lua. We would gladly make these part of the standard SWIG + distribution. However, we also need help to do it. Porting from + SWIG-1.1 is no easy task, but we're more than willing to help. It's + not as bad as one might imagine. + +- We are always looking for developers. Subscribe to + swig-dev@cs.uchicago.edu (http://mailman.cs.uchicago.edu/listinfo/swig-dev) + or send me email to get involved. + +Acknowledgements +---------------- +I'd just like to thank everyone who has submitted feedback, bugs, made +contributions, and put up with my occasional thrashing over the years. +I welcome any comments about this document and how we can make SWIG even +better. + +Dave Beazley (beazley@cs.uchicago.edu) +June 2, 2002 + diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..666ffd9f8 --- /dev/null +++ b/INSTALL @@ -0,0 +1,226 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for variables by setting +them in the environment. You can do that on the command line like this: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Environment Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it cannot guess the host type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the host +platform (i.e., that on which the generated programs will eventually be +run) with `--host=TYPE'. In this case, you should also specify the +build platform with `--build=TYPE', because, in this case, it may not +be possible to guess the build platform (it sometimes involves +compiling and running simple test programs, and this can't be done if +the compiler is a cross compiler). + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Environment Variables +===================== + + Variables not defined in a site shell script can be set in the +environment passed to configure. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Lib/_std_deque.i b/Lib/_std_deque.i new file mode 100644 index 000000000..907450719 --- /dev/null +++ b/Lib/_std_deque.i @@ -0,0 +1,143 @@ +/* This file contains a generic definition of std::deque along with + * some helper functions. Specific language modules should include + * this file to generate wrappers. + */ + +%{ +#include +#include +%} + +%include "exception.i" + +%exception std::deque::getitem { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::deque::setitem { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::deque::delitem { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +/* This macro defines all of the standard methods for a deque. This + is defined as a macro to simplify the task of specialization. For + example, + + template<> class deque { + public: + %std_deque_methods(int); + }; +*/ + +%define %std_deque_methods(T) + typedef T &reference; + typedef const T& const_reference; + + deque(); + deque(unsigned int size, const T& value=T()); + deque(const deque &); + ~deque(); + + void assign(unsigned int n, const T& value); + void swap(deque &x); + unsigned int size() const; + unsigned int max_size() const; + void resize(unsigned int n, T c = T()); + bool empty() const; + const_reference front(); + const_reference back(); + void push_front(const T& x); + void push_back(const T& x); + void pop_front(); + void pop_back(); + void clear(); + + /* Some useful extensions */ + %extend { + const_reference getitem(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && isize()); + if (i<0) i+= size; + if (i>=0 && isize()); + if (i<0) i+= size; + if (i>=0 && ierase(self->begin()+i); + } else { + throw std::out_of_range("deque index out of range"); + } + } + std::deque getslice(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + std::deque tmp(j-i); + std::copy(self->begin()+i,self->begin()+j,tmp.begin()); + return tmp; + } + void setslice(int i, int j, const std::deque& v) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + if (int(v.size()) == j-i) { + std::copy(v.begin(),v.end(),self->begin()+i); + } else { + self->erase(self->begin()+i,self->begin()+j); + if (i+1 <= size) + self->insert(self->begin()+i+1,v.begin(),v.end()); + else + self->insert(self->end(),v.begin(),v.end()); + } + } + void delslice(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + self->erase(self->begin()+i,self->begin()+j); + } + }; + +%enddef + +namespace std { + template class deque { + public: + %std_deque_methods(T); + }; +} + + + diff --git a/Lib/array.i b/Lib/array.i deleted file mode 100644 index b592b39b5..000000000 --- a/Lib/array.i +++ /dev/null @@ -1,401 +0,0 @@ -// -// array.i -// Dave Beazley -// November 30, 1996 -// -// This SWIG library file provides access to C arrays. - -%module carray - -%section "SWIG C Array Module",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 - -%text %{ -%include array.i - -This module provides scripting language access to various kinds of C/C++ -arrays. For each datatype, a collection of four functions are created : - - _array(size) : Create a new array of given size - _get(array, index) : Get an element from the array - _set(array, index, value) : Set an element in the array - _destroy(array) : Destroy an array - -The functions in this library are only low-level accessor functions -designed to directly access C arrays. Like C, no bounds checking is -performed so use at your own peril. -%} - -// Grab the SWIG exception library - -#ifndef AUTODOC -%include exception.i -#endif - -// A Typemap used to check input arguments. - -%typemap(check) int *, double *, float *, char **, short *, long * { - if (!$target) { - SWIG_exception(SWIG_ValueError,"Received a NULL Pointer"); - } -} - -%typemap(ret) int *, double *, float *, char **, short *, long * { - if (!$source) { - SWIG_exception(SWIG_MemoryError,"Out of memory."); - } -} - -// ----------------------------------------------------------------------- -// Integer array support -// ----------------------------------------------------------------------- - -%subsection "Integer Arrays" -%text %{ -The following functions provide access to integer arrays (mapped -onto the C 'int' datatype. -%} - -%{ -#include - -/* Create a new integer array */ - - static int *int_array(int size) { -#ifdef __cplusplus - return new int[size]; -#else - return (int *) malloc(size*sizeof(int)); -#endif - } - - /* Destroy an integer array */ - - static void int_destroy(int *array) { - if (array) { -#ifdef __cplusplus - delete [] array; -#else - free(array); -#endif - } - } - - /* Return an element */ - - static int int_get(int *array, int index) { - if (array) { - return array[index]; - } else { - return INT_MIN; - } - } - - /* Set an element */ - - static int int_set(int *array, int index, int value) { - if (array) { - return (array[index] = value); - } else { - return INT_MIN; - } - } - -%} - -int *int_array(int nitems); -/* Creates a new array of integers. nitems specifies the number of elements. - The array is created using malloc() in C and new() in C++. */ - -void int_destroy(int *array); -/* Destroys the given array. */ - -int int_get(int *array, int index); -/* Returns the value of array[index]. */ - -int int_set(int *array, int index, int value); -/* Sets array[index] = value. Returns value. */ - - -// ----------------------------------------------------------------------- -// Floating point -// ----------------------------------------------------------------------- - -%subsection "Floating Point Arrays" -/* The following functions provide access to arrays of floats and doubles. */ - - -%{ - #include - - /* Create a new float array */ - - static float *float_array(int size) { -#ifdef __cplusplus - return new float[size]; -#else - return (float *) malloc(size*sizeof(float)); -#endif - } - - /* Destroy an array */ - - static void float_destroy(float *array) { - if (array) { -#ifdef __cplusplus - delete [] array; -#else - free(array); -#endif - } - } - - /* Return an element */ - - static float float_get(float *array, int index) { - if (array) { - return array[index]; - } else { - return FLT_MIN; - } - } - - /* Set an element */ - - static float float_set(float *array, int index, float value) { - if (array) { - return (array[index] = value); - } else { - return FLT_MIN; - } - } - - /* Create a new double array */ - - static double *double_array(int size) { -#ifdef __cplusplus - return new double[size]; -#else - return (double *) malloc(size*sizeof(double)); -#endif - } - - /* Destroy an array */ - - static void double_destroy(double *array) { - if (array) { -#ifdef __cplusplus - delete [] array; -#else - free(array); -#endif - } - } - - /* Return an element */ - - static double double_get(double *array, int index) { - if (array) { - return array[index]; - } else { - return FLT_MIN; - } - } - - /* Set an element */ - - static double double_set(double *array, int index, double value) { - if (array) { - return (array[index] = value); - } else { - return FLT_MIN; - } - } - -%} - -double *double_array(int nitems); -/* Creates a new array of doubles. nitems specifies the number of elements. - The array is created using malloc() in C and new() in C++. */ - -void double_destroy(double *array); -/* Destroys the given array. */ - -double double_get(double *array, int index); -/* Returns the value of array[index]. */ - -double double_set(double *array, int index, double value); -/* Sets array[index] = value. Returns value. */ - -float *float_array(int nitems); -/* Creates a new array of floats. nitems specifies the number of elements. - The array is created using malloc() in C and new() in C++. */ - -void float_destroy(float *array); -/* Destroys the given array. */ - -float float_get(float *array, int index); -/* Returns the value of array[index]. */ - -float float_set(float *array, int index, float value); -/* Sets array[index] = value. Returns value. */ - -// ----------------------------------------------------------------------- -// Character strings -// ----------------------------------------------------------------------- - -%subsection "String Arrays" - -%text %{ -The following functions provide support for the 'char **' datatype. This -is primarily used to handle argument lists and other similar structures that -need to be passed to a C/C++ function. -%} - -#if defined(SWIGTCL) -%text %{ -To convert from a Tcl list into a 'char **', the following code can be used : - - # $list is a list - set args [string_array expr {[llength $list] + 1}] - set i 0 - foreach a $list { - string_set $args $i $a - incr i 1 - } - string_set $i "" - # $args is now a char ** type -%} -#elif defined(SWIGPERL) - -%text %{ -To convert from a Perl list into a 'char **', code similar to the following -can be used : - - # @list is a list - my $l = scalar(@list); - my $args = string_array($l+1); - my $i = 0; - foreach $arg (@list) { - string_set($args,$i,$arg); - $i++; - } - string_set($args,$i,""); - -(of course, there is always more than one way to do it) -%} -#elif defined(SWIGPYTHON) - -%text %{ -To convert from a Python list to a 'char **', code similar to the following -can be used : - - # 'list' is a list - args = string_array(len(list)+1) - for i in range(0,len(list)): - string_set(args,i,list[i]) - string_set(args,len(list),"") -%} - -#endif - -%{ -/* Create character string arrays */ - -static char **string_array(int size) { - char **a; - int i; -#ifdef __cplusplus - a = new char *[size]; -#else - a = (char **) malloc(size*sizeof(char *)); -#endif - for (i = 0; i < size; i++) - a[i] = 0; - return a; -} - -/* Destroy a string array */ - -static void string_destroy(char **array) { - int i = 0; - if (array) { - while (array[i]) { -#ifdef __cplusplus - delete array[i]; -#else - free(array[i]); -#endif - i++; - } -#ifdef __cplusplus - delete [] array; -#else - free(array); -#endif - } -} - -/* Get an element */ - -static char *string_get(char **array_string, int index) { - if (array_string) - if (array_string[index]) return (array_string[index]); - else return ""; - else - return ""; -} - -/* Set an element */ - -static char *string_set(char **array_string, int index, char * val) { - if (array_string) { - if (array_string[index]) { -#ifdef __cplusplus - delete array_string[index]; -#else - free(array_string[index]); -#endif - } - if (strlen(val) > 0) { -#ifdef __cplusplus - array_string[index] = new char[strlen(val)+1]; -#else - array_string[index] = (char *) malloc(strlen(val)+1); -#endif - strcpy(array_string[index],val); - return array_string[index]; - } else { - array_string[index] = 0; - return val; - } - } else return val; -} - -%} - -char **string_array(int nitems); -/* Creates a new array of strings. nitems specifies the number of elements. - The array is created using malloc() in C and new() in C++. Each element - of the array is set to NULL upon initialization. */ - -void string_destroy(char **array); -/* Destroys the given array. Each element of the array is assumed to be - a NULL-terminated string allocated with malloc() or new(). All of - these strings will be destroyed as well. (It is probably only safe to - use this function on an array created by string_array) */ - -char *string_get(char **array, int index); -/* Returns the value of array[index]. Returns a string of zero length - if the corresponding element is NULL. */ - -char *string_set(char **array, int index, char *value); -/* Sets array[index] = value. value is assumed to be a NULL-terminated - string. A string of zero length is mapped into a NULL value. When - setting the value, the value will be copied into a new string allocated - with malloc() or new(). Any previous value in the array will be - destroyed. */ - - -%typemap(check) int *, double *, float *, char **, short *, long * = PREVIOUS; -%typemap(out) int *, double *, float *, char **, short *, long * = PREVIOUS; - diff --git a/Lib/autodoc.i b/Lib/autodoc.i deleted file mode 100644 index 0ef408da7..000000000 --- a/Lib/autodoc.i +++ /dev/null @@ -1,101 +0,0 @@ -// This file automatically generates the SWIG library documentation -%doconly -%style latex_section="\\newpage \\section{:}" -%title "SWIG Library Reference",pre,sort,chop_left = 0,noinfo -/* -Version 1.1p4 -January, 1998 - -Copyright (C) 1996-1998 -Dave Beazley - -(This file was automatically generated by SWIG) -*/ -%style html_contents="


      :

      " -%module swig_lib - -%section " Introduction" -%text %{ -This file describes all of the functions in the generic SWIG library. -The SWIG library is a collection of generally useful functions that -can be used to supplement an interface file. These include functions -to manipulate arrays, functions from the C library, and interesting -modules. - -This document is automatically generated by SWIG from the file -"swig_lib/autodoc.i". Some modules may supply additional documentation -for a particular target language. To recreate the documentation for -a particular target language, simply run SWIG on the file 'autodoc.i' -with the appropriate target language option. -%} - -#if defined(SWIGTCL) -%text %{ -This document has been generated for Tcl. -%} -#elif defined(SWIGPERL) -%text %{ -This document has been generated for Perl. -%} -#elif defined(SWIGPYTHON) -%text %{ -This document has been generated for Python. -%} -#endif - -%subsection "Call for contributions" -%text %{ -My long-term goal is for the SWIG library to be a collection of useful -modules that can be used to quickly put together interesting programs. -To contribute new modules send e-mail to beazley@cs.utah.edu and I -will include them here. -%} - -#define AUTODOC - -%include array.i -%include math.i -%include timers.i -%include malloc.i -%include memory.i -%include exception.i -%include pointer.i -%include constraints.i -%include typemaps.i - -#ifdef SWIGTCL -%section "Tcl Library Files",nosort -%text %{ -The following library modules are available when using the Tcl -language module. -%} -%include "tcl/consthash.i" -%include "tcl/constarray.i" -%include "tcl/tclsh.i" -%include "tcl/wish.i" -#endif - -#ifdef SWIGPYTHON -%section "Python Library Files",nosort -%text %{ -The following modules are available when using the Python language -module. -%} -%include "python/embed.i" -%include "python/embed14.i" -%include "python/embed13.i" - -#endif - -#ifdef SWIGPERL -%section "Perl Library Files",nosort - -%text %{ -The following modules are available when using the Perl5 language -module. -%} - -%include "perl5/perlmain.i" -#endif - - diff --git a/Lib/carray.i b/Lib/carray.i deleted file mode 100644 index 5bcdea528..000000000 --- a/Lib/carray.i +++ /dev/null @@ -1,175 +0,0 @@ -// -// $Header$ -// carray.i -// Dave Beazley -// March 24, 1996 -// -// This SWIG library file supports C arrays of various datatypes. -// These arrays are probably *not* compatible with scripting languages -// but they are compatible with C functions. -// -/* Revision History - * -- $Log$ - * -- Revision 1.1 2000/01/11 21:15:47 beazley - * -- Added files - * -- - * -- Revision 1.1.1.1 1999/02/28 02:00:53 beazley - * -- Swig1.1 - * -- - * -- Revision 1.1 1996/05/22 17:23:48 beazley - * -- Initial revision - * -- - */ - -%module carray -%{ - -#include - -/* Create an integer array of given size */ - -static int *array_int(int size) { - return (int *) malloc(size*sizeof(int)); -} - -static int get_int(int *array_int, int index) { - if (array_int) - return (array_int[index]); - else - return 0; -} - -static int set_int(int *array_int, int index, int val) { - if (array_int) - return (array_int[index] = val); - else - return 0; -} - -/* Create double precision arrays */ - -static double *array_double(int size) { - return (double *) malloc(size*sizeof(double)); -} - -static double get_double(double *array_double, int index) { - if (array_double) - return (array_double[index]); - else - return 0; -} - -static double set_double(double *array_double, int index, double val) { - if (array_double) - return (array_double[index] = val); - else - return 0; -} - -/* Create byte arrays */ - -typedef unsigned char byte; - -static byte *array_byte(int size) { - return (byte *) malloc(size*sizeof(byte)); -} - -static byte get_byte(byte *array_byte, int index) { - if (array_byte) - return (array_byte[index]); - else - return 0; -} - -static byte set_byte(byte *array_byte, int index, byte val) { - if (array_byte) - return (array_byte[index] = val); - else - return 0; -} - -/* Create character string arrays */ - -static char **array_string(int size) { - char **a; - int i; - - a = (char **) malloc(size*sizeof(char *)); - for (i = 0; i < size; i++) - a[i] = 0; - return a; -} - -static char *get_string(char **array_string, int index) { - if (array_string) - return (array_string[index]); - else - return ""; -} - -static char *set_string(char **array_string, int index, char * val) { - if (array_string) { - if (array_string[index]) free(array_string[index]); - if (strlen(val) > 0) { - array_string[index] = (char *) malloc(strlen(val)+1); - strcpy(array_string[index],val); - return array_string[index]; - } else { - array_string[index] = 0; - return val; - } - } - else - return val; - } - -%} - -%section "Array Operations" - -int *array_int(int size); -/* Creates an integer array of size elements. Integers are the same -size as the C int type. */ - -int get_int(int *array_int, int index) ; -/* Return the integer in array_int[index] */ - -int set_int(int *array_int, int index, int ival); -/* Sets array_int[index] = ival. Returns it's value so you -can use this function in an expression. */ - -/* Create double precision arrays */ - -double *array_double(int size); -/* Creates an array of double precision floats. */ - -double get_double(double *array_double, int index); -/* Return the double in array_double[index] */ - -double set_double(double *array_double, int index, double dval); -/* Sets array_double[index] = dval. Returns it's value */ - -typedef unsigned char byte; - -byte *array_byte(int nbytes); -/* Creates a byte array. A byte is defined as an unsigned char. */ - -byte get_byte(byte *array_byte, int index); -/* Returns array_byte[index] */ - -byte set_byte(byte *array_byte, int index, byte val); -/* Sets array_byte[index] = val. Returns it's new value */ - -char **array_string(int size); -/* Creates a string array. A string is array is the same as char ** in C */ - -char *get_string(char **array_string, int index); -/* Returns character string in array_string[index]. If that entry is -NULL, returns an empty string */ - -char *set_string(char **array_string, int index, char * string); -/* Sets array_string[index] = string. string must be a 0-terminated -ASCII string. If string is "" then this will create a NULL pointer. */ - - - diff --git a/Lib/carrays.i b/Lib/carrays.i new file mode 100644 index 000000000..f5cb2e681 --- /dev/null +++ b/Lib/carrays.i @@ -0,0 +1,132 @@ +/* ----------------------------------------------------------------------------- + * carrays.i + * + * Author(s): David Beazley (beazley@cs.uchicago.edu) + * + * This library file contains macros that can be used to manipulate simple + * pointers as arrays. + * + * $Header$ + * ----------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------------- + * %array_functions(TYPE,NAME) + * + * Generates functions for creating and accessing elements of a C array + * (as pointers). Creates the following functions: + * + * TYPE *new_NAME(int nelements) + * void delete_NAME(TYPE *); + * TYPE NAME_getitem(TYPE *, int index); + * void NAME_setitem(TYPE *, int index, TYPE value); + * + * ----------------------------------------------------------------------------- */ + +%define %array_functions(TYPE,NAME) +%{ +static TYPE *new_##NAME(int nelements) { %} +#if __cplusplus +%{ return new TYPE[nelements]; %} +#else +%{ return (TYPE *) calloc(nelements,sizeof(TYPE)); %} +#endif +%{} + +static void delete_##NAME(TYPE *ary) { %} +#if __cplusplus +%{ delete [] ary; %} +#else +%{ free(ary); %} +#endif +%{} + +static TYPE NAME##_getitem(TYPE *ary, int index) { + return ary[index]; +} +static void NAME##_setitem(TYPE *ary, int index, TYPE value) { + ary[index] = value; +} +%} + +TYPE *new_##NAME(int nelements); +void delete_##NAME(TYPE *ary); +TYPE NAME##_getitem(TYPE *ary, int index); +void NAME##_setitem(TYPE *ary, int index, TYPE value); + +%enddef + + +/* ----------------------------------------------------------------------------- + * %array_class(TYPE,NAME) + * + * Generates a class wrapper around a C array. The class has the following + * interface: + * + * struct NAME { + * NAME(int nelements, TYPE value = 0); + * ~NAME(); + * TYPE getitem(int index); + * void setitem(int index, TYPE value); + * TYPE * cast(); + * static NAME *frompointer(TYPE *t); + * } + * + * ----------------------------------------------------------------------------- */ + +%define %array_class(TYPE,NAME) +%{ +typedef TYPE NAME; +%} +typedef struct NAME { + /* Put language specific enhancements here */ + +#if SWIGPYTHON + %rename(__getitem__) getitem; + %rename(__setitem__) setitem; +#endif +} NAME; + +%extend NAME { + +#if __cplusplus +NAME(int nelements) { + return new TYPE[nelements]; +} +~NAME() { + delete [] self; +} +#else +NAME(int nelements) { + return (TYPE *) calloc(nelements,sizeof(TYPE)); +} +~NAME() { + free(self); +} +#endif + +TYPE getitem(int index) { + return self[index]; +} +void setitem(int index, TYPE value) { + self[index] = value; +} +TYPE * cast() { + return self; +} +static NAME *frompointer(TYPE *t) { + return (NAME *) t; +} + +}; + +%types(NAME = TYPE); + +%enddef + + + + + + + + diff --git a/Lib/cdata.i b/Lib/cdata.i new file mode 100644 index 000000000..8076e7f35 --- /dev/null +++ b/Lib/cdata.i @@ -0,0 +1,92 @@ +/* ----------------------------------------------------------------------------- + * cdata.i + * + * Author(s): David Beazley (beazley@cs.uchicago.edu) + * + * This library file contains macros for manipulating raw C data as strings. + * + * $Header$ + * ----------------------------------------------------------------------------- */ + +%{ +typedef struct SWIGCDATA { + char *data; + int len; +} SWIGCDATA; +%} + +/* ----------------------------------------------------------------------------- + * Typemaps for returning binary data + * ----------------------------------------------------------------------------- */ + +#if SWIGPYTHON +%typemap(out) SWIGCDATA { + $result = PyString_FromStringAndSize($1.data,$1.len); +} +%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); +#elif SWIGPERL +%typemap(out) SWIGCDATA { + ST(argvi) = sv_newmortal(); + sv_setpvn((SV*)ST(argvi++),$1.data,$1.len); +} +%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); +#elif SWIGTCL +%typemap(out) SWIGCDATA { + Tcl_SetObjResult(interp,Tcl_NewStringObj($1.data,$1.len)); +} +%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); +#elif SWIGRUBY +%typemap(out) SWIGCDATA { + $result = rb_str_new($1.data,$1.len); +} +%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); +#elif SWIGGUILE +%typemap(out) SWIGCDATA { + $result = gh_str2scm($1.data,$1.len); +} +%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); +#else +%echo "cdata.i module not supported." +#endif + + +/* ----------------------------------------------------------------------------- + * %cdata(TYPE [, NAME]) + * + * Convert raw C data to a binary string. + * ----------------------------------------------------------------------------- */ + +%define %cdata(TYPE,...) + +%insert("header") { +#if #__VA_ARGS__ == "" +static SWIGCDATA cdata_##TYPE(TYPE *ptr, int nelements) { +#else +static SWIGCDATA cdata_##__VA_ARGS__(TYPE *ptr, int nelements) { +#endif + SWIGCDATA d; + d.data = (char *) ptr; +#if #TYPE != "void" + d.len = nelements*sizeof(TYPE); +#else + d.len = nelements; +#endif + return d; +} +} +#if #__VA_ARGS__ == "" +SWIGCDATA cdata_##TYPE(TYPE *ptr, int nelements = 1); +#else +SWIGCDATA cdata_##__VA_ARGS__(TYPE *ptr, int nelements = 1); +#endif +%enddef + +%name(cdata) +%cdata(void); + +/* Memory move function */ +void memmove(void *data, const void *indata, int inlen); + + + + diff --git a/Lib/cmalloc.i b/Lib/cmalloc.i new file mode 100644 index 000000000..aa378ea2a --- /dev/null +++ b/Lib/cmalloc.i @@ -0,0 +1,110 @@ +/* ----------------------------------------------------------------------------- + * cmalloc.i + * + * Author(s): David Beazley (beazley@cs.uchicago.edu) + * + * This library file contains macros that can be used to create objects using + * the C malloc function. + * + * $Header$ + * ----------------------------------------------------------------------------- */ + +%{ +#include +%} + +/* %malloc(TYPE [, NAME = TYPE]) + %calloc(TYPE [, NAME = TYPE]) + %realloc(TYPE [, NAME = TYPE]) + %free(TYPE [, NAME = TYPE]) + %allocators(TYPE [,NAME = TYPE]) + + Creates functions for allocating/reallocating memory. + + TYPE *malloc_NAME(int nbytes = sizeof(TYPE); + TYPE *calloc_NAME(int nobj=1, int size=sizeof(TYPE)); + TYPE *realloc_NAME(TYPE *ptr, int nbytes); + void free_NAME(TYPE *ptr); + +*/ + +%define %malloc(TYPE,...) +#if #__VA_ARGS__ != "" +%name(malloc_##__VA_ARGS__) +#else +%name(malloc_##TYPE) +#endif +TYPE *malloc(int nbytes +#if #TYPE != "void" += sizeof(TYPE) +#endif +); +%enddef + +%define %calloc(TYPE,...) +#if #__VA_ARGS__ != "" +%name(calloc_##__VA_ARGS__) +#else +%name(calloc_##TYPE) +#endif +TYPE *calloc(int nobj = 1, int sz = +#if #TYPE != "void" +sizeof(TYPE) +#else +1 +#endif +); +%enddef + +%define %realloc(TYPE,...) +%insert("header") { +#if #__VA_ARGS__ != "" +TYPE *realloc_##__VA_ARGS__(TYPE *ptr, int nitems) +#else +TYPE *realloc_##TYPE(TYPE *ptr, int nitems) +#endif +{ +#if #TYPE != "void" +return (TYPE *) realloc(ptr, nitems*sizeof(TYPE)); +#else +return (TYPE *) realloc(ptr, nitems); +#endif +} +} +#if #__VA_ARGS__ != "" +TYPE *realloc_##__VA_ARGS__(TYPE *ptr, int nitems); +#else +TYPE *realloc_##TYPE(TYPE *ptr, int nitems); +#endif +%enddef + +%define %free(TYPE,...) +#if #__VA_ARGS__ != "" +%name(free_##__VA_ARGS__) void free(TYPE *ptr); +#else +%name(free_##TYPE) void free(TYPE *ptr); +#endif +%enddef + +%define %sizeof(TYPE,...) +#if #__VA_ARGS__ != "" +%constant int sizeof_##__VA_ARGS__ = sizeof(TYPE); +#else +%constant int sizeof_##TYPE = sizeof(TYPE); +#endif +%enddef + +%define %allocators(TYPE,...) +%malloc(TYPE,__VA_ARGS__) +%calloc(TYPE,__VA_ARGS__) +%realloc(TYPE,__VA_ARGS__) +%free(TYPE,__VA_ARGS__) +#if #TYPE != "void" +%sizeof(TYPE,__VA_ARGS__) +#endif +%enddef + + + + + diff --git a/Lib/common.swg b/Lib/common.swg index 6a51b84e0..c35ecb3a0 100644 --- a/Lib/common.swg +++ b/Lib/common.swg @@ -19,18 +19,23 @@ # if defined(_MSC_VER) # if defined(STATIC_LINKED) # define SWIGEXPORT(a) a +# define SWIGIMPORT(a) extern a # else # define SWIGEXPORT(a) __declspec(dllexport) a +# define SWIGIMPORT(a) extern a # endif # else # if defined(__BORLANDC__) # define SWIGEXPORT(a) a _export +# define SWIGIMPORT(a) a _export # else # define SWIGEXPORT(a) a +# define SWIGIMPORT(a) a +# endif # endif -#endif #else # define SWIGEXPORT(a) a +# define SWIGIMPORT(a) a #endif #ifdef SWIG_GLOBAL @@ -43,18 +48,29 @@ extern "C" { #endif +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + typedef struct swig_type_info { - char *name; - void *(*converter)(void *); - char *str; + const char *name; + swig_converter_func converter; + const char *str; + void *clientdata; + swig_dycast_func dcast; struct swig_type_info *next; struct swig_type_info *prev; } swig_type_info; #ifdef SWIG_NOINCLUDE -SWIGEXPORT(swig_type_info *) SWIG_TypeRegister(swig_type_info *); -SWIGEXPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *); -SWIGEXPORT(void *) SWIG_TypeCast(swig_type_info *, void *); + +SWIGIMPORT(swig_type_info *) SWIG_TypeRegister(swig_type_info *); +SWIGIMPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *); +SWIGIMPORT(void *) SWIG_TypeCast(swig_type_info *, void *); +SWIGIMPORT(swig_type_info *) SWIG_TypeDynamicCast(swig_type_info *, void **); +SWIGIMPORT(const char *) SWIG_TypeName(const swig_type_info *); +SWIGIMPORT(swig_type_info *) SWIG_TypeQuery(const char *); +SWIGIMPORT(void) SWIG_TypeClientData(swig_type_info *, void *); + #else static swig_type_info *swig_type_list = 0; @@ -69,6 +85,7 @@ SWIG_TypeRegister(swig_type_info *ti) while (tc) { if (strcmp(tc->name, ti->name) == 0) { /* Already exists in the table. Just add additional types to the list */ + if (tc->clientdata) ti->clientdata = tc->clientdata; head = tc; next = tc->next; goto l1; @@ -104,7 +121,7 @@ SWIG_TypeCheck(char *c, swig_type_info *ty) swig_type_info *s; if (!ty) return 0; /* Void pointer */ s = ty->next; /* First element always just a name */ - while (s) { + do { if (strcmp(s->name,c) == 0) { if (s == ty->next) return s; /* Move s to the top of the linked list */ @@ -119,11 +136,11 @@ SWIG_TypeCheck(char *c, swig_type_info *ty) return s; } s = s->next; - } + } while (s && (s != ty->next)); return 0; } -/* Cast a pointer (needed for C++ inheritance */ +/* Cast a pointer up an inheritance hierarchy */ SWIGRUNTIME(void *) SWIG_TypeCast(swig_type_info *ty, void *ptr) { @@ -131,8 +148,27 @@ SWIG_TypeCast(swig_type_info *ty, void *ptr) return (*ty->converter)(ptr); } +/* Dynamic pointer casting. Down an inheritance hierarchy */ +SWIGRUNTIME(swig_type_info *) +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) +{ + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* Return the name associated with this type */ +SWIGRUNTIME(const char *) +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + /* Search for a swig_type_info structure */ -SWIGRUNTIME(void *) +SWIGRUNTIME(swig_type_info *) SWIG_TypeQuery(const char *name) { swig_type_info *ty = swig_type_list; while (ty) { @@ -143,11 +179,28 @@ SWIG_TypeQuery(const char *name) { return 0; } +/* Set the clientdata field for a type */ +SWIGRUNTIME(void) +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_type_info *tc, *equiv; + if (ti->clientdata == clientdata) return; + ti->clientdata = clientdata; + equiv = ti->next; + while (equiv) { + if (!equiv->converter) { + tc = swig_type_list; + while (tc) { + if ((strcmp(tc->name, equiv->name) == 0)) + SWIG_TypeClientData(tc,clientdata); + tc = tc->prev; + } + } + equiv = equiv->next; + } +} #endif #ifdef __cplusplus } + #endif - - - diff --git a/Lib/constraints.i b/Lib/constraints.i index 12e7b2d56..f2ffb4848 100644 --- a/Lib/constraints.i +++ b/Lib/constraints.i @@ -8,8 +8,6 @@ // errors in a language-independent manner. #ifdef AUTODOC -%section "Constraint Library",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 - %text %{ %include constraints.i @@ -82,7 +80,7 @@ If you have used typedef to change type-names, you can also do this : double POSITIVE, Number POSITIVE { - if ($target <= 0) { + if ($1 <= 0) { SWIG_exception(SWIG_ValueError,"Expected a positive value."); } } @@ -101,7 +99,7 @@ If you have used typedef to change type-names, you can also do this : double NEGATIVE, Number NEGATIVE { - if ($target >= 0) { + if ($1 >= 0) { SWIG_exception(SWIG_ValueError,"Expected a negative value."); } } @@ -120,7 +118,7 @@ If you have used typedef to change type-names, you can also do this : double NONZERO, Number NONZERO { - if ($target == 0) { + if ($1 == 0) { SWIG_exception(SWIG_ValueError,"Expected a nonzero value."); } } @@ -139,7 +137,7 @@ If you have used typedef to change type-names, you can also do this : double NONNEGATIVE, Number NONNEGATIVE { - if ($target < 0) { + if ($1 < 0) { SWIG_exception(SWIG_ValueError,"Expected a non-negative value."); } } @@ -158,7 +156,7 @@ If you have used typedef to change type-names, you can also do this : double NONPOSITIVE, Number NONPOSITIVE { - if ($target > 0) { + if ($1 > 0) { SWIG_exception(SWIG_ValueError,"Expected a non-positive value."); } } @@ -168,7 +166,7 @@ If you have used typedef to change type-names, you can also do this : %typemap(check) void * NONNULL, Pointer NONNULL { - if (!$target) { + if (!$1) { SWIG_exception(SWIG_ValueError,"Received a NULL pointer."); } } @@ -179,7 +177,7 @@ If you have used typedef to change type-names, you can also do this : Pointer ALIGN8 { long tmp; - tmp = (long) $target; + tmp = (long) $1; if (tmp & 7) { SWIG_exception(SWIG_ValueError,"Pointer must be 8-byte aligned."); } @@ -189,7 +187,7 @@ If you have used typedef to change type-names, you can also do this : Pointer ALIGN4 { long tmp; - tmp = (long) $target; + tmp = (long) $1; if (tmp & 3) { SWIG_exception(SWIG_ValueError,"Pointer must be 4-byte aligned."); } @@ -199,7 +197,7 @@ If you have used typedef to change type-names, you can also do this : Pointer ALIGN2 { long tmp; - tmp = (long) $target; + tmp = (long) $1; if (tmp & 1) { SWIG_exception(SWIG_ValueError,"Pointer must be 2-byte aligned."); } diff --git a/Lib/cpointer.i b/Lib/cpointer.i new file mode 100644 index 000000000..a1cdf7891 --- /dev/null +++ b/Lib/cpointer.i @@ -0,0 +1,184 @@ +/* ----------------------------------------------------------------------------- + * cpointer.i + * + * Author(s): David Beazley (beazley@cs.uchicago.edu) + * + * This library file contains macros that can be used to manipulate simple + * pointer objects. + * + * $Header$ + * ----------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------------- + * %pointer_class(type,name) + * + * Places a simple proxy around a simple type like 'int', 'float', or whatever. + * The proxy provides this interface: + * + * class type { + * public: + * type(); + * ~type(); + * type value(); + * void assign(type value); + * }; + * + * Example: + * + * %pointer_class(int, intp); + * + * int add(int *x, int *y) { return *x + *y; } + * + * In python (with proxies) + * + * >>> a = intp() + * >>> a.assign(10) + * >>> a.value() + * 10 + * >>> b = intp() + * >>> b.assign(20) + * >>> print add(a,b) + * 30 + * + * As a general rule, this macro should not be used on class/structures that + * are already defined in the interface. + * ----------------------------------------------------------------------------- */ + + +%define %pointer_class(TYPE, NAME) +%{ +typedef TYPE NAME; +%} + +typedef struct { +} NAME; + +%extend NAME { +#if __cplusplus +NAME() { + return new TYPE(); +} +~NAME() { + if (self) delete self; +} +#else +NAME() { + return (TYPE *) calloc(1,sizeof(TYPE)); +} +~NAME() { + if (self) free(self); +} +#endif +} + +%extend NAME { + +void assign(TYPE value) { + *self = value; +} +TYPE value() { + return *self; +} +TYPE * cast() { + return self; +} +static NAME * frompointer(TYPE *t) { + return (NAME *) t; +} + +} + +%types(NAME = TYPE); + +%enddef + +/* ----------------------------------------------------------------------------- + * %pointer_functions(type,name) + * + * Create functions for allocating/deallocating pointers. This can be used + * if you don't want to create a proxy class or if the pointer is complex. + * + * %pointer_functions(int, intp) + * + * int add(int *x, int *y) { return *x + *y; } + * + * In python (with proxies) + * + * >>> a = copy_intp(10) + * >>> intp_value(a) + * 10 + * >>> b = new_intp() + * >>> intp_assign(b,20) + * >>> print add(a,b) + * 30 + * >>> delete_intp(a) + * >>> delete_intp(b) + * + * ----------------------------------------------------------------------------- */ + +%define %pointer_functions(TYPE,NAME) +%{ +static TYPE *new_##NAME() { %} +#if __cplusplus +%{ return new TYPE(); %} +#else +%{ return (TYPE *) calloc(1,sizeof(TYPE)); %} +#endif +%{} + +static TYPE *copy_##NAME(TYPE value) { %} +#if __cplusplus +%{ return new TYPE(value); %} +#else +%{ TYPE *self = (TYPE *) calloc(1,sizeof(TYPE)); + *self = value; + return self; %} +#endif +%{} + +static void delete_##NAME(TYPE *self) { %} +#if __cplusplus +%{ if (self) delete self; %} +#else +%{ if (self) free(self); %} +#endif +%{} + +static void NAME ##_assign(TYPE *self, TYPE value) { + *self = value; +} + +static TYPE NAME ##_value(TYPE *self) { + return *self; +} +%} + +TYPE *new_##NAME(); +TYPE *copy_##NAME(TYPE value); +void delete_##NAME(TYPE *self); +void NAME##_assign(TYPE *self, TYPE value); +TYPE NAME##_value(TYPE *self); + +%enddef + +/* ----------------------------------------------------------------------------- + * %pointer_cast(type1,type2,name) + * + * Generates a pointer casting function. + * ----------------------------------------------------------------------------- */ + +%define %pointer_cast(TYPE1,TYPE2,NAME) +%inline %{ +TYPE2 NAME(TYPE1 x) { + return (TYPE2) x; +} +%} +%enddef + + + + + + + + diff --git a/Lib/cstring.i b/Lib/cstring.i new file mode 100644 index 000000000..510fffd67 --- /dev/null +++ b/Lib/cstring.i @@ -0,0 +1,6 @@ +%echo "cstring.i not implemented for this target" + +#define _CSTRING_UNIMPL + + + diff --git a/Lib/ctype.i b/Lib/ctype.i deleted file mode 100644 index 5b4ac54e8..000000000 --- a/Lib/ctype.i +++ /dev/null @@ -1,64 +0,0 @@ -// -// ctype.i -// Dave Beazley -// November 30, 1996 -// SWIG file for character tests -// - -%module ctype -%{ -#include -%} - -%section "Character Class Testing Module",after,info,nosort,pre,chop_left=3,chop_bottom=0,chop_top=0,chop_right=0,skip=1 - -%text %{ -%include ctype.i - -This module provides access to a number of functions for testing -characters. These functions are in the C library. -Most scripting languages already provide much of this functionality, -but just in case you want to use one of the built-in C functions, -you can use this module. -%} - -int isalnum(char c); -/* Returns 1 if isalpha(c) or isdigit(c) is true. */ - -int isalpha(char c); -/* Returns 1 if isupper(c) or islower(c) is true. */ - -int iscntrl(char c); -/* Returns 1 if c is a control character. */ - -int isdigit(char c); -/* Returns 1 if c is a decimal digit. */ - -int isgraph(char c); -/* Returns 1 if c is a printing character except space. */ - -int islower(char c); -/* Returns 1 if c is a lower-case letter. */ - -int isprint(char c); -/* Returns 1 if c is a printing character including space. */ - -int ispunct(char c); -/* Returns 1 if c is a printing character except space or letter - or digit. */ - -int isspace(char c); -/* Returns 1 if c is a space, formfeed, newline, carriage return, - tab, or vertical tab. */ - -int isupper(char c); -/* Returns 1 if c is an upper case letter. */ - -int isxdigit(char c); -/* Returns 1 if c is a hexadecimal digit. */ - -char tolower(char c); -/* Converts c to lower case */ - -char toupper(char c); -/* Converts c to upper case */ diff --git a/Lib/exception.i b/Lib/exception.i index 1d6a9e35e..de90e2ef6 100644 --- a/Lib/exception.i +++ b/Lib/exception.i @@ -5,56 +5,6 @@ // // This SWIG library file provides language independent exception handling -#ifdef AUTODOC -%section "Exception Handling Library",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 - -%text %{ -%include exception.i - -This library provides language independent support for raising scripting -language exceptions in SWIG generated wrapper code. Normally, this is -used in conjunction with the %except directive. - -To raise an exception, use the following function call : - - SWIG_exception(int exctype, char *msg); - -'exctype' is an exception type code and may be one of the following : - - SWIG_MemoryError - SWIG_IOError - SWIG_RuntimeError - SWIG_IndexError - SWIG_TypeError - SWIG_DivisionByZero - SWIG_OverflowError - SWIG_SyntaxError - SWIG_ValueError - SWIG_SystemError - SWIG_UnknownError - -'msg' is an error string that should be reported to the user. - -The library is normally used in conjunction with the %except directive -as follows : - -%except { - try { - $function - } catch RangeError { - SWIG_exception(SWIG_IndexError,"Array index out of bounds"); - } catch(...) { - SWIG_exception(SWIG_UnknownError,"Uncaught exception"); - } -} - -It is important to note that the SWIG_exception() function is only available -to the C code generated by SWIG. It is not available in the scripting language -interface itself. -%} - -#endif - %{ #define SWIG_MemoryError 1 #define SWIG_IOError 2 @@ -71,7 +21,7 @@ interface itself. #ifdef SWIGTCL8 %{ -#define SWIG_exception(a,b) { Tcl_SetResult(interp,b,TCL_VOLATILE); return TCL_ERROR; } +#define SWIG_exception(a,b) { Tcl_SetResult(interp,b,TCL_VOLATILE); SWIG_fail; } %} #else #ifdef SWIGTCL @@ -83,19 +33,20 @@ interface itself. #ifdef SWIGPERL5 %{ -#define SWIG_exception(a,b) croak(b) +#define SWIG_exception(a,b) SWIG_croak(b) %} #endif -#ifdef SWIGPERL4 +#ifdef SWIGPHP4 %{ -#define SWIG_exception(a,b) fatal(b) +/* We should make use of "code" if we can */ +#define SWIG_exception(code, msg) { zend_error(E_ERROR, msg); } %} #endif #ifdef SWIGPYTHON %{ -static void _SWIG_exception(int code, char *msg) { +static void _SWIG_exception(int code, const char *msg) { switch(code) { case SWIG_MemoryError: PyErr_SetString(PyExc_MemoryError,msg); @@ -133,7 +84,7 @@ static void _SWIG_exception(int code, char *msg) { } } -#define SWIG_exception(a,b) { _SWIG_exception(a,b); return NULL; } +#define SWIG_exception(a,b) { _SWIG_exception(a,b); SWIG_fail; } %} #endif @@ -171,54 +122,132 @@ static void _SWIG_exception(int code, char *msg) { %} #endif +#ifdef SWIGMZSCHEME + +%{ + static void _SWIG_exception (int code, const char *msg) { +#define ERROR(errname) \ + scheme_signal_error(errname " (%s)", msg); +#define MAP(swigerr, errname) \ + case swigerr: \ + ERROR(errname); \ + break + switch (code) { + MAP(SWIG_MemoryError, "swig-memory-error"); + MAP(SWIG_IOError, "swig-io-error"); + MAP(SWIG_RuntimeError, "swig-runtime-error"); + MAP(SWIG_IndexError, "swig-index-error"); + MAP(SWIG_TypeError, "swig-type-error"); + MAP(SWIG_DivisionByZero, "swig-division-by-zero"); + MAP(SWIG_OverflowError, "swig-overflow-error"); + MAP(SWIG_SyntaxError, "swig-syntax-error"); + MAP(SWIG_ValueError, "swig-value-error"); + MAP(SWIG_SystemError, "swig-system-error"); + default: + ERROR("swig-error"); + } +#undef ERROR +#undef MAP + } + +#define SWIG_exception(a,b) _SWIG_exception(a, b) +%} +#endif + #ifdef SWIGJAVA %{ -static void _SWIG_exception(JNIEnv *jenv, int code, const char *msg) { - char exception_path[512]; - const char *classname; - const char *class_package = "java/lang"; - - +static void SWIG_JavaException(JNIEnv *jenv, int code, const char *msg) { + SWIG_JavaExceptionCodes exception_code = SWIG_JavaUnknownError; switch(code) { case SWIG_MemoryError: - classname = "OutOfMemoryError"; + exception_code = SWIG_JavaOutOfMemoryError; break; case SWIG_IOError: - classname = "IOException"; - class_package = "java/io"; + exception_code = SWIG_JavaIOException; break; case SWIG_SystemError: case SWIG_RuntimeError: - classname = "RuntimeException"; + exception_code = SWIG_JavaRuntimeException; break; case SWIG_OverflowError: case SWIG_IndexError: - classname = "IndexOutOfBoundsException"; + exception_code = SWIG_JavaIndexOutOfBoundsException; break; case SWIG_DivisionByZero: - classname = "ArithmeticException"; + exception_code = SWIG_JavaArithmeticException; break; case SWIG_SyntaxError: case SWIG_ValueError: case SWIG_TypeError: - classname = "IllegalArgumentException"; + exception_code = SWIG_JavaIllegalArgumentException; break; case SWIG_UnknownError: default: - classname = "UnknownError"; + exception_code = SWIG_JavaUnknownError; break; } - sprintf(exception_path, "%s/%s", class_package, classname); - jclass excep; - jenv->ExceptionClear(); - excep = jenv->FindClass(exception_path); - if (excep) - { - jenv->ThrowNew(excep, msg); - } + SWIG_JavaThrowException(jenv, exception_code, msg); } -#define SWIG_exception(a,b) { _SWIG_exception(jenv, a,b); } +#define SWIG_exception(code, msg) { SWIG_JavaException(jenv, code, msg); } %} #endif // SWIGJAVA +#ifdef SWIGOCAML +%{ +#define OCAML_MSG_BUF_LEN 1024 +static void _SWIG_exception(int code, const char *msg) { + char msg_buf[OCAML_MSG_BUF_LEN]; + sprintf( msg_buf, "Exception(%d): %s\n", code, msg ); + failwith( msg_buf ); +} +#define SWIG_exception(a,b) _SWIG_exception((a),(b)) +%} +#endif + +#ifdef SWIGRUBY +%{ +static void _SWIG_exception(int code, const char *msg) { + switch (code) { + case SWIG_MemoryError: + rb_raise(rb_eNoMemError, msg); + break; + case SWIG_IOError: + rb_raise(rb_eIOError, msg); + break; + case SWIG_RuntimeError: + rb_raise(rb_eRuntimeError, msg); + break; + case SWIG_IndexError: + rb_raise(rb_eIndexError, msg); + break; + case SWIG_TypeError: + rb_raise(rb_eTypeError, msg); + break; + case SWIG_DivisionByZero: + rb_raise(rb_eZeroDivError, msg); + break; + case SWIG_OverflowError: + rb_raise(rb_eRangeError, msg); + break; + case SWIG_SyntaxError: + rb_raise(rb_eSyntaxError, msg); + break; + case SWIG_ValueError: + rb_raise(rb_eArgError, msg); + break; + case SWIG_SystemError: + rb_raise(rb_eFatal, msg); + break; + case SWIG_UnknownError: + rb_raise(rb_eRuntimeError, msg); + break; + default: + break; + } +} + +#define SWIG_exception(a, b) _SWIG_exception((a), (b)) +%} +#endif + /* exception.i ends here */ diff --git a/Lib/guile/cplusplus.i b/Lib/guile/cplusplus.i new file mode 100644 index 000000000..39b12d5ee --- /dev/null +++ b/Lib/guile/cplusplus.i @@ -0,0 +1,20 @@ +/* SWIG typemaps for C++ */ + +/* By Marcio Luis Teixeira : */ + +%typemap(guile,out) string, std::string { + $result = gh_str02scm(const_cast($1.c_str())); +} +%typemap(guile,in) string, std::string { + $1 = SWIG_scm2str($input); +} + +%typemap(guile,out) complex, complex, std::complex { + $result = scm_make_rectangular( gh_double2scm ($1.real ()), + gh_double2scm ($1.imag ()) ); +} +%typemap(guile,in) complex, complex, std::complex { + $1 = std::complex( gh_scm2double (scm_real_part ($input)), + gh_scm2double (scm_imag_part ($input)) ); +} + diff --git a/Lib/guile/guile.i b/Lib/guile/guile.i index df81de988..601013474 100644 --- a/Lib/guile/guile.i +++ b/Lib/guile/guile.i @@ -1,4 +1,4 @@ -/* SWIG Configuration File for Guile. +/* SWIG Configuration File for Guile. -*-c-*- This file is parsed by SWIG before reading any other interface file. */ @@ -9,6 +9,43 @@ %insert(runtime) "guile.swg" #endif +/* Macro for inserting Scheme code into the stub */ +#define %scheme %insert("scheme") + +/* Return-styles */ +%pragma(guile) return_nothing_doc = "Returns unspecified." +%pragma(guile) return_one_doc = "Returns $values." + +%define %values_as_list + %pragma(guile) beforereturn = "" + %pragma(guile) return_multi_doc = "Returns a list of $num_values values: $values." +%enddef +%values_as_list /* the default style */ + +%define %values_as_vector + %pragma(guile) beforereturn = "GUILE_MAYBE_VECTOR" + %pragma(guile) return_multi_doc = "Returns a vector of $num_values values: $values." +%enddef + +%define %multiple_values + %pragma(guile) beforereturn = "GUILE_MAYBE_VALUES" + %pragma(guile) return_multi_doc = "Returns $num_values values: $values." +%enddef + +/* The following definitions are supposed to provide a common API for + the supported Scheme dialects, so that typemaps may be shared. I + also plan to adopt Guile's high-level interface (GH) for this + purpose. */ +#define SWIG_malloc(size) \ + SCM_MUST_MALLOC(size) +#define SWIG_free(mem) \ + scm_must_free(mem) +#define SWIG_GetPtr(s, result, type) \ + SWIG_Guile_GetPtr(s, result, type) +#define SWIG_MustGetPtr(s, type, argnum) \ + SWIG_Guile_MustGetPtr(s, type, argnum, FUNC_NAME) +#define SWIG_MakePtr(ptr, type) \ + SWIG_Guile_MakePtr(ptr, type) + /* Read in standard typemaps. */ %include "typemaps.i" - diff --git a/Lib/guile/guile.swg b/Lib/guile/guile.swg index 3b5dd1e24..b48799309 100644 --- a/Lib/guile/guile.swg +++ b/Lib/guile/guile.swg @@ -7,6 +7,10 @@ /* SWIG pointer structure */ +#ifdef __cplusplus +extern "C" { +#endif + struct SwigCast { unsigned short type; /* Index into SwigPtrTbl */ void *(*cast)(void *); /* Pointer casting function */ @@ -14,8 +18,8 @@ struct SwigCast { }; struct SwigPtrType { - char *name; /* Datatype name */ - char *prettyname; /* Pretty datatype name */ + const char *name; /* Datatype name */ + const char *prettyname; /* Pretty datatype name */ unsigned short tag; /* Index in SwigPtrTable */ struct SwigCast *cast; /* List of compatible types */ }; @@ -45,7 +49,7 @@ swigsort (const void *data1, const void *data2) /* Register a new datatype with the type-checker */ SWIGSTATIC size_t -SWIG_RegisterType (char *type, char *prettyname) +SWIG_RegisterType (const char *type, const char *prettyname) { int i; @@ -90,9 +94,9 @@ SWIG_RegisterType (char *type, char *prettyname) /* Register two data types and their mapping with the type checker. */ SWIGSTATIC void -SWIG_RegisterMapping (char *origtype, char *newtype, void *(*cast)(void *)) +SWIG_RegisterMapping (const char *origtype, const char *newtype, + swig_converter_func cast) { - int i; size_t t = SWIG_RegisterType(origtype, NULL); if (newtype!=NULL) { @@ -118,7 +122,6 @@ SWIG_RegisterMapping (char *origtype, char *newtype, void *(*cast)(void *)) static void SWIG_SortTable (void) { - int i; qsort ((void *) SwigPtrTbl, SwigPtrN, sizeof(size_t), swigsort); /* Indicate that everything is sorted */ SwigPtrSort = 1; @@ -137,10 +140,9 @@ swigcmp (const void *key, const void *data) static SwigPtrType * SWIG_GetPtrType (const char *_t) { - int start, end; size_t *result; if (!SwigPtrSort) SWIG_SortTable(); - result = bsearch(_t, SwigPtrTbl, SwigPtrN, sizeof(size_t), swigcmp); + result = (size_t *) bsearch(_t, SwigPtrTbl, SwigPtrN, sizeof(size_t), swigcmp); if (result!=NULL) return SwigPtrList+*result; else return NULL; } @@ -156,8 +158,8 @@ SWIG_Cast (void *source, size_t source_type, mapping table to figure out whether or not we can accept this datatype. */ struct SwigCast *c; - for (c = SwigPtrList[source_type].cast; - c && c->type!=dest_type; c = c->next) /* nothing */; + for (c = SwigPtrList[dest_type].cast; + c && c->type!=source_type; c = c->next) /* nothing */; if (c) { /* Get pointer value. */ if (c->cast) *ptr = (*(c->cast))(source); @@ -175,6 +177,19 @@ SWIG_Cast (void *source, size_t source_type, } } +/* Dynamic pointer casting. Down an inheritance hierarchy */ +SWIGSTATIC swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) +{ + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + /* Function for getting a pointer value */ static unsigned long swig_tag = 0; @@ -199,7 +214,7 @@ SWIG_Guile_GetPtr(SCM s, void **result, swig_type_info *type) && (unsigned long) SCM_TYP16(s) == swig_tag) { if (type) return !SWIG_Cast((void *) SCM_CDR(s), - SCM_CAR(s) >> 16, + (long) SCM_CAR(s) >> 16, result, type->tag); else { *result = (void *) SCM_CDR(s); @@ -209,18 +224,30 @@ SWIG_Guile_GetPtr(SCM s, void **result, swig_type_info *type) return 1; } +SWIGSTATIC void * +SWIG_Guile_MustGetPtr (SCM s, swig_type_info *type, + int argnum, const char *func_name) +{ + void *result; + if (SWIG_Guile_GetPtr(s, &result, type)) { + /* type mismatch */ + scm_wrong_type_arg((char *) func_name, argnum, s); + } + return result; +} + /* Init */ static int print_swig (SCM swig_smob, SCM port, scm_print_state *pstate) { - char buf[16]; - scm_puts("#> 16].prettyname != NULL) - scm_puts(SwigPtrList[SCM_CAR(swig_smob) >> 16].prettyname, port); - else scm_puts(SwigPtrList[SCM_CAR(swig_smob) >> 16].name, port); - sprintf(buf, " 0x%lx>", SCM_CDR(swig_smob)); - scm_puts(buf, port); + scm_puts((char *) "#> 16].prettyname != NULL) + scm_puts((char*) SwigPtrList[(long) SCM_CAR(swig_smob) >> 16].prettyname, port); + else scm_puts((char*) SwigPtrList[(long) SCM_CAR(swig_smob) >> 16].name, port); + scm_puts((char *) " ", port); + scm_intprint((long) SCM_CDR(swig_smob), 16, port); + scm_puts((char *) ">", port); /* non-zero means success */ return 1; } @@ -238,7 +265,7 @@ SWIGSTATIC void SWIG_Guile_Init (void) { if (swig_tag == 0) { - swig_tag = scm_make_smob_type_mfpe("swig", 0, NULL, NULL, + swig_tag = scm_make_smob_type_mfpe((char *) "swig", 0, NULL, NULL, print_swig, equalp_swig); } } @@ -246,11 +273,12 @@ SWIG_Guile_Init (void) /* Convert datatype table */ SWIGSTATIC -void SWIG_Guile_RegisterTypes(swig_type_info **table) +void SWIG_Guile_RegisterTypes(swig_type_info **table, + swig_type_info **init) { - for (; *table; table++) { - swig_type_info *type = *table; - char *origname = type->name; + for (; *init; table++, init++) { + swig_type_info *type = *table = *init; + const char *origname = type->name; /* Register datatype itself and store pointer back */ type->tag = SWIG_RegisterType(origname, type->str); /* Register compatible types */ @@ -259,26 +287,30 @@ void SWIG_Guile_RegisterTypes(swig_type_info **table) } } -SWIGSTATIC void +SWIGSTATIC int SWIG_Guile_GetArgs (SCM *dest, SCM rest, int reqargs, int optargs, const char *procname) { int i; + int num_args_passed = 0; for (i = 0; i +#ifdef __cplusplus +extern "C" { +#endif + /* Debugger interface (don't change the order of the following lines) */ #define GDB_TYPE SCM #include @@ -44,6 +48,10 @@ inner_main(void *closure, int argc, char **argv) /* never reached: scm_shell will perform an exit */ } +#ifdef __cplusplus +} +#endif + int main(int argc, char **argv) { diff --git a/Lib/guile/list-vector.i b/Lib/guile/list-vector.i new file mode 100644 index 000000000..65ccd7aed --- /dev/null +++ b/Lib/guile/list-vector.i @@ -0,0 +1,430 @@ +/* list-vector.i --- Guile typemaps for converting between -*- c -*- arrays + and Scheme lists or vectors + + Copyright (C) 2001, 2002 Matthias Koeppe + + $Header$ +*/ + +/* Here is a macro that will define typemaps for converting between C + arrays and Scheme lists or vectors when passing arguments to the C + function. + + TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) + + Supported calling conventions: + + func(int VECTORLENINPUT, [const] C_TYPE *VECTORINPUT) + + Scheme wrapper will take one argument, a vector. A temporary C + array of elements of type C_TYPE will be allocated and filled + with the elements of the vectors, converted to C with the + SCM_TO_C function. Length and address of the array are passed + to the C function. + + SCM_TYPE is used to describe the Scheme type of the elements in + the Guile procedure documentation. + + func(int LISTLENINPUT, [const] C_TYPE *LISTINPUT) + + Likewise, but the Scheme wrapper will take one argument, a list. + + func(int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) + + Scheme wrapper will take no arguments. Addresses of an integer + and a C_TYPE * variable will be passed to the C function. The + C function is expected to return address and length of a + freshly allocated array of elements of type C_TYPE through + these pointers. The elements of this array are converted to + Scheme with the C_TO_SCM function and returned as a Scheme + vector. + + If the function has a void return value, the vector constructed + by this typemap becomes the return value of the Scheme wrapper. + Otherwise, the function returns multiple values. (See + the documentation on how to deal with multiple values.) + + func(int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) + + Likewise, but the Scheme wrapper will return a list instead of + a vector. + + It is also allowed to use "size_t LISTLENINPUT" rather than "int + LISTLENINPUT". */ + +%define TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) + + /* input */ + + /* We make use of the new multi-dispatch typemaps here. */ + + %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values") + (int VECTORLENINPUT, C_TYPE *VECTORINPUT), + (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT) + { + SCM_VALIDATE_VECTOR($argnum, $input); + $1 = gh_vector_length($input); + if ($1 > 0) { + $1_ltype i; + $2 = SWIG_malloc(sizeof(C_TYPE) * $1); + for (i = 0; i<$1; i++) { + SCM swig_scm_value = gh_vector_ref($input, gh_int2scm(i)); + $2[i] = SCM_TO_C_EXPR; + } + } + else $2 = NULL; + } + + %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values") + (int LISTLENINPUT, C_TYPE *LISTINPUT), + (size_t LISTLENINPUT, C_TYPE *LISTINPUT) + { + SCM_VALIDATE_LIST($argnum, $input); + $1 = gh_length($input); + if ($1 > 0) { + $1_ltype i; + SCM rest; + $2 = SWIG_malloc(sizeof(C_TYPE) * $1); + for (i = 0, rest = $input; + i<$1; + i++, rest = gh_cdr(rest)) { + SCM swig_scm_value = gh_car(rest); + $2[i] = SCM_TO_C_EXPR; + } + } + else $2 = NULL; + } + + /* Do not check for NULL pointers (override checks). */ + + %typemap(check) C_TYPE *VECTORINPUT, + const C_TYPE *VECTORINPUT, + C_TYPE *LISTINPUT, + const C_TYPE *LISTINPUT + "/* no check for NULL pointer */"; + + /* Discard the temporary array after the call. */ + + %typemap(freearg) C_TYPE *VECTORINPUT, + const C_TYPE *VECTORINPUT, + C_TYPE *LISTINPUT, + const C_TYPE *LISTINPUT + {if ($1!=NULL) SWIG_free($1);} + +%enddef + + /* output */ + +%define TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) + + /* First we make temporary variables ARRAYLENTEMP and ARRAYTEMP, + whose addresses we pass to the C function. We ignore both + arguments for Scheme. */ + + %typemap(in,numinputs=0) (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) + (int arraylentemp, C_TYPE *arraytemp), + (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) + (int arraylentemp, C_TYPE *arraytemp), + (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) + (int arraylentemp, C_TYPE *arraytemp), + (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) + (int arraylentemp, C_TYPE *arraytemp) + %{ + $1 = &arraylentemp; + $2 = &arraytemp; + %} + + /* In the ARGOUT typemaps, we convert the array into a vector or + a list and append it to the results. */ + + %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)") + (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), + (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) + { + $*1_ltype i; + SCM res = gh_make_vector(gh_int2scm(*$1), + SCM_BOOL_F); + for (i = 0; i<*$1; i++) { + C_TYPE swig_c_value = (*$2)[i]; + SCM elt = C_TO_SCM_EXPR; + gh_vector_set_x(res, gh_int2scm(i), elt); + } + SWIG_APPEND_VALUE(res); + } + + %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)") + (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT), + (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) + { + int i; + SCM res = SCM_EOL; + for (i = ((int)(*$1)) - 1; i>=0; i--) { + C_TYPE swig_c_value = (*$2)[i]; + SCM elt = C_TO_SCM_EXPR; + res = gh_cons(elt, res); + } + SWIG_APPEND_VALUE(res); + } + + /* In the FREEARG typemaps, get rid of the C vector. + (This can be overridden if you want to keep the C vector.) */ + + %typemap(freearg) + (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), + (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), + (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT), + (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) + { + if ((*$2)!=NULL) free(*$2); + } + +%enddef + +%define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE) + TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) + TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) +%enddef + +%define TYPEMAP_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE) + TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR + (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE) +%enddef + +%define TYPEMAP_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE) + TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR + (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE) +%enddef + +%define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) + TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR + (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE) +%enddef + +/* We use the macro to define typemaps for some standard types. */ + +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string); +TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string); + +/* Following is a macro that emits typemaps that are much more + flexible. (They are also messier.) It supports multiple parallel + lists and vectors (sharing one length argument each). + + TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) + + Supported calling conventions: + + func(int PARALLEL_VECTORLENINPUT, [const] C_TYPE *PARALLEL_VECTORINPUT, ...) or + func([const] C_TYPE *PARALLEL_VECTORINPUT, ..., int PARALLEL_VECTORLENINPUT) + + func(int PARALLEL_LISTLENINPUT, [const] C_TYPE *PARALLEL_LISTINPUT, ...) or + func([const] C_TYPE *PARALLEL_LISTINPUT, ..., int PARALLEL_LISTLENINPUT) + + func(int *PARALLEL_VECTORLENOUTPUT, C_TYPE **PARALLEL_VECTOROUTPUT, ...) or + func(C_TYPE **PARALLEL_VECTOROUTPUT, int *PARALLEL_VECTORLENOUTPUT, ...) + + func(int *PARALLEL_LISTLENOUTPUT, C_TYPE **PARALLEL_LISTOUTPUT) or + func(C_TYPE **PARALLEL_LISTOUTPUT, int *PARALLEL_LISTLENOUTPUT) + + It is also allowed to use "size_t PARALLEL_LISTLENINPUT" rather than "int + PARALLEL_LISTLENINPUT". */ + +%define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) + + /* input */ + + /* Passing data is a little complicated here; just remember: + IGNORE typemaps come first, then IN, then CHECK. But if + IGNORE is given, IN won't be used for this type. + + We need to "ignore" one of the parameters because there shall + be only one argument on the Scheme side. Here we only + initialize the array length to 0 but save its address for a + later change. */ + + %typemap(in,numinputs=0) int PARALLEL_VECTORLENINPUT (int *_global_vector_length), + size_t PARALLEL_VECTORLENINPUT (size_t *_global_vector_length) + { + $1 = 0; + _global_vector_length = &$1; + } + + %typemap(in,numinputs=0) int PARALLEL_LISTLENINPUT (int *_global_list_length), + size_t PARALLEL_LISTLENINPUT (int *_global_list_length) + { + $1 = 0; + _global_list_length = &$1; + } + + /* All the work is done in IN. */ + + %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values") + C_TYPE *PARALLEL_VECTORINPUT, + const C_TYPE *PARALLEL_VECTORINPUT + { + SCM_VALIDATE_VECTOR($argnum, $input); + *_global_vector_length = gh_vector_length($input); + if (*_global_vector_length > 0) { + int i; + $1 = SWIG_malloc(sizeof(C_TYPE) + * (*_global_vector_length)); + for (i = 0; i<*_global_vector_length; i++) { + SCM swig_scm_value = gh_vector_ref($input, gh_int2scm(i)); + $1[i] = SCM_TO_C_EXPR; + } + } + else $1 = NULL; + } + + %typemap(in, doc="($arg >)") + C_TYPE *PARALLEL_LISTINPUT, + const C_TYPE *PARALLEL_LISTINPUT + { + SCM_VALIDATE_LIST($argnum, $input); + *_global_list_length = gh_length($input); + if (*_global_list_length > 0) { + int i; + SCM rest; + $1 = SWIG_malloc(sizeof(C_TYPE) + * (*_global_list_length)); + for (i = 0, rest = $input; + i<*_global_list_length; + i++, rest = gh_cdr(rest)) { + SCM swig_scm_value = gh_car(rest); + $1[i] = SCM_TO_C_EXPR; + } + } + else $1 = NULL; + } + + /* Don't check for NULL pointers (override checks). */ + + %typemap(check) C_TYPE *PARALLEL_VECTORINPUT, + const C_TYPE *PARALLEL_VECTORINPUT, + C_TYPE *PARALLEL_LISTINPUT, + const C_TYPE *PARALLEL_LISTINPUT + "/* no check for NULL pointer */"; + + /* Discard the temporary array after the call. */ + + %typemap(freearg) C_TYPE *PARALLEL_VECTORINPUT, + const C_TYPE *PARALLEL_VECTORINPUT, + C_TYPE *PARALLEL_LISTINPUT, + const C_TYPE *PARALLEL_LISTINPUT + {if ($1!=NULL) SWIG_free($1);} + +%enddef + +%define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) + + /* output */ + + /* First we make a temporary variable ARRAYLENTEMP, use its + address as the ...LENOUTPUT argument for the C function and + "ignore" the ...LENOUTPUT argument for Scheme. */ + + %typemap(in,numinputs=0) int *PARALLEL_VECTORLENOUTPUT (int _global_arraylentemp), + size_t *PARALLEL_VECTORLENOUTPUT (size_t _global_arraylentemp), + int *PARALLEL_LISTLENOUTPUT (int _global_arraylentemp), + size_t *PARALLEL_LISTLENOUTPUT (size_t _global_arraylentemp) + "$1 = &_global_arraylentemp;"; + + /* We also need to ignore the ...OUTPUT argument. */ + + %typemap(in,numinputs=0) C_TYPE **PARALLEL_VECTOROUTPUT (C_TYPE *arraytemp), + C_TYPE **PARALLEL_LISTOUTPUT (C_TYPE *arraytemp) + "$1 = &arraytemp;"; + + /* In the ARGOUT typemaps, we convert the array into a vector or + a list and append it to the results. */ + + %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)") + C_TYPE **PARALLEL_VECTOROUTPUT + { + int i; + SCM res = gh_make_vector(gh_int2scm(_global_arraylentemp), + SCM_BOOL_F); + for (i = 0; i<_global_arraylentemp; i++) { + C_TYPE swig_c_value = (*$1)[i]; + SCM elt = C_TO_SCM_EXPR; + gh_vector_set_x(res, gh_int2scm(i), elt); + } + SWIG_APPEND_VALUE(res); + } + + %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)") + C_TYPE **PARALLEL_LISTOUTPUT + { + int i; + SCM res = SCM_EOL; + if (_global_arraylentemp > 0) { + for (i = _global_arraylentemp - 1; i>=0; i--) { + C_TYPE swig_c_value = (*$1)[i]; + SCM elt = C_TO_SCM_EXPR; + res = gh_cons(elt, res); + } + } + SWIG_APPEND_VALUE(res); + } + + /* In the FREEARG typemaps, get rid of the C vector. + (This can be overridden if you want to keep the C vector.) */ + + %typemap(freearg) C_TYPE **PARALLEL_VECTOROUTPUT, + C_TYPE **PARALLEL_LISTOUTPUT + { + if ((*$1)!=NULL) free(*$1); + } + +%enddef + +%define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE) + TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) + TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) +%enddef + +%define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE) + TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR + (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE) +%enddef + +%define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE) + TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR + (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE) +%enddef + +%define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) + TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR + (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE) +%enddef + +/* We use the macro to define typemaps for some standard types. */ + +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string); +TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string); + diff --git a/Lib/guile/pointer-in-out.i b/Lib/guile/pointer-in-out.i new file mode 100644 index 000000000..160cfa5e9 --- /dev/null +++ b/Lib/guile/pointer-in-out.i @@ -0,0 +1,68 @@ +/* pointer-in-out.i --- Guile typemaps for passing -*- c -*- pointers indirectly + + Copyright (C) 2001 Matthias Koeppe + + $Header$ +*/ + +/* Here is a macro that will define typemaps for passing C pointers indirectly. + + TYPEMAP_POINTER_INPUT_OUTPUT(PTRTYPE, SCM_TYPE) + + Supported calling conventions (in this example, PTRTYPE is int *): + + func(int **INPUT) + + Scheme wrapper will take one argument, a wrapped C pointer. + The address of a variable containing this pointer will be + passed to the function. + + func(int **OUTPUT) + + Scheme wrapper will take no arguments. The address of an int * + variable will be passed to the function. The function is + expected to modify the variable; its value is wrapped and + becomes an extra return value. (See the documentation on how + to deal with multiple values.) + + func(int **BOTH) + func(int **INOUT) + + This annotation combines INPUT and OUTPUT. + +*/ + +%define TYPEMAP_POINTER_INPUT_OUTPUT(PTRTYPE, SCM_TYPE) + +%typemap(in, doc="$NAME is of type <" #SCM_TYPE ">") PTRTYPE *INPUT(PTRTYPE temp) +{ + if (SWIG_Guile_GetPtr($input, (void **) &temp, $*descriptor)) { + scm_wrong_type_arg(FUNC_NAME, $argnum, $input); + } + $1 = &temp; +} + +%typemap(in, numinputs=0) PTRTYPE *OUTPUT(PTRTYPE temp) + "$1 = &temp;"; + +%typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT + "SWIG_APPEND_VALUE(SWIG_Guile_MakePtr(*$1, $*descriptor));"; + +%typemap(in) PTRTYPE *BOTH = PTRTYPE *INPUT; +%typemap(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT; +%typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT; +%typemap(argout) PTRTYPE *INOUT = PTRTYPE *OUTPUT; + +/* As a special convenience measure, also attach docs involving + SCM_TYPE to the standard pointer typemaps */ + +%typemap(in, doc="$NAME is of type <" #SCM_TYPE ">") PTRTYPE { + if (SWIG_Guile_GetPtr($input, (void **) &$1, $descriptor)) + scm_wrong_type_arg(FUNC_NAME, $argnum, $input); +} + +%typemap(out, doc="<" #SCM_TYPE ">") PTRTYPE { + $result = SWIG_Guile_MakePtr ($1, $descriptor); +} + +%enddef diff --git a/Lib/guile/ports.i b/Lib/guile/ports.i index 906178f29..f53cf7722 100644 --- a/Lib/guile/ports.i +++ b/Lib/guile/ports.i @@ -11,34 +11,33 @@ #endif #include #include + #include %} -/* Feed FILE * arguments from file ports */ +/* Feed temporary FILE * arguments from file ports */ -%typemap(guile, in) FILE * +%typemap(in, doc="$NAME is a port") FILE * { - if(!(SCM_FPORTP($source))) - scm_wrong_type_arg("$name", $argnum, $source); + if(!(SCM_FPORTP($input))) + scm_wrong_type_arg("$name", $argnum, $input); else { int fd; - if (SCM_OUTPUT_PORT_P($source)) - scm_force_output($source); - fd=dup(SCM_FPORT_FDES($source)); + if (SCM_OUTPUT_PORT_P($input)) + scm_force_output($input); + fd=dup(SCM_FPORT_FDES($input)); if(fd==-1) scm_misc_error("$name", strerror(errno), SCM_EOL); - $target=fdopen(fd, - SCM_OUTPUT_PORT_P($source) - ? (SCM_INPUT_PORT_P($source) + $1=fdopen(fd, + SCM_OUTPUT_PORT_P($input) + ? (SCM_INPUT_PORT_P($input) ? "rw" : "w") : "r"); - if($target==NULL) + if($1==NULL) scm_misc_error("$name", strerror(errno), SCM_EOL); } } -%typemap(guile, indoc) FILE * "($arg )"; - -%typemap(guile, freearg) FILE* { - fclose($target); +%typemap(freearg) FILE* { + fclose($1); } diff --git a/Lib/guile/std_common.i b/Lib/guile/std_common.i new file mode 100644 index 000000000..dc7f8fef5 --- /dev/null +++ b/Lib/guile/std_common.i @@ -0,0 +1,26 @@ +// +// SWIG typemaps for STL - common utilities +// Luigi Ballabio +// Aug 3, 2002 +// +// Guile implementation + +%{ +#include + +SCM SWIG_bool2scm(bool b) { + int i = b ? 1 : 0; + return gh_bool2scm(i); +} +std::string SWIG_scm2string(SCM x) { + char* temp; + std::string s; + temp = gh_scm2newstr(x, NULL); + s = std::string(temp); + if (temp) scm_must_free(temp); + return s; +} +SCM SWIG_string2scm(const std::string& s) { + return gh_str02scm(s.c_str()); +} +%} diff --git a/Lib/guile/std_string.i b/Lib/guile/std_string.i new file mode 100644 index 000000000..acb817852 --- /dev/null +++ b/Lib/guile/std_string.i @@ -0,0 +1,58 @@ +// +// SWIG typemaps for std::string +// Luigi Ballabio +// Apr 8, 2002 +// +// Guile implementation + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string (char* tempptr) { + if (gh_string_p($input)) { + tempptr = gh_scm2newstr($input, NULL); + $1 = std::string(tempptr); + if (tempptr) scm_must_free(tempptr); + } else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + + %typemap(in) const string & (std::string temp, + char* tempptr) { + if (gh_string_p($input)) { + tempptr = gh_scm2newstr($input, NULL); + temp = std::string(tempptr); + if (tempptr) scm_must_free(tempptr); + $1 = &temp; + } else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + + %typemap(out) string { + $result = gh_str02scm($1.c_str()); + } + + %typemap(out) const string & { + $result = gh_str02scm($1->c_str()); + } + +} diff --git a/Lib/guile/std_vector.i b/Lib/guile/std_vector.i new file mode 100644 index 000000000..85d680e64 --- /dev/null +++ b/Lib/guile/std_vector.i @@ -0,0 +1,436 @@ +// +// SWIG typemaps for std::vector +// Luigi Ballabio +// Apr 8, 2002 +// +// Guile implementation + +%include std_common.i +%include exception.i + +%exception std::vector::ref { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::set { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Guile as much as possible, namely, to allow the user to pass and +// be returned Guile vectors or lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Guile sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Guile vector of T:s +// is returned which is most easily used in other Guile functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class vector { + %typemap(in) vector { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + $1 = std::vector(size); + for (unsigned long i=0; i(); + } else if (gh_pair_p($input)) { + SCM head, tail; + $1 = std::vector(); + tail = $input; + while (!gh_null_p(tail)) { + head = gh_car(tail); + tail = gh_cdr(tail); + $1.push_back(*((T*)SWIG_MustGetPtr(head, + $descriptor(T *), + $argnum))); + } + } else { + $1 = *(($&1_type) + SWIG_MustGetPtr($input,$&1_descriptor,$argnum)); + } + } + %typemap(in) const vector& (std::vector temp), + const vector* (std::vector temp) { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + temp = std::vector(size); + $1 = &temp; + for (unsigned long i=0; i(); + $1 = &temp; + } else if (gh_pair_p($input)) { + temp = std::vector(); + $1 = &temp; + SCM head, tail; + tail = $input; + while (!gh_null_p(tail)) { + head = gh_car(tail); + tail = gh_cdr(tail); + temp.push_back(*((T*) SWIG_MustGetPtr(head, + $descriptor(T *), + $argnum))); + } + } else { + $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum); + } + } + %typemap(out) vector { + $result = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED); + for (unsigned int i=0; i<$1.size(); i++) { + T* x = new T((($1_type &)$1)[i]); + gh_vector_set_x($result,gh_long2scm(i), + SWIG_MakePtr(x,$descriptor(T *))); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + T* x; + if (SWIG_Guile_GetPtr(o,(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + if (SWIG_Guile_GetPtr(head,(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_Guile_GetPtr($input,(void **) &v, + $&1_descriptor) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + if (SWIG_Guile_GetPtr(o,(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + if (SWIG_Guile_GetPtr(head,(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_Guile_GetPtr($input,(void **) &v, + $1_descriptor) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector&); + %rename(length) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename("set!") set; + %rename("pop!") pop; + %rename("push!") push_back; + void push_back(const T& x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& ref(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + %typemap(in) vector { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + $1 = std::vector(size); + for (unsigned long i=0; i(); + } else if (gh_pair_p($input)) { + SCM v = gh_list_to_vector($input); + unsigned long size = gh_vector_length(v); + $1 = std::vector(size); + for (unsigned long i=0; i& (std::vector temp), + const vector* (std::vector temp) { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + temp = std::vector(size); + $1 = &temp; + for (unsigned long i=0; i(); + $1 = &temp; + } else if (gh_pair_p($input)) { + SCM v = gh_list_to_vector($input); + unsigned long size = gh_vector_length(v); + temp = std::vector(size); + $1 = &temp; + for (unsigned long i=0; i { + $result = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED); + for (unsigned int i=0; i<$1.size(); i++) { + SCM x = CONVERT_TO((($1_type &)$1)[i]); + gh_vector_set_x($result,gh_long2scm(i),x); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + $1 = CHECK(o) ? 1 : 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + $1 = CHECK(head) ? 1 : 0; + } else { + /* wrapped vector? */ + std::vector* v; + $1 = (SWIG_Guile_GetPtr($input,(void **) &v, + $&1_descriptor) != -1) ? 1 : 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + $1 = CHECK(o) ? 1 : 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + $1 = CHECK(head) ? 1 : 0; + } else { + /* wrapped vector? */ + std::vector* v; + $1 = (SWIG_Guile_GetPtr($input,(void **) &v, + $1_descriptor) != -1) ? 1 : 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector&); + %rename(length) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename("set!") set; + %rename("pop!") pop; + %rename("push!") push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T ref(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i") C_NAME + { SCM swig_scm_value = $input; + $1 = SCM_TO_C_EXPR; } + %typemap (varin, doc="NEW-VALUE is of type <" #SCM_NAME ">") C_NAME + { SCM swig_scm_value = $input; + $1 = SCM_TO_C_EXPR; } + %typemap (out, doc="<" #SCM_NAME ">") C_NAME + { C_NAME swig_c_value = $1; + $result = C_TO_SCM_EXPR; } + %typemap (varout, doc="<" #SCM_NAME ">") C_NAME + { C_NAME swig_c_value = $1; + $result = C_TO_SCM_EXPR; } + /* INPUT and OUTPUT */ + %typemap (in, doc="$NAME is of type <" #SCM_NAME ">)") + C_NAME *INPUT(C_NAME temp) { + SCM swig_scm_value = $input; + temp = (C_NAME) SCM_TO_C_EXPR; $1 = &temp; } + %typemap (in,numinputs=0) C_NAME *OUTPUT (C_NAME temp) + {$1 = &temp;} + %typemap (argout,doc="$name (of type <" #SCM_NAME ">)") C_NAME *OUTPUT + { C_NAME swig_c_value = *$1; + SWIG_APPEND_VALUE(C_TO_SCM_EXPR); } + %typemap (in) C_NAME *BOTH = C_NAME *INPUT; + %typemap (argout) C_NAME *BOTH = C_NAME *OUTPUT; + %typemap (in) C_NAME *INOUT = C_NAME *INPUT; + %typemap (argout) C_NAME *INOUT = C_NAME *OUTPUT; + /* Const primitive references. Passed by value */ + %typemap(in, doc="$NAME is of type <" #SCM_NAME ">") const C_NAME & (C_NAME temp) + { SCM swig_scm_value = $input; + temp = SCM_TO_C_EXPR; + $1 = &temp; } + %typemap(out, doc="<" #SCM_NAME ">") const C_NAME & + { C_NAME swig_c_value = *$1; + $result = C_TO_SCM_EXPR; } +%enddef + +/* The SIMPLE_MAP macro below defines the whole set of typemaps needed + for simple types. It generates slightly simpler code than the + macro above, but it is only suitable for very simple conversion + expressions. */ %define SIMPLE_MAP(C_NAME, SCM_TO_C, C_TO_SCM, SCM_NAME) - %typemap (guile, in) C_NAME "$target = SCM_TO_C($source);"; - %typemap (guile, varin) C_NAME "$target = SCM_TO_C($source);"; - %typemap (guile, out) C_NAME "$target = C_TO_SCM($source);"; - %typemap (guile, varout) C_NAME "$target = C_TO_SCM($source);"; - %typemap (guile, indoc) C_NAME "($arg )"; - %typemap (guile, varindoc) C_NAME "($arg )"; - %typemap (guile, outdoc) C_NAME ""; - %typemap (guile, varoutdoc) C_NAME ""; - %typemap (guile, in) C_NAME *INPUT (C_NAME temp) - "temp = (C_NAME) C_TO_SCM($source); $target = &temp;" - %typemap (guile, indoc) C_NAME *INPUT "($arg )"; - %typemap (guile, ignore) C_NAME *OUTPUT (C_NAME temp) - "$target = &temp;" - %typemap (guile, argout) C_NAME *OUTPUT - "GUILE_APPEND_RESULT(C_TO_SCM(*$target));"; - %typemap (guile, argoutdoc) C_NAME *OUTPUT "($arg )"; - %typemap (guile, in) C_NAME *BOTH = C_NAME *INPUT; - %typemap (guile, indoc) C_NAME *BOTH = C_NAME *INPUT; - %typemap (guile, argout) C_NAME *BOTH = C_NAME *OUTPUT; - %typemap (guile, argoutdoc) C_NAME *BOTH = C_NAME *OUTPUT; + %typemap (in, doc="$NAME is of type <" #SCM_NAME ">") + C_NAME {$1 = SCM_TO_C($input);} + %typemap (varin, doc="NEW-VALUE is of type <" #SCM_NAME ">") + C_NAME {$1 = SCM_TO_C($input);} + %typemap (out, doc="<" #SCM_NAME ">") + C_NAME {$result = C_TO_SCM($1);} + %typemap (varout, doc="<" #SCM_NAME ">") + C_NAME {$result = C_TO_SCM($1);} + /* INPUT and OUTPUT */ + %typemap (in, doc="$NAME is of type <" #SCM_NAME ">)") + C_NAME *INPUT(C_NAME temp) { + temp = (C_NAME) SCM_TO_C($input); $1 = &temp; + } + %typemap (in,numinputs=0) C_NAME *OUTPUT (C_NAME temp) + {$1 = &temp;} + %typemap (argout,doc="$name (of type <" #SCM_NAME ">)") C_NAME *OUTPUT + {SWIG_APPEND_VALUE(C_TO_SCM(*$1));} + %typemap (in) C_NAME *BOTH = C_NAME *INPUT; + %typemap (argout) C_NAME *BOTH = C_NAME *OUTPUT; + %typemap (in) C_NAME *INOUT = C_NAME *INPUT; + %typemap (argout) C_NAME *INOUT = C_NAME *OUTPUT; + /* Const primitive references. Passed by value */ + %typemap(in, doc="$NAME is of type <" #SCM_NAME ">") const C_NAME & (C_NAME temp) { + temp = SCM_TO_C($input); + $1 = &temp; + } + %typemap(out, doc="<" #SCM_NAME ">") const C_NAME & { + $result = C_TO_SCM(*$1); + } %enddef - + SIMPLE_MAP(bool, gh_scm2bool, gh_bool2scm, boolean); - SIMPLE_MAP(char, GSWIG_scm2char, gh_char2scm, char); - SIMPLE_MAP(unsigned char, GSWIG_scm2char, gh_char2scm, char); + SIMPLE_MAP(char, gh_scm2char, gh_char2scm, char); + SIMPLE_MAP(unsigned char, gh_scm2char, gh_char2scm, char); SIMPLE_MAP(int, gh_scm2int, gh_int2scm, integer); SIMPLE_MAP(short, gh_scm2int, gh_int2scm, integer); SIMPLE_MAP(long, gh_scm2long, gh_long2scm, integer); @@ -46,17 +242,122 @@ SIMPLE_MAP(size_t, gh_scm2ulong, gh_ulong2scm, integer); SIMPLE_MAP(float, gh_scm2double, gh_double2scm, real); SIMPLE_MAP(double, gh_scm2double, gh_double2scm, real); - SIMPLE_MAP(char *, GSWIG_scm2str, gh_str02scm, string); - SIMPLE_MAP(const char *, GSWIG_scm2str, gh_str02scm, string); +// SIMPLE_MAP(char *, SWIG_scm2str, gh_str02scm, string); +// SIMPLE_MAP(const char *, SWIG_scm2str, gh_str02scm, string); + +/* Strings */ + + %typemap (in, doc="$NAME is a string") char *(int must_free = 0) { + $1 = SWIG_scm2str($input); + must_free = 1; + } + %typemap (varin, doc="NEW-VALUE is a string") char * {$1 = SWIG_scm2str($input);} + %typemap (out, doc="") char * {$result = gh_str02scm($1);} + %typemap (varout, doc="") char * {$result = gh_str02scm($1);} + %typemap (in, doc="$NAME is a string") char * *INPUT(char * temp, int must_free = 0) { + temp = (char *) SWIG_scm2str($input); $1 = &temp; + must_free = 1; + } + %typemap (in,numinputs=0) char * *OUTPUT (char * temp) + {$1 = &temp;} + %typemap (argout,doc="$NAME (a string)") char * *OUTPUT + {SWIG_APPEND_VALUE(gh_str02scm(*$1));} + %typemap (in) char * *BOTH = char * *INPUT; + %typemap (argout) char * *BOTH = char * *OUTPUT; + %typemap (in) char * *INOUT = char * *INPUT; + %typemap (argout) char * *INOUT = char * *OUTPUT; /* GSWIG_scm2str makes a malloc'ed copy of the string, so get rid of it after the function call. */ -%typemap (guile, freearg) char *, const char * "if ($target) scm_must_free($target);"; +%typemap (freearg) char * "if (must_free$argnum && $1) scm_must_free($1);"; +%typemap (freearg) char **INPUT, char **BOTH "if (must_free$argnum && (*$1)) scm_must_free(*$1);" +%typemap (freearg) char **OUTPUT "scm_must_free(*$1);" + +/* But this shall not apply if we try to pass a single char by + reference. */ + +%typemap (freearg) char *OUTPUT, char *BOTH ""; + +/* If we set a string variable, delete the old result first. */ + +%typemap (varin) char * { + if ($1) free($1); + $1 = SWIG_scm2str($input); +} /* Void */ -%typemap (guile, out) void "gswig_result = GH_UNSPECIFIED;"; -%typemap (guile, outdoc) void ""; +%typemap (out,doc="") void "gswig_result = GH_UNSPECIFIED;"; + +/* SCM is passed through */ + +typedef unsigned long SCM; +%typemap (in) SCM "$1=$input;"; +%typemap (out) SCM "$result=$1;"; + +/* Some ANSI C typemaps */ + +%apply long { size_t }; + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +%typemap(in) (char *STRING, int LENGTH) { + size_t temp; + $1 = ($1_ltype) gh_scm2newstr($input, &temp); + $2 = ($2_ltype) temp; +} + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +/* adapted from python.swg */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE, + bool, const bool & +{ + $1 = SCM_NFALSEP(scm_integer_p($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = SCM_NFALSEP(scm_real_p($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + $1 = SCM_CHARP($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = SCM_STRINGP($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + $1 = !SWIG_Guile_GetPtr($input, &ptr, $1_descriptor); +} + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + $1 = !SWIG_Guile_GetPtr($input, &ptr, 0); +} /* typemaps.i ends here */ + + + + + diff --git a/Lib/java/arrays_java.i b/Lib/java/arrays_java.i new file mode 100644 index 000000000..696dcab08 --- /dev/null +++ b/Lib/java/arrays_java.i @@ -0,0 +1,407 @@ +/* arrays_java.i + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from Java and visa versa. + + Example usage: + Wrapping: + + %include "arrays_java.i" + %inline %{ + short FiddleSticks[3]; + %} + + Use from Java like this: + + short[] fs = new short[] {10, 11, 12}; + example.setFiddleSticks(fs); + fs = example.getFiddleSticks(); + + */ + +/* Primitive array support is a combination of SWIG macros and functions in order to reduce + * code bloat and aid maintainability. The SWIG preprocessor expands the macros into functions + * for inclusion in the generated code. */ + +/* Array support functions declarations macro */ +%define JAVA_ARRAYS_DECL(CTYPE, JNITYPE, JAVATYPE, JFUNCNAME) +%{ +int SWIG_JavaArrayIn##JFUNCNAME (JNIEnv *jenv, JNITYPE **jarr, CTYPE **carr, JNITYPE##Array input); +void SWIG_JavaArrayArgout##JFUNCNAME (JNIEnv *jenv, JNITYPE *jarr, CTYPE *carr, JNITYPE##Array input); +JNITYPE##Array SWIG_JavaArrayOut##JFUNCNAME (JNIEnv *jenv, CTYPE *result, jsize sz); +%} +%enddef + +/* Array support functions macro */ +%define JAVA_ARRAYS_IMPL(CTYPE, JNITYPE, JAVATYPE, JFUNCNAME) +%{ +/* CTYPE[] support */ +int SWIG_JavaArrayIn##JFUNCNAME (JNIEnv *jenv, JNITYPE **jarr, CTYPE **carr, JNITYPE##Array input) { + int i; + jsize sz; + if (!input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); + return 0; + } + sz = JCALL1(GetArrayLength, jenv, input); + *jarr = JCALL2(Get##JAVATYPE##ArrayElements, jenv, input, 0); + if (!*jarr) + return 0; %} +#if __cplusplus +%{ *carr = new CTYPE[sz]; %} +#else +%{ *carr = (CTYPE*) calloc(sz, sizeof(CTYPE)); %} +#endif +%{ if (!*carr) { + SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); + return 0; + } + for (i=0; i -#include +/* ----------------------------------------------------------------------------- + * java.swg + * + * Java typemaps + * ----------------------------------------------------------------------------- */ + +%include "javahead.swg" + +/* The jni, jtype and jstype typemaps work together and so there should be one of each. + * The jni typemap contains the JNI type used in the JNI (C/C++) code. + * The jtype typemap contains the Java type used in the Java module class. + * The jstype typemap contains the Java type used in the Java proxy class. */ + +/* Primitive types */ +%typemap(jni) bool, const bool & "jboolean" +%typemap(jni) char, const char & "jchar" +%typemap(jni) signed char, const signed char & "jbyte" +%typemap(jni) unsigned char, const unsigned char & "jshort" +%typemap(jni) short, const short & "jshort" +%typemap(jni) unsigned short, const unsigned short & "jint" +%typemap(jni) int, const int & "jint" +%typemap(jni) unsigned int, const unsigned int & "jlong" +%typemap(jni) long, const long & "jint" +%typemap(jni) unsigned long, const unsigned long & "jlong" +%typemap(jni) long long, const long long & "jlong" +%typemap(jni) unsigned long long, const unsigned long long & "jobject" +%typemap(jni) float, const float & "jfloat" +%typemap(jni) double, const double & "jdouble" +%typemap(jni) char * "jstring" +%typemap(jni) void "void" + +%typemap(jtype) bool, const bool & "boolean" +%typemap(jtype) char, const char & "char" +%typemap(jtype) signed char, const signed char & "byte" +%typemap(jtype) unsigned char, const unsigned char & "short" +%typemap(jtype) short, const short & "short" +%typemap(jtype) unsigned short, const unsigned short & "int" +%typemap(jtype) int, const int & "int" +%typemap(jtype) unsigned int, const unsigned int & "long" +%typemap(jtype) long, const long & "int" +%typemap(jtype) unsigned long, const unsigned long & "long" +%typemap(jtype) long long, const long long & "long" +%typemap(jtype) unsigned long long, const unsigned long long & "java.math.BigInteger" +%typemap(jtype) float, const float & "float" +%typemap(jtype) double, const double & "double" +%typemap(jtype) char * "String" +%typemap(jtype) void "void" + +%typemap(jstype) bool, const bool & "boolean" +%typemap(jstype) char, const char & "char" +%typemap(jstype) signed char, const signed char & "byte" +%typemap(jstype) unsigned char, const unsigned char & "short" +%typemap(jstype) short, const short & "short" +%typemap(jstype) unsigned short, const unsigned short & "int" +%typemap(jstype) int, const int & "int" +%typemap(jstype) unsigned int, const unsigned int & "long" +%typemap(jstype) long, const long & "int" +%typemap(jstype) unsigned long, const unsigned long & "long" +%typemap(jstype) long long, const long long & "long" +%typemap(jstype) unsigned long long, const unsigned long long & "java.math.BigInteger" +%typemap(jstype) float, const float & "float" +%typemap(jstype) double, const double & "double" +%typemap(jstype) char * "String" +%typemap(jstype) void "void" + +%typemap(jni) char[ANY] "jstring" +%typemap(jtype) char[ANY] "String" +%typemap(jstype) char[ANY] "String" + +/* JNI types */ +%typemap(jni) jboolean "jboolean" +%typemap(jni) jchar "jchar" +%typemap(jni) jbyte "jbyte" +%typemap(jni) jshort "jshort" +%typemap(jni) jint "jint" +%typemap(jni) jlong "jlong" +%typemap(jni) jfloat "jfloat" +%typemap(jni) jdouble "jdouble" +%typemap(jni) jstring "jstring" +%typemap(jni) jobject "jobject" +%typemap(jni) jbooleanArray "jbooleanArray" +%typemap(jni) jcharArray "jcharArray" +%typemap(jni) jbyteArray "jbyteArray" +%typemap(jni) jshortArray "jshortArray" +%typemap(jni) jintArray "jintArray" +%typemap(jni) jlongArray "jlongArray" +%typemap(jni) jfloatArray "jfloatArray" +%typemap(jni) jdoubleArray "jdoubleArray" +%typemap(jni) jobjectArray "jobjectArray" + +%typemap(jtype) jboolean "boolean" +%typemap(jtype) jchar "char" +%typemap(jtype) jbyte "byte" +%typemap(jtype) jshort "short" +%typemap(jtype) jint "int" +%typemap(jtype) jlong "long" +%typemap(jtype) jfloat "float" +%typemap(jtype) jdouble "double" +%typemap(jtype) jstring "String" +%typemap(jtype) jobject "Object" +%typemap(jtype) jbooleanArray "boolean[]" +%typemap(jtype) jcharArray "char[]" +%typemap(jtype) jbyteArray "byte[]" +%typemap(jtype) jshortArray "short[]" +%typemap(jtype) jintArray "int[]" +%typemap(jtype) jlongArray "long[]" +%typemap(jtype) jfloatArray "float[]" +%typemap(jtype) jdoubleArray "double[]" +%typemap(jtype) jobjectArray "Object[]" + +%typemap(jstype) jboolean "boolean" +%typemap(jstype) jchar "char" +%typemap(jstype) jbyte "byte" +%typemap(jstype) jshort "short" +%typemap(jstype) jint "int" +%typemap(jstype) jlong "long" +%typemap(jstype) jfloat "float" +%typemap(jstype) jdouble "double" +%typemap(jstype) jstring "String" +%typemap(jstype) jobject "Object" +%typemap(jstype) jbooleanArray "boolean[]" +%typemap(jstype) jcharArray "char[]" +%typemap(jstype) jbyteArray "byte[]" +%typemap(jstype) jshortArray "short[]" +%typemap(jstype) jintArray "int[]" +%typemap(jstype) jlongArray "long[]" +%typemap(jstype) jfloatArray "float[]" +%typemap(jstype) jdoubleArray "double[]" +%typemap(jstype) jobjectArray "Object[]" + +/* Non primitive types */ +%typemap(jni) SWIGTYPE "jlong" +%typemap(jtype) SWIGTYPE "long" +%typemap(jstype) SWIGTYPE "$&javaclassname" + +%typemap(jni) SWIGTYPE [] "jlong" +%typemap(jtype) SWIGTYPE [] "long" +%typemap(jstype) SWIGTYPE [] "$javaclassname" + +%typemap(jni) SWIGTYPE * "jlong" +%typemap(jtype) SWIGTYPE * "long" +%typemap(jstype) SWIGTYPE * "$javaclassname" + +%typemap(jni) SWIGTYPE & "jlong" +%typemap(jtype) SWIGTYPE & "long" +%typemap(jstype) SWIGTYPE & "$javaclassname" + +%typemap(jni) enum SWIGTYPE "jint" +%typemap(jtype) enum SWIGTYPE "int" +%typemap(jstype) enum SWIGTYPE "int" + +/* pointer to a class member */ +%typemap(jni) SWIGTYPE (CLASS::*) "jlong" +%typemap(jtype) SWIGTYPE (CLASS::*) "long" +%typemap(jstype) SWIGTYPE (CLASS::*) "$javaclassname" + +/* The following are the in, out, freearg, argout typemaps. These are the JNI code generating typemaps for converting from Java to C and visa versa. */ + +/* primitive types */ +%typemap(in) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + float, + double, + enum SWIGTYPE +%{ $1 = ($1_ltype)$input; %} + +%typemap(out) bool %{ $result = (jboolean)$1; %} +%typemap(out) char %{ $result = (jchar)$1; %} +%typemap(out) signed char %{ $result = (jbyte)$1; %} +%typemap(out) unsigned char %{ $result = (jshort)$1; %} +%typemap(out) short %{ $result = (jshort)$1; %} +%typemap(out) unsigned short %{ $result = (jint)$1; %} +%typemap(out) int %{ $result = (jint)$1; %} +%typemap(out) unsigned int %{ $result = (jlong)$1; %} +%typemap(out) long %{ $result = (jint)$1; %} +%typemap(out) unsigned long %{ $result = (jlong)$1; %} +%typemap(out) long long %{ $result = (jlong)$1; %} +%typemap(out) float %{ $result = (jfloat)$1; %} +%typemap(out) double %{ $result = (jdouble)$1; %} +%typemap(out) enum SWIGTYPE %{ $result = (jint)$1; %} + + +/* unsigned long long */ +/* Convert from BigInteger using the toByteArray member function */ +%typemap(in) unsigned long long { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return $null; + } + clazz = JCALL1(GetObjectClass, jenv, $input); + mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); + ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); + bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + sz = JCALL1(GetArrayLength, jenv, ba); + $1 = 0; + if (bae[0] == 0) { + for(i=sz-1; i>0; i-- ) { + $1 = ($1 << 8) | (unsigned char)bae[sz-i]; + } + } + else { + for(i=sz; i>=0; i-- ) { + $1 = ($1 << 8) | (unsigned char)bae[sz-1-i]; + } + } + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); +} + +/* Convert to BigInteger - byte array holds number in 2's complement big endian format */ +%typemap(out) unsigned long long { + jbyteArray ba = JCALL1(NewByteArray, jenv, 9); + jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); + jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)($1>>8*(8-i)); + } + + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); + bigint = JCALL3(NewObject, jenv, clazz, mid, ba); + $result = bigint; +} + +/* char * - treat as String */ +%typemap(in) char * { + $1 = 0; + if ($input) { + $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); + if (!$1) return $null; + } +} +%typemap(freearg) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); } +%typemap(out) char * { if($1) $result = JCALL1(NewStringUTF, jenv, $1); } + +%typemap(out) void "" + +/* primitive types by reference */ +%typemap(in) const bool & (bool temp), + const char & (char temp), + const signed char & (signed char temp), + const unsigned char & (unsigned char temp), + const short & (short temp), + const unsigned short & (unsigned short temp), + const int & (int temp), + const unsigned int & (unsigned int temp), + const long & (long temp), + const unsigned long & (unsigned long temp), + const long long & (long long temp), + const float & (float temp), + const double & (double temp) +%{ temp = ($*1_ltype)$input; +$1 = &temp; %} + +%typemap(out) const bool & %{ $result = (jboolean)*$1; %} +%typemap(out) const char & %{ $result = (jchar)*$1; %} +%typemap(out) const signed char & %{ $result = (jbyte)*$1; %} +%typemap(out) const unsigned char & %{ $result = (jshort)*$1; %} +%typemap(out) const short & %{ $result = (jshort)*$1; %} +%typemap(out) const unsigned short & %{ $result = (jint)*$1; %} +%typemap(out) const int & %{ $result = (jint)*$1; %} +%typemap(out) const unsigned int & %{ $result = (jlong)*$1; %} +%typemap(out) const long & %{ $result = (jint)*$1; %} +%typemap(out) const unsigned long & %{ $result = (jlong)*$1; %} +%typemap(out) const long long & %{ $result = (jlong)*$1; %} +%typemap(out) const float & %{ $result = (jfloat)*$1; %} +%typemap(out) const double & %{ $result = (jdouble)*$1; %} + +/* const unsigned long long & */ +/* Similar to unsigned long long */ +%typemap(in) const unsigned long long & (unsigned long long temp) { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return $null; + } + clazz = JCALL1(GetObjectClass, jenv, $input); + mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); + ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); + bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + sz = JCALL1(GetArrayLength, jenv, ba); + $1 = &temp; + temp = 0; + if (bae[0] == 0) { + for(i=sz-1; i>0; i-- ) { + temp = (temp << 8) | (unsigned char)bae[sz-i]; + } + } + else { + for(i=sz; i>=0; i-- ) { + temp = (temp << 8) | (unsigned char)bae[sz-1-i]; + } + } + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); +} + +%typemap(out) const unsigned long long & { + jbyteArray ba = JCALL1(NewByteArray, jenv, 9); + jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); + jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(*$1>>8*(8-i)); + } + + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); + bigint = JCALL3(NewObject, jenv, clazz, mid, ba); + $result = bigint; +} + +/* Default handling. Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE ($&1_type argp) +%{ argp = *($&1_ltype*)&$input; + if (!argp) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type"); + return $null; + } + $1 = *argp; %} +%typemap(out) SWIGTYPE #ifdef __cplusplus -#define JCALL(func, jenv) jenv->func( +%{$&1_ltype $1ptr = new $1_ltype(($1_ltype &)$1); + *($&1_ltype*)&$result = $1ptr; %} #else -#define JCALL(func, jenv) (*jenv)->func(jenv, +{ + $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); + memmove($1ptr, &$1, sizeof($1_type)); + *($&1_ltype*)&$result = $1ptr; +} #endif +/* Generic pointers and references */ +%typemap(in) SWIGTYPE *, SWIGTYPE (CLASS::*) %{ $1 = *($&1_ltype)&$input; %} +%typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input; + if(!$1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null"); + return $null; + } %} +%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE (CLASS::*) %{ *($&1_ltype)&$result = $1; %} + + +/* Default array handling */ +%typemap(in) SWIGTYPE [] %{ $1 = *($&1_ltype)&$input; %} +%typemap(out) SWIGTYPE [] %{ *($&1_ltype)&$result = $1; %} + +/* char[ANY] - treat as String */ +%typemap(in) char[ANY] { + $1 = 0; + if ($input) { + $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); + if (!$1) return $null; + } +} +%typemap(argout) char[ANY] "" +%typemap(freearg) char[ANY] { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); } +%typemap(out) char[ANY] { if($1) $result = JCALL1(NewStringUTF, jenv, $1); } + +/* JNI types */ +%typemap(in) jboolean, + jchar, + jbyte, + jshort, + jint, + jlong, + jfloat, + jdouble, + jstring, + jobject, + jbooleanArray, + jcharArray, + jbyteArray, + jshortArray, + jintArray, + jlongArray, + jfloatArray, + jdoubleArray, + jobjectArray +%{ $1 = $input; %} + +%typemap(out) jboolean, + jchar, + jbyte, + jshort, + jint, + jlong, + jfloat, + jdouble, + jstring, + jobject, + jbooleanArray, + jcharArray, + jbyteArray, + jshortArray, + jintArray, + jlongArray, + jfloatArray, + jdoubleArray, + jobjectArray +%{ $result = $1; %} + + +/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions + * that cannot be overloaded in Java as more than one C++ type maps to a single Java type */ + +%typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */ + jboolean, + bool, + const bool & + "" + +%typecheck(SWIG_TYPECHECK_CHAR) /* Java char */ + jchar, + char, + const char & + "" + +%typecheck(SWIG_TYPECHECK_INT8) /* Java byte */ + jbyte, + signed char, + const signed char & + "" + +%typecheck(SWIG_TYPECHECK_INT16) /* Java short */ + jshort, + unsigned char, + short, + const unsigned char &, + const short & + "" + +%typecheck(SWIG_TYPECHECK_INT32) /* Java int */ + jint, + unsigned short, + int, + long, + const unsigned short &, + const int &, + const long &, + enum SWIGTYPE + "" + +%typecheck(SWIG_TYPECHECK_INT64) /* Java long */ + jlong, + unsigned int, + unsigned long, + long long, + const unsigned int &, + const unsigned long &, + const long long & + "" + +%typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */ + unsigned long long + "" + +%typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */ + jfloat, + float, + const float & + "" + +%typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */ + jdouble, + double, + const double & + "" + +%typecheck(SWIG_TYPECHECK_STRING) /* Java String */ + jstring, + char *, + char[ANY] + "" + +%typecheck(SWIG_TYPECHECK_BOOL_ARRAY) /* Java boolean[] */ + jbooleanArray + "" + +%typecheck(SWIG_TYPECHECK_CHAR_ARRAY) /* Java char[] */ + jcharArray + "" + +%typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */ + jbyteArray + "" + +%typecheck(SWIG_TYPECHECK_INT16_ARRAY) /* Java short[] */ + jshortArray + "" + +%typecheck(SWIG_TYPECHECK_INT32_ARRAY) /* Java int[] */ + jintArray + "" + +%typecheck(SWIG_TYPECHECK_INT64_ARRAY) /* Java long[] */ + jlongArray + "" + +%typecheck(SWIG_TYPECHECK_FLOAT_ARRAY) /* Java float[] */ + jfloatArray + "" + +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY) /* Java double[] */ + jdoubleArray + "" + +%typecheck(SWIG_TYPECHECK_POINTER) /* Default */ + SWIGTYPE, + SWIGTYPE *, + SWIGTYPE &, + SWIGTYPE [], + SWIGTYPE (CLASS::*) + "" + + +/* Exception handling */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + char error_msg[256]; + sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1); + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg); + return $null; +} + +%typemap(throws) SWIGTYPE { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); + return $null; +} + +%typemap(throws) char * { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1); + return $null; +} + + +/* Typemaps for code generation in proxy classes and Java type wrapper classes */ + +/* The javain typemap is used for converting function parameter types from the type + * used in the proxy, module or type wrapper class to the type used in the JNI class. */ +%typemap(javain) bool, const bool &, + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + char *, + char[ANY], + enum SWIGTYPE + "$javainput" +%typemap(javain) jboolean, + jchar, + jbyte, + jshort, + jint, + jlong, + jfloat, + jdouble, + jstring, + jobject, + jbooleanArray, + jcharArray, + jbyteArray, + jshortArray, + jintArray, + jlongArray, + jfloatArray, + jdoubleArray, + jobjectArray + "$javainput" +%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)" +%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "$javaclassname.getCPtr($javainput)" + +/* The javaout typemap is used for converting function return types from the return type + * used in the JNI class to the type returned by the proxy, module or type wrapper class. */ +%typemap(javaout) bool, const bool &, + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + char *, + char[ANY], + enum SWIGTYPE { + return $jnicall; + } +%typemap(javaout) jboolean, + jchar, + jbyte, + jshort, + jint, + jlong, + jfloat, + jdouble, + jstring, + jobject, + jbooleanArray, + jcharArray, + jbyteArray, + jshortArray, + jintArray, + jlongArray, + jfloatArray, + jdoubleArray, + jobjectArray { + return $jnicall; + } +%typemap(javaout) void { + $jnicall; + } +%typemap(javaout) SWIGTYPE { + return new $&javaclassname($jnicall, true); + } +%typemap(javaout) SWIGTYPE & { + return new $javaclassname($jnicall, $owner); + } +%typemap(javaout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) { + long cPtr = $jnicall; + return (cPtr == 0) ? null : new $javaclassname(cPtr, $owner); + } + +/* Typemaps used for the generation of proxy and type wrapper class code */ +%typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(javaclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public" +%typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(javaimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(javainterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(javaptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "protected" + +%typemap(javafinalize) SWIGTYPE %{ + protected void finalize() { + delete(); + } +%} + +%typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + protected static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} + +/* Java specific directives */ +#define %javaconst(flag) %feature("java:const","flag") +#define %javamethodmodifiers %feature("java:methodmodifiers") + +%javamethodmodifiers "public"; + + +/* Some ANSI C typemaps */ + +%apply long { size_t }; + diff --git a/Lib/java/javahead.swg b/Lib/java/javahead.swg new file mode 100644 index 000000000..9ca85fa48 --- /dev/null +++ b/Lib/java/javahead.swg @@ -0,0 +1,84 @@ +/* ----------------------------------------------------------------------------- + * javahead.swg + * + * Java support code + * ----------------------------------------------------------------------------- */ + + +/* JNI function calls require different calling conventions for C and C++. These JCALL macros are used so + * that the same typemaps can be used for generating code for both C and C++. The SWIG preprocessor can expand + * the macros thereby generating the correct calling convention. It is thus essential that all typemaps that + * use the macros are not within %{ %} brackets as they won't be run through the SWIG preprocessor. */ +#ifdef __cplusplus +# define JCALL0(func, jenv) jenv->func() +# define JCALL1(func, jenv, ar1) jenv->func(ar1) +# define JCALL2(func, jenv, ar1, ar2) jenv->func(ar1, ar2) +# define JCALL3(func, jenv, ar1, ar2, ar3) jenv->func(ar1, ar2, ar3) +# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) jenv->func(ar1, ar2, ar3, ar4) +#else +# define JCALL0(func, jenv) (*jenv)->func(jenv) +# define JCALL1(func, jenv, ar1) (*jenv)->func(jenv, ar1) +# define JCALL2(func, jenv, ar1, ar2) (*jenv)->func(jenv, ar1, ar2) +# define JCALL3(func, jenv, ar1, ar2, ar3) (*jenv)->func(jenv, ar1, ar2, ar3) +# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) (*jenv)->func(jenv, ar1, ar2, ar3, ar4) +#endif + +%insert(runtime) %{ +#if defined(__GNUC__) + typedef long long __int64; /*For gcc on Windows */ +#endif +#include +#include +#include +%} + +%insert(runtime) %{ +/* Support for throwing Java exceptions */ +typedef enum { + SWIG_JavaOutOfMemoryError = 1, + SWIG_JavaIOException, + SWIG_JavaRuntimeException, + SWIG_JavaIndexOutOfBoundsException, + SWIG_JavaArithmeticException, + SWIG_JavaIllegalArgumentException, + SWIG_JavaNullPointerException, + SWIG_JavaUnknownError +} SWIG_JavaExceptionCodes; + +typedef struct { + SWIG_JavaExceptionCodes code; + const char *java_exception; +} SWIG_JavaExceptions_t; + +#if defined(SWIG_NOINCLUDE) +void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg); +#else +%} +%insert(runtime) { +void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { + jclass excep; + static const SWIG_JavaExceptions_t java_exceptions[] = { + { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, + { SWIG_JavaIOException, "java/io/IOException" }, + { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, + { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, + { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, + { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, + { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, + { SWIG_JavaUnknownError, "java/lang/UnknownError" }, + { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } }; + const SWIG_JavaExceptions_t *except_ptr = java_exceptions; + + while (except_ptr->code != code && except_ptr->code) + except_ptr++; + + JCALL0(ExceptionClear, jenv); + excep = JCALL1(FindClass, jenv, except_ptr->java_exception); + if (excep) + JCALL2(ThrowNew, jenv, excep, msg); +} +} +%insert(runtime) %{ +#endif +%} + diff --git a/Lib/java/std_string.i b/Lib/java/std_string.i new file mode 100644 index 000000000..7023d7ba4 --- /dev/null +++ b/Lib/java/std_string.i @@ -0,0 +1,183 @@ +// +// SWIG typemaps for std::string +// Luigi Ballabio, Tal Shalif and William Fulton +// May 7, 2002 +// +// Java implementation +// +// ------------------------------------------------------------------------ +// These are mapped to a Java String and are passed around by value. +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +// std::string +%typemap(jni) std::string "jstring" +%typemap(jtype) std::string "String" +%typemap(jstype) std::string "String" + +%typemap(in) std::string +%{if($input) { + const char *pstr = (const char *)jenv->GetStringUTFChars($input, 0); + if (!pstr) return $null; + $1 = std::string(pstr); + jenv->ReleaseStringUTFChars($input, pstr); + } + else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::string"); + return $null; + } %} + +%typemap(out) std::string +%{ $result = jenv->NewStringUTF($1.c_str()); %} + +%typemap(javain) std::string "$javainput" + +%typemap(javaout) std::string { + return $jnicall; + } + +%typemap(typecheck) std::string = char *; + +// const std::string & +%typemap(jni) const std::string & "jstring" +%typemap(jtype) const std::string & "String" +%typemap(jstype) const std::string & "String" + +%typemap(in) const std::string & +%{$1 = NULL; + if($input) { + const char *pstr = (const char *)jenv->GetStringUTFChars($input, 0); + if (!pstr) return $null; + $1 = new std::string(pstr); + jenv->ReleaseStringUTFChars($input, pstr); + } + else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::string"); + return $null; + } %} + +%typemap(freearg) const std::string & +%{ delete $1; %} + +%typemap(out) const std::string & +%{ $result = jenv->NewStringUTF($1->c_str()); %} + +%typemap(javain) const std::string & "$javainput" + +%typemap(javaout) const std::string & { + return $jnicall; + } + +%typemap(typecheck) const std::string & = char *; + +// For using std::string in the global namespace +%apply const std::string & {const string &}; +%apply std::string {string}; + +/* To use non-const std::string references use the following %apply. Note that they are passed by value. +// std::string & +%apply const std::string & {std::string &}; +%apply std::string & {string &}; +*/ + +#ifdef SWIGJAVA_WSTRING +// Warning: Unicode / multibyte characters are handled differently on different OSs so the std::wstring +// typemaps may not always work as intended. Therefore a #define is required to use them. +// std::wstring +%typemap(jni) std::wstring "jstring" +%typemap(jtype) std::wstring "String" +%typemap(jstype) std::wstring "String" + +%typemap(in) std::wstring +%{if($input) { + const jchar *pstr = jenv->GetStringChars($input, 0); + if (!pstr) return $null; + jsize len = jenv->GetStringLength($input); + if (len) { + wchar_t *conv_buf = new wchar_t[len]; + for (jsize i = 0; i < len; ++i) { + conv_buf[i] = pstr[i]; + } + $1 = std::wstring(conv_buf, len); + delete [] conv_buf; + } + jenv->ReleaseStringChars($input, pstr); + } + else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::wstring"); + return $null; + } %} + +%typemap(out) std::wstring +%{jsize len = $1.length(); + jchar *conv_buf = new jchar[len]; + for (jsize i = 0; i < len; ++i) { + conv_buf[i] = (jchar)$1[i]; + } + $result = jenv->NewString(conv_buf, len); + delete [] conv_buf; %} + +%typemap(javain) std::wstring "$javainput" + +%typemap(javaout) std::wstring { + return $jnicall; + } + +// const std::wstring & +%typemap(jni) const std::wstring & "jstring" +%typemap(jtype) const std::wstring & "String" +%typemap(jstype) const std::wstring & "String" + +%typemap(in) const std::wstring & +%{$1 = NULL; + if($input) { + const jchar *pstr = jenv->GetStringChars($input, 0); + if (!pstr) return $null; + jsize len = jenv->GetStringLength($input); + if (len) { + wchar_t *conv_buf = new wchar_t[len]; + for (jsize i = 0; i < len; ++i) { + conv_buf[i] = pstr[i]; + } + $1 = new std::wstring(conv_buf, len); + delete [] conv_buf; + } + jenv->ReleaseStringChars($input, pstr); + } + else { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::wstring"); + return $null; + } %} + +%typemap(out) const std::wstring & +%{jsize len = $1->length(); + jchar *conv_buf = new jchar[len]; + for (jsize i = 0; i < len; ++i) { + conv_buf[i] = (jchar)(*$1)[i]; + } + $result = jenv->NewString(conv_buf, len); + delete [] conv_buf; %} + +%typemap(javain) const std::wstring & "$javainput" + +%typemap(javaout) const std::wstring & { + return $jnicall; + } + +// For using std::wstring in the global namespace +%apply const std::wstring & {const wstring &}; +%apply std::wstring {wstring}; + +/* To use non-const std::wstring references use the following %apply. Note that they are passed by value. +// std::wstring & +%apply const std::wstring & {std::wstring &}; +%apply std::wstring & {wstring &}; +*/ + +#endif + diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i new file mode 100644 index 000000000..ccc82203e --- /dev/null +++ b/Lib/java/std_vector.i @@ -0,0 +1,137 @@ +// +// SWIG typemaps for std::vector +// Luigi Ballabio +// May 7, 2002 +// +// Java implementation + + +%include exception.i + +// containers + +// methods which can raise are caused to throw an IndexError +%exception std::vector::get { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::set { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Java as much as possible, namely, to allow the user to pass and +// be returned Java (arrays? containers?) +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Java sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Java sequence of T:s +// is returned which is most easily used in other Java functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class vector { + // add generic typemaps here + public: + vector(unsigned int size = 0); + unsigned int size() const; + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const T& x); + %extend { + T& get(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + // add specialized typemaps here + public: + vector(unsigned int size = 0); + unsigned int size() const; + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(int x); + %extend { + T get(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i - */ -/* what type to use in java source code */ -%typemap(java,jtype) const string & {String} +The following methods can be applied to turn a pointer or reference into a simple +"input" value. That is, instead of passing a pointer or reference to an object, +you would use a real value instead. -/* what is the corresponding jni type */ -%typemap(java,jni) const string & {jstring} + bool *INPUT, bool &INPUT + signed char *INPUT, signed char &INPUT + unsigned char *INPUT, unsigned char &INPUT + short *INPUT, short &INPUT + unsigned short *INPUT, unsigned short &INPUT + int *INPUT, int &INPUT + unsigned int *INPUT, unsigned int &INPUT + long *INPUT, long &INPUT + unsigned long *INPUT, unsigned long &INPUT + long long *INPUT, long long &INPUT + unsigned long long *INPUT, unsigned long long &INPUT + float *INPUT, float &INPUT + double *INPUT, double &INPUT + +To use these, suppose you had a C function like this : -/* how to convert the c++ type to the java type */ -%typemap(java,out) const string & { - $target = JCALL(NewStringUTF, jenv) $source->c_str()); -} + double fadd(double *a, double *b) { + return *a+*b; + } -/* how to convert java type to requested c++ type */ -%typemap(java,in) const string & { - $target = NULL; - if($source != NULL) { - /* get the String from the StringBuffer */ - char *p = (char *)jenv->GetStringUTFChars($source, 0); - $target = new string(p); - JCALL(ReleaseStringUTFChars, jenv) $source, p); +You could wrap it with SWIG as follows : + + %include typemaps.i + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +In Java you could then use it like this: + double answer = modulename.fadd(10.0 + 20.0); + +*/ + +%define INPUT_TYPEMAP(CTYPE, JNITYPE, JTYPE) +%typemap(jni) CTYPE *INPUT "JNITYPE" +%typemap(jtype) CTYPE *INPUT "JTYPE" +%typemap(jstype) CTYPE *INPUT "JTYPE" +%typemap(javain) CTYPE *INPUT "$javainput" + +%typemap(jni) CTYPE &INPUT "JNITYPE" +%typemap(jtype) CTYPE &INPUT "JTYPE" +%typemap(jstype) CTYPE &INPUT "JTYPE" +%typemap(javain) CTYPE &INPUT "$javainput" + +%typemap(in) CTYPE *INPUT, CTYPE &INPUT +%{ $1 = ($1_ltype)&$input; %} + +%typemap(typecheck) CTYPE *INPUT = CTYPE; +%typemap(typecheck) CTYPE &INPUT = CTYPE; +%enddef + +INPUT_TYPEMAP(bool, jboolean, boolean); +INPUT_TYPEMAP(signed char, jbyte, byte); +INPUT_TYPEMAP(unsigned char, jshort, short); +INPUT_TYPEMAP(short, jshort, short); +INPUT_TYPEMAP(unsigned short, jint, int); +INPUT_TYPEMAP(int, jint, int); +INPUT_TYPEMAP(unsigned int, jlong, long); +INPUT_TYPEMAP(long, jint, int); +INPUT_TYPEMAP(unsigned long, jlong, long); +INPUT_TYPEMAP(long long, jlong, long); +INPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger); +INPUT_TYPEMAP(float, jfloat, float); +INPUT_TYPEMAP(double, jdouble, double); + +#undef INPUT_TYPEMAP + +/* Convert from BigInteger using the toByteArray member function */ +/* Overrides the typemap in the INPUT_TYPEMAP macro */ +%typemap(in) unsigned long long *INPUT($*1_type temp), unsigned long long &INPUT(unsigned long long temp) { + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); + return $null; } -} -/* free resource once finished using */ -%typemap(java,freearg) const string & { - delete $target; -} - -%typemap(java,jtype) string & = const string &; -%typemap(java,jni) string & = const string &; -%typemap(java,in) string & = const string &; -%typemap(java,out) string & = const string &; -%typemap(java,freearg) string & = const string &; - -/* what type to use in java source code */ -%typemap(java,jtype) const wstring & {String} - -/* what is the corresponding jni type */ -%typemap(java,jni) const wstring & {jstring} - -/* how to convert the c++ type to the java type */ -%typemap(java,out) const wstring & { - unsigned int len = $source->length(); - jchar *conv_buf = new jchar[len]; - for (unsigned int i = 0; i < len; ++i) { - conv_buf[i] = (jchar)(*$source)[i]; - } - $target = JCALL(NewString, jenv) conv_buf, len); - delete [] conv_buf; -} - -/* how to convert java type to requested c++ type */ -%typemap(java,in) const wstring & { - $target = NULL; - if($source != NULL) { - /* get the String from the StringBuffer */ - const jchar *jchar_p = jenv->GetStringChars($source, 0); - unsigned int len; - for (len = 0; jchar_p[len]; ++len); - if (len) { - wchar_t *conv_buf = new wchar_t[len]; - for (unsigned int i = 0; i < len; ++i) { - conv_buf[i] = jchar_p[i]; - } - $target = new wstring(conv_buf, len); - delete [] conv_buf; + clazz = JCALL1(GetObjectClass, jenv, $input); + mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); + ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); + bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + sz = JCALL1(GetArrayLength, jenv, ba); + temp = 0; + if (bae[0] == 0) { + for(i=sz-1; i>0; i-- ) { + temp = (temp << 8) | (unsigned char)bae[sz-i]; + } + } + else { + for(i=sz; i>=0; i-- ) { + temp = (temp << 8) | (unsigned char)bae[sz-1-i]; } - - JCALL(ReleaseStringChars, jenv) $source, jchar_p); } + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); + $1 = &temp; } +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. An array replaces the c pointer or reference parameter. +// The output value is returned in this array passed in. + +/* +The following methods can be applied to turn a pointer or reference into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. This works by a +Java array being passed as a parameter where a c pointer or reference is required. +As with any Java function, the array is passed by reference so that +any modifications to the array will be picked up in the calling function. +Note that the array passed in MUST have at least one element, but as the +c function does not require any input, the value can be set to anything. + + bool *OUTPUT, bool &OUTPUT + signed char *OUTPUT, signed char &OUTPUT + unsigned char *OUTPUT, unsigned char &OUTPUT + short *OUTPUT, short &OUTPUT + unsigned short *OUTPUT, unsigned short &OUTPUT + int *OUTPUT, int &OUTPUT + unsigned int *OUTPUT, unsigned int &OUTPUT + long *OUTPUT, long &OUTPUT + unsigned long *OUTPUT, unsigned long &OUTPUT + long long *OUTPUT, long long &OUTPUT + unsigned long long *OUTPUT, unsigned long long &OUTPUT + float *OUTPUT, float &OUTPUT + double *OUTPUT, double &OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters): + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include typemaps.i + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Java output of the function would be the function return value and the +value in the single element array. In Java you would use it like this: + + double[] intptr = {0}; + double fraction = modulename.modf(5,intptr); + +*/ + +%typecheck(SWIG_TYPECHECK_INT128_ARRAY) SWIGBIGINTEGERARRAY "" /* Java BigInteger[] */ + +%define OUTPUT_TYPEMAP(CTYPE, JNITYPE, JTYPE, JAVATYPE, TYPECHECKTYPE) +%typemap(jni) CTYPE *OUTPUT %{JNITYPE##Array%} +%typemap(jtype) CTYPE *OUTPUT "JTYPE[]" +%typemap(jstype) CTYPE *OUTPUT "JTYPE[]" +%typemap(javain) CTYPE *OUTPUT "$javainput" + +%typemap(jni) CTYPE &OUTPUT %{JNITYPE##Array%} +%typemap(jtype) CTYPE &OUTPUT "JTYPE[]" +%typemap(jstype) CTYPE &OUTPUT "JTYPE[]" +%typemap(javain) CTYPE &OUTPUT "$javainput" + +%typemap(in) CTYPE *OUTPUT($*1_type temp), CTYPE &OUTPUT(CTYPE temp) +{ + if (!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); + return $null; + } + if (JCALL1(GetArrayLength, jenv, $input) == 0) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); + return $null; + } + $1 = &temp; +} + +%typemap(argout) CTYPE *OUTPUT, CTYPE &OUTPUT +{ JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, (JNITYPE *)&temp$argnum); } + +%typemap(typecheck) CTYPE *INOUT = TYPECHECKTYPE; +%typemap(typecheck) CTYPE &INOUT = TYPECHECKTYPE; +%enddef + +OUTPUT_TYPEMAP(bool, jboolean, boolean, Boolean, jbooleanArray); +OUTPUT_TYPEMAP(signed char, jbyte, byte, Byte, jbyteArray); +OUTPUT_TYPEMAP(unsigned char, jshort, short, Short, jshortArray); +OUTPUT_TYPEMAP(short, jshort, short, Short, jshortArray); +OUTPUT_TYPEMAP(unsigned short, jint, int, Int, jintArray); +OUTPUT_TYPEMAP(int, jint, int, Int, jintArray); +OUTPUT_TYPEMAP(unsigned int, jlong, long, Long, jlongArray); +OUTPUT_TYPEMAP(long, jint, int, Int, jintArray); +OUTPUT_TYPEMAP(unsigned long, jlong, long, Long, jlongArray); +OUTPUT_TYPEMAP(long long, jlong, long, Long, jlongArray); +OUTPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, NOTUSED, SWIGBIGINTEGERARRAY); +OUTPUT_TYPEMAP(float, jfloat, float, Float, jfloatArray); +OUTPUT_TYPEMAP(double, jdouble, double, Double, jdoubleArray); + +#undef OUTPUT_TYPEMAP + +/* Convert to BigInteger - byte array holds number in 2's complement big endian format */ +/* Use first element in BigInteger array for output */ +/* Overrides the typemap in the OUTPUT_TYPEMAP macro */ +%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { + jbyteArray ba = JCALL1(NewByteArray, jenv, 9); + jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); + jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); + jobject bigint; + int i; + + bae[0] = 0; + for(i=1; i<9; i++ ) { + bae[i] = (jbyte)(temp$argnum>>8*(8-i)); + } + + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); + bigint = JCALL3(NewObject, jenv, clazz, mid, ba); + JCALL3(SetObjectArrayElement, jenv, $input, 0, bigint); +} + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned as an element in a Java array. + + bool *INOUT, bool &INOUT + signed char *INOUT, signed char &INOUT + unsigned char *INOUT, unsigned char &INOUT + short *INOUT, short &INOUT + unsigned short *INOUT, unsigned short &INOUT + int *INOUT, int &INOUT + unsigned int *INOUT, unsigned int &INOUT + long *INOUT, long &INOUT + unsigned long *INOUT, unsigned long &INOUT + long long *INOUT, long long &INOUT + unsigned long long *INOUT, unsigned long long &INOUT + float *INOUT, float &INOUT + double *INOUT, double &INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + void neg(double *INOUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *INOUT { double *x }; + void neg(double *x); + +This works similarly to C in that the mapping directly modifies the +input value - the input must be an array with a minimum of one element. +The element in the array is the input and the output is the element in +the array. + + double x[] = {5}; + neg(x); + +The implementation of the OUTPUT and INOUT typemaps is different to other +languages in that other languages will return the output value as part +of the function return value. This difference is due to Java being a typed language. + +*/ + +%define INOUT_TYPEMAP(CTYPE, JNITYPE, JTYPE, JAVATYPE, TYPECHECKTYPE) +%typemap(jni) CTYPE *INOUT %{JNITYPE##Array%} +%typemap(jtype) CTYPE *INOUT "JTYPE[]" +%typemap(jstype) CTYPE *INOUT "JTYPE[]" +%typemap(javain) CTYPE *INOUT "$javainput" + +%typemap(jni) CTYPE &INOUT %{JNITYPE##Array%} +%typemap(jtype) CTYPE &INOUT "JTYPE[]" +%typemap(jstype) CTYPE &INOUT "JTYPE[]" +%typemap(javain) CTYPE &INOUT "$javainput" + +%typemap(in) CTYPE *INOUT, CTYPE &INOUT { + if (!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); + return $null; + } + if (JCALL1(GetArrayLength, jenv, $input) == 0) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); + return $null; + } + $1 = ($1_ltype) JCALL2(Get##JAVATYPE##ArrayElements, jenv, $input, 0); +} + +%typemap(argout) CTYPE *INOUT, CTYPE &INOUT +{ JCALL3(Release##JAVATYPE##ArrayElements, jenv, $input, (JNITYPE *)$1, 0); } + +%typemap(typecheck) CTYPE *INOUT = TYPECHECKTYPE; +%typemap(typecheck) CTYPE &INOUT = TYPECHECKTYPE; +%enddef + +INOUT_TYPEMAP(bool, jboolean, boolean, Boolean, jbooleanArray); +INOUT_TYPEMAP(signed char, jbyte, byte, Byte, jbyteArray); +INOUT_TYPEMAP(unsigned char, jshort, short, Short, jshortArray); +INOUT_TYPEMAP(short, jshort, short, Short, jshortArray); +INOUT_TYPEMAP(unsigned short, jint, int, Int, jintArray); +INOUT_TYPEMAP(int, jint, int, Int, jintArray); +INOUT_TYPEMAP(unsigned int, jlong, long, Long, jlongArray); +INOUT_TYPEMAP(long, jint, int, Int, jintArray); +INOUT_TYPEMAP(unsigned long, jlong, long, Long, jlongArray); +INOUT_TYPEMAP(long long, jlong, long, Long, jlongArray); +INOUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, NOTUSED, SWIGBIGINTEGERARRAY); +INOUT_TYPEMAP(float, jfloat, float, Float, jfloatArray); +INOUT_TYPEMAP(double, jdouble, double, Double, jdoubleArray); + +#undef INOUT_TYPEMAP + +/* Override the typemap in the INOUT_TYPEMAP macro */ +%typemap(in) unsigned long long *INOUT ($*1_type temp), unsigned long long &INOUT (unsigned long long temp) { + jobject bigint; + jclass clazz; + jmethodID mid; + jbyteArray ba; + jbyte* bae; + jsize sz; + int i; + + if (!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); + return $null; + } + if (JCALL1(GetArrayLength, jenv, $input) == 0) { + SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); + return $null; + } + bigint = JCALL2(GetObjectArrayElement, jenv, $input, 0); + if (!bigint) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array element null"); + return $null; + } + clazz = JCALL1(GetObjectClass, jenv, bigint); + mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); + ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, bigint, mid); + bae = JCALL2(GetByteArrayElements, jenv, ba, 0); + sz = JCALL1(GetArrayLength, jenv, ba); + temp = 0; + if (bae[0] == 0) { + for(i=sz-1; i>0; i-- ) { + temp = (temp << 8) | (unsigned char)bae[sz-i]; + } + } + else { + for(i=sz; i>=0; i-- ) { + temp = (temp << 8) | (unsigned char)bae[sz-1-i]; + } + } + JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); + $1 = &temp; +} + +%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; +%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; + -%typemap(java,jtype) wstring & = const wstring &; -%typemap(java,jni) wstring & = const wstring &; -%typemap(java,in) wstring & = const wstring &; -%typemap(java,out) wstring & = const wstring &; -%typemap(java,freearg) wstring & = const wstring &; diff --git a/Lib/java/various.i b/Lib/java/various.i new file mode 100644 index 000000000..e19188e0d --- /dev/null +++ b/Lib/java/various.i @@ -0,0 +1,106 @@ +/* + * SWIG Typemap library for Java + * Various useful typemaps. + * +*/ + +/* char **STRING_IN */ +%typemap(jni) char **STRING_IN "jobjectArray" +%typemap(jtype) char **STRING_IN "String[]" +%typemap(jstype) char **STRING_IN "String[]" +%typemap(in) char **STRING_IN { + int i; + jsize sz = JCALL1(GetArrayLength, jenv, $input); + $1 = (char **) calloc((sz+1), sizeof(char *)); + for(i=0; i -%} - -%section "Memory Allocation Module", - pre,info,after,nosort,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0,skip=1 - -%text %{ -%include malloc.i - -This module provides access to a few basic C memory management functions. -All functions return void pointers, but realloc() and free() will operate -on any sort of pointer. Sizes should be specified in bytes. -%} - -void *calloc(unsigned nobj, unsigned size); -/* Returns a pointer to a space for an array of nobj objects, each with - size bytes. Returns NULL if the request can't be satisfied. - Initializes the space to zero bytes. */ - -void *malloc(unsigned size); -/* Returns a pointer to space for an object of size bytes. Returns NULL - upon failure. */ - -void *realloc(void *ptr, unsigned size); -/* Changes the size of the object pointed to by ptr to size bytes. - The contents will be unchanged up the minimum of the old and new - sizes. Returns a pointer to the new space of NULL upon failure, - in which case *ptr is unchanged. */ - -void free(void *ptr); -/* Deallocates the space pointed to by ptr. Does nothing if ptr is NULL. - ptr must be a space previously allocated by calloc, malloc, or realloc. */ - diff --git a/Lib/math.i b/Lib/math.i index bdec05e12..752fa1e1a 100644 --- a/Lib/math.i +++ b/Lib/math.i @@ -1,21 +1,10 @@ -// -// $Header$ -// -// math.i -// Dave Beazley -// March 24, 1996 -// SWIG file for floating point operations -// -/* Revision history - * $Log$ - * Revision 1.1 2000/01/11 21:15:48 beazley - * Added files +/* + * $Header$ * - * Revision 1.1.1.1 1999/02/28 02:00:53 beazley - * Swig1.1 - * - * Revision 1.1 1996/05/22 17:27:01 beazley - * Initial revision + * math.i + * Dave Beazley + * March 24, 1996 + * SWIG file for floating point operations * */ @@ -24,20 +13,6 @@ #include %} -%section "SWIG Math Module",after,info,nosort,pre,chop_left=3,chop_bottom=0,chop_top=0,chop_right=0,skip=1 - -%text %{ -%include math.i - -This module provides access to the C math library and contains most -of the functions in . Most scripting languages already provide -math support, but in certain cases, this module can provide more -direct access. -%} - -%subsection "Functions" - - extern double cos(double x); /* Cosine of x */ @@ -95,8 +70,6 @@ extern double floor(double x); extern double fmod(double x, double y); /* Floating-point remainder of x/y, with the same sign as x. */ -%subsection "Mathematical constants",noinfo - #define M_E 2.7182818284590452354 #define M_LOG2E 1.4426950408889634074 #define M_LOG10E 0.43429448190325182765 diff --git a/Lib/memory.i b/Lib/memory.i deleted file mode 100644 index e656325a0..000000000 --- a/Lib/memory.i +++ /dev/null @@ -1,39 +0,0 @@ -// -// memory.i -// Dave Beazley -// November 30, 1996 -// SWIG file for memory operations -// - -%module memory -%{ -#include -%} - -%section "Memory Manipulation Module",after,info,nosort,pre,chop_left=3,chop_bottom=0,chop_top=0,chop_right=0,skip=1 - -%text %{ -%include memory.i - -This module provides support for a few memory operations from the C - library. These functions can be used to manipulate binary -data. s and t are of type void *, cs and ct are both of type const void *. -%} - -void *memcpy(void *s, const void *ct, int n); -/* Copy n characters from ct to s, and return s */ - -void *memmove(void *s, const void *ct, int n); -/* Same as memcpy except that it works even if the objects overlap. */ - -int memcmp(const void *cs, const void *ct, int n); -/* Compare the first n characters of cs with ct. Returns 0 if - they are equal, <0 if cs < ct, and >0 if cs > ct. */ - -void *memchr(const void *cs, char c, int n); -/* Returns pointer to the first occurrence of character c in cs. */ - -void *memset(void *s, char c, int n); -/* Place character c into first n characters of s, return s */ - - diff --git a/Lib/mzscheme/mzscheme.i b/Lib/mzscheme/mzscheme.i new file mode 100644 index 000000000..372a0b906 --- /dev/null +++ b/Lib/mzscheme/mzscheme.i @@ -0,0 +1,26 @@ +/* SWIG Configuration File for MzScheme. -*-c-*- + This file is parsed by SWIG before reading any other interface + file. */ + +/* Include headers */ +%insert(runtime) "mzschemedec.swg" + +/*#ifndef SWIG_NOINCLUDE*/ +%insert(runtime) "mzscheme.swg" +/*#endif*/ + +%define SWIG_APPEND_VALUE(value) + values[lenv++] = value +%enddef + +/* Definitions */ +#define SWIG_malloc(size) swig_malloc(size, FUNC_NAME) +#define SWIG_free(mem) free(mem) + +/* Guile compatibility kludges */ +#define SCM_VALIDATE_VECTOR(argnum, value) (void)0 +#define SCM_VALIDATE_LIST(argnum, value) (void)0 + +/* Read in standard typemaps. */ +%include "typemaps.i" + diff --git a/Lib/mzscheme/mzscheme.swg b/Lib/mzscheme/mzscheme.swg index cd0a732eb..e4ac8864f 100644 --- a/Lib/mzscheme/mzscheme.swg +++ b/Lib/mzscheme/mzscheme.swg @@ -1,29 +1,270 @@ -#include +/* -*-c-*- */ -typedef struct swig_proxy { +/* SWIG pointer structure */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct SwigCast { + struct SwigPtrType *type; /* Type in SwigPtrTbl */ + void *(*cast)(void *); /* Pointer casting function */ + struct SwigCast *next; /* Linked list pointer */ +}; + +struct SwigPtrType { + const char *name; /* Datatype name */ + const char *prettyname; /* Pretty datatype name */ + struct SwigCast *cast; /* List of compatible types */ +}; + +struct swig_proxy { Scheme_Type type; + SwigPtrType *ptrtype; void *object; -} swig_proxy; +}; -static Scheme_Object *swig_make_c_pointer(void *c_pointer, char *type_name) { - swig_proxy *new_proxy; - new_proxy = (swig_proxy *) scheme_malloc(sizeof(swig_proxy)); - new_proxy->type = scheme_make_type(type_name); +/* Pointer table */ +static SwigPtrType **SwigPtrTbl = 0; /* Sorted table */ +static int SwigPtrMax = 64; /* Max entries that can be held */ + /* (may be adjusted dynamically) */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ + +/* Sort comparison function */ +static int +swigsort (const void *data1, const void *data2) +{ + SwigPtrType *type1 = * (SwigPtrType **) data1; + SwigPtrType *type2 = * (SwigPtrType **) data2; + return strcmp(type1->name, type2->name); +} + +/* Register a new datatype with the type-checker */ +SWIGSTATIC SwigPtrType * +SWIG_RegisterType (const char *type, const char *prettyname) +{ + int i; + struct SwigPtrType **t; + + /* Allocate the pointer table if necessary */ + if (!SwigPtrTbl) { + SwigPtrTbl = (SwigPtrType **) malloc(SwigPtrMax*sizeof(SwigPtrType *)); + SwigPtrN = 0; + } + /* Grow the table if necessary */ + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTbl = (SwigPtrType **) realloc((char *) SwigPtrTbl, + SwigPtrMax*sizeof(SwigPtrType *)); + } + /* Look up type */ + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTbl[i]->name,type) == 0) { + if (prettyname!=NULL) + SwigPtrTbl[i]->prettyname = prettyname; + return SwigPtrTbl[i]; + } + t = SwigPtrTbl + SwigPtrN; + *t = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + (*t)->name = type; + (*t)->prettyname = prettyname; + (*t)->cast = NULL; + SwigPtrN++; + SwigPtrSort = 0; + return *t; +} + +/* Register two data types and their mapping with the type checker. */ +SWIGSTATIC void +SWIG_RegisterMapping (const char *origtype, const char *newtype, void *(*cast)(void *)) +{ + struct SwigPtrType *t = SWIG_RegisterType(origtype, NULL); + + if (newtype!=NULL) { + struct SwigPtrType *t1 = SWIG_RegisterType(newtype, NULL); + struct SwigCast *c; + /* Check for existing cast */ + for (c = t->cast; c && c->type!=t1; c=c->next) /* nothing */; + if (c) { + if (cast) c->cast = cast; + } + else { + c = (struct SwigCast *) malloc(sizeof(struct SwigCast)); + c->type = t1; + c->cast = cast; + c->next = t->cast; + t->cast = c; + } + } +} + +/* Sort table */ + +static void +SWIG_SortTable (void) +{ + qsort ((void *) SwigPtrTbl, SwigPtrN, sizeof(struct SwigPtrTbl *), swigsort); + /* Indicate that everything is sorted */ + SwigPtrSort = 1; +} + +/* Look up pointer-type entry in table */ + +static int +swigcmp (const void *key, const void *data) +{ + char *k = (char *) key; + SwigPtrType *t = *(SwigPtrType **) data; + return strcmp(k, t->name); +} + +static SwigPtrType * +SWIG_GetPtrType (const char *_t) +{ + SwigPtrType **result; + if (!SwigPtrSort) SWIG_SortTable(); + result = (SwigPtrType **) bsearch(_t, SwigPtrTbl, SwigPtrN, + sizeof(SwigPtrType *), swigcmp); + if (result!=NULL) return *result; + else return NULL; +} + +/* Cast a pointer if possible; returns 1 if successful */ + +static int +SWIG_Cast (void *source, SwigPtrType *source_type, + void **ptr, SwigPtrType *dest_type) +{ + if (dest_type != source_type) { + /* We have a type mismatch. Will have to look through our type + mapping table to figure out whether or not we can accept this + datatype. */ + struct SwigCast *c; + for (c = dest_type->cast; + c && c->type!=source_type; c = c->next) /* nothing */; + if (c) { + /* Get pointer value. */ + if (c->cast) *ptr = (*(c->cast))(source); + else *ptr = source; + return -1; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return false. */ + *ptr = source; + return 0; + } else { + /* Found a match on the first try. Return pointer value. */ + *ptr = source; + return -1; + } +} + +/* Function for getting a pointer value */ + +static Scheme_Type swig_type; +int swig_initialized_p = 0; + +SWIGSTATIC Scheme_Object * +SWIG_MakePtr(void *c_pointer, swig_type_info *type) { + struct swig_proxy *new_proxy; + new_proxy = (struct swig_proxy *) scheme_malloc(sizeof(struct swig_proxy)); + new_proxy->type = swig_type; + new_proxy->ptrtype = type->ptrtype; new_proxy->object = (void *) c_pointer; - return (Scheme_Object *) new_proxy; } -/* returns 1 on success, 0 otherwise */ -static int swig_get_c_pointer(Scheme_Object *so, char *c_type, void **c_ptr) { - Scheme_Type st = SCHEME_TYPE(so); - char *type_name = scheme_get_type_name(st); - int err = 1; - if(strcmp(type_name, c_type)) - err = 0; - else - *c_ptr = ((swig_proxy *) so)->object; - - return err; +/* Return 0 if successful. */ +SWIGSTATIC int +SWIG_GetPtr(Scheme_Object *s, void **result, swig_type_info *type) +{ + if (SCHEME_NULLP(s)) { + *result = NULL; + return 0; + } + else if (SCHEME_TYPE(s) == swig_type) { + struct swig_proxy *proxy = (struct swig_proxy *) s; + if (type) { + return !SWIG_Cast(proxy->object, proxy->ptrtype, + result, type->ptrtype); + } + else { + *result = proxy->object; + return 0; + } + } + return -1; } +SWIGSTATIC void * +SWIG_MustGetPtr_ (Scheme_Object *s, swig_type_info *type, + int argnum, const char *func_name, + int argc, Scheme_Object **argv) +{ + void *result; + if (SWIG_GetPtr(s, &result, type) != 0) { + /* type mismatch */ + scheme_wrong_type(func_name, type->str ? type->str : "void *", argnum, argc, argv); + } + return result; +} + +SWIGSTATIC +void SWIG_RegisterTypes(swig_type_info **table, + swig_type_info **init) +{ + if (!swig_initialized_p) { + swig_type = scheme_make_type((char *) "swig"); + swig_initialized_p = 1; + } + for (; *init; table++, init++) { + swig_type_info *type = *table = *init; + const char *origname = type->name; + /* Register datatype itself and store pointer back */ + type->ptrtype = SWIG_RegisterType(origname, type->str); + /* Register compatible types */ + for (type++; type->name; type++) + SWIG_RegisterMapping(origname, type->name, type->converter); + } +} + + +/* Dynamic pointer casting. Down an inheritance hierarchy */ +SWIGSTATIC swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) +{ + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +static Scheme_Object * +swig_package_values(int num, Scheme_Object **values) +{ + /* ignore first value if void */ + if (num > 0 && SCHEME_VOIDP(values[0])) + num--, values++; + if (num == 0) return scheme_void; + else if (num == 1) return values[0]; + else return scheme_values(num, values); +} + +static void * +swig_malloc(size_t size, const char *func_name) +{ + void *p = malloc(size); + if (p == NULL) { + scheme_signal_error("swig-memory-error"); + } + else return p; +} + +#ifdef __cplusplus +} +#endif + diff --git a/Lib/mzscheme/mzschemedec.swg b/Lib/mzscheme/mzschemedec.swg new file mode 100644 index 000000000..59a540422 --- /dev/null +++ b/Lib/mzscheme/mzschemedec.swg @@ -0,0 +1,84 @@ +/* -*-c-*- + * ----------------------------------------------------------------------- + * swig_lib/mzscheme/mzschemedec.swg + * Copyright (C) 2000, 2001 Matthias Koeppe + * + * MzScheme runtime code -- declarations + * ----------------------------------------------------------------------- */ + +#include +#include +#include + +#include + +#if defined(SWIG_NOINCLUDE) +# define SWIGSTATIC +#elif defined(SWIG_GLOBAL) +# define SWIGSTATIC +#else +# define SWIGSTATIC static +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXVALUES 6 + +static Scheme_Object * +swig_make_boolean(int b) +{ + if (b) return scheme_true; + else return scheme_false; +} + +static Scheme_Object * +swig_package_values(int num, Scheme_Object **values); + + +typedef struct SwigPtrType SwigPtrType; +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +typedef struct swig_type_info { + const char *name; + void *(*converter)(void *); + const char *str; + void *clientdata; + SwigPtrType *ptrtype; + swig_dycast_func dcast; +} swig_type_info; + +SWIGSTATIC SwigPtrType * +SWIG_RegisterType (const char *type, const char *prettyname); + +SWIGSTATIC void +SWIG_RegisterMapping (const char *origtype, const char *newtype, void *(*cast)(void *)); + +/* Dynamic pointer casting. Down an inheritance hierarchy */ +SWIGSTATIC swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr); + +SWIGSTATIC Scheme_Object * +SWIG_MakePtr(void *c_pointer, swig_type_info *type); + +SWIGSTATIC int +SWIG_GetPtr(Scheme_Object *s, void **result, swig_type_info *type); + +SWIGSTATIC void * +SWIG_MustGetPtr_ (Scheme_Object *s, swig_type_info *type, + int argnum, const char *func_name, + int argc, Scheme_Object **argv); + +#define SWIG_MustGetPtr(s, type, argnum) \ + SWIG_MustGetPtr_(s, type, argnum, FUNC_NAME, argc, argv) + +SWIGSTATIC +void SWIG_RegisterTypes(swig_type_info **table, + swig_type_info **init); + +#ifdef __cplusplus +} +#endif + +/* mzschemedec.swg ends here */ diff --git a/Lib/mzscheme/std_common.i b/Lib/mzscheme/std_common.i new file mode 100644 index 000000000..d3c29110f --- /dev/null +++ b/Lib/mzscheme/std_common.i @@ -0,0 +1,17 @@ +// +// SWIG typemaps for STL - common utilities +// Luigi Ballabio +// Aug 3, 2002 +// +// MzScheme implementation + +%{ +#include + +std::string swig_scm_to_string(Scheme_Object* x) { + return std::string(SCHEME_STR_VAL(x)); +} +Scheme_Object* swig_make_string(const std::string& s) { + return scheme_make_string(s.c_str()); +} +%} diff --git a/Lib/mzscheme/std_string.i b/Lib/mzscheme/std_string.i new file mode 100644 index 000000000..fe70e9ab5 --- /dev/null +++ b/Lib/mzscheme/std_string.i @@ -0,0 +1,56 @@ +// +// SWIG typemaps for std::string types +// Luigi Ballabio +// Apr 8, 2002 +// +// MzScheme implementation + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + /* Overloading check */ + + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string { + if (SCHEME_STRINGP($input)) + $1 = std::string(SCHEME_STR_VAL($input)); + else + SWIG_exception(SWIG_TypeError, "string expected"); + } + + %typemap(in) const string & (std::string temp) { + if (SCHEME_STRINGP($input)) { + temp = std::string(SCHEME_STR_VAL($input)); + $1 = &temp; + } else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + + %typemap(out) string { + $result = scheme_make_string($1.c_str()); + } + + %typemap(out) const string & { + $result = scheme_make_string($1->c_str()); + } + +} + + diff --git a/Lib/mzscheme/std_vector.i b/Lib/mzscheme/std_vector.i new file mode 100644 index 000000000..ad1f75de1 --- /dev/null +++ b/Lib/mzscheme/std_vector.i @@ -0,0 +1,460 @@ +// +// SWIG typemaps for std::vector +// Luigi Ballabio +// Apr 8, 2002 +// +// MzScheme implementation + +%include std_common.i +%include exception.i + +// containers + + +%exception std::vector::ref { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::set { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// MzScheme as much as possible, namely, to allow the user to pass and +// be returned MzScheme vectors or lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a MzScheme sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a MzScheme vector of T:s +// is returned which is most easily used in other MzScheme functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class vector { + %typemap(in) vector { + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + $1 = std::vector(size); + Scheme_Object** items = SCHEME_VEC_ELS($input); + for (unsigned int i=0; i(); + } else if (SCHEME_PAIRP($input)) { + Scheme_Object *head, *tail; + $1 = std::vector(); + tail = $input; + while (!SCHEME_NULLP(tail)) { + head = scheme_car(tail); + tail = scheme_cdr(tail); + $1.push_back(*((T*)SWIG_MustGetPtr(head, + $descriptor(T *), + $argnum))); + } + } else { + $1 = *(($&1_type) + SWIG_MustGetPtr($input,$&1_descriptor,$argnum)); + } + } + %typemap(in) const vector& (std::vector temp), + const vector* (std::vector temp) { + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + temp = std::vector(size); + $1 = &temp; + Scheme_Object** items = SCHEME_VEC_ELS($input); + for (unsigned int i=0; i(); + $1 = &temp; + } else if (SCHEME_PAIRP($input)) { + temp = std::vector(); + $1 = &temp; + Scheme_Object *head, *tail; + tail = $input; + while (!SCHEME_NULLP(tail)) { + head = scheme_car(tail); + tail = scheme_cdr(tail); + temp.push_back(*((T*) SWIG_MustGetPtr(head, + $descriptor(T *), + $argnum))); + } + } else { + $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum); + } + } + %typemap(out) vector { + $result = scheme_make_vector($1.size(),scheme_undefined); + Scheme_Object** els = SCHEME_VEC_ELS($result); + for (unsigned int i=0; i<$1.size(); i++) { + T* x = new T((($1_type &)$1)[i]); + els[i] = SWIG_MakePtr(x,$descriptor(T *)); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + Scheme_Object** items = SCHEME_VEC_ELS($input); + if (SWIG_GetPtr(items[0],(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } + } else if (SCHEME_NULLP($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (SCHEME_PAIRP($input)) { + /* check the first element only */ + T* x; + Scheme_Object *head = scheme_car($input); + if (SWIG_GetPtr(head,(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_GetPtr($input,(void **) &v, + $&1_descriptor) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + Scheme_Object** items = SCHEME_VEC_ELS($input); + if (SWIG_GetPtr(items[0],(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } + } else if (SCHEME_NULLP($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (SCHEME_PAIRP($input)) { + /* check the first element only */ + T* x; + Scheme_Object *head = scheme_car($input); + if (SWIG_GetPtr(head,(void**) &x, + $descriptor(T *)) != -1) + $1 = 1; + else + $1 = 0; + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_GetPtr($input,(void **) &v, + $1_descriptor) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector&); + %rename(length) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename("set!") set; + %rename("pop!") pop; + %rename("push!") push_back; + void push_back(const T& x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& ref(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + %typemap(in) vector { + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + $1 = std::vector(size); + Scheme_Object** items = SCHEME_VEC_ELS($input); + for (unsigned int i=0; i", + $argnum, argc, argv); + } + } else if (SCHEME_NULLP($input)) { + $1 = std::vector(); + } else if (SCHEME_PAIRP($input)) { + Scheme_Object *head, *tail; + $1 = std::vector(); + tail = $input; + while (!SCHEME_NULLP(tail)) { + head = scheme_car(tail); + tail = scheme_cdr(tail); + if (CHECK(head)) + $1.push_back((T)(CONVERT_FROM(head))); + else + scheme_wrong_type(FUNC_NAME, "vector<" #T ">", + $argnum, argc, argv); + } + } else { + $1 = *(($&1_type) + SWIG_MustGetPtr($input,$&1_descriptor,$argnum)); + } + } + %typemap(in) const vector& (std::vector temp), + const vector* (std::vector temp) { + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + temp = std::vector(size); + $1 = &temp; + Scheme_Object** items = SCHEME_VEC_ELS($input); + for (unsigned int i=0; i", + $argnum, argc, argv); + } + } else if (SCHEME_NULLP($input)) { + temp = std::vector(); + $1 = &temp; + } else if (SCHEME_PAIRP($input)) { + temp = std::vector(); + $1 = &temp; + Scheme_Object *head, *tail; + tail = $input; + while (!SCHEME_NULLP(tail)) { + head = scheme_car(tail); + tail = scheme_cdr(tail); + if (CHECK(head)) + temp.push_back((T)(CONVERT_FROM(head))); + else + scheme_wrong_type(FUNC_NAME, "vector<" #T ">", + $argnum, argc, argv); + } + } else { + $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum); + } + } + %typemap(out) vector { + $result = scheme_make_vector($1.size(),scheme_undefined); + Scheme_Object** els = SCHEME_VEC_ELS($result); + for (unsigned int i=0; i<$1.size(); i++) + els[i] = CONVERT_TO((($1_type &)$1)[i]); + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + Scheme_Object** items = SCHEME_VEC_ELS($input); + $1 = CHECK(items[0]) ? 1 : 0; + } + } else if (SCHEME_NULLP($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (SCHEME_PAIRP($input)) { + /* check the first element only */ + T* x; + Scheme_Object *head = scheme_car($input); + $1 = CHECK(head) ? 1 : 0; + } else { + /* wrapped vector? */ + std::vector* v; + $1 = (SWIG_GetPtr($input,(void **) &v, + $&1_descriptor) != -1) ? 1 : 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (SCHEME_VECTORP($input)) { + unsigned int size = SCHEME_VEC_SIZE($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + Scheme_Object** items = SCHEME_VEC_ELS($input); + $1 = CHECK(items[0]) ? 1 : 0; + } + } else if (SCHEME_NULLP($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (SCHEME_PAIRP($input)) { + /* check the first element only */ + T* x; + Scheme_Object *head = scheme_car($input); + $1 = CHECK(head) ? 1 : 0; + } else { + /* wrapped vector? */ + std::vector* v; + $1 = (SWIG_GetPtr($input,(void **) &v, + $1_descriptor) != -1) ? 1 : 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector&); + %rename(length) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename("set!") set; + %rename("pop!") pop; + %rename("push!") push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T ref(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i + Based on code written by Oleg Tolmatcev. -%{ -#define MAXVALUES 6 -%} + $Id$ +*/ -%typemap(mzscheme, argout) - int *M_OUTPUT, - unsigned int *M_OUTPUT, - short *M_OUTPUT, - unsigned short *M_OUTPUT +/* The MzScheme module handles all types uniformly via typemaps. Here + are the definitions. */ + +/* Pointers */ + +%typemap(in) SWIGTYPE * { + $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum); +} + +%typemap(in) void * { + $1 = SWIG_MustGetPtr($input, NULL, $argnum); +} + +%typemap(varin) SWIGTYPE * { + $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, 1); +} + +%typemap(varin) void * { + $1 = SWIG_MustGetPtr($input, NULL, 1); +} + +%typemap(out) SWIGTYPE * { + $result = SWIG_MakePtr ($1, $descriptor); +} + +%typemap(out) SWIGTYPE *DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); + $result = SWIG_MakePtr ($1, ty); +} + +%typemap(varout) SWIGTYPE * { + $result = SWIG_MakePtr ($1, $descriptor); +} + +/* C++ References */ + +#ifdef __cplusplus + +%typemap(in) SWIGTYPE &, const SWIGTYPE & { + $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum); + if ($1 == NULL) scheme_signal_error("swig-type-error (null reference)"); +} + +%typemap(out) SWIGTYPE &, const SWIGTYPE & { + $result = SWIG_MakePtr ($1, $descriptor); +} + +%typemap(out) SWIGTYPE &DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); + $result = SWIG_MakePtr ($1, ty); +} + +#endif + +%typemap(out) SWIGTYPE +#ifdef __cplusplus { - Scheme_Object *s; - s = scheme_make_integer(*$target); - m_output_helper(_values, s, &_lenv); -} - -%typemap(mzscheme, argout) - long *M_OUTPUT + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + $result = SWIG_MakePtr (resultptr, $&1_descriptor); +} +#else { - Scheme_Object *s; - s = scheme_make_integer_value(*$target); - m_output_helper(_values, s, &_lenv); + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + $result = SWIG_MakePtr(resultptr, $&1_descriptor); +} +#endif + +/* Arrays */ + +%typemap(in) SWIGTYPE[] { + $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum); +} + +%typemap(out) SWIGTYPE[] { + $result = SWIG_MakePtr ($1, $descriptor); +} + +/* Enums */ +%typemap(in) enum SWIGTYPE { + if (!SCHEME_INTP($input)) + scheme_wrong_type("$name", "integer", $argnum, argc, argv); + $1 = SCHEME_INT_VAL($input); +} + +%typemap(varin) enum SWIGTYPE { + if (!SCHEME_INTP($input)) + scheme_wrong_type("$name", "integer", 1, argc, argv); + $1 = ($1_type) SCHEME_INT_VAL($input); +} + +%typemap(out) enum SWIGTYPE "$result = scheme_make_integer_value($1);"; +%typemap(varout) enum SWIGTYPE "$result = scheme_make_integer_value($1);"; + + +/* Pass-by-value */ + +%typemap(in) SWIGTYPE($&1_ltype argp) { + argp = ($&1_ltype) SWIG_MustGetPtr($input, $&1_descriptor, $argnum); + $1 = *argp; +} + +%typemap(varin) SWIGTYPE { + $&1_ltype argp; + argp = ($&1_ltype) SWIG_MustGetPtr($input, $&1_descriptor, 1); + $1 = *argp; } -%typemap(mzscheme, argout) - unsigned long *M_OUTPUT +%typemap(out) SWIGTYPE +#ifdef __cplusplus { - Scheme_Object *s; - s = scheme_make_integer_value_from_unsigned(*$target); - m_output_helper(_values, s, &_lenv); -} - - -%typemap(mzscheme, argout) - char *M_OUTPUT, - unsigned char *M_OUTPUT + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + $result = SWIG_MakePtr (resultptr, $&1_descriptor); +} +#else { - Scheme_Object *s; - s = scheme_make_string_without_copying(*$target); - m_output_helper(_values, s, &_lenv); + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + $result = SWIG_MakePtr(resultptr, $&1_descriptor); } +#endif -%typemap(mzscheme, argout) -float *M_OUTPUT, -double *M_OUTPUT +%typemap(varout) SWIGTYPE +#ifdef __cplusplus { + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + $result = SWIG_MakePtr (resultptr, $&1_descriptor); +} +#else +{ + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + $result = SWIG_MakePtr(resultptr, $&1_descriptor); +} +#endif + +/* The SIMPLE_MAP macro below defines the whole set of typemaps needed + for simple types. */ + +%define SIMPLE_MAP(C_NAME, MZ_PREDICATE, MZ_TO_C, C_TO_MZ, MZ_NAME) +%typemap(in) C_NAME { + if (!MZ_PREDICATE($input)) + scheme_wrong_type("$name", #MZ_NAME, $argnum, argc, argv); + $1 = MZ_TO_C($input); +} +%typemap(varin) C_NAME { + if (!MZ_PREDICATE($input)) + scheme_wrong_type("$name", #MZ_NAME, 1, argc, argv); + $1 = MZ_TO_C($input); +} +%typemap(out) C_NAME { + $result = C_TO_MZ($1); +} +%typemap(varout) C_NAME { + $result = C_TO_MZ($1); +} +%typemap(in) C_NAME *INPUT (C_NAME temp) { + temp = (C_NAME) MZ_TO_C($input); + $1 = &temp; +} +%typemap(in,numinputs=0) C_NAME *OUTPUT (C_NAME temp) { + $1 = &temp; +} +%typemap(argout) C_NAME *OUTPUT { Scheme_Object *s; - s = scheme_make_double(*$target); - m_output_helper(_values, s, &_lenv); + s = C_TO_MZ(*$1); + SWIG_APPEND_VALUE(s); +} +%typemap(in) C_NAME *BOTH = C_NAME *INPUT; +%typemap(argout) C_NAME *BOTH = C_NAME *OUTPUT; +%typemap(in) C_NAME *INOUT = C_NAME *INPUT; +%typemap(argout) C_NAME *INOUT = C_NAME *OUTPUT; +%enddef + +SIMPLE_MAP(bool, SCHEME_BOOLP, SCHEME_TRUEP, + swig_make_boolean, boolean); +SIMPLE_MAP(char, SCHEME_CHARP, SCHEME_CHAR_VAL, + scheme_make_character, character); +SIMPLE_MAP(unsigned char, SCHEME_CHARP, SCHEME_CHAR_VAL, + scheme_make_character, character); +SIMPLE_MAP(int, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +SIMPLE_MAP(short, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +SIMPLE_MAP(long, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +SIMPLE_MAP(ptrdiff_t, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +SIMPLE_MAP(unsigned int, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +SIMPLE_MAP(unsigned short, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +SIMPLE_MAP(unsigned long, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +SIMPLE_MAP(size_t, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +SIMPLE_MAP(float, SCHEME_REALP, scheme_real_to_double, + scheme_make_double, real); +SIMPLE_MAP(double, SCHEME_REALP, scheme_real_to_double, + scheme_make_double, real); +SIMPLE_MAP(char *, SCHEME_STRINGP, SCHEME_STR_VAL, + scheme_make_string_without_copying, string); +SIMPLE_MAP(const char *, SCHEME_STRINGP, SCHEME_STR_VAL, + scheme_make_string_without_copying, string); + + +/* Const primitive references. Passed by value */ + +%define REF_MAP(C_NAME, MZ_PREDICATE, MZ_TO_C, C_TO_MZ, MZ_NAME) + %typemap(in) const C_NAME & (C_NAME temp) { + if (!MZ_PREDICATE($input)) + scheme_wrong_type("$name", #MZ_NAME, $argnum, argc, argv); + temp = MZ_TO_C($input); + $1 = &temp; + } + %typemap(out) const C_NAME & { + $result = C_TO_MZ(*$1); + } +%enddef + +REF_MAP(bool, SCHEME_BOOLP, SCHEME_TRUEP, + swig_make_boolean, boolean); +REF_MAP(char, SCHEME_CHARP, SCHEME_CHAR_VAL, + scheme_make_character, character); +REF_MAP(unsigned char, SCHEME_CHARP, SCHEME_CHAR_VAL, + scheme_make_character, character); +REF_MAP(int, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +REF_MAP(short, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +REF_MAP(long, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value, integer); +REF_MAP(unsigned int, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +REF_MAP(unsigned short, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +REF_MAP(unsigned long, SCHEME_INTP, SCHEME_INT_VAL, + scheme_make_integer_value_from_unsigned, integer); +REF_MAP(float, SCHEME_REALP, scheme_real_to_double, + scheme_make_double, real); +REF_MAP(double, SCHEME_REALP, scheme_real_to_double, + scheme_make_double, real); + +/* Void */ + +%typemap(out) void "$result = scheme_void;"; + +/* Pass through Scheme_Object * */ + +%typemap (in) Scheme_Object * "$1=$input;"; +%typemap (out) Scheme_Object * "$result=$1;"; + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +//%typemap(in) (char *STRING, int LENGTH) { +// int temp; +// $1 = ($1_ltype) gh_scm2newstr($input, &temp); +// $2 = ($2_ltype) temp; +//} + + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE +{ + $1 = (SCHEME_INTP($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_BOOL) bool &, const bool & +{ + $1 = (SCHEME_BOOLP($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = (SCHEME_REALP($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char { + $1 = (SCHEME_STRINGP($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = (SCHEME_STRINGP($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + if (SWIG_GetPtr($input, (void **) &ptr, $1_descriptor)) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + if (SWIG_GetPtr($input, (void **) &ptr, $&1_descriptor)) { + $1 = 0; + } else { + $1 = 1; + } } -%{ -void m_output_helper(Scheme_Object **target, Scheme_Object *s, int *_lenv) { - target[*_lenv] = s; - (*_lenv)++; +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + if (SWIG_GetPtr($input, (void **) &ptr, 0)) { + $1 = 0; + } else { + $1 = 1; + } } -%} -/* - ------------------------------------------------- - Check the type of the MzScheme arguments and - convert function arguments from a MzScheme to a C - representation. - ------------------------------------------------- - */ -%typemap(mzscheme, in) char { - if(!SCHEME_CHARP($source)) - scheme_wrong_type("$name", "character", $argnum, argc, argv); - $target = SCHEME_CHAR_VAL($source); -} - -%typemap(mzscheme, in) unsigned char { - if(!SCHEME_CHARP($source)) - scheme_wrong_type("$name", "character", $argnum, argc, argv); - $target = SCHEME_CHAR_VAL($source); -} - -%typemap(mzscheme, in) char * { - if(!SCHEME_STRINGP($source)) - scheme_wrong_type("$name", "string", $argnum, argc, argv); - $target = SCHEME_STR_VAL($source); -} - -%typemap(mzscheme, in) char [ANY] { - if(!SCHEME_STRINGP($source)) - scheme_wrong_type("$name", "string", $argnum, argc, argv); - $target = SCHEME_STR_VAL($source); -} - -%typemap(mzscheme, in) int { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} - -%typemap(mzscheme, in) long { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &$target); -} - -%typemap(mzscheme, in) short { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} - -%typemap(mzscheme, in) unsigned int { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} - -%typemap(mzscheme, in) unsigned long { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_unsigned_int_val($source, &$target); -} - -%typemap(mzscheme, in) unsigned short { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} -/* -%typemap(mzscheme, in) long long { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &$target); -} -*/ -%typemap(mzscheme, in) float { - if(!SCHEME_DBLP($source)) - scheme_wrong_type("$name", "double", $argnum, argc, argv); - $target = SCHEME_DBL_VAL($source); -} - -%typemap(mzscheme, in) double { - if(SCHEME_DBLP($source)) - $target = SCHEME_DBL_VAL($source); - else if(SCHEME_REALP($source)) - $target = scheme_real_to_double($source); - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -/* -%typemap(mzscheme, in) long double { - if(SCHEME_DBLP($source)) - $target = SCHEME_DBL_VAL($source); - else if(SCHEME_REALP($source)) - $target = scheme_real_to_double($source); - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -*/ - -/* - ------------------------------------ - in typemaps for pass-by-reference - ------------------------------------ - */ - -%typemap(mzscheme, in) unsigned char *(unsigned char temp) { - if(!SCHEME_CHARP($source)) - scheme_wrong_type("$name", "character", $argnum, argc, argv); - temp = SCHEME_STR_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, in) int *(int temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (int)SCHEME_INT_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, in) long *(long temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &temp); - $target = &temp; - -} - -%typemap(mzscheme, in) short *(short temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (short)SCHEME_INT_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, in) unsigned int *(unsigned temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (unsigned)SCHEME_INT_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, in) unsigned long *(unsigned long temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_unsigned_int_val($source, &temp); - $target = &temp; -} - -%typemap(mzscheme, in) unsigned short *(unsigned short temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (unsigned short)SCHEME_INT_VAL($source); - $target = &temp; - -} -/* -%typemap(mzscheme, in) long long *(long long temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &temp); - $target = &temp; -} -*/ -%typemap(mzscheme, in) float *(float temp) { - if(!SCHEME_DBLP($source)) - scheme_wrong_type("$name", "double", $argnum, argc, argv); - temp = (float)SCHEME_DBL_VAL($source); - $target = &temp; - -} - -%typemap(mzscheme, in) double *(double temp) { - if(SCHEME_DBLP($source)) { - temp = (double)SCHEME_DBL_VAL($source); - $target = &temp; - } - else if(SCHEME_REALP($source)) { - temp = (double)scheme_real_to_double($source); - $target = &temp; - } - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -/* -%typemap(mzscheme, in) long double *(long double temp) { - if(SCHEME_DBLP($source)) { - temp = (long double)SCHEME_DBL_VAL($source); - $target = &temp; - } - else if(SCHEME_REALP($source)) { - temp = (long double)scheme_real_to_double($source); - $target = &temp; - } - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -*/ - -/* - ------------------------------------ - convert return type from C to Scheme - ------------------------------------ - */ - -%typemap(mzscheme, out) char { - $target = scheme_make_character($source); -} - -%typemap(mzscheme, out) unsigned char { - $target = scheme_make_character($source); -} - -%typemap(mzscheme, out) char * { - $target = scheme_make_string_without_copying($source); -} - -%typemap(mzscheme, out) char [ANY] { - $target = scheme_make_string_without_copying($source); -} - -%typemap(mzscheme, out) int { - $target = scheme_make_integer_value($source); -} - -%typemap(mzscheme, out) long { - $target = scheme_make_integer_value($source); -} - -%typemap(mzscheme, out) short { - $target = scheme_make_integer_value($source); -} -/* -%typemap(mzscheme, out) long long { - $target = scheme_make_integer_value($source); -} -*/ -%typemap(mzscheme, out) unsigned int { - $target = scheme_make_integer_value_from_unsigned($source); -} - -%typemap(mzscheme, out) unsigned long { - $target = scheme_make_integer_value_from_unsigned($source); -} - -%typemap(mzscheme, out) unsigned short { - $target = scheme_make_integer_value_from_unsigned($source); -} - -%typemap(mzscheme, out) float { - $target = scheme_make_double($source); -} - -%typemap(mzscheme, out) double { - $target = scheme_make_double($source); -} -/* -%typemap(mzscheme, out) long double { - $target = scheme_make_double($source); -} -*/ - -/* - ----------------------------------- - convert pointers from C to MzScheme - ----------------------------------- - */ - -%typemap(mzscheme, out) int * { - $target = scheme_make_integer_value(*$source); -} - -%typemap(mzscheme, out) long * { - $target = scheme_make_integer_value(*$source); -} - -%typemap(mzscheme, out) short * { - $target = scheme_make_integer_value(*$source); -} - -/* -%typemap(mzscheme, out) long long * { - $target = scheme_make_integer_value(*$source); -} -*/ -%typemap(mzscheme, out) unsigned int * { - $target = scheme_make_integer_value_from_unsigned(*$source); -} - -%typemap(mzscheme, out) unsigned long * { - $target = scheme_make_integer_value_from_unsigned(*$source); -} - -%typemap(mzscheme, out) unsigned short * { - $target = scheme_make_integer_value_from_unsigned(*$source); -} - -%typemap(mzscheme, out) float * { - $target = scheme_make_double(*$source); -} - -%typemap(mzscheme, out) double * { - $target = scheme_make_double(*$source); -} -/* -%typemap(mzscheme, out) long double * { - $target = scheme_make_double(*$source); -} -*/ - -/* - ------------------------------------------------------------ - Typemaps for accessing a global C variable from MzScheme - ------------------------------------------------------------ - */ -%typemap(mzscheme, varin) char { - if(!SCHEME_CHARP($source)) - scheme_wrong_type("$name", "character", $argnum, argc, argv); - $target = SCHEME_CHAR_VAL($source); -} - -%typemap(mzscheme, varin) unsigned char { - if(!SCHEME_CHARP($source)) - scheme_wrong_type("$name", "character", $argnum, argc, argv); - $target = SCHEME_CHAR_VAL($source); -} - -%typemap(mzscheme, varin) char * { - if(!SCHEME_STRINGP($source)) - scheme_wrong_type("$name", "string", $argnum, argc, argv); - $target = SCHEME_STR_VAL($source); -} - -%typemap(mzscheme, varin) char [ANY] { - if(!SCHEME_STRINGP($source)) - scheme_wrong_type("$name", "string", $argnum, argc, argv); - $target = SCHEME_STR_VAL($source); -} - -%typemap(mzscheme, varin) int { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} - -%typemap(mzscheme, varin) long { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &$target); -} - -%typemap(mzscheme, varin) short { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} - -%typemap(mzscheme, varin) unsigned int { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} - -%typemap(mzscheme, varin) unsigned long { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_unsigned_int_val($source, &$target); -} - -%typemap(mzscheme, varin) unsigned short { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - $target = SCHEME_INT_VAL($source); -} -/* -%typemap(mzscheme, varin) long long { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &$target); -} -*/ -%typemap(mzscheme, varin) float { - if(!SCHEME_DBLP($source)) - scheme_wrong_type("$name", "double", $argnum, argc, argv); - $target = SCHEME_DBL_VAL($source); -} - -%typemap(mzscheme, varin) double { - if(SCHEME_DBLP($source)) - $target = SCHEME_DBL_VAL($source); - else if(SCHEME_REALP($source)) - $target = scheme_real_to_double($source); - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -/* -%typemap(mzscheme, varin) long double { - if(SCHEME_DBLP($source)) - $target = SCHEME_DBL_VAL($source); - else if(SCHEME_REALP($source)) - $target = scheme_real_to_double($source); - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -*/ - -/* - ------------------------------------ - global pointer variable - ------------------------------------ - */ - -%typemap(mzscheme, varin) unsigned char *(unsigned char temp) { - if(!SCHEME_CHARP($source)) - scheme_wrong_type("$name", "character", $argnum, argc, argv); - temp = SCHEME_STR_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, varin) int *(int temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (int)SCHEME_INT_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, varin) long *(long temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &temp); - $target = &temp; - -} - -%typemap(mzscheme, varin) short *(short temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (short)SCHEME_INT_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, varin) unsigned int *(unsigned temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (unsigned)SCHEME_INT_VAL($source); - $target = &temp; -} - -%typemap(mzscheme, varin) unsigned long *(unsigned long temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_unsigned_int_val($source, &temp); - $target = &temp; -} - -%typemap(mzscheme, varin) unsigned short *(unsigned short temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - temp = (unsigned short)SCHEME_INT_VAL($source); - $target = &temp; - -} -/* -%typemap(mzscheme, varin) long long *(long long temp) { - if(!SCHEME_INTP($source)) - scheme_wrong_type("$name", "integer", $argnum, argc, argv); - scheme_get_int_val($source, &temp); - $target = &temp; -} -*/ -%typemap(mzscheme, varin) float *(float temp) { - if(!SCHEME_DBLP($source)) - scheme_wrong_type("$name", "double", $argnum, argc, argv); - temp = (float)SCHEME_DBL_VAL($source); - $target = &temp; - -} - -%typemap(mzscheme, varin) double *(double temp) { - if(SCHEME_DBLP($source)) { - temp = (double)SCHEME_DBL_VAL($source); - $target = &temp; - } - else if(SCHEME_REALP($source)) { - temp = (double)scheme_real_to_double($source); - $target = &temp; - } - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -/* -%typemap(mzscheme, varin) long double *(long double temp) { - if(SCHEME_DBLP($source)) { - temp = (long double)SCHEME_DBL_VAL($source); - $target = &temp; - } - else if(SCHEME_REALP($source)) { - temp = (long double)scheme_real_to_double($source); - $target = &temp; - } - else scheme_wrong_type("$name", "real", $argnum, argc, argv); -} -*/ - - -/* - ----------------------------------- - convert a variable from C to Scheme - ----------------------------------- - */ - -%typemap(mzscheme, varout) char { - $target = scheme_make_character($source); -} - -%typemap(mzscheme, varout) unsigned char { - $target = scheme_make_character($source); -} - -%typemap(mzscheme, varout) char * { - $target = scheme_make_string_without_copying($source); -} - -%typemap(mzscheme, varout) char [ANY] { - $target = scheme_make_string_without_copying($source); -} - -%typemap(mzscheme, varout) int { - $target = scheme_make_integer_value($source); -} - -%typemap(mzscheme, varout) long { - $target = scheme_make_integer_value($source); -} - -%typemap(mzscheme, varout) short { - $target = scheme_make_integer_value($source); -} -/* -%typemap(mzscheme, varout) long long { - $target = scheme_make_integer_value($source); -} -*/ -%typemap(mzscheme, varout) unsigned int { - $target = scheme_make_integer_value_from_unsigned($source); -} - -%typemap(mzscheme, varout) unsigned long { - $target = scheme_make_integer_value_from_unsigned($source); -} - -%typemap(mzscheme, varout) unsigned short { - $target = scheme_make_integer_value_from_unsigned($source); -} - -%typemap(mzscheme, varout) float { - $target = scheme_make_double($source); -} - -%typemap(mzscheme, varout) double { - $target = scheme_make_double($source); -} -/* -%typemap(mzscheme, varout) long double { - $target = scheme_make_double($source); -} -*/ - -/* - ----------------------------------- - convert a pointer variable from C to MzScheme - ----------------------------------- - */ - -%typemap(mzscheme, varout) int * { - $target = scheme_make_integer_value(*$source); -} - -%typemap(mzscheme, varout) long * { - $target = scheme_make_integer_value(*$source); -} - -%typemap(mzscheme, varout) short * { - $target = scheme_make_integer_value(*$source); -} - -/* -%typemap(mzscheme, varout) long long * { - $target = scheme_make_integer_value(*$source); -} -*/ -%typemap(mzscheme, varout) unsigned int * { - $target = scheme_make_integer_value_from_unsigned(*$source); -} - -%typemap(mzscheme, varout) unsigned long * { - $target = scheme_make_integer_value_from_unsigned(*$source); -} - -%typemap(mzscheme, varout) unsigned short * { - $target = scheme_make_integer_value_from_unsigned(*$source); -} - -%typemap(mzscheme, varout) float * { - $target = scheme_make_double(*$source); -} - -%typemap(mzscheme, varout) double * { - $target = scheme_make_double(*$source); -} -/* -%typemap(mzscheme, varout) long double * { - $target = scheme_make_double(*$source); -} -*/ diff --git a/Lib/objc.i b/Lib/objc.i deleted file mode 100644 index 2655fb896..000000000 --- a/Lib/objc.i +++ /dev/null @@ -1,56 +0,0 @@ -// SWIG Objective-C configuration file -// Dave Beazley -// Copyright (C) 1997 - -// This file provides support to Objective-C parsing and -// should be included with just about any Objective-C module - -// Base Object class - -@interface Object { } - --(char *) name; // Get object name - -@end - -typedef Object *id; // Make 'id' behave like any other "Object" - -// Typemaps to make *id work like kind of like a void pointer - -%typemap(python,in) id { - char *temp; - if (!PyString_Check($source)) { - PyErr_SetString(PyExc_TypeError,"Expecting an 'id' in argument $argnum of $name"); - return NULL; - } - temp = PyString_AsString($source); - if (SWIG_GetPtr(temp, (void **) &$target, 0)) { - PyErr_SetString(PyExc_TypeError,"Expecting an 'id' in argument $argnum of $name"); - return NULL; - } -} - -%typemap(tcl,in) id { - if (SWIG_GetPtr($source,(void **) &$target, 0)) { - Tcl_SetResult(interp,"Expecting an 'id' in argument $argnum of $name",TCL_STATIC); - return TCL_ERROR; - } -} - -%typemap(tcl8,in) id { - if (SWIG_GetPointerObj(interp, $source, (void **) &$target, 0)) { - Tcl_SetStringObj(result_obj, "Expecting an 'id' in argument $argnum of $name"); - } -} - -%typemap(perl5,in) id { - if (SWIG_GetPtr($source, (void **) &$target, 0)) { - croak("Expecting an 'id' in argument $argnum of $name"); - } -} - - - - - - diff --git a/Lib/ocaml/carray.i b/Lib/ocaml/carray.i new file mode 100644 index 000000000..435d21c37 --- /dev/null +++ b/Lib/ocaml/carray.i @@ -0,0 +1,36 @@ +template < class T > class SWIG_OCAML_ARRAY_WRAPPER { +public: + SWIG_OCAML_ARRAY_WRAPPER( T *t ) : t(t) { } + SWIG_OCAML_ARRAY_WRAPPER( T &t ) : t(&t) { } + SWIG_OCAML_ARRAY_WRAPPER( T t[] ) : t(&t[0]) { } + T &operator[]( int n ) { return t[n]; } + SWIG_OCAML_ARRAY_WRAPPER offset( int elts ) { + return SWIG_OCAML_ARRAY_WRAPPER( t + elts ); + } + T *operator & () { return t; } + void own() { owned = true; } + void disown() { owned = false; } + ~SWIG_OCAML_ARRAY_WRAPPER() { + if( owned ) delete t; + } + +private: + T *t; + int owned; +}; + +%typemap(ocaml,out) SWIGTYPE [ANY] { + $result = new SWIG_OCAML_ARRAY_WRAPPER($1); +} + +%typemap(ocaml,varout) SWIGTYPE [ANY] { + $result = new SWIG_OCAML_ARRAY_WRAPPER($1); +} + +%typemap(ocaml,in) SWIGTYPE [ANY] { + $1 = (SWIG_OCAML_ARRAY_WRAPPER<$ltype> *)$input; +} + +%typemap(ocaml,varin) SWIGTYPE [ANY] { + $1 = (SWIG_OCAML_ARRAY_WRAPPER<$ltype> *)$input; +} diff --git a/Lib/ocaml/cstring.i b/Lib/ocaml/cstring.i new file mode 100644 index 000000000..07eb3d6ef --- /dev/null +++ b/Lib/ocaml/cstring.i @@ -0,0 +1,274 @@ +/* -*- C++ -*- + * cstring.i + * $Header$ + * + * Author(s): Art Yerkes + * Modified from David Beazley (beazley@cs.uchicago.edu) + * + * This file provides typemaps and macros for dealing with various forms + * of C character string handling. The primary use of this module + * is in returning character data that has been allocated or changed in + * some way. + */ + +%include "fragments.i" + +/* %cstring_input_binary(TYPEMAP, SIZE) + * + * Macro makes a function accept binary string data along with + * a size. + */ + +%define %cstring_input_binary(TYPEMAP, SIZE) +%apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; +%enddef + +/* + * %cstring_bounded_output(TYPEMAP, MAX) + * + * This macro is used to return a NULL-terminated output string of + * some maximum length. For example: + * + * %cstring_bounded_output(char *outx, 512); + * void foo(char *outx) { + * sprintf(outx,"blah blah\n"); + * } + * + */ + +%define %cstring_bounded_output(TYPEMAP,MAX) +%typemap(ignore) TYPEMAP(char temp[MAX+1]) { + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + $1[MAX] = 0; + $result = caml_list_append($result,caml_val_string(str)); +} +%enddef + +/* + * %cstring_chunk_output(TYPEMAP, SIZE) + * + * This macro is used to return a chunk of binary string data. + * Embedded NULLs are okay. For example: + * + * %cstring_chunk_output(char *outx, 512); + * void foo(char *outx) { + * memmove(outx, somedata, 512); + * } + * + */ + +%define %cstring_chunk_output(TYPEMAP,SIZE) +%typemap(ignore) TYPEMAP(char temp[SIZE]) { + $1 = ($1_ltype) temp; +} +%typemap(argout) TYPEMAP { + $result = caml_list_append($result,caml_val_string_len($1,SIZE)); +} +%enddef + +/* + * %cstring_bounded_mutable(TYPEMAP, SIZE) + * + * This macro is used to wrap a string that's going to mutate. + * + * %cstring_bounded_mutable(char *in, 512); + * void foo(in *x) { + * while (*x) { + * *x = toupper(*x); + * x++; + * } + * } + * + */ + + +%define %cstring_bounded_mutable(TYPEMAP,MAX) +%typemap(in) TYPEMAP(char temp[MAX+1]) { + char *t = (char *)caml_ptr_val($input); + strncpy(temp,t,MAX); + $1 = ($1_ltype) temp; +} +%typemap(argout) TYPEMAP { + $result = caml_list_append($result,caml_val_string_len($1,MAX)); +} +%enddef + +/* + * %cstring_mutable(TYPEMAP [, expansion]) + * + * This macro is used to wrap a string that will mutate in place. + * It may change size up to a user-defined expansion. + * + * %cstring_mutable(char *in); + * void foo(in *x) { + * while (*x) { + * *x = toupper(*x); + * x++; + * } + * } + * + */ + +%define %cstring_mutable(TYPEMAP,...) +%typemap(in) TYPEMAP { + char *t = String_val($input); + int n = string_length($input); + $1 = ($1_ltype) t; +#if #__VA_ARGS__ == "" +#if __cplusplus + $1 = ($1_ltype) new char[n+1]; +#else + $1 = ($1_ltype) malloc(n+1); +#endif +#else +#if __cplusplus + $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; +#else + $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); +#endif +#endif + memmove($1,t,n); + $1[n] = 0; +} + +%typemap(argout) TYPEMAP { + $result = caml_list_append($result,caml_val_string($1)); +#if __cplusplus + delete[] $1; +#else + free($1); +#endif +} +%enddef + +/* + * %cstring_output_maxsize(TYPEMAP, SIZE) + * + * This macro returns data in a string of some user-defined size. + * + * %cstring_output_maxsize(char *outx, int max) { + * void foo(char *outx, int max) { + * sprintf(outx,"blah blah\n"); + * } + */ + +%define %cstring_output_maxsize(TYPEMAP, SIZE) +%typemap(in) (TYPEMAP, SIZE) { + $2 = caml_val_long($input); +#ifdef __cpluscplus + $1 = ($1_ltype) new char[$2+1]; +#else + $1 = ($1_ltype) malloc($2+1); +#endif +} +%typemap(argout) (TYPEMAP,SIZE) { + $result = caml_list_append($result,caml_val_string($1)); +#ifdef __cplusplus + delete [] $1; +#else + free($1); +#endif +} +%enddef + +/* + * %cstring_output_withsize(TYPEMAP, SIZE) + * + * This macro is used to return character data along with a size + * parameter. + * + * %cstring_output_maxsize(char *outx, int *max) { + * void foo(char *outx, int *max) { + * sprintf(outx,"blah blah\n"); + * *max = strlen(outx); + * } + */ + +%define %cstring_output_withsize(TYPEMAP, SIZE) +%typemap(in) (TYPEMAP, SIZE) { + int n = caml_val_long($input); +#ifdef __cpluscplus + $1 = ($1_ltype) new char[n+1]; + $2 = ($2_ltype) new $*1_ltype; +#else + $1 = ($1_ltype) malloc(n+1); + $2 = ($2_ltype) malloc(sizeof($*1_ltype)); +#endif + *$2 = n; +} +%typemap(argout) (TYPEMAP,SIZE) { + $result = caml_list_append($result,caml_val_string_len($1,$2)); +#ifdef __cplusplus + delete [] $1; + delete $2; +#else + free($1); + free($2); +#endif +} +%enddef + +/* + * %cstring_output_allocate(TYPEMAP, RELEASE) + * + * This macro is used to return character data that was + * allocated with new or malloc. + * + * %cstring_output_allocated(char **outx, free($1)); + * void foo(char **outx) { + * *outx = (char *) malloc(512); + * sprintf(outx,"blah blah\n"); + * } + */ + +%define %cstring_output_allocate(TYPEMAP, RELEASE) +%typemap(ignore) TYPEMAP($*1_ltype temp = 0) { + $1 = &temp; +} + +%typemap(argout) TYPEMAP { + if (*$1) { + $result = caml_list_append($result,caml_val_string($1)); + RELEASE; + } else { + $result = caml_list_append($result,caml_val_ptr($1)); + } +} +%enddef + +/* + * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) + * + * This macro is used to return character data that was + * allocated with new or malloc. + * + * %cstring_output_allocated(char **outx, int *sz, free($1)); + * void foo(char **outx, int *sz) { + * *outx = (char *) malloc(512); + * sprintf(outx,"blah blah\n"); + * *sz = strlen(outx); + * } + */ + +%define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) +%typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { + $1 = &temp; + $2 = &tempn; +} + +%typemap(argout)(TYPEMAP,SIZE) { + if (*$1) { + $result = caml_list_append($result,caml_val_string_len($1,$2)); + RELEASE; + } else + $result = caml_list_append($result,caml_val_ptr($1)); +} +%enddef + + + + + + diff --git a/Lib/ocaml/extra-install.list b/Lib/ocaml/extra-install.list new file mode 100644 index 000000000..faa456745 --- /dev/null +++ b/Lib/ocaml/extra-install.list @@ -0,0 +1,2 @@ +# see top-level Makefile.in +libswigocaml.h diff --git a/Lib/ocaml/libswigocaml.h b/Lib/ocaml/libswigocaml.h new file mode 100644 index 000000000..e752540fe --- /dev/null +++ b/Lib/ocaml/libswigocaml.h @@ -0,0 +1,20 @@ +/* Ocaml runtime support */ + +#ifdef __cplusplus +extern "C" { +#endif + + typedef int oc_bool; + extern void *nullptr; + + extern oc_bool isnull( void *v ); + + extern void *get_char_ptr( char *str ); + extern void *make_ptr_array( int size ); + extern void *get_ptr( void *arrayptr, int elt ); + extern void set_ptr( void *arrayptr, int elt, void *elt_v ); + extern void *offset_ptr( void *ptr, int n ); + +#ifdef __cplusplus +}; +#endif diff --git a/Lib/ocaml/libswigocaml.swg b/Lib/ocaml/libswigocaml.swg new file mode 100644 index 000000000..15d54df1a --- /dev/null +++ b/Lib/ocaml/libswigocaml.swg @@ -0,0 +1,18 @@ +#include +#include +#include "libswigocaml.h" +/* Ocaml runtime support ... not much here yet */ + +void *nullptr = 0; +oc_bool isnull( void *v ) { return v ? 0 : 1; } +void *get_char_ptr( char *str ) { return str; } +void *make_ptr_array( int size ) { + return (void *)malloc( sizeof( void * ) * size ); +} +void *get_ptr( void *arrayptr, int elt ) { + return ((void **)arrayptr)[elt]; +} +void set_ptr( void *arrayptr, int elt, void *elt_v ) { + ((void **)arrayptr)[elt] = elt_v; +} +void *offset_ptr( void *p, int n ) { return ((char *)p) + n; } diff --git a/Lib/ocaml/mlheading.swg b/Lib/ocaml/mlheading.swg new file mode 100644 index 000000000..b68fbf3f3 --- /dev/null +++ b/Lib/ocaml/mlheading.swg @@ -0,0 +1,54 @@ +open Int32 +open Int64 + +type c_obj = + C_void + | C_bool of bool + | C_char of char + | C_uchar of char + | C_short of int + | C_ushort of int + | C_int of int + | C_uint of int32 + | C_int32 of int32 + | C_int64 of int64 + | C_float of float + | C_double of float + | C_ptr of int64 * int64 + | C_array of c_obj array + | C_list of c_obj list + | C_obj of (string -> c_obj -> c_obj) + | C_string of string + | C_enum of c_enum_tag +exception BadArgs of string +exception BadMethodName of c_obj * string * string +exception NotObject of c_obj +exception NotEnumType of c_obj +exception LabelNotFromThisEnum of c_obj + +let invoke obj = match obj with C_obj o -> o | _ -> raise (NotObject obj) +let fnhelper fin f arg = + let args = match arg with C_list l -> l | C_void -> [] | _ -> [ arg ] in + match f args with + [] -> C_void + | [ x ] -> (if fin then Gc.finalise + (fun x -> ignore ((invoke x) "~" C_void)) x) ; x + | lst -> C_list lst +let rec get_int x = + match x with + C_char c + | C_uchar c -> (int_of_char c) + | C_short s + | C_ushort s + | C_int s -> s + | C_uint u + | C_int32 u -> (Int32.to_int u) + | C_int64 u -> (Int64.to_int u) + | C_float f -> (int_of_float f) + | C_double d -> (int_of_float d) + | C_ptr (p,q) -> (Int64.to_int p) + | C_obj o -> (try (get_int (o "int" C_void)) + with _ -> (get_int (o "&" C_void))) + | _ -> raise (Failure "Can't convert to int") +let addr_of obj = (invoke obj) "&" C_void +let _ = Callback.register "caml_obj_ptr" addr_of diff --git a/Lib/ocaml/mliheading.swg b/Lib/ocaml/mliheading.swg new file mode 100644 index 000000000..3c525f985 --- /dev/null +++ b/Lib/ocaml/mliheading.swg @@ -0,0 +1,27 @@ +type c_obj = + C_void + | C_bool of bool + | C_char of char + | C_uchar of char + | C_short of int + | C_ushort of int + | C_int of int + | C_uint of int32 + | C_int32 of int32 + | C_int64 of int64 + | C_float of float + | C_double of float + | C_ptr of int64 * int64 + | C_array of c_obj array + | C_list of c_obj list + | C_obj of (string -> c_obj -> c_obj) + | C_string of string + | C_enum of c_enum_tag +exception BadArgs of string +exception BadMethodName of c_obj * string * string +exception NotObject of c_obj +exception NotEnumType of c_obj +exception LabelNotFromThisEnum of c_obj + +val invoke : c_obj -> (string -> c_obj -> c_obj) +val get_int : c_obj -> int diff --git a/Lib/ocaml/ocaml.i b/Lib/ocaml/ocaml.i new file mode 100644 index 000000000..3d543dc8b --- /dev/null +++ b/Lib/ocaml/ocaml.i @@ -0,0 +1,32 @@ +/* SWIG Configuration File for Ocaml. -*-c-*- + Modified from mzscheme.i + This file is parsed by SWIG before reading any other interface + file. */ + +/* Insert ML/MLI Common stuff */ +%insert(mli) "mliheading.swg" +%insert(ml) "mlheading.swg" + +/* Insert common stuff */ +%insert(runtime) "common.swg" + +/* Include headers */ +%insert(runtime) "ocamldec.swg" + +/*#ifndef SWIG_NOINCLUDE*/ +%insert(runtime) "ocaml.swg" +/*#endif*/ + +/* Definitions */ +#define SWIG_malloc(size) swig_malloc(size, FUNC_NAME) +#define SWIG_free(mem) free(mem) + +/* Guile compatibility kludges */ +#define SCM_VALIDATE_VECTOR(argnum, value) (void)0 +#define SCM_VALIDATE_LIST(argnum, value) (void)0 + +/* Read in standard typemaps. */ +%include "swig.swg" +%include "typemaps.i" +%include "typecheck.i" +%include "exception.i" diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg new file mode 100644 index 000000000..b91d14ca4 --- /dev/null +++ b/Lib/ocaml/ocaml.swg @@ -0,0 +1,533 @@ +/* -*-c-*- */ + +/* SWIG pointer structure */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define C_bool 0 +#define C_char 1 +#define C_uchar 2 +#define C_short 3 +#define C_ushort 4 +#define C_int 5 +#define C_uint 6 +#define C_int32 7 +#define C_int64 8 +#define C_float 9 +#define C_double 10 +#define C_ptr 11 +#define C_array 12 +#define C_list 13 +#define C_obj 14 +#define C_string 15 +#define C_enum 16 + +struct custom_block_contents { + swig_type_info *type; + void *object; + char *delete_fn; +}; + +static void generic_delete_fn( value v ) { + CAMLparam1(v); + CAMLlocal1(x); + struct custom_block_contents *new_proxy; + value *deleter = NULL; + + new_proxy = (struct custom_block_contents *)(Data_custom_val(v)); + if( new_proxy->delete_fn ) + deleter = caml_named_value(new_proxy->delete_fn); + if( *deleter ) + x = callback( *deleter, v ); + free( new_proxy->delete_fn ); + CAMLreturn0; +} + +static struct custom_operations makeptr_custom_ops = { + "SWIG-Wrapped Object", + generic_delete_fn, + custom_compare_default, + custom_hash_default, + custom_serialize_default, + custom_deserialize_default +}; + +static value _wrap_delete_void( value v ) { + CAMLparam0(); + CAMLreturn(Val_unit); +} + +/* Cast a pointer if possible; returns 1 if successful */ + + static int + SWIG_Cast (void *source, swig_type_info *source_type, + void **ptr, swig_type_info *dest_type) + { + if (dest_type != source_type) { + /* We have a type mismatch. Will have to look through our type + mapping table to figure out whether or not we can accept this + datatype. */ + if( !dest_type || !source_type ) { + *ptr = source; + return 0; + } else { + swig_type_info *tc = + SWIG_TypeCheck( (char *)source_type->name, dest_type ); + if( tc ) { + *ptr = SWIG_TypeCast( tc, source ); + return 0; + } else + return -1; + } + } else { + *ptr = source; + return 0; + } + } + +/* Return 0 if successful. */ + SWIGSTATIC int + SWIG_GetPtr(void *inptr, void **outptr, + swig_type_info *intype, swig_type_info *outtype) { + CAMLparam0(); + if (intype) { + return !SWIG_Cast(inptr, intype, + outptr, outtype); + } else { + *outptr = inptr; + return 0; + } + } + + static void caml_print_list( value v ); + + static void caml_print_val( value v ) { + switch( Tag_val(v) ) { + case C_bool: + if( Bool_val(Field(v,0)) ) fprintf( stderr, "true " ); + else fprintf( stderr, "false " ); + break; + case C_char: + case C_uchar: + fprintf( stderr, "'%c' (\\%03d) ", + (Int_val(Field(v,0)) >= ' ' && + Int_val(Field(v,0)) < 127) ? Int_val(Field(v,0)) : '.', + Int_val(Field(v,0)) ); + break; + case C_short: + case C_ushort: + case C_int: + fprintf( stderr, "%d ", (int)caml_long_val(v) ); + break; + + case C_uint: + case C_int32: + fprintf( stderr, "%ud ", (unsigned int)caml_long_val(v) ); + break; + case C_int64: + fprintf( stderr, "%ld ", caml_long_val(v) ); + break; + case C_float: + case C_double: + fprintf( stderr, "%f ", caml_double_val(v) ); + break; + + case C_ptr: + fprintf( stderr, "PTR(%p) ", caml_ptr_val(v,0) ); + break; + case C_array: + { + unsigned int i; + for( i = 0; i < Wosize_val( Field(v,0) ); i++ ) + caml_print_val( Field(Field(v,0),i) ); + } + break; + case C_list: + caml_print_list( Field(v,0) ); + break; + case C_obj: + fprintf( stderr, "OBJ(%p) ", (void *)Field(v,0) ); + break; + case C_string: + fprintf( stderr, "'%s' ", (char *)caml_ptr_val(v,0) ); + break; + } + } + + static void caml_print_list( value v ) { + CAMLparam1(v); + while( v && Is_block(v) ) { + fprintf( stderr, "[ " ); + caml_print_val( Field(v,0) ); + fprintf( stderr, "]\n" ); + v = Field(v,1); + } + } + +static value caml_list_nth( value lst, int n ) { + CAMLparam1(lst); + int i = 0; + while( i < n && lst && Is_block(lst) ) { + i++; lst = Field(lst,1); + } + if( lst == Val_unit ) CAMLreturn(Val_unit); + else CAMLreturn(Field(lst,0)); +} + +static value caml_list_append( value lst, value elt ) { + CAMLparam2(lst,elt); + CAMLlocal3(v,vt,lh); + lh = Val_unit; + v = Val_unit; + + /* Appending C_void should have no effect */ + if( !Is_block(elt) ) return lst; + + while( lst && Is_block(lst) ) { + if( v && v != Val_unit ) { + vt = alloc_tuple(2); + Store_field(v,1,vt); + v = vt; + } else { + v = lh = alloc_tuple(2); + } + Store_field(v,0,Field(lst,0)); + lst = Field(lst,1); + } + + if( v && Is_block(v) ) { + vt = alloc_tuple(2); + Store_field(v,1,vt); + v = vt; + } else { + v = lh = alloc_tuple(2); + } + Store_field(v,0,elt); + Store_field(v,1,Val_unit); + + CAMLreturn(lh); +} + +static int caml_list_length( value lst ) { + CAMLparam1(lst); + int i = 0; + while( lst && Is_block(lst) ) { i++; lst = Field(lst,1); } + CAMLreturn(i); +} + +#ifdef __cplusplus + namespace caml { + extern "C" +#endif + value alloc(int,int); +#ifdef __cplusplus + }; +#endif + +#ifdef __cplusplus + extern "C" +#endif + value caml_swig_alloc(int x,int y) { +#ifdef __cplusplus + using namespace caml; +#endif + return alloc(x,y); + } + + static value caml_val_bool( int b ) { + CAMLparam0(); + CAMLlocal1(bv); + bv = caml_swig_alloc(1,C_bool); + Store_field(bv,0,Val_bool(b)); + CAMLreturn(bv); + } + + static value caml_val_char( char c ) { + CAMLparam0(); + CAMLlocal1(cv); + cv = caml_swig_alloc(1,C_char); + Store_field(cv,0,Val_int(c)); + CAMLreturn(cv); + } + + static value caml_val_uchar( unsigned char uc ) { + CAMLparam0(); + CAMLlocal1(ucv); + ucv = caml_swig_alloc(1,C_uchar); + Store_field(ucv,0,Val_int(uc)); + CAMLreturn(ucv); + } + + static value caml_val_short( short s ) { + CAMLparam0(); + CAMLlocal1(sv); + sv = caml_swig_alloc(1,C_short); + Store_field(sv,0,Val_int(s)); + CAMLreturn(sv); + } + + static value caml_val_ushort( unsigned short us ) { + CAMLparam0(); + CAMLlocal1(usv); + usv = caml_swig_alloc(1,C_ushort); + Store_field(usv,0,Val_int(us)); + CAMLreturn(usv); + } + + static value caml_val_int( int i ) { + CAMLparam0(); + CAMLlocal1(iv); + iv = caml_swig_alloc(1,C_int); + Store_field(iv,0,Val_int(i)); + CAMLreturn(iv); + } + + static value caml_val_uint( unsigned int ui ) { + CAMLparam0(); + CAMLlocal1(uiv); + uiv = caml_swig_alloc(1,C_int); + Store_field(uiv,0,Val_int(ui)); + CAMLreturn(uiv); + } + + static value caml_val_long( long l ) { + CAMLparam0(); + CAMLlocal1(lv); + lv = caml_swig_alloc(1,C_int64); + Store_field(lv,0,copy_int64(l)); + CAMLreturn(lv); + } + + static value caml_val_ulong( unsigned long ul ) { + CAMLparam0(); + CAMLlocal1(ulv); + ulv = caml_swig_alloc(1,C_int64); + Store_field(ulv,0,copy_int64(ul)); + CAMLreturn(ulv); + } + + static value caml_val_float( float f ) { + CAMLparam0(); + CAMLlocal1(fv); + fv = caml_swig_alloc(1,C_float); + Store_field(fv,0,copy_double(f)); + CAMLreturn(fv); + } + + static value caml_val_double( double d ) { + CAMLparam0(); + CAMLlocal1(fv); + fv = caml_swig_alloc(1,C_double); + Store_field(fv,0,copy_double(d)); + CAMLreturn(fv); + } + + static value caml_val_ptr( void *p, swig_type_info *info ) { + CAMLparam0(); + CAMLlocal1(vv); + vv = caml_swig_alloc(2,C_ptr); + Store_field(vv,0,copy_int64((long)p)); + Store_field(vv,1,copy_int64((long)info)); + CAMLreturn(vv); + } + + static value caml_val_string( char *p ) { + CAMLparam0(); + CAMLlocal1(vv); + if( !p ) CAMLreturn(caml_val_ptr( (void *)p, 0 )); + vv = caml_swig_alloc(1,C_string); + Store_field(vv,0,copy_string(p)); + CAMLreturn(vv); + } + + static value caml_val_string_len( char *p, int len ) { + CAMLparam0(); + CAMLlocal1(vv); + if( !p || len < 0 ) CAMLreturn(caml_val_ptr( (void *)p, 0 )); + vv = caml_swig_alloc(1,C_string); + Store_field(vv,0,alloc_string(len)); + memcpy(String_val(Field(vv,0)),p,len); + CAMLreturn(vv); + } + + static value caml_val_obj( void *v, char *object_type ) { + CAMLparam0(); + CAMLreturn(callback2(*caml_named_value("caml_create_object_fn"), + caml_val_ptr(v,SWIG_TypeQuery(object_type)), + copy_string(object_type))); + } + + static long caml_long_val_full( value v, char *name ) { + CAMLparam1(v); + if( !Is_block(v) ) return 0; + + switch( Tag_val(v) ) { + case C_bool: + case C_char: + case C_uchar: + case C_short: + case C_ushort: + case C_int: + CAMLreturn(Int_val(Field(v,0))); + case C_uint: + case C_int32: + CAMLreturn(Int32_val(Field(v,0))); + case C_int64: + CAMLreturn((long)Int64_val(Field(v,0))); + case C_float: + case C_double: + CAMLreturn((long)Double_val(Field(v,0))); + case C_string: + CAMLreturn((long)String_val(Field(v,0))); + case C_ptr: + CAMLreturn((long)Int64_val(Field(Field(v,0),0))); + case C_enum: { + CAMLlocal1(ret); + value *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int"); + if( !name ) failwith( "Not an enum conversion" ); + ret = callback2(*enum_to_int,*caml_named_value(name),v); + CAMLreturn(caml_long_val(ret)); + } + default: + failwith("No conversion to int"); + } + } + + static long caml_long_val( value v ) { + return caml_long_val_full(v,0); + } + + static double caml_double_val( value v ) { + CAMLparam1(v); + if( !Is_block(v) ) return 0.0; + switch( Tag_val(v) ) { + case C_bool: + case C_char: + case C_uchar: + case C_short: + case C_ushort: + case C_int: + CAMLreturn(Int_val(Field(v,0))); + case C_uint: + case C_int32: + CAMLreturn(Int32_val(Field(v,0))); + case C_int64: + CAMLreturn(Int64_val(Field(v,0))); + case C_float: + case C_double: + CAMLreturn(Double_val(Field(v,0))); + default: + fprintf( stderr, "Unknown block tag %d\n", Tag_val(v) ); + failwith("No conversion to double"); + } + } + + static int caml_ptr_val_internal( value v, void **out, + swig_type_info *descriptor ) { + CAMLparam1(v); + void *outptr = NULL; + swig_type_info *outdescr = NULL; + + if( !Is_block(v) ) return -1; + switch( Tag_val(v) ) { + case C_obj: + return caml_ptr_val_internal + (callback(*caml_named_value("caml_obj_ptr"),v),out,descriptor); + case C_string: + outptr = (void *)String_val(Field(v,0)); + break; + case C_ptr: + outptr = (void *)(long)Int64_val(Field(v,0)); + outdescr = (swig_type_info *)(long)Int64_val(Field(v,1)); + break; + default: + outptr = (void *)caml_long_val(v); + break; + } + + CAMLreturn(SWIG_GetPtr(outptr,out,descriptor,outdescr)); + } + + static void *caml_ptr_val( value v, swig_type_info *descriptor ) { + CAMLparam0(); + void *out = NULL; + if( !caml_ptr_val_internal( v, &out, descriptor ) ) + CAMLreturn(out); + else + failwith( "No appropriate conversion found." ); + } + + static char *caml_string_val( value v ) { + return (char *)caml_ptr_val( v, 0 ); + } + + static int caml_bool_check( value v ) { + CAMLparam1(v); + + if( !Is_block(v) ) return 0; + + switch( Tag_val(v) ) { + case C_bool: + case C_ptr: + case C_string: + CAMLreturn(1); + default: + CAMLreturn(0); + } + } + + static int caml_int_check( value v ) { + CAMLparam1(v); + + if( !Is_block(v) ) return 0; + + switch( Tag_val(v) ) { + case C_char: + case C_uchar: + case C_short: + case C_ushort: + case C_int: + case C_uint: + case C_int32: + case C_int64: + CAMLreturn(1); + + default: + CAMLreturn(0); + } + } + + static int caml_float_check( value v ) { + CAMLparam1(v); + if( !Is_block(v) ) return 0; + + switch( Tag_val(v) ) { + case C_float: + case C_double: + CAMLreturn(1); + + default: + CAMLreturn(0); + } + } + + static int caml_ptr_check( value v ) { + CAMLparam1(v); + if( !Is_block(v) ) return 0; + + switch( Tag_val(v) ) { + case C_string: + case C_ptr: + case C_int64: + CAMLreturn(1); + + default: + CAMLreturn(0); + } + } + +#ifdef __cplusplus +} +#endif diff --git a/Lib/ocaml/ocamldec.swg b/Lib/ocaml/ocamldec.swg new file mode 100644 index 000000000..038c6773f --- /dev/null +++ b/Lib/ocaml/ocamldec.swg @@ -0,0 +1,106 @@ +/* -*-c-*- + * ----------------------------------------------------------------------- + * ocaml/ocamldec.swg + * Copyright (C) 2000, 2001 Matthias Koeppe + * + * Ocaml runtime code -- declarations + * ----------------------------------------------------------------------- */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +#define alloc caml_alloc +#include +#include +#include +#include +#include +#include +#include +#undef alloc + +#if defined(SWIG_NOINCLUDE) +# define SWIGSTATIC +#elif defined(SWIG_GLOBAL) +# define SWIGSTATIC +#else +# define SWIGSTATIC static +#endif + +#define __OCAML__SWIG__MAXVALUES 6 + + SWIGSTATIC int + SWIG_GetPtr(void *source, void **result, swig_type_info *type, swig_type_info *result_type); + + SWIGSTATIC void * + SWIG_MustGetPtr (value v, swig_type_info *type); + + static value _wrap_delete_void( value ); + + static int enum_to_int( char *name, value v ); + static value int_to_enum( char *name, int v ); + + static value caml_list_nth( value lst, int n ); + static value caml_list_append( value lst, value elt ); + static int caml_list_length( value lst ); + + static value caml_val_char( char c ); + static value caml_val_uchar( unsigned char c ); + + static value caml_val_short( short s ); + static value caml_val_ushort( unsigned short s ); + + static value caml_val_int( int x ); + static value caml_val_uint( unsigned int x ); + + static value caml_val_long( long x ); + static value caml_val_ulong( unsigned long x ); + + static value caml_val_float( float f ); + static value caml_val_double( double d ); + + static value caml_val_ptr( void *p, swig_type_info *descriptor ); + + static value caml_val_string( char *str ); + static value caml_val_string_len( char *str, int len ); + + static long caml_long_val( value v ); + static double caml_double_val( value v ); + + static int caml_ptr_val_internal( value v, void **out, + swig_type_info *descriptor ); + static void *caml_ptr_val( value v, swig_type_info *descriptor ); + + static char *caml_string_val( value v ); + +#ifdef __cplusplus +} + +template < class T > class SWIG_OCAML_ARRAY_WRAPPER { +public: + SWIG_OCAML_ARRAY_WRAPPER( T *t ) : t(t) { } + SWIG_OCAML_ARRAY_WRAPPER( T &t ) : t(&t) { } + SWIG_OCAML_ARRAY_WRAPPER( T t[] ) : t(&t[0]) { } + T &operator[]( int n ) { return t[n]; } + SWIG_OCAML_ARRAY_WRAPPER offset( int elts ) { + return SWIG_OCAML_ARRAY_WRAPPER( t + elts ); + } + T *operator & () { return t; } + void own() { owned = true; } + void disown() { owned = false; } + ~SWIG_OCAML_ARRAY_WRAPPER() { + if( owned ) delete t; + } + +private: + T *t; + int owned; +}; + +#endif + +/* mzschemedec.swg ends here */ diff --git a/Lib/ocaml/std_common.i b/Lib/ocaml/std_common.i new file mode 100644 index 000000000..73ca92fd5 --- /dev/null +++ b/Lib/ocaml/std_common.i @@ -0,0 +1,17 @@ +// -*- C++ -*- +// SWIG typemaps for STL - common utilities +// Art Yerkes +// Modified from: Luigi Ballabio +// Aug 3, 2002 +// +// Ocaml implementation + +%{ +#include + value SwigString_FromString(const std::string& s) { + return caml_val_string((char *)s.c_str()); + } + std::string SwigString_AsString(value o) { + return std::string((char *)caml_ptr_val(o,0)); + } +%} diff --git a/Lib/ocaml/std_complex.i b/Lib/ocaml/std_complex.i new file mode 100644 index 000000000..0bdedc019 --- /dev/null +++ b/Lib/ocaml/std_complex.i @@ -0,0 +1,65 @@ +// -*- C++ -*- +#ifndef __swig_std_complex_i__ +#define __swig_std_complex_i__ + +#ifdef SWIG + +%{ +#include +%} + +namespace std +{ + template class complex; + + %define specialize_std_complex(T) + + %typemap(in) complex { + if (PyComplex_Check($input)) { + $1 = std::complex(PyComplex_RealAsDouble($input), + PyComplex_ImagAsDouble($input)); + } else if (PyFloat_Check($input)) { + $1 = std::complex(PyFloat_AsDouble($input), 0); + } else if (PyInt_Check($input)) { + $1 = std::complex(PyInt_AsLong($input), 0); + } + else { + PyErr_SetString(PyExc_TypeError,"Expected a complex"); + SWIG_fail; + } + } + + %typemap(in) const complex& (std::complex temp) { + if (PyComplex_Check($input)) { + temp = std::complex(PyComplex_RealAsDouble($input), + PyComplex_ImagAsDouble($input)); + $1 = &temp; + } else if (PyFloat_Check($input)) { + temp = std::complex(PyFloat_AsDouble($input), 0); + $1 = &temp; + } else if (PyInt_Check($input)) { + temp = std::complex(PyInt_AsLong($input), 0); + $1 = &temp; + } else { + PyErr_SetString(PyExc_TypeError,"Expected a complex"); + SWIG_fail; + } + } + + %typemap(out) complex { + $result = PyComplex_FromDoubles($1.real(), $1.imag()); + } + + %typemap(out) const complex & { + $result = PyComplex_FromDoubles($1->real(), $1->imag()); + } + + %enddef + + specialize_std_complex(double); + specialize_std_complex(float); +} + +#endif // SWIG + +#endif //__swig_std_complex_i__ diff --git a/Lib/ocaml/std_deque.i b/Lib/ocaml/std_deque.i new file mode 100644 index 000000000..499549cbf --- /dev/null +++ b/Lib/ocaml/std_deque.i @@ -0,0 +1,23 @@ +/* Default std_deque wrapper */ +%module std_deque + +%rename(__getitem__) std::deque::getitem; +%rename(__setitem__) std::deque::setitem; +%rename(__delitem__) std::deque::delitem; +%rename(__getslice__) std::deque::getslice; +%rename(__setslice__) std::deque::setslice; +%rename(__delslice__) std::deque::delslice; + +%extend std::deque { + int __len__() { + return (int) self->size(); + } + int __nonzero__() { + return ! self->empty(); + } + void append(const T &x) { + self->push_back(x); + } +}; + +%include "_std_deque.i" diff --git a/Lib/ocaml/std_list.i b/Lib/ocaml/std_list.i new file mode 100644 index 000000000..e5319d86f --- /dev/null +++ b/Lib/ocaml/std_list.i @@ -0,0 +1,246 @@ +// -*- C++ -*- +// SWIG typemaps for std::list types +// Art Yerkes +// Modified from: Jing Cao +// Aug 1st, 2002 +// +// Python implementation + + +%module std_list +%{ +#include +#include +%} + +%include "exception.i" + +%exception std::list::__getitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::list::__setitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::list::__delitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +namespace std{ + template class list + { + public: + + typedef T &reference; + typedef const T& const_reference; + typedef T &iterator; + typedef const T& const_iterator; + + list(); + list(unsigned int size, const T& value = T()); + list(const list &); + + ~list(); + void assign(unsigned int n, const T& value); + void swap(list &x); + + const_reference front(); + const_reference back(); + const_iterator begin(); + const_iterator end(); + + void resize(unsigned int n, T c = T()); + bool empty() const; + + void push_front(const T& x); + void push_back(const T& x); + + + void pop_front(); + void pop_back(); + void clear(); + unsigned int size() const; + unsigned int max_size() const; + void resize(unsigned int n, const T& value); + + void remove(const T& value); + void unique(); + void reverse(); + void sort(); + + + + %extend + { + const_reference __getitem__(int i) + { + std::list::iterator first = self->begin(); + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i::iterator first = self->begin(); + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i::iterator first = self->begin(); + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && ierase(first); + } + else throw std::out_of_range("list index out of range"); + } + std::list __getslice__(int i,int j) + { + std::list::iterator first = self->begin(); + std::list::iterator end = self->end(); + + int size = int(self->size()); + if (i<0) i += size; + if (j<0) j += size; + if (i<0) i = 0; + if (j>size) j = size; + if (i>=j) i=j; + if (i>=0 && i=0) + { + for (int k=0;k tmp(j-i); + if (j>i) std::copy(first,end,tmp.begin()); + return tmp; + } + else throw std::out_of_range("list index out of range"); + } + void __delslice__(int i,int j) + { + std::list::iterator first = self->begin(); + std::list::iterator end = self->end(); + + int size = int(self->size()); + if (i<0) i += size; + if (j<0) j += size; + if (i<0) i = 0; + if (j>size) j = size; + + for (int k=0;kerase(first,end); + } + void __setslice__(int i,int j, const std::list& v) + { + std::list::iterator first = self->begin(); + std::list::iterator end = self->end(); + + int size = int(self->size()); + if (i<0) i += size; + if (j<0) j += size; + if (i<0) i = 0; + if (j>size) j = size; + + for (int k=0;kerase(first,end); + if (i+1 <= self->size()) + { + first = self->begin(); + for (int k=0;kinsert(first,v.begin(),v.end()); + } + else self->insert(self->end(),v.begin(),v.end()); + } + + } + unsigned int __len__() + { + return self->size(); + } + bool __nonzero__() + { + return !(self->empty()); + } + void append(const T& x) + { + self->push_back(x); + } + void pop() + { + self->pop_back(); + } + + }; + + }; +} + + + + + + diff --git a/Lib/ocaml/std_string.i b/Lib/ocaml/std_string.i new file mode 100644 index 000000000..4aa61a90b --- /dev/null +++ b/Lib/ocaml/std_string.i @@ -0,0 +1,55 @@ +// -*- C++ -*- +// SWIG typemaps for std::string +// Art Yerkes +// Modified from: Luigi Ballabio +// Apr 8, 2002 +// +// Ocaml implementation + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + /* Overloading check */ + + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string { + if (caml_ptr_check($input)) + $1 = std::string((char *)caml_ptr_val($input,0)); + else + SWIG_exception(SWIG_TypeError, "string expected"); + } + + %typemap(in) const string & (std::string temp) { + if (caml_ptr_check($input)) { + temp = std::string((char *)caml_ptr_val($input,0)); + $1 = &temp; + } else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + + %typemap(out) string { + $result = caml_val_ptr((char *)$1.c_str(),0); + } + + %typemap(out) const string & { + $result = caml_val_ptr((char *)$1->c_str(),0); + } +} + diff --git a/Lib/ocaml/std_vector.i b/Lib/ocaml/std_vector.i new file mode 100644 index 000000000..3eb6ab82b --- /dev/null +++ b/Lib/ocaml/std_vector.i @@ -0,0 +1,90 @@ +// -*- C++ -*- +// SWIG typemaps for std::vector types +// Art Yerkes +// Modified from: Luigi Ballabio +// Apr 8, 2002 +// +// Ocaml implementation + +%include std_common.i +%include exception.i + +// __getitem__ is required to raise an IndexError for for-loops to work +// other methods which can raise are made to throw an IndexError as well +%exception std::vector::__getitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::__setitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::__delitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Python as much as possible, namely, to allow the user to pass and +// be returned Python tuples or lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Python sequence of T:s +// is returned which is most easily used in other Python functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include + %} + +// exported class + +namespace std { + + template class vector { + }; + + + // Partial specialization for vectors of pointers. [ beazley ] + + template class vector { + }; + +} diff --git a/Lib/ocaml/stl.i b/Lib/ocaml/stl.i new file mode 100644 index 000000000..ce9a6c1a7 --- /dev/null +++ b/Lib/ocaml/stl.i @@ -0,0 +1,9 @@ +// +// SWIG typemaps for STL types +// Luigi Ballabio and Manu ??? +// Apr 26, 2002 +// + +%include std_string.i +%include std_vector.i + diff --git a/Lib/ocaml/swig.ml b/Lib/ocaml/swig.ml new file mode 100644 index 000000000..602c9b08e --- /dev/null +++ b/Lib/ocaml/swig.ml @@ -0,0 +1,100 @@ +open Pcaml ;; + +let lap x y = x :: y +let c_ify e loc = + match e with + <:expr< $int:_$ >> -> <:expr< (C_int $e$) >> + | <:expr< $str:_$ >> -> <:expr< (C_string $e$) >> + | <:expr< $chr:_$ >> -> <:expr< (C_char $e$) >> + | <:expr< $flo:_$ >> -> <:expr< (C_double $e$) >> + | _ -> <:expr< $e$ >> +let rec mk_list args l f = + match args with + [] -> (let loc = l in <:expr< [] >>) + | x :: xs -> + (let loc = MLast.loc_of_expr x in + <:expr< [ ($f x loc$) ] @ ($mk_list xs loc f$) >>) + +EXTEND + expr: + [ [ e1 = expr ; "'" ; "[" ; e2 = expr ; "]" -> + <:expr< (invoke $e1$) "[]" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "->" ; e2 = expr LEVEL "simple" ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> + <:expr< (invoke $e1$) $e2$ (C_list $mk_list args loc c_ify$) >> + | e1 = expr ; "'" ; "." ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> + <:expr< (invoke $e1$) "()" (C_list $mk_list args loc c_ify$) >> + | e1 = expr ; "'" ; "->" -> + <:expr< (invoke ((invoke $e1$) "->" C_void)) >> + | e1 = expr ; "'" ; "++" -> + <:expr< (invoke $e1$) "++" C_void >> + | e1 = expr ; "'" ; "--" -> + <:expr< (invoke $e1$) "--" C_void >> + | e1 = expr ; "'" ; "-" ; e2 = expr -> + <:expr< (invoke $e1$) "-" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "+" ; e2 = expr -> <:expr< (invoke $e1$) "+" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "*" ; e2 = expr -> <:expr< (invoke $e1$) "*" (C_list [ $c_ify e2 loc$ ]) >> + | "'" ; "&" ; e1 = expr -> + <:expr< (invoke $e1$) "&" C_void >> + | "'" ; "!" ; e1 = expr -> + <:expr< (invoke $e1$) "!" C_void >> + | "'" ; "~" ; e1 = expr -> + <:expr< (invoke $e1$) "~" C_void >> + | e1 = expr ; "'" ; "/" ; e2 = expr -> + <:expr< (invoke $e1$) "/" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "%" ; e2 = expr -> + <:expr< (invoke $e1$) "%" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "lsl" ; e2 = expr -> + <:expr< (invoke $e1$) ("<" ^ "<") (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "lsr" ; e2 = expr -> + <:expr< (invoke $e1$) (">" ^ ">") (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "<" ; e2 = expr -> + <:expr< (invoke $e1$) "<" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "<=" ; e2 = expr -> + <:expr< (invoke $e1$) "<=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; ">" ; e2 = expr -> + <:expr< (invoke $e1$) ">" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; ">=" ; e2 = expr -> + <:expr< (invoke $e1$) ">=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "==" ; e2 = expr -> + <:expr< (invoke $e1$) "==" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "!=" ; e2 = expr -> + <:expr< (invoke $e1$) "!=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "&" ; e2 = expr -> + <:expr< (invoke $e1$) "&" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "^" ; e2 = expr -> + <:expr< (invoke $e1$) "^" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "|" ; e2 = expr -> + <:expr< (invoke $e1$) "|" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "&&" ; e2 = expr -> + <:expr< (invoke $e1$) "&&" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "||" ; e2 = expr -> + <:expr< (invoke $e1$) "||" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "=" ; e2 = expr -> + <:expr< (invoke $e1$) "=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "+=" ; e2 = expr -> + <:expr< (invoke $e1$) "+=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "-=" ; e2 = expr -> + <:expr< (invoke $e1$) "-=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "*=" ; e2 = expr -> + <:expr< (invoke $e1$) "*=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "/=" ; e2 = expr -> + <:expr< (invoke $e1$) "/=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "%=" ; e2 = expr -> + <:expr< (invoke $e1$) "%=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "lsl" ; "=" ; e2 = expr -> + <:expr< (invoke $e1$) ("<" ^ "<=") (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "lsr" ; "=" ; e2 = expr -> + <:expr< (invoke $e1$) (">" ^ ">=") (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "&=" ; e2 = expr -> + <:expr< (invoke $e1$) "&=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "^=" ; e2 = expr -> + <:expr< (invoke $e1$) "^=" (C_list [ $c_ify e2 loc$ ]) >> + | e1 = expr ; "'" ; "|=" ; e2 = expr -> + <:expr< (invoke $e1$) "|=" (C_list [ $c_ify e2 loc$ ]) >> + | "'" ; e = expr -> c_ify e loc + | f = expr ; "'" ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> + let l = mk_list args loc c_ify in + <:expr< $f$ (C_list $l$) >> + ] ] ; +END ;; + diff --git a/Lib/ocaml/typecheck.i b/Lib/ocaml/typecheck.i new file mode 100644 index 000000000..8c8eaea97 --- /dev/null +++ b/Lib/ocaml/typecheck.i @@ -0,0 +1,175 @@ +/* -*- C++ -*- */ +/* Type checking code adapted from python backend. */ +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_INTEGER) char, signed char, const char &, const signed char & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_char: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_INTEGER) unsigned char, const unsigned char & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_uchar: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_INTEGER) short, signed short, const short &, const signed short & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_short: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_INTEGER) unsigned short, const unsigned short & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_ushort: $1 = 1; + default: $1 = 0; + } + } +} + +// XXX arty +// Will move enum SWIGTYPE later when I figure out what to do with it... + +%typecheck(SWIG_TYPECHECK_INTEGER) int, signed int, const int &, const signed int &, enum SWIGTYPE { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_int: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_INTEGER) unsigned int, const unsigned int & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_uint: $1 = 1; + case C_int32: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_INTEGER) long, signed long, unsigned long, long long, signed long long, unsigned long long, const long &, const signed long &, const unsigned long &, const long long &, const signed long long &, const unsigned long long & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_int64: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_INTEGER) bool, oc_bool, BOOL, const bool &, const oc_bool &, const BOOL & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_bool: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) float, const float & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_float: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) double, const double & { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_double: $1 = 1; + default: $1 = 0; + } + } +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + if( !Is_block($input) ) $1 = 0; + else { + switch( Tag_val($input) ) { + case C_string: $1 = 1; break; + case C_ptr: { + swig_type_info *typeinfo = + (swig_type_info *)(long)Int64_val(Field($input,1)); + $1 = SWIG_TypeCheck("char *",typeinfo) || + SWIG_TypeCheck("signed char *",typeinfo) || + SWIG_TypeCheck("unsigned char *",typeinfo) || + SWIG_TypeCheck("const char *",typeinfo) || + SWIG_TypeCheck("const signed char *",typeinfo) || + SWIG_TypeCheck("const unsigned char *",typeinfo) || + SWIG_TypeCheck("std::string",typeinfo); + } break; + default: $1 = 0; break; + } + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + $1 = !caml_ptr_val_internal($input, &ptr,$descriptor); +} + +#if 0 + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + $1 = !caml_ptr_val_internal($input, &ptr, $&1_descriptor); +} + +#endif + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + $1 = !caml_ptr_val_internal($input, &ptr, 0); +} + +/* ------------------------------------------------------------ + * Exception handling + * ------------------------------------------------------------ */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + SWIG_exception($1,"Thrown exception from C++ (int)"); +} + +%typemap(throws) SWIGTYPE CLASS { + $&1_ltype temp = new $1_ltype($1); + SWIG_exception((int)temp,"Thrown exception from C++ (object)"); +} + +%typemap(throws) SWIGTYPE { + SWIG_exception(0,"Thrown exception from C++ (unknown)"); +} + +%typemap(throws) char * { + SWIG_exception(0,$1); +} diff --git a/Lib/ocaml/typemaps.i b/Lib/ocaml/typemaps.i new file mode 100644 index 000000000..8baf76fca --- /dev/null +++ b/Lib/ocaml/typemaps.i @@ -0,0 +1,174 @@ +/* typemaps.i --- ocaml typemaps -*- c -*- + Ocaml conversion by Art Yerkes, modified from mzscheme/typemaps.i + Copyright 2000, 2001 Matthias Koeppe + Based on code written by Oleg Tolmatcev. + + $Id$ +*/ + +/* The Ocaml module handles all types uniformly via typemaps. Here + are the definitions. */ + +/* Pointers */ + +%typemap(ocaml,in) void * { + $1 = caml_ptr_val($input,$descriptor); +} + +%typemap(ocaml,varin) void * { + $1 = ($ltype)caml_ptr_val($input,$descriptor); +} + +%typemap(ocaml,in) char *, signed char *, unsigned char *, const char *, const signed char *, const unsigned char * { + $1 = ($ltype)caml_string_val($input); +} + +%typemap(ocaml,varin) char *, signed char *, unsigned char *, const char *, const signed char *, const unsigned char * { + $1 = ($ltype)caml_string_val($input); +} + +%typemap(ocaml,out) void * { + $result = caml_val_ptr($1,$descriptor); +} + +%typemap(ocaml,varout) void * { + $result = caml_val_ptr($1,$descriptor); +} + +%typemap(ocaml,out) char *, signed char *, unsigned char *, const char *, const signed char *, const unsigned char * { + $result = caml_val_string($1); +} + +%typemap(ocaml,varout) char *, signed char *, unsigned char *, const char *, const signed char *, const unsigned char * { + $result = caml_val_string($1); +} + +%typemap(ocaml,in) SWIGTYPE * { + $1 = ($ltype)caml_ptr_val($input,$descriptor); +} + +%typemap(ocaml,out) SWIGTYPE * { + value *fromval = caml_named_value("create_$*1_type_from_ptr"); + if( fromval ) { + $result = callback(*fromval,caml_val_ptr((void *)$1,$descriptor)); + } else { + $result = caml_val_ptr ((void *)$1,$descriptor); + } +} + +%typemap(ocaml,varin) SWIGTYPE * { + $1 = ($ltype)caml_ptr_val($input,$descriptor); +} + +%typemap(ocaml,varout) SWIGTYPE * { + value *fromval = caml_named_value("create_$*1_type_from_ptr"); + if( fromval ) { + $result = callback(*fromval,caml_val_ptr((void *)$1,$descriptor)); + } else { + $result = caml_val_ptr ((void *)$1,$descriptor); + } +} + +/* C++ References */ + +#ifdef __cplusplus + +%typemap(ocaml,in) SWIGTYPE & { + $1 = ($ltype) caml_ptr_val($input,$descriptor); +} + +%typemap(ocaml,out) SWIGTYPE & { + value *fromval = caml_named_value("create_$*1_ltype_from_ptr"); + if( fromval ) { + $result = callback(*fromval,caml_val_ptr((void *) $1,$descriptor)); + } else { + $result = caml_val_ptr ((void *) $1,$descriptor); + } +} + +#else + +%typemap(ocaml,in) SWIGTYPE { + $1 = *(($&1_ltype) caml_ptr_val($input,$descriptor)) ; +} + +%typemap(ocaml,out) SWIGTYPE { + void *temp = calloc(1,sizeof($ltype)); + value *fromval = caml_named_value("create_$ltype_from_ptr"); + *(($ltype *)temp) = $1; + if( fromval ) { + $result = callback(*fromval,caml_val_ptr((void *)temp,$descriptor)); + } else { + $result = caml_val_ptr ((void *)temp,$descriptor); + } +} + +#endif + +/* Arrays */ + +/* Enums */ +%typemap(ocaml,in) enum SWIGTYPE { + $1 = ($type)caml_long_val_full($input,"$type_marker"); +} + +%typemap(ocaml,varin) enum SWIGTYPE { + $1 = ($type)caml_long_val_full($input,"$type_marker"); +} + +%typemap(ocaml,out) enum SWIGTYPE "$result = callback2(*caml_named_value(SWIG_MODULE \"_int_to_enum\"),*caml_named_value(\"$type_marker\"),Val_int($1));" +%typemap(ocaml,varout) enum SWIGTYPE "$result = callback2(*caml_named_value(SWIG_MODULE \"_int_to_enum\"),*caml_named_value(\"$type_marker\"),Val_int($1));" + +/* The SIMPLE_MAP macro below defines the whole set of typemaps needed + for simple types. */ + +%define SIMPLE_MAP(C_NAME, C_TO_MZ, MZ_TO_C) +%typemap(in) C_NAME { + $1 = MZ_TO_C($input); +} +%typemap(varin) C_NAME { + $1 = MZ_TO_C($input); +} +%typemap(out) C_NAME { + $result = C_TO_MZ($1); +} +%typemap(varout) C_NAME { + $result = C_TO_MZ($1); +} +%typemap(in) C_NAME *INPUT (C_NAME temp) { + temp = (C_NAME) MZ_TO_C($input); + $1 = &temp; +} +%typemap(in,numinputs=0) C_NAME *OUTPUT (C_NAME temp) { + $1 = &temp; +} +%typemap(argout) C_NAME *OUTPUT { + caml_list_append(swig_result,(long)*$1); +} +%enddef + +SIMPLE_MAP(oc_bool, caml_val_bool, caml_long_val); +SIMPLE_MAP(bool, caml_val_bool, caml_long_val); +SIMPLE_MAP(char, caml_val_char, caml_long_val); +SIMPLE_MAP(unsigned char, caml_val_uchar, caml_long_val); +SIMPLE_MAP(int, caml_val_int, caml_long_val); +SIMPLE_MAP(short, caml_val_short, caml_long_val); +SIMPLE_MAP(long, caml_val_long, caml_long_val); +SIMPLE_MAP(ptrdiff_t, caml_val_int, caml_long_val); +SIMPLE_MAP(unsigned int, caml_val_uint, caml_long_val); +SIMPLE_MAP(unsigned short, caml_val_ushort, caml_long_val); +SIMPLE_MAP(unsigned long, caml_val_ulong, caml_long_val); +SIMPLE_MAP(size_t, caml_val_int, caml_long_val); +SIMPLE_MAP(float, caml_val_float, caml_double_val); +SIMPLE_MAP(double, caml_val_double, caml_double_val); +SIMPLE_MAP(long long,caml_val_ulong,caml_long_val); +SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val); + +/* Void */ + +%typemap(out) void "$result = Val_unit;"; + +/* Pass through value */ + +%typemap (in) value "$1=$input;"; +%typemap (out) value "$result=$1;"; diff --git a/Lib/perl5/Makefile.in b/Lib/perl5/Makefile.in index 7501aeca3..36ab94805 100644 --- a/Lib/perl5/Makefile.in +++ b/Lib/perl5/Makefile.in @@ -35,7 +35,7 @@ CC = @CC@ CXX = @CXX@ OBJC = @CC@ -Wno-import # -Wno-import needed for gcc CFLAGS = -INCLUDE = +INCLUDES = LIBS = # SWIG Options @@ -103,13 +103,13 @@ BUILD_LIBS = $(LIBS) # Dynamic loading .SUFFIXES: .c .cxx .m .c.o: - $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< .cxx.o: - $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDES) -c $< .m.o: - $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< # ---------------------------------------------------------------------- @@ -121,7 +121,7 @@ all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) - $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(INCLUDE) $(PERL_INCLUDE) $(PERL_FLAGS) $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(PERL_INCLUDE) $(PERL_FLAGS) $(WRAPFILE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) diff --git a/Lib/perl5/extra-install.list b/Lib/perl5/extra-install.list new file mode 100644 index 000000000..d49f4150a --- /dev/null +++ b/Lib/perl5/extra-install.list @@ -0,0 +1,2 @@ +# see top-level Makefile.in +Makefile.pl diff --git a/Lib/perl5/perl5.swg b/Lib/perl5/perl5.swg index ddf188f81..a0dedf056 100644 --- a/Lib/perl5/perl5.swg +++ b/Lib/perl5/perl5.swg @@ -1,186 +1,571 @@ /* ----------------------------------------------------------------------------- * perl5.swg * - * Perl5 runtime library - * $Header$ + * Perl 5 configuration file * ----------------------------------------------------------------------------- */ -#define SWIGPERL -#define SWIGPERL5 -#ifdef __cplusplus -/* Needed on some windows machines---since MS plays funny - games with the header files under C++ */ -#include -#include -extern "C" { -#endif -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" +%runtime "common.swg" // common type checking code +%runtime "perlrun.swg" // Perl runtime functions -/* Get rid of free and malloc defined by perl */ -#undef free -#undef malloc +/* Typemaps for input parameters */ -#include +%typemap(in) int, short, long, signed char, bool, enum SWIGTYPE + "$1 = ($1_ltype) SvIV($input);"; + +%typemap(in) unsigned int, unsigned short, unsigned long, unsigned char + "$1 = ($1_ltype) SvUV($input);"; + +%typemap(in) char + "$1 = ($1_ltype) *SvPV($input,PL_na);"; + +%typemap(in) float, double + "$1 = ($1_ltype) SvNV($input);\n"; + +%typemap(in) long long "$1 = (long long) strtoll(SvPV($input, PL_na), 0, 0);"; +%typemap(in) unsigned long long "$1 = (unsigned long long) strtoull(SvPV($input, PL_na), 0, 0);"; + +%typemap(in) char * + "if (!SvOK((SV*) $input)) $1 = 0; + else $1 = ($1_ltype) SvPV($input, PL_na);"; + +%typemap(in) char [ANY] + "$1 = SvPV($input,PL_na);\n"; + +%typemap(in) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & { + if (SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0) < 0) { + SWIG_croak("Type error in argument $argnum of $symname. Expected $1_mangle"); + } +} + +%typemap(in) void * { + if (SWIG_ConvertPtr($input, (void **) &$1, 0,0) < 0) { + SWIG_croak("Type error in argument $argnum of $symname. Expected $1_mangle"); + } +} + +/* Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE { + $&1_ltype argp; + if (SWIG_ConvertPtr($input,(void **) &argp, $&1_descriptor,0) < 0) { + SWIG_croak("Type error in argument $argnum of $symname. Expected $&1_mangle"); + } + $1 = *argp; +} + + +/* Const primitive references. Passed by value */ + +%typemap(in) const int & (int temp), + const short & (short temp), + const long & (long temp), + const signed char & (signed char temp), + const bool & (bool temp) + "temp = ($*1_ltype) SvIV($input); + $1 = &temp;"; + +%typemap(in) const unsigned int & (unsigned int temp), + const unsigned short & (unsigned short temp), + const unsigned long & (unsigned long temp), + const unsigned char & (unsigned char temp) + "temp = ($*1_ltype) SvUV($input); + $1 = &temp;"; + +%typemap(in) const float & (float temp), + const double & (double temp) + "temp = ($*1_ltype) SvNV($input); + $1 = &temp;"; + +%typemap(in) const long long & (long long temp) + "temp = (long long) strtoll(SvPV($input,PL_na),0,0); + $1 = &temp;"; + +%typemap(in) const unsigned long long & (unsigned long long temp) + "temp = (unsigned long long) strtoull(SvPV($input, PL_na),0,0); + $1 = &temp;"; + +%typemap(in) const char &(char temp) { + temp = *SvPV($input,PL_na); + $1 = &temp; +} + + +/* Typemap for output values */ + +%typemap(out) int, short, long, signed char, bool, enum SWIGTYPE + "ST(argvi) = sv_newmortal(); + sv_setiv(ST(argvi++), (IV) $1);"; + +%typemap(out) unsigned int, unsigned short, unsigned long, unsigned char + "ST(argvi) = sv_newmortal(); + sv_setuv(ST(argvi++), (UV) $1);"; + +%typemap(out) float, double + "ST(argvi) = sv_newmortal(); + sv_setnv(ST(argvi++), (double) $1);"; + +%typemap(out) char + "ST(argvi) = sv_newmortal(); + sv_setpvn((SV*)ST(argvi++), &$1, 1);"; + +%typemap(out) char * + "ST(argvi) = sv_newmortal(); + if ($1) { + sv_setpv((SV*)ST(argvi++), (char *) $1); + } else { + sv_setsv((SV*)ST(argvi++), &PL_sv_undef); + }"; + +%typemap(out) long long { + char temp[256]; + sprintf(temp,"%lld", $1); + ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++), temp); +} + +%typemap(out) unsigned long long { + char temp[256]; + sprintf(temp,"%llu", $1); + ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++), temp); +} + +%typemap(out) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & + "ST(argvi) = sv_newmortal(); + SWIG_MakePtr(ST(argvi++), (void *) $1, $1_descriptor,0);"; + + +%typemap(out) SWIGTYPE #ifdef __cplusplus +{ + $&1_ltype resultobj = new $1_ltype(($1_ltype &)$1); + ST(argvi) = sv_newmortal(); + SWIG_MakePtr(ST(argvi++), (void *) resultobj, $&1_descriptor,0); +} +#else +{ + $&1_ltype resultobj = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultobj, &$1, sizeof($1_type)); + ST(argvi) = sv_newmortal(); + SWIG_MakePtr(ST(argvi++), (void *) resultobj, $&1_descriptor,0); } #endif -#ifdef PERL_OBJECT -#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; -#define MAGIC_CAST (int (CPerlObj::*)(SV *, MAGIC *)) -#define SWIGCLASS_STATIC -#else -#define MAGIC_PPERL -#define MAGIC_CAST -#define SWIGCLASS_STATIC static -#endif +/* Dynamic casts */ -#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) -#define PerlIO_exportFILE(fh,fl) (FILE*)(fh) -#endif +%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); + ST(argvi) = sv_newmortal(); + SWIG_MakePtr(ST(argvi++), (void *) $1, ty,0); +} -/* Modifications for newer Perl 5.005 releases */ +%typemap(out) void ""; -#if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) -#ifndef PL_sv_yes -#define PL_sv_yes sv_yes -#endif -#ifndef PL_sv_undef -#define PL_sv_undef sv_undef -#endif -#ifndef PL_na -#define PL_na na -#endif -#endif +/* Typemap for character array returns */ -#include +%typemap(out) char [ANY] + "ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++),(char *) $1);"; + + +/* References to primitive types. Return by value */ + +%typemap(out) const int &, + const short &, + const long &, + const signed char &, + const bool & + "ST(argvi) = sv_newmortal(); + sv_setiv(ST(argvi++), (IV) *($1));"; + +%typemap(out) const unsigned int &, + const unsigned short &, + const unsigned long &, + const unsigned char & + "ST(argvi) = sv_newmortal(); + sv_setuv(ST(argvi++), (UV) *($1));"; + +%typemap(out) const float &, const double & + "ST(argvi) = sv_newmortal(); + sv_setnv(ST(argvi++), (double) *($1));"; + +%typemap(out) const long long & { + char temp[256]; + sprintf(temp,"%lld", *($1)); + ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++), temp); +} + +%typemap(out) const unsigned long long & { + char temp[256]; + sprintf(temp,"%llu", *($1)); + ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++), temp); +} + +%typemap(out) const char & + "ST(argvi) = sv_newmortal(); + sv_setpvn((SV*)ST(argvi++), $1, 1);"; + + +/* Variable input */ + +%typemap(varin) int, short, long, signed char, bool, enum SWIGTYPE + "$1 = ($1_ltype) SvIV($input);"; + +%typemap(varin) unsigned int, unsigned short, unsigned long, unsigned char + "$1 = ($1_ltype) SvUV($input);"; + +%typemap(varin) char + "$1 = ($1_ltype) *SvPV($input,PL_na);"; + +%typemap(varin) float, double + "$1 = ($1_ltype) SvNV($input);\n"; + +%typemap(varin) long long "$1 = (long long) strtoll(SvPV($input, PL_na), 0, 0);"; +%typemap(varin) unsigned long long "$1 = (unsigned long long) strtoull(SvPV($input, PL_na), 0, 0);"; + +%typemap(varin) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & { + if (SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0) < 0) { + croak("Type error in argument $argnum of $symname. Expected $1_mangle"); + } +} + +%typemap(varin) void * { + if (SWIG_ConvertPtr($input, (void **) &$1, 0,0) < 0) { + croak("Type error in argument $argnum of $symname. Expected $1_mangle"); + } +} + +/* Object passed by value. Convert to a pointer */ +%typemap(varin) SWIGTYPE { + $&1_ltype argp; + if (SWIG_ConvertPtr($input,(void **) &argp, $&1_descriptor,0) < 0) { + croak("Type error in argument $argnum of $symname. Expected $&1_mangle"); + } + $1 = *argp; +} + +/* Const primitive references. Passed by value */ + +%typemap(varin) const int & (int temp), + const short & (short temp), + const long & (long temp), + const signed char & (signed char temp), + const bool & (bool temp) + "temp = ($*1_ltype) SvIV($input); + $1 = &temp;"; + +%typemap(varin) const unsigned int & (unsigned int temp), + const unsigned short & (unsigned short temp), + const unsigned long & (unsigned long temp), + const unsigned char & (unsigned char temp) + "temp = ($*1_ltype) SvUV($input); + $1 = &temp;"; + +%typemap(varin) const float & (float temp), + const double & (double temp) + "temp = ($*1_ltype) SvNV($input); + $1 = &temp;"; + +%typemap(varin) const long long & (long long temp) + "temp = (long long) strtoll(SvPV($input,PL_na),0,0); + $1 = &temp;"; + +%typemap(varin) const unsigned long long & (unsigned long long temp) + "temp = (unsigned long long) strtoull(SvPV($input, PL_na),0,0); + $1 = &temp;"; + +%typemap(varin) const char &(char temp) { + temp = *SvPV($input,PL_na); + $1 = &temp; +} + +%typemap(varin) char * #ifdef __cplusplus -extern "C" { -#endif - -#ifdef SWIG_NOINCLUDE - -#ifndef PERL_OBJECT -extern int SWIG_ConvertPtr(SV *, void **, swig_type_info *); -extern void SWIG_MakePtr(SV *, void *, swig_type_info *); -#else -extern int _SWIG_ConvertPtr(CPerlObj *, SV *, void **, swig_type_info *); -extern void _SWIG_MakePtr(CPerlObj *, SV *, void *, swig_type_info *); -#define SWIG_ConvertPtr(a,b,c) _SWIG_ConvertPtr(pPerl,a,b,c) -#define SWIG_MakePtr(a,b,c) _SWIG_MakePtr(pPerl,a,b,c) -#endif - -#endif - -/* Function for getting a pointer value */ - -#ifndef PERL_OBJECT -SWIGRUNTIME(int) -SWIG_ConvertPtr(SV *sv, void **ptr, swig_type_info *_t) -#else -#define SWIG_ConvertPtr(a,b,c) _SWIG_ConvertPtr(pPerl,a,b,c) -SWIGRUNTIME(int) -_SWIG_ConvertPtr(CPerlObj *pPerl, SV *sv, void **ptr, swig_type_info *_t) -#endif { - char *_c; - swig_type_info *tc; - IV tmp; + char *_a = (char *) SvPV(sv,PL_na); + if ($1) delete [] $1; + $1 = new char[strlen(_a)+1]; + strcpy((char *)$1,_a); +} +#else +{ + char *_a = (char *) SvPV(sv,PL_na); + if ($1) free((char *) $1); + $1 = (char *) malloc(strlen(_a)+1); + strcpy((char *)$1,_a); +} +#endif - /* If magical, apply more magic */ - if (SvGMAGICAL(sv)) - mg_get(sv); +%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * +#ifdef __cplusplus +{ + char *_a = (char *) SvPV(sv,PL_na); + $1 = new char[strlen(_a)+1]; + strcpy((char *)$1,_a); +} +#else +{ + char *_a = (char *) SvPV(sv,PL_na); + $1 = (char *) malloc(strlen(_a)+1); + strcpy((char *)$1,_a); +} +#endif - /* Check to see if this is an object */ - if (sv_isobject(sv)) { - SV *tsv = (SV*) SvRV(sv); - if ((SvTYPE(tsv) == SVt_PVHV)) { - MAGIC *mg; - if (SvMAGICAL(tsv)) { - mg = mg_find(tsv,'P'); - if (mg) { - SV *rsv = mg->mg_obj; - if (sv_isobject(rsv)) { - tmp = SvIV((SV*)SvRV(rsv)); - } - } +%typemap(varin) char [ANY] + "strncpy($1, (char *) SvPV(sv,PL_na), $1_dim0);"; + +%typemap(varin) SWIGTYPE [] "croak(\"Value is read-only.\");"; + +%typemap(varin) enum SWIGTYPE + "$1 = ($1_type) SvIV($input);"; + +/* --- Typemaps for variable output --- */ + +%typemap(varout) int, short, long, signed char, bool, enum SWIGTYPE + "sv_setiv($result, (IV) $1);"; + +%typemap(varout) unsigned int, unsigned short, unsigned long, unsigned char + "sv_setuv($result, (UV) $1);"; + +%typemap(varout) float, double + "sv_setnv($result, (double) $1);"; + +%typemap(varout) char + "sv_setpvn((SV *) $result, &$1, 1);"; + +%typemap(varout) long long { + char temp[256]; + sprintf(temp,"%lld",$1); + sv_setpv((SV *) $result, temp); +} + +%typemap(varout) unsigned long long { + char temp[256]; + sprintf(temp,"%llu",$1); + sv_setpv((SV *) $result, temp); +} + +%typemap(varout) char *, char [ANY] + "if ($1) { + sv_setpv((SV*)$result, (char *) $1); + } else { + sv_setsv((SV*)$result, &PL_sv_undef); + }"; + +//%typemap(varout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] +// "SWIG_MakePtr($result, (void *) $1, $1_descriptor);"; + +%typemap(varout,type="$1_descriptor") SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + "sv_setiv(SvRV($result),(IV) $1);"; + +//%typemap(varout) SWIGTYPE +// "SWIG_MakePtr($result, (void *) &$1, $&1_descriptor);"; + +%typemap(varout,type="$&1_descriptor") SWIGTYPE + "sv_setiv(SvRV($result), (IV) &$1);"; + +/* --- Typemaps for constants --- * + +/* --- Constants --- */ + +%typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE + { SWIG_INT, (char *) SWIG_prefix "$symname", (long) $value, 0, 0, 0} + +%typemap(consttab) float, double + { SWIG_FLOAT, (char *) SWIG_prefix "$symname", 0, (double) $value, 0, 0} + +%typemap(consttab) char, char * + { SWIG_STRING, (char *) SWIG_prefix "$symname", 0, 0, (void *)"$value", 0} + +%typemap(consttab) long long, unsigned long long + { SWIG_STRING, (char *) SWIG_prefix "$symname", 0, 0, (void *) "$value", 0} + +%typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + { SWIG_POINTER, (char *) SWIG_prefix "$symname", 0, 0, (void *)$value, &$1_descriptor} + +%typemap(consttab) SWIGTYPE (CLASS::*) + { SWIG_BINARY, (char *) SWIG_prefix "$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor} + + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +%typemap(in) (char *STRING, int LENGTH) { + unsigned int temp; + $1 = ($1_ltype) SvPV($input,temp); + $2 = ($2_ltype) temp; +} + +/* ------------------------------------------------------------ + * ANSI C typemaps + * ------------------------------------------------------------ */ + +%apply unsigned long { size_t }; + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE, + bool, const bool & +{ + $1 = SvIOK($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = SvNOK($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + $1 = SvPOK($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = SvPOK($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *tmp; + if (SWIG_ConvertPtr($input, (void **) &tmp, $1_descriptor, 0) == -1) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *tmp; + if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) == -1) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *tmp; + if (SWIG_ConvertPtr($input, (void **) &tmp, 0, 0) == -1) { + $1 = 0; + } else { + $1 = 1; + } +} + +/* ------------------------------------------------------------ + * Exception handling + * ------------------------------------------------------------ */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + sprintf(_swigmsg,"%d",$1); + SWIG_croak(_swigmsg); +} + +%typemap(throws) SWIGTYPE { + SWIG_croak("$1_type"); +} + +%typemap(throws) char * { + SWIG_croak($1); + SWIG_fail; +} + + +/* Export the SWIG initialization function */ +%header %{ +#ifdef __cplusplus +extern "C" +#endif +#ifndef PERL_OBJECT +#ifndef MULTIPLICITY +SWIGEXPORT(void) SWIG_init (CV* cv); +#else +SWIGEXPORT(void) SWIG_init (pTHXo_ CV* cv); +#endif +#else +SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *); +#endif +%} + +/* Module initialization function */ + +%init %{ +#ifdef __cplusplus +extern "C" +#endif + +XS(SWIG_init) { + dXSARGS; + int i; + static int _init = 0; + if (!_init) { + for (i = 0; swig_types_initial[i]; i++) { + swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); + } + _init = 1; + } + + /* Install commands */ + for (i = 0; swig_commands[i].name; i++) { + newXS((char*) swig_commands[i].name,swig_commands[i].wrapper, (char*)__FILE__); + } + + /* Install variables */ + for (i = 0; swig_variables[i].name; i++) { + SV *sv; + sv = perl_get_sv((char*) swig_variables[i].name, TRUE | 0x2); + if (swig_variables[i].type) { + SWIG_MakePtr(sv,(void *)1, *swig_variables[i].type,0); } else { - return -1; + sv_setiv(sv,(IV) 0); } - } else { - tmp = SvIV((SV*)SvRV(sv)); + swig_create_magic(sv, (char *) swig_variables[i].name, swig_variables[i].set, swig_variables[i].get); } - if (!_t) { - *(ptr) = (void *) tmp; - return 0; + + /* Install constant */ + for (i = 0; swig_constants[i].type; i++) { + SV *sv; + sv = perl_get_sv((char*)swig_constants[i].name, TRUE | 0x2); + switch(swig_constants[i].type) { + case SWIG_INT: + sv_setiv(sv, (IV) swig_constants[i].lvalue); + break; + case SWIG_FLOAT: + sv_setnv(sv, (double) swig_constants[i].dvalue); + break; + case SWIG_STRING: + sv_setpv(sv, (char *) swig_constants[i].pvalue); + break; + case SWIG_POINTER: + SWIG_MakePtr(sv, swig_constants[i].pvalue, *(swig_constants[i].ptype),0); + break; + case SWIG_BINARY: + /* obj = SWIG_NewPackedObj(swig_constants[i].pvalue, swig_constants[i].lvalue, *(swig_constants[i].ptype)); */ + break; + default: + break; + } + SvREADONLY_on(sv); } - } else if (! SvOK(sv)) { /* Check for undef */ - *(ptr) = (void *) 0; - return 0; - } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ - *(ptr) = (void *) 0; - if (!SvROK(sv)) - return 0; - else - return -1; - } else { /* Don't know what it is */ - *(ptr) = (void *) 0; - return -1; - } - if (_t) { - /* Now see if the types match */ - _c = HvNAME(SvSTASH(SvRV(sv))); - tc = SWIG_TypeCheck(_c,_t); - if (!tc) { - *ptr = (void *) tmp; - return -1; - } - *ptr = SWIG_TypeCast(tc,(void *)tmp); - return 0; - } - *ptr = (void *) tmp; - return 0; -} -#ifndef PERL_OBJECT -SWIGRUNTIME(void) -SWIG_MakePtr(SV *sv, void *ptr, swig_type_info *t) -#else -#define SWIG_MakePtr(a,b,c) _SWIG_MakePtr(pPerl,a,b,c) -SWIGRUNTIME(int *) -_SWIG_MakePtr(CPerlObj *pPerl, SV *sv, void *ptr, swig_type_info *t) -#endif -{ - sv_setref_pv(sv, t->name, ptr); -} - -/* Magic variable code */ -#ifndef PERL_OBJECT -#define swig_create_magic(s,a,b,c) _swig_create_magic(s,a,b,c) -static void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *)) { -#else -#define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c) -static void _swig_create_magic(CPerlObj *pPerl, SV *sv, char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *)) { -#endif - MAGIC *mg; - sv_magic(sv,sv,'U',name,strlen(name)); - mg = mg_find(sv,'U'); - mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL)); - mg->mg_virtual->svt_get = get; - mg->mg_virtual->svt_set = set; - mg->mg_virtual->svt_len = 0; - mg->mg_virtual->svt_clear = 0; - mg->mg_virtual->svt_free = 0; -} - -#ifdef __cplusplus -} -#endif - - - +%} diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg new file mode 100644 index 000000000..dba587471 --- /dev/null +++ b/Lib/perl5/perlrun.swg @@ -0,0 +1,286 @@ +/* ----------------------------------------------------------------------------- + * perl5.swg + * + * Perl5 runtime library + * $Header$ + * ----------------------------------------------------------------------------- */ + +#define SWIGPERL +#define SWIGPERL5 +#ifdef __cplusplus +/* Needed on some windows machines---since MS plays funny + games with the header files under C++ */ +#include +#include +extern "C" { +#endif +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +/* Get rid of free and malloc defined by perl */ +#undef free +#undef malloc + +#ifndef pTHX_ +#define pTHX_ +#endif + +#include +#ifdef __cplusplus +} +#endif + +/* Macro to call an XS function */ + +#ifdef PERL_OBJECT +#define SWIG_CALLXS(_name) _name(cv,pPerl) +#else +#ifndef MULTIPLICITY +#define SWIG_CALLXS(_name) _name(cv) +#else +#define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv) +#endif +#endif + +/* Macros for low-level exception handling */ +#define SWIG_fail goto fail +#define SWIG_croak(x) { if ((_swigerr = (const char *) x)) goto fail; } +#define SWIG_MAX_ERRMSG 256 + +/* Note: SwigMagicFuncHack is a typedef used to get the C++ + compiler to just shut up already */ + +#ifdef PERL_OBJECT +#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; +typedef int (CPerlObj::*SwigMagicFunc)(SV *, MAGIC *); + +#ifdef __cplusplus +extern "C" { +#endif +typedef int (CPerlObj::*SwigMagicFuncHack)(SV *, MAGIC *); +#ifdef __cplusplus +} +#endif + +#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b) +#define SWIGCLASS_STATIC +#else +#define MAGIC_PPERL +#define SWIGCLASS_STATIC static +#ifndef MULTIPLICITY +#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b) +typedef int (*SwigMagicFunc)(SV *, MAGIC *); + +#ifdef __cplusplus +extern "C" { +#endif +typedef int (*SwigMagicFuncHack)(SV *, MAGIC *); +#ifdef __cplusplus +} +#endif + + +#else +#define SWIG_MAGIC(a,b) (struct interpreter *interp, SV *a, MAGIC *b) +typedef int (*SwigMagicFunc)(struct interpreter *, SV *, MAGIC *); +#ifdef __cplusplus +extern "C" { +#endif +typedef int (*SwigMagicFuncHack)(struct interpreter *, SV *, MAGIC *); +#ifdef __cplusplus +} +#endif + +#endif +#endif + +#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) +#define PerlIO_exportFILE(fh,fl) (FILE*)(fh) +#endif + +/* Modifications for newer Perl 5.005 releases */ + +#if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) +#ifndef PL_sv_yes +#define PL_sv_yes sv_yes +#endif +#ifndef PL_sv_undef +#define PL_sv_undef sv_undef +#endif +#ifndef PL_na +#define PL_na na +#endif +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_NOINCLUDE + +#ifndef PERL_OBJECT +extern int SWIG_ConvertPtr(SV *, void **, swig_type_info *, int flags); +extern void SWIG_MakePtr(SV *, void *, swig_type_info *, int flags); +#else +extern int _SWIG_ConvertPtr(CPerlObj *, SV *, void **, swig_type_info *,int flags); +extern void _SWIG_MakePtr(CPerlObj *, SV *, void *, swig_type_info *, int flags); +#define SWIG_ConvertPtr(a,b,c,d) _SWIG_ConvertPtr(pPerl,a,b,c,d) +#define SWIG_MakePtr(a,b,c,d) _SWIG_MakePtr(pPerl,a,b,c,d) +#endif + +#else + +/* Function for getting a pointer value */ + +#ifndef PERL_OBJECT +SWIGRUNTIME(int) +SWIG_ConvertPtr(SV *sv, void **ptr, swig_type_info *_t, int flags) +#else +#define SWIG_ConvertPtr(a,b,c,d) _SWIG_ConvertPtr(pPerl,a,b,c,d) +SWIGRUNTIME(int) +_SWIG_ConvertPtr(CPerlObj *pPerl, SV *sv, void **ptr, swig_type_info *_t, int flags) +#endif +{ + char *_c; + swig_type_info *tc; + IV tmp; + + /* If magical, apply more magic */ + if (SvGMAGICAL(sv)) + mg_get(sv); + + /* Check to see if this is an object */ + if (sv_isobject(sv)) { + SV *tsv = (SV*) SvRV(sv); + if ((SvTYPE(tsv) == SVt_PVHV)) { + MAGIC *mg; + if (SvMAGICAL(tsv)) { + mg = mg_find(tsv,'P'); + if (mg) { + SV *rsv = mg->mg_obj; + if (sv_isobject(rsv)) { + tmp = SvIV((SV*)SvRV(rsv)); + } + } + } else { + return -1; + } + } else { + tmp = SvIV((SV*)SvRV(sv)); + } + if (!_t) { + *(ptr) = (void *) tmp; + return 0; + } + } else if (! SvOK(sv)) { /* Check for undef */ + *(ptr) = (void *) 0; + return 0; + } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ + *(ptr) = (void *) 0; + if (!SvROK(sv)) + return 0; + else + return -1; + } else { /* Don't know what it is */ + *(ptr) = (void *) 0; + return -1; + } + if (_t) { + /* Now see if the types match */ + _c = HvNAME(SvSTASH(SvRV(sv))); + tc = SWIG_TypeCheck(_c,_t); + if (!tc) { + *ptr = (void *) tmp; + return -1; + } + *ptr = SWIG_TypeCast(tc,(void *)tmp); + return 0; + } + *ptr = (void *) tmp; + return 0; +} +#ifndef PERL_OBJECT +SWIGRUNTIME(void) +SWIG_MakePtr(SV *sv, void *ptr, swig_type_info *t,int flags) +#else +#define SWIG_MakePtr(a,b,c,d) _SWIG_MakePtr(pPerl,a,b,c,d) +SWIGRUNTIME(void) +_SWIG_MakePtr(CPerlObj *pPerl, SV *sv, void *ptr, swig_type_info *t, int flags) +#endif +{ + sv_setref_pv(sv, (char *) t->name, ptr); +} + +#endif + +typedef XS(SwigPerlWrapper); +typedef SwigPerlWrapper *SwigPerlWrapperPtr; + +/* Structure for command table */ +typedef struct { + const char *name; + SwigPerlWrapperPtr wrapper; +} swig_command_info; + +/* Information for constant table */ + +#define SWIG_INT 1 +#define SWIG_FLOAT 2 +#define SWIG_STRING 3 +#define SWIG_POINTER 4 +#define SWIG_BINARY 5 + +/* Constant information structure */ +typedef struct swig_constant_info { + int type; + const char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_constant_info; + +#ifdef __cplusplus +} +#endif + +/* Structure for variable table */ +typedef struct { + const char *name; + SwigMagicFunc set; + SwigMagicFunc get; + swig_type_info **type; +} swig_variable_info; + +/* Magic variable code */ +#ifndef PERL_OBJECT +#define swig_create_magic(s,a,b,c) _swig_create_magic(s,a,b,c) + #ifndef MULTIPLICITY + static void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int \ +(*get)(SV *,MAGIC *)) { + #else + static void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*,\ + SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *)) { + #endif +#else +#define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c) +static void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *)) { +#endif + MAGIC *mg; + sv_magic(sv,sv,'U',(char *) name,strlen(name)); + mg = mg_find(sv,'U'); + mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL)); + mg->mg_virtual->svt_get = (SwigMagicFuncHack) get; + mg->mg_virtual->svt_set = (SwigMagicFuncHack) set; + mg->mg_virtual->svt_len = 0; + mg->mg_virtual->svt_clear = 0; + mg->mg_virtual->svt_free = 0; +} + + + + + diff --git a/Lib/perl5/ptrlang.i b/Lib/perl5/ptrlang.i deleted file mode 100644 index e0cee9cf4..000000000 --- a/Lib/perl5/ptrlang.i +++ /dev/null @@ -1,511 +0,0 @@ -// -// SWIG pointer conversion and utility library -// -// Dave Beazley -// April 19, 1997 -// -// Perl5 specific implementation. This file is included -// by the file ../pointer.i - -%{ -#include - -/* Types used by the library */ -static swig_type_info *SWIG_POINTER_int_p = 0; -static swig_type_info *SWIG_POINTER_short_p =0; -static swig_type_info *SWIG_POINTER_long_p = 0; -static swig_type_info *SWIG_POINTER_float_p = 0; -static swig_type_info *SWIG_POINTER_double_p = 0; -static swig_type_info *SWIG_POINTER_char_p = 0; -static swig_type_info *SWIG_POINTER_char_pp = 0; -static swig_type_info *SWIG_POINTER_void_p = 0; -%} - -%init %{ - SWIG_POINTER_int_p = SWIG_TypeQuery("int *"); - SWIG_POINTER_short_p = SWIG_TypeQuery("short *"); - SWIG_POINTER_long_p = SWIG_TypeQuery("long *"); - SWIG_POINTER_float_p = SWIG_TypeQuery("float *"); - SWIG_POINTER_double_p = SWIG_TypeQuery("double *"); - SWIG_POINTER_char_p = SWIG_TypeQuery("char *"); - SWIG_POINTER_char_pp = SWIG_TypeQuery("char **"); - SWIG_POINTER_void_p = SWIG_TypeQuery("void *"); -%} - -%{ - -/* #ifdef WIN32 -#undef isspace -#define isspace(c) (c == ' ') -#endif -*/ - -/*------------------------------------------------------------------ - ptrvalue(ptr,type = 0) - - Attempts to dereference a pointer value. If type is given, it - will try to use that type. Otherwise, this function will attempt - to "guess" the proper datatype by checking against all of the - builtin C datatypes. - ------------------------------------------------------------------ */ - -#ifdef PERL_OBJECT -static SV *_ptrvalue(CPerlObj *pPerl,SV *_PTRVALUE, int index, char *type) { -#define ptrvalue(a,b,c) _ptrvalue(pPerl,a,b,c) -#else -static SV *_ptrvalue(SV *_PTRVALUE, int index, char *type) { -#define ptrvalue(a,b,c) _ptrvalue(a,b,c) -#endif - - void *ptr; - SV *obj = 0; - - if (SWIG_ConvertPtr(_PTRVALUE, &ptr, 0) < 0) { - croak("Type error it ptrvalue. Argument is not a valid pointer value."); - } else { - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - - /* No datatype was passed. Type to figure out if it's a common one */ - - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_int_p) >= 0) { - type = "int"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_double_p) >= 0) { - type = "double"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_short_p) >= 0) { - type = "short"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_long_p) >= 0) { - type = "long"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_float_p) >= 0) { - type = "float"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_p) >= 0) { - type = "char"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_pp) >= 0) { - type = "char *"; - } else { - type = "unknown"; - } - } - - if (!ptr) { - croak("Unable to dereference NULL pointer."); - return 0; - } - - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - obj = sv_newmortal(); - sv_setiv(obj,(IV) *(((int *) ptr) + index)); - } else if (strcmp(type,"double") == 0) { - obj = sv_newmortal(); - sv_setnv(obj,(double) *(((double *) ptr)+index)); - } else if (strcmp(type,"short") == 0) { - obj = sv_newmortal(); - sv_setiv(obj,(IV) *(((short *) ptr) + index)); - } else if (strcmp(type,"long") == 0) { - obj = sv_newmortal(); - sv_setiv(obj,(IV) *(((long *) ptr) + index)); - } else if (strcmp(type,"float") == 0) { - obj = sv_newmortal(); - sv_setnv(obj,(double) *(((float *) ptr)+index)); - } else if (strcmp(type,"char") == 0) { - obj = sv_newmortal(); - sv_setpv(obj,((char *) ptr)+index); - } else if (strcmp(type,"char *") == 0) { - char *c = *(((char **) ptr)+index); - obj = sv_newmortal(); - if (c) - sv_setpv(obj,c); - else - sv_setpv(obj,"NULL"); - } else { - croak("Unable to dereference unsupported datatype."); - obj = 0; - } - } - return obj; -} - -/*------------------------------------------------------------------ - ptrcreate(type,value = 0,numelements = 1) - - Attempts to create a new object of given type. Type must be - a basic C datatype. Will not create complex objects. - ------------------------------------------------------------------ */ -#ifdef PERL_OBJECT -static SV *_ptrcreate(CPerlObj *pPerl, char *type, SV *value, int numelements) { -#define ptrcreate(a,b,c) _ptrcreate(pPerl,a,b,c) -#else -static SV *_ptrcreate(char *type, SV *value, int numelements) { -#define ptrcreate(a,b,c) _ptrcreate(a,b,c) -#endif - - void *ptr; - SV *obj; - int sz; - swig_type_info *cast = 0; - - /* Check the type string against a variety of possibilities */ - - if (strcmp(type,"int") == 0) { - sz = sizeof(int)*numelements; - cast = SWIG_POINTER_int_p; - } else if (strcmp(type,"short") == 0) { - sz = sizeof(short)*numelements; - cast = SWIG_POINTER_short_p; - } else if (strcmp(type,"long") == 0) { - sz = sizeof(long)*numelements; - cast = SWIG_POINTER_long_p; - } else if (strcmp(type,"double") == 0) { - sz = sizeof(double)*numelements; - cast = SWIG_POINTER_double_p; - } else if (strcmp(type,"float") == 0) { - sz = sizeof(float)*numelements; - cast = SWIG_POINTER_float_p; - } else if (strcmp(type,"char") == 0) { - sz = sizeof(char)*numelements; - cast = SWIG_POINTER_char_p; - } else if (strcmp(type,"char *") == 0) { - sz = sizeof(char *)*(numelements+1); - cast = SWIG_POINTER_char_pp; - } else if (strcmp(type,"void") == 0) { - sz = numelements; - cast = SWIG_POINTER_void_p; - } else { - croak("Unable to create unknown datatype."); - return 0; - } - - /* Create the new object */ - - ptr = (void *) malloc(sz); - if (!ptr) { - croak("Out of memory in ptrcreate."); - return 0; - } - - /* Now try to set its default value */ - - if (value) { - if (strcmp(type,"int") == 0) { - int *ip,i,ivalue; - ivalue = (int) SvIV(value); - ip = (int *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"short") == 0) { - short *ip,ivalue; - int i; - ivalue = (short) SvIV(value); - ip = (short *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"long") == 0) { - long *ip,ivalue; - int i; - ivalue = (long) SvIV(value); - ip = (long *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"double") == 0) { - double *ip,ivalue; - int i; - ivalue = (double) SvNV(value); - ip = (double *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"float") == 0) { - float *ip,ivalue; - int i; - ivalue = (float) SvNV(value); - ip = (float *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"char") == 0) { - char *ip,*ivalue; - ivalue = (char *) SvPV(value,PL_na); - ip = (char *) ptr; - strncpy(ip,ivalue,numelements-1); - } else if (strcmp(type,"char *") == 0) { - char **ip, *ivalue; - int i; - ivalue = (char *) SvPV(value,PL_na); - ip = (char **) ptr; - for (i = 0; i < numelements; i++) { - if (ivalue) { - ip[i] = (char *) malloc(strlen(ivalue)+1); - strcpy(ip[i],ivalue); - } else { - ip[i] = 0; - } - } - ip[numelements] = 0; - } - } - /* Create the pointer value */ - - - obj = sv_newmortal(); - SWIG_MakePtr(obj,ptr,cast); - return obj; -} - -/*------------------------------------------------------------------ - ptrset(ptr,value,index = 0,type = 0) - - Attempts to set the value of a pointer variable. If type is - given, we will use that type. Otherwise, we'll guess the datatype. - ------------------------------------------------------------------ */ - -#ifdef PERL_OBJECT -static void _ptrset(CPerlObj *pPerl,SV *_PTRVALUE, SV *value, int index, char *type) { -#define ptrset(a,b,c,d) _ptrset(pPerl,a,b,c,d) -#else -static void _ptrset(SV *_PTRVALUE, SV *value, int index, char *type) { -#define ptrset(a,b,c,d) _ptrset(a,b,c,d) -#endif - void *ptr; - SV *obj; - - - if (SWIG_ConvertPtr(_PTRVALUE, &ptr, 0) < 0) { - croak("Type error it ptrvalue. Argument is not a valid pointer value."); - } else { - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - /* No datatype was passed. Type to figure out if it's a common one */ - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_int_p) >= 0) { - type = "int"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_double_p) >= 0) { - type = "double"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_short_p) >= 0) { - type = "short"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_long_p) >= 0) { - type = "long"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_float_p) >= 0) { - type = "float"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_p) >= 0) { - type = "char"; - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_pp) >= 0) { - type = "char *"; - } else { - type = "unknown"; - } - } - } - if (!ptr) { - croak("Unable to set NULL pointer."); - return; - } - - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - *(((int *) ptr)+index) = (int) SvIV(value); - } else if (strcmp(type,"double") == 0) { - *(((double *) ptr)+index) = (double) SvNV(value); - } else if (strcmp(type,"short") == 0) { - *(((short *) ptr)+index) = (short) SvIV(value); - } else if (strcmp(type,"long") == 0) { - *(((long *) ptr)+index) = (long) SvIV(value); - } else if (strcmp(type,"float") == 0) { - *(((float *) ptr)+index) = (float) SvNV(value); - } else if (strcmp(type,"char") == 0) { - char *c = SvPV(value,PL_na); - strcpy(((char *) ptr)+index, c); - } else if (strcmp(type,"char *") == 0) { - char *c = SvPV(value,PL_na); - char **ca = (char **) ptr; - if (ca[index]) free(ca[index]); - if (strcmp(c,"NULL") == 0) { - ca[index] = 0; - } else { - ca[index] = (char *) malloc(strlen(c)+1); - strcpy(ca[index],c); - } - } else { - croak("Unable to set unsupported datatype."); - return; - } -} - -/*------------------------------------------------------------------ - ptradd(ptr,offset) - - Adds a value to an existing pointer value. Will do a type-dependent - add for basic datatypes. For other datatypes, will do a byte-add. - ------------------------------------------------------------------ */ - -#ifdef PERL_OBJECT -static SV *_ptradd(CPerlObj *pPerl, SV *_PTRVALUE, int offset) { -#define ptradd(a,b) _ptradd(pPerl,a,b) -#else -static SV *_ptradd(SV *_PTRVALUE, int offset) { -#define ptradd(a,b) _ptradd(a,b) -#endif - - void *ptr,*junk; - SV *obj; - swig_type_info *type; - char *tname; - - /* Try to handle a few common datatypes first */ - - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_int_p) >= 0) { - ptr = (void *) (((int *) ptr) + offset); - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_double_p) >= 0) { - ptr = (void *) (((double *) ptr) + offset); - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_short_p) >= 0) { - ptr = (void *) (((short *) ptr) + offset); - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_long_p) >= 0) { - ptr = (void *) (((long *) ptr) + offset); - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_float_p) >= 0) { - ptr = (void *) (((float *) ptr) + offset); - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_p) >= 0) { - ptr = (void *) (((char *) ptr) + offset); - } else if (SWIG_ConvertPtr(_PTRVALUE,&ptr,0) >= 0) { - ptr = (void *) (((char *) ptr) + offset); - } else { - croak("Type error in ptradd. Argument is not a valid pointer value."); - return 0; - } - printf("ptradd = %x\n", ptr); - tname = HvNAME(SvSTASH(SvRV(_PTRVALUE))); - obj = sv_newmortal(); - sv_setref_pv(obj,tname,ptr); - return obj; -} - -/*------------------------------------------------------------------ - ptrfree(ptr) - - Destroys a pointer value - ------------------------------------------------------------------ */ -#ifdef PERL_OBJECT -void _ptrfree(CPerlObj *pPerl, SV *_PTRVALUE) { -#define ptrfree(a) _ptrfree(pPerl, a) -#else -void _ptrfree(SV *_PTRVALUE) { -#define ptrfree(a) _ptrfree(a) -#endif - - void *ptr, *junk; - - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,0) < 0) { - croak("Type error in ptrfree. Argument is not a valid pointer value."); - return; - } - - /* Check to see if this pointer is a char ** */ - if (SWIG_ConvertPtr(_PTRVALUE,&junk,SWIG_POINTER_char_pp) >= 0) { - char **c = (char **) ptr; - if (c) { - int i = 0; - while (c[i]) { - free(c[i]); - i++; - } - } - } - if (ptr) - free((char *) ptr); -} - -%} - -%typemap(perl5,in) SV *ptr, SV *value { - $target = $source; -} - - -%typemap(perl5,out) SV *ptrcast, - SV *ptrvalue, - SV *ptrcreate, - SV *ptradd -{ - $target = $source; - argvi++; -} - -%typemap(perl5,ret) int ptrset { - if ($source == -1) return NULL; -} - -SV *ptrvalue(SV *ptr, int index = 0, char *type = 0); -// Returns the value that a pointer is pointing to (ie. dereferencing). -// The type is automatically inferred by the pointer type--thus, an -// integer pointer will return an integer, a double will return a double, -// and so on. The index and type fields are optional parameters. When -// an index is specified, this function returns the value of ptr[index]. -// This allows array access. When a type is specified, it overrides -// the given pointer type. Examples : -// -// ptrvalue($a) # Returns the value *a -// ptrvalue($a,10) # Returns the value a[10] -// ptrvalue($a,10,"double") # Returns a[10] assuming a is a double * - - -void ptrset(SV *ptr, SV *value, int index = 0, char *type = 0); -// Sets the value pointed to by a pointer. The type is automatically -// inferred from the pointer type so this function will work for -// integers, floats, doubles, etc... The index and type fields are -// optional. When an index is given, it provides array access. When -// type is specified, it overrides the given pointer type. Examples : -// -// ptrset($a,3) # Sets the value *a = 3 -// ptrset($a,3,10) # Sets a[10] = 3 -// ptrset($a,3,10,"int") # Sets a[10] = 3 assuming a is a int * - - -SV *ptrcreate(char *type, SV *value = 0, int nitems = 1); -// Creates a new object and returns a pointer to it. This function -// can be used to create various kinds of objects for use in C functions. -// type specifies the basic C datatype to create and value is an -// optional parameter that can be used to set the initial value of the -// object. nitems is an optional parameter that can be used to create -// an array. This function results in a memory allocation using -// malloc(). Examples : -// -// $a = ptrcreate("double") # Create a new double, return pointer -// $a = ptrcreate("int",7) # Create an integer, set value to 7 -// $a = ptrcreate("int",0,1000) # Create an integer array with initial -// # values all set to zero -// -// This function only recognizes a few common C datatypes as listed below : -// -// int, short, long, float, double, char, char *, void -// -// All other datatypes will result in an error. However, other -// datatypes can be created by using the ptrcast function. For -// example: -// -// $a = ptrcast(ptrcreate("int",0,100),"unsigned int *") - - -void ptrfree(SV *ptr); -// Destroys the memory pointed to by ptr. This function calls free() -// and should only be used with objects created by ptrcreate(). Since -// this function calls free, it may work with other objects, but this -// is generally discouraged unless you absolutely know what you're -// doing. - -SV *ptradd(SV *ptr, int offset); -// Adds a value to the current pointer value. For the C datatypes of -// int, short, long, float, double, and char, the offset value is the -// number of objects and works in exactly the same manner as in C. For -// example, the following code steps through the elements of an array -// -// $a = ptrcreate("double",0,100); # Create an array double a[100] -// $b = $a; -// for ($i = 0; $i < 100; $i++) { -// ptrset($b,0.0025*$i); # set *b = 0.0025*i -// $b = ptradd($b,1); # b++ (go to next double) -// } -// -// In this case, adding one to b goes to the next double. -// -// For all other datatypes (including all complex datatypes), the -// offset corresponds to bytes. This function does not perform any -// bounds checking and negative offsets are perfectly legal. - - - diff --git a/Lib/perl5/std_string.i b/Lib/perl5/std_string.i new file mode 100644 index 000000000..e16ee012e --- /dev/null +++ b/Lib/perl5/std_string.i @@ -0,0 +1,69 @@ +// +// SWIG typemaps for std::string +// Roy M. LeCates +// October 23, 2002 +// +// Perl implementation + + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + /* Overloading check */ + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string { + if (!SvPOK((SV*) $input)) { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected a string"); + } else { + STRLEN len; + const char *ptr = SvPV($input, len); + $1.assign(ptr, len); + } + } + + %typemap(in) string *INPUT(std::string temp), + const string & (std::string temp) { + if (!SvPOK((SV*) $input)) { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected a string"); + } else { + STRLEN len; + const char *ptr = SvPV($input, len); + temp.assign(ptr, len); + $1 = &temp; + } + } + + %typemap(out) string { + if (argvi >= items) EXTEND(sp, 1); // bump stack ptr, if needed + char *data = const_cast($1.data()); + sv_setpvn($result = sv_newmortal(), data, $1.size()); + ++argvi; + } + + %typemap(out) const string & { + if (argvi >= items) EXTEND(sp, 1); // bump stack ptr, if needed + char *data = const_cast($1->data()); + sv_setpvn($result = sv_newmortal(), data, $1->size()); + ++argvi; + } + +} + diff --git a/Lib/perl5/std_vector.i b/Lib/perl5/std_vector.i new file mode 100644 index 000000000..aaf1b858b --- /dev/null +++ b/Lib/perl5/std_vector.i @@ -0,0 +1,297 @@ +// +// SWIG typemaps for std::vector types +// Luigi Ballabio +// May 7, 2002 +// Chris Seatory +// August 5, 2002 +// +// Perl implementation + +%include exception.i + +// containers + +// methods which can raise are caused to throw an IndexError +%exception std::vector::get { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::set { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Perl as much as possible, namely, to allow the user to pass and +// be returned Perl lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Perl sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Perl sequence of T:s +// is returned which is most easily used in other Perl functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class vector { + %typemap(in) vector (std::vector* v) { + if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + SV **tv; + I32 len = av_len(av) + 1; + T* obj; + for (int i=0; i& (std::vector temp, + std::vector* v), + const vector* (std::vector temp, + std::vector* v) { + if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + SV **tv; + I32 len = av_len(av) + 1; + T* obj; + for (int i=0; i { + int len = $1.size(); + SV **svs = new SV*[len]; + for (unsigned int i=0; iat(i)), + $descriptor(T *), 0); + } + AV *myav = av_make(len, svs); + delete[] svs; + $result = newRV_noinc((SV*) myav); + sv_2mortal($result); + argvi++; + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + SV **tv; + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* obj; + tv = av_fetch(av, 0, 0); + if (SWIG_ConvertPtr(*tv, (void **)&obj, + $descriptor(T *),0) != -1) + $1 = 1; + else + $1 = 0; + } + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_&descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + SV **tv; + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* obj; + tv = av_fetch(av, 0, 0); + if (SWIG_ConvertPtr(*tv, (void **)&obj, + $descriptor(T *),0) != -1) + $1 = 1; + else + $1 = 0; + } + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(const T& x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& get(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + // add specialized typemaps here + public: + vector(); + vector(unsigned int size, const T& value=T()); + vector(const vector &); + + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T get(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i= items) { EXTEND(sp,1); } - $target = sv_newmortal(); - sv_setiv($target,(IV) *($source)); + $result = sv_newmortal(); + sv_setiv($result,(IV) *($1)); argvi++; } -%typemap(perl5,argout) float *OUTPUT, - double *OUTPUT +%typemap(argout) unsigned int *OUTPUT, unsigned int &OUTPUT, + unsigned short *OUTPUT, unsigned short &OUTPUT, + unsigned long *OUTPUT, unsigned long &OUTPUT, + unsigned char *OUTPUT, unsigned char &OUTPUT { if (argvi >= items) { EXTEND(sp,1); } - $target = sv_newmortal(); - sv_setnv($target,(double) *($source)); + $result = sv_newmortal(); + sv_setuv($result,(UV) *($1)); argvi++; } -// BOTH + + +%typemap(argout) float *OUTPUT, float &OUTPUT, + double *OUTPUT, double &OUTPUT +{ + if (argvi >= items) { + EXTEND(sp,1); + } + $result = sv_newmortal(); + sv_setnv($result,(double) *($1)); + argvi++; +} + +// INOUT // Mappings for an argument that is both an input and output // parameter - -#ifdef AUTODOC -%subsection "Input/Output Methods" - -%text %{ +/* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a Tcl list. +returned in the form of a Perl array. - int *BOTH - short *BOTH - long *BOTH - unsigned int *BOTH - unsigned short *BOTH - unsigned long *BOTH - unsigned char *BOTH - float *BOTH - double *BOTH + int *INOUT + short *INOUT + long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned char *INOUT + float *INOUT + double *INOUT For example, suppose you were trying to wrap the following function : @@ -247,12 +207,12 @@ For example, suppose you were trying to wrap the following function : You could wrap it with SWIG as follows : %include typemaps.i - void neg(double *BOTH); + void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i - %apply double *BOTH { double *x }; + %apply double *INOUT { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value. @@ -262,38 +222,61 @@ do this : $x = neg($x); -%} +*/ -#endif +%typemap(in) int *INOUT = int *INPUT; +%typemap(in) short *INOUT = short *INPUT; +%typemap(in) long *INOUT = long *INPUT; +%typemap(in) unsigned *INOUT = unsigned *INPUT; +%typemap(in) unsigned short *INOUT = unsigned short *INPUT; +%typemap(in) unsigned long *INOUT = unsigned long *INPUT; +%typemap(in) unsigned char *INOUT = unsigned char *INPUT; +%typemap(in) signed char *INOUT = signed char *INPUT; +%typemap(in) bool *INOUT = bool *INPUT; +%typemap(in) float *INOUT = float *INPUT; +%typemap(in) double *INOUT = double *INPUT; -%typemap(perl5,in) int *BOTH = int *INPUT; -%typemap(perl5,in) short *BOTH = short *INPUT; -%typemap(perl5,in) long *BOTH = long *INPUT; -%typemap(perl5,in) unsigned *BOTH = unsigned *INPUT; -%typemap(perl5,in) unsigned short *BOTH = unsigned short *INPUT; -%typemap(perl5,in) unsigned long *BOTH = unsigned long *INPUT; -%typemap(perl5,in) unsigned char *BOTH = unsigned char *INPUT; -%typemap(perl5,in) float *BOTH = float *INPUT; -%typemap(perl5,in) double *BOTH = double *INPUT; +%typemap(in) int &INOUT = int &INPUT; +%typemap(in) short &INOUT = short &INPUT; +%typemap(in) long &INOUT = long &INPUT; +%typemap(in) unsigned &INOUT = unsigned &INPUT; +%typemap(in) unsigned short &INOUT = unsigned short &INPUT; +%typemap(in) unsigned long &INOUT = unsigned long &INPUT; +%typemap(in) unsigned char &INOUT = unsigned char &INPUT; +%typemap(in) signed char &INOUT = signed char &INPUT; +%typemap(in) bool &INOUT = bool &INPUT; +%typemap(in) float &INOUT = float &INPUT; +%typemap(in) double &INOUT = double &INPUT; -%typemap(perl5,argout) int *BOTH = int *OUTPUT; -%typemap(perl5,argout) short *BOTH = short *OUTPUT; -%typemap(perl5,argout) long *BOTH = long *OUTPUT; -%typemap(perl5,argout) unsigned *BOTH = unsigned *OUTPUT; -%typemap(perl5,argout) unsigned short *BOTH = unsigned short *OUTPUT; -%typemap(perl5,argout) unsigned long *BOTH = unsigned long *OUTPUT; -%typemap(perl5,argout) unsigned char *BOTH = unsigned char *OUTPUT; -%typemap(perl5,argout) float *BOTH = float *OUTPUT; -%typemap(perl5,argout) double *BOTH = double *OUTPUT; + +%typemap(argout) int *INOUT = int *OUTPUT; +%typemap(argout) short *INOUT = short *OUTPUT; +%typemap(argout) long *INOUT = long *OUTPUT; +%typemap(argout) unsigned *INOUT = unsigned *OUTPUT; +%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; +%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; +%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; +%typemap(argout) signed char *INOUT = signed char *OUTPUT; +%typemap(argout) bool *INOUT = bool *OUTPUT; +%typemap(argout) float *INOUT = float *OUTPUT; +%typemap(argout) double *INOUT = double *OUTPUT; + +%typemap(argout) int &INOUT = int &OUTPUT; +%typemap(argout) short &INOUT = short &OUTPUT; +%typemap(argout) long &INOUT = long &OUTPUT; +%typemap(argout) unsigned &INOUT = unsigned &OUTPUT; +%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; +%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; +%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; +%typemap(argout) signed char &INOUT = signed char &OUTPUT; +%typemap(argout) bool &INOUT = bool &OUTPUT; +%typemap(argout) float &INOUT = float &OUTPUT; +%typemap(argout) double &INOUT = double &OUTPUT; // REFERENCE // Accept Perl references as pointers - -#ifdef AUTODOC -%subsection "Reference Methods" - -%text %{ +/* The following methods make Perl references work like simple C pointers. References can only be used for simple input/output values, not C arrays however. It should also be noted that @@ -327,149 +310,207 @@ or you can use the %apply directive : %apply double *REFERENCE { double *x }; void neg(double *x); -Unlike the BOTH mapping described previous, this approach directly +Unlike the INOUT mapping described previous, this approach directly modifies the value of a Perl reference. Thus, you could use it as follows : $x = 3; neg(\$x); print "$x\n"; # Should print out -3. -%} -#endif +*/ -%typemap(perl5,in) double *REFERENCE (double dvalue) +%typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { printf("Received %d\n", SvTYPE(tempsv)); - croak("Expected a double reference."); + SWIG_croak("Expected a double reference."); } dvalue = SvNV(tempsv); - $target = &dvalue; + $1 = &dvalue; } -%typemap(perl5,in) float *REFERENCE (float dvalue) +%typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { - croak("expected a double reference"); + SWIG_croak("expected a double reference"); } dvalue = (float) SvNV(tempsv); - $target = &dvalue; + $1 = &dvalue; } -%typemap(perl5,in) int *REFERENCE (int dvalue) +%typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if (!SvIOK(tempsv)) { - croak("expected a integer reference"); + SWIG_croak("expected a integer reference"); } dvalue = SvIV(tempsv); - $target = &dvalue; + $1 = &dvalue; } -%typemap(perl5,in) short *REFERENCE (short dvalue) +%typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if (!SvIOK(tempsv)) { - croak("expected a integer reference"); + SWIG_croak("expected a integer reference"); } dvalue = (short) SvIV(tempsv); - $target = &dvalue; + $1 = &dvalue; } -%typemap(perl5,in) long *REFERENCE (long dvalue) +%typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if (!SvIOK(tempsv)) { - croak("expected a integer reference"); + SWIG_croak("expected a integer reference"); } dvalue = (long) SvIV(tempsv); - $target = &dvalue; + $1 = &dvalue; } -%typemap(perl5,in) unsigned int *REFERENCE (unsigned int dvalue) +%typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if (!SvIOK(tempsv)) { - croak("expected a integer reference"); + SWIG_croak("expected a integer reference"); } - dvalue = (unsigned int) SvIV(tempsv); - $target = &dvalue; + dvalue = (unsigned int) SvUV(tempsv); + $1 = &dvalue; } -%typemap(perl5,in) unsigned short *REFERENCE (unsigned short dvalue) +%typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if (!SvIOK(tempsv)) { - croak("expected a integer reference"); + SWIG_croak("expected a integer reference"); } - dvalue = (unsigned short) SvIV(tempsv); - $target = &dvalue; + dvalue = (unsigned short) SvUV(tempsv); + $1 = &dvalue; } -%typemap(perl5,in) unsigned long *REFERENCE (unsigned long dvalue) +%typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue) { SV *tempsv; - if (!SvROK($source)) { - croak("expected a reference"); + if (!SvROK($input)) { + SWIG_croak("expected a reference"); } - tempsv = SvRV($source); + tempsv = SvRV($input); if (!SvIOK(tempsv)) { - croak("expected a integer reference"); + SWIG_croak("expected a integer reference"); } - dvalue = (unsigned long) SvIV(tempsv); - $target = &dvalue; + dvalue = (unsigned long) SvUV(tempsv); + $1 = &dvalue; } -%typemap(perl5,argout) double *REFERENCE, - float *REFERENCE +%typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue) +{ + SV *tempsv; + if (!SvROK($input)) { + SWIG_croak("expected a reference"); + } + tempsv = SvRV($input); + if (!SvIOK(tempsv)) { + SWIG_croak("expected a integer reference"); + } + dvalue = (unsigned char) SvUV(tempsv); + $1 = &dvalue; +} + +%typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue) +{ + SV *tempsv; + if (!SvROK($input)) { + SWIG_croak("expected a reference"); + } + tempsv = SvRV($input); + if (!SvIOK(tempsv)) { + SWIG_croak("expected a integer reference"); + } + dvalue = (signed char) SvIV(tempsv); + $1 = &dvalue; +} + +%typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue) +{ + SV *tempsv; + if (!SvROK($input)) { + SWIG_croak("expected a reference"); + } + tempsv = SvRV($input); + if (!SvIOK(tempsv)) { + SWIG_croak("expected a integer reference"); + } + dvalue = (bool) SvIV(tempsv); + $1 = &dvalue; +} + +%typemap(argout) double *REFERENCE, double &REFERENCE, + float *REFERENCE, float &REFERENCE { SV *tempsv; tempsv = SvRV($arg); - sv_setnv(tempsv, (double) *$source); + sv_setnv(tempsv, (double) *$1); } -%typemap(perl5,argout) int *REFERENCE, - short *REFERENCE, - long *REFERENCE, - unsigned int *REFERENCE, - unsigned short *REFERENCE, - unsigned long *REFERENCE +%typemap(argout) int *REFERENCE, int &REFERENCE, + short *REFERENCE, short &REFERENCE, + long *REFERENCE, long &REFERENCE, + signed char *REFERENCE, unsigned char &REFERENCE, + bool *REFERENCE, bool &REFERENCE { SV *tempsv; - tempsv = SvRV($arg); - sv_setiv(tempsv, (int) *$source); + tempsv = SvRV($input); + sv_setiv(tempsv, (IV) *$1); } -// -------------------------------------------------------------------- -// Special types -// -// -------------------------------------------------------------------- +%typemap(argout) unsigned int *REFERENCE, unsigned int &REFERENCE, + unsigned short *REFERENCE, unsigned short &REFERENCE, + unsigned long *REFERENCE, unsigned long &REFERENCE, + unsigned char *REFERENCE, unsigned char &REFERENCE +{ + SV *tempsv; + tempsv = SvRV($input); + sv_setuv(tempsv, (UV) *$1); +} +/* Overloading information */ + +%typemap(typecheck) double *INOUT = double; +%typemap(typecheck) bool *INOUT = bool; +%typemap(typecheck) signed char *INOUT = signed char; +%typemap(typecheck) unsigned char *INOUT = unsigned char; +%typemap(typecheck) unsigned long *INOUT = unsigned long; +%typemap(typecheck) unsigned short *INOUT = unsigned short; +%typemap(typecheck) unsigned int *INOUT = unsigned int; +%typemap(typecheck) long *INOUT = long; +%typemap(typecheck) short *INOUT = short; +%typemap(typecheck) int *INOUT = int; +%typemap(typecheck) float *INOUT = float; diff --git a/Lib/php4/php4.swg b/Lib/php4/php4.swg new file mode 100644 index 000000000..81bb482b7 --- /dev/null +++ b/Lib/php4/php4.swg @@ -0,0 +1,498 @@ +/* + * php4.swg + * + * PHP 4 configuration file + * + */ + +%runtime "common.swg" // common type checking code +%runtime "php4run.swg" // Php4 runtime functions +%include "utils.i" // building blocks + +/* Typemaps for input parameters by value */ + +%typemap(in) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE %{ + convert_to_long_ex($input); + $1 = ($1_ltype) Z_LVAL_PP($input); +%} + +%typemap(in) bool %{ + convert_to_boolean_ex($input); + $1 = ($1_ltype) Z_LVAL_PP($input); +%} + +%typemap(in) char %{ + convert_to_string_ex($input); + $1 = ($1_ltype) *Z_STRVAL_PP($input); +%} + +%typemap(in) float,double %{ + convert_to_double_ex($input); + $1 = ($1_ltype) Z_DVAL_PP($input); +%} + +// char * is input only normally +%typemap(in) char * %{ + convert_to_string_ex($input); + $1 = ($1_ltype) Z_STRVAL_PP($input); +%} + +// char array can be in/out, though the passed string may not be big enough... +// so we have to size it +strarray_inout(char [ANY]) + +%typemap(in) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & %{ + if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { + zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s", $argnum-argbase, $1_descriptor->name); + } +%} + +%typemap(in) void * %{ + if(SWIG_ConvertPtr(*$input, (void **) &$1, 0) < 0) { + /* Allow NULL from php for void* */ + if ((*$input)->type==IS_NULL) $1=0; + else zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s", $argnum-argbase, $1_descriptor->name); + } +%} + +/* Special case when void* is passed by reference so it can be made to point + to opaque api structs */ +%typemap(in) void ** ($*1_ltype ptr, int force), void *& ($*1_ltype ptr, int force) %{ + /* If they pass NULL by reference, make it into a void* + This bit should go in arginit if arginit support init-ing scripting args */ + if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { + /* So... we didn't get a ref or ptr, but we'll accept NULL by reference */ + if ((*$input)->type==IS_NULL && PZVAL_IS_REF(*$input)) { +#if __cplusplus + ptr=new $*1_ltype; +#else + ptr=($*1_ltype) calloc(1,sizeof($*1_ltype)); +#endif + $1=&ptr; + /* have to passback arg$arg too */ + force=1; + } else { /* wasn't a pre/ref/thing, OR anything like an int thing */ + force=0; + zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s or %s or at least NULL passed by reference", $argnum-argbase, $1_descriptor->name,$*1_descriptor->name); + } + } else force=0; +%} + +%typemap(argout) void **, void *& %{ + if (force$argnum) { /* pass back arg$argnum through params ($arg) if we can */ + if(! PZVAL_IS_REF(*$arg)) { + zend_error(E_WARNING, "Parameter %d of $symname wasn't passed by reference: [argout void**, void*&]",$argnum-argbase); + } else { + SWIG_SetPointerZval(*$arg, (void *) ptr$argnum, $*1_descriptor, 1); + } + } +%} + +/* Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE { + $&1_ltype argp; + if(SWIG_ConvertPtr(*$input, (void **) &argp, $&1_descriptor) < 0) { + zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s", $argnum-argbase, $&1_descriptor->name); + } + $1 = *argp; +} + +/* Typemap for output values */ + +%typemap(out) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE %{ + ZVAL_LONG(return_value,$1); +%} + +%typemap(out) bool %{ + ZVAL_BOOL(return_value,($1)?1:0); +%} + +%typemap(out) float, double %{ + ZVAL_DOUBLE(return_value,$1); +%} + +%typemap(out) char %{ + // out char + ZVAL_STRINGL(return_value,$1, 1, 1); +%} + +%typemap(out) char * %{ + ZVAL_STRING(return_value,$1, 1); +%} + +%typemap(out) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & %{ + SWIG_SetPointerZval(return_value, (void *)$1, $1_descriptor, $owner); +%} + +%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); + SWIG_SetPointerZval(return_value, (void *)$1, ty, $owner); +} + +%typemap(out) SWIGTYPE +#ifdef __cplusplus +{ + $&1_ltype resultobj = new $1_ltype(($1_ltype &) $1); + SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, $owner); +} +#else +{ + $&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type)); + memmove(resultobj, &$1, sizeof($1_type)); + SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, $owner); +} +#endif + +%typemap(out) void ""; + +/* Typemap for character array returns */ + +%typemap(out) char [ANY] { + // out char any + ZVAL_STRINGL(return_value,$1, $1_dim0, 1); +} + +/* Typemap for in/argout references + NOTE: we don't choose to use these for arrays yet, maybe later */ + +%typemap_inout_ord(bool,convert_to_bool_ex,ZVAL_BOOL) +%typemap_inout_ord(int,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(unsigned int,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(short,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(unsigned short,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(long,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(unsigned long,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(signed char,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(unsigned char,convert_to_long_ex,ZVAL_LONG) +%typemap_inout_ord(enum SWIGTYPE,convert_to_long_ex,ZVAL_LONG) + +/* Global variables - add the variable to PHP */ + +%typemap(varinit) char * +{ + zval *z_var; + MAKE_STD_ZVAL(z_var); + z_var->type = IS_STRING; + if($1) { + z_var->value.str.val = estrdup($1); + z_var->value.str.len = strlen($1); + } else { + z_var->value.str.val = 0; + z_var->value.str.len = 0; + } + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); +} + +%typemap(varinit) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE +{ + zval *z_var; + MAKE_STD_ZVAL(z_var); + z_var->type = IS_LONG; + z_var->value.lval = $1; + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); +} + +%typemap(varinit) bool +{ + zval *z_var; + MAKE_STD_ZVAL(z_var); + z_var->type = IS_BOOL; + z_var->value.lval = ($1)?1:0; + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); +} + +%typemap(varinit) float, double +{ + zval *z_var; + MAKE_STD_ZVAL(z_var); + z_var->type = IS_DOUBLE; + z_var->value.dval = $1; + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, + sizeof(zval *), NULL); +} + +%typemap(varinit) char +{ + zval *z_var; + char c[2]; + MAKE_STD_ZVAL(z_var); + c[0] = $1; + c[1] = 0; + z_var->type = IS_STRING; + z_var->value.str.val = estrdup(c); + z_var->value.str.len = 2; + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, + sizeof(zval *), NULL); +} + +%typemap(varinit) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] +{ + zval *z_var; + MAKE_STD_ZVAL(z_var); + SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, $owner); + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, + sizeof(zval *), NULL); +} + +%typemap(varinit) SWIGTYPE +{ + $&1_ltype argp; + zval *z_var; + + MAKE_STD_ZVAL(z_var); + SWIG_SetPointerZval(z_var, (void*)&$1, $&1_descriptor, $owner); + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void*)&z_var, + sizeof(zval *), NULL); +} + +%typemap(varinit) char [ANY] +{ + zval *z_var; + MAKE_STD_ZVAL(z_var); + z_var->type = IS_STRING; + if($1) { + // varinit char [ANY] + ZVAL_STRINGL(z_var,$1, $1_dim0, 1); + } + zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void*)&z_var, + sizeof(zval *), NULL); +} + +%typemap(varin) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1",strlen("$1")+1, (void**)&z_var); + convert_to_long_ex(z_var); + if($1 != ($1_ltype)((*z_var)->value.lval)) { + $1 = Z_LVAL_PP(z_var); + } +} + +%typemap(varin) bool +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1",strlen("$1")+1, (void**)&z_var); + convert_to_boolean_ex(z_var); + if($1 != ($1_ltype)((*z_var)->value.lval)) { + $1 = Z_LVAL_PP(z_var); + } +} + +%typemap(varin) double,float +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + convert_to_double_ex(z_var); + if($1 != ($1_ltype)((*z_var)->value.dval)) { + $1 = Z_DVAL_PP(z_var); + } +} + +%typemap(varin) char +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1",strlen("$1")+1, (void**)&z_var); + convert_to_string_ex(z_var); + if($1 != *((*z_var)->value.str.val)) { + $1 = *((*z_var)->value.str.val); + } +} + +%typemap(varin) char * +{ + zval **z_var; + char *s1; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + convert_to_string_ex(z_var); + s1 = Z_STRVAL_PP(z_var); + if((s1 == NULL) || ($1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1))) { + if(s1) + $1 = estrdup(s1); + else + $1 = NULL; + } +} + + +%typemap(varin) SWIGTYPE [] +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if($1) { + SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, $owner); + } +} + +%typemap(varin) char [ANY] +{ + zval **z_var; + char *s1; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + s1 = Z_STRVAL_PP(z_var); + if((s1 == NULL) || ($1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1))) { + if(s1) + strncpy($1, s1, $1_dim0); + } +} + +%typemap(varin) SWIGTYPE +{ + zval **z_var; + $&1_ltype _temp; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if (SWIG_ConvertPtr(*z_var, (void**)&_temp, $&1_descriptor) < 0) { + zend_error(E_ERROR, "Type error in value of $symname. Expected %s", $&1_descriptor->name); + } + + $1 = *($&1_ltype)_temp; + +} + +%typemap(varin) SWIGTYPE *, SWIGTYPE & +{ + zval **z_var; + $1_ltype _temp; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if (SWIG_ConvertPtr(*z_var, (void **)&_temp, $1_descriptor) < 0) { + zend_error(E_ERROR, "Type error in value of $symname. Expected %s", $1_descriptor->name); + } + + $1 = ($1_ltype)_temp; +} + +%typemap(varout) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE +{ + zval **z_var; + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if($1 != ($1_ltype)((*z_var)->value.lval)) { + (*z_var)->value.lval = (long)$1; + } +} + +//SAMFIX need to cast zval->type, what if zend-hash_find fails? etc? +%typemap(varout) bool +{ + zval **z_var; + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if($1 != ($1_ltype)((*z_var)->value.lval)) { + (*z_var)->value.lval = (long)$1; + } +} + +%typemap(varout) double, float +{ + zval **z_var; + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if($1 != ($1_ltype)((*z_var)->value.dval)) { + (*z_var)->value.dval = (double)$1; + } +} + +%typemap(varout) char +{ + zval **z_var; + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if($1 != *((*z_var)->value.str.val)) { + char c[2]; + efree((*z_var)->value.str.val); + c[0] = $1; + c[1] = 0; + (*z_var)->value.str.val = estrdup(c); + } +} + +%typemap(varout) char * +{ + zval **z_var; + char *s1; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + s1 = Z_STRVAL_PP(z_var); + if((s1 == NULL) || ($1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1) )) { + if(s1) + efree(s1); + if($1) { + (*z_var)->value.str.val = estrdup($1); + (*z_var)->value.str.len = strlen($1) +1; + } else { + (*z_var)->value.str.val = 0; + (*z_var)->value.str.len = 0; + } + } +} + +%typemap(varout) SWIGTYPE +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + SWIG_SetPointerZval(*z_var, (void*)&$1, $&1_descriptor, $owner); +} + +%typemap(varout) SWIGTYPE [] +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + if($1) + SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, $owner); +} + +%typemap(varout) char [ANY] +{ + zval **z_var; + char *s1; +deliberate error cos this code looks bogus to me + zend_hash_find(&EG(symbol_table), "$1" ,strlen("$1")+1, (void**)&z_var); + s1 = Z_STRVAL_PP(z_var); + if((s1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1))) { + + if($1) { + (*z_var)->value.str.val = estrdup($1); + (*z_var)->value.str.len = strlen($1)+1; + } else { + (*z_var)->value.str.val = 0; + (*z_var)->value.str.len = 0; + } + } +} + +%typemap(varout) SWIGTYPE *, SWIGTYPE & +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); + SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, $owner); +} + + + +/* Typemaps for constants */ + +%typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE + "REGISTER_LONG_CONSTANT( \"$symname\", $value, CONST_CS | CONST_PERSISTENT);"; + +%typemap(consttab) float, double + "REGISTER_DOUBLE_CONSTANT(\"$symname\", $value, CONST_CS | CONST_PERSISTENT);"; + +%typemap(consttab) char, char * + "REGISTER_STRING_CONSTANT(\"$symname\", \"$value\", CONST_CS | CONST_PERSISTENT);"; + +%typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + char *cp; + SWIG_SetPointerChar(&cp, (void*)$value, $1_descriptor); + REGISTER_STRING_CONSTANT("$symname", cp, CONST_CS | CONST_PERSISTENT); +} + +/* Some ANSI C typemaps */ + +%apply long { size_t }; diff --git a/Lib/php4/php4run.swg b/Lib/php4/php4run.swg new file mode 100644 index 000000000..fd6737219 --- /dev/null +++ b/Lib/php4/php4run.swg @@ -0,0 +1,240 @@ +/* + * php4.swg + * + * PHP4 runtime library + * + */ + +#ifdef __cplusplus +extern "C" { +#endif +#include "zend.h" +#include "zend_API.h" +#include "php.h" + +/* These TSRMLS_ stuff should already be defined now, but with older php under + redhat are not... */ +#ifndef TSRMLS_D +#define TSRMLS_D +#endif +#ifndef TSRMLS_DC +#define TSRMLS_DC +#endif +#ifndef TSRMLS_C +#define TSRMLS_C +#endif +#ifndef TSRMLS_CC +#define TSRMLS_CC +#endif + +#ifdef __cplusplus +} +#endif + +/* used to wrap returned objects in so we know whether they are newobject + and need freeing, or not */ +typedef struct _swig_object_wrapper { + void * ptr; + int newobject; +} swig_object_wrapper; + +/* local scope self_constructors are set to 1 inside function wrappers + which are also class constructors, so that the php4.swg output typemaps + know whether or not to wrap returned objects in this_ptr or a new object */ +int self_constructor=0; + +/* empty zend destructor for types without one */ +static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) {}; + +/* This one makes old swig style string pointers but the php module doesn't + use these any more. This is just left here for old times sake and may go */ +SWIGRUNTIME(void) +SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) { + static char hex[17] = "0123456789abcdef"; + unsigned long p, s; + char data[32], *r; + + r = data; + p = (unsigned long) ptr; + if (p > 0) { + while (p > 0) { + s = p & 0xf; + *(r++) = hex[s]; + p = p >> 4; + } + *r = '_'; + while (r >= data) { + *(c++) = *(r--); + } + strcpy (c, ty->name); + } else { + strcpy (c, "NULL"); + } +} + +SWIGRUNTIME(void) +SWIG_SetPointerChar(char **c, void *ptr, swig_type_info *type) { + char data[512]; + + SWIG_MakePtr(data, ptr, type); + *c = estrdup(data); +} + +#define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d, SWIG_module_entry TSRMLS_CC) + +SWIGRUNTIME(void) +SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject, zend_module_entry* module_entry TSRMLS_DC) { + swig_object_wrapper *value=NULL; + /* No need to call SWIG_MakePtr here! */ + if (type->clientdata) { + if (! (*(int *)(type->clientdata))) zend_error(E_ERROR, "Type: %s failed to register with zend",type->name); + value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper)); + value->ptr=ptr; + value->newobject=newobject; + ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata)); + return; + } else { /* have to deal with old fashioned string pointer? + but this should not get this far */ + zend_error(E_ERROR, "Type: %s not registered with zend",type->name); + } +} + +/* This old-style routine converts an old string-pointer c into a real pointer + ptr calling making appropriate casting functions according to ty + We don't use this any more */ +SWIGRUNTIME(int) +_SWIG_ConvertPtr(char *c, void **ptr, swig_type_info *ty) { + register int d; + unsigned long p; + swig_type_info *tc; + + if(c == NULL) { + *ptr = 0; + return 0; + } + + p = 0; + if (*c != '_') { + *ptr = (void *) 0; + if (strcmp(c,"NULL") == 0) { + return 0; + } else { + goto type_error; + } + } + + c++; + /* Extract hex value from pointer */ + while ((d = *c)) { + if ((d >= '0') && (d <= '9')) + p = (p << 4) + (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + p = (p << 4) + (d - ('a'-10)); + else + break; + c++; + } + *ptr = (void *) p; + + if(ty) { + tc = SWIG_TypeCheck(c,ty); + if(!tc) goto type_error; + *ptr = SWIG_TypeCast(tc, (void*)p); + } + return 0; + +type_error: + + return -1; +} + +/* This is a new pointer conversion routine + Taking the native pointer p (which would have been converted from the old + string pointer) and it's php type id, and it's type name (which also would + have come from the old string pointer) it converts it to ptr calling + appropriate casting functions according to ty + Sadly PHP has no API to find a type name from a type id, only from an instance + of a resource of the type id, so we have to pass type_name as well. + The two functions which might call this are: + SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource + and the registered zend destructors for which we have one per type each + with the type name hard wired in. */ +SWIGRUNTIME(int) +SWIG_ZTS_ConvertResourceData(void * p, int type, const char *type_name, void **ptr, swig_type_info *ty TSRMLS_DC) { + swig_type_info *tc; + + if (ty) { + if (! type_name) { + /* can't convert p to ptr type ty if we don't know what type p is */ + return -1; + } else { + /* convert and cast p from type_name to ptr as ty + Need to sort out const-ness, can SWIG_TypeCast really not take a const? */ + tc = SWIG_TypeCheck((char *)type_name,ty); + if (!tc) return -1; + *ptr = SWIG_TypeCast(tc, (void*)p); + } + } else { + /* They don't care about the target type, so just pass on the pointer! */ + *ptr = (void *) p; + } + return 0; +} + +/* This function fills ptr with a pointer of type ty by extracting the pointer + and type info from the resource in z. z must be a resource + It uses SWIG_ZTS_ConvertResourceData to do the real work. */ +SWIGRUNTIME(int) +SWIG_ZTS_ConvertResourcePtr(zval *z, void **ptr, swig_type_info *ty TSRMLS_DC) { + swig_object_wrapper *value; + void *p; + int type; + char *type_name; + + value = (swig_object_wrapper *) zend_list_find(z->value.lval,&type); + p = value->ptr; + if (type==-1) return -1; + + type_name=zend_rsrc_list_get_rsrc_type(z->value.lval); + + return SWIG_ZTS_ConvertResourceData(p,type,type_name,ptr,ty TSRMLS_CC); +} + +/* But in fact SWIG_ConvertPtr is the native interface for getting typed + pointer values out of zvals. We need the TSRMLS_ macros for when we + make PHP type calls later as we handle php resources */ +#define SWIG_ConvertPtr(a,b,c) SWIG_ZTS_ConvertPtr(a,b,c TSRMLS_CC) + +/* We allow passing of a STRING or RESOURCE pointing to the object + or an OBJECT whose _cPtr is a string or resource pointing to the object + STRING pointers are very depracated */ +SWIGRUNTIME(int) +SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty TSRMLS_DC) { + char *c; + zval *val; + + if(z == NULL) { + *ptr = 0; + return 0; + } + + if (z->type==IS_OBJECT) { + zval ** _cPtr; + if (zend_hash_find(HASH_OF(z),"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) { + /* Don't co-erce to string if it isn't */ + if ((*_cPtr)->type==IS_STRING) c = Z_STRVAL_PP(_cPtr); + else if ((*_cPtr)->type==IS_RESOURCE) { + return SWIG_ZTS_ConvertResourcePtr(*_cPtr,ptr,ty TSRMLS_CC); + } else goto type_error; /* _cPtr was not string or resource property */ + } else goto type_error; /* can't find property _cPtr */ + } else if (z->type==IS_RESOURCE) { + return SWIG_ZTS_ConvertResourcePtr(z,ptr,ty TSRMLS_CC); + } else if (z->type==IS_STRING) { + c = Z_STRVAL_P(z); + return _SWIG_ConvertPtr(c,ptr,ty); + } else goto type_error; + +type_error: + + return -1; +} diff --git a/Lib/php4/std_string.i b/Lib/php4/std_string.i new file mode 100644 index 000000000..4c46ee647 --- /dev/null +++ b/Lib/php4/std_string.i @@ -0,0 +1,45 @@ +// +// SWIG typemaps for std::string types +// Luigi Ballabio +// May 7, 2002 +// +// PHP implementation + + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + %typemap(in) string { + convert_to_string_ex($input); + $1 = std::string(Z_STRVAL_PP($input)); + } + + %typemap(in) const string & (std::string temp) { + convert_to_string_ex($input); + temp = std::string(Z_STRVAL_PP($input)); + $1 = &temp; + } + + %typemap(out) string { + ZVAL_STRINGL($result,const_cast($1.c_str()),$1.length(),1); + } + + %typemap(out) const string & { + ZVAL_STRINGL($result,const_cast($1->c_str()),$1->length(),1); + } + +} diff --git a/Lib/php4/std_vector.i b/Lib/php4/std_vector.i new file mode 100644 index 000000000..2a88d60cb --- /dev/null +++ b/Lib/php4/std_vector.i @@ -0,0 +1,156 @@ +// +// SWIG typemaps for std::vector types +// Luigi Ballabio +// May 7, 2002 +// +// PHP implementation + +%include exception.i + +// containers + +// methods which can raise are caused to throw an IndexError +%exception std::vector::get { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::set { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// PHP as much as possible, namely, to allow the user to pass and +// be returned PHP lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a PHP sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a PHP sequence of T:s +// is returned which is most easily used in other PHP functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class vector { + // add generic typemaps here + public: + vector(unsigned int size = 0); + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(const T& x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& get(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + // add specialized typemaps here + public: + vector(unsigned int size = 0); + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T get(int i) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && ivalue.dval; + $1 = &dvalue; +} + +%typemap(in) float *REFERENCE (float dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (float) (*$input)->value.dval; + $1 = &dvalue; +} + +%typemap(in) int *REFERENCE (int dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (int) (*$input)->value.lval; + $1 = &dvalue; +} + +%typemap(in) short *REFERENCE (short dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (short) (*$input)->value.lval; + $1 = &dvalue; +} + +%typemap(in) long *REFERENCE (long dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (long) (*$input)->value.lval; + $1 = &dvalue; +} + +%typemap(in) unsigned int *REFERENCE (unsigned int dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (unsigned int) (*$input)->value.lval; + $1 = &dvalue; +} + +%typemap(in) unsigned short *REFERENCE (unsigned short dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (unsigned short) $input->value.lval; + $1 = &dvalue; +} + +%typemap(in) unsigned long *REFERENCE (unsigned long dvalue) +{ + if(!ParameterPassedByReference(ht, argvi)) + { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + dvalue = (unsigned long) $input->value.lval; + $1 = &dvalue; +} + +%typemap(argout) double *REFERENCE, + float *REFERENCE +{ + $1->value.dval = (double)(*$arg); + $1->type = IS_DOUBLE; +} + +%typemap(argout) int *REFERENCE, + short *REFERENCE, + long *REFERENCE, + unsigned int *REFERENCE, + unsigned short *REFERENCE, + unsigned long *REFERENCE +{ + + (*$arg)->value.lval = (long)(*$input); + (*$arg)->type = IS_LONG; +} diff --git a/Lib/php4/utils.i b/Lib/php4/utils.i new file mode 100644 index 000000000..2ead83f2d --- /dev/null +++ b/Lib/php4/utils.i @@ -0,0 +1,145 @@ +// Contains operations useful in php typemaps +// typemaps don't support "subroutine" typemaps where one typemap can +// include another, so we define useful bodies here to include inother places + +// _strbuf_out is designed to be included as part of an argout typemap +// and _strbuf_in which should be part of the in typemap for the same argument +// They share knowledge of the "force" temporary variable. +// You probably don't want to make direct use of _strbuf_out or _strbuf_in but +// you may want strbufsize_inout which uses these +%define _strbuf_out(BUFFER,SIZE) + if (force$argnum) { /* pass back arg$argnum through params ($arg) if we can */ + if(! PZVAL_IS_REF(*$arg)) { + zend_error(E_WARNING, "Parameter %d of $symname wasn't passed by reference [argout TYPES *, TYPES &]",$argnum-argbase); + } else { + #if SIZE + // SIZE + ZVAL_STRINGL(*$arg,BUFFER$argnum, SIZE, 1); + #else + // Measure length + ZVAL_STRING(*$arg,BUFFER$argnum, 1); + #endif + } + } +%enddef + +%define +_strbuf_in(BUFFER) + // _strbuf_in + if(! SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { + /* Using a _p_ SWIG pointer, so they will have to manage size themselves */ + force=0; + } else if ((*$input)->type==IS_STRING || + (*$input)->type==IS_LONG || + /* Null passed by reference means we want a value back */ + (*$input)->type==IS_NULL || + (*$input)->type==IS_BOOL || + (*$input)->type==IS_DOUBLE) { + + // Only pass back if we can... + if (PZVAL_IS_REF(*$input)) force=1; + else force=0; + + convert_to_string_ex($input); + // Init temp buffer + strncpy((char *)temp,Z_STRVAL_PP($input),sizeof(BUFFER)); + $1=temp; + } else { + force=0; + $1=NULL; + zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s or at least something looking vaguely like a string hopefully passed by reference", $argnum-argbase, $1_descriptor->name); + } +%enddef + +// strbufsize_inout defines a typemap which +// Example: strbufsize_inout(UCHAR FAR * szErrorMsg, SWORD cbErrorMsgMax,1024) +// defines a typeemap for UCHAR FAR * szErrorMsg, SWORD cbErrorMsgMax with a +// max buffer size of 1024 +%define strbufsize_inout(BUFFER,SIZE,MAXSIZE) +%typemap(in) (BUFFER, SIZE) ($*1_ltype temp[MAXSIZE], int force) { + _strbuf_in(temp) + $2=sizeof(temp); +} +%typemap(argout) (BUFFER, SIZE) { + _strbuf_out((char *)temp,strlen(temp)) +} +%enddef + +// char array can be in/out, though the passed string may not be big enough... +// so we have to size it +// e.g. Do: strarray_inout(char [ANY]) +%define strarray_inout(TYPE) +%typemap(in) TYPE ($*1_ltype temp[$1_dim0], int force) %{ + _strbuf_in(temp) +%} +%typemap(argout) TYPE %{ + _strbuf_out((char *)temp,$1_dim0); +%} +%enddef + +%define strarraysize_inout(TYPE,SIZE) +%typemap(in) TYPE ($*1_ltype temp[SIZE], int force) %{ + _strbuf_in(temp) +%} +%typemap(argout) TYPE %{ + _strbuf_out((char *)temp,SIZE); +%} +%enddef + +%define strbuf_inout(BUFFER,MAXSIZE) +%typemap(in) (BUFFER) ($*1_ltype temp[MAXSIZE], int force) { + _strbuf_in(temp) +} +%typemap(argout) (BUFFER) { + _strbuf_out(temp,strlen(temp)) +} +%enddef + +/* Typemap for in/argout references + NOTE: we don't choose to use these for arrays yet, maybe later */ +%define outLONG(ZVALARG,CARG) + ZVAL_LONG(*$arg,intr$argnum); +%enddef + +// Defines an on/argout typemap for ordinal types +//Usage: %typemap_inout_ord(bool,convert_to_bool_ex,ZVAL_BOOL) +%define %typemap_inout_ord(TYPES,TYPE_IN,TYPE_OUT) +%typemap(in) TYPES * ($*1_ltype intr, int force), + TYPES & ($*1_ltype intr, int force) %{ + /* inout typemap for TYPES using TYPE_IN and TYPE_OUT */ + if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { + /* So... we didn't get a ref or ptr, but can it be reasonably + co-erced into what we were looking for a ref of or ptr to? */ + if (!PZVAL_IS_REF(*$input) && (*$input)->type==IS_NULL) { + // null passed not by reference means pass NULL + $1 = NULL; + force=0; + } else if (PZVAL_IS_REF(*$input) && + ((*$input)->type==IS_STRING || + (*$input)->type==IS_LONG || + /* Null passed by reference means we want a value back */ + (*$input)->type==IS_NULL || + (*$input)->type==IS_BOOL || + (*$input)->type==IS_DOUBLE)) { + TYPE_IN($input); + intr = ($*1_ltype) (*$input)->value.lval; + $1 = &intr; + /* have to passback arg$arg too */ + force=1; + } else { /* wasn't a pre/ref/thing, OR anything like an int thing */ + force=0; + zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s or at least something looking vaguely like a number hopefully passed by reference", $argnum-argbase, $1_descriptor->name); + } + } else force=0; +%} + +%typemap(argout) TYPES *, TYPES & %{ + if (force$argnum) { /* pass back arg$argnum through params ($arg) if we can */ + if(! PZVAL_IS_REF(*$arg)) { + zend_error(E_WARNING, "Parameter %d of $symname wasn't passed by reference [argout TYPES *, TYPES &]",$argnum-argbase); + } else { + TYPE_OUT(*$arg,intr$argnum); + } + } +%} +%enddef diff --git a/Lib/pike/pike.swg b/Lib/pike/pike.swg new file mode 100644 index 000000000..4ec1d21b1 --- /dev/null +++ b/Lib/pike/pike.swg @@ -0,0 +1,337 @@ +/* ----------------------------------------------------------------------------- + * pike.swg + * + * Pike configuration module. + * ----------------------------------------------------------------------------- */ + +%insert(runtime) "common.swg"; // Common type-checking code +%insert(runtime) "pikerun.swg"; // Pike run-time code + +%insert(runtime) %{ +#ifdef __cplusplus +extern "C" { +#endif +#include "global.h" +#include "interpret.h" + +/* This must be included last! */ +#include "module_magic.h" +#ifdef __cplusplus +} +#endif +%} + +/* ----------------------------------------------------------------------------- + * standard typemaps + * ----------------------------------------------------------------------------- */ + +/* --- Input arguments --- */ + +/* Primitive datatypes. */ + +%typemap(in, pikedesc="tInt") + int, unsigned int, short, unsigned short, + long, unsigned long, char, signed char, unsigned char, + bool, enum SWIGTYPE, long long, unsigned long long +{ + if ($input.type != T_INT) + Pike_error("Bad argument: Expected an integer.\n"); + $1 = ($1_ltype) $input.u.integer; +} + +%typemap(in, pikedesc="tFloat") float, double { + if ($input.type != T_FLOAT) + Pike_error("Bad argument: Expected a float.\n"); + $1 = ($1_ltype) $input.u.float_number; +} + +%typemap(in, pikedesc="tStr") char *, char [ANY] { + if ($input.type != T_STRING) + Pike_error("Bad argument: Expected a string.\n"); + $1 = ($1_ltype) STR0($input.u.string); +} + +/* Pointers, references and arrays */ + +%typemap(in) SWIGTYPE *, + SWIGTYPE &, + SWIGTYPE [] + "SWIG_ConvertPtr($input.u.object, (void **) &$1, $1_descriptor, 1);" + +/* Void pointer. Accepts any kind of pointer */ +%typemap(in) void * "/* FIXME */"; + +/* Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE ($&1_ltype argp) "/* FIXME */"; + +/* Pointer to a class member */ +%typemap(in) SWIGTYPE (CLASS::*) "/* FIXME */"; + +/* Const primitive references. Passed by value */ + +%typemap(in, pikedesc="tInt") const int & (int temp), + const short & (short temp), + const long & (long temp), + const unsigned int & (unsigned int temp), + const unsigned short & (unsigned short temp), + const unsigned long & (unsigned long temp), + const char & (char temp), + const signed char & (signed char temp), + const unsigned char & (unsigned char temp), + const bool & (bool temp), + const long long & (long long temp), + const unsigned long long & (unsigned long long temp) +{ + if ($input.type != T_INT) + Pike_error("Bad argument: Expected an integer.\n"); + temp = ($*1_ltype) $input.u.integer; + $1 = &temp; +} + +%typemap(in, pikedesc="tFloat") const float & (float temp), + const double & (double temp) +{ + if ($input.type != T_FLOAT) + Pike_error("Bad argument: Expected a float.\n"); + temp = ($*1_ltype) $input.u.float_number; + $1 = &temp; +} + +/************************ Output Typemaps *****************************/ + +%typemap(out, pikedesc="tInt") + int, unsigned int, + short, unsigned short, + long, unsigned long, + char, signed char, unsigned char, + bool, enum SWIGTYPE + "push_int($1);"; + +%typemap(out, pikedesc="tInt") long long "push_int64($1);"; +%typemap(out, pikedesc="tInt") unsigned long long "push_int64($1);"; +%typemap(out, pikedesc="tFloat") float, double "push_float($1);"; +%typemap(out, pikedesc="tStr") char * "push_text($1);"; + +/* Pointers, references, and arrays */ +%typemap(out) SWIGTYPE*, SWIGTYPE &, SWIGTYPE [] + "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor, $owner);"; + +/* Void return value; don't push anything */ +%typemap(out, pikedesc="tVoid") void ""; + +/* Dynamic casts */ + +%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC "/* FIXME */"; + +/* Member pointer */ +%typemap(out) SWIGTYPE (CLASS::*) "/* FIXME */"; + +/* Special typemap for character array return values */ +%typemap(out, pikedesc="tStr") char [ANY], const char [ANY] "push_text($1);"; + +/* Primitive types--return by value */ +%typemap(out) SWIGTYPE +#ifdef __cplusplus +{ + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); +} +#else +{ + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); +} +#endif + +/* References to primitive types. Return by value */ + +%typemap(out, pikedesc="tInt") const int &, const unsigned int &, + const short &, const unsigned short &, + const long &, const unsigned long &, + const char &, const signed char &, const unsigned char &, + const bool &, + const long long &, const unsigned long long & + "push_int(*($1));"; + +%typemap(out, pikedesc="tFloat") const float &, const double & "push_float(*($1));"; + +/************************ Constant Typemaps *****************************/ + +%typemap(constant) + int, unsigned int, + short, unsigned short, + long, unsigned long, + signed char, unsigned char, + bool, enum SWIGTYPE, + long long, unsigned long long + "add_integer_constant(\"$symname\", $1, 0);"; + +%typemap(constant) char + "add_integer_constant(\"$symname\", '$1', 0);"; + +%typemap(constant) long long, unsigned long long + "add_integer_constant(\"$symname\", $1, 0);"; + +%typemap(constant) float, double + "add_float_constant(\"$symname\", $1, 0);"; + +%typemap(constant) char * + "add_string_constant(\"$symname\", \"$1\", 0);"; + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +%typemap(in, pikedesc="tStr") (char *STRING, int LENGTH) { + if ($input.type != T_STRING) + Pike_error("Bad argument: Expected a string.\n"); + $1 = ($1_ltype) STR0($input.u.string); + $2 = ($2_ltype) $input.u.string->length; +} + +/* ------------------------------------------------------------ + * ANSI C typemaps + * ------------------------------------------------------------ */ + +%typemap(in, pikedesc="tInt") size_t { + if ($input.type != T_INT) + Pike_error("Bad argument: Expected an integer.\n"); + $1 = ($1_ltype) $input.u.integer; +} + +%typemap(out) size_t = long; + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE, + bool, const bool & +{ + $1 = ($input.type == T_INT) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = (($input.type == T_FLOAT) || ($input.type == T_INT)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + $1 = ($input.type == T_INT) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = ($input.type == T_STRING) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, $1_descriptor, 0) == -1) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, $&1_descriptor, 0) == -1) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, 0, 0) == -1) { + $1 = 0; + } else { + $1 = 1; + } +} + +/* ------------------------------------------------------------ + * Overloaded operator support + * ------------------------------------------------------------ */ + +#ifdef __cplusplus +%rename("`+") *::operator+; +%rename("`-") *::operator-; +%rename("`*") *::operator*; +%rename("`/") *::operator/; +%rename("`%") *::operator%; +%rename("`<<") *::operator<<; +%rename("`>>") *::operator>>; +%rename("`&") *::operator&; +%rename("`|") *::operator|; +%rename("`^") *::operator^; +%rename("`~") *::operator~; +%rename("`<") *::operator<; +%rename("`>") *::operator>; +%rename("`==") *::operator==; + +/* Special cases */ +%rename("`()") *::operator(); + +/* Ignored operators */ +%ignorewarn("362:operator= ignored") operator=; +%ignorewarn("365:operator+= ignored") operator+=; +%ignorewarn("366:operator-= ignored") operator-=; +%ignorewarn("367:operator*= ignored") operator*=; +%ignorewarn("368:operator/= ignored") operator/=; +%ignorewarn("369:operator%= ignored") operator%=; +%ignorewarn("370:operator^= ignored") operator^=; +%ignorewarn("371:operator&= ignored") operator&=; +%ignorewarn("372:operator|= ignored") operator|=; +%ignorewarn("375:operator<<= ignored") operator<<=; +%ignorewarn("376:operator>>= ignored") operator>>=; +%ignorewarn("378:operator!= ignored") operator!=; +%ignorewarn("379:operator<= ignored") operator<=; +%ignorewarn("380:operator>= ignored") operator>=; +%ignorewarn("381:operator&& ignored") operator&&; +%ignorewarn("382:operator|| ignored") operator||; +%ignorewarn("383:operator++ ignored") operator++; +%ignorewarn("384:operator-- ignored") operator--; +%ignorewarn("386:operator->* ignored") operator->*; +%ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; +%ignorewarn("390:operator+() ignored") operator+(); +%ignorewarn("390:operator+() const ignored") operator+() const; +%ignorewarn("391:operator-() ignored") operator-(); +%ignorewarn("391:operator-() const ignored") operator-() const; + +#endif + +/* ------------------------------------------------------------ + * The start of the Pike initialization function + * ------------------------------------------------------------ */ + +%init %{ +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT(void) pike_module_exit(void) {} + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT(void) pike_module_init(void) { + struct program *pr; + int i; + for (i = 0; swig_types_initial[i]; i++) { + swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); + } +%} diff --git a/Lib/pike/pikerun.swg b/Lib/pike/pikerun.swg new file mode 100644 index 000000000..5ca7effb5 --- /dev/null +++ b/Lib/pike/pikerun.swg @@ -0,0 +1,59 @@ +/*********************************************************************** + * pikerun.swg + * + * This file contains the runtime support for Pike modules + * and includes code for managing global variables and pointer + * type checking. + * + * Author : Lyle Johnson (lyle@users.sourceforge.net) + ************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif +#include "object.h" +#include "program.h" +#ifdef __cplusplus +} +#endif + +/* Stores information about a wrapped object */ +typedef struct swig_object_wrapper { + void *self; +} swig_object_wrapper; + +#ifdef THIS +#undef THIS +#endif +#define THIS (((swig_object_wrapper *) Pike_fp->current_storage)->self) + +#ifdef SWIG_NOINCLUDE + +SWIGEXPORT(int) SWIG_ConvertPtr(struct object *, void **, swig_type_info *, int); +SWIGEXPORT(struct object *) SWIG_NewPointerObj(void *, swig_type_info *, int); + +#else + +/* Convert a pointer value */ +SWIGRUNTIME(int) +SWIG_ConvertPtr(struct object *obj, void **ptr, swig_type_info *ty, int flags) { + char *storage; + struct program *pr; + if (ty) { + pr = (struct program *) ty->clientdata; + storage = get_storage(obj, pr); + if (storage) { + *ptr = ((swig_object_wrapper *) storage)->self; + return 0; + } + } + return -1; +} + +/* Create a new pointer object */ +SWIGRUNTIME(struct object *) +SWIG_NewPointerObj(void *ptr, swig_type_info *type, int own) { + return 0; +} + +#endif diff --git a/Lib/pointer.i b/Lib/pointer.i index 841a71df0..0f799ace2 100644 --- a/Lib/pointer.i +++ b/Lib/pointer.i @@ -1,58 +1,6 @@ -// -// SWIG Pointer manipulation library -// -// This library can be used to manipulate C pointers. -%title "SWIG Pointer Library" -%module pointer - - -%section "Pointer Handling Library",noinfo,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 - -%text %{ -%include pointer.i - -The pointer.i library provides run-time support for managing and -manipulating a variety of C/C++ pointer values. In particular, -you can create various kinds of objects and dereference common -pointer types. This is done through a common set of functions: - - ptrvalue - Dereferences a pointer - ptrset - Set the value of an object referenced by - a pointer. - ptrcreate - Create a new object and return a pointer. - ptrfree - Free the memory allocated by ptrcreate. - ptradd - Increment/decrement a pointer value. - -When creating, dereferencing, or setting the value of pointer -variable, only the common C datatypes of int, short, long, float, -double, char, and char * are currently supported. Other -datatypes may generate an error. - -One of the more interesting aspects of this library is that -it operates with a wide range of datatypes. For example, -the "ptrvalue" function can dereference "double *", "int *", -"long *", "char *", and other datatypes. Since SWIG encodes -pointers with type information, this can be done transparently -and in most cases, you can dereference a pointer without -ever knowing what type it actually is. - -This library is primarily designed for utility, not high -performance (the dynamic determination of pointer types takes -more work than most normal wrapper functions). As a result, -you may achieve better performance by writing customized -"helper" functions if you're making lots of calls to these -functions in inner loops or other intensive operations. -%} - -// Record the types that supported by the library - -%types(int *, short *, long *, float *, double *, char *, char **, void *); - -// This library is a pretty hideous mess of language dependent code. -// Grab the implementation from the appropriate libray - -%include ptrlang.i +%echo "pointer.i is deprecated. Use cpointer.i instead." +%echo "See http://www.swig.org/Doc1.3/Library.html" diff --git a/Lib/python/Makefile.in b/Lib/python/Makefile.in index e9f553078..eb18214d0 100644 --- a/Lib/python/Makefile.in +++ b/Lib/python/Makefile.in @@ -35,7 +35,7 @@ CC = @CC@ CXX = @CXX@ OBJC = @CC@ -Wno-import # -Wno-import needed for gcc CFLAGS = -INCLUDE = +INCLUDES = LIBS = # SWIG Options @@ -102,13 +102,13 @@ BUILD_LIBS = $(LIBS) # Dynamic loading .SUFFIXES: .c .cxx .m .c.o: - $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< .cxx.o: - $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDES) -c $< .m.o: - $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< # ---------------------------------------------------------------------- @@ -120,7 +120,7 @@ all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) - $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDE) $(PY_INCLUDE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(PY_INCLUDE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) diff --git a/Lib/python/cstring.i b/Lib/python/cstring.i new file mode 100644 index 000000000..0712e29d7 --- /dev/null +++ b/Lib/python/cstring.i @@ -0,0 +1,288 @@ +/* + * cstring.i + * $Header$ + * + * Author(s): David Beazley (beazley@cs.uchicago.edu) + * + * This file provides typemaps and macros for dealing with various forms + * of C character string handling. The primary use of this module + * is in returning character data that has been allocated or changed in + * some way. + */ + +%include "fragments.i" + +/* %cstring_input_binary(TYPEMAP, SIZE) + * + * Macro makes a function accept binary string data along with + * a size. + */ + +%define %cstring_input_binary(TYPEMAP, SIZE) +%apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; +%enddef + +/* + * %cstring_bounded_output(TYPEMAP, MAX) + * + * This macro is used to return a NULL-terminated output string of + * some maximum length. For example: + * + * %cstring_bounded_output(char *outx, 512); + * void foo(char *outx) { + * sprintf(outx,"blah blah\n"); + * } + * + */ + +%define %cstring_bounded_output(TYPEMAP,MAX) +%typemap(ignore) TYPEMAP(char temp[MAX+1]) { + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + PyObject *o; + $1[MAX] = 0; + o = PyString_FromString($1); + $result = t_output_helper($result,o); +} +%enddef + +/* + * %cstring_chunk_output(TYPEMAP, SIZE) + * + * This macro is used to return a chunk of binary string data. + * Embedded NULLs are okay. For example: + * + * %cstring_chunk_output(char *outx, 512); + * void foo(char *outx) { + * memmove(outx, somedata, 512); + * } + * + */ + +%define %cstring_chunk_output(TYPEMAP,SIZE) +%typemap(ignore) TYPEMAP(char temp[SIZE]) { + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + PyObject *o = PyString_FromStringAndSize($1,SIZE); + $result = t_output_helper($result,o); +} +%enddef + +/* + * %cstring_bounded_mutable(TYPEMAP, SIZE) + * + * This macro is used to wrap a string that's going to mutate. + * + * %cstring_bounded_mutable(char *in, 512); + * void foo(in *x) { + * while (*x) { + * *x = toupper(*x); + * x++; + * } + * } + * + */ + + +%define %cstring_bounded_mutable(TYPEMAP,MAX) +%typemap(in) TYPEMAP(char temp[MAX+1]) { + char *t = PyString_AsString($input); + if (PyErr_Occurred()) SWIG_fail; + strncpy(temp,t,MAX); + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + PyObject *o; + $1[MAX] = 0; + o = PyString_FromString($1); + $result = t_output_helper($result,o); +} +%enddef + +/* + * %cstring_mutable(TYPEMAP [, expansion]) + * + * This macro is used to wrap a string that will mutate in place. + * It may change size up to a user-defined expansion. + * + * %cstring_mutable(char *in); + * void foo(in *x) { + * while (*x) { + * *x = toupper(*x); + * x++; + * } + * } + * + */ + +%define %cstring_mutable(TYPEMAP,...) +%typemap(in) TYPEMAP { + char *t = PyString_AsString($input); + int n = PyString_Size($input); + if (PyErr_Occurred()) return SWIG_fail; + $1 = ($1_ltype) t; +#if #__VA_ARGS__ == "" +#if __cplusplus + $1 = ($1_ltype) new char[n+1]; +#else + $1 = ($1_ltype) malloc(n+1); +#endif +#else +#if __cplusplus + $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; +#else + $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); +#endif +#endif + memmove($1,t,n); + $1[n] = 0; +} + +%typemap(argout,fragment="t_output_helper") TYPEMAP { + PyObject *o; + o = PyString_FromString($1); + $result = t_output_helper($result,o); +#if __cplusplus + delete[] $1; +#else + free($1); +#endif +} +%enddef + +/* + * %cstring_output_maxsize(TYPEMAP, SIZE) + * + * This macro returns data in a string of some user-defined size. + * + * %cstring_output_maxsize(char *outx, int max) { + * void foo(char *outx, int max) { + * sprintf(outx,"blah blah\n"); + * } + */ + +%define %cstring_output_maxsize(TYPEMAP, SIZE) +%typemap(in) (TYPEMAP, SIZE) { + $2 = PyInt_AsLong($input); + if (PyErr_Occurred()) return SWIG_fail; +#ifdef __cplusplus + $1 = ($1_ltype) new char[$2+1]; +#else + $1 = ($1_ltype) malloc($2+1); +#endif +} +%typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { + PyObject *o; + o = PyString_FromString($1); + $result = t_output_helper($result,o); +#ifdef __cplusplus + delete [] $1; +#else + free($1); +#endif +} +%enddef + +/* + * %cstring_output_withsize(TYPEMAP, SIZE) + * + * This macro is used to return character data along with a size + * parameter. + * + * %cstring_output_maxsize(char *outx, int *max) { + * void foo(char *outx, int *max) { + * sprintf(outx,"blah blah\n"); + * *max = strlen(outx); + * } + */ + +%define %cstring_output_withsize(TYPEMAP, SIZE) +%typemap(in) (TYPEMAP, SIZE) { + int n = PyInt_AsLong($input); + if (PyErr_Occurred()) SWIG_fail; +#ifdef __cplusplus + $1 = ($1_ltype) new char[n+1]; + $2 = ($2_ltype) new $*2_ltype; +#else + $1 = ($1_ltype) malloc(n+1); + $2 = ($2_ltype) malloc(sizeof($*2_ltype)); +#endif + *$2 = n; +} +%typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { + PyObject *o; + o = PyString_FromStringAndSize($1,*$2); + $result = t_output_helper($result,o); +#ifdef __cplusplus + delete [] $1; + delete $2; +#else + free($1); + free($2); +#endif +} +%enddef + +/* + * %cstring_output_allocate(TYPEMAP, RELEASE) + * + * This macro is used to return character data that was + * allocated with new or malloc. + * + * %cstring_output_allocated(char **outx, free($1)); + * void foo(char **outx) { + * *outx = (char *) malloc(512); + * sprintf(outx,"blah blah\n"); + * } + */ + +%define %cstring_output_allocate(TYPEMAP, RELEASE) +%typemap(ignore) TYPEMAP($*1_ltype temp = 0) { + $1 = &temp; +} + +%typemap(argout,fragment="t_output_helper") TYPEMAP { + if (*$1) { + PyObject *o = PyString_FromString(*$1); + RELEASE; + $result = t_output_helper($result,o); + } +} +%enddef + +/* + * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) + * + * This macro is used to return character data that was + * allocated with new or malloc. + * + * %cstring_output_allocated(char **outx, int *sz, free($1)); + * void foo(char **outx, int *sz) { + * *outx = (char *) malloc(512); + * sprintf(outx,"blah blah\n"); + * *sz = strlen(outx); + * } + */ + +%define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) +%typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { + $1 = &temp; + $2 = &tempn; +} + +%typemap(argout,fragment="t_output_helper")(TYPEMAP,SIZE) { + if (*$1) { + PyObject *o = PyString_FromStringAndSize(*$1,*$2); + RELEASE; + $result = t_output_helper($result,o); + } +} +%enddef + + + + + + diff --git a/Lib/python/embed13.i b/Lib/python/embed13.i deleted file mode 100644 index 0b952638e..000000000 --- a/Lib/python/embed13.i +++ /dev/null @@ -1,342 +0,0 @@ -// -// embed.i -// SWIG file embedding the Python interpreter in something else. -// This file is based on Python-1.3, but it might work with -// later versions. -// -// This file makes it possible to extend Python and all of its -// built-in functions without having to hack it's setup script. -// - -#ifdef AUTODOC -%subsection "embed13.i" -%text %{ -This module provides support for building a new version of the -Python 1.3 executable. This will be necessary on systems that do -not support shared libraries and may be necessary with C++ -extensions. This file contains everything you need to build -a new version of Python from include files and libraries normally -installed with the Python language. - -This module is functionally equivalent to the embed.i library, -but has a number of changes needed to work with older versions -of Python. -%} -#else -%echo "embed.i : Using Python 1.3" -#endif - - - - -%wrapper %{ - -#ifndef NEED_GETOPT -#include -#endif - -#include -typedef struct SWIGPyTab { - char *name; - void (*initfunc)(); -} SWIGPyTab; - -#ifdef __cplusplus -extern "C" -#endif -void SWIG_init(void); /* Forward reference */ - -#define inittab python_inittab - -/* Grab Python's inittab[] structure */ - -#ifdef __cplusplus -extern "C" { -#endif -#include - -#undef inittab - - -/* Now define our own version of it. - God forbid someone have more than 1000 built-in modules! */ - -SWIGPyTab inittab[1000]; - -static int swig_num_modules = 0; - -/* Function for adding modules to Python */ - -static void swig_add_module(char *name, void (*initfunc)()) { - inittab[swig_num_modules].name = name; - inittab[swig_num_modules].initfunc = initfunc; - swig_num_modules++; - inittab[swig_num_modules].name = (char *) 0; - inittab[swig_num_modules].initfunc = (void (*)()) 0; -} - -/* Function to add all of Python's build in modules to our interpreter */ - -static void swig_add_builtin() { - int i = 0; - while (python_inittab[i].name) { - swig_add_module(python_inittab[i].name, python_inittab[i].initfunc); - i++; - } - - /* Add SWIG builtin function */ - swig_add_module(SWIG_name, SWIG_init); -#ifdef SWIGMODINIT - SWIGMODINIT -#endif -} -#ifdef __cplusplus -} -#endif - -/* Interface to getopt(): */ -extern int optind; -extern char *optarg; - -#ifdef NEED_GETOPT -#ifdef __cplusplus -extern "C" int getopt(int, char **, char *); -#else -extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */ -#endif -#endif - -extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */ -extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */ -extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */ - -/* Subroutines that live in their own file */ -#ifdef __cplusplus -extern "C" { -extern int isatty(int fd); -extern int PySys_SetArgv(int, char **); -#endif -extern char *getversion(); -extern char *getcopyright(); -#ifdef __cplusplus -} -#endif - -/* For getprogramname(); set by main() */ -static char *argv0; - -/* For getargcargv(); set by main() */ -static char **orig_argv; -static int orig_argc; - -/* Short usage message (with %s for argv0) */ -static char *usage_line = -"usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n"; - -/* Long usage message, split into parts < 512 bytes */ -static char *usage_top = "\n\ -Options and arguments (and corresponding environment variables):\n\ --d : debug output from parser (also PYTHONDEBUG=x)\n\ --i : inspect interactively after running script (also PYTHONINSPECT=x)\n\ --s : suppress printing of top level expressions (also PYTHONSUPPRESS=x)\n\ --u : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\ --v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ --c cmd : program passed in as string (terminates option list)\n\ -"; -static char *usage_bot = "\ -file : program read from script file\n\ -- : program read from stdin (default; interactive mode if a tty)\n\ -arg ...: arguments passed to program in sys.argv[1:]\n\ -\n\ -Other environment variables:\n\ -PYTHONSTARTUP: file executed on interactive startup (no default)\n\ -PYTHONPATH : colon-separated list of directories prefixed to the\n\ - default module search path. The result is sys.path.\n\ -"; - -/* Main program */ - -int -main(int argc, char **argv) { - int c; - int sts; - char *command = NULL; - char *filename = NULL; - FILE *fp = stdin; - char *p; - int inspect = 0; - int unbuffered = 0; - - swig_add_builtin(); /* Add SWIG built-in modules */ - orig_argc = argc; /* For getargcargv() */ - orig_argv = argv; - argv0 = argv[0]; /* For getprogramname() */ - - if ((p = getenv("PYTHONDEBUG")) && *p != '\0') - Py_DebugFlag = 1; - if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0') - Py_SuppressPrintingFlag = 1; - if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') - Py_VerboseFlag = 1; - if ((p = getenv("PYTHONINSPECT")) && *p != '\0') - inspect = 1; - if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') - unbuffered = 1; - - while ((c = getopt(argc, argv, "c:disuv")) != EOF) { - if (c == 'c') { - /* -c is the last option; following arguments - that look like options are left for the - the command to interpret. */ - command = (char *) malloc(strlen(optarg) + 2); - if (command == NULL) - Py_FatalError( - "not enough memory to copy -c argument"); - strcpy(command, optarg); - strcat(command, "\n"); - break; - } - - switch (c) { - - case 'd': - Py_DebugFlag++; - break; - - case 'i': - inspect++; - break; - - case 's': - Py_SuppressPrintingFlag++; - break; - - case 'u': - unbuffered++; - break; - - case 'v': - Py_VerboseFlag++; - break; - - /* This space reserved for other options */ - - default: - fprintf(stderr, usage_line, argv[0]); - fprintf(stderr, usage_top); - fprintf(stderr, usage_bot); - exit(2); - /*NOTREACHED*/ - - } - } - - if (unbuffered) { -#ifndef MPW - setbuf(stdout, (char *)NULL); - setbuf(stderr, (char *)NULL); -#else - /* On MPW (3.2) unbuffered seems to hang */ - setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); - setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ); -#endif - } - - if (command == NULL && optind < argc && - strcmp(argv[optind], "-") != 0) - filename = argv[optind]; - - if (Py_VerboseFlag || - command == NULL && filename == NULL && isatty((int)fileno(fp))) - fprintf(stderr, "Python %s\n%s\n", - getversion(), getcopyright()); - - if (filename != NULL) { - if ((fp = fopen(filename, "r")) == NULL) { - fprintf(stderr, "%s: can't open file '%s'\n", - argv[0], filename); - exit(2); - } - } - - Py_Initialize(); - if (command != NULL) { - /* Backup optind and force sys.argv[0] = '-c' */ - optind--; - argv[optind] = "-c"; - } - - PySys_SetArgv(argc-optind, argv+optind); - - if (command) { - sts = PyRun_SimpleString(command) != 0; - } - else { - if (filename == NULL && isatty((int)fileno(fp))) { - char *startup = getenv("PYTHONSTARTUP"); - if (startup != NULL && startup[0] != '\0') { - FILE *fp = fopen(startup, "r"); - if (fp != NULL) { - (void) PyRun_SimpleFile(fp, startup); - PyErr_Clear(); - fclose(fp); - } - } - } - sts = PyRun_AnyFile( - fp, filename == NULL ? "" : filename) != 0; - if (filename != NULL) - fclose(fp); - } - - if (inspect && isatty((int)fileno(stdin)) && - (filename != NULL || command != NULL)) - sts = PyRun_AnyFile(stdin, "") != 0; - - Py_Exit(sts); - /*NOTREACHED*/ -} - - -/* Return the program name -- some code out there needs this. */ - -#ifdef __cplusplus -extern "C" -#endif - -char * -getprogramname() -{ - return argv0; -} - - -/* Make the *original* argc/argv available to other modules. - This is rare, but it is needed by the secureware extension. */ - -#ifdef __cplusplus -extern "C" -#endif -void -getargcargv(int *argc,char ***argv) -{ - *argc = orig_argc; - *argv = orig_argv; -} - -/* Total Hack to get getpath.c to compile under C++ */ - -#ifdef __cplusplus -#define malloc (char *) malloc -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#undef malloc -#endif - -%} - - - diff --git a/Lib/python/embed14.i b/Lib/python/embed14.i deleted file mode 100644 index 2558c3975..000000000 --- a/Lib/python/embed14.i +++ /dev/null @@ -1,340 +0,0 @@ -// -// embed.i -// SWIG file embedding the Python interpreter in something else. -// This file is based on Python-1.4. -// -// This file makes it possible to extend Python and all of its -// built-in functions without having to hack it's setup script. -// - - -#ifdef AUTODOC -%subsection "embed.i" -%text %{ -This module provides support for building a new version of the -Python executable. This will be necessary on systems that do -not support shared libraries and may be necessary with C++ -extensions. This file contains everything you need to build -a new version of Python from include files and libraries normally -installed with the Python language. - -This module will automatically grab all of the Python modules -present in your current Python executable (including any special -purpose modules you have enabled such as tkinter). Thus, you -may need to provide additional link libraries when compiling. - -This library file only works with Python 1.4. A version compatible -with Python 1.3 is available as embed13.i. A Python 1.5 version is -available as embed15.i As far as I know, this module is C++ safe -(well, it works for me). -%} -#else -%echo "embed.i : Using Python 1.4" -#endif - -%wrapper %{ -#ifndef NEED_GETOPT -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" -#endif -void SWIG_init(); /* Forward reference */ - -#define inittab python_inittab - -/* Grab Python's inittab[] structure */ - -#ifdef __cplusplus -extern "C" { -#endif -#include - -#undef inittab - -/* Now define our own version of it. - Hopefully someone does not have more than 1000 built-in modules */ - -struct _inittab inittab[1000]; - -static int swig_num_modules = 0; - -/* Function for adding modules to Python */ - - -static void swig_add_module(char *name, void (*initfunc)()) { - inittab[swig_num_modules].name = name; - inittab[swig_num_modules].initfunc = initfunc; - swig_num_modules++; - inittab[swig_num_modules].name = (char *) 0; - inittab[swig_num_modules].initfunc = 0; -} - -/* Function to add all of Python's build in modules to our interpreter */ - -static void swig_add_builtin() { - int i = 0; - while (python_inittab[i].name) { - swig_add_module(python_inittab[i].name, python_inittab[i].initfunc); - i++; - } -#ifdef SWIGMODINIT - SWIGMODINIT -#endif - /* Add SWIG builtin function */ - swig_add_module(SWIG_name, SWIG_init); -} - -#ifdef __cplusplus -} -#endif - -/* Interface to getopt(): */ -extern int optind; -extern char *optarg; -#ifdef NEED_GETOPT -#ifdef __cplusplus -extern "C" int getopt(int, char **, char *); -#else -extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */ -#endif -#endif - -extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */ -extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */ -extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */ - -/* Subroutines that live in their own file */ -#ifdef __cplusplus -extern "C" { -extern int isatty(int fd); -extern void PySys_SetArgv(int, char **); -#endif -extern char *Py_GetVersion(); -extern char *Py_GetCopyright(); -#ifdef __cplusplus -} -#endif - -/* For getprogramname(); set by main() */ -static char *argv0; - -/* For getargcargv(); set by main() */ -static char **orig_argv; -static int orig_argc; - -/* Short usage message (with %s for argv0) */ -static char *usage_line = -"usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n"; - -/* Long usage message, split into parts < 512 bytes */ -static char *usage_top = "\n\ -Options and arguments (and corresponding environment variables):\n\ --d : debug output from parser (also PYTHONDEBUG=x)\n\ --i : inspect interactively after running script (also PYTHONINSPECT=x)\n\ --s : suppress printing of top level expressions (also PYTHONSUPPRESS=x)\n\ --u : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\ --v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ --c cmd : program passed in as string (terminates option list)\n\ -"; -static char *usage_bot = "\ -file : program read from script file\n\ -- : program read from stdin (default; interactive mode if a tty)\n\ -arg ...: arguments passed to program in sys.argv[1:]\n\ -\n\ -Other environment variables:\n\ -PYTHONSTARTUP: file executed on interactive startup (no default)\n\ -PYTHONPATH : colon-separated list of directories prefixed to the\n\ - default module search path. The result is sys.path.\n\ -"; - -/* Main program */ - -int -main(int argc, char **argv) { - int c; - int sts; - char *command = NULL; - char *filename = NULL; - FILE *fp = stdin; - char *p; - int inspect = 0; - int unbuffered = 0; - - swig_add_builtin(); /* Add SWIG built-in modules */ - orig_argc = argc; /* For getargcargv() */ - orig_argv = argv; - argv0 = argv[0]; /* For getprogramname() */ - - if ((p = getenv("PYTHONDEBUG")) && *p != '\0') - Py_DebugFlag = 1; - if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0') - Py_SuppressPrintingFlag = 1; - if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') - Py_VerboseFlag = 1; - if ((p = getenv("PYTHONINSPECT")) && *p != '\0') - inspect = 1; - if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') - unbuffered = 1; - - while ((c = getopt(argc, argv, "c:disuv")) != EOF) { - if (c == 'c') { - /* -c is the last option; following arguments - that look like options are left for the - the command to interpret. */ - command = (char *) malloc(strlen(optarg) + 2); - if (command == NULL) - Py_FatalError( - "not enough memory to copy -c argument"); - strcpy(command, optarg); - strcat(command, "\n"); - break; - } - - switch (c) { - - case 'd': - Py_DebugFlag++; - break; - - case 'i': - inspect++; - break; - - case 's': - Py_SuppressPrintingFlag++; - break; - - case 'u': - unbuffered++; - break; - - case 'v': - Py_VerboseFlag++; - break; - - /* This space reserved for other options */ - - default: - fprintf(stderr, usage_line, argv[0]); - fprintf(stderr, usage_top); - fprintf(stderr, usage_bot); - exit(2); - /*NOTREACHED*/ - - } - } - - if (unbuffered) { -#ifndef MPW - setbuf(stdout, (char *)NULL); - setbuf(stderr, (char *)NULL); -#else - /* On MPW (3.2) unbuffered seems to hang */ - setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); - setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ); -#endif - } - - if (command == NULL && optind < argc && - strcmp(argv[optind], "-") != 0) - filename = argv[optind]; - - if (Py_VerboseFlag || - command == NULL && filename == NULL && isatty((int)fileno(fp))) - fprintf(stderr, "Python %s\n%s\n", - Py_GetVersion(), Py_GetCopyright()); - - if (filename != NULL) { - if ((fp = fopen(filename, "r")) == NULL) { - fprintf(stderr, "%s: can't open file '%s'\n", - argv[0], filename); - exit(2); - } - } - - Py_Initialize(); - if (command != NULL) { - /* Backup optind and force sys.argv[0] = '-c' */ - optind--; - argv[optind] = "-c"; - } - - PySys_SetArgv(argc-optind, argv+optind); - - if (command) { - sts = PyRun_SimpleString(command) != 0; - } - else { - if (filename == NULL && isatty((int)fileno(fp))) { - char *startup = getenv("PYTHONSTARTUP"); - if (startup != NULL && startup[0] != '\0') { - FILE *fp = fopen(startup, "r"); - if (fp != NULL) { - (void) PyRun_SimpleFile(fp, startup); - PyErr_Clear(); - fclose(fp); - } - } - } - sts = PyRun_AnyFile( - fp, filename == NULL ? "" : filename) != 0; - if (filename != NULL) - fclose(fp); - } - - if (inspect && isatty((int)fileno(stdin)) && - (filename != NULL || command != NULL)) - sts = PyRun_AnyFile(stdin, "") != 0; - - Py_Exit(sts); - /*NOTREACHED*/ -} - - -/* Return the program name -- some code out there needs this. */ - -#ifdef __cplusplus -extern "C" -#endif - -char * -Py_GetProgramName() -{ - return argv0; -} - - -/* Make the *original* argc/argv available to other modules. - This is rare, but it is needed by the secureware extension. */ - -#ifdef __cplusplus -extern "C" -#endif -void -getargcargv(int *argc,char ***argv) -{ - *argc = orig_argc; - *argv = orig_argv; -} - -/* Total Hack to get getpath.c to compile under C++ */ - -#ifdef __cplusplus -#define malloc (char *) malloc -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#undef malloc -#endif - -%} - - - - diff --git a/Lib/python/fragments.i b/Lib/python/fragments.i new file mode 100644 index 000000000..0fbe1f2f8 --- /dev/null +++ b/Lib/python/fragments.i @@ -0,0 +1,29 @@ +/* Helper function to return tuples */ + +%fragment("t_output_helper","header") %{ +static PyObject* t_output_helper(PyObject* target, PyObject* o) { + PyObject* o2; + PyObject* o3; + + if (!target) { + target = o; + } else if (target == Py_None) { + Py_DECREF(Py_None); + target = o; + } else { + if (!PyTuple_Check(target)) { + o2 = target; + target = PyTuple_New(1); + PyTuple_SetItem(target, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SetItem(o3, 0, o); + + o2 = target; + target = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return target; +} +%} diff --git a/Lib/python/ptrlang.i b/Lib/python/ptrlang.i deleted file mode 100644 index 231cf7463..000000000 --- a/Lib/python/ptrlang.i +++ /dev/null @@ -1,464 +0,0 @@ -// -// SWIG pointer conversion and utility library -// -// Dave Beazley -// April 19, 1997 -// -// Python specific implementation. This file is included -// by the file ../pointer.i - - -%{ -#include - -/* Types used by the library */ -static swig_type_info *SWIG_POINTER_int_p = 0; -static swig_type_info *SWIG_POINTER_short_p =0; -static swig_type_info *SWIG_POINTER_long_p = 0; -static swig_type_info *SWIG_POINTER_float_p = 0; -static swig_type_info *SWIG_POINTER_double_p = 0; -static swig_type_info *SWIG_POINTER_char_p = 0; -static swig_type_info *SWIG_POINTER_char_pp = 0; -%} - -%init %{ - SWIG_POINTER_int_p = SWIG_TypeQuery("int *"); - SWIG_POINTER_short_p = SWIG_TypeQuery("short *"); - SWIG_POINTER_long_p = SWIG_TypeQuery("long *"); - SWIG_POINTER_float_p = SWIG_TypeQuery("float *"); - SWIG_POINTER_double_p = SWIG_TypeQuery("double *"); - SWIG_POINTER_char_p = SWIG_TypeQuery("char *"); - SWIG_POINTER_char_pp = SWIG_TypeQuery("char **"); -%} - -%{ - -/*------------------------------------------------------------------ - ptrvalue(ptr,type = 0) - - Attempts to dereference a pointer value. If type is given, it - will try to use that type. Otherwise, this function will attempt - to "guess" the proper datatype by checking against all of the - builtin C datatypes. - ------------------------------------------------------------------ */ - -static PyObject *ptrvalue(PyObject *_PTRVALUE, int index, char *type) { - void *ptr; - char *s; - PyObject *obj; - - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,0,0)) { - PyErr_SetString(PyExc_TypeError,"Type error in ptrvalue. Argument is not a valid pointer value."); - return NULL; - } - - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - /* No datatype was passed. Type to figure out if it's a common one */ - if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_int_p,0)) { - type = "int"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_double_p,0)) { - type = "double"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_short_p,0)) { - type = "short"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_long_p,0)) { - type = "long"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_float_p,0)) { - type = "float"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_p,0)) { - type = "char"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_pp,0)) { - type = "char *"; - } else { - type = "unknown"; - } - } - if (!ptr) { - PyErr_SetString(PyExc_TypeError,"Unable to dereference NULL pointer."); - return NULL; - } - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - obj = PyInt_FromLong((long) *(((int *) ptr) + index)); - } else if (strcmp(type,"double") == 0) { - obj = PyFloat_FromDouble((double) *(((double *) ptr)+index)); - } else if (strcmp(type,"short") == 0) { - obj = PyInt_FromLong((long) *(((short *) ptr)+index)); - } else if (strcmp(type,"long") == 0) { - obj = PyInt_FromLong((long) *(((long *) ptr)+index)); - } else if (strcmp(type,"float") == 0) { - obj = PyFloat_FromDouble((double) *(((float *) ptr)+index)); - } else if (strcmp(type,"char") == 0) { - obj = PyString_FromString(((char *) ptr)+index); - } else if (strcmp(type,"char *") == 0) { - char *c = *(((char **) ptr)+index); - if (c) obj = PyString_FromString(c); - else obj = PyString_FromString("NULL"); - } else { - PyErr_SetString(PyExc_TypeError,"Unable to dereference unsupported datatype."); - return NULL; - } - return obj; -} - -/*------------------------------------------------------------------ - ptrcreate(type,value = 0,numelements = 1) - - Attempts to create a new object of given type. Type must be - a basic C datatype. Will not create complex objects. - ------------------------------------------------------------------ */ - -static PyObject *ptrcreate(char *type, PyObject *_PYVALUE, int numelements) { - void *ptr; - PyObject *obj; - int sz; - swig_type_info *cast; - char temp[40]; - - /* Check the type string against a variety of possibilities */ - - if (strcmp(type,"int") == 0) { - sz = sizeof(int)*numelements; - cast = SWIG_POINTER_int_p; - } else if (strcmp(type,"short") == 0) { - sz = sizeof(short)*numelements; - cast = SWIG_POINTER_short_p; - } else if (strcmp(type,"long") == 0) { - sz = sizeof(long)*numelements; - cast = SWIG_POINTER_long_p; - } else if (strcmp(type,"double") == 0) { - sz = sizeof(double)*numelements; - cast = SWIG_POINTER_double_p; - } else if (strcmp(type,"float") == 0) { - sz = sizeof(float)*numelements; - cast = SWIG_POINTER_float_p; - } else if (strcmp(type,"char") == 0) { - sz = sizeof(char)*numelements; - cast = SWIG_POINTER_char_p; - } else if (strcmp(type,"char *") == 0) { - sz = sizeof(char *)*(numelements+1); - cast = SWIG_POINTER_char_pp; - } else { - PyErr_SetString(PyExc_TypeError,"Unable to create unknown datatype."); - return NULL; - } - - /* Create the new object */ - - ptr = (void *) malloc(sz); - if (!ptr) { - PyErr_SetString(PyExc_MemoryError,"Out of memory in swig_create."); - return NULL; - } - - /* Now try to set its default value */ - - if (_PYVALUE) { - if (strcmp(type,"int") == 0) { - int *ip,i,ivalue; - ivalue = (int) PyInt_AsLong(_PYVALUE); - ip = (int *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"short") == 0) { - short *ip,ivalue; - int i; - ivalue = (short) PyInt_AsLong(_PYVALUE); - ip = (short *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"long") == 0) { - long *ip,ivalue; - int i; - ivalue = (long) PyInt_AsLong(_PYVALUE); - ip = (long *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"double") == 0) { - double *ip,ivalue; - int i; - ivalue = (double) PyFloat_AsDouble(_PYVALUE); - ip = (double *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"float") == 0) { - float *ip,ivalue; - int i; - ivalue = (float) PyFloat_AsDouble(_PYVALUE); - ip = (float *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"char") == 0) { - char *ip,*ivalue; - ivalue = (char *) PyString_AsString(_PYVALUE); - ip = (char *) ptr; - strncpy(ip,ivalue,numelements-1); - } else if (strcmp(type,"char *") == 0) { - char **ip, *ivalue; - int i; - ivalue = (char *) PyString_AsString(_PYVALUE); - ip = (char **) ptr; - for (i = 0; i < numelements; i++) { - if (ivalue) { - ip[i] = (char *) malloc(strlen(ivalue)+1); - strcpy(ip[i],ivalue); - } else { - ip[i] = 0; - } - } - ip[numelements] = 0; - } - } - /* Create the pointer value */ - - obj = SWIG_NewPointerObj(ptr,cast); - return obj; -} - - -/*------------------------------------------------------------------ - ptrset(ptr,value,index = 0,type = 0) - - Attempts to set the value of a pointer variable. If type is - given, we will use that type. Otherwise, we'll guess the datatype. - ------------------------------------------------------------------ */ - -static PyObject *ptrset(PyObject *_PTRVALUE, PyObject *_PYVALUE, int index, char *type) { - void *ptr; - PyObject *obj; - - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,0,0)) { - PyErr_SetString(PyExc_TypeError,"Type error in ptrset. Argument is not a valid pointer value."); - return NULL; - } - - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - /* No datatype was passed. Type to figure out if it's a common one */ - if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_int_p,0)) { - type = "int"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_double_p,0)) { - type = "double"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_short_p,0)) { - type = "short"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_long_p,0)) { - type = "long"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_float_p,0)) { - type = "float"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_p,0)) { - type = "char"; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_pp,0)) { - type = "char *"; - } else { - type = "unknown"; - } - } - if (!ptr) { - PyErr_SetString(PyExc_TypeError,"Unable to set NULL pointer."); - return NULL; - } - - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - *(((int *) ptr)+index) = (int) PyInt_AsLong(_PYVALUE); - } else if (strcmp(type,"double") == 0) { - *(((double *) ptr)+index) = (double) PyFloat_AsDouble(_PYVALUE); - } else if (strcmp(type,"short") == 0) { - *(((short *) ptr)+index) = (short) PyInt_AsLong(_PYVALUE); - } else if (strcmp(type,"long") == 0) { - *(((long *) ptr)+index) = (long) PyInt_AsLong(_PYVALUE); - } else if (strcmp(type,"float") == 0) { - *(((float *) ptr)+index) = (float) PyFloat_AsDouble(_PYVALUE); - } else if (strcmp(type,"char") == 0) { - char *c = PyString_AsString(_PYVALUE); - strcpy(((char *) ptr)+index, c); - } else if (strcmp(type,"char *") == 0) { - char *c = PyString_AsString(_PYVALUE); - char **ca = (char **) ptr; - if (ca[index]) free(ca[index]); - if (strcmp(c,"NULL") == 0) { - ca[index] = 0; - } else { - ca[index] = (char *) malloc(strlen(c)+1); - strcpy(ca[index],c); - } - } else { - PyErr_SetString(PyExc_TypeError,"Unable to set unsupported datatype."); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; -} - -/*------------------------------------------------------------------ - ptradd(ptr,offset) - - Adds a value to an existing pointer value. Will do a type-dependent - add for basic datatypes. For other datatypes, will do a byte-add. - ------------------------------------------------------------------ */ - -static PyObject *ptradd(PyObject *_PTRVALUE, int offset) { - - char *r; - void *ptr,*junk; - PyObject *obj; - swig_type_info *type; - - /* Check to see what kind of object _PTRVALUE is */ - - /* Try to handle a few common datatypes first */ - if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_int_p,0)) { - ptr = (void *) (((int *) ptr) + offset); - type = SWIG_POINTER_int_p; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_double_p,0)) { - ptr = (void *) (((double *) ptr) + offset); - type = SWIG_POINTER_double_p; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_short_p,0)) { - ptr = (void *) (((short *) ptr) + offset); - type = SWIG_POINTER_short_p; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_long_p,0)) { - ptr = (void *) (((long *) ptr) + offset); - type = SWIG_POINTER_long_p; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_float_p,0)) { - ptr = (void *) (((float *) ptr) + offset); - type = SWIG_POINTER_float_p; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_p,0)) { - ptr = (void *) (((char *) ptr) + offset); - type = SWIG_POINTER_char_p; - } else if (!SWIG_ConvertPtr(_PTRVALUE,&ptr,SWIG_POINTER_char_pp,0)) { - ptr = (void *) (((char *) ptr) + offset); - type = SWIG_POINTER_char_pp; - } else { - PyErr_SetString(PyExc_TypeError,"Type error in ptradd. Argument is not a valid pointer value."); - return NULL; - } - obj = SWIG_NewPointerObj(ptr, type); - return obj; -} - -/*------------------------------------------------------------------ - ptrfree(ptr) - - Destroys a pointer value - ------------------------------------------------------------------ */ - -PyObject *ptrfree(PyObject *_PTRVALUE) { - void *ptr, *junk; - - if (SWIG_ConvertPtr(_PTRVALUE,&ptr,0,0)) { - PyErr_SetString(PyExc_TypeError,"Type error in ptrfree. Argument is not a valid pointer value."); - return NULL; - } - - /* Check to see if this pointer is a char ** */ - if (!SWIG_ConvertPtr(_PTRVALUE,&junk,SWIG_POINTER_char_pp,0)) { - char **c = (char **) ptr; - if (c) { - int i = 0; - while (c[i]) { - free(c[i]); - i++; - } - } - } - if (ptr) - free((char *) ptr); - - Py_INCREF(Py_None); - return Py_None; -} - -%} -%typemap(python,in) PyObject *ptr, PyObject *value { - $target = $source; -} - -%typemap(python,out) PyObject *ptrcast, - PyObject *ptrvalue, - PyObject *ptrcreate, - PyObject *ptrset, - PyObject *ptradd, - PyObject *ptrfree -{ - $target = $source; -} - -%typemap(python,ret) int ptrset { - if ($source == -1) return NULL; -} - -PyObject *ptrvalue(PyObject *ptr, int index = 0, char *type = 0); -// Returns the value that a pointer is pointing to (ie. dereferencing). -// The type is automatically inferred by the pointer type--thus, an -// integer pointer will return an integer, a double will return a double, -// and so on. The index and type fields are optional parameters. When -// an index is specified, this function returns the value of ptr[index]. -// This allows array access. When a type is specified, it overrides -// the given pointer type. Examples : -// -// ptrvalue(a) # Returns the value *a -// ptrvalue(a,10) # Returns the value a[10] -// ptrvalue(a,10,"double") # Returns a[10] assuming a is a double * - -PyObject *ptrset(PyObject *ptr, PyObject *value, int index = 0, char *type = 0); -// Sets the value pointed to by a pointer. The type is automatically -// inferred from the pointer type so this function will work for -// integers, floats, doubles, etc... The index and type fields are -// optional. When an index is given, it provides array access. When -// type is specified, it overrides the given pointer type. Examples : -// -// ptrset(a,3) # Sets the value *a = 3 -// ptrset(a,3,10) # Sets a[10] = 3 -// ptrset(a,3,10,"int") # Sets a[10] = 3 assuming a is a int * - -PyObject *ptrcreate(char *type, PyObject *value = 0, int nitems = 1); -// Creates a new object and returns a pointer to it. This function -// can be used to create various kinds of objects for use in C functions. -// type specifies the basic C datatype to create and value is an -// optional parameter that can be used to set the initial value of the -// object. nitems is an optional parameter that can be used to create -// an array. This function results in a memory allocation using -// malloc(). Examples : -// -// a = ptrcreate("double") # Create a new double, return pointer -// a = ptrcreate("int",7) # Create an integer, set value to 7 -// a = ptrcreate("int",0,1000) # Create an integer array with initial -// # values all set to zero -// -// This function only recognizes a few common C datatypes as listed below : -// -// int, short, long, float, double, char, char *, void -// -// All other datatypes will result in an error. However, other -// datatypes can be created by using the ptrcast function. For -// example: -// -// a = ptrcast(ptrcreate("int",0,100),"unsigned int *") - -PyObject *ptrfree(PyObject *ptr); -// Destroys the memory pointed to by ptr. This function calls free() -// and should only be used with objects created by ptrcreate(). Since -// this function calls free, it may work with other objects, but this -// is generally discouraged unless you absolutely know what you're -// doing. - -PyObject *ptradd(PyObject *ptr, int offset); -// Adds a value to the current pointer value. For the C datatypes of -// int, short, long, float, double, and char, the offset value is the -// number of objects and works in exactly the same manner as in C. For -// example, the following code steps through the elements of an array -// -// a = ptrcreate("double",0,100); # Create an array double a[100] -// b = a; -// for i in range(0,100): -// ptrset(b,0.0025*i); # set *b = 0.0025*i -// b = ptradd(b,1); # b++ (go to next double) -// -// In this case, adding one to b goes to the next double. -// -// For all other datatypes (including all complex datatypes), the -// offset corresponds to bytes. This function does not perform any -// bounds checking and negative offsets are perfectly legal. - - - diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg new file mode 100644 index 000000000..1b770bde0 --- /dev/null +++ b/Lib/python/pyrun.swg @@ -0,0 +1,416 @@ +/*********************************************************************** + * python.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * Author : David Beazley (beazley@cs.uchicago.edu) + ************************************************************************/ + +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SWIG_PY_INT 1 +#define SWIG_PY_FLOAT 2 +#define SWIG_PY_STRING 3 +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Flags for pointer conversion */ + +#define SWIG_POINTER_EXCEPTION 0x1 +#define SWIG_POINTER_DISOWN 0x2 + +/* Exception handling in wrappers */ +#define SWIG_fail goto fail + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef SWIG_NOINCLUDE + +SWIGEXPORT(PyObject *) SWIG_newvarlink(); +SWIGEXPORT(void) SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); +SWIGEXPORT(int) SWIG_ConvertPtr(PyObject *, void **, swig_type_info *, int); +SWIGEXPORT(int) SWIG_ConvertPacked(PyObject *, void *, int sz, swig_type_info *, int); +SWIGEXPORT(char *) SWIG_PackData(char *c, void *, int); +SWIGEXPORT(char *) SWIG_UnpackData(char *c, void *, int); +SWIGEXPORT(PyObject *) SWIG_NewPointerObj(void *, swig_type_info *,int own); +SWIGEXPORT(PyObject *) SWIG_NewPackedObj(void *, int sz, swig_type_info *); +SWIGEXPORT(void) SWIG_InstallConstants(PyObject *d, swig_const_info constants[]); +#else + +/* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + +typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; +} swig_globalvar; + +typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; +} swig_varlinkobject; + +static PyObject * +swig_varlink_repr(swig_varlinkobject *v) { + v = v; + return PyString_FromString(""); +} + +static int +swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) { + swig_globalvar *var; + flags = flags; + fprintf(fp,"Global variables { "); + for (var = v->vars; var; var=var->next) { + fprintf(fp,"%s", var->name); + if (var->next) fprintf(fp,", "); + } + fprintf(fp," }\n"); + return 0; +} + +static PyObject * +swig_varlink_getattr(swig_varlinkobject *v, char *n) { + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + return (*var->get_attr)(); + } + var = var->next; + } + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + return NULL; +} + +static int +swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + return (*var->set_attr)(p); + } + var = var->next; + } + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + return 1; +} + +statichere PyTypeObject varlinktype = { + PyObject_HEAD_INIT(0) + 0, + (char *)"swigvarlink", /* Type name */ + sizeof(swig_varlinkobject), /* Basic size */ + 0, /* Itemsize */ + 0, /* Deallocator */ + (printfunc) swig_varlink_print, /* Print */ + (getattrfunc) swig_varlink_getattr, /* get attr */ + (setattrfunc) swig_varlink_setattr, /* Set attr */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_mapping*/ + 0, /* tp_hash */ +}; + +/* Create a variable linking object for use later */ +SWIGRUNTIME(PyObject *) +SWIG_newvarlink(void) { + swig_varlinkobject *result = 0; + result = PyMem_NEW(swig_varlinkobject,1); + varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ + result->ob_type = &varlinktype; + result->vars = 0; + result->ob_refcnt = 0; + Py_XINCREF((PyObject *) result); + return ((PyObject*) result); +} + +SWIGRUNTIME(void) +SWIG_addvarlink(PyObject *p, char *name, + PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v; + swig_globalvar *gv; + v= (swig_varlinkobject *) p; + gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + gv->name = (char *) malloc(strlen(name)+1); + strcpy(gv->name,name); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + v->vars = gv; +} + +/* Pack binary data into a string */ +SWIGRUNTIME(char *) +SWIG_PackData(char *c, void *ptr, int sz) { + static char hex[17] = "0123456789abcdef"; + int i; + unsigned char *u = (unsigned char *) ptr; + register unsigned char uu; + for (i = 0; i < sz; i++,u++) { + uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* Unpack binary data from a string */ +SWIGRUNTIME(char *) +SWIG_UnpackData(char *c, void *ptr, int sz) { + register unsigned char uu = 0; + register int d; + unsigned char *u = (unsigned char *) ptr; + int i; + for (i = 0; i < sz; i++, u++) { + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + *u = uu; + } + return c; +} + +/* Convert a pointer value */ +SWIGRUNTIME(int) +SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { + swig_type_info *tc; + char *c; + static PyObject *SWIG_this = 0; + int newref = 0; + PyObject *pyobj = 0; + + if (!obj) return 0; + if (obj == Py_None) { + *ptr = 0; + return 0; + } +#ifdef SWIG_COBJECT_TYPES + if (!(PyCObject_Check(obj))) { + if (!SWIG_this) + SWIG_this = PyString_FromString("this"); + pyobj = obj; + obj = PyObject_GetAttr(obj,SWIG_this); + newref = 1; + if (!obj) goto type_error; + if (!PyCObject_Check(obj)) { + Py_DECREF(obj); + goto type_error; + } + } + *ptr = PyCObject_AsVoidPtr(obj); + c = (char *) PyCObject_GetDesc(obj); + if (newref) Py_DECREF(obj); + goto cobject; +#else + if (!(PyString_Check(obj))) { + if (!SWIG_this) + SWIG_this = PyString_FromString("this"); + pyobj = obj; + obj = PyObject_GetAttr(obj,SWIG_this); + newref = 1; + if (!obj) goto type_error; + if (!PyString_Check(obj)) { + Py_DECREF(obj); + goto type_error; + } + } + c = PyString_AsString(obj); + /* Pointer values must start with leading underscore */ + if (*c != '_') { + *ptr = (void *) 0; + if (strcmp(c,"NULL") == 0) { + if (newref) { Py_DECREF(obj); } + return 0; + } else { + if (newref) { Py_DECREF(obj); } + goto type_error; + } + } + c++; + c = SWIG_UnpackData(c,ptr,sizeof(void *)); + if (newref) { Py_DECREF(obj); } +#endif + +#ifdef SWIG_COBJECT_TYPES +cobject: +#endif + + if (ty) { + tc = SWIG_TypeCheck(c,ty); + if (!tc) goto type_error; + *ptr = SWIG_TypeCast(tc,(void*) *ptr); + } + + if ((pyobj) && (flags & SWIG_POINTER_DISOWN)) { + PyObject *zero = PyInt_FromLong(0); + PyObject_SetAttrString(pyobj,(char*)"thisown",zero); + Py_DECREF(zero); + } + return 0; + +type_error: + if (flags & SWIG_POINTER_EXCEPTION) { + if (ty) { + char *temp = (char *) malloc(64+strlen(ty->name)); + sprintf(temp,"Type error. Expected %s", ty->name); + PyErr_SetString(PyExc_TypeError, temp); + free((char *) temp); + } else { + PyErr_SetString(PyExc_TypeError,"Expected a pointer"); + } + } + return -1; +} + +/* Convert a packed value value */ +SWIGRUNTIME(int) +SWIG_ConvertPacked(PyObject *obj, void *ptr, int sz, swig_type_info *ty, int flags) { + swig_type_info *tc; + char *c; + + if ((!obj) || (!PyString_Check(obj))) goto type_error; + c = PyString_AsString(obj); + /* Pointer values must start with leading underscore */ + if (*c != '_') goto type_error; + c++; + c = SWIG_UnpackData(c,ptr,sz); + if (ty) { + tc = SWIG_TypeCheck(c,ty); + if (!tc) goto type_error; + } + return 0; + +type_error: + + if (flags) { + if (ty) { + char *temp = (char *) malloc(64+strlen(ty->name)); + sprintf(temp,"Type error. Expected %s", ty->name); + PyErr_SetString(PyExc_TypeError, temp); + free((char *) temp); + } else { + PyErr_SetString(PyExc_TypeError,"Expected a pointer"); + } + } + return -1; +} + +/* Create a new pointer object */ +SWIGRUNTIME(PyObject *) +SWIG_NewPointerObj(void *ptr, swig_type_info *type, int own) { + PyObject *robj; + if (!ptr) { + Py_INCREF(Py_None); + return Py_None; + } +#ifdef SWIG_COBJECT_TYPES + robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, (char *) type->name, NULL); +#else + { + char result[1024]; + char *r = result; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + strcpy(r,type->name); + robj = PyString_FromString(result); + } +#endif + if (!robj || (robj == Py_None)) return robj; + if (type->clientdata) { + PyObject *inst; + PyObject *args = Py_BuildValue((char*)"(O)", robj); + Py_DECREF(robj); + inst = PyObject_CallObject((PyObject *) type->clientdata, args); + Py_DECREF(args); + if (inst) { + if (own) { + PyObject *n = PyInt_FromLong(1); + PyObject_SetAttrString(inst,(char*)"thisown",n); + Py_DECREF(n); + } + robj = inst; + } + } + return robj; +} + +SWIGRUNTIME(PyObject *) +SWIG_NewPackedObj(void *ptr, int sz, swig_type_info *type) { + char result[1024]; + char *r = result; + if ((2*sz + 1 + strlen(type->name)) > 1000) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + strcpy(r,type->name); + return PyString_FromString(result); +} + +/* Install Constants */ +SWIGRUNTIME(void) +SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { + int i; + PyObject *obj; + for (i = 0; constants[i].type; i++) { + switch(constants[i].type) { + case SWIG_PY_INT: + obj = PyInt_FromLong(constants[i].lvalue); + break; + case SWIG_PY_FLOAT: + obj = PyFloat_FromDouble(constants[i].dvalue); + break; + case SWIG_PY_STRING: + obj = PyString_FromString((char *) constants[i].pvalue); + break; + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d,constants[i].name,obj); + Py_DECREF(obj); + } + } +} + +#endif + +#ifdef __cplusplus +} +#endif + + + + + + diff --git a/Lib/python/python.swg b/Lib/python/python.swg index d0fc9a6c1..2c5a03aee 100644 --- a/Lib/python/python.swg +++ b/Lib/python/python.swg @@ -1,321 +1,627 @@ -/*********************************************************************** +/* ----------------------------------------------------------------------------- * python.swg * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - ************************************************************************/ - -#include -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SWIG_PY_INT 1 -#define SWIG_PY_FLOAT 2 -#define SWIG_PY_STRING 3 -#define SWIG_PY_POINTER 4 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef SWIG_NOINCLUDE - -SWIGEXPORT(PyObject *) SWIG_newvarlink(); -SWIGEXPORT(void) SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); -SWIGEXPORT(int) SWIG_ConvertPtr(PyObject *, void **, swig_type_info *, int); -SWIGEXPORT(void) SWIG_MakePtr(char *c, void *, swig_type_info *); -SWIGEXPORT(PyObject *) SWIG_NewPointerObj(void *, swig_type_info *); -SWIGEXPORT(void) SWIG_InstallConstants(PyObject *d, swig_const_info constants[]); - -#else - -/* ----------------------------------------------------------------------------- - * global variable support code. + * Python configuration module. * ----------------------------------------------------------------------------- */ -typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; -} swig_globalvar; +/* Python.h has to appear first */ -typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; -} swig_varlinkobject; +%insert(runtime) %{ +#include "Python.h" +%} -static PyObject * -swig_varlink_repr(swig_varlinkobject *v) { - v = v; - return PyString_FromString(""); +%insert(runtime) "common.swg"; // Common type-checking code +%insert(runtime) "pyrun.swg"; // Python run-time code + +/* Special directive for shadow code */ + +#define %shadow %insert("shadow") +#define %pythoncode %insert("python") + +/* ----------------------------------------------------------------------------- + * standard typemaps + * ----------------------------------------------------------------------------- */ + +/* --- Input arguments --- */ + +/* Primitive datatypes. These only supply a parse code to PyTuple_ParseArgs */ + +%typemap(in,parse="i") int ""; +%typemap(in,parse="h") short ""; +%typemap(in,parse="l") long ""; +%typemap(in,parse="b") signed char ""; + +%typemap(in) unsigned int, unsigned short, unsigned long, unsigned char + "$1 = ($1_ltype) PyInt_AsLong($input); + if (PyErr_Occurred()) SWIG_fail;"; + +%typemap(in) long long + "$1 = (long long) PyLong_AsLongLong($input); + if (PyErr_Occurred()) SWIG_fail;"; + + +%typemap(in) unsigned long long + "$1 = (unsigned long long) PyLong_AsUnsignedLongLong($input); + if (PyErr_Occurred()) SWIG_fail;"; + +%typemap(in,parse="f") float ""; +%typemap(in,parse="d") double ""; +%typemap(in,parse="c") char ""; +%typemap(in,parse="s") char *, char [ANY] ""; + +/* Boolean values. Have to convert from a long since */ +%typemap(in) bool "$1 = (bool) PyInt_AsLong($input); + if (PyErr_Occurred()) SWIG_fail;"; + +/* Enum values. */ +%typemap(in,parse="i") enum SWIGTYPE ""; + +/* Pointers, references, and arrays */ +%typemap(in) SWIGTYPE *, + SWIGTYPE [] + "if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) SWIG_fail;" + +/* Additional check for null references */ +%typemap(in) SWIGTYPE & + "if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) SWIG_fail; + if ($1 == NULL) { PyErr_SetString(PyExc_TypeError,\"null reference\"); SWIG_fail; }" + +/* Void pointer. Accepts any kind of pointer */ +%typemap(in) void * "if ((SWIG_ConvertPtr($input,(void **) &$1, 0, SWIG_POINTER_EXCEPTION | $disown )) == -1) SWIG_fail;" + +/* Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE ($&1_ltype argp) "if ((SWIG_ConvertPtr($input,(void **) &argp, $&1_descriptor,SWIG_POINTER_EXCEPTION) == -1)) SWIG_fail; + $1 = *argp; "; + +/* Pointer to a class member */ +%typemap(in) SWIGTYPE (CLASS::*) "if ((SWIG_ConvertPacked($input, (void *) &$1, sizeof($1_type), $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) SWIG_fail;"; + +/* Const primitive references. Passed by value */ + +%typemap(in) const int & (int temp), + const short & (short temp), + const long & (long temp), + const unsigned int & (unsigned int temp), + const unsigned short & (unsigned short temp), + const unsigned long & (unsigned long temp), + const signed char & (signed char temp), + const unsigned char & (unsigned char temp), + const bool & (bool temp) + "temp = ($*1_ltype) PyInt_AsLong($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp;"; + +%typemap(in) const float & (float temp), + const double & (double temp) + "temp = ($*1_ltype) PyFloat_AsDouble($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp;"; + +%typemap(in) const long long & (long long temp) + "temp = (long long) PyLong_AsLongLong($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp;"; + +%typemap(in) const unsigned long long & (unsigned long long temp) + "temp = (unsigned long long) PyLong_AsUnsignedLongLong($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp;"; + +%typemap(in) const char &(char temp) { + char *stemp = PyString_AsString($input); + if (PyErr_Occurred()) SWIG_fail; + temp = *stemp; + $1 = &temp; } -static int -swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) { - swig_globalvar *var; - flags = flags; - fprintf(fp,"Global variables { "); - for (var = v->vars; var; var=var->next) { - fprintf(fp,"%s", var->name); - if (var->next) fprintf(fp,", "); - } - fprintf(fp," }\n"); - return 0; +/* --- Output values --- */ + +%typemap(out) int, unsigned int, + short, unsigned short, + long, unsigned long, + signed char, unsigned char, + bool, enum SWIGTYPE + "$result = PyInt_FromLong((long)$1);"; + +%typemap(out) long long "$result = PyLong_FromLongLong($1);"; +%typemap(out) unsigned long long "$result = PyLong_FromUnsignedLongLong($1);"; +%typemap(out) float, double "$result = PyFloat_FromDouble($1);"; +%typemap(out) char * "$result = $1 ? PyString_FromString($1) : Py_BuildValue((char*)\"\");"; +%typemap(out) char "$result = Py_BuildValue((char*)\"c\",$1);"; + +/* Pointers, references, and arrays */ +%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor, $owner);"; + +/* Dynamic casts */ + +%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); + $result = SWIG_NewPointerObj((void *) $1, ty, $owner); } -static PyObject * -swig_varlink_getattr(swig_varlinkobject *v, char *n) { - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - return (*var->get_attr)(); - } - var = var->next; +/* Member pointer */ +%typemap(out) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor);"; + +/* Void */ +%typemap(out) void "Py_INCREF(Py_None); $result = Py_None;"; + +/* Special typemap for character array return values */ +%typemap(out) char [ANY], const char [ANY] "$result = PyString_FromString($1);"; + +/* Primitive types--return by value */ +%typemap(out) SWIGTYPE +#ifdef __cplusplus +{ + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); +} +#else +{ + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); +} +#endif + +/* References to primitive types. Return by value */ + +%typemap(out) const int &, const unsigned int &, + const short &, const unsigned short &, + const long &, const unsigned long &, + const signed char &, const unsigned char &, + const bool & + "$result = PyInt_FromLong((long) *($1));"; + +%typemap(out) const float &, const double & + "$result = PyFloat_FromDouble((double) *($1));"; + +%typemap(out) const long long & + "$result = PyLong_FromLongLong(*($1));"; + +%typemap(out) const unsigned long long & + "$result = PyLong_FromUnsignedLongLong(*($1));"; + +%typemap(out) const char & + "$result = PyString_FromStringAndSize($1,1);"; + +/* --- Variable input --- */ + +%typemap(varin) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE +{ + long temp = PyInt_AsLong($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; } - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - return NULL; + $1 = ($1_type) temp; } -static int -swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - return (*var->set_attr)(p); - } - var = var->next; +%typemap(varin) long long { + long long temp = PyLong_AsLongLong($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = temp; +} + +%typemap(varin) unsigned long long { + unsigned long long temp = PyLong_AsUnsignedLongLong($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = temp; +} + +%typemap(varin) float, double { + double temp = PyFloat_AsDouble($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; } - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + $1 = ($1_ltype) temp; +} + +/* A single character */ +%typemap(varin) char { + char *temp = PyString_AsString($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = *temp; +} + +/* A string */ +#ifdef __cplusplus +%typemap(varin) char * { + char *temp = (char *) PyString_AsString($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + if ($1) delete [] $1; + $1 = ($type) new char[strlen(temp)+1]; + strcpy((char*)$1,temp); +} +%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { + char *temp = (char *) PyString_AsString($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = ($type) new char[strlen(temp)+1]; + strcpy((char*)$1,temp); +} +#else +%typemap(varin) char * { + char *temp = (char *) PyString_AsString($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + if ($1) free((char*) $1); + $1 = ($type) malloc(strlen(temp)+1); + strcpy((char*)$1,temp); +} +%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { + char *temp = (char *) PyString_AsString($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = ($type) malloc(strlen(temp)+1); + strcpy((char*)$1,temp); +} +#endif + +%typemap(varin) SWIGTYPE [] { + PyErr_SetString(PyExc_TypeError, "Variable $name is read-only."); return 1; } -statichere PyTypeObject varlinktype = { - PyObject_HEAD_INIT(0) - 0, - "swigvarlink", /* Type name */ - sizeof(swig_varlinkobject), /* Basic size */ - 0, /* Itemsize */ - 0, /* Deallocator */ - (printfunc) swig_varlink_print, /* Print */ - (getattrfunc) swig_varlink_getattr, /* get attr */ - (setattrfunc) swig_varlink_setattr, /* Set attr */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_mapping*/ - 0, /* tp_hash */ -}; - -/* Create a variable linking object for use later */ -SWIGRUNTIME(PyObject *) -SWIG_newvarlink(void) { - swig_varlinkobject *result = 0; - result = PyMem_NEW(swig_varlinkobject,1); - varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ - result->ob_type = &varlinktype; - result->vars = 0; - result->ob_refcnt = 0; - Py_XINCREF((PyObject *) result); - return ((PyObject*) result); +/* Special case for string array variables */ +%typemap(varin) char [ANY] { + char *temp = (char *) PyString_AsString($input); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + strncpy($1,temp,$1_dim0); } -SWIGRUNTIME(void) -SWIG_addvarlink(PyObject *p, char *name, - PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v; - swig_globalvar *gv; - v= (swig_varlinkobject *) p; - gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - gv->name = (char *) malloc(strlen(name)+1); - strcpy(gv->name,name); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - v->vars = gv; -} -/* Convert a pointer value */ -SWIGRUNTIME(int) -SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { - unsigned long p; - register int d; - swig_type_info *tc; - char *c; - static PyObject *SWIG_this = 0; - int newref = 0; - - if (!obj || (obj == Py_None)) { - return 0; +%typemap(varin) SWIGTYPE * { + void *temp; + if ((SWIG_ConvertPtr($input,(void **) &temp, $1_descriptor, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN)) == -1) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; } -#ifdef SWIG_COBJECT_TYPES - if (!(PyCObject_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_InternFromString("this"); - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyCObject_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - *ptr = PyCObject_AsVoidPtr(obj); - c = (char *) PyCObject_GetDesc(obj); - if (newref) Py_DECREF(obj); - goto cobject; -#else - if (!(PyString_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_InternFromString("this"); - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyString_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - c = PyString_AsString(obj); - p = 0; - /* Pointer values must start with leading underscore */ - if (*c != '_') { - *ptr = (void *) 0; - if (strcmp(c,"NULL") == 0) { - if (newref) { Py_DECREF(obj); } - return 0; - } else { - if (newref) { Py_DECREF(obj); } - goto type_error; - } - } - c++; - /* Extract hex value from pointer */ - while ((d = *c)) { - if ((d >= '0') && (d <= '9')) - p = (p << 4) + (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - p = (p << 4) + (d - ('a'-10)); - else - break; - c++; - } - *ptr = (void *) p; - if (newref) { Py_DECREF(obj); } -#endif - -#ifdef SWIG_COBJECT_TYPES -cobject: -#endif - - if (ty) { - tc = SWIG_TypeCheck(c,ty); - if (!tc) goto type_error; - *ptr = SWIG_TypeCast(tc,(void*)p); - } - return 0; - -type_error: - - if (flags) { - if (ty) { - char *temp = (char *) malloc(64+strlen(ty->name)); - sprintf(temp,"Type error. Expected %s", ty->name); - PyErr_SetString(PyExc_TypeError, temp); - free((char *) temp); - } else { - PyErr_SetString(PyExc_TypeError,"Expected a pointer"); - } - } - return -1; + $1 = ($1_ltype) temp; } -/* Take a pointer and convert it to a string */ -SWIGRUNTIME(void) -SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) { - static char hex[17] = "0123456789abcdef"; - unsigned long p, s; - char result[32], *r; - r = result; - p = (unsigned long) ptr; - if (p > 0) { - while (p > 0) { - s = p & 0xf; - *(r++) = hex[s]; - p = p >> 4; - } - *r = '_'; - while (r >= result) - *(c++) = *(r--); - strcpy (c, ty->name); +%typemap(varin) SWIGTYPE & { + void *temp; + if ((SWIG_ConvertPtr($input,(void **) &temp, $1_descriptor, SWIG_POINTER_EXCEPTION)) == -1 || temp == NULL) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = ($1_ltype) temp; +} + +%typemap(varin) void * { + void * temp; + if ((SWIG_ConvertPtr($input,(void **) &temp, 0, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN)) == -1) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = ($1_ltype) temp; +} + +%typemap(varin) SWIGTYPE (CLASS::*) { + char temp[sizeof($1_type)]; + if ((SWIG_ConvertPacked($input,(void *) temp, sizeof($1_type), $1_descriptor, SWIG_POINTER_EXCEPTION)) == -1) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + memmove((void *) &$1,temp,sizeof($1_type)); +} + +%typemap(varin) SWIGTYPE { + $&1_ltype temp; + if ((SWIG_ConvertPtr($input, (void **) &temp, $&1_descriptor, SWIG_POINTER_EXCEPTION)) == -1) { + PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); + return 1; + } + $1 = *(($&1_type) temp); +} + +/* --- Variable output --- */ + +%typemap(varout) int, unsigned int, + short, unsigned short, + long, unsigned long, + signed char, unsigned char, + bool, enum SWIGTYPE + "$result = PyInt_FromLong((long)$1);"; + +%typemap(varout) long long "$result = PyLong_FromLongLong($1);"; +%typemap(varout) unsigned long long "$result = PyLong_FromUnsignedLongLong($1);"; +%typemap(varout) float, double "$result = PyFloat_FromDouble($1);"; +%typemap(varout) char * "$result = $1 ? PyString_FromString($1) : Py_BuildValue((char*)\"\");"; +%typemap(varout) char "$result = Py_BuildValue((char*)\"c\",$1);"; + +/* Pointers, references, and arrays */ +%typemap(varout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor, 0);"; + +/* Member pointer */ +%typemap(varout) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor);"; + +/* Void */ +%typemap(varout) void "Py_INCREF(Py_None); $result = Py_None;"; + +/* Special typemap for character array return values */ +%typemap(varout) char [ANY], const char [ANY] "$result = PyString_FromString($1);"; + +%typemap(varout) SWIGTYPE "$result = SWIG_NewPointerObj((void *) &$1, $&1_descriptor, 0);"; + +/* --- Constants --- */ + +%typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE + { SWIG_PY_INT, (char *)"$symname", (long) $value, 0, 0, 0} + +%typemap(consttab) float, double + { SWIG_PY_FLOAT, (char*)"$symname", 0, (double) $value, 0, 0} + +%typemap(consttab) char, char * + { SWIG_PY_STRING, (char*)"$symname", 0, 0, (void *)"$value", 0} + +%typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + { SWIG_PY_POINTER, (char*)"$symname", 0, 0, (void *)$value, &$1_descriptor} + +%typemap(consttab) SWIGTYPE (CLASS::*) + { SWIG_PY_BINARY, (char *)"$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor} + +%typemap(constcode) long long "PyDict_SetItemString(d,\"$symname\", PyLong_FromLongLong($value));"; +%typemap(constcode) unsigned long long "PyDict_SetItemString(d,\"$symname\", PyLong_FromUnsignedLongLong($value));"; + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +%typemap(in) (char *STRING, int LENGTH) { + $1 = ($1_ltype) PyString_AsString($input); + $2 = ($2_ltype) PyString_Size($input); +} + +/* ------------------------------------------------------------ + * ANSI C typemaps + * ------------------------------------------------------------ */ + +%typemap(in) size_t "$1 = (size_t) PyInt_AsLong($input); + if (PyErr_Occurred()) SWIG_fail;"; + +%typemap(out) size_t = long; +%typemap(varin) size_t = long; +%typemap(varout) size_t = long; +%typemap(consttab) size_t = long; + +/* ------------------------------------------------------------ + * PyObject * - Just pass straight through unmodified + * ------------------------------------------------------------ */ + +%typemap(in) PyObject * "$1 = $input;"; +%typemap(out) PyObject * "$result = $1;"; + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE, + bool, const bool & +{ + $1 = (PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = (PyFloat_Check($input) || PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + $1 = (PyString_Check($input) && (PyString_Size($input) == 1)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = PyString_Check($input) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == -1) { + $1 = 0; + PyErr_Clear(); } else { - strcpy (c, "NULL"); + $1 = 1; } } -/* Create a new pointer object */ -SWIGRUNTIME(PyObject *) -SWIG_NewPointerObj(void *ptr, swig_type_info *type) { - char result[512]; - PyObject *robj; - if (!ptr) { - Py_INCREF(Py_None); - return Py_None; - } -#ifdef SWIG_COBJECT_TYPES - robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, type->name, NULL); -#else - SWIG_MakePtr(result,ptr,type); - robj = PyString_FromString(result); -#endif - return robj; -} - -/* Install Constants */ -SWIGRUNTIME(void) -SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { - int i; - PyObject *obj; - for (i = 0; constants[i].type; i++) { - switch(constants[i].type) { - case SWIG_PY_INT: - obj = PyInt_FromLong(constants[i].lvalue); - break; - case SWIG_PY_FLOAT: - obj = PyFloat_FromDouble(constants[i].dvalue); - break; - case SWIG_PY_STRING: - obj = PyString_FromString((char *) constants[i].pvalue); - break; - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d,constants[i].name,obj); - Py_DECREF(obj); - } +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + if (SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 0) == -1) { + $1 = 0; + PyErr_Clear(); + } else { + $1 = 1; } } -#endif +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0) == -1) { + $1 = 0; + PyErr_Clear(); + } else { + $1 = 1; + } +} + +/* ------------------------------------------------------------ + * Exception handling + * ------------------------------------------------------------ */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + PyErr_SetObject(PyExc_RuntimeError, PyInt_FromLong((long) $1)); + SWIG_fail; +} + +%typemap(throws) SWIGTYPE CLASS { + $&1_ltype temp = new $1_ltype($1); + if ($&1_descriptor->clientdata) { + PyErr_SetObject((PyObject *) ($&1_descriptor->clientdata), SWIG_NewPointerObj(temp,$&1_descriptor,1)); + } else { + PyErr_SetObject(PyExc_RuntimeError, SWIG_NewPointerObj(temp,$&1_descriptor,1)); + } + SWIG_fail; +} + +%typemap(throws) SWIGTYPE { + PyErr_SetString(PyExc_RuntimeError,"$1_type"); + SWIG_fail; +} + +%typemap(throws) char * { + PyErr_SetString(PyExc_RuntimeError, $1); + SWIG_fail; +} + +/* ------------------------------------------------------------ + * Overloaded operator support + * ------------------------------------------------------------ */ #ifdef __cplusplus -} +%rename(__add__) *::operator+; +%rename(__pos__) *::operator+(); +%rename(__pos__) *::operator+() const; +%rename(__sub__) *::operator-; +%rename(__neg__) *::operator-(); +%rename(__neg__) *::operator-() const; +%rename(__mul__) *::operator*; +%rename(__div__) *::operator/; +%rename(__mod__) *::operator%; +%rename(__lshift__) *::operator<<; +%rename(__rshift__) *::operator>>; +%rename(__and__) *::operator&; +%rename(__or__) *::operator|; +%rename(__xor__) *::operator^; +%rename(__invert__) *::operator~; +%rename(__iadd__) *::operator+=; +%rename(__isub__) *::operator-=; +%rename(__imul__) *::operator*=; +%rename(__idiv__) *::operator/=; +%rename(__imod__) *::operator%=; +%rename(__ilshift__) *::operator<<=; +%rename(__irshift__) *::operator>>=; +%rename(__iand__) *::operator&=; +%rename(__ior__) *::operator|=; +%rename(__ixor__) *::operator^=; +%rename(__lt__) *::operator<; +%rename(__le__) *::operator<=; +%rename(__gt__) *::operator>; +%rename(__ge__) *::operator>=; +%rename(__eq__) *::operator==; +%rename(__ne__) *::operator!=; + +/* Special cases */ +%rename(__call__) *::operator(); + +/* Ignored operators */ +%ignorewarn("362:operator= ignored") operator=; +%ignorewarn("383:operator++ ignored") operator++; +%ignorewarn("384:operator-- ignored") operator--; +%ignorewarn("381:operator&& ignored") operator&&; +%ignorewarn("382:operator|| ignored") operator||; +%ignorewarn("386:operator->* ignored") operator->*; +%ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; + #endif +/* Warnings for certain Python keywords */ +#define PYKW(x) %namewarn("314:" #x " is a python keyword") #x + +PYKW(and); +PYKW(assert); +PYKW(break); +PYKW(class); +PYKW(continue); +PYKW(def); +PYKW(del); +PYKW(elif); +PYKW(else); +PYKW(except); +PYKW(exec); +PYKW(finally); +PYKW(for); +PYKW(from); +PYKW(global); +PYKW(if); +PYKW(import); +PYKW(in); +PYKW(is); +PYKW(lambda); +PYKW(not); +PYKW(or); +PYKW(pass); +PYKW(print); +PYKW(raise); +PYKW(return); +PYKW(try); +PYKW(while); + + +/* The start of the Python initialization function */ + +%init %{ +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT(void) SWIG_init(void) { + static PyObject *SWIG_globals = 0; + static int typeinit = 0; + PyObject *m, *d; + int i; + if (!SWIG_globals) SWIG_globals = SWIG_newvarlink(); + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + if (!typeinit) { + for (i = 0; swig_types_initial[i]; i++) { + swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); + } + typeinit = 1; + } + SWIG_InstallConstants(d,swig_const_table); +%} + + + + + diff --git a/Lib/python/std_common.i b/Lib/python/std_common.i new file mode 100644 index 000000000..d7b192407 --- /dev/null +++ b/Lib/python/std_common.i @@ -0,0 +1,26 @@ +// +// SWIG typemaps for STL - common utilities +// Luigi Ballabio +// Aug 3, 2002 +// +// Python implementation + +%{ +#include + +PyObject* SwigInt_FromBool(bool b) { + return PyInt_FromLong(b ? 1L : 0L); +} +double SwigNumber_Check(PyObject* o) { + return PyFloat_Check(o) || PyInt_Check(o); +} +double SwigNumber_AsDouble(PyObject* o) { + return (PyFloat_Check(o) ? PyFloat_AsDouble(o) : double(PyInt_AsLong(o))); +} +PyObject* SwigString_FromString(const std::string& s) { + return PyString_FromString(s.c_str()); +} +std::string SwigString_AsString(PyObject* o) { + return std::string(PyString_AsString(o)); +} +%} diff --git a/Lib/python/std_complex.i b/Lib/python/std_complex.i new file mode 100644 index 000000000..703201b70 --- /dev/null +++ b/Lib/python/std_complex.i @@ -0,0 +1,64 @@ +#ifndef __swig_std_complex_i__ +#define __swig_std_complex_i__ + +#ifdef SWIG + +%{ +#include +%} + +namespace std +{ + template class complex; + + %define specialize_std_complex(T) + + %typemap(in) complex { + if (PyComplex_Check($input)) { + $1 = std::complex(PyComplex_RealAsDouble($input), + PyComplex_ImagAsDouble($input)); + } else if (PyFloat_Check($input)) { + $1 = std::complex(PyFloat_AsDouble($input), 0); + } else if (PyInt_Check($input)) { + $1 = std::complex(PyInt_AsLong($input), 0); + } + else { + PyErr_SetString(PyExc_TypeError,"Expected a complex"); + SWIG_fail; + } + } + + %typemap(in) const complex& (std::complex temp) { + if (PyComplex_Check($input)) { + temp = std::complex(PyComplex_RealAsDouble($input), + PyComplex_ImagAsDouble($input)); + $1 = &temp; + } else if (PyFloat_Check($input)) { + temp = std::complex(PyFloat_AsDouble($input), 0); + $1 = &temp; + } else if (PyInt_Check($input)) { + temp = std::complex(PyInt_AsLong($input), 0); + $1 = &temp; + } else { + PyErr_SetString(PyExc_TypeError,"Expected a complex"); + SWIG_fail; + } + } + + %typemap(out) complex { + $result = PyComplex_FromDoubles($1.real(), $1.imag()); + } + + %typemap(out) const complex & { + $result = PyComplex_FromDoubles($1->real(), $1->imag()); + } + + %enddef + + specialize_std_complex(double); + specialize_std_complex(float); +} + +#endif // SWIG + +#endif //__swig_std_complex_i__ diff --git a/Lib/python/std_deque.i b/Lib/python/std_deque.i new file mode 100644 index 000000000..499549cbf --- /dev/null +++ b/Lib/python/std_deque.i @@ -0,0 +1,23 @@ +/* Default std_deque wrapper */ +%module std_deque + +%rename(__getitem__) std::deque::getitem; +%rename(__setitem__) std::deque::setitem; +%rename(__delitem__) std::deque::delitem; +%rename(__getslice__) std::deque::getslice; +%rename(__setslice__) std::deque::setslice; +%rename(__delslice__) std::deque::delslice; + +%extend std::deque { + int __len__() { + return (int) self->size(); + } + int __nonzero__() { + return ! self->empty(); + } + void append(const T &x) { + self->push_back(x); + } +}; + +%include "_std_deque.i" diff --git a/Lib/python/std_list.i b/Lib/python/std_list.i new file mode 100644 index 000000000..1aecfd2af --- /dev/null +++ b/Lib/python/std_list.i @@ -0,0 +1,245 @@ +// +// SWIG typemaps for std::list types +// Jing Cao +// Aug 1st, 2002 +// +// Python implementation + + +%module std_list +%{ +#include +#include +%} + +%include "exception.i" + +%exception std::list::__getitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::list::__setitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::list::__delitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +namespace std{ + template class list + { + public: + + typedef T &reference; + typedef const T& const_reference; + typedef T &iterator; + typedef const T& const_iterator; + + list(); + list(unsigned int size, const T& value = T()); + list(const list &); + + ~list(); + void assign(unsigned int n, const T& value); + void swap(list &x); + + const_reference front(); + const_reference back(); + const_iterator begin(); + const_iterator end(); + + void resize(unsigned int n, T c = T()); + bool empty() const; + + void push_front(const T& x); + void push_back(const T& x); + + + void pop_front(); + void pop_back(); + void clear(); + unsigned int size() const; + unsigned int max_size() const; + void resize(unsigned int n, const T& value); + + void remove(const T& value); + void unique(); + void reverse(); + void sort(); + + + + %extend + { + const_reference __getitem__(int i) + { + std::list::iterator first = self->begin(); + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i::iterator first = self->begin(); + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i::iterator first = self->begin(); + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && ierase(first); + } + else throw std::out_of_range("list index out of range"); + } + std::list __getslice__(int i,int j) + { + std::list::iterator first = self->begin(); + std::list::iterator end = self->end(); + + int size = int(self->size()); + if (i<0) i += size; + if (j<0) j += size; + if (i<0) i = 0; + if (j>size) j = size; + if (i>=j) i=j; + if (i>=0 && i=0) + { + for (int k=0;k tmp(j-i); + if (j>i) std::copy(first,end,tmp.begin()); + return tmp; + } + else throw std::out_of_range("list index out of range"); + } + void __delslice__(int i,int j) + { + std::list::iterator first = self->begin(); + std::list::iterator end = self->end(); + + int size = int(self->size()); + if (i<0) i += size; + if (j<0) j += size; + if (i<0) i = 0; + if (j>size) j = size; + + for (int k=0;kerase(first,end); + } + void __setslice__(int i,int j, const std::list& v) + { + std::list::iterator first = self->begin(); + std::list::iterator end = self->end(); + + int size = int(self->size()); + if (i<0) i += size; + if (j<0) j += size; + if (i<0) i = 0; + if (j>size) j = size; + + for (int k=0;kerase(first,end); + if (i+1 <= self->size()) + { + first = self->begin(); + for (int k=0;kinsert(first,v.begin(),v.end()); + } + else self->insert(self->end(),v.begin(),v.end()); + } + + } + unsigned int __len__() + { + return self->size(); + } + bool __nonzero__() + { + return !(self->empty()); + } + void append(const T& x) + { + self->push_back(x); + } + void pop() + { + self->pop_back(); + } + + }; + + }; +} + + + + + + diff --git a/Lib/python/std_string.i b/Lib/python/std_string.i new file mode 100644 index 000000000..2e63ef318 --- /dev/null +++ b/Lib/python/std_string.i @@ -0,0 +1,54 @@ +// +// SWIG typemaps for std::string +// Luigi Ballabio +// Apr 8, 2002 +// +// Python implementation + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + /* Overloading check */ + + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string { + if (PyString_Check($input)) + $1 = std::string(PyString_AsString($input)); + else + SWIG_exception(SWIG_TypeError, "string expected"); + } + + %typemap(in) const string & (std::string temp) { + if (PyString_Check($input)) { + temp = std::string(PyString_AsString($input)); + $1 = &temp; + } else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + + %typemap(out) string { + $result = PyString_FromString($1.c_str()); + } + + %typemap(out) const string & { + $result = PyString_FromString($1->c_str()); + } +} + diff --git a/Lib/python/std_vector.i b/Lib/python/std_vector.i new file mode 100644 index 000000000..b4bd35e19 --- /dev/null +++ b/Lib/python/std_vector.i @@ -0,0 +1,726 @@ +// +// SWIG typemaps for std::vector types +// Luigi Ballabio +// Apr 8, 2002 +// +// Python implementation + +%include std_common.i +%include exception.i + +// __getitem__ is required to raise an IndexError for for-loops to work +// other methods which can raise are made to throw an IndexError as well +%exception std::vector::__getitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::__setitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::__delitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Python as much as possible, namely, to allow the user to pass and +// be returned Python tuples or lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Python sequence or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Python sequence of T:s +// is returned which is most easily used in other Python functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class vector { + %typemap(in) vector (std::vector* v) { + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + $1 = std::vector(size); + for (unsigned int i=0; i expected"); + SWIG_fail; + } + } + } else if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,1) != -1){ + $1 = *v; + } else { + PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); + SWIG_fail; + } + } + %typemap(in) const vector& (std::vector temp, + std::vector* v), + const vector* (std::vector temp, + std::vector* v) { + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + temp = std::vector(size); + $1 = &temp; + for (unsigned int i=0; i expected"); + SWIG_fail; + } + } + } else if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1){ + $1 = v; + } else { + PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); + SWIG_fail; + } + } + %typemap(out) vector { + $result = PyTuple_New($1.size()); + for (unsigned int i=0; i<$1.size(); i++) { + T* ptr = new T((($1_type &)$1)[i]); + PyTuple_SetItem($result,i, + SWIG_NewPointerObj((void *) ptr, + $descriptor(T *), 1)); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + PyObject* o = PySequence_GetItem($input,0); + if ((SWIG_ConvertPtr(o,(void **) &x, + $descriptor(T *),0)) != -1) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + PyObject* o = PySequence_GetItem($input,0); + if ((SWIG_ConvertPtr(o,(void **) &x, + $descriptor(T *),0)) != -1) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector &); + + %rename(__len__) size; + unsigned int size() const; + void clear(); + %rename(append) push_back; + void push_back(const T& x); + %extend { + bool __nonzero__() { + return !(self->empty()); + } + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& __getitem__(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i __getslice__(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + std::vector tmp(j-i); + std::copy(self->begin()+i,self->begin()+j,tmp.begin()); + return tmp; + } + void __setitem__(int i, const T& x) { + int size = int(self->size()); + if (i<0) i+= size; + if (i>=0 && i& v) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + if (int(v.size()) == j-i) { + std::copy(v.begin(),v.end(),self->begin()+i); + } else { + self->erase(self->begin()+i,self->begin()+j); + if (i+1 <= self->size()) { + self->insert(self->begin()+i,v.begin(),v.end()); + } else { + self->insert(self->end(),v.begin(),v.end()); + } + } + } + void __delitem__(int i) { + int size = int(self->size()); + if (i<0) i+= size; + if (i>=0 && ierase(self->begin()+i); + else + throw std::out_of_range("vector index out of range"); + } + void __delslice__(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + self->erase(self->begin()+i,self->begin()+j); + } + } + }; + + + // Partial specialization for vectors of pointers. [ beazley ] + + template class vector { + %typemap(in) vector (std::vector* v) { + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + $1 = std::vector(size); + for (unsigned int i=0; i expected"); + SWIG_fail; + } + } + } else if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,1) != -1){ + $1 = *v; + } else { + PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); + SWIG_fail; + } + } + %typemap(in) const vector& (std::vector temp, + std::vector* v), + const vector* (std::vector temp, + std::vector* v) { + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + temp = std::vector(size); + $1 = &temp; + for (unsigned int i=0; i expected"); + SWIG_fail; + } + } + } else if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1){ + $1 = v; + } else { + PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); + SWIG_fail; + } + } + %typemap(out) vector { + $result = PyTuple_New($1.size()); + for (unsigned int i=0; i<$1.size(); i++) { + T ptr = (($1_type &)$1)[i]; + PyTuple_SetItem($result,i, + SWIG_NewPointerObj((void *) ptr, + $descriptor(T), 0)); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T x; + PyObject* o = PySequence_GetItem($input,0); + if ((SWIG_ConvertPtr(o,(void **) &x, + $descriptor(T),0)) != -1) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T x; + PyObject* o = PySequence_GetItem($input,0); + if ((SWIG_ConvertPtr(o,(void **) &x, + $descriptor(T),0)) != -1) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector &); + + %rename(__len__) size; + unsigned int size() const; + void clear(); + %rename(append) push_back; + void push_back(T x); + %extend { + bool __nonzero__() { + return !(self->empty()); + } + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T __getitem__(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i __getslice__(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + std::vector tmp(j-i); + std::copy(self->begin()+i,self->begin()+j,tmp.begin()); + return tmp; + } + void __setitem__(int i, const T& x) { + int size = int(self->size()); + if (i<0) i+= size; + if (i>=0 && i& v) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + if (int(v.size()) == j-i) { + std::copy(v.begin(),v.end(),self->begin()+i); + } else { + self->erase(self->begin()+i,self->begin()+j); + if (i+1 <= self->size()) + self->insert(self->begin()+i,v.begin(),v.end()); + else + self->insert(self->end(),v.begin(),v.end()); + } + } + void __delitem__(int i) { + int size = int(self->size()); + if (i<0) i+= size; + if (i>=0 && ierase(self->begin()+i); + else + throw std::out_of_range("vector index out of range"); + } + void __delslice__(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + self->erase(self->begin()+i,self->begin()+j); + } + } + }; + + // specializations for built-ins + + %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) + template<> class vector { + %typemap(in) vector (std::vector* v) { + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + $1 = std::vector(size); + for (unsigned int i=0; i expected"); + SWIG_fail; + } + } + } else if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,1) != -1){ + $1 = *v; + } else { + PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); + SWIG_fail; + } + } + %typemap(in) const vector& (std::vector temp, + std::vector* v), + const vector* (std::vector temp, + std::vector* v) { + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + temp = std::vector(size); + $1 = &temp; + for (unsigned int i=0; i expected"); + SWIG_fail; + } + } + } else if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1){ + $1 = v; + } else { + PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); + SWIG_fail; + } + } + %typemap(out) vector { + $result = PyTuple_New($1.size()); + for (unsigned int i=0; i<$1.size(); i++) + PyTuple_SetItem($result,i, + CONVERT_TO((($1_type &)$1)[i])); + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + PyObject* o = PySequence_GetItem($input,0); + if (CHECK(o)) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (PyTuple_Check($input) || PyList_Check($input)) { + unsigned int size = (PyTuple_Check($input) ? + PyTuple_Size($input) : + PyList_Size($input)); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + PyObject* o = PySequence_GetItem($input,0); + if (CHECK(o)) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector &); + %rename(__len__) size; + unsigned int size() const; + %rename(__nonzero__) empty; + bool empty() const; + void clear(); + %rename(append) push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T __getitem__(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && i __getslice__(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + std::vector tmp(j-i); + std::copy(self->begin()+i,self->begin()+j,tmp.begin()); + return tmp; + } + void __setitem__(int i, T x) { + int size = int(self->size()); + if (i<0) i+= size; + if (i>=0 && i& v) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + if (int(v.size()) == j-i) { + std::copy(v.begin(),v.end(),self->begin()+i); + } else { + self->erase(self->begin()+i,self->begin()+j); + if (i+1 <= self->size()) + self->insert(self->begin()+i,v.begin(),v.end()); + else + self->insert(self->end(),v.begin(),v.end()); + } + } + void __delitem__(int i) { + int size = int(self->size()); + if (i<0) i+= size; + if (i>=0 && ierase(self->begin()+i); + else + throw std::out_of_range("vector index out of range"); + } + void __delslice__(int i, int j) { + int size = int(self->size()); + if (i<0) i = size+i; + if (j<0) j = size+j; + if (i<0) i = 0; + if (j>size) j = size; + self->erase(self->begin()+i,self->begin()+j); + } + } + }; + %enddef + + specialize_std_vector(bool,PyInt_Check,PyInt_AsLong,SwigInt_FromBool); + specialize_std_vector(int,PyInt_Check,PyInt_AsLong,PyInt_FromLong); + specialize_std_vector(short,PyInt_Check,PyInt_AsLong,PyInt_FromLong); + specialize_std_vector(long,PyInt_Check,PyInt_AsLong,PyInt_FromLong); + specialize_std_vector(unsigned int,PyInt_Check,\ + PyInt_AsLong,PyInt_FromLong); + specialize_std_vector(unsigned short,PyInt_Check,\ + PyInt_AsLong,PyInt_FromLong); + specialize_std_vector(unsigned long,PyInt_Check,\ + PyInt_AsLong,PyInt_FromLong); + specialize_std_vector(double,SwigNumber_Check,\ + SwigNumber_AsDouble,PyFloat_FromDouble); + specialize_std_vector(float,SwigNumber_Check,\ + SwigNumber_AsDouble,PyFloat_FromDouble); + specialize_std_vector(std::string,PyString_Check,\ + SwigString_AsString,SwigString_FromString); + +} + diff --git a/Lib/python/stl.i b/Lib/python/stl.i new file mode 100644 index 000000000..ce9a6c1a7 --- /dev/null +++ b/Lib/python/stl.i @@ -0,0 +1,9 @@ +// +// SWIG typemaps for STL types +// Luigi Ballabio and Manu ??? +// Apr 26, 2002 +// + +%include std_string.i +%include std_vector.i + diff --git a/Lib/python/typemaps.i b/Lib/python/typemaps.i index fa20464cc..d6c2ee0a8 100644 --- a/Lib/python/typemaps.i +++ b/Lib/python/typemaps.i @@ -12,19 +12,6 @@ // Disclaimer : Unless you really understand how typemaps work, this file // probably isn't going to make much sense. // -#ifdef AUTODOC -%section "Typemap Library (Python)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 -%text %{ -%include typemaps.i - -The SWIG typemap library provides a language independent mechanism for -supporting output arguments, input values, and other C function -calling mechanisms. The primary use of the library is to provide a -better interface to certain C function--especially those involving -pointers. -%} - -#endif // ------------------------------------------------------------------------ // Pointer handling @@ -37,11 +24,7 @@ pointers. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. - -#ifdef AUTODOC -%subsection "Input Methods" - -%text %{ +/* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. @@ -49,10 +32,13 @@ you would use a real value instead. int *INPUT short *INPUT long *INPUT + long long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT + unsigned long long *INPUT unsigned char *INPUT + bool *INPUT float *INPUT double *INPUT @@ -73,73 +59,40 @@ or you can use the %apply directive : %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); -%} -#endif +*/ -%typemap(python,in) double *INPUT(double temp) +%define INPUT_TYPEMAP(type, converter) +%typemap(in) type *INPUT(type temp), type &INPUT(type temp) { - temp = PyFloat_AsDouble($source); - $target = &temp; + temp = converter($input); + if (PyErr_Occurred()) SWIG_fail; + $1 = &temp; } +%typemap(typecheck) type *INPUT = type; +%typemap(typecheck) type &INPUT = type; +%enddef -%typemap(python,in) float *INPUT(float temp) -{ - temp = (float) PyFloat_AsDouble($source); - $target = &temp; -} +INPUT_TYPEMAP(float, PyFloat_AsDouble); +INPUT_TYPEMAP(double, PyFloat_AsDouble); +INPUT_TYPEMAP(int, PyInt_AsLong); +INPUT_TYPEMAP(short, PyInt_AsLong); +INPUT_TYPEMAP(long, PyInt_AsLong); +INPUT_TYPEMAP(long long, PyLong_AsLongLong); +INPUT_TYPEMAP(unsigned int, PyInt_AsLong); +INPUT_TYPEMAP(unsigned short, PyInt_AsLong); +INPUT_TYPEMAP(unsigned long, PyInt_AsLong); +INPUT_TYPEMAP(unsigned long long, PyLong_AsUnsignedLongLong); +INPUT_TYPEMAP(unsigned char, PyInt_AsLong); +INPUT_TYPEMAP(signed char, PyInt_AsLong); +INPUT_TYPEMAP(bool, PyInt_AsLong); -%typemap(python,in) int *INPUT(int temp) -{ - temp = (int) PyInt_AsLong($source); - $target = &temp; -} +#undef INPUT_TYPEMAP -%typemap(python,in) short *INPUT(short temp) -{ - temp = (short) PyInt_AsLong($source); - $target = &temp; -} - -%typemap(python,in) long *INPUT(long temp) -{ - temp = (long) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned int *INPUT(unsigned int temp) -{ - temp = (unsigned int) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned short *INPUT(unsigned short temp) -{ - temp = (unsigned short) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned long *INPUT(unsigned long temp) -{ - temp = (unsigned long) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned char *INPUT(unsigned char temp) -{ - temp = (unsigned char) PyInt_AsLong($source); - $target = &temp; -} - -%typemap(python,in) signed char *INPUT(signed char temp) -{ - temp = (unsigned char) PyInt_AsLong($source); - $target = &temp; -} - // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. -#ifdef AUTODOC -%subsection "Output Methods" - -%text %{ +/* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of @@ -148,15 +101,16 @@ multiple output values, they are returned in the form of a Python tuple. int *OUTPUT short *OUTPUT long *OUTPUT + long long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT + unsigned long long *OUTPUT unsigned char *OUTPUT + bool *OUTPUT float *OUTPUT double *OUTPUT -A Python List can also be returned by using L_OUTPUT instead of OUTPUT. - For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).K: @@ -176,70 +130,8 @@ or you can use the %apply directive : The Python output of the function would be a tuple containing both output values. -%} -#endif -// Helper function for List output - -%{ -static PyObject* l_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyList_Check(target)) { - o2 = target; - target = PyList_New(0); - PyList_Append(target, o2); - Py_XDECREF(o2); - } - PyList_Append(target,o); - Py_XDECREF(o); - } - return target; -} -%} - -// Force the argument to be ignored. - -%typemap(python,ignore) int *L_OUTPUT(int temp), - short *L_OUTPUT(short temp), - long *L_OUTPUT(long temp), - unsigned int *L_OUTPUT(unsigned int temp), - unsigned short *L_OUTPUT(unsigned short temp), - unsigned long *L_OUTPUT(unsigned long temp), - unsigned char *L_OUTPUT(unsigned char temp), - signed char *L_OUTPUT(signed char temp), - float *L_OUTPUT(float temp), - double *L_OUTPUT(double temp) -{ - $target = &temp; -} - -%typemap(python,argout) int *L_OUTPUT, - short *L_OUTPUT, - long *L_OUTPUT, - unsigned int *L_OUTPUT, - unsigned short *L_OUTPUT, - unsigned long *L_OUTPUT, - unsigned char *L_OUTPUT, - signed char *L_OUTPUT -{ - PyObject *o; - o = PyInt_FromLong((long) (*$source)); - l_output_helper($target,o); -} - -%typemap(python,argout) float *L_OUTPUT, - double *L_OUTPUT -{ - PyObject *o; - o = PyFloat_FromDouble((double) (*$source)); - $target = l_output_helper($target,o); -} +*/ // These typemaps contributed by Robin Dunn //---------------------------------------------------------------------- @@ -250,139 +142,52 @@ static PyObject* l_output_helper(PyObject* target, PyObject* o) { // Author: Robin Dunn //---------------------------------------------------------------------- -%{ -static PyObject* t_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - PyObject* o3; +%include "fragments.i" - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyTuple_Check(target)) { - o2 = target; - target = PyTuple_New(1); - PyTuple_SetItem(target, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SetItem(o3, 0, o); - - o2 = target; - target = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return target; +%define OUTPUT_TYPEMAP(type, converter, convtype) +%typemap(in,numinputs=0) type *OUTPUT(type temp), type &OUTPUT(type temp) "$1 = &temp;"; +%typemap(argout,fragment="t_output_helper") type *OUTPUT, type &OUTPUT { + PyObject *o = converter(convtype (*$1)); + $result = t_output_helper($result,o); } -%} +%enddef -// Force the argument to be ignored. -%typemap(python,ignore) int *T_OUTPUT(int temp), - short *T_OUTPUT(short temp), - long *T_OUTPUT(long temp), - unsigned int *T_OUTPUT(unsigned int temp), - unsigned short *T_OUTPUT(unsigned short temp), - unsigned long *T_OUTPUT(unsigned long temp), - unsigned char *T_OUTPUT(unsigned char temp), - float *T_OUTPUT(float temp), - double *T_OUTPUT(double temp) -{ - $target = &temp; -} +OUTPUT_TYPEMAP(int, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(short, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(long, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(long long, PyLong_FromLongLong, (long long)); +OUTPUT_TYPEMAP(unsigned int, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(unsigned short, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(unsigned long, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(unsigned long long, PyLong_FromUnsignedLongLong, (unsigned long long)); +OUTPUT_TYPEMAP(unsigned char, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(signed char, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(bool, PyInt_FromLong, (long)); +OUTPUT_TYPEMAP(float, PyFloat_FromDouble, (double)); +OUTPUT_TYPEMAP(double, PyFloat_FromDouble, (double)); -%typemap(python,argout) int *T_OUTPUT, - short *T_OUTPUT, - long *T_OUTPUT, - unsigned int *T_OUTPUT, - unsigned short *T_OUTPUT, - unsigned long *T_OUTPUT, - unsigned char *T_OUTPUT -{ - PyObject *o; - o = PyInt_FromLong((long) (*$source)); - $target = t_output_helper($target, o); -} - -%typemap(python,argout) float *T_OUTPUT, - double *T_OUTPUT -{ - PyObject *o; - o = PyFloat_FromDouble((double) (*$source)); - $target = t_output_helper($target, o); -} - -// Set the default output typemap - -#ifdef OUTPUT_LIST -%typemap(python,ignore) int *OUTPUT = int *L_OUTPUT; -%typemap(python,ignore) short *OUTPUT = short *L_OUTPUT; -%typemap(python,ignore) long *OUTPUT = long *L_OUTPUT; -%typemap(python,ignore) unsigned *OUTPUT = unsigned *L_OUTPUT; -%typemap(python,ignore) unsigned short *OUTPUT = unsigned short *L_OUTPUT; -%typemap(python,ignore) unsigned long *OUTPUT = unsigned long *L_OUTPUT; -%typemap(python,ignore) unsigned char *OUTPUT = unsigned char *L_OUTPUT; -%typemap(python,ignore) signed char *OUTPUT = signed char *L_OUTPUT; -%typemap(python,ignore) double *OUTPUT = double *L_OUTPUT; -%typemap(python,ignore) float *OUTPUT = float *L_OUTPUT; - -%typemap(python,argout) int *OUTPUT = int *L_OUTPUT; -%typemap(python,argout) short *OUTPUT = short *L_OUTPUT; -%typemap(python,argout) long *OUTPUT = long *L_OUTPUT; -%typemap(python,argout) unsigned *OUTPUT = unsigned *L_OUTPUT; -%typemap(python,argout) unsigned short *OUTPUT = unsigned short *L_OUTPUT; -%typemap(python,argout) unsigned long *OUTPUT = unsigned long *L_OUTPUT; -%typemap(python,argout) unsigned char *OUTPUT = unsigned char *L_OUTPUT; -%typemap(python,argout) signed char *OUTPUT = signed char *L_OUTPUT; -%typemap(python,argout) double *OUTPUT = double *L_OUTPUT; -%typemap(python,argout) float *OUTPUT = float *L_OUTPUT; -#else -%typemap(python,ignore) int *OUTPUT = int *T_OUTPUT; -%typemap(python,ignore) short *OUTPUT = short *T_OUTPUT; -%typemap(python,ignore) long *OUTPUT = long *T_OUTPUT; -%typemap(python,ignore) unsigned *OUTPUT = unsigned *T_OUTPUT; -%typemap(python,ignore) unsigned short *OUTPUT = unsigned short *T_OUTPUT; -%typemap(python,ignore) unsigned long *OUTPUT = unsigned long *T_OUTPUT; -%typemap(python,ignore) unsigned char *OUTPUT = unsigned char *T_OUTPUT; -%typemap(python,ignore) signed char *OUTPUT = signed char *T_OUTPUT; -%typemap(python,ignore) double *OUTPUT = double *T_OUTPUT; -%typemap(python,ignore) float *OUTPUT = float *T_OUTPUT; - -%typemap(python,argout) int *OUTPUT = int *T_OUTPUT; -%typemap(python,argout) short *OUTPUT = short *T_OUTPUT; -%typemap(python,argout) long *OUTPUT = long *T_OUTPUT; -%typemap(python,argout) unsigned *OUTPUT = unsigned *T_OUTPUT; -%typemap(python,argout) unsigned short *OUTPUT = unsigned short *T_OUTPUT; -%typemap(python,argout) unsigned long *OUTPUT = unsigned long *T_OUTPUT; -%typemap(python,argout) unsigned char *OUTPUT = unsigned char *T_OUTPUT; -%typemap(python,argout) signed char *OUTPUT = signed char *T_OUTPUT; -%typemap(python,argout) double *OUTPUT = double *T_OUTPUT; -%typemap(python,argout) float *OUTPUT = float *T_OUTPUT; -#endif +#undef OUTPUT_TYPEMAP // INOUT // Mappings for an argument that is both an input and output // parameter - -#ifdef AUTODOC -%subsection "Input/Output Methods" - -%text %{ +/* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a Python tuple. To return a Python list, -using L_INOUT instead. +returned in the form of a Python tuple. int *INOUT short *INOUT long *INOUT + long long *INOUT unsigned int *INOUT unsigned short *INOUT unsigned long *INOUT + unsigned long long *INOUT unsigned char *INOUT + bool *INOUT float *INOUT double *INOUT @@ -413,149 +218,92 @@ to a Python variable you might do this : Note : previous versions of SWIG used the symbol 'BOTH' to mark input/output arguments. This is still supported, but will be slowly phased out in future releases. -%} -#endif +*/ -%typemap(python,in) int *INOUT = int *INPUT; -%typemap(python,in) short *INOUT = short *INPUT; -%typemap(python,in) long *INOUT = long *INPUT; -%typemap(python,in) unsigned *INOUT = unsigned *INPUT; -%typemap(python,in) unsigned short *INOUT = unsigned short *INPUT; -%typemap(python,in) unsigned long *INOUT = unsigned long *INPUT; -%typemap(python,in) unsigned char *INOUT = unsigned char *INPUT; -%typemap(python,in) float *INOUT = float *INPUT; -%typemap(python,in) double *INOUT = double *INPUT; +%typemap(in) int *INOUT = int *INPUT; +%typemap(in) short *INOUT = short *INPUT; +%typemap(in) long *INOUT = long *INPUT; +%typemap(in) long long *INOUT = long long *INPUT; +%typemap(in) unsigned *INOUT = unsigned *INPUT; +%typemap(in) unsigned short *INOUT = unsigned short *INPUT; +%typemap(in) unsigned long *INOUT = unsigned long *INPUT; +%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; +%typemap(in) unsigned char *INOUT = unsigned char *INPUT; +%typemap(in) bool *INOUT = bool *INPUT; +%typemap(in) float *INOUT = float *INPUT; +%typemap(in) double *INOUT = double *INPUT; -%typemap(python,argout) int *INOUT = int *OUTPUT; -%typemap(python,argout) short *INOUT = short *OUTPUT; -%typemap(python,argout) long *INOUT = long *OUTPUT; -%typemap(python,argout) unsigned *INOUT = unsigned *OUTPUT; -%typemap(python,argout) unsigned short *INOUT = unsigned short *OUTPUT; -%typemap(python,argout) unsigned long *INOUT = unsigned long *OUTPUT; -%typemap(python,argout) unsigned char *INOUT = unsigned char *OUTPUT; -%typemap(python,argout) float *INOUT = float *OUTPUT; -%typemap(python,argout) double *INOUT = double *OUTPUT; +%typemap(in) int &INOUT = int &INPUT; +%typemap(in) short &INOUT = short &INPUT; +%typemap(in) long &INOUT = long &INPUT; +%typemap(in) long long &INOUT = long long &INPUT; +%typemap(in) unsigned &INOUT = unsigned &INPUT; +%typemap(in) unsigned short &INOUT = unsigned short &INPUT; +%typemap(in) unsigned long &INOUT = unsigned long &INPUT; +%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; +%typemap(in) unsigned char &INOUT = unsigned char &INPUT; +%typemap(in) bool &INOUT = bool &INPUT; +%typemap(in) float &INOUT = float &INPUT; +%typemap(in) double &INOUT = double &INPUT; -%typemap(python,in) int *T_INOUT = int *INPUT; -%typemap(python,in) short *T_INOUT = short *INPUT; -%typemap(python,in) long *T_INOUT = long *INPUT; -%typemap(python,in) unsigned *T_INOUT = unsigned *INPUT; -%typemap(python,in) unsigned short *T_INOUT = unsigned short *INPUT; -%typemap(python,in) unsigned long *T_INOUT = unsigned long *INPUT; -%typemap(python,in) unsigned char *T_INOUT = unsigned char *INPUT; -%typemap(python,in) float *T_INOUT = float *INPUT; -%typemap(python,in) double *T_INOUT = double *INPUT; +%typemap(argout) int *INOUT = int *OUTPUT; +%typemap(argout) short *INOUT = short *OUTPUT; +%typemap(argout) long *INOUT = long *OUTPUT; +%typemap(argout) long long *INOUT = long long *OUTPUT; +%typemap(argout) unsigned *INOUT = unsigned *OUTPUT; +%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; +%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; +%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; +%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; +%typemap(argout) bool *INOUT = bool *OUTPUT; +%typemap(argout) float *INOUT = float *OUTPUT; +%typemap(argout) double *INOUT = double *OUTPUT; -%typemap(python,argout) int *T_INOUT = int *T_OUTPUT; -%typemap(python,argout) short *T_INOUT = short *T_OUTPUT; -%typemap(python,argout) long *T_INOUT = long *T_OUTPUT; -%typemap(python,argout) unsigned *T_INOUT = unsigned *T_OUTPUT; -%typemap(python,argout) unsigned short *T_INOUT = unsigned short *T_OUTPUT; -%typemap(python,argout) unsigned long *T_INOUT = unsigned long *T_OUTPUT; -%typemap(python,argout) unsigned char *T_INOUT = unsigned char *T_OUTPUT; -%typemap(python,argout) float *T_INOUT = float *T_OUTPUT; -%typemap(python,argout) double *T_INOUT = double *T_OUTPUT; +%typemap(argout) int &INOUT = int &OUTPUT; +%typemap(argout) short &INOUT = short &OUTPUT; +%typemap(argout) long &INOUT = long &OUTPUT; +%typemap(argout) long long &INOUT = long long &OUTPUT; +%typemap(argout) unsigned &INOUT = unsigned &OUTPUT; +%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; +%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; +%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; +%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; +%typemap(argout) bool &INOUT = bool &OUTPUT; +%typemap(argout) float &INOUT = float &OUTPUT; +%typemap(argout) double &INOUT = double &OUTPUT; -%typemap(python,in) int *L_INOUT = int *INPUT; -%typemap(python,in) short *L_INOUT = short *INPUT; -%typemap(python,in) long *L_INOUT = long *INPUT; -%typemap(python,in) unsigned *L_INOUT = unsigned *INPUT; -%typemap(python,in) unsigned short *L_INOUT = unsigned short *INPUT; -%typemap(python,in) unsigned long *L_INOUT = unsigned long *INPUT; -%typemap(python,in) unsigned char *L_INOUT = unsigned char *INPUT; -%typemap(python,in) float *L_INOUT = float *INPUT; -%typemap(python,in) double *L_INOUT = double *INPUT; +/* Overloading information */ -%typemap(python,argout) int *L_INOUT = int *L_OUTPUT; -%typemap(python,argout) short *L_INOUT = short *L_OUTPUT; -%typemap(python,argout) long *L_INOUT = long *L_OUTPUT; -%typemap(python,argout) unsigned *L_INOUT = unsigned *L_OUTPUT; -%typemap(python,argout) unsigned short *L_INOUT = unsigned short *L_OUTPUT; -%typemap(python,argout) unsigned long *L_INOUT = unsigned long *L_OUTPUT; -%typemap(python,argout) unsigned char *L_INOUT = unsigned char *L_OUTPUT; -%typemap(python,argout) float *L_INOUT = float *L_OUTPUT; -%typemap(python,argout) double *L_INOUT = double *L_OUTPUT; +%typemap(typecheck) double *INOUT = double; +%typemap(typecheck) bool *INOUT = bool; +%typemap(typecheck) signed char *INOUT = signed char; +%typemap(typecheck) unsigned char *INOUT = unsigned char; +%typemap(typecheck) unsigned long *INOUT = unsigned long; +%typemap(typecheck) unsigned long long *INOUT = unsigned long long; +%typemap(typecheck) unsigned short *INOUT = unsigned short; +%typemap(typecheck) unsigned int *INOUT = unsigned int; +%typemap(typecheck) long *INOUT = long; +%typemap(typecheck) long long *INOUT = long long; +%typemap(typecheck) short *INOUT = short; +%typemap(typecheck) int *INOUT = int; +%typemap(typecheck) float *INOUT = float; -// Backwards compatibility - -%typemap(python,in) int *BOTH = int *INOUT; -%typemap(python,in) short *BOTH = short *INOUT; -%typemap(python,in) long *BOTH = long *INOUT; -%typemap(python,in) unsigned *BOTH = unsigned *INOUT; -%typemap(python,in) unsigned short *BOTH = unsigned short *INOUT; -%typemap(python,in) unsigned long *BOTH = unsigned long *INOUT; -%typemap(python,in) unsigned char *BOTH = unsigned char *INOUT; -%typemap(python,in) float *BOTH = float *INOUT; -%typemap(python,in) double *BOTH = double *INOUT; - -%typemap(python,argout) int *BOTH = int *INOUT; -%typemap(python,argout) short *BOTH = short *INOUT; -%typemap(python,argout) long *BOTH = long *INOUT; -%typemap(python,argout) unsigned *BOTH = unsigned *INOUT; -%typemap(python,argout) unsigned short *BOTH = unsigned short *INOUT; -%typemap(python,argout) unsigned long *BOTH = unsigned long *INOUT; -%typemap(python,argout) unsigned char *BOTH = unsigned char *INOUT; -%typemap(python,argout) float *BOTH = float *INOUT; -%typemap(python,argout) double *BOTH = double *INOUT; - -%typemap(python,in) int *T_BOTH = int *T_INOUT; -%typemap(python,in) short *T_BOTH = short *T_INOUT; -%typemap(python,in) long *T_BOTH = long *T_INOUT; -%typemap(python,in) unsigned *T_BOTH = unsigned *T_INOUT; -%typemap(python,in) unsigned short *T_BOTH = unsigned short *T_INOUT; -%typemap(python,in) unsigned long *T_BOTH = unsigned long *T_INOUT; -%typemap(python,in) unsigned char *T_BOTH = unsigned char *T_INOUT; -%typemap(python,in) float *T_BOTH = float *T_INOUT; -%typemap(python,in) double *T_BOTH = double *T_INOUT; - -%typemap(python,argout) int *T_BOTH = int *T_INOUT; -%typemap(python,argout) short *T_BOTH = short *T_INOUT; -%typemap(python,argout) long *T_BOTH = long *T_INOUT; -%typemap(python,argout) unsigned *T_BOTH = unsigned *T_INOUT; -%typemap(python,argout) unsigned short *T_BOTH = unsigned short *T_INOUT; -%typemap(python,argout) unsigned long *T_BOTH = unsigned long *T_INOUT; -%typemap(python,argout) unsigned char *T_BOTH = unsigned char *T_INOUT; -%typemap(python,argout) float *T_BOTH = float *T_INOUT; -%typemap(python,argout) double *T_BOTH = double *T_INOUT; - -// -------------------------------------------------------------------- -// Special types -// -// -------------------------------------------------------------------- - -#ifdef AUTODOC -%subsection "Special Methods" - -%text %{ -The typemaps.i library also provides the following mappings : - -PyObject * - - When a PyObject * appears as either an input value or return - value of a function, SWIG passes it through unmodified. Thus, - if you want to write a C function that operates on PyObjects, - it is easy to write. For example : - - %include typemaps.i - PyObject *spam(PyObject *obj1, int n); - - Unlike normal Python wrapper functions, These functions can - use any combination of parameters that you wish. - -%} - -#endif +%typemap(typecheck) double &INOUT = double; +%typemap(typecheck) bool &INOUT = bool; +%typemap(typecheck) signed char &INOUT = signed char; +%typemap(typecheck) unsigned char &INOUT = unsigned char; +%typemap(typecheck) unsigned long &INOUT = unsigned long; +%typemap(typecheck) unsigned long long &INOUT = unsigned long long; +%typemap(typecheck) unsigned short &INOUT = unsigned short; +%typemap(typecheck) unsigned int &INOUT = unsigned int; +%typemap(typecheck) long &INOUT = long; +%typemap(typecheck) long long &INOUT = long long; +%typemap(typecheck) short &INOUT = short; +%typemap(typecheck) int &INOUT = int; +%typemap(typecheck) float &INOUT = float; -// If a PyObject * appears as either an argument or a function return -// value, simply pass it straight through. -%typemap(python,in) PyObject * { - $target = $source; -} -%typemap(python,out) PyObject * { - $target = $source; -} diff --git a/Lib/python/typemaps_old.i b/Lib/python/typemaps_old.i deleted file mode 100644 index 44582d383..000000000 --- a/Lib/python/typemaps_old.i +++ /dev/null @@ -1,441 +0,0 @@ -// -// SWIG Typemap library -// Dave Beazley -// May 5, 1997 -// -// Python implementation -// -// This library provides standard typemaps for modifying SWIG's behavior. -// With enough entries in this file, I hope that very few people actually -// ever need to write a typemap. -// -#ifdef AUTODOC -%section "Typemap Library (Python)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 -%text %{ -%include typemaps.i - -The SWIG typemap library provides a language independent mechanism for -supporting output arguments, input values, and other C function -calling mechanisms. The primary use of the library is to provide a -better interface to certain C function--especially those involving -pointers. -%} - -#endif - -// ------------------------------------------------------------------------ -// Pointer handling -// -// These mappings provide support for input/output arguments and common -// uses for C/C++ pointers. -// ------------------------------------------------------------------------ - -// INPUT typemaps. -// These remap a C pointer to be an "INPUT" value which is passed by value -// instead of reference. - - -#ifdef AUTODOC -%subsection "Input Methods" - -%text %{ -The following methods can be applied to turn a pointer into a simple -"input" value. That is, instead of passing a pointer to an object, -you would use a real value instead. - - int *INPUT - short *INPUT - long *INPUT - unsigned int *INPUT - unsigned short *INPUT - unsigned long *INPUT - unsigned char *INPUT - float *INPUT - double *INPUT - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - %include typemaps.i - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %include typemaps.i - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -%} -#endif - -%typemap(python,in) double *INPUT(double temp) -{ - temp = PyFloat_AsDouble($source); - $target = &temp; -} - -%typemap(python,in) float *INPUT(float temp) -{ - temp = (float) PyFloat_AsDouble($source); - $target = &temp; -} - -%typemap(python,in) int *INPUT(int temp) -{ - temp = (int) PyInt_AsLong($source); - $target = &temp; -} - -%typemap(python,in) short *INPUT(short temp) -{ - temp = (short) PyInt_AsLong($source); - $target = &temp; -} - -%typemap(python,in) long *INPUT(long temp) -{ - temp = (long) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned int *INPUT(unsigned int temp) -{ - temp = (unsigned int) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned short *INPUT(unsigned short temp) -{ - temp = (unsigned short) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned long *INPUT(unsigned long temp) -{ - temp = (unsigned long) PyInt_AsLong($source); - $target = &temp; -} -%typemap(python,in) unsigned char *INPUT(unsigned char temp) -{ - temp = (unsigned char) PyInt_AsLong($source); - $target = &temp; -} - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. The output value is appended to the result as -// a list element. - -#ifdef AUTODOC -%subsection "Output Methods" - -%text %{ -The following methods can be applied to turn a pointer into an "output" -value. When calling a function, no input value would be given for -a parameter, but an output value would be returned. In the case of -multiple output values, they are returned in the form of a Python list. - - int *OUTPUT - short *OUTPUT - long *OUTPUT - unsigned int *OUTPUT - unsigned short *OUTPUT - unsigned long *OUTPUT - unsigned char *OUTPUT - float *OUTPUT - double *OUTPUT - -A Python Tuple can also be replaced by using T_OUTPUT instead of OUTPUT. - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters).K: - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - %include typemaps.i - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %include typemaps.i - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The Python output of the function would be a list containing both -output values. -%} -#endif - -// Force the argument to be ignored. - -%typemap(python,ignore) int *OUTPUT(int temp), - short *OUTPUT(short temp), - long *OUTPUT(long temp), - unsigned int *OUTPUT(unsigned int temp), - unsigned short *OUTPUT(unsigned short temp), - unsigned long *OUTPUT(unsigned long temp), - unsigned char *OUTPUT(unsigned char temp), - float *OUTPUT(float temp), - double *OUTPUT(double temp) -{ - $target = &temp; -} - -%typemap(python,argout) int *OUTPUT, - short *OUTPUT, - long *OUTPUT, - unsigned int *OUTPUT, - unsigned short *OUTPUT, - unsigned long *OUTPUT, - unsigned char *OUTPUT -{ - PyObject *o; - o = PyInt_FromLong((long) (*$source)); - if (!$target) { - $target = o; - } else if ($target == Py_None) { - Py_DECREF(Py_None); - $target = o; - } else { - if (!PyList_Check($target)) { - PyObject *o2 = $target; - $target = PyList_New(0); - PyList_Append($target,o2); - Py_XDECREF(o2); - } - PyList_Append($target,o); - Py_XDECREF(o); - } -} - -%typemap(python,argout) float *OUTPUT, - double *OUTPUT -{ - PyObject *o; - o = PyFloat_FromDouble((double) (*$source)); - if (!$target) { - $target = o; - } else if ($target == Py_None) { - Py_DECREF(Py_None); - $target = o; - } else { - if (!PyList_Check($target)) { - PyObject *o2 = $target; - $target = PyList_New(0); - PyList_Append($target,o2); - Py_XDECREF(o2); - } - PyList_Append($target,o); - Py_XDECREF(o); - } -} - -// These typemaps contributed by Robin Dunn -//---------------------------------------------------------------------- -// -// T_OUTPUT typemap (and helper function) to return multiple argouts as -// a tuple instead of a list. -// -// Author: Robin Dunn -//---------------------------------------------------------------------- - -%{ -static PyObject* t_output_helper(PyObject* target, PyObject* o) { - PyObject* o2; - PyObject* o3; - - if (!target) { - target = o; - } else if (target == Py_None) { - Py_DECREF(Py_None); - target = o; - } else { - if (!PyTuple_Check(target)) { - o2 = target; - target = PyTuple_New(1); - PyTuple_SetItem(target, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SetItem(o3, 0, o); - - o2 = target; - target = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return target; -} -%} - -// Force the argument to be ignored. -%typemap(python,ignore) int *T_OUTPUT(int temp), - short *T_OUTPUT(short temp), - long *T_OUTPUT(long temp), - unsigned int *T_OUTPUT(unsigned int temp), - unsigned short *T_OUTPUT(unsigned short temp), - unsigned long *T_OUTPUT(unsigned long temp), - unsigned char *T_OUTPUT(unsigned char temp), - float *T_OUTPUT(float temp), - double *T_OUTPUT(double temp) -{ - $target = &temp; -} - -%typemap(python,argout) int *T_OUTPUT, - short *T_OUTPUT, - long *T_OUTPUT, - unsigned int *T_OUTPUT, - unsigned short *T_OUTPUT, - unsigned long *T_OUTPUT, - unsigned char *T_OUTPUT -{ - PyObject *o; - o = PyInt_FromLong((long) (*$source)); - $target = t_output_helper($target, o); -} - -%typemap(python,argout) float *T_OUTPUT, - double *T_OUTPUT -{ - PyObject *o; - o = PyFloat_FromDouble((double) (*$source)); - $target = t_output_helper($target, o); -} - -// BOTH -// Mappings for an argument that is both an input and output -// parameter - - -#ifdef AUTODOC -%subsection "Input/Output Methods" - -%text %{ -The following methods can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a Python list. To return a Python tuple, -using T_BOTH instead. - - int *BOTH - short *BOTH - long *BOTH - unsigned int *BOTH - unsigned short *BOTH - unsigned long *BOTH - unsigned char *BOTH - float *BOTH - double *BOTH - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include typemaps.i - void neg(double *BOTH); - -or you can use the %apply directive : - - %include typemaps.i - %apply double *BOTH { double *x }; - void neg(double *x); - -Unlike C, this mapping does not directly modify the input value (since -this makes no sense in Python). Rather, the modified input value shows -up as the return value of the function. Thus, to apply this function -to a Python variable you might do this : - - x = neg(x) - -%} - -#endif - -%typemap(python,in) int *BOTH = int *INPUT; -%typemap(python,in) short *BOTH = short *INPUT; -%typemap(python,in) long *BOTH = long *INPUT; -%typemap(python,in) unsigned *BOTH = unsigned *INPUT; -%typemap(python,in) unsigned short *BOTH = unsigned short *INPUT; -%typemap(python,in) unsigned long *BOTH = unsigned long *INPUT; -%typemap(python,in) unsigned char *BOTH = unsigned char *INPUT; -%typemap(python,in) float *BOTH = float *INPUT; -%typemap(python,in) double *BOTH = double *INPUT; - -%typemap(python,argout) int *BOTH = int *OUTPUT; -%typemap(python,argout) short *BOTH = short *OUTPUT; -%typemap(python,argout) long *BOTH = long *OUTPUT; -%typemap(python,argout) unsigned *BOTH = unsigned *OUTPUT; -%typemap(python,argout) unsigned short *BOTH = unsigned short *OUTPUT; -%typemap(python,argout) unsigned long *BOTH = unsigned long *OUTPUT; -%typemap(python,argout) unsigned char *BOTH = unsigned char *OUTPUT; -%typemap(python,argout) float *BOTH = float *OUTPUT; -%typemap(python,argout) double *BOTH = double *OUTPUT; - -%typemap(python,in) int *T_BOTH = int *INPUT; -%typemap(python,in) short *T_BOTH = short *INPUT; -%typemap(python,in) long *T_BOTH = long *INPUT; -%typemap(python,in) unsigned *T_BOTH = unsigned *INPUT; -%typemap(python,in) unsigned short *T_BOTH = unsigned short *INPUT; -%typemap(python,in) unsigned long *T_BOTH = unsigned long *INPUT; -%typemap(python,in) unsigned char *T_BOTH = unsigned char *INPUT; -%typemap(python,in) float *T_BOTH = float *INPUT; -%typemap(python,in) double *T_BOTH = double *INPUT; - -%typemap(python,argout) int *T_BOTH = int *T_OUTPUT; -%typemap(python,argout) short *T_BOTH = short *T_OUTPUT; -%typemap(python,argout) long *T_BOTH = long *T_OUTPUT; -%typemap(python,argout) unsigned *T_BOTH = unsigned *T_OUTPUT; -%typemap(python,argout) unsigned short *T_BOTH = unsigned short *T_OUTPUT; -%typemap(python,argout) unsigned long *T_BOTH = unsigned long *T_OUTPUT; -%typemap(python,argout) unsigned char *T_BOTH = unsigned char *T_OUTPUT; -%typemap(python,argout) float *T_BOTH = float *T_OUTPUT; -%typemap(python,argout) double *T_BOTH = double *T_OUTPUT; - -// -------------------------------------------------------------------- -// Special types -// -// -------------------------------------------------------------------- - -#ifdef AUTODOC -%subsection "Special Methods" - -%text %{ -The typemaps.i library also provides the following mappings : - -PyObject * - - When a PyObject * appears as either an input value or return - value of a function, SWIG passes it through unmodified. Thus, - if you want to write a C function that operates on PyObjects, - it is easy to write. For example : - - %include typemaps.i - PyObject *spam(PyObject *obj1, int n); - - Unlike normal Python wrapper functions, These functions can - use any combination of parameters that you wish. - -%} - -#endif - - -// If a PyObject * appears as either an argument or a function return -// value, simply pass it straight through. - -%typemap(python,in) PyObject * { - $target = $source; -} - -%typemap(python,out) PyObject * { - $target = $source; -} - diff --git a/Lib/ruby/Makefile.swig b/Lib/ruby/Makefile.swig index 6b34b8d86..a7f3ae3d2 100644 --- a/Lib/ruby/Makefile.swig +++ b/Lib/ruby/Makefile.swig @@ -16,11 +16,11 @@ RUBY = ruby SWIG = swig # for C extension -SWIGOPT = -ruby -feature $(FEATURE) +SWIGOPT = -ruby WRAPPER = $(MODULE)_wrap.c ## for C++ extension -#SWIGOPT = -ruby -c++ -feature $(FEATURE) +#SWIGOPT = -ruby -c++ #WRAPPER = $(MODULE)_wrap.cc diff --git a/Lib/ruby/exception.i b/Lib/ruby/exception.i deleted file mode 100644 index e12fd1c35..000000000 --- a/Lib/ruby/exception.i +++ /dev/null @@ -1,27 +0,0 @@ -// -// SWIG exception handling for Ruby -// -// $Header$ -// -// Copyright (C) 2000 Network Applied Communication Laboratory, Inc. -// Copyright (C) 2000 Information-technology Promotion Agency, Japan -// -// Masaki Fukushima -// - -%{ -#define SWIG_MemoryError rb_eFatal -#define SWIG_IOError rb_eIOError -#define SWIG_RuntimeError rb_eRuntimeError -#define SWIG_IndexError rb_eIndexError -#define SWIG_TypeError rb_eTypeError -#define SWIG_DivisionByZero rb_eZeroDivError -#define SWIG_OverflowError rb_eRuntimeException -#define SWIG_SyntaxError rb_eSyntaxError -#define SWIG_ValueError rb_eArgError -#define SWIG_SystemError rb_eSystemError -#define SWIG_UnknownError rb_eRuntimeError - -#define SWIG_exception(a,b) rb_raise(a,b) - -%} diff --git a/Lib/ruby/extra-install.list b/Lib/ruby/extra-install.list new file mode 100644 index 000000000..4610fa8f7 --- /dev/null +++ b/Lib/ruby/extra-install.list @@ -0,0 +1,3 @@ +# see top-level Makefile.in +Makefile.swig +extconf.rb diff --git a/Lib/ruby/fragments.i b/Lib/ruby/fragments.i new file mode 100644 index 000000000..8d4629005 --- /dev/null +++ b/Lib/ruby/fragments.i @@ -0,0 +1,17 @@ +// Helper function for Array output + +%fragment("output_helper", "header") %{ +static VALUE output_helper(VALUE target, VALUE o) { + if (NIL_P(target)) { + target = o; + } else { + if (TYPE(target) != T_ARRAY) { + VALUE o2 = target; + target = rb_ary_new(); + rb_ary_push(target, o2); + } + rb_ary_push(target, o); + } + return target; +} +%} diff --git a/Lib/ruby/ptrlang.i b/Lib/ruby/ptrlang.i deleted file mode 100644 index 922dab0c3..000000000 --- a/Lib/ruby/ptrlang.i +++ /dev/null @@ -1,461 +0,0 @@ -// -// Pointer library for Ruby -// -// $Header$ -// -// Copyright (C) 2000 Network Applied Communication Laboratory, Inc. -// Copyright (C) 2000 Information-technology Promotion Agency, Japan -// -// Masaki Fukushima -// -// Originally derived from python/ptrlang.i -// - -// -// SWIG pointer conversion and utility library -// -// Dave Beazley -// April 19, 1997 -// -// Python specific implementation. This file is included -// by the file ../pointer.i - - -%{ -#include - -/* Types used by the library */ -static swig_type_info *SWIG_POINTER_int_p = 0; -static swig_type_info *SWIG_POINTER_short_p =0; -static swig_type_info *SWIG_POINTER_long_p = 0; -static swig_type_info *SWIG_POINTER_float_p = 0; -static swig_type_info *SWIG_POINTER_double_p = 0; -static swig_type_info *SWIG_POINTER_char_p = 0; -static swig_type_info *SWIG_POINTER_char_pp = 0; -%} - -%init %{ - SWIG_POINTER_int_p = SWIG_TypeQuery("int *"); - SWIG_POINTER_short_p = SWIG_TypeQuery("short *"); - SWIG_POINTER_long_p = SWIG_TypeQuery("long *"); - SWIG_POINTER_float_p = SWIG_TypeQuery("float *"); - SWIG_POINTER_double_p = SWIG_TypeQuery("double *"); - SWIG_POINTER_char_p = SWIG_TypeQuery("char *"); - SWIG_POINTER_char_pp = SWIG_TypeQuery("char **"); -%} - -%{ - -/*------------------------------------------------------------------ - ptrvalue(ptr,type = 0) - - Attempts to dereference a pointer value. If type is given, it - will try to use that type. Otherwise, this function will attempt - to "guess" the proper datatype by checking against all of the - builtin C datatypes. - ------------------------------------------------------------------ */ - -static VALUE ptrvalue(VALUE _PTRVALUE, int index, char *type) { - void *ptr; - char *s; - VALUE obj; - - ptr = SWIG_ConvertPtr(_PTRVALUE,0); - - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - /* No datatype was passed. Type to figure out if it's a common one */ - if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_int_p)) { - type = "int"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_double_p)) { - type = "double"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_short_p)) { - type = "short"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_long_p)) { - type = "long"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_float_p)) { - type = "float"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_p)) { - type = "char"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_pp)) { - type = "char *"; - } else { - type = "unknown"; - } - } - if (!ptr) { - rb_raise(rb_eTypeError,"Unable to dereference NULL pointer."); - } - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - obj = INT2NUM((long) *(((int *) ptr) + index)); - } else if (strcmp(type,"double") == 0) { - obj = rb_float_new((double) *(((double *) ptr)+index)); - } else if (strcmp(type,"short") == 0) { - obj = INT2NUM((long) *(((short *) ptr)+index)); - } else if (strcmp(type,"long") == 0) { - obj = INT2NUM((long) *(((long *) ptr)+index)); - } else if (strcmp(type,"float") == 0) { - obj = rb_float_new((double) *(((float *) ptr)+index)); - } else if (strcmp(type,"char") == 0) { - obj = rb_str_new2(((char *) ptr)+index); - } else if (strcmp(type,"char *") == 0) { - char *c = *(((char **) ptr)+index); - if (c) obj = rb_str_new2(c); - else obj = rb_str_new2("NULL"); - } else { - rb_raise(rb_eTypeError,"Unable to dereference unsupported datatype."); - } - return obj; -} - -/*------------------------------------------------------------------ - ptrcreate(type,value = 0,numelements = 1) - - Attempts to create a new object of given type. Type must be - a basic C datatype. Will not create complex objects. - ------------------------------------------------------------------ */ - -static VALUE ptrcreate(char *type, VALUE _RBVALUE, int numelements) { - void *ptr; - VALUE obj; - int sz; - swig_type_info *cast; - char temp[40]; - - /* Check the type string against a variety of possibilities */ - - if (strcmp(type,"int") == 0) { - sz = sizeof(int)*numelements; - cast = SWIG_POINTER_int_p; - } else if (strcmp(type,"short") == 0) { - sz = sizeof(short)*numelements; - cast = SWIG_POINTER_short_p; - } else if (strcmp(type,"long") == 0) { - sz = sizeof(long)*numelements; - cast = SWIG_POINTER_long_p; - } else if (strcmp(type,"double") == 0) { - sz = sizeof(double)*numelements; - cast = SWIG_POINTER_double_p; - } else if (strcmp(type,"float") == 0) { - sz = sizeof(float)*numelements; - cast = SWIG_POINTER_float_p; - } else if (strcmp(type,"char") == 0) { - sz = sizeof(char)*numelements; - cast = SWIG_POINTER_char_p; - } else if (strcmp(type,"char *") == 0) { - sz = sizeof(char *)*(numelements+1); - cast = SWIG_POINTER_char_pp; - } else { - rb_raise(rb_eTypeError,"Unable to create unknown datatype."); - } - - /* Create the new object */ - - ptr = (void *) malloc(sz); - if (!ptr) { - rb_raise(rb_eFatal,"Out of memory in swig_create."); - } - - /* Now try to set its default value */ - - if (_RBVALUE) { - if (strcmp(type,"int") == 0) { - int *ip,i,ivalue; - ivalue = (int) NUM2LONG(_RBVALUE); - ip = (int *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"short") == 0) { - short *ip,ivalue; - int i; - ivalue = (short) NUM2LONG(_RBVALUE); - ip = (short *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"long") == 0) { - long *ip,ivalue; - int i; - ivalue = (long) NUM2LONG(_RBVALUE); - ip = (long *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"double") == 0) { - double *ip,ivalue; - int i; - ivalue = (double) NUM2DBL(_RBVALUE); - ip = (double *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"float") == 0) { - float *ip,ivalue; - int i; - ivalue = (float) NUM2DBL(_RBVALUE); - ip = (float *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"char") == 0) { - char *ip,*ivalue; - ivalue = (char *) STR2CSTR(_RBVALUE); - ip = (char *) ptr; - strncpy(ip,ivalue,numelements-1); - } else if (strcmp(type,"char *") == 0) { - char **ip, *ivalue; - int i; - ivalue = (char *) STR2CSTR(_RBVALUE); - ip = (char **) ptr; - for (i = 0; i < numelements; i++) { - if (ivalue) { - ip[i] = (char *) malloc(strlen(ivalue)+1); - strcpy(ip[i],ivalue); - } else { - ip[i] = 0; - } - } - ip[numelements] = 0; - } - } - /* Create the pointer value */ - - obj = SWIG_NewPointerObj(ptr,cast); - return obj; -} - - -/*------------------------------------------------------------------ - ptrset(ptr,value,index = 0,type = 0) - - Attempts to set the value of a pointer variable. If type is - given, we will use that type. Otherwise, we'll guess the datatype. - ------------------------------------------------------------------ */ - -static VALUE ptrset(VALUE _PTRVALUE, VALUE _RBVALUE, int index, char *type) { - void *ptr; - VALUE obj; - - ptr = SWIG_ConvertPtr(_PTRVALUE,0); - - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - /* No datatype was passed. Type to figure out if it's a common one */ - if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_int_p)) { - type = "int"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_double_p)) { - type = "double"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_short_p)) { - type = "short"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_long_p)) { - type = "long"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_float_p)) { - type = "float"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_p)) { - type = "char"; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_pp)) { - type = "char *"; - } else { - type = "unknown"; - } - } - if (!ptr) { - rb_raise(rb_eTypeError,"Unable to set NULL pointer."); - } - - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - *(((int *) ptr)+index) = (int) NUM2LONG(_RBVALUE); - } else if (strcmp(type,"double") == 0) { - *(((double *) ptr)+index) = (double) NUM2DBL(_RBVALUE); - } else if (strcmp(type,"short") == 0) { - *(((short *) ptr)+index) = (short) NUM2LONG(_RBVALUE); - } else if (strcmp(type,"long") == 0) { - *(((long *) ptr)+index) = (long) NUM2LONG(_RBVALUE); - } else if (strcmp(type,"float") == 0) { - *(((float *) ptr)+index) = (float) NUM2DBL(_RBVALUE); - } else if (strcmp(type,"char") == 0) { - char *c = STR2CSTR(_RBVALUE); - strcpy(((char *) ptr)+index, c); - } else if (strcmp(type,"char *") == 0) { - char *c = STR2CSTR(_RBVALUE); - char **ca = (char **) ptr; - if (ca[index]) free(ca[index]); - if (strcmp(c,"NULL") == 0) { - ca[index] = 0; - } else { - ca[index] = (char *) malloc(strlen(c)+1); - strcpy(ca[index],c); - } - } else { - rb_raise(rb_eTypeError,"Unable to set unsupported datatype."); - } - return Qnil; -} - -/*------------------------------------------------------------------ - ptradd(ptr,offset) - - Adds a value to an existing pointer value. Will do a type-dependent - add for basic datatypes. For other datatypes, will do a byte-add. - ------------------------------------------------------------------ */ - -static VALUE ptradd(VALUE _PTRVALUE, int offset) { - - char *r; - void *ptr,*junk; - VALUE obj; - swig_type_info *type; - - ptr = SWIG_ConvertPtr(_PTRVALUE,0); - - /* Check to see what kind of object _PTRVALUE is */ - - /* Try to handle a few common datatypes first */ - if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_int_p)) { - ptr = (void *) (((int *) ptr) + offset); - type = SWIG_POINTER_int_p; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_double_p)) { - ptr = (void *) (((double *) ptr) + offset); - type = SWIG_POINTER_double_p; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_short_p)) { - ptr = (void *) (((short *) ptr) + offset); - type = SWIG_POINTER_short_p; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_long_p)) { - ptr = (void *) (((long *) ptr) + offset); - type = SWIG_POINTER_long_p; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_float_p)) { - ptr = (void *) (((float *) ptr) + offset); - type = SWIG_POINTER_float_p; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_p)) { - ptr = (void *) (((char *) ptr) + offset); - type = SWIG_POINTER_char_p; - } else if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_pp)) { - ptr = (void *) (((char *) ptr) + offset); - type = SWIG_POINTER_char_pp; - } else { - rb_raise(rb_eTypeError,"Type error in ptradd. Argument is not a valid pointer value."); - } - obj = SWIG_NewPointerObj(ptr, type); - return obj; -} - -/*------------------------------------------------------------------ - ptrfree(ptr) - - Destroys a pointer value - ------------------------------------------------------------------ */ - -VALUE ptrfree(VALUE _PTRVALUE) { - void *ptr; - - ptr = SWIG_ConvertPtr(_PTRVALUE,0); - - /* Check to see if this pointer is a char ** */ - if (SWIG_CheckConvert(_PTRVALUE,SWIG_POINTER_char_pp)) { - char **c = (char **) ptr; - if (c) { - int i = 0; - while (c[i]) { - free(c[i]); - i++; - } - } - } - if (ptr) - free((char *) ptr); - - return Qnil; -} - -%} -%typemap(ruby,in) VALUE ptr, VALUE value { - $target = $source; -} - -%typemap(ruby,out) VALUE ptrcast, - VALUE ptrvalue, - VALUE ptrcreate, - VALUE ptrset, - VALUE ptradd, - VALUE ptrfree -{ - $target = $source; -} - -%typemap(ruby,ret) int ptrset { - if ($source == -1) return Qnil; -} - -VALUE ptrvalue(VALUE ptr, int index = 0, char *type = 0); -// Returns the value that a pointer is pointing to (ie. dereferencing). -// The type is automatically inferred by the pointer type--thus, an -// integer pointer will return an integer, a double will return a double, -// and so on. The index and type fields are optional parameters. When -// an index is specified, this function returns the value of ptr[index]. -// This allows array access. When a type is specified, it overrides -// the given pointer type. Examples : -// -// ptrvalue(a) # Returns the value *a -// ptrvalue(a,10) # Returns the value a[10] -// ptrvalue(a,10,"double") # Returns a[10] assuming a is a double * - -VALUE ptrset(VALUE ptr, VALUE value, int index = 0, char *type = 0); -// Sets the value pointed to by a pointer. The type is automatically -// inferred from the pointer type so this function will work for -// integers, floats, doubles, etc... The index and type fields are -// optional. When an index is given, it provides array access. When -// type is specified, it overrides the given pointer type. Examples : -// -// ptrset(a,3) # Sets the value *a = 3 -// ptrset(a,3,10) # Sets a[10] = 3 -// ptrset(a,3,10,"int") # Sets a[10] = 3 assuming a is a int * - -VALUE ptrcreate(char *type, VALUE value = 0, int nitems = 1); -// Creates a new object and returns a pointer to it. This function -// can be used to create various kinds of objects for use in C functions. -// type specifies the basic C datatype to create and value is an -// optional parameter that can be used to set the initial value of the -// object. nitems is an optional parameter that can be used to create -// an array. This function results in a memory allocation using -// malloc(). Examples : -// -// a = ptrcreate("double") # Create a new double, return pointer -// a = ptrcreate("int",7) # Create an integer, set value to 7 -// a = ptrcreate("int",0,1000) # Create an integer array with initial -// # values all set to zero -// -// This function only recognizes a few common C datatypes as listed below : -// -// int, short, long, float, double, char, char *, void -// -// All other datatypes will result in an error. However, other -// datatypes can be created by using the ptrcast function. For -// example: -// -// a = ptrcast(ptrcreate("int",0,100),"unsigned int *") - -VALUE ptrfree(VALUE ptr); -// Destroys the memory pointed to by ptr. This function calls free() -// and should only be used with objects created by ptrcreate(). Since -// this function calls free, it may work with other objects, but this -// is generally discouraged unless you absolutely know what you're -// doing. - -VALUE ptradd(VALUE ptr, int offset); -// Adds a value to the current pointer value. For the C datatypes of -// int, short, long, float, double, and char, the offset value is the -// number of objects and works in exactly the same manner as in C. For -// example, the following code steps through the elements of an array -// -// a = ptrcreate("double",0,100); # Create an array double a[100] -// b = a; -// for i in range(0,100): -// ptrset(b,0.0025*i); # set *b = 0.0025*i -// b = ptradd(b,1); # b++ (go to next double) -// -// In this case, adding one to b goes to the next double. -// -// For all other datatypes (including all complex datatypes), the -// offset corresponds to bytes. This function does not perform any -// bounds checking and negative offsets are perfectly legal. - - - diff --git a/Lib/ruby/ruby.i b/Lib/ruby/ruby.i deleted file mode 100644 index a0f084513..000000000 --- a/Lib/ruby/ruby.i +++ /dev/null @@ -1,5 +0,0 @@ -%typemap(ruby,varin) char * " - Check_Type($source, T_STRING); - if ($target) free($target); - $target = xmalloc(RSTRING($source)->len + 1); - strncpy($target, STR2CSTR($source), RSTRING($source)->len + 1);"; diff --git a/Lib/ruby/ruby.swg b/Lib/ruby/ruby.swg index ddf101b8a..bb4dd1136 100644 --- a/Lib/ruby/ruby.swg +++ b/Lib/ruby/ruby.swg @@ -1,19 +1,520 @@ -/* ruby.swg */ -#include "ruby.h" +/* ---------------------------------------------------------------------- + * ruby.swg + * + * Ruby configuation file. + * ---------------------------------------------------------------------- */ -#define NUM2USHRT(n) NUM2UINT(n) -#define NUM2SHRT(n) (\ - (SHRT_MIN <= NUM2INT(n) && NUM2INT(n) <= SHRT_MAX)\ - ? (short)NUM2INT(n)\ - : (rb_raise(rb_eArgError, "integer %d out of range of `short'",\ - NUM2INT(n)), (short)0)\ -) +%runtime "rubyhead.swg" +%runtime "common.swg" -#ifdef __cplusplus -# define VALUEFUNC(f) ((VALUE (*)(...))f) -# define VOIDFUNC(f) ((void (*)(...))f) +#ifdef SWIG_NOINCLUDE +%runtime "rubydec.swg" #else -# define VALUEFUNC(f) (f) -# define VOIDFUNC(f) (f) +%runtime "rubydef.swg" #endif +#define %alias %feature("alias") +#define %freefunc %feature("freefunc") +#define %markfunc %feature("markfunc") +#define %mixin %feature("mixin") +#define %predicate %feature("predicate", "1") + +/* ---------------------------------------------------------------------- + * Standard Typemaps + * ---------------------------------------------------------------------- */ + +/* --- Input Values --- */ + +%typemap(in) int "$1 = NUM2INT($input);"; +%typemap(in) unsigned int "$1 = NUM2UINT($input);"; +%typemap(in) short "$1 = NUM2SHRT($input);"; +%typemap(in) unsigned short "$1 = NUM2USHRT($input);"; +%typemap(in) long "$1 = NUM2LONG($input);"; +%typemap(in) unsigned long "$1 = NUM2ULONG($input);"; +%typemap(in) signed char "$1 = ($1_ltype) NUM2INT($input);"; +%typemap(in) unsigned char "$1 = ($1_ltype) NUM2INT($input);"; +%typemap(in) char "$1 = NUM2CHR($input);"; +%typemap(in) float, double "$1 = ($1_ltype) NUM2DBL($input);"; +%typemap(in) bool "$1 = RTEST($input);"; +%typemap(in) char * "$1 = STR2CSTR($input);"; +%typemap(in) char [ANY] "$1 = STR2CSTR($input);"; +%typemap(in) enum SWIGTYPE "$1 = ($1_ltype) NUM2INT($input);"; + +/* Long long */ + +%typemap(in) long long "$1 = ($1_ltype) NUM2LL($input);"; +%typemap(in) unsigned long long "$1 = ($1_ltype) NUM2ULL($input);"; + +/* Typemaps for pointers. Note: the SWIG run-time type checker works + even if a pointer happens to be mapped to a Ruby class */ + +%typemap(in) SWIGTYPE *, + SWIGTYPE [] + "SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);" + +/* Additional check for null references */ +%typemap(in) SWIGTYPE & + "SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); if ($1 == NULL) rb_raise(rb_eTypeError, \"null reference\");" + +/* Void pointer. Accepts any kind of pointer */ +%typemap(in) void * + "SWIG_ConvertPtr($input, (void **) &$1, 0, 1);"; + +/* Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE { + $&1_ltype ptr; + SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 1); + if (ptr) $1 = *ptr; +} + +/* Pointer to a class member */ +%typemap(in) SWIGTYPE (CLASS::*) "SWIG_ConvertPacked($input, (void *) &$1, sizeof($1_type), $1_descriptor, 1);"; + +/* Const primitive references. Passed by value */ + +%typemap(in) const int & (int temp), + const signed char & (signed char temp), + const unsigned char & (unsigned char temp) + "temp = ($*1_ltype) NUM2INT($input); + $1 = &temp;"; + +%typemap(in) const short & (short temp) + "temp = ($*1_ltype) NUM2SHRT($input); + $1 = &temp;"; + +%typemap(in) const long & (long temp) + "temp = ($*1_ltype) NUM2LONG($input); + $1 = &temp;"; + +%typemap(in) const unsigned int & (unsigned int temp) + "temp = ($*1_ltype) NUM2UINT($input); + $1 = &temp;"; + +%typemap(in) const unsigned short & (unsigned short temp) + "temp = ($*1_ltype) NUM2USHRT($input); + $1 = &temp;"; + +%typemap(in) const unsigned long & (unsigned long temp) + "temp = ($*1_ltype) NUM2ULONG($input); + $1 = &temp;"; + +%typemap(in) const bool & (bool temp) + "temp = ($*1_ltype) RTEST($input); + $1 = &temp;"; + +%typemap(in) const float & (float temp), + const double & (double temp) + "temp = ($*1_ltype) NUM2DBL($input); + $1 = &temp;"; + +%typemap(in) const long long & (long long temp) + "temp = ($*1_ltype) NUM2LL($input); + $1 = &temp;"; + +%typemap(in) const unsigned long long & (unsigned long long temp) + "temp = ($*1_ltype) NUM2ULL($input); + $1 = &temp;"; + +%typemap(in) const char &(char temp) { + char *stemp = STR2CSTR($input); + temp = *stemp; + $1 = &temp; +} + +/* --- Output typemaps --- */ + +%typemap(out) int, short, long, signed char, enum SWIGTYPE + "$result = INT2NUM($1);"; + +%typemap(out) unsigned int, unsigned short, unsigned long, unsigned char + "$result = UINT2NUM($1);"; + + +/* Long long */ + +%typemap(out) long long "$result = LL2NUM($1);"; +%typemap(out) unsigned long long "$result = ULL2NUM($1);"; + +/* Floating point output values */ +%typemap(out) double, float + "$result = rb_float_new($1);"; + +/* Character */ +%typemap(out) char + "$result = rb_str_new(&$1,1);"; + +/* Boolean */ +%typemap(out) bool + "$result = $1 ? Qtrue : Qfalse;"; + +/* C string */ +%typemap(out) char * + "$result = rb_str_new2($1);"; + +/* Pointers, references, and arrays */ +%typemap(out) SWIGTYPE*, SWIGTYPE &, SWIGTYPE [] + "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor,$owner);"; + +/* Dynamic casts */ +%typemap(out) SWIGTYPE*DYNAMIC, SWIGTYPE &DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); + $result = SWIG_NewPointerObj((void *) $1, ty,$owner); +} + +/* Member pointer */ +%typemap(out) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor);"; + +/* Void */ +%typemap(out) void "$result = Qnil;"; + +/* Primitive types--return by value */ +%typemap(out) SWIGTYPE +#ifdef __cplusplus +{ + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &)$1); + $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); +} +#else +{ + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); +} +#endif + +%typemap(out) char [ANY] "$result = rb_str_new2($1);"; + +/* References to primitive types. Return by value */ + +%typemap(out) const int &, + const short &, + const long &, + const signed char & + "$result = INT2NUM((long) *($1));"; + +%typemap(out) const unsigned int &, + const unsigned short &, + const unsigned long &, + const unsigned char & + "$result = UINT2NUM((unsigned long) *($1));"; + +%typemap(out) const bool & + "$result = *($1) ? Qtrue : Qfalse;"; + +%typemap(out) const float &, const double & + "$result = rb_float_new((double) *($1));"; + +%typemap(out) const long long & + "$result = LL2NUM(*($1));"; + +%typemap(out) const unsigned long long & + "$result = ULL2NUM(*($1));"; + +%typemap(out) const char & + "$result = rb_str_new($1, 1);"; + +/* --- Variable Input --- */ + +%typemap(varin) int "$1 = NUM2INT($input);"; +%typemap(varin) unsigned int "$1 = NUM2UINT($input);"; +%typemap(varin) short "$1 = NUM2SHRT($input);"; +%typemap(varin) unsigned short "$1 = NUM2USHRT($input);"; +%typemap(varin) long "$1 = NUM2LONG($input);"; +%typemap(varin) unsigned long "$1 = NUM2ULONG($input);"; +%typemap(varin) signed char "$1 = (signed char) NUM2INT($input);"; +%typemap(varin) unsigned char "$1 = (unsigned char) NUM2INT($input);"; +%typemap(varin) char "$1 = NUM2CHR($input);"; +%typemap(varin) float, double "$1 = ($1_ltype) NUM2DBL($input);"; +%typemap(varin) bool "$1 = RTEST($input);"; + +%typemap(varin) long long "$1 = NUM2LL($input);"; +%typemap(varin) unsigned long long "$1 = NUM2ULL($input);"; + +/* A string */ +#ifdef __cplusplus +%typemap(varin) char * { + char *temp = (char *) STR2CSTR($input); + if ($1) delete [] $1; + $1 = ($type) new char[strlen(temp)+1]; + strcpy((char*)$1,temp); +} +%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { + char *temp = (char *) STR2CSTR($input); + $1 = ($type) new char[strlen(temp)+1]; + strcpy((char*)$1,temp); +} +#else +%typemap(varin) char * { + char *temp = (char *) STR2CSTR($input); + if ($1) free((char*) $1); + $1 = ($type) malloc(strlen(temp)+1); + strcpy((char*)$1,temp); +} +%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { + char *temp = (char *) STR2CSTR($input); + $1 = ($type) malloc(strlen(temp)+1); + strcpy((char*)$1,temp); +} + +#endif + +%typemap(varin) char [ANY] "strncpy($1,STR2CSTR($input),$1_dim0);"; +%typemap(varin) enum SWIGTYPE "$1 = ($1_type) NUM2INT($input);"; + +/* Typemaps for pointers. Note: the SWIG run-time type checker works + even if a pointer happens to be mapped to a Ruby class */ + +%typemap(varin) SWIGTYPE *, + SWIGTYPE & + "SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);" + +%typemap(varin) SWIGTYPE [] { + rb_raise(rb_eRuntimeError, "Array $name is readonly"); +} + +%typemap(varin) void * + "SWIG_ConvertPtr($input, (void **) &$1, 0, 1);"; + +%typemap(varin) SWIGTYPE { + $&1_ltype ptr; + SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 1); + if (ptr) $1 = *ptr; +} + +%typemap(varin) SWIGTYPE (CLASS::*) { + char temp[sizeof($1_type)]; + SWIG_ConvertPacked($input, (void *) temp, sizeof($1_type), $1_descriptor, 1); + memmove((void *) &$1, temp, sizeof($1_type)); +} + +/* --- Output typemaps --- */ + +%typemap(varout) int, short, long, signed char, enum SWIGTYPE + "$result = INT2NUM($1);"; + +%typemap(varout) unsigned int, unsigned short, unsigned long, unsigned char + "$result = UINT2NUM($1);"; + +%typemap(varout) long long "$result = LL2NUM($1);"; +%typemap(varout) unsigned long long "$result = ULL2NUM($1);"; + +/* Floats and doubles */ +%typemap(varout) double, float + "$result = rb_float_new($1);"; + +/* Character */ +%typemap(varout) char + "$result = rb_str_new(&$1,1);"; + +/* Boolean */ +%typemap(varout) bool + "$result = $1 ? Qtrue : Qfalse;"; + +/* C string */ +%typemap(varout) char * + "$result = rb_str_new2($1);"; + +/* Pointers, references, and arrays */ +%typemap(varout) SWIGTYPE*, SWIGTYPE [] + "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor,0);"; + +%typemap(varout) SWIGTYPE & + "$result = SWIG_NewPointerObj((void *) &$1, $1_descriptor,0);"; + +/* Void */ +%typemap(varout) void "$result = Qnil;"; + +/* Copy by value */ +%typemap(varout) SWIGTYPE "$result = SWIG_NewPointerObj((void *) &$1, $&1_descriptor, 1);"; + +%typemap(varout) char [ANY] "$result = rb_str_new2($1);"; + +/* Member pointer */ +%typemap(varout) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor);"; + +/* --- Constants --- */ + +%typemap(constant) int, short, long, signed char, enum SWIGTYPE + "rb_define_const($module,\"$symname\", INT2NUM($1));"; + +%typemap(constant) unsigned int, unsigned short, unsigned long, unsigned char + "rb_define_const($module,\"$symname\", UINT2NUM($1));"; + +%typemap(constant) long long + "rb_define_const($module,\"$symname\", LL2NUM($1));"; + +%typemap(constant) unsigned long long + "rb_define_const($module,\"$symname\", ULL2NUM($1));"; + +%typemap(constant) double, float + "rb_define_const($module,\"$symname\", rb_float_new($1));"; + +%typemap(constant) char + "rb_define_const($module,\"$symname\", rb_str_new(\"$1\",1));"; + +%typemap(constant) bool + "rb_define_const($module,\"$symname\", ($1 ? Qtrue : Qfalse));"; + +%typemap(constant) char * + "rb_define_const($module,\"$symname\", rb_str_new2(\"$1\"));"; + +%typemap(constant) SWIGTYPE*, SWIGTYPE &, SWIGTYPE [] + "rb_define_const($module,\"$symname\", SWIG_NewPointerObj((void *) $1, $1_descriptor,0));"; + +%typemap(constant) SWIGTYPE "rb_define_const($module,\"$symname\", SWIG_NewPointerObj((void *) &$1, $&1_descriptor, 0));"; + +%typemap(constant) SWIGTYPE (CLASS::*) "rb_define_const($module, \"$symname\", SWIG_NewPackedObj((void *) &$1, sizeof($type), $1_descriptor));"; + +/* ------------------------------------------------------------ + * typedef & typemaps for VALUE (passed through unmodified) + * ------------------------------------------------------------ */ + +typedef unsigned long VALUE; + +%typemap(ruby,in) VALUE "$1 = $input;"; +%typemap(ruby,out) VALUE "$result = $1;"; + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +%typemap(in) (char *STRING, int LENGTH) { + $1 = ($1_ltype) STR2CSTR($input); + $2 = ($2_ltype) RSTRING($input)->len; +} + +/* Some ANSI C typemaps */ + +%apply long { size_t }; + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + $1 = (NIL_P($input) || (TYPE($input) == T_DATA && SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 0) != -1)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + $1 = (NIL_P($input) || (TYPE($input) == T_DATA && SWIG_ConvertPtr($input, &ptr, $1_descriptor, 0) != -1)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + $1 = (NIL_P($input) || (TYPE($input) == T_DATA && SWIG_ConvertPtr($input, &ptr, 0, 0) != -1)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_BOOL) bool { + $1 = ($input == Qtrue || $input == Qfalse) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE +{ + $1 = ((TYPE($input) == T_FIXNUM) || (TYPE($input) == T_BIGNUM)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + $1 = ((TYPE($input) == T_FLOAT) || (TYPE($input) == T_FIXNUM) || (TYPE($input) == T_BIGNUM)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + $1 = (TYPE($input) == T_STRING && (RSTRING($input)->len == 1)) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = (TYPE($input) == T_STRING) ? 1 : 0; +} + +/* ------------------------------------------------------------ + * Exception handling + * ------------------------------------------------------------ */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + rb_exc_raise(rb_exc_new3(rb_eRuntimeError, INT2NUM($1))); +} + +%typemap(throws) SWIGTYPE { + $&1_ltype temp = new $1_ltype($1); + if ($&1_descriptor->clientdata) { + rb_exc_raise(rb_exc_new3(((swig_class *) ($&1_descriptor->clientdata))->klass, SWIG_NewPointerObj(temp, $&1_descriptor, 1))); + } else { + rb_exc_raise(rb_exc_new3(rb_eRuntimeError, SWIG_NewPointerObj(temp, $&1_descriptor, 1))); + } +} + +%typemap(throws) char * { + rb_raise(rb_eRuntimeError, $1); +} + +/* ------------------------------------------------------------ + * Overloaded operator support + * ------------------------------------------------------------ */ + +#ifdef __cplusplus + +%rename(__add__) *::operator+; +%rename(__pos__) *::operator+(); +%rename(__pos__) *::operator+() const; +%rename(__sub__) *::operator-; +%rename(__neg__) *::operator-(); +%rename(__neg__) *::operator-() const; +%rename(__mul__) *::operator*; +%rename(__div__) *::operator/; +%rename(__mod__) *::operator%; +%rename(__lshift__) *::operator<<; +%rename(__rshift__) *::operator>>; +%rename(__and__) *::operator&; +%rename(__or__) *::operator|; +%rename(__xor__) *::operator^; +%rename(__invert__) *::operator~; +%rename(__lt__) *::operator<; +%rename(__le__) *::operator<=; +%rename(__gt__) *::operator>; +%rename(__ge__) *::operator>=; +%rename(__eq__) *::operator==; + +/* Special cases */ +%rename(__call__) *::operator(); + +/* Ignored operators */ +%ignorewarn("378:operator!= ignored") operator!=; +%ignorewarn("365:operator+= ignored") operator+=; +%ignorewarn("366:operator-= ignored") operator-=; +%ignorewarn("367:operator*= ignored") operator*=; +%ignorewarn("368:operator/= ignored") operator/=; +%ignorewarn("369:operator%= ignored") operator%=; +%ignorewarn("375:operator<<= ignored") operator<<=; +%ignorewarn("376:operator>>= ignored") operator>>=; +%ignorewarn("371:operator&= ignored") operator&=; +%ignorewarn("372:operator|= ignored") operator|=; +%ignorewarn("370:operator^= ignored") operator^=; +%ignorewarn("362:operator= ignored") operator=; +%ignorewarn("383:operator++ ignored") operator++; +%ignorewarn("384:operator-- ignored") operator--; +%ignorewarn("381:operator&& ignored") operator&&; +%ignorewarn("382:operator|| ignored") operator||; +// %ignorewarn("387:operator-> ignored") operator->; +%ignorewarn("386:operator->* ignored") operator->*; +%ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; + +#endif /* __cplusplus */ diff --git a/Lib/ruby/rubydec.swg b/Lib/ruby/rubydec.swg index fe1fc2780..210310301 100644 --- a/Lib/ruby/rubydec.swg +++ b/Lib/ruby/rubydec.swg @@ -3,13 +3,18 @@ extern "C" { #endif -SWIGEXPORT(void) SWIG_define_class(VALUE, swig_type_info *) -SWIGEXPORT(VALUE) SWIG_NewPointerObj(void *, swig_type_info *); -SWIGEXPORT(char *) SWIG_MangleStr(VALUE); -SWIGEXPORT(void *) SWIG_ConvertPtr(VALUE, swig_type_info *); -SWIGEXPORT(int) SWIG_CheckConvert(VALUE, swig_type_info *); +SWIGIMPORT(void) SWIG_InitRuntime(void); +SWIGIMPORT(void) SWIG_define_class(swig_type_info *); +SWIGIMPORT(VALUE) SWIG_NewPointerObj(void *, swig_type_info *, int); +SWIGIMPORT(VALUE) SWIG_NewClassInstance(VALUE, swig_type_info *); +SWIGIMPORT(char *) SWIG_MangleStr(VALUE); +SWIGIMPORT(int) SWIG_ConvertPtr(VALUE, void**, swig_type_info *, int); +SWIGIMPORT(int) SWIG_CheckConvert(VALUE, swig_type_info *); +SWIGIMPORT(char *) SWIG_PackData(char *c, void *ptr, int sz); +SWIGIMPORT(char *) SWIG_UnpackData(char *c, void *ptr, int sz); +SWIGIMPORT(VALUE) SWIG_NewPackedObj(void *ptr, int sz, swig_type_info *type); +SWIGIMPORT(void) SWIG_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty, int flags); #ifdef __cplusplus } #endif - diff --git a/Lib/ruby/rubydef.swg b/Lib/ruby/rubydef.swg index ec0d0f0c3..07276414c 100644 --- a/Lib/ruby/rubydef.swg +++ b/Lib/ruby/rubydef.swg @@ -3,75 +3,121 @@ extern "C" { #endif - static VALUE _mSWIG = Qnil; static VALUE _cSWIG_Pointer = Qnil; -/* Define ruby class for C type */ +/* Initialize Ruby runtime support */ +SWIGRUNTIME(void) +SWIG_InitRuntime(void) +{ + if (_mSWIG == Qnil) { + _mSWIG = rb_define_module("SWIG"); + } +} + +/* Define Ruby class for C type */ SWIGRUNTIME(void) SWIG_define_class(swig_type_info *type) { VALUE klass; - char *klass_name = ALLOCA_N(char, 4 + strlen(type->name) + 1); - + char *klass_name = (char *) malloc(4 + strlen(type->name) + 1); sprintf(klass_name, "TYPE%s", type->name); if (NIL_P(_cSWIG_Pointer)) { _cSWIG_Pointer = rb_define_class_under(_mSWIG, "Pointer", rb_cObject); rb_undef_method(CLASS_OF(_cSWIG_Pointer), "new"); } klass = rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer); + free((void *) klass_name); } /* Create a new pointer object */ SWIGRUNTIME(VALUE) -SWIG_NewPointerObj(void *ptr, swig_type_info *type) +SWIG_NewPointerObj(void *ptr, swig_type_info *type, int own) { char *klass_name; + swig_class *sklass; VALUE klass; - + VALUE obj; + if (!ptr) return Qnil; + + if (type->clientdata) { + sklass = (swig_class *) type->clientdata; + obj = Data_Wrap_Struct(sklass->klass, VOIDFUNC(sklass->mark), (own ? VOIDFUNC(sklass->destroy) : 0), ptr); + } else { + klass_name = (char *) malloc(4 + strlen(type->name) + 1); + sprintf(klass_name, "TYPE%s", type->name); + klass = rb_const_get(_mSWIG, rb_intern(klass_name)); + free((void *) klass_name); + obj = Data_Wrap_Struct(klass, 0, 0, ptr); + } + rb_iv_set(obj, "__swigtype__", rb_str_new2(type->name)); + return obj; +} - klass_name = ALLOCA_N(char, 4 + strlen(type->name) + 1); - sprintf(klass_name, "TYPE%s", type->name); - klass = rb_const_get(_mSWIG, rb_intern(klass_name)); - return Data_Wrap_Struct(klass, 0, 0, ptr); +/* Create a new class instance (always owned) */ +SWIGRUNTIME(VALUE) +SWIG_NewClassInstance(VALUE klass, swig_type_info *type) +{ + VALUE obj; + swig_class *sklass = (swig_class *) type->clientdata; + obj = Data_Wrap_Struct(klass, VOIDFUNC(sklass->mark), VOIDFUNC(sklass->destroy), 0); + rb_iv_set(obj, "__swigtype__", rb_str_new2(type->name)); + return obj; } /* Get type mangle from class name */ SWIGRUNTIME(char *) SWIG_MangleStr(VALUE obj) { - char *c; - - if (!rb_obj_is_kind_of(obj, _cSWIG_Pointer)) - return 0; - - c = rb_class2name(rb_class_of(obj)); - c += strlen(c); - while (*(--c) != ':'); - /* skip ":TYPE" */ - c += 5; - return c; + VALUE stype = rb_iv_get(obj, "__swigtype__"); + return STR2CSTR(stype); } /* Convert a pointer value */ -SWIGRUNTIME(void *) -SWIG_ConvertPtr(VALUE obj, swig_type_info *ty) +SWIGRUNTIME(int) +SWIG_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, int flags) { char *c; - void *ptr; swig_type_info *tc; - if ((c = SWIG_MangleStr(obj)) == NULL) - rb_raise(rb_eTypeError, "Expected %s", ty->str); - Data_Get_Struct(obj, void, ptr); + /* Grab the pointer */ + if (NIL_P(obj)) { + *ptr = 0; + return 0; + } else + Data_Get_Struct(obj, void, *ptr); + + /* Do type-checking if type info was provided */ if (ty) { - tc = SWIG_TypeCheck(c, ty); - if (!tc) rb_raise(rb_eTypeError, "Expected %s", ty->str); - ptr = SWIG_TypeCast(tc, ptr); + if (ty->clientdata) { + if (!rb_obj_is_kind_of(obj, ((swig_class *) (ty->clientdata))->klass)) { + if (flags) + rb_raise(rb_eTypeError, "wrong argument type (expected %s)", ty->str); + else + return -1; + } + if (*ptr == 0) + rb_raise(rb_eRuntimeError, "This %s already released", ty->str); + } else { + if ((c = SWIG_MangleStr(obj)) == NULL) { + if (flags) + rb_raise(rb_eTypeError, "Expected %s", ty->str); + else + return -1; + } + tc = SWIG_TypeCheck(c, ty); + if (!tc) { + if (flags) + rb_raise(rb_eTypeError, "Expected %s", ty->str); + else + return -1; + } + *ptr = SWIG_TypeCast(tc, *ptr); + } } - return ptr; + return 0; } /* Check convert */ @@ -84,6 +130,84 @@ SWIG_CheckConvert(VALUE obj, swig_type_info *ty) return SWIG_TypeCheck(c,ty) != 0; } +/* Pack binary data into a string */ +SWIGRUNTIME(char *) +SWIG_PackData(char *c, void *ptr, int sz) { + static char hex[17] = "0123456789abcdef"; + int i; + unsigned char *u = (unsigned char *) ptr; + register unsigned char uu; + for (i = 0; i < sz; i++,u++) { + uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* Unpack binary data from a string */ +SWIGRUNTIME(char *) +SWIG_UnpackData(char *c, void *ptr, int sz) { + register unsigned char uu = 0; + register int d; + unsigned char *u = (unsigned char *) ptr; + int i; + for (i = 0; i < sz; i++, u++) { + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + *u = uu; + } + return c; +} + +SWIGRUNTIME(VALUE) +SWIG_NewPackedObj(void *ptr, int sz, swig_type_info *type) { + char result[1024]; + char *r = result; + if ((2*sz + 1 + strlen(type->name)) > 1000) return 0; + *(r++) = '_'; + r = SWIG_PackData(r, ptr, sz); + strcpy(r, type->name); + return rb_str_new2(result); +} + +/* Convert a packed value value */ +SWIGRUNTIME(void) +SWIG_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty, int flags) { + swig_type_info *tc; + char *c; + + if (TYPE(obj) != T_STRING) goto type_error; + c = STR2CSTR(obj); + /* Pointer values must start with leading underscore */ + if (*c != '_') goto type_error; + c++; + c = SWIG_UnpackData(c, ptr, sz); + if (ty) { + tc = SWIG_TypeCheck(c, ty); + if (!tc) goto type_error; + } + return; + +type_error: + + if (flags) { + if (ty) { + rb_raise(rb_eTypeError, "Type error. Expected %s", ty->name); + } else { + rb_raise(rb_eTypeError, "Expected a pointer"); + } + } +} + #ifdef __cplusplus } #endif diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg new file mode 100644 index 000000000..23783ef95 --- /dev/null +++ b/Lib/ruby/rubyhead.swg @@ -0,0 +1,71 @@ +/* ruby.swg */ +/* Implementation : RUBY */ +#define SWIGRUBY 1 + +#include "ruby.h" + +#define NUM2USHRT(n) NUM2UINT(n) +#define NUM2SHRT(n) (\ + (SHRT_MIN <= NUM2INT(n) && NUM2INT(n) <= SHRT_MAX)\ + ? (short)NUM2INT(n)\ + : (rb_raise(rb_eArgError, "integer %d out of range of `short'",\ + NUM2INT(n)), (short)0)\ +) + +/* Ruby 1.7 defines NUM2LL(), LL2NUM() and ULL2NUM() macros */ +#ifndef NUM2LL +#define NUM2LL(x) NUM2LONG((x)) +#endif +#ifndef LL2NUM +#define LL2NUM(x) INT2NUM((long) (x)) +#endif +#ifndef ULL2NUM +#define ULL2NUM(x) UINT2NUM((unsigned long) (x)) +#endif + +/* Ruby 1.7 doesn't (yet) define NUM2ULL() */ +#ifndef NUM2ULL +#ifdef HAVE_LONG_LONG +#define NUM2ULL(x) rb_num2ull((x)) +#else +#define NUM2ULL(x) NUM2ULONG(x) +#endif +#endif + +/* + * Need to be very careful about how these macros are defined, especially + * when compiling C++ code or C code with an ANSI C compiler. + * + * VALUEFUNC(f) is a macro used to typecast a C function that implements + * a Ruby method so that it can be passed as an argument to API functions + * like rb_define_method() and rb_define_singleton_method(). + * + * VOIDFUNC(f) is a macro used to typecast a C function that implements + * either the "mark" or "free" stuff for a Ruby Data object, so that it + * can be passed as an argument to API functions like Data_Wrap_Struct() + * and Data_Make_Struct(). + */ + +#ifdef __cplusplus +# ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */ +# define VALUEFUNC(f) ((VALUE (*)()) f) +# define VOIDFUNC(f) ((void (*)()) f) +# else +# ifndef ANYARGS /* These definitions should work for Ruby 1.6 */ +# define VALUEFUNC(f) ((VALUE (*)()) f) +# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) +# else /* These definitions should work for Ruby 1.7 */ +# define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f) +# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) +# endif +# endif +#else +# define VALUEFUNC(f) (f) +# define VOIDFUNC(f) (f) +#endif + +typedef struct { + VALUE klass; + void (*mark)(void *); + void (*destroy)(void *); +} swig_class; diff --git a/Lib/ruby/std_common.i b/Lib/ruby/std_common.i new file mode 100644 index 000000000..23069f364 --- /dev/null +++ b/Lib/ruby/std_common.i @@ -0,0 +1,35 @@ +// +// SWIG typemaps for STL - common utilities +// Luigi Ballabio +// Aug 3, 2002 +// +// Ruby implementation + +%{ +#include + +#define SWIG_FLOAT_P(x) ((TYPE(x) == T_FLOAT) || FIXNUM_P(x)) + +bool SWIG_BOOL_P(VALUE) { + // dummy test, RTEST should take care of everything + return true; +} +bool SWIG_RB2BOOL(VALUE x) { + return RTEST(x); +} +VALUE SWIG_BOOL2RB(bool b) { + return b ? Qtrue : Qfalse; +} +double SWIG_NUM2DBL(VALUE x) { + return (FIXNUM_P(x) ? FIX2INT(x) : NUM2DBL(x)); +} +bool SWIG_STRING_P(VALUE x) { + return TYPE(x) == T_STRING; +} +std::string SWIG_RB2STR(VALUE x) { + return std::string(STR2CSTR(x)); +} +VALUE SWIG_STR2RB(const std::string& s) { + return rb_str_new2(s.c_str()); +} +%} diff --git a/Lib/ruby/std_string.i b/Lib/ruby/std_string.i new file mode 100644 index 000000000..0fc77b4ce --- /dev/null +++ b/Lib/ruby/std_string.i @@ -0,0 +1,56 @@ +// +// SWIG typemaps for std::string +// Luigi Ballabio +// Apr 8, 2002 +// +// Ruby implementation + + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + // Ruby wants class names to start with a capital letter + %rename(String) string; + class string; + + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string { + if (TYPE($input) == T_STRING) { + $1 = std::string(STR2CSTR($input)); + } else { + SWIG_exception(SWIG_TypeError, "not a string"); + } + } + + %typemap(in) const string & (std::string temp) { + if (TYPE($input) == T_STRING) { + temp = std::string(STR2CSTR($input)); + $1 = &temp; + } else { + SWIG_exception(SWIG_TypeError, "not a string"); + } + } + + %typemap(out) string { + $result = rb_str_new2($1.c_str()); + } + + %typemap(out) const string & { + $result = rb_str_new2($1->c_str()); + } + +} diff --git a/Lib/ruby/std_vector.i b/Lib/ruby/std_vector.i new file mode 100644 index 000000000..5297c585f --- /dev/null +++ b/Lib/ruby/std_vector.i @@ -0,0 +1,373 @@ +// +// SWIG typemaps for std::vector +// Luigi Ballabio +// Apr 8, 2002 +// +// Ruby implementation + +%include std_common.i +%include exception.i + +%exception std::vector::__getitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::__setitem__ { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Ruby as much as possible, namely, to allow the user to pass and +// be returned Ruby arrays +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Ruby array or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Ruby array of T:s +// is returned which is most easily used in other Ruby functions +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + %mixin vector "Enumerable"; + + template class vector { + %typemap(in) vector { + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + $1 = std::vector(size); + for (unsigned int i=0; iptr[i]; + T* x; + SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); + (($1_type &)$1)[i] = *x; + } + } else { + void *ptr; + SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); + $1 = *(($&1_type) ptr); + } + } + %typemap(in) const vector& (std::vector temp), + const vector* (std::vector temp) { + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + temp = std::vector(size); + $1 = &temp; + for (unsigned int i=0; iptr[i]; + T* x; + SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); + temp[i] = *x; + } + } else { + SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); + } + } + %typemap(out) vector { + $result = rb_ary_new2($1.size()); + for (unsigned int i=0; i<$1.size(); i++) { + T* x = new T((($1_type &)$1)[i]); + rb_ary_store($result,i, + SWIG_NewPointerObj((void *) x, + $descriptor(T *), 1)); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + VALUE o = RARRAY($input)->ptr[0]; + if ((SWIG_ConvertPtr(o,(void **) &x, + $descriptor(T *),0)) != -1) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + VALUE o = RARRAY($input)->ptr[0]; + if ((SWIG_ConvertPtr(o,(void **) &x, + $descriptor(T *),0)) != -1) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector &); + + %rename(__len__) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename(push) push_back; + void push_back(const T& x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& __getitem__(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && isize()); + if (i<0) i+= size; + if (i>=0 && isize(); i++) { + T* x = new T((*self)[i]); + rb_yield(SWIG_NewPointerObj((void *) x, type, 1)); + } + } + } + }; + + + // specializations for built-ins + + %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) + %mixin vector "Enumerable"; + template<> class vector { + %typemap(in) vector { + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + $1 = std::vector(size); + for (unsigned int i=0; iptr[i]; + if (CHECK(o)) + (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); + else + rb_raise(rb_eTypeError, + "wrong argument type" + " (expected vector<" #T ">)"); + } + } else { + void *ptr; + SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); + $1 = *(($&1_type) ptr); + } + } + %typemap(in) const vector& (std::vector temp), + const vector* (std::vector temp) { + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + temp = std::vector(size); + $1 = &temp; + for (unsigned int i=0; iptr[i]; + if (CHECK(o)) + temp[i] = (T)(CONVERT_FROM(o)); + else + rb_raise(rb_eTypeError, + "wrong argument type" + " (expected vector<" #T ">)"); + } + } else { + SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); + } + } + %typemap(out) vector { + $result = rb_ary_new2($1.size()); + for (unsigned int i=0; i<$1.size(); i++) + rb_ary_store($result,i,CONVERT_TO((($1_type &)$1)[i])); + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + /* native sequence? */ + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + VALUE o = RARRAY($input)->ptr[0]; + if (CHECK(o)) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + /* native sequence? */ + if (rb_obj_is_kind_of($input,rb_cArray)) { + unsigned int size = RARRAY($input)->len; + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + VALUE o = RARRAY($input)->ptr[0]; + if (CHECK(o)) + $1 = 1; + else + $1 = 0; + } + } else { + /* wrapped vector? */ + std::vector* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector &); + + %rename(__len__) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename(push) push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T __getitem__(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && isize()); + if (i<0) i+= size; + if (i>=0 && isize(); i++) + rb_yield(CONVERT_TO((*self)[i])); + } + } + }; + %enddef + + specialize_std_vector(bool,SWIG_BOOL_P,SWIG_RB2BOOL,SWIG_BOOL2RB); + specialize_std_vector(int,FIXNUM_P,FIX2INT,INT2NUM); + specialize_std_vector(short,FIXNUM_P,FIX2INT,INT2NUM); + specialize_std_vector(long,FIXNUM_P,FIX2INT,INT2NUM); + specialize_std_vector(unsigned int,FIXNUM_P,FIX2INT,INT2NUM); + specialize_std_vector(unsigned short,FIXNUM_P,FIX2INT,INT2NUM); + specialize_std_vector(unsigned long,FIXNUM_P,FIX2INT,INT2NUM); + specialize_std_vector(double,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new); + specialize_std_vector(float,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new); + specialize_std_vector(std::string,SWIG_STRING_P,SWIG_RB2STR,SWIG_STR2RB); + +} + diff --git a/Lib/ruby/stl.i b/Lib/ruby/stl.i new file mode 100644 index 000000000..ce9a6c1a7 --- /dev/null +++ b/Lib/ruby/stl.i @@ -0,0 +1,9 @@ +// +// SWIG typemaps for STL types +// Luigi Ballabio and Manu ??? +// Apr 26, 2002 +// + +%include std_string.i +%include std_vector.i + diff --git a/Lib/ruby/typemaps.i b/Lib/ruby/typemaps.i index 9e04d42e8..2439eab36 100644 --- a/Lib/ruby/typemaps.i +++ b/Lib/ruby/typemaps.i @@ -9,19 +9,13 @@ // Masaki Fukushima // -#ifdef AUTODOC -%section "Typemap Library (Ruby)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 -%text %{ -%include typemaps.i - +/* The SWIG typemap library provides a language independent mechanism for supporting output arguments, input values, and other C function calling mechanisms. The primary use of the library is to provide a better interface to certain C function--especially those involving pointers. -%} - -#endif +*/ // ------------------------------------------------------------------------ // Pointer handling @@ -34,11 +28,7 @@ pointers. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. - -#ifdef AUTODOC -%subsection "Input Methods" - -%text %{ +/* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. @@ -50,6 +40,7 @@ you would use a real value instead. unsigned short *INPUT unsigned long *INPUT unsigned char *INPUT + bool *INPUT float *INPUT double *INPUT @@ -70,73 +61,37 @@ or you can use the %apply directive : %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); -%} -#endif +*/ -%typemap(ruby,in) double *INPUT(double temp) +%define INPUT_TYPEMAP(type, converter) +%typemap(in) type *INPUT(type temp), type &INPUT(type temp) { - temp = NUM2DBL($source); - $target = &temp; + temp = (type) converter($input); + $1 = &temp; } +%typemap(typecheck) type *INPUT = type; +%typemap(typecheck) type &INPUT = type; +%enddef -%typemap(ruby,in) float *INPUT(float temp) -{ - temp = (float) NUM2DBL($source); - $target = &temp; -} +INPUT_TYPEMAP(float, NUM2DBL); +INPUT_TYPEMAP(double, NUM2DBL); +INPUT_TYPEMAP(int, NUM2INT); +INPUT_TYPEMAP(short, NUM2SHRT); +INPUT_TYPEMAP(long, NUM2LONG); +INPUT_TYPEMAP(unsigned int, NUM2UINT); +INPUT_TYPEMAP(unsigned short, NUM2USHRT); +INPUT_TYPEMAP(unsigned long, NUM2ULONG); +INPUT_TYPEMAP(unsigned char, NUM2UINT); +INPUT_TYPEMAP(signed char, NUM2INT); +INPUT_TYPEMAP(bool, RTEST); -%typemap(ruby,in) int *INPUT(int temp) -{ - temp = NUM2INT($source); - $target = &temp; -} +#undef INPUT_TYPEMAP -%typemap(ruby,in) short *INPUT(short temp) -{ - temp = NUM2SHRT($source); - $target = &temp; -} - -%typemap(ruby,in) long *INPUT(long temp) -{ - temp = NUM2LONG($source); - $target = &temp; -} -%typemap(ruby,in) unsigned int *INPUT(unsigned int temp) -{ - temp = NUM2UINT($source); - $target = &temp; -} -%typemap(ruby,in) unsigned short *INPUT(unsigned short temp) -{ - temp = NUM2USHRT($source); - $target = &temp; -} -%typemap(ruby,in) unsigned long *INPUT(unsigned long temp) -{ - temp = NUM2ULONG($source); - $target = &temp; -} -%typemap(ruby,in) unsigned char *INPUT(unsigned char temp) -{ - temp = (unsigned char)NUM2UINT($source); - $target = &temp; -} - -%typemap(ruby,in) signed char *INPUT(signed char temp) -{ - temp = (signed char)NUM2INT($source); - $target = &temp; -} - // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a array element. -#ifdef AUTODOC -%subsection "Output Methods" - -%text %{ +/* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of @@ -149,6 +104,7 @@ multiple output values, they are returned in the form of a Ruby Array. unsigned short *OUTPUT unsigned long *OUTPUT unsigned char *OUTPUT + bool *OUTPUT float *OUTPUT double *OUTPUT @@ -171,74 +127,42 @@ or you can use the %apply directive : The Ruby output of the function would be a Array containing both output values. -%} -#endif +*/ -// Helper function for Array output - -%{ -static VALUE output_helper(VALUE target, VALUE o) { - if (NIL_P(target)) { - target = o; - } else { - if (TYPE(target) != T_ARRAY) { - VALUE o2 = target; - target = rb_ary_new(); - rb_ary_push(target, o2); - } - rb_ary_push(target, o); - } - return target; +%include "fragments.i" + +%define OUTPUT_TYPEMAP(type, converter, convtype) +%typemap(in,numinputs=0) type *OUTPUT(type temp), type &OUTPUT(type temp) "$1 = &temp;"; +%typemap(argout, fragment="output_helper") type *OUTPUT, type &OUTPUT { + VALUE o = converter(convtype (*$1)); + $result = output_helper($result, o); } -%} +%enddef -// Force the argument to be ignored. +OUTPUT_TYPEMAP(int, INT2NUM, (int)); +OUTPUT_TYPEMAP(short, INT2NUM, (int)); +OUTPUT_TYPEMAP(long, INT2NUM, (int)); +OUTPUT_TYPEMAP(unsigned int, UINT2NUM, (unsigned int)); +OUTPUT_TYPEMAP(unsigned short, UINT2NUM, (unsigned int)); +OUTPUT_TYPEMAP(unsigned long, UINT2NUM, (unsigned int)); +OUTPUT_TYPEMAP(unsigned char, UINT2NUM, (unsigned int)); +OUTPUT_TYPEMAP(signed char, INT2NUM, (int)); +OUTPUT_TYPEMAP(float, rb_float_new, (double)); +OUTPUT_TYPEMAP(double, rb_float_new, (double)); -%typemap(ruby,ignore) int *OUTPUT(int temp), - short *OUTPUT(short temp), - long *OUTPUT(long temp), - unsigned int *OUTPUT(unsigned int temp), - unsigned short *OUTPUT(unsigned short temp), - unsigned long *OUTPUT(unsigned long temp), - unsigned char *OUTPUT(unsigned char temp), - signed char *OUTPUT(signed char temp), - float *OUTPUT(float temp), - double *OUTPUT(double temp) -{ - $target = &temp; -} +#undef OUTPUT_TYPEMAP -%typemap(ruby,argout) int *OUTPUT, - short *OUTPUT, - long *OUTPUT, - signed char *OUTPUT -{ - $target = output_helper($target, INT2NUM(*$source)); -} - -%typemap(ruby,argout) unsigned int *OUTPUT, - unsigned short *OUTPUT, - unsigned long *OUTPUT, - unsigned char *OUTPUT -{ - $target = output_helper($target, UINT2NUM(*$source)); -} - -%typemap(ruby,argout) float *OUTPUT, - double *OUTPUT -{ - $target = output_helper($target, rb_float_new(*$source)); +%typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;"; +%typemap(argout, fragment="output_helper") bool *OUTPUT, bool &OUTPUT { + VALUE o = (*$1) ? Qtrue : Qfalse; + $result = output_helper($result, o); } // INOUT // Mappings for an argument that is both an input and output // parameter - -#ifdef AUTODOC -%subsection "Input/Output Methods" - -%text %{ +/* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are @@ -251,6 +175,7 @@ returned in the form of a Ruby array. unsigned short *INOUT unsigned long *INOUT unsigned char *INOUT + bool *INOUT float *INOUT double *INOUT @@ -281,101 +206,68 @@ to a Ruby variable you might do this : Note : previous versions of SWIG used the symbol 'BOTH' to mark input/output arguments. This is still supported, but will be slowly phased out in future releases. -%} -#endif +*/ -%typemap(ruby,in) int *INOUT = int *INPUT; -%typemap(ruby,in) short *INOUT = short *INPUT; -%typemap(ruby,in) long *INOUT = long *INPUT; -%typemap(ruby,in) unsigned *INOUT = unsigned *INPUT; -%typemap(ruby,in) unsigned short *INOUT = unsigned short *INPUT; -%typemap(ruby,in) unsigned long *INOUT = unsigned long *INPUT; -%typemap(ruby,in) unsigned char *INOUT = unsigned char *INPUT; -%typemap(ruby,in) float *INOUT = float *INPUT; -%typemap(ruby,in) double *INOUT = double *INPUT; +%typemap(in) int *INOUT = int *INPUT; +%typemap(in) short *INOUT = short *INPUT; +%typemap(in) long *INOUT = long *INPUT; +%typemap(in) unsigned *INOUT = unsigned *INPUT; +%typemap(in) unsigned short *INOUT = unsigned short *INPUT; +%typemap(in) unsigned long *INOUT = unsigned long *INPUT; +%typemap(in) unsigned char *INOUT = unsigned char *INPUT; +%typemap(in) signed char *INOUT = signed char *INPUT; +%typemap(in) bool *INOUT = bool *INPUT; +%typemap(in) float *INOUT = float *INPUT; +%typemap(in) double *INOUT = double *INPUT; -%typemap(ruby,argout) int *INOUT = int *OUTPUT; -%typemap(ruby,argout) short *INOUT = short *OUTPUT; -%typemap(ruby,argout) long *INOUT = long *OUTPUT; -%typemap(ruby,argout) unsigned *INOUT = unsigned *OUTPUT; -%typemap(ruby,argout) unsigned short *INOUT = unsigned short *OUTPUT; -%typemap(ruby,argout) unsigned long *INOUT = unsigned long *OUTPUT; -%typemap(ruby,argout) unsigned char *INOUT = unsigned char *OUTPUT; -%typemap(ruby,argout) float *INOUT = float *OUTPUT; -%typemap(ruby,argout) double *INOUT = double *OUTPUT; +%typemap(in) int &INOUT = int &INPUT; +%typemap(in) short &INOUT = short &INPUT; +%typemap(in) long &INOUT = long &INPUT; +%typemap(in) unsigned &INOUT = unsigned &INPUT; +%typemap(in) unsigned short &INOUT = unsigned short &INPUT; +%typemap(in) unsigned long &INOUT = unsigned long &INPUT; +%typemap(in) unsigned char &INOUT = unsigned char &INPUT; +%typemap(in) signed char &INOUT = signed char &INPUT; +%typemap(in) bool &INOUT = bool &INPUT; +%typemap(in) float &INOUT = float &INPUT; +%typemap(in) double &INOUT = double &INPUT; -// Backwards compatibility - -%typemap(ruby,in) int *BOTH = int *INOUT; -%typemap(ruby,in) short *BOTH = short *INOUT; -%typemap(ruby,in) long *BOTH = long *INOUT; -%typemap(ruby,in) unsigned *BOTH = unsigned *INOUT; -%typemap(ruby,in) unsigned short *BOTH = unsigned short *INOUT; -%typemap(ruby,in) unsigned long *BOTH = unsigned long *INOUT; -%typemap(ruby,in) unsigned char *BOTH = unsigned char *INOUT; -%typemap(ruby,in) float *BOTH = float *INOUT; -%typemap(ruby,in) double *BOTH = double *INOUT; - -%typemap(ruby,argout) int *BOTH = int *INOUT; -%typemap(ruby,argout) short *BOTH = short *INOUT; -%typemap(ruby,argout) long *BOTH = long *INOUT; -%typemap(ruby,argout) unsigned *BOTH = unsigned *INOUT; -%typemap(ruby,argout) unsigned short *BOTH = unsigned short *INOUT; -%typemap(ruby,argout) unsigned long *BOTH = unsigned long *INOUT; -%typemap(ruby,argout) unsigned char *BOTH = unsigned char *INOUT; -%typemap(ruby,argout) float *BOTH = float *INOUT; -%typemap(ruby,argout) double *BOTH = double *INOUT; - -// -------------------------------------------------------------------- -// OUTPUT typemaps for user defined type. -// -// -------------------------------------------------------------------- - -#ifdef AUTODOC -%subsection "Output Methods for User-defined types" - -%text %{ -The following method can be applied to turn a pointer to -user-defined type returned through function aruguments into -an output value. - - User **OUTPUT - -You can use the %apply directive : - - %include typemaps.i - %apply User **OUTPUT { Foo **OUTPUT }; - int foo_func(Foo **OUTPUT); - -%} -#endif - -%typemap(ruby,ignore) User **OUTPUT(void *temp) -{ - $target = ($type)&temp; -} -%typemap(ruby,argout) User **OUTPUT -{ - $target = output_helper($target, Wrap_$basetype(*$source)); -} +%typemap(argout) int *INOUT = int *OUTPUT; +%typemap(argout) short *INOUT = short *OUTPUT; +%typemap(argout) long *INOUT = long *OUTPUT; +%typemap(argout) unsigned *INOUT = unsigned *OUTPUT; +%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; +%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; +%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; +%typemap(argout) signed char *INOUT = signed char *OUTPUT; +%typemap(argout) bool *INOUT = bool *OUTPUT; +%typemap(argout) float *INOUT = float *OUTPUT; +%typemap(argout) double *INOUT = double *OUTPUT; +%typemap(argout) int &INOUT = int &OUTPUT; +%typemap(argout) short &INOUT = short &OUTPUT; +%typemap(argout) long &INOUT = long &OUTPUT; +%typemap(argout) unsigned &INOUT = unsigned &OUTPUT; +%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; +%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; +%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; +%typemap(argout) signed char &INOUT = signed char &OUTPUT; +%typemap(argout) bool &INOUT = bool &OUTPUT; +%typemap(argout) float &INOUT = float &OUTPUT; +%typemap(argout) double &INOUT = double &OUTPUT; // -------------------------------------------------------------------- // Special types -// // -------------------------------------------------------------------- -#ifdef AUTODOC -%subsection "Special Methods" - -%text %{ +/* The typemaps.i library also provides the following mappings : struct timeval * time_t - Ruby has builtin class Time. INPUT/OUPUT typemap for timeval and + Ruby has builtin class Time. INPUT/OUTPUT typemap for timeval and time_t is provided. int PROG_ARGC @@ -384,9 +276,7 @@ char **PROG_ARGV Some C function receive argc and argv from C main function. This typemap provides ignore typemap which pass Ruby ARGV contents as argc and argv to C function. -%} - -#endif +*/ // struct timeval * @@ -403,71 +293,71 @@ struct timeval rb_time_timeval(VALUE); #endif %} -%typemap(ruby,in) struct timeval *INPUT (struct timeval temp) +%typemap(in) struct timeval *INPUT (struct timeval temp) { - if (NIL_P($source)) - $target = NULL; + if (NIL_P($input)) + $1 = NULL; else { - temp = rb_time_timeval($source); - $target = &temp; + temp = rb_time_timeval($input); + $1 = &temp; } } -%typemap(ruby,ignore) struct timeval *OUTPUT(struct timeval temp) +%typemap(in,numinputs=0) struct timeval *OUTPUT(struct timeval temp) { - $target = &temp; + $1 = &temp; } -%typemap(ruby,argout) struct timeval *OUTPUT +%typemap(argout) struct timeval *OUTPUT { - $target = rb_time_new($source->tv_sec, $source->tv_usec); + $result = rb_time_new($1->tv_sec, $1->tv_usec); } -%typemap(ruby,out) struct timeval * +%typemap(out) struct timeval * { - $target = rb_time_new($source->tv_sec, $source->tv_usec); + $result = rb_time_new($1->tv_sec, $1->tv_usec); } -%typemap(ruby,out) struct timespec * +%typemap(out) struct timespec * { - $target = rb_time_new($source->tv_sec, $source->tv_nsec / 1000); + $result = rb_time_new($1->tv_sec, $1->tv_nsec / 1000); } // time_t -%typemap(ruby,in) time_t +%typemap(in) time_t { - if (NIL_P($source)) - $target = (time_t)-1; + if (NIL_P($input)) + $1 = (time_t)-1; else - $target = NUM2LONG(rb_funcall($source, rb_intern("tv_sec"), 0)); + $1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0)); } -%typemap(ruby,out) time_t +%typemap(out) time_t { - $target = rb_time_new($source, 0); + $result = rb_time_new($1, 0); } // argc and argv -%typemap(ruby,ignore) int PROG_ARGC { - $target = RARRAY(rb_argv)->len + 1; +%typemap(in,numinputs=0) int PROG_ARGC { + $1 = RARRAY(rb_argv)->len + 1; } -%typemap(ruby,ignore) char **PROG_ARGV { +%typemap(in,numinputs=0) char **PROG_ARGV { int i, n; VALUE ary = rb_eval_string("[$0] + ARGV"); n = RARRAY(ary)->len; - $target = (char **)malloc(n + 1); + $1 = (char **)malloc(n + 1); for (i = 0; i < n; i++) { VALUE v = rb_obj_as_string(RARRAY(ary)->ptr[i]); - $target[i] = (char *)malloc(RSTRING(v)->len + 1); - strcpy($target[i], RSTRING(v)->ptr); + $1[i] = (char *)malloc(RSTRING(v)->len + 1); + strcpy($1[i], RSTRING(v)->ptr); } } -%typemap(ruby,freearg) char **PROG_ARGV { +%typemap(freearg) char **PROG_ARGV { int i, n = RARRAY(rb_argv)->len + 1; - for (i = 0; i < n; i++) free($source[i]); - free($source); + for (i = 0; i < n; i++) free($1[i]); + free($1); } // FILE * @@ -480,25 +370,49 @@ extern "C" { } #endif %} -%typemap(ruby,in) FILE *READ { + +%typemap(in) FILE *READ { OpenFile *of; - Check_Type($source, T_FILE); - GetOpenFile($source, of); + GetOpenFile($input, of); rb_io_check_readable(of); - $target = GetReadFile(of); - rb_read_check($target); + $1 = GetReadFile(of); + rb_read_check($1); } -%typemap(ruby,in) FILE *READ_NOCHECK { + +%typemap(in) FILE *READ_NOCHECK { OpenFile *of; - Check_Type($source, T_FILE); - GetOpenFile($source, of); + GetOpenFile($input, of); rb_io_check_readable(of); - $target = GetReadFile(of); + $1 = GetReadFile(of); } -%typemap(ruby,in) FILE *WRITE { + +%typemap(in) FILE *WRITE { OpenFile *of; - Check_Type($source, T_FILE); - GetOpenFile($source, of); + GetOpenFile($input, of); rb_io_check_writable(of); - $target = GetWriteFile(of); + $1 = GetWriteFile(of); } + +/* Overloading information */ + +%typemap(typecheck) double *INOUT = double; +%typemap(typecheck) signed char *INOUT = signed char; +%typemap(typecheck) unsigned char *INOUT = unsigned char; +%typemap(typecheck) unsigned long *INOUT = unsigned long; +%typemap(typecheck) unsigned short *INOUT = unsigned short; +%typemap(typecheck) unsigned int *INOUT = unsigned int; +%typemap(typecheck) long *INOUT = long; +%typemap(typecheck) short *INOUT = short; +%typemap(typecheck) int *INOUT = int; +%typemap(typecheck) float *INOUT = float; + +%typemap(typecheck) double &INOUT = double; +%typemap(typecheck) signed char &INOUT = signed char; +%typemap(typecheck) unsigned char &INOUT = unsigned char; +%typemap(typecheck) unsigned long &INOUT = unsigned long; +%typemap(typecheck) unsigned short &INOUT = unsigned short; +%typemap(typecheck) unsigned int &INOUT = unsigned int; +%typemap(typecheck) long &INOUT = long; +%typemap(typecheck) short &INOUT = short; +%typemap(typecheck) int &INOUT = int; +%typemap(typecheck) float &INOUT = float; diff --git a/Lib/std_deque.i b/Lib/std_deque.i new file mode 100644 index 000000000..c580c72d6 --- /dev/null +++ b/Lib/std_deque.i @@ -0,0 +1,5 @@ +/* Default std_deque wrapper */ +%module std_deque + +/* Include implementation specific code */ +%include "_std_deque.i" diff --git a/Lib/stdlib.i b/Lib/stdlib.i deleted file mode 100644 index 41137060a..000000000 --- a/Lib/stdlib.i +++ /dev/null @@ -1,43 +0,0 @@ -// -// $Header$ -// -// stdlib.i -// Dave Beazley -// March 24, 1996 -// SWIG file for some C stdlib functions -// -/* Revision history - * $Log$ - * Revision 1.1 2000/01/11 21:15:49 beazley - * Added files - * - * Revision 1.1.1.1 1999/02/28 02:00:53 beazley - * Swig1.1 - * - * Revision 1.1 1996/05/22 17:27:01 beazley - * Initial revision - * - */ - -%module stdlib -%{ -#include -%} - -typedef unsigned int size_t; - -double atof(const char *s); -int atoi(const char *s); -long atol(const char *s); -int rand(); -void srand(unsigned int seed); -void *calloc(size_t nobj, size_t size); -void *malloc(size_t size); -void *realloc(void *ptr, size_t size); -void free(void *ptr); -void abort(void); -int system(const char *s); -char *getenv(const char *name); -int abs(int n); -long labs(long n); - diff --git a/Lib/swig.swg b/Lib/swig.swg index 269abdd70..3c7ed71ea 100644 --- a/Lib/swig.swg +++ b/Lib/swig.swg @@ -1,32 +1,293 @@ /* ----------------------------------------------------------------------------- * swig.swg * - * Common macro definitions and other definitions used by the SWIG parser. + * $Header$ + * + * Common macro definitions for various SWIG directives. This file is always + * included at the top of each input file. * ----------------------------------------------------------------------------- */ -#define %init %insert("init") -#define %wrapper %insert("wrapper") -#define %runtime %insert("runtime") -#define %shadow %insert("shadow") +/* Deprecated SWIG directives */ -#define %readonly %scope("readonly") +#define %disabledoc %warn "104:%disabledoc is deprecated" +#define %enabledoc %warn "105:%enabledoc is deprecated" +#define %doconly %warn "106:%doconly is deprecated" +#define %style %warn "107:%style is deprecated" /##/ +#define %localstyle %warn "108:%localstyle is deprecated" /##/ +#define %title %warn "109:%title is deprecated" /##/ +#define %section %warn "110:%section is deprecated" /##/ +#define %subsection %warn "111:%subsection is deprecated" /##/ +#define %subsubsection %warn "112:%subsubsection is deprecated" /##/ +#define %new %warn "117:%new is deprecated. Use %newobject" +#define %text %insert("null") -#define %new %pragma "new"; -#define %name(x) %pragma "name" `x`; -#define %disabledoc %pragma "disabledoc"; -#define %enabledoc %pragma "enabledoc"; -#define %doconly %pragma "doconly"; +/* Code insertion directives such as %wrapper %{ ... %} */ -#define %alpha %echo "$file.$line. %alpha directive is obsolete" -#define %raw %echo "$file:$line. %raw directive is obsolete" +#define %init %insert("init") +#define %wrapper %insert("wrapper") +#define %header %insert("header") +#define %runtime %insert("runtime") -#define %title /##/ -#define %localstyle /##/ -#define %style /##/ -#define %section /##/ -#define %subsection /##/ -#define %subsubsection /##/ +/* Class extension */ + +#define %addmethods %warn "113:%addmethods is now %extend" %extend + +/* Access control directives */ + +#define %readonly %warn "114:%readonly is deprecated. Use %immutable; " %feature("immutable"); +#define %readwrite %warn "115:%readwrite is deprecated. Use %mutable; " %feature("immutable",""); + +#define %immutable %feature("immutable") +#define %mutable %feature("immutable","") + +/* Directives for callback functions */ + +/* Experimental */ + +#define %callback(x) %feature("callback") `x`; +#define %nocallback %feature("callback",""); + +/* Directives for attribute functions */ + +#define %attributefunc(_x,_y) %pragma(swig) attributefunction=`_x`":"`_y`; +#define %noattributefunc %pragma(swig) noattributefunction; + +/* %ignore directive */ + +#define %ignore %rename($ignore) +#define %ignorewarn(x) %rename("$ignore:" x) + +/* Generation of default constructors/destructors */ + +#define %nodefault %feature("nodefault") +#define %makedefault %feature("nodefault","") + +/* Common features */ + +#define %exception %feature("except") +#define %noexception %feature("except","") +#define %newobject %feature("new") + +/* Warnings */ +#define %warnfilter(...) %feature("warnfilter",`__VA_ARGS__`) + +/* Default handling of certain overloaded operators */ + +#ifdef __cplusplus +%ignorewarn("350:operator new ignored") operator new; +%ignorewarn("351:operator delete ignored") operator delete; +%ignorewarn("394:operator new[] ignored") operator new[]; +%ignorewarn("395:operator delete[] ignored") operator delete[]; + +/* Smart pointer handling */ +%rename(__deref__) operator->; + +/* Define std namespace */ +namespace std { +} +#endif + +/* Set up the typemap for handling new return strings */ + +#ifdef __cplusplus +%typemap(newfree) char * "delete [] $1;"; +#else +%typemap(newfree) char * "free($1);"; +#endif + +/* Default typemap for handling char * members */ + +#ifdef __cplusplus +%typemap(memberin) char * { + if ($1) delete [] $1; + $1 = ($1_type) (new char[strlen($input)+1]); + strcpy((char *) $1,$input); +} +%typemap(memberin,warning="451:Setting const char * member may leak memory.") const char * { + $1 = ($1_type) (new char[strlen($input)+1]); + strcpy((char *) $1,$input); +} +%typemap(globalin) char * { + if ($1) delete [] $1; + $1 = ($1_type) (new char[strlen($input)+1]); + strcpy((char *) $1,$input); +} +%typemap(globalin,warning="451:Setting const char * variable may leak memory.") const char * { + $1 = ($1_type) (new char[strlen($input)+1]); + strcpy((char *) $1,$input); +} +#else +%typemap(memberin) char * { + if ($1) free((char*)$1); + $1 = ($1_type) malloc(strlen($input)+1); + strcpy((char*)$1,$input); +} +%typemap(memberin,warning="451:Setting const char * member may leak memory.") const char * { + $1 = ($1_type) malloc(strlen($input)+1); + strcpy((char*)$1,$input); +} +%typemap(globalin) char * { + if ($1) free((char*)$1); + $1 = ($1_type) malloc(strlen($input)+1); + strcpy((char*)$1,$input); +} +%typemap(globalin,warning="451:Setting const char * variable may leak memory.") const char * { + $1 = ($1_type) malloc(strlen($input)+1); + strcpy((char*)$1,$input); +} + +#endif + +/* Character array handling */ + +%typemap(memberin) char [ANY] { + if ($input) strncpy($1,$input,$1_dim0); + else $1[0] = 0; +} + +%typemap(globalin) char [ANY] { + if ($input) strncpy($1,$input,$1_dim0); + else $1[0] = 0; +} + +/* memberin typemap for arrays. */ + +%typemap(memberin) SWIGTYPE [] { + int ii; + $1_basetype *b = ($1_basetype *) $1; + for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) $input + ii); +} + +%typemap(globalin) SWIGTYPE [] { + int ii; + $1_basetype *b = ($1_basetype *) $1; + for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) $input + ii); +} + +/* Typemap for variable length arguments sentinel value. Used + by the %varargs directive. */ + +%typemap(in,numinputs=0) SWIGTYPE *VARARGS_SENTINEL, SWIGTYPE VARARGS_SENTINEL ""; + + +/* + * Function/method overloading support. This is done through typemaps, + * but also involve a precedence level. + */ + +/* Macro for overload resolution */ + +#define %typecheck(_x) %typemap(typecheck, precedence=_x) + +/* Macros for precedence levels */ + +%define SWIG_TYPECHECK_POINTER 0 %enddef +%define SWIG_TYPECHECK_VOIDPTR 10 %enddef +%define SWIG_TYPECHECK_BOOL 15 %enddef +%define SWIG_TYPECHECK_UINT8 20 %enddef +%define SWIG_TYPECHECK_INT8 25 %enddef +%define SWIG_TYPECHECK_UINT16 30 %enddef +%define SWIG_TYPECHECK_INT16 35 %enddef +%define SWIG_TYPECHECK_UINT32 40 %enddef +%define SWIG_TYPECHECK_INT32 45 %enddef +%define SWIG_TYPECHECK_UINT64 50 %enddef +%define SWIG_TYPECHECK_INT64 55 %enddef +%define SWIG_TYPECHECK_UINT128 60 %enddef +%define SWIG_TYPECHECK_INT128 65 %enddef +%define SWIG_TYPECHECK_INTEGER 70 %enddef +%define SWIG_TYPECHECK_FLOAT 80 %enddef +%define SWIG_TYPECHECK_DOUBLE 90 %enddef +%define SWIG_TYPECHECK_COMPLEX 100 %enddef +%define SWIG_TYPECHECK_UNICHAR 110 %enddef +%define SWIG_TYPECHECK_UNISTRING 120 %enddef +%define SWIG_TYPECHECK_CHAR 130 %enddef +%define SWIG_TYPECHECK_STRING 140 %enddef +%define SWIG_TYPECHECK_VECTOR 150 %enddef + +%define SWIG_TYPECHECK_BOOL_ARRAY 1015 %enddef +%define SWIG_TYPECHECK_INT8_ARRAY 1025 %enddef +%define SWIG_TYPECHECK_INT16_ARRAY 1035 %enddef +%define SWIG_TYPECHECK_INT32_ARRAY 1045 %enddef +%define SWIG_TYPECHECK_INT64_ARRAY 1055 %enddef +%define SWIG_TYPECHECK_INT128_ARRAY 1065 %enddef +%define SWIG_TYPECHECK_FLOAT_ARRAY 1080 %enddef +%define SWIG_TYPECHECK_DOUBLE_ARRAY 1090 %enddef +%define SWIG_TYPECHECK_CHAR_ARRAY 1130 %enddef +%define SWIG_TYPECHECK_STRING_ARRAY 1140 %enddef + +/* + * This template wrapper is used to handle C++ objects that are passed or + * returned by value. This is necessary to handle objects that define + * no default-constructor (making it difficult for SWIG to properly declare + * local variables). + * + * The wrapper is used as follows. First consider a function like this: + * + * Vector cross_product(Vector a, Vector b) + * + * Now, if Vector is defined as a C++ class with no default constructor, + * code is generated as follows: + * + * Vector *wrap_cross_product(Vector *inarg1, Vector *inarg2) { + * SwigValueWrapper arg1; + * SwigValueWrapper arg2; + * SwigValueWrapper result; + * + * arg1 = *inarg1; + * arg2 = *inarg2; + * ... + * result = cross_product(arg1,arg2); + * ... + * return new Vector(result); + * } + * + * In the wrappers, the template SwigValueWrapper simply provides a thin + * layer around a Vector *. However, it does this in a way that allows + * the object to be bound after the variable declaration (which is not possible + * with the bare object when it lacks a default constructor). + * + * An observant reader will notice that the code after the variable declarations + * is *identical* to the code used for classes that do define default constructors. + * Thus, this neat trick allows us to fix this special case without having to + * make massive changes to typemaps and other parts of the SWIG code generator. + * + * Note: this code is not included when SWIG runs in C-mode, when classes + * define default constructors, or when pointers and references are used. + * SWIG tries to avoid doing this except in very special circumstances. + * + * Note: This solution suffers from making a large number of copies + * of the underlying object. However, this is needed in the interest of + * safety and in order to cover all of the possible ways in which a value + * might be assigned. For example: + * + * arg1 = *inarg1; // Assignment from a pointer + * arg1 = Vector(1,2,3); // Assignment from a value + * + * This wrapping technique was suggested by William Fulton and is henceforth + * known as the "Fulton Transform" :-). + */ + +#ifdef __cplusplus +%insert("runtime") %{ +#ifdef __cplusplus +template class SwigValueWrapper { + T *tt; +public: + inline SwigValueWrapper() : tt(0) { } + inline ~SwigValueWrapper() { if (tt) delete tt; } + inline SwigValueWrapper& operator=(const T& t) { tt = new T(t); return *this; } + inline operator T&() const { return *tt; } + inline T *operator&() { return tt; } +}; +#endif +%} +#endif + +/* Macro for setting a dynamic cast function */ +%define DYNAMIC_CAST(mangle,func) +%init %{ + mangle->dcast = (swig_dycast_func) func; +%} +%enddef -#define %text %insert("doc") -#define %native %scope("native") diff --git a/Lib/tcl/Makefile.in b/Lib/tcl/Makefile.in index 3ba07d4a3..0ed59f274 100644 --- a/Lib/tcl/Makefile.in +++ b/Lib/tcl/Makefile.in @@ -37,7 +37,7 @@ CC = @CC@ CXX = @CXX@ OBJC = @CC@ -Wno-import # -Wno-import needed for gcc CFLAGS = -INCLUDE = +INCLUDES = LIBS = # SWIG Options @@ -100,13 +100,13 @@ BUILD_LIBS = $(LIBS) # Dynamic loading .SUFFIXES: .c .cxx .m .c.o: - $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< .cxx.o: - $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDES) -c $< .m.o: - $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< # ---------------------------------------------------------------------- @@ -118,7 +118,7 @@ all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) - $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDE) $(TCL_INCLUDE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(TCL_INCLUDE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) diff --git a/Lib/tcl/constarray.i b/Lib/tcl/constarray.i deleted file mode 100644 index d9a4dc290..000000000 --- a/Lib/tcl/constarray.i +++ /dev/null @@ -1,108 +0,0 @@ -// constarray.i -// -// This module changes SWIG to place constant values into a Tcl array - - -#ifdef AUTODOC -%subsection "Array Constants",pre -%text %{ -%include constarray.i - -This module changes SWIG so that constant values are placed into a Tcl -array instead of global variables. The array is given the same name as -the SWIG module (specified with the %module directive). - -This module should generally be included at the top of an interface -file before any declarations appear. Furthermore, this module changes -the default handling of basic datatypes including integers, floats, -and character strings. - -When this module is used, constants are simply accessed through the -module name. For example : - - %module example - ... - #define FOO 42 - -would be accessed as '$example(FOO)' - -Note : This module replaces the existing mechanism for creating constants. -The method used by this module is based on a set of typemaps supplied -by Tim Medley. -%} -#endif - -%typemap(tcl,const) int SWIG_DEFAULT_TYPE, - unsigned int SWIG_DEFAULT_TYPE, - long SWIG_DEFAULT_TYPE, - unsigned long SWIG_DEFAULT_TYPE, - short SWIG_DEFAULT_TYPE, - unsigned short SWIG_DEFAULT_TYPE, - unsigned char SWIG_DEFAULT_TYPE, - signed char SWIG_DEFAULT_TYPE -{ - static int ivalue = (int) $source; - Tcl_LinkVar(interp,SWIG_name "($target)",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); -} - -%typemap(tcl,const) float SWIG_DEFAULT_TYPE, - double SWIG_DEFAULT_TYPE -{ - static double dvalue = (double) $source; - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); -} - -%typemap(tcl,const) char *SWIG_DEFAULT_TYPE -{ - static char *cvalue = $source; - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); -} - -%typemap(tcl,const) Pointer *SWIG_DEFAULT_TYPE -{ - static char *pvalue; - pvalue = (char *) malloc(20+strlen("$mangle")); - SWIG_MakePtr(pvalue, (void *) ($source), "$mangle"); - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &pvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); -} - -// ---------------------------------------------------------------------------------- -// Tcl 8 Object versions -// ---------------------------------------------------------------------------------- - -%typemap(tcl8,const) int SWIG_DEFAULT_TYPE, - unsigned int SWIG_DEFAULT_TYPE, - long SWIG_DEFAULT_TYPE, - unsigned long SWIG_DEFAULT_TYPE, - short SWIG_DEFAULT_TYPE, - unsigned short SWIG_DEFAULT_TYPE, - unsigned char SWIG_DEFAULT_TYPE, - signed char SWIG_DEFAULT_TYPE -{ - static int ivalue = (int) $source; - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); -} - -%typemap(tcl8,const) float SWIG_DEFAULT_TYPE, - double SWIG_DEFAULT_TYPE -{ - static double dvalue = (double) $source; - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); -} - -%typemap(tcl8,const) char *SWIG_DEFAULT_TYPE -{ - static char *cvalue = $source; - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); -} - -%typemap(tcl8,const) Pointer *SWIG_DEFAULT_TYPE -{ - static char *pvalue; - pvalue = (char *) malloc(20+strlen("$mangle")); - SWIG_MakePtr(pvalue, (void *) ($source), "$mangle"); - Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &pvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); -} - - - diff --git a/Lib/tcl/consthash.i b/Lib/tcl/consthash.i deleted file mode 100644 index e90f96564..000000000 --- a/Lib/tcl/consthash.i +++ /dev/null @@ -1,223 +0,0 @@ -// consthash.i -// -// This module changes SWIG to place constant values into a Tcl -// hash table. - - -#ifdef AUTODOC -%subsection "Hash Constants",pre -%text %{ -%include consthash.i - -This module changes SWIG so that constant values are placed into a Tcl -hash table in addition to normal Tcl variables. When working with systems -involving large numbers of constants, the use of a hash table -simplifies use because it is no longer necessary to declare constants -using the 'global' statement. - -This module should generally be included at the top of an interface -file before any declarations appear. Furthermore, this module changes -the default handling of basic datatypes including integers, floats, -and character strings. - -When this module is used, constants are simply accessed by name -without the associated dollar sign. For example : - - #define FOO 42 - -would be accessed as 'FOO' in Tcl, not '$FOO'. - -Note : This module only affects integer, float, and character -constants. Pointer constants are not currently affected. This module -should not break existing Tcl scripts that rely on the normal SWIG -constant mechanism. -%} -#endif - -%{ -static Tcl_HashTable intHash, doubleHash, charHash; -static Tcl_HashEntry *entryPtr; -static int init_dummy; -%} - -%init %{ - Tcl_InitHashTable(&intHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&doubleHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&charHash, TCL_STRING_KEYS); -%} - -%typemap(tcl,const) int SWIG_DEFAULT_TYPE, - unsigned int SWIG_DEFAULT_TYPE, - long SWIG_DEFAULT_TYPE, - unsigned long SWIG_DEFAULT_TYPE, - short SWIG_DEFAULT_TYPE, - unsigned short SWIG_DEFAULT_TYPE, - unsigned char SWIG_DEFAULT_TYPE, - signed char SWIG_DEFAULT_TYPE -{ - static int ivalue = (int) $source; - entryPtr = Tcl_CreateHashEntry(&intHash, "$target", &init_dummy); - Tcl_SetHashValue(entryPtr, &ivalue); - Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); -} - -%typemap(tcl,const) float SWIG_DEFAULT_TYPE, - double SWIG_DEFAULT_TYPE -{ - static double dvalue = (double) $source; - entryPtr = Tcl_CreateHashEntry(&doubleHash, "$target", &init_dummy); - Tcl_SetHashValue(entryPtr, &dvalue); - Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); -} - -%typemap(tcl,const) char *SWIG_DEFAULT_TYPE -{ - static char *cvalue = $source; - entryPtr = Tcl_CreateHashEntry(&charHash, "$target", &init_dummy); - Tcl_SetHashValue(entryPtr, &cvalue); - Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); -} - -// Change input handling to look for names - -%typemap(tcl,in) int SWIG_DEFAULT_TYPE, - unsigned int SWIG_DEFAULT_TYPE, - long SWIG_DEFAULT_TYPE, - unsigned long SWIG_DEFAULT_TYPE, - short SWIG_DEFAULT_TYPE, - unsigned short SWIG_DEFAULT_TYPE, - unsigned char SWIG_DEFAULT_TYPE, - signed char SWIG_DEFAULT_TYPE -{ - Tcl_HashEntry *entry; - entry = Tcl_FindHashEntry(&intHash,$source); - if (entry) { - $target = ($type) (*((int *) Tcl_GetHashValue(entry))); - } else { - int temp; - if (Tcl_GetInt(interp, $source, &temp) == TCL_ERROR) return TCL_ERROR; - $target = ($type) temp; - } -} - -%typemap(tcl,in) float SWIG_DEFAULT_TYPE, - double SWIG_DEFAULT_TYPE -{ - Tcl_HashEntry *entry; - entry = Tcl_FindHashEntry(&doubleHash,$source); - if (entry) { - $target = ($type) (*((double *) Tcl_GetHashValue(entry))); - } else if (entry = Tcl_FindHashEntry(&intHash,$source)) { - $target = ($type) (*((int *) Tcl_GetHashValue(entry))); - } else { - double temp; - if (Tcl_GetDouble(interp,$source,&temp) == TCL_ERROR) return TCL_ERROR; - $target = ($type) temp; - } -} - -%typemap(tcl,in) char *SWIG_DEFAULT_TYPE -{ - Tcl_HashEntry *entry; - entry = Tcl_FindHashEntry(&charHash,$source); - if (entry) { - $target = ($type) (*((char **) Tcl_GetHashValue(entry))); - } else { - $target = $source; - } -} - -// ---------------------------------------------------------------------------------- -// Tcl 8 Object versions -// ---------------------------------------------------------------------------------- - -%typemap(tcl8,const) int SWIG_DEFAULT_TYPE, - unsigned int SWIG_DEFAULT_TYPE, - long SWIG_DEFAULT_TYPE, - unsigned long SWIG_DEFAULT_TYPE, - short SWIG_DEFAULT_TYPE, - unsigned short SWIG_DEFAULT_TYPE, - unsigned char SWIG_DEFAULT_TYPE, - signed char SWIG_DEFAULT_TYPE -{ - static int ivalue = (int) $source; - entryPtr = Tcl_CreateHashEntry(&intHash, "$target", &init_dummy); - Tcl_SetHashValue(entryPtr, &ivalue); - Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); -} - -%typemap(tcl8,const) float SWIG_DEFAULT_TYPE, - double SWIG_DEFAULT_TYPE -{ - static double dvalue = (double) $source; - entryPtr = Tcl_CreateHashEntry(&doubleHash, "$target", &init_dummy); - Tcl_SetHashValue(entryPtr, &dvalue); - Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); -} - -%typemap(tcl8,const) char *SWIG_DEFAULT_TYPE -{ - static char *cvalue = $source; - entryPtr = Tcl_CreateHashEntry(&charHash, "$target", &init_dummy); - Tcl_SetHashValue(entryPtr, &cvalue); - Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); -} - -// Change input handling to look for names - -%typemap(tcl8,in) int SWIG_DEFAULT_TYPE, - unsigned int SWIG_DEFAULT_TYPE, - long SWIG_DEFAULT_TYPE, - unsigned long SWIG_DEFAULT_TYPE, - short SWIG_DEFAULT_TYPE, - unsigned short SWIG_DEFAULT_TYPE, - unsigned char SWIG_DEFAULT_TYPE, - signed char SWIG_DEFAULT_TYPE -{ - Tcl_HashEntry *entry; - int _len; - char *_str = Tcl_GetStringFromObj($source,&_len); - entry = Tcl_FindHashEntry(&intHash,_str); - if (entry) { - $target = ($type) (*((int *) Tcl_GetHashValue(entry))); - } else { - int temp; - if (Tcl_GetIntFromObj(interp, $source, &temp) == TCL_ERROR) return TCL_ERROR; - $target = ($type) temp; - } -} - -%typemap(tcl8,in) float SWIG_DEFAULT_TYPE, - double SWIG_DEFAULT_TYPE -{ - Tcl_HashEntry *entry; - int _len; - char *_str = Tcl_GetStringFromObj($source,&_len); - entry = Tcl_FindHashEntry(&doubleHash,_str); - if (entry) { - $target = ($type) (*((double *) Tcl_GetHashValue(entry))); - } else if (entry = Tcl_FindHashEntry(&intHash,_str)) { - $target = ($type) (*((int *) Tcl_GetHashValue(entry))); - } else { - double temp; - if (Tcl_GetDoubleFromObj(interp,$source,&temp) == TCL_ERROR) return TCL_ERROR; - $target = ($type) temp; - } -} - -%typemap(tcl8,in) char *SWIG_DEFAULT_TYPE -{ - Tcl_HashEntry *entry; - int _len; - char *_str = Tcl_GetStringFromObj($source,&_len); - entry = Tcl_FindHashEntry(&charHash,_str); - if (entry) { - $target = ($type) (*((char **) Tcl_GetHashValue(entry))); - } else { - $target = _str; - } -} - - - - diff --git a/Lib/tcl/cstring.i b/Lib/tcl/cstring.i new file mode 100644 index 000000000..a411d5bab --- /dev/null +++ b/Lib/tcl/cstring.i @@ -0,0 +1,290 @@ +/* + * cstring.i + * $Header$ + * + * Author(s): David Beazley (beazley@cs.uchicago.edu) + * + * This file provides typemaps and macros for dealing with various forms + * of C character string handling. The primary use of this module + * is in returning character data that has been allocated or changed in + * some way. + */ + +/* %cstring_input_binary(TYPEMAP, SIZE) + * + * Macro makes a function accept binary string data along with + * a size. + */ + +%define %cstring_input_binary(TYPEMAP, SIZE) +%apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; +%enddef + +/* + * %cstring_bounded_output(TYPEMAP, MAX) + * + * This macro is used to return a NULL-terminated output string of + * some maximum length. For example: + * + * %cstring_bounded_output(char *outx, 512); + * void foo(char *outx) { + * sprintf(outx,"blah blah\n"); + * } + * + */ + +%define %cstring_bounded_output(TYPEMAP,MAX) +%typemap(ignore) TYPEMAP(char temp[MAX+1]) { + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + Tcl_Obj *o; + $1[MAX] = 0; + o = Tcl_NewStringObj($1,-1); + Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp), o); +} +%enddef + +/* + * %cstring_chunk_output(TYPEMAP, SIZE) + * + * This macro is used to return a chunk of binary string data. + * Embedded NULLs are okay. For example: + * + * %cstring_chunk_output(char *outx, 512); + * void foo(char *outx) { + * memmove(outx, somedata, 512); + * } + * + */ + +%define %cstring_chunk_output(TYPEMAP,SIZE) +%typemap(ignore) TYPEMAP(char temp[SIZE]) { + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + Tcl_Obj *o = Tcl_NewStringObj($1,SIZE); + Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),o); +} +%enddef + +/* + * %cstring_bounded_mutable(TYPEMAP, SIZE) + * + * This macro is used to wrap a string that's going to mutate. + * + * %cstring_bounded_mutable(char *in, 512); + * void foo(in *x) { + * while (*x) { + * *x = toupper(*x); + * x++; + * } + * } + * + */ + + +%define %cstring_bounded_mutable(TYPEMAP,MAX) +%typemap(in) TYPEMAP(char temp[MAX+1]) { + char *t = Tcl_GetStringFromObj($input,NULL); + strncpy(temp,t,MAX); + $1 = ($1_ltype) temp; +} +%typemap(argout,fragment="t_output_helper") TYPEMAP { + Tcl_Obj *o; + $1[MAX] = 0; + o = Tcl_NewStringObj($1,-1); + Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),o); +} +%enddef + +/* + * %cstring_mutable(TYPEMAP [, expansion]) + * + * This macro is used to wrap a string that will mutate in place. + * It may change size up to a user-defined expansion. + * + * %cstring_mutable(char *in); + * void foo(in *x) { + * while (*x) { + * *x = toupper(*x); + * x++; + * } + * } + * + */ + +%define %cstring_mutable(TYPEMAP,...) +%typemap(in) TYPEMAP { + int n; + char *t = Tcl_GetStringFromObj($input,&n); + $1 = ($1_ltype) t; + +#if #__VA_ARGS__ == "" +#if __cplusplus + $1 = ($1_ltype) new char[n+1]; +#else + $1 = ($1_ltype) malloc(n+1); +#endif +#else +#if __cplusplus + $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; +#else + $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); +#endif +#endif + memmove($1,t,n); + $1[n] = 0; +} + +%typemap(argout,fragment="t_output_helper") TYPEMAP { + Tcl_Obj *o; + o = Tcl_NewStringObj($1,-1); + Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), o); +#if __cplusplus + delete[] $1; +#else + free($1); +#endif +} +%enddef + +/* + * %cstring_output_maxsize(TYPEMAP, SIZE) + * + * This macro returns data in a string of some user-defined size. + * + * %cstring_output_maxsize(char *outx, int max) { + * void foo(char *outx, int max) { + * sprintf(outx,"blah blah\n"); + * } + */ + +%define %cstring_output_maxsize(TYPEMAP, SIZE) +%typemap(in) (TYPEMAP, SIZE) { + long temp; + if (Tcl_GetLongFromObj(interp,$input,&temp) != TCL_OK) { + SWIG_fail; + } + $2 = ($2_ltype) temp; +#ifdef __cpluscplus + $1 = ($1_ltype) new char[$2+1]; +#else + $1 = ($1_ltype) malloc($2+1); +#endif +} +%typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { + Tcl_Obj *o; + o = Tcl_NewStringObj($1,-1); + Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); +#ifdef __cplusplus + delete [] $1; +#else + free($1); +#endif +} +%enddef + +/* + * %cstring_output_withsize(TYPEMAP, SIZE) + * + * This macro is used to return character data along with a size + * parameter. + * + * %cstring_output_maxsize(char *outx, int *max) { + * void foo(char *outx, int *max) { + * sprintf(outx,"blah blah\n"); + * *max = strlen(outx); + * } + */ + +%define %cstring_output_withsize(TYPEMAP, SIZE) +%typemap(in) (TYPEMAP, SIZE) { + long n; + if (Tcl_GetLongFromObj(interp,$input,&n) != TCL_OK) { + SWIG_fail; + } +#ifdef __cpluscplus + $1 = ($1_ltype) new char[n+1]; + $2 = ($2_ltype) new $*1_ltype; +#else + $1 = ($1_ltype) malloc(n+1); + $2 = ($2_ltype) malloc(sizeof($*1_ltype)); +#endif + *$2 = n; +} +%typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { + Tcl_Obj *o; + o = Tcl_NewStringObj($1,*$2); + Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp), o); +#ifdef __cplusplus + delete [] $1; + delete $2; +#else + free($1); + free($2); +#endif +} +%enddef + +/* + * %cstring_output_allocate(TYPEMAP, RELEASE) + * + * This macro is used to return character data that was + * allocated with new or malloc. + * + * %cstring_output_allocated(char **outx, free($1)); + * void foo(char **outx) { + * *outx = (char *) malloc(512); + * sprintf(outx,"blah blah\n"); + * } + */ + +%define %cstring_output_allocate(TYPEMAP, RELEASE) +%typemap(ignore) TYPEMAP($*1_ltype temp = 0) { + $1 = &temp; +} + +%typemap(argout,fragment="t_output_helper") TYPEMAP { + if (*$1) { + Tcl_Obj *o = Tcl_NewStringObj(*$1,-1); + RELEASE; + Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), o); + } +} +%enddef + +/* + * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) + * + * This macro is used to return character data that was + * allocated with new or malloc. + * + * %cstring_output_allocated(char **outx, int *sz, free($1)); + * void foo(char **outx, int *sz) { + * *outx = (char *) malloc(512); + * sprintf(outx,"blah blah\n"); + * *sz = strlen(outx); + * } + */ + +%define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) +%typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { + $1 = &temp; + $2 = &tempn; +} + +%typemap(argout,fragment="t_output_helper")(TYPEMAP,SIZE) { + if (*$1) { + Tcl_Obj *o = Tcl_NewStringObj(*$1,*$2); + RELEASE; + Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp), o); + } +} +%enddef + + + + + + diff --git a/Lib/tcl/object.swg b/Lib/tcl/object.swg deleted file mode 100644 index 7e806c65d..000000000 --- a/Lib/tcl/object.swg +++ /dev/null @@ -1,229 +0,0 @@ -/* object.swg - * - * Tcl8.x - Object oriented runtime functions - */ - -typedef int (*swig_wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); - -typedef struct swig_method { - const char *name; - swig_wrapper method; -} swig_method; - -typedef struct swig_attribute { - const char *name; - swig_wrapper getmethod; - swig_wrapper setmethod; -} swig_attribute; - -typedef struct swig_class { - const char *name; - swig_type_info **type; - swig_wrapper constructor; - void (*destructor)(void *); - swig_method *methods; - swig_attribute *attributes; -} swig_class; - -typedef struct swig_instance { - Tcl_Obj *thisptr; - void *thisvalue; - swig_class *classptr; - int destroy; -} swig_instance; - -static void SwigObjectDelete(ClientData clientData) { - swig_instance *si = (swig_instance *) clientData; - if (si->destroy) { - if (si->classptr->destructor) { - (si->classptr->destructor)(si->thisvalue); - } - } - Tcl_DecrRefCount(si->thisptr); - free(si); -} - -/* Function to invoke object methods given an instance */ -static int -SwigMethodCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST _objv[]) -{ - char *method, *attrname; - swig_instance *inst = (swig_instance *) clientData; - swig_method *meth; - swig_attribute *attr; - Tcl_Obj *oldarg; - Tcl_Obj **objv; - int rcode; - - objv = (Tcl_Obj **) _objv; - if (objc < 2) { - Tcl_SetResult(interp,"wrong # args.", TCL_STATIC); - return TCL_ERROR; - } - meth = inst->classptr->methods; - method = Tcl_GetStringFromObj(objv[1],NULL); - - /* Check for methods */ - while (meth && meth->name) { - if (strcmp(meth->name,method) == 0) { - oldarg = objv[1]; - objv[1] = inst->thisptr; - Tcl_IncrRefCount(inst->thisptr); - rcode = (*meth->method)(clientData,interp,objc,objv); - objv[1] = oldarg; - Tcl_DecrRefCount(inst->thisptr); - return rcode; - } - meth++; - } - /* Check class methods for a match */ - if (strcmp(method,"cget") == 0) { - if (objc < 3) { - Tcl_SetResult(interp,"wrong # args.", TCL_STATIC); - return TCL_ERROR; - } - attrname = Tcl_GetStringFromObj(objv[2],NULL); - attr = inst->classptr->attributes; - while (attr && attr->name) { - if ((strcmp(attr->name, attrname) == 0) && (attr->getmethod)) { - oldarg = objv[1]; - objv[1] = inst->thisptr; - Tcl_IncrRefCount(inst->thisptr); - rcode = (*attr->getmethod)(clientData,interp,2, objv); - objv[1] = oldarg; - Tcl_DecrRefCount(inst->thisptr); - return rcode; - } - attr++; - } - if (strcmp(attrname, "-this") == 0) { - Tcl_SetObjResult(interp, Tcl_DuplicateObj(inst->thisptr)); - return TCL_OK; - } - Tcl_SetResult(interp,"Invalid attribute.", TCL_STATIC); - return TCL_ERROR; - } else if (strcmp(method, "configure") == 0) { - int i; - if (objc < 4) { - Tcl_SetResult(interp,"wrong # args.", TCL_STATIC); - return TCL_ERROR; - } - i = 2; - while (i < objc) { - attrname = Tcl_GetStringFromObj(objv[i],NULL); - attr = inst->classptr->attributes; - while (attr && attr->name) { - if ((strcmp(attr->name, attrname) == 0) && (attr->setmethod)) { - oldarg = objv[i]; - objv[i] = inst->thisptr; - Tcl_IncrRefCount(inst->thisptr); - rcode = (*attr->setmethod)(clientData,interp,3, &objv[i-1]); - objv[i] = oldarg; - Tcl_DecrRefCount(inst->thisptr); - if (rcode != TCL_OK) return rcode; - i+=2; - break; - } - attr++; - } - if (inst->classptr->attributes && !(attr->name)) { - Tcl_SetResult(interp,"Invalid attribute name.", TCL_STATIC); - return TCL_ERROR; - } - } - return TCL_OK; - } else { - Tcl_SetResult(interp,"Invalid method. Must be one of: configure cget ", TCL_STATIC); - meth = inst->classptr->methods; - while (meth && meth->name) { - Tcl_AppendElement(interp, meth->name); - meth++; - } - return TCL_ERROR; - } - - -} - -/* Function to create objects */ -static int -SwigObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) -{ - Tcl_Obj *newObj = 0; - void *thisvalue = 0; - swig_instance *newinst = 0; - swig_class *classptr = (swig_class *) clientData; - swig_wrapper cons = 0; - char *name = 0; - int firstarg = 0; - int thisarg = 0; - int destroy = 1; - Tcl_CmdInfo ci; - - if (!classptr) { - Tcl_SetResult(interp,"swig: internal runtime error. No class object defined.", TCL_STATIC); - return TCL_ERROR; - } - cons = classptr->constructor; - if (objc > 1) { - char *s = Tcl_GetStringFromObj(objv[1],NULL); - if (strcmp(s,"-this") == 0) { - thisarg = 2; - cons = 0; - } else if (strcmp(s,"-args") == 0) { - firstarg = 1; - } else if (objc == 2) { - firstarg = 1; - name = s; - } else if (objc >= 3) { - char *s1; - name = s; - s1 = Tcl_GetStringFromObj(objv[2],NULL); - if (strcmp(s1,"-this") == 0) { - thisarg = 3; - cons = 0; - } else { - firstarg = 1; - } - } - } - if (cons) { - int result; - result = (*cons)(0, interp, objc-firstarg, &objv[firstarg]); - if (result != TCL_OK) { - return result; - } - newObj = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); - if (!name) name = Tcl_GetStringFromObj(newObj,NULL); - } else if (thisarg > 0) { - if (thisarg < objc) { - destroy = 0; - newObj = Tcl_DuplicateObj(objv[thisarg]); - if (!name) name = Tcl_GetStringFromObj(newObj,NULL); - } else { - Tcl_SetResult(interp,"wrong # args.", TCL_STATIC); - return TCL_ERROR; - } - } else { - Tcl_SetResult(interp,"No constructor available.", TCL_STATIC); - return TCL_ERROR; - } - if (!Tcl_GetCommandInfo(interp,name,&ci)) { - if (SWIG_ConvertPtr(interp,newObj, (void **) &thisvalue, *(classptr->type)) == TCL_ERROR) { - Tcl_DecrRefCount(newObj); - return TCL_ERROR; - } - newinst = (swig_instance *) malloc(sizeof(swig_instance)); - newinst->thisptr = newObj; - Tcl_IncrRefCount(newObj); - newinst->thisvalue = thisvalue; - newinst->classptr = classptr; - newinst->destroy = destroy; - Tcl_CreateObjCommand(interp,name, SwigMethodCmd, (ClientData) newinst, SwigObjectDelete); - return TCL_OK; - } else { - Tcl_SetResult(interp,"Object name already exists!", TCL_STATIC); - return TCL_ERROR; - } -} - diff --git a/Lib/tcl/ptrlang.i b/Lib/tcl/ptrlang.i deleted file mode 100644 index fbd1278c9..000000000 --- a/Lib/tcl/ptrlang.i +++ /dev/null @@ -1,490 +0,0 @@ -// -// SWIG pointer conversion and utility library -// -// Dave Beazley -// April 19, 1997 -// -// Tcl specific implementation. This file is included -// by the file ../pointer.i - - -%{ -#include - -/* Types used by the library */ -static swig_type_info *SWIG_POINTER_int_p = 0; -static swig_type_info *SWIG_POINTER_short_p =0; -static swig_type_info *SWIG_POINTER_long_p = 0; -static swig_type_info *SWIG_POINTER_float_p = 0; -static swig_type_info *SWIG_POINTER_double_p = 0; -static swig_type_info *SWIG_POINTER_char_p = 0; -static swig_type_info *SWIG_POINTER_char_pp = 0; -%} - -%init %{ - SWIG_POINTER_int_p = SWIG_TypeQuery("int *"); - SWIG_POINTER_short_p = SWIG_TypeQuery("short *"); - SWIG_POINTER_long_p = SWIG_TypeQuery("long *"); - SWIG_POINTER_float_p = SWIG_TypeQuery("float *"); - SWIG_POINTER_double_p = SWIG_TypeQuery("double *"); - SWIG_POINTER_char_p = SWIG_TypeQuery("char *"); - SWIG_POINTER_char_pp = SWIG_TypeQuery("char **"); -%} - -%{ - -/*------------------------------------------------------------------ - ptrvalue(ptr,type = 0) - - Attempts to dereference a pointer value. If type is given, it - will try to use that type. Otherwise, this function will attempt - to "guess" the proper datatype by checking against all of the - builtin C datatypes. - ------------------------------------------------------------------ */ - -static int ptrvalue(Tcl_Interp *interp, char *ptrvalue, int index, char *type) { - void *ptr; - char *s; - int error = 0; - - if (type) { - if (strlen(type) == 0) type = 0; - } - s = ptrvalue; - if (SWIG_ConvertPtrFromString(interp,s,&ptr,0) != TCL_OK) { - Tcl_SetResult(interp,"Type error in ptrvalue. Argument is not a valid pointer value.", TCL_STATIC); - return TCL_ERROR; - } - - /* If no datatype was passed, try a few common datatypes first */ - if (!type) { - /* No datatype was passed. Type to figure out if it's a common one */ - if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_int_p) == TCL_OK) { - type = "int"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_double_p) == TCL_OK) { - type = "double"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_short_p) == TCL_OK) { - type = "short"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_long_p) == TCL_OK) { - type = "long"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_float_p) == TCL_OK) { - type = "float"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_char_p) == TCL_OK) { - type = "char"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_char_pp) == TCL_OK) { - type = "char *"; - } else { - type = "unknown"; - } - } - - if (!ptr) { - Tcl_SetResult(interp,"Unable to dereference NULL pointer.",TCL_STATIC); - return TCL_ERROR; - } - - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - sprintf(interp->result,"%ld",(long) *(((int *) ptr) + index)); - } else if (strcmp(type,"double") == 0) { - Tcl_PrintDouble(interp,(double) *(((double *) ptr)+index), interp->result); - } else if (strcmp(type,"short") == 0) { - sprintf(interp->result,"%ld",(long) *(((short *) ptr) + index)); - } else if (strcmp(type,"long") == 0) { - sprintf(interp->result,"%ld",(long) *(((long *) ptr) + index)); - } else if (strcmp(type,"float") == 0) { - Tcl_PrintDouble(interp,(double) *(((float *) ptr)+index), interp->result); - } else if (strcmp(type,"char") == 0) { - Tcl_SetResult(interp,((char *) ptr) + index, TCL_VOLATILE); - } else if (strcmp(type,"char *") == 0) { - char *c = *(((char **) ptr)+index); - if (c) Tcl_SetResult(interp,(char *) c, TCL_VOLATILE); - else Tcl_SetResult(interp,"NULL", TCL_VOLATILE); - } else { - Tcl_SetResult(interp,"Unable to dereference unsupported datatype.",TCL_STATIC); - return TCL_ERROR; - } - return TCL_OK; -} - -/*------------------------------------------------------------------ - ptrcreate(type,value = 0,numelements = 1) - - Attempts to create a new object of given type. Type must be - a basic C datatype. Will not create complex objects. - ------------------------------------------------------------------ */ - -static int ptrcreate(Tcl_Interp *interp, char *type, char *ptrvalue, int numelements) { - void *ptr; - int sz; - swig_type_info *cast = 0; - char temp[40]; - - /* Check the type string against a variety of possibilities */ - - if (strcmp(type,"int") == 0) { - sz = sizeof(int)*numelements; - cast = SWIG_POINTER_int_p; - } else if (strcmp(type,"short") == 0) { - sz = sizeof(short)*numelements; - cast = SWIG_POINTER_short_p; - } else if (strcmp(type,"long") == 0) { - sz = sizeof(long)*numelements; - cast = SWIG_POINTER_long_p; - } else if (strcmp(type,"double") == 0) { - sz = sizeof(double)*numelements; - cast = SWIG_POINTER_double_p; - } else if (strcmp(type,"float") == 0) { - sz = sizeof(float)*numelements; - cast = SWIG_POINTER_float_p; - } else if (strcmp(type,"char") == 0) { - sz = sizeof(char)*numelements; - cast = SWIG_POINTER_char_p; - } else if (strcmp(type,"char *") == 0) { - sz = sizeof(char *)*(numelements+1); - cast = SWIG_POINTER_char_pp; - } else if (strcmp(type,"void") == 0) { - sz = numelements; - } else { - Tcl_SetResult(interp,"Unable to create unknown datatype.",TCL_STATIC); - return TCL_ERROR; - } - - /* Create the new object */ - - ptr = (void *) malloc(sz); - if (!ptr) { - Tcl_SetResult(interp,"Out of memory in ptrcreate.",TCL_STATIC); - return TCL_ERROR; - } - - /* Now try to set its default value */ - - if (ptrvalue) { - if (strcmp(type,"int") == 0) { - int *ip,i,ivalue; - Tcl_GetInt(interp,ptrvalue,&ivalue); - ip = (int *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"short") == 0) { - short *ip; - int i, ivalue; - Tcl_GetInt(interp,ptrvalue,&ivalue); - ip = (short *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = (short) ivalue; - } else if (strcmp(type,"long") == 0) { - long *ip; - int i, ivalue; - Tcl_GetInt(interp,ptrvalue,&ivalue); - ip = (long *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = (long) ivalue; - } else if (strcmp(type,"double") == 0) { - double *ip,ivalue; - int i; - Tcl_GetDouble(interp,ptrvalue,&ivalue); - ip = (double *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = ivalue; - } else if (strcmp(type,"float") == 0) { - float *ip; - double ivalue; - int i; - Tcl_GetDouble(interp,ptrvalue,&ivalue); - ip = (float *) ptr; - for (i = 0; i < numelements; i++) - ip[i] = (double) ivalue; - } else if (strcmp(type,"char") == 0) { - char *ip,*ivalue; - ivalue = (char *) ptrvalue; - ip = (char *) ptr; - strncpy(ip,ivalue,numelements-1); - } else if (strcmp(type,"char *") == 0) { - char **ip, *ivalue; - int i; - ivalue = (char *) ptrvalue; - ip = (char **) ptr; - for (i = 0; i < numelements; i++) { - if (ivalue) { - ip[i] = (char *) malloc(strlen(ivalue)+1); - strcpy(ip[i],ivalue); - } else { - ip[i] = 0; - } - } - ip[numelements] = 0; - } - } - /* Create the pointer value */ - - Tcl_SetObjResult(interp,SWIG_NewPointerObj(ptr,cast)); - return TCL_OK; -} - -/*------------------------------------------------------------------ - ptrset(ptr,value,index = 0,type = 0) - - Attempts to set the value of a pointer variable. If type is - given, we will use that type. Otherwise, we'll guess the datatype. - ------------------------------------------------------------------ */ - -static int ptrset(Tcl_Interp *interp, char *ptrvalue, char *value, int index, char *type) { - void *ptr; - char *s; - - s = ptrvalue; - if (SWIG_ConvertPtrFromString(interp,s,&ptr,0) != TCL_OK) { - Tcl_SetResult(interp,"Type error in ptrset. Argument is not a valid pointer value.", - TCL_STATIC); - return TCL_ERROR; - } - - /* If no datatype was passed, try a few common datatypes first */ - - if (!type) { - - /* No datatype was passed. Type to figure out if it's a common one */ - if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_int_p) == TCL_OK) { - type = "int"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_double_p) == TCL_OK) { - type = "double"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_short_p) == TCL_OK) { - type = "short"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_long_p) == TCL_OK) { - type = "long"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_float_p) == TCL_OK) { - type = "float"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_char_p) == TCL_OK) { - type = "char"; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_char_pp) == TCL_OK) { - type = "char *"; - } else { - type = "unknown"; - } - } - - if (!ptr) { - Tcl_SetResult(interp,"Unable to set NULL pointer.",TCL_STATIC); - return TCL_ERROR; - } - - /* Now we have a datatype. Try to figure out what to do about it */ - if (strcmp(type,"int") == 0) { - int ivalue; - Tcl_GetInt(interp,value, &ivalue); - *(((int *) ptr)+index) = ivalue; - } else if (strcmp(type,"double") == 0) { - double ivalue; - Tcl_GetDouble(interp,value, &ivalue); - *(((double *) ptr)+index) = (double) ivalue; - } else if (strcmp(type,"short") == 0) { - int ivalue; - Tcl_GetInt(interp,value, &ivalue); - *(((short *) ptr)+index) = (short) ivalue; - } else if (strcmp(type,"long") == 0) { - int ivalue; - Tcl_GetInt(interp,value, &ivalue); - *(((long *) ptr)+index) = (long) ivalue; - } else if (strcmp(type,"float") == 0) { - double ivalue; - Tcl_GetDouble(interp,value, &ivalue); - *(((float *) ptr)+index) = (float) ivalue; - } else if (strcmp(type,"char") == 0) { - char *c = value; - strcpy(((char *) ptr)+index, c); - } else if (strcmp(type,"char *") == 0) { - char *c = value; - char **ca = (char **) ptr; - if (ca[index]) free(ca[index]); - if (strcmp(c,"NULL") == 0) { - ca[index] = 0; - } else { - ca[index] = (char *) malloc(strlen(c)+1); - strcpy(ca[index],c); - } - } else { - Tcl_SetResult(interp,"Unable to set unsupported datatype.",TCL_STATIC); - return TCL_ERROR; - } - return TCL_OK; -} - -/*------------------------------------------------------------------ - ptradd(ptr,offset) - - Adds a value to an existing pointer value. Will do a type-dependent - add for basic datatypes. For other datatypes, will do a byte-add. - ------------------------------------------------------------------ */ - -static int ptradd(Tcl_Interp *interp, char *ptrvalue, int offset) { - - char *r,*s; - void *ptr,*junk; - swig_type_info *type = 0; - swig_type_info stype; - - /* Check to see what kind of object ptrvalue is */ - - s = ptrvalue; - - /* Try to handle a few common datatypes first */ - - if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_int_p) == TCL_OK) { - ptr = (void *) (((int *) ptr) + offset); - type = SWIG_POINTER_int_p; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_double_p) == TCL_OK) { - ptr = (void *) (((double *) ptr) + offset); - type = SWIG_POINTER_double_p; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_short_p) == TCL_OK) { - ptr = (void *) (((short *) ptr) + offset); - type = SWIG_POINTER_short_p; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_long_p) == TCL_OK) { - ptr = (void *) (((long *) ptr) + offset); - type = SWIG_POINTER_long_p; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_float_p) == TCL_OK) { - ptr = (void *) (((float *) ptr) + offset); - type = SWIG_POINTER_float_p; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,SWIG_POINTER_char_p) == TCL_OK) { - ptr = (void *) (((char *) ptr) + offset); - type = SWIG_POINTER_char_p; - } else if (SWIG_ConvertPtrFromString(interp,s,&ptr,0) == TCL_OK) { - ptr = (void *) (((char *) ptr) + offset); - stype.name = SWIG_PointerTypeFromString(s); - type = &stype; - } else { - Tcl_SetResult(interp,"Type error in ptradd. Argument is not a valid pointer value.",TCL_STATIC); - return TCL_ERROR; - } - Tcl_SetObjResult(interp,SWIG_NewPointerObj(ptr,type)); - return TCL_OK; -} - -/*------------------------------------------------------------------ - ptrfree(ptr) - - Destroys a pointer value - ------------------------------------------------------------------ */ - -int ptrfree(Tcl_Interp *interp, char *ptrvalue) { - void *ptr, *junk; - char *s; - - s = ptrvalue; - if (SWIG_ConvertPtrFromString(interp,ptrvalue,&ptr,0) != TCL_OK) { - Tcl_SetResult(interp,"Type error in ptrfree. Argument is not a valid pointer value.",TCL_STATIC); - return TCL_ERROR; - } - - /* Check to see if this pointer is a char ** */ - if (SWIG_ConvertPtrFromString(interp,ptrvalue,&junk,SWIG_POINTER_char_pp) == TCL_OK) { - char **c = (char **) ptr; - if (c) { - int i = 0; - while (c[i]) { - free(c[i]); - i++; - } - } - } - if (ptr) - free((char *) ptr); - return TCL_OK; -} -%} - -%typemap(tcl8,out) int ptrcast, - int ptrvalue, - int ptrcreate, - int ptrset, - int ptradd, - int ptrfree -{ - return $source; -} - -%typemap(tcl8,ignore) Tcl_Interp * { - $target = interp; -} - -int ptrvalue(Tcl_Interp *interp, char *ptr, int index = 0, char *type = 0); -// Returns the value that a pointer is pointing to (ie. dereferencing). -// The type is automatically inferred by the pointer type--thus, an -// integer pointer will return an integer, a double will return a double, -// and so on. The index and type fields are optional parameters. When -// an index is specified, this function returns the value of ptr[index]. -// This allows array access. When a type is specified, it overrides -// the given pointer type. Examples : -// -// ptrvalue $a # Returns the value *a -// ptrvalue $a 10 # Returns the value a[10] -// ptrvalue $a 10 double # Returns a[10] assuming a is a double * - -int ptrset(Tcl_Interp *interp, char *ptr, char *value, int index = 0, char *type = 0); -// Sets the value pointed to by a pointer. The type is automatically -// inferred from the pointer type so this function will work for -// integers, floats, doubles, etc... The index and type fields are -// optional. When an index is given, it provides array access. When -// type is specified, it overrides the given pointer type. Examples : -// -// ptrset $a 3 # Sets the value *a = 3 -// ptrset $a 3 10 # Sets a[10] = 3 -// ptrset $a 3 10 int # Sets a[10] = 3 assuming a is a int * - -int ptrcreate(Tcl_Interp *interp, char *type, char *value = 0, int nitems = 1); -// Creates a new object and returns a pointer to it. This function -// can be used to create various kinds of objects for use in C functions. -// type specifies the basic C datatype to create and value is an -// optional parameter that can be used to set the initial value of the -// object. nitems is an optional parameter that can be used to create -// an array. This function results in a memory allocation using -// malloc(). Examples : -// -// set a [ptrcreate "double"] # Create a new double, return pointer -// set a [ptrcreate int 7] # Create an integer, set value to 7 -// set a [ptrcreate int 0 1000] # Create an integer array with initial -// # values all set to zero -// -// This function only recognizes a few common C datatypes as listed below : -// -// int, short, long, float, double, char, char *, void -// -// All other datatypes will result in an error. However, other -// datatypes can be created by using the ptrcast function. For -// example: -// -// set a [ptrcast [ptrcreate int 0 100],"unsigned int *"] - -int ptrfree(Tcl_Interp *interp, char *ptr); -// Destroys the memory pointed to by ptr. This function calls free() -// and should only be used with objects created by ptrcreate(). Since -// this function calls free, it may work with other objects, but this -// is generally discouraged unless you absolutely know what you're -// doing. - -int ptradd(Tcl_Interp *interp, char *ptr, int offset); -// Adds a value to the current pointer value. For the C datatypes of -// int, short, long, float, double, and char, the offset value is the -// number of objects and works in exactly the same manner as in C. For -// example, the following code steps through the elements of an array -// -// set a [ptrcreate double 0 100] # Create an array double a[100] -// set b $a -// for {set i 0} {$i < 100} {incr i 1} { -// ptrset $b [expr{0.0025*$i}] # set *b = 0.0025*i -// set b [ptradd $b 1] # b++ (go to next double) -// } -// -// In this case, adding one to b goes to the next double. -// -// For all other datatypes (including all complex datatypes), the -// offset corresponds to bytes. This function does not perform any -// bounds checking and negative offsets are perfectly legal. - - - - - - - diff --git a/Lib/tcl/std_string.i b/Lib/tcl/std_string.i new file mode 100644 index 000000000..c636c0388 --- /dev/null +++ b/Lib/tcl/std_string.i @@ -0,0 +1,47 @@ +// +// SWIG typemaps for std::string +// Luigi Ballabio and Manu ??? +// Apr 26, 2002 +// +// Tcl implementation + + +// ------------------------------------------------------------------------ +// std::string is typemapped by value +// This can prevent exporting methods which return a string +// in order for the user to modify it. +// However, I think I'll wait until someone asks for it... +// ------------------------------------------------------------------------ + +%include exception.i + +%{ +#include +%} + +namespace std { + + class string; + + /* Overloading check */ + %typemap(typecheck) string = char *; + %typemap(typecheck) const string & = char *; + + %typemap(in) string { + $1 = std::string(Tcl_GetStringFromObj($input,NULL)); + } + + %typemap(in) const string & (std::string temp) { + temp = std::string(Tcl_GetStringFromObj($input,NULL)); + $1 = &temp; + } + + %typemap(out) string { + Tcl_SetStringObj($result,(char*)$1.c_str(),$1.length()); + } + + %typemap(out) const string & { + Tcl_SetStringObj($result,(char*)$1->c_str(),$1->length()); + } + +} diff --git a/Lib/tcl/std_vector.i b/Lib/tcl/std_vector.i new file mode 100644 index 000000000..fa8f804a6 --- /dev/null +++ b/Lib/tcl/std_vector.i @@ -0,0 +1,442 @@ +// +// SWIG typemaps for std::vector +// Luigi Ballabio and Manu ??? and Kristopher Blom +// Apr 26, 2002, updated Nov 13, 2002[blom] +// +// Tcl implementation + + +%include exception.i + +// containers + +// methods which can raise are caused to throw an IndexError +%exception std::vector::get { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::set { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + +%exception std::vector::pop { + try { + $action + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError,const_cast(e.what())); + } +} + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Tcl as much as possible, namely, to allow the user to pass and +// be returned Tcl lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector), f(const std::vector&), f(const std::vector*): +// the parameter being read-only, either a Tcl list or a +// previously wrapped std::vector can be passed. +// -- f(std::vector&), f(std::vector*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector f(): +// the vector is returned by copy; therefore, a Tcl list of T:s +// is returned which is most easily used in other Tcl functions procs +// -- std::vector& f(), std::vector* f(), const std::vector& f(), +// const std::vector* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +#include + +Tcl_Obj* SwigString_FromString(std::string s) { + return Tcl_NewStringObj(s.c_str(), s.length()); +} + +int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) { + int len; + const char* temp = Tcl_GetStringFromObj(o, &len); + if(temp == NULL) + return TCL_ERROR; + *val = temp; +} + +// behaviour of this is such as the real Tcl_GetIntFromObj +template +int SwigInt_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) { + int temp_val, return_val; + return_val = Tcl_GetIntFromObj(interp, o, &temp_val); + *val = (Type) temp_val; + return return_val; +} + +// behaviour of this is such as the real Tcl_GetDoubleFromObj +template +int SwigDouble_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) { + int return_val; + double temp_val; + return_val = Tcl_GetDoubleFromObj(interp, o, &temp_val); + *val = (Type) temp_val; + return return_val; +} + +%} + +// exported class + +namespace std { + + template class vector { + %typemap(in) vector (std::vector *v) { + Tcl_Obj **listobjv; + int nitems; + int i; + T* temp; + + if (SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $&1_descriptor, 0) == 0){ + $1 = *v; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, \ + &nitems, &listobjv) == TCL_ERROR) + return TCL_ERROR; + $1 = std::vector(); + for (i = 0; i < nitems; i++) { + if ((SWIG_ConvertPtr(interp, listobjv[i],(void **) &temp, + $descriptor(T),0)) != 0) { + char message[] = + "list of type $descriptor(T) expected"; + Tcl_SetResult(interp, message, TCL_VOLATILE); + return TCL_ERROR; + } + $1.push_back(*temp); + } + } + } + + %typemap(in) const vector* (std::vector *v, std::vector w), + const vector& (std::vector *v, std::vector w) { + Tcl_Obj **listobjv; + int nitems; + int i; + T* temp; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $&1_descriptor, 0) == 0) { + $1 = v; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + return TCL_ERROR; + w = std::vector(); + for (i = 0; i < nitems; i++) { + if ((SWIG_ConvertPtr(interp, listobjv[i],(void **) &temp, + $descriptor(T),0)) != 0) { + char message[] = + "list of type $descriptor(T) expected"; + Tcl_SetResult(interp, message, TCL_VOLATILE); + return TCL_ERROR; + } + w.push_back(*temp); + } + $1 = &w; + } + } + + %typemap(out) vector { + for (unsigned int i=0; i<$1.size(); i++) { + T* ptr = new T((($1_type &)$1)[i]); + Tcl_ListObjAppendElement(interp, $result, \ + SWIG_NewPointerObj(ptr, + $descriptor(T), + 0)); + } + } + + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + Tcl_Obj **listobjv; + int nitems; + int i; + T* temp; + std::vector *v; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $&1_descriptor, 0) == 0) { + /* wrapped vector */ + $1 = 1; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + $1 = 0; + else + if (nitems == 0) + $1 = 1; + //check the first value to see if it is of correct type + else if ((SWIG_ConvertPtr(interp, listobjv[i], + (void **) &temp, + $descriptor(T),0)) != 0) + $1 = 0; + else + $1 = 1; + } + } + + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector* { + Tcl_Obj **listobjv; + int nitems; + int i; + T* temp; + std::vector *v; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $1_descriptor, 0) == 0){ + /* wrapped vector */ + $1 = 1; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + $1 = 0; + else + if (nitems == 0) + $1 = 1; + //check the first value to see if it is of correct type + else if ((SWIG_ConvertPtr(interp, listobjv[i], + (void **) &temp, + $descriptor(T),0)) != 0) + $1 = 0; + else + $1 = 1; + } + } + + public: + vector(); + vector(unsigned int size, const T& value=T()); + vector(const vector &); + + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(const T& x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& get(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && isize()); + if (i<0) i+= size; + if (i>=0 && i class vector { + + %typemap(in) vector (std::vector *v){ + Tcl_Obj **listobjv; + int nitems; + int i; + T temp; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $&1_descriptor, 0) == 0) { + $1 = *v; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + return TCL_ERROR; + $1 = std::vector(); + for (i = 0; i < nitems; i++) { + if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR) + return TCL_ERROR; + $1.push_back(temp); + } + } + } + + %typemap(in) const vector& (std::vector *v,std::vector w), + const vector* (std::vector *v,std::vector w) { + Tcl_Obj **listobjv; + int nitems; + int i; + T temp; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $1_descriptor, 0) == 0) { + $1 = v; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + return TCL_ERROR; + w = std::vector(); + for (i = 0; i < nitems; i++) { + if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR) + return TCL_ERROR; + w.push_back(temp); + } + $1 = &w; + } + } + + %typemap(out) vector { + for (unsigned int i=0; i<$1.size(); i++) { + Tcl_ListObjAppendElement(interp, $result, \ + CONVERT_TO((($1_type &)$1)[i])); + } + } + + %typecheck(SWIG_TYPECHECK_VECTOR) vector { + Tcl_Obj **listobjv; + int nitems; + int i; + T temp; + std::vector *v; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $&1_descriptor, 0) == 0){ + /* wrapped vector */ + $1 = 1; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + $1 = 0; + else + if (nitems == 0) + $1 = 1; + //check the first value to see if it is of correct type + if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR) + $1 = 0; + else + $1 = 1; + } + } + + %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, + const vector*{ + Tcl_Obj **listobjv; + int nitems; + int i; + T temp; + std::vector *v; + + if(SWIG_ConvertPtr(interp, $input, (void **) &v, \ + $1_descriptor, 0) == 0){ + /* wrapped vector */ + $1 = 1; + } else { + // It isn't a vector so it should be a list of T's + if(Tcl_ListObjGetElements(interp, $input, + &nitems, &listobjv) == TCL_ERROR) + $1 = 0; + else + if (nitems == 0) + $1 = 1; + //check the first value to see if it is of correct type + if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR) + $1 = 0; + else + $1 = 1; + } + } + + public: + vector(); + vector(unsigned int size, const T& value=T()); + vector(const vector &); + + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(T x); + %extend { + T pop() { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T get(int i) { + int size = int(self->size()); + if (i<0) i += size; + if (i>=0 && isize()); + if (i<0) i+= size; + if (i>=0 && i, Tcl_NewIntObj); + specialize_std_vector(long, SwigInt_As, Tcl_NewIntObj); + specialize_std_vector(unsigned int, + SwigInt_As, Tcl_NewIntObj); + specialize_std_vector(unsigned short, + SwigInt_As, Tcl_NewIntObj); + specialize_std_vector(unsigned long, + SwigInt_As, Tcl_NewIntObj); + specialize_std_vector(double, Tcl_GetDoubleFromObj, Tcl_NewDoubleObj); + specialize_std_vector(float, SwigDouble_As, Tcl_NewDoubleObj); + specialize_std_vector(std::string, + SwigString_AsString, SwigString_FromString); + +} + + diff --git a/Lib/tcl/stl.i b/Lib/tcl/stl.i new file mode 100644 index 000000000..ce9a6c1a7 --- /dev/null +++ b/Lib/tcl/stl.i @@ -0,0 +1,9 @@ +// +// SWIG typemaps for STL types +// Luigi Ballabio and Manu ??? +// Apr 26, 2002 +// + +%include std_string.i +%include std_vector.i + diff --git a/Lib/tcl/swigtcl8.swg b/Lib/tcl/swigtcl8.swg index 44087256d..0817b4ec5 100644 --- a/Lib/tcl/swigtcl8.swg +++ b/Lib/tcl/swigtcl8.swg @@ -7,186 +7,430 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { #endif +/* Constant table */ + +#define SWIG_TCL_INT 1 +#define SWIG_TCL_FLOAT 2 +#define SWIG_TCL_STRING 3 +#define SWIG_TCL_POINTER 4 +#define SWIG_TCL_BINARY 5 + +/* Flags for pointer conversion */ +#define SWIG_POINTER_EXCEPTION 0x1 +#define SWIG_POINTER_DISOWN 0x2 + +/* Swig fail macro */ + +#define SWIG_fail goto fail + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +typedef int (*swig_wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); +typedef int (*swig_wrapper_func)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); +typedef char *(*swig_variable_func)(ClientData, Tcl_Interp *, char *, char *, int); +typedef void (*swig_delete_func)(ClientData); + +typedef struct swig_method { + const char *name; + swig_wrapper method; +} swig_method; + +typedef struct swig_attribute { + const char *name; + swig_wrapper getmethod; + swig_wrapper setmethod; +} swig_attribute; + +typedef struct swig_class { + const char *name; + swig_type_info **type; + swig_wrapper constructor; + void (*destructor)(void *); + swig_method *methods; + swig_attribute *attributes; + struct swig_class **bases; +} swig_class; + +typedef struct swig_instance { + Tcl_Obj *thisptr; + void *thisvalue; + swig_class *classptr; + int destroy; + Tcl_Command cmdtok; +} swig_instance; + #ifdef SWIG_NOINCLUDE -SWIGEXPORT(int) SWIG_ConvertPtrFromString(Tcl_Interp *, char *, void **, swig_type_info *); -SWIGEXPORT(int) SWIG_ConvertPtr(Tcl_Interp *, Tcl_Obj *, void **, swig_type_info *); -SWIGEXPORT(void) SWIG_MakePtr(char *, void *, swig_type_info *); -SWIGEXPORT(Tcl_Obj *) SWIG_NewPointerObj(void *, swig_type_info *); -SWIGEXPORT(int) SWIG_GetArgs(Tcl_Interp *, int, Tcl_Obj *CONST [], const char *, ...); -SWIGEXPORT(char *) SWIG_PointerTypeFromString(char *c); +SWIGEXPORT(char *) SWIG_PackData(char *c, void *ptr, int sz); +SWIGEXPORT(char *) SWIG_UnpackData(char *c, void *ptr, int sz); +SWIGEXPORT(int) SWIG_ConvertPtrFromString(Tcl_Interp *, char *, void **, swig_type_info *,int flags); +SWIGEXPORT(int) SWIG_ConvertPtr(Tcl_Interp *, Tcl_Obj *, void **, swig_type_info *, int flags); +SWIGEXPORT(int) SWIG_ConvertPacked(Tcl_Interp *, Tcl_Obj *, void *, int sz, swig_type_info *, int flags); +SWIGEXPORT(void) SWIG_MakePtr(char *, void *, swig_type_info *, int flags); +SWIGEXPORT(Tcl_Obj *) SWIG_NewPointerObj(void *, swig_type_info *, int flags); +SWIGEXPORT(Tcl_Obj *) SWIG_NewPackedObj(void *, int sz, swig_type_info *, int flags); +SWIGEXPORT(int) SWIG_GetArgs(Tcl_Interp *, int, Tcl_Obj *CONST [], const char *, ...); +SWIGEXPORT(char *) SWIG_PointerTypeFromString(char *c); +SWIGEXPORT(void) SWIG_Acquire(void *ptr); +SWIGEXPORT(int) SWIG_Disown(void *ptr); +SWIGEXPORT(int) SWIG_Thisown(void *ptr); +SWIGEXPORT(void) SWIG_InstallConstants(Tcl_Interp *interp, struct swig_const_info constants[]); +SWIGEXPORT(Tcl_Obj *) SWIG_GetConstant(const char *key); +SWIGEXPORT(Tcl_Obj *) SWIG_NewInstanceObj(Tcl_Interp *interp, void *, swig_type_info *, int flags); +SWIGEXPORT(int) SWIG_ObjectConstructor(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]); +SWIGEXPORT(int) SWIG_MethodCommand(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]); +SWIGEXPORT(void) SWIG_ObjectDelete(ClientData); #else +/* Object support */ +static Tcl_HashTable swigobjectTable; +static int swigobjectTableinit = 0; + +/* Acquire ownership of a pointer */ +SWIGRUNTIME(void) +SWIG_Acquire(void *ptr) +{ + Tcl_HashEntry *entryPtr; + int newobj; + if (!swigobjectTableinit) { + Tcl_InitHashTable(&swigobjectTable, TCL_ONE_WORD_KEYS); + swigobjectTableinit = 1; + } + entryPtr = Tcl_CreateHashEntry(&swigobjectTable, (char *) ptr, &newobj); +} + +/* Disown a pointer. Returns 1 if we owned it to begin with */ +SWIGRUNTIME(int) +SWIG_Disown(void *ptr) +{ + Tcl_HashEntry *entryPtr; + if (!swigobjectTableinit) return 0; + entryPtr = Tcl_FindHashEntry(&swigobjectTable, (char *) ptr); + if (entryPtr) { + Tcl_DeleteHashEntry(entryPtr); + return 1; + } + return 0; +} + +SWIGRUNTIME(int) +SWIG_Thisown(void *ptr) { + if (!swigobjectTableinit) return 0; + if (Tcl_FindHashEntry(&swigobjectTable, (char *) ptr)) { + return 1; + } + return 0; +} + +/* Pack binary data into a string */ +SWIGRUNTIME(char *) +SWIG_PackData(char *c, void *ptr, int sz) { + static char hex[17] = "0123456789abcdef"; + int i; + unsigned char *u = (unsigned char *) ptr; + register unsigned char uu; + for (i = 0; i < sz; i++,u++) { + uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* Unpack binary data from a string */ +SWIGRUNTIME(char *) +SWIG_UnpackData(char *c, void *ptr, int sz) { + register unsigned char uu = 0; + register int d; + unsigned char *u = (unsigned char *) ptr; + int i; + if ((int)strlen(c) < (2*sz)) return c; + for (i = 0; i < sz; i++, u++) { + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + *u = uu; + } + return c; +} + /* Convert a pointer value */ SWIGRUNTIME(int) -SWIG_ConvertPtrFromString(Tcl_Interp *interp, char *c, void **ptr, swig_type_info *ty) +SWIG_ConvertPtrFromString(Tcl_Interp *interp, char *c, void **ptr, swig_type_info *ty, int flags) { - unsigned long p; - register int d; swig_type_info *tc; - p = 0; /* Pointer values must start with leading underscore */ - if (*c != '_') { + while (*c != '_') { *ptr = (void *) 0; if (strcmp(c,"NULL") == 0) return TCL_OK; - Tcl_SetResult(interp,"Type error. Expected a pointer", TCL_STATIC); + /* Hmmm. It could be an object name. */ + if (Tcl_VarEval(interp,c," cget -this", (char *) NULL) == TCL_OK) { + Tcl_Obj *result = Tcl_GetObjResult(interp); + c = Tcl_GetStringFromObj(result, NULL); + continue; + } + if (flags & SWIG_POINTER_EXCEPTION) + Tcl_SetResult(interp, (char *) "Type error. Expected a pointer", TCL_STATIC); return TCL_ERROR; } c++; - /* Extract hex value from pointer */ - while ((d = *c)) { - if ((d >= '0') && (d <= '9')) - p = (p << 4) + (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - p = (p << 4) + (d - ('a'-10)); - else - break; - c++; - } - *ptr = (void *) p; + c = SWIG_UnpackData(c,ptr,sizeof(void *)); if (ty) { tc = SWIG_TypeCheck(c,ty); - if (!tc) { - Tcl_SetResult(interp,"Type error. Expected ", TCL_STATIC); - Tcl_AppendElement(interp, ty->name); + if ((!tc) && (flags & SWIG_POINTER_EXCEPTION)) { + Tcl_SetResult(interp, (char *) "Type error. Expected ", TCL_STATIC); + Tcl_AppendElement(interp, (char *) ty->name); + return TCL_ERROR; + } else if (!tc) { return TCL_ERROR; } - *ptr = SWIG_TypeCast(tc,(void *)p); + if (flags & SWIG_POINTER_DISOWN) { + SWIG_Disown((void *) *ptr); + } + *ptr = SWIG_TypeCast(tc,(void *) *ptr); } return TCL_OK; } - /* Convert a pointer value */ SWIGRUNTIME(int) -SWIG_ConvertPtr(Tcl_Interp *interp, Tcl_Obj *oc, void **ptr, swig_type_info *ty) +SWIG_ConvertPtr(Tcl_Interp *interp, Tcl_Obj *oc, void **ptr, swig_type_info *ty, int flags) { - return SWIG_ConvertPtrFromString(interp, Tcl_GetStringFromObj(oc,NULL), ptr, ty); + return SWIG_ConvertPtrFromString(interp, Tcl_GetStringFromObj(oc,NULL), ptr, ty, flags); } - /* Convert a pointer value */ SWIGRUNTIME(char *) SWIG_PointerTypeFromString(char *c) { char d; - /* Pointer values must start with leading underscore */ + /* Pointer values must start with leading underscore. NULL has no type */ if (*c != '_') { return 0; } c++; /* Extract hex value from pointer */ - while (d = *c) { + while ((d = *c)) { if (!(((d >= '0') && (d <= '9')) || ((d >= 'a') && (d <= 'f')))) break; c++; } return c; } +/* Convert a packed value value */ +SWIGRUNTIME(int) +SWIG_ConvertPacked(Tcl_Interp *interp, Tcl_Obj *obj, void *ptr, int sz, swig_type_info *ty, int flags) { + swig_type_info *tc; + char *c; + + if (!obj) goto type_error; + c = Tcl_GetStringFromObj(obj,NULL); + /* Pointer values must start with leading underscore */ + if (*c != '_') goto type_error; + c++; + c = SWIG_UnpackData(c,ptr,sz); + if (ty) { + tc = SWIG_TypeCheck(c,ty); + if (!tc) goto type_error; + } + return TCL_OK; + +type_error: + + if (flags) { + if (ty) { + Tcl_SetResult(interp, (char *) "Type error. Expected ", TCL_STATIC); + Tcl_AppendElement(interp, (char *) ty->name); + return TCL_ERROR; + } else { + Tcl_SetResult(interp, (char *) "Expected packed data.", TCL_STATIC); + return TCL_ERROR; + } + } + return TCL_ERROR; +} + + /* Take a pointer and convert it to a string */ SWIGRUNTIME(void) -SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) { - static char hex[17] = "0123456789abcdef"; - unsigned long p, s; - char result[24], *r; - r = result; - p = (unsigned long) ptr; - if (p > 0) { - while (p > 0) { - s = p & 0xf; - *(r++) = hex[s]; - p = p >> 4; - } - *r = '_'; - while (r >= result) - *(c++) = *(r--); - strcpy (c, ty->name); +SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty, int flags) { + if (ptr) { + *(c++) = '_'; + c = SWIG_PackData(c,&ptr,sizeof(void *)); + strcpy(c,ty->name); } else { - strcpy (c, "NULL"); + strcpy(c,(char *)"NULL"); } + flags = 0; } /* Create a new pointer object */ SWIGRUNTIME(Tcl_Obj *) -SWIG_NewPointerObj(void *ptr, swig_type_info *type) { - char result[256]; +SWIG_NewPointerObj(void *ptr, swig_type_info *type, int flags) { Tcl_Obj *robj; - SWIG_MakePtr(result,ptr,type); + char result[512]; + SWIG_MakePtr(result,ptr,type,flags); robj = Tcl_NewStringObj(result,-1); return robj; } +SWIGRUNTIME(Tcl_Obj *) +SWIG_NewPackedObj(void *ptr, int sz, swig_type_info *type, int flags) { + char result[1024]; + char *r = result; + if ((2*sz + 1 + strlen(type->name)) > 1000) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + strcpy(r,type->name); + flags = 0; + return Tcl_NewStringObj(result,-1); +} + +static Tcl_HashTable swigconstTable; +static int swigconstTableinit = 0; + +/* Install Constants */ +SWIGRUNTIME(void) +SWIG_InstallConstants(Tcl_Interp *interp, swig_const_info constants[]) { + int i; + Tcl_Obj *obj; + Tcl_HashEntry *entryPtr; + int newobj; + + if (!swigconstTableinit) { + Tcl_InitHashTable(&swigconstTable, TCL_STRING_KEYS); + swigconstTableinit = 1; + } + for (i = 0; constants[i].type; i++) { + switch(constants[i].type) { + case SWIG_TCL_INT: + obj = Tcl_NewIntObj(constants[i].lvalue); + break; + case SWIG_TCL_FLOAT: + obj = Tcl_NewDoubleObj(constants[i].dvalue); + break; + case SWIG_TCL_STRING: + obj = Tcl_NewStringObj((char *) constants[i].pvalue,-1); + break; + case SWIG_TCL_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_TCL_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype),0); + break; + default: + obj = 0; + break; + } + if (obj) { + Tcl_ObjSetVar2(interp,Tcl_NewStringObj(constants[i].name,-1), NULL, obj, TCL_GLOBAL_ONLY); + entryPtr = Tcl_CreateHashEntry(&swigconstTable, constants[i].name, &newobj); + Tcl_SetHashValue(entryPtr, (ClientData) obj); + } + } +} + +SWIGRUNTIME(Tcl_Obj *) +SWIG_GetConstant(const char *key) { + Tcl_HashEntry *entryPtr; + if (!swigconstTableinit) return 0; + entryPtr = Tcl_FindHashEntry(&swigconstTable, key); + if (entryPtr) { + return (Tcl_Obj *) Tcl_GetHashValue(entryPtr); + } + printf("Searching %s\n", key); + return 0; +} + /* Get arguments */ SWIGRUNTIME(int) SWIG_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], const char *fmt, ...) { int argno = 0, opt = 0, tempi; - int us = 0; double tempd; const char *c; va_list ap; void *vptr; + Tcl_Obj *obj = 0; swig_type_info *ty; va_start(ap,fmt); - for (c = fmt; (*c && (*c != ':')); c++,argno++) { + for (c = fmt; (*c && (*c != ':') && (*c != ';')); c++,argno++) { if (*c == '|') { opt = 1; c++; } if (argno >= (objc-1)) { if (!opt) { - Tcl_SetResult(interp,"Wrong # args. ", TCL_STATIC); + Tcl_SetResult(interp, (char *) "Wrong # args. ", TCL_STATIC); goto argerror; } else { va_end(ap); return TCL_OK; } } + vptr = va_arg(ap,void *); if (vptr) { - us = 0; - if (*c == 'u') { - us = 1; - c++; + if (isupper(*c)) { + obj = SWIG_GetConstant(Tcl_GetStringFromObj(objv[argno+1],0)); + if (!obj) obj = objv[argno+1]; + } else { + obj = objv[argno+1]; } switch(*c) { - case 'i': - case 'l': - case 'h': - case 'b': - if (Tcl_GetIntFromObj(interp,objv[argno+1],&tempi) != TCL_OK) goto argerror; - if (*c == 'i') *((int *)vptr) = tempi; - else if (*c == 'l') *((long *)vptr) = tempi; - else if (*c == 'h') *((short*)vptr) = tempi; - else if (*c == 'b') *((unsigned char *)vptr) = tempi; + case 'i': case 'I': + case 'l': case 'L': + case 'h': case 'H': + case 'b': case 'B': + if (Tcl_GetIntFromObj(interp,obj,&tempi) != TCL_OK) goto argerror; + if ((*c == 'i') || (*c == 'I')) *((int *)vptr) = tempi; + else if ((*c == 'l') || (*c == 'L')) *((long *)vptr) = tempi; + else if ((*c == 'h') || (*c == 'H')) *((short*)vptr) = tempi; + else if ((*c == 'b') || (*c == 'B')) *((unsigned char *)vptr) = tempi; break; - case 'f': - case 'd': - if (Tcl_GetDoubleFromObj(interp,objv[argno+1],&tempd) != TCL_OK) goto argerror; - if (*c == 'f') *((float *) vptr) = tempd; - else if (*c == 'd') *((double*) vptr) = tempd; + case 'f': case 'F': + case 'd': case 'D': + if (Tcl_GetDoubleFromObj(interp,obj,&tempd) != TCL_OK) goto argerror; + if ((*c == 'f') || (*c == 'F')) *((float *) vptr) = (float)tempd; + else if ((*c == 'd') || (*c == 'D')) *((double*) vptr) = tempd; break; - case 's': + case 's': case 'S': if (*(c+1) == '#') { int *vlptr = (int *) va_arg(ap, void *); - *((char **) vptr) = Tcl_GetStringFromObj(objv[argno+1], vlptr); + *((char **) vptr) = Tcl_GetStringFromObj(obj, vlptr); c++; } else { - *((char **)vptr) = Tcl_GetStringFromObj(objv[argno+1],NULL); + *((char **)vptr) = Tcl_GetStringFromObj(obj,NULL); } break; - case 'c': - *((char *)vptr) = *(Tcl_GetStringFromObj(objv[argno+1],NULL)); + case 'c': case 'C': + *((char *)vptr) = *(Tcl_GetStringFromObj(obj,NULL)); break; - case 'p': + case 'p': case 'P': ty = (swig_type_info *) va_arg(ap, void *); - if (SWIG_ConvertPtr(interp, objv[argno+1], (void **) vptr, ty) == TCL_ERROR) goto argerror; + if (SWIG_ConvertPtr(interp, obj, (void **) vptr, ty, SWIG_POINTER_EXCEPTION) == TCL_ERROR) goto argerror; break; - case 'o': + case 'o': case 'O': *((Tcl_Obj **)vptr) = objv[argno+1]; break; default: @@ -194,8 +438,9 @@ SWIG_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], const char *fm } } } - if ((objc-1) > argno) { - Tcl_SetResult(interp,"Wrong # args.", TCL_STATIC); + + if ((*c != ';') && ((objc-1) > argno)) { + Tcl_SetResult(interp, (char *) "Wrong # args.", TCL_STATIC); goto argerror; } va_end(ap); @@ -204,13 +449,298 @@ SWIG_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], const char *fm argerror: { char temp[32]; - sprintf(temp,"%d", argno); - Tcl_AppendResult(interp,strchr(fmt,':'), " argument ", temp, NULL); + sprintf(temp,"%d", argno+1); + c = strchr(fmt,':'); + if (!c) c = strchr(fmt,';'); + if (!c) c = (char *)""; + Tcl_AppendResult(interp,c," argument ", temp, NULL); va_end(ap); return TCL_ERROR; } } +SWIGRUNTIME(void) +SWIG_ObjectDelete(ClientData clientData) { + swig_instance *si = (swig_instance *) clientData; + if ((si) && (si->destroy) && (SWIG_Disown(si->thisvalue))) { + if (si->classptr->destructor) { + (si->classptr->destructor)(si->thisvalue); + } + } + Tcl_DecrRefCount(si->thisptr); + free(si); +} + +/* Function to invoke object methods given an instance */ +SWIGRUNTIME(int) +SWIG_MethodCommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST _objv[]) +{ + char *method, *attrname; + swig_instance *inst = (swig_instance *) clientData; + swig_method *meth; + swig_attribute *attr; + Tcl_Obj *oldarg; + Tcl_Obj **objv; + int rcode; + swig_class *cls; + swig_class *cls_stack[64]; + int cls_stack_bi[64]; + int cls_stack_top = 0; + int numconf = 2; + int bi; + + objv = (Tcl_Obj **) _objv; + if (objc < 2) { + Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC); + return TCL_ERROR; + } + method = Tcl_GetStringFromObj(objv[1],NULL); + if (strcmp(method,"-acquire") == 0) { + inst->destroy = 1; + SWIG_Acquire(inst->thisvalue); + return TCL_OK; + } + if (strcmp(method,"-disown") == 0) { + if (inst->destroy) { + SWIG_Disown(inst->thisvalue); + } + inst->destroy = 0; + return TCL_OK; + } + if (strcmp(method,"-delete") == 0) { + Tcl_DeleteCommandFromToken(interp,inst->cmdtok); + return TCL_OK; + } + cls_stack[cls_stack_top] = inst->classptr; + cls_stack_bi[cls_stack_top] = -1; + cls = inst->classptr; + while (1) { + bi = cls_stack_bi[cls_stack_top]; + cls = cls_stack[cls_stack_top]; + if (bi != -1) { + cls = cls->bases[bi]; + if (cls) { + cls_stack_bi[cls_stack_top]++; + cls_stack_top++; + cls_stack[cls_stack_top] = cls; + cls_stack_bi[cls_stack_top] = -1; + continue; + } + } + if (!cls) { + cls_stack_top--; + if (cls_stack_top < 0) break; + else continue; + } + cls_stack_bi[cls_stack_top]++; + + meth = cls->methods; + /* Check for methods */ + while (meth && meth->name) { + if (strcmp(meth->name,method) == 0) { + oldarg = objv[1]; + objv[1] = inst->thisptr; + Tcl_IncrRefCount(inst->thisptr); + rcode = (*meth->method)(clientData,interp,objc,objv); + objv[1] = oldarg; + Tcl_DecrRefCount(inst->thisptr); + return rcode; + } + meth++; + } + /* Check class methods for a match */ + if (strcmp(method,"cget") == 0) { + if (objc < 3) { + Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC); + return TCL_ERROR; + } + attrname = Tcl_GetStringFromObj(objv[2],NULL); + attr = cls->attributes; + while (attr && attr->name) { + if ((strcmp(attr->name, attrname) == 0) && (attr->getmethod)) { + oldarg = objv[1]; + objv[1] = inst->thisptr; + Tcl_IncrRefCount(inst->thisptr); + rcode = (*attr->getmethod)(clientData,interp,2, objv); + objv[1] = oldarg; + Tcl_DecrRefCount(inst->thisptr); + return rcode; + } + attr++; + } + if (strcmp(attrname, "-this") == 0) { + Tcl_SetObjResult(interp, Tcl_DuplicateObj(inst->thisptr)); + return TCL_OK; + } + if (strcmp(attrname, "-thisown") == 0) { + if (SWIG_Thisown(inst->thisvalue)) { + Tcl_SetResult(interp,(char*)"1",TCL_STATIC); + } else { + Tcl_SetResult(interp,(char*)"0",TCL_STATIC); + } + return TCL_OK; + } + } else if (strcmp(method, "configure") == 0) { + int i; + if (objc < 4) { + Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC); + return TCL_ERROR; + } + i = 2; + while (i < objc) { + attrname = Tcl_GetStringFromObj(objv[i],NULL); + attr = cls->attributes; + while (attr && attr->name) { + if ((strcmp(attr->name, attrname) == 0) && (attr->setmethod)) { + oldarg = objv[i]; + objv[i] = inst->thisptr; + Tcl_IncrRefCount(inst->thisptr); + rcode = (*attr->setmethod)(clientData,interp,3, &objv[i-1]); + objv[i] = oldarg; + Tcl_DecrRefCount(inst->thisptr); + if (rcode != TCL_OK) return rcode; + numconf += 2; + } + attr++; + } + i+=2; + } + } + } + if (strcmp(method,"configure") == 0) { + if (numconf >= objc) { + return TCL_OK; + } else { + Tcl_SetResult(interp,(char *) "Invalid attribute name.", TCL_STATIC); + return TCL_ERROR; + } + } + if (strcmp(method,"cget") == 0) { + Tcl_SetResult(interp,(char *) "Invalid attribute name.", TCL_STATIC); + return TCL_ERROR; + } + + Tcl_SetResult(interp, (char *) "Invalid method. Must be one of: configure cget -acquire -disown -delete", TCL_STATIC); + cls = inst->classptr; + bi = 0; + while (cls) { + meth = cls->methods; + while (meth && meth->name) { + char *cr = (char *) Tcl_GetStringResult(interp); + if (!strstr(strchr(cr,':'), meth->name)) + Tcl_AppendElement(interp, (char *) meth->name); + meth++; + } + cls = inst->classptr->bases[bi++]; + } + return TCL_ERROR; +} + +/* Function to create objects */ +SWIGRUNTIME(int) +SWIG_ObjectConstructor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + Tcl_Obj *newObj = 0; + void *thisvalue = 0; + swig_instance *newinst = 0; + swig_class *classptr = (swig_class *) clientData; + swig_wrapper cons = 0; + char *name = 0; + int firstarg = 0; + int thisarg = 0; + int destroy = 1; + + if (!classptr) { + Tcl_SetResult(interp, (char *) "swig: internal runtime error. No class object defined.", TCL_STATIC); + return TCL_ERROR; + } + cons = classptr->constructor; + if (objc > 1) { + char *s = Tcl_GetStringFromObj(objv[1],NULL); + if (strcmp(s,"-this") == 0) { + thisarg = 2; + cons = 0; + } else if (strcmp(s,"-args") == 0) { + firstarg = 1; + } else if (objc == 2) { + firstarg = 1; + name = s; + } else if (objc >= 3) { + char *s1; + name = s; + s1 = Tcl_GetStringFromObj(objv[2],NULL); + if (strcmp(s1,"-this") == 0) { + thisarg = 3; + cons = 0; + } else { + firstarg = 1; + } + } + } + if (cons) { + int result; + result = (*cons)(0, interp, objc-firstarg, &objv[firstarg]); + if (result != TCL_OK) { + return result; + } + newObj = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + if (!name) name = Tcl_GetStringFromObj(newObj,NULL); + } else if (thisarg > 0) { + if (thisarg < objc) { + destroy = 0; + newObj = Tcl_DuplicateObj(objv[thisarg]); + if (!name) name = Tcl_GetStringFromObj(newObj,NULL); + } else { + Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC); + return TCL_ERROR; + } + } else { + Tcl_SetResult(interp, (char *) "No constructor available.", TCL_STATIC); + return TCL_ERROR; + } + if (SWIG_ConvertPtr(interp,newObj, (void **) &thisvalue, *(classptr->type), SWIG_POINTER_EXCEPTION) == TCL_ERROR) { + Tcl_DecrRefCount(newObj); + return TCL_ERROR; + } + newinst = (swig_instance *) malloc(sizeof(swig_instance)); + newinst->thisptr = newObj; + Tcl_IncrRefCount(newObj); + newinst->thisvalue = thisvalue; + newinst->classptr = classptr; + newinst->destroy = destroy; + if (destroy) { + SWIG_Acquire(thisvalue); + } + newinst->cmdtok = Tcl_CreateObjCommand(interp,name, (swig_wrapper) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete); + return TCL_OK; +} + + +/* This function takes the current result and turns it into an object command */ +SWIGRUNTIME(Tcl_Obj *) +SWIG_NewInstanceObj(Tcl_Interp *interp, void *thisvalue, swig_type_info *type, int flags) { + Tcl_Obj *robj = SWIG_NewPointerObj(thisvalue, type,0); + /* Check to see if this pointer belongs to a class or not */ + if ((type->clientdata) && (interp)) { + Tcl_CmdInfo ci; + char *name; + name = Tcl_GetStringFromObj(robj,NULL); + if (!Tcl_GetCommandInfo(interp,name, &ci) || (flags)) { + swig_instance *newinst = (swig_instance *) malloc(sizeof(swig_instance)); + newinst->thisptr = Tcl_DuplicateObj(robj); + Tcl_IncrRefCount(newinst->thisptr); + newinst->thisvalue = thisvalue; + newinst->classptr = (swig_class *) type->clientdata; + newinst->destroy = flags; + newinst->cmdtok = Tcl_CreateObjCommand(interp, Tcl_GetStringFromObj(robj,NULL), (swig_wrapper_func) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete); + if (flags) { + SWIG_Acquire(thisvalue); + } + } + } + return robj; +} + #endif /* Structure for command table */ @@ -228,8 +758,10 @@ typedef struct { char * (*set)(ClientData, Tcl_Interp *, char *, char *, int); } swig_var_info; - #ifdef __cplusplus } #endif + + + diff --git a/Lib/tcl/tcl8.swg b/Lib/tcl/tcl8.swg index eeb7f2af4..3afb0b9dc 100644 --- a/Lib/tcl/tcl8.swg +++ b/Lib/tcl/tcl8.swg @@ -4,5 +4,595 @@ * Tcl8 configuration module. * ----------------------------------------------------------------------------- */ -%insert(runtime) "common.swg"; -%insert(runtime) "swigtcl8.swg"; +%runtime "common.swg" +%runtime "swigtcl8.swg" + +/* ----------------------------------------------------------------------------- + * --- standard typemaps --- + * ----------------------------------------------------------------------------- */ + +/* Input arguments */ + +/* For primitive types, the Tcl module uses a special function + + SWIG_GetArgs(Tcl_Interp *, int objc, Tcl_Obj *CONST objv[], const char *fmt, ...) + + The fmt field contains special conversion characters i,h,l,b,f,d,c,p, and o + that are used to marshal different types. The parse codes below correspond + to these special codes */ + +%typemap(in,parse="i") int, unsigned int ""; +%typemap(in,parse="h") short, unsigned short ""; +%typemap(in,parse="l") long, unsigned long ""; +%typemap(in,parse="b") signed char, unsigned char ""; +%typemap(in,parse="f") float ""; +%typemap(in,parse="d") double ""; +%typemap(in,parse="c") char ""; +%typemap(in,parse="s") char *, char [ANY] ""; + +/* Pointers */ +%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + "if ((SWIG_ConvertPtr(interp, $input, (void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION | $disown) != TCL_OK)) SWIG_fail;"; + + +/* For bools, we first convert to an integer and then to a bool. There + is no guarantee that a bool is the same size as an int so we have to do this */ + +%typemap(in) bool (int tempb) "if (Tcl_GetIntFromObj(interp,$input,&tempb) == TCL_ERROR) SWIG_fail; + $1 = (bool) tempb;"; + +/* These will pass an integer as an unsigned long. However, the implementation is crippled due + to limited precision in Tcl */ + +%typemap(in) long long "$1 = (long long) strtoll(Tcl_GetStringFromObj($input,NULL),0,0);"; +%typemap(in) unsigned long long "$1 = (unsigned long long) strtoull(Tcl_GetStringFromObj($input,NULL), 0, 0);"; + +/* Enum parsing. Note: internally SWIG converts enums to/from integers so it's okay to use + the "i" parse code here */ + +%typemap(in,parse="i") enum SWIGTYPE ""; + +/* Unknown type. We convert from a pointer */ +%typemap(in) SWIGTYPE ($&1_ltype argp) + "if ((SWIG_ConvertPtr(interp, $input, (void **) &argp, $&1_descriptor,SWIG_POINTER_EXCEPTION ) != TCL_OK)) SWIG_fail; + $1 = *argp; "; + + + +/* Special constant variations. These typemaps can be used to parse objects that are both constants + or values. A Hash table lookup will occur. */ + +%typemap(in,parse="I") int CONSTANT, unsigned int CONSTANT ""; +%typemap(in,parse="H") short CONSTANT, unsigned short CONSTANT ""; +%typemap(in,parse="L") long CONSTANT, unsigned long CONSTANT ""; +%typemap(in,parse="B") signed char CONSTANT, unsigned char CONSTANT ""; +%typemap(in,parse="F") float CONSTANT ""; +%typemap(in,parse="D") double CONSTANT ""; +%typemap(in,parse="C") char CONSTANT ""; +%typemap(in,parse="S") char * CONSTANT ""; +%typemap(in,parse="P") SWIGTYPE *CONSTANT, SWIGTYPE &CONSTANT, SWIGTYPE CONSTANT [] ""; +%typemap(in,parse="I") enum SWIGTYPE CONSTANT ""; + +/* Constant references. Passed by value */ +/* Const primitive references. Passed by value */ + +%typemap(in) const int & (int temp), + const short & (short temp), + const long & (long temp), + const unsigned int & (unsigned int temp), + const unsigned short & (unsigned short temp), + const unsigned long & (unsigned long temp), + const signed char & (signed char temp), + const unsigned char & (unsigned char temp), + const bool & (bool temp) +{ + long ltemp; + if (Tcl_GetLongFromObj(interp, $input, <emp) != TCL_OK) { + SWIG_fail; + } + temp = ($*1_ltype) ltemp; + $1 = &temp; +} + +%typemap(in) const float & (float temp), + const double & (double temp) +{ + double dtemp; + if (Tcl_GetDoubleFromObj(interp, $input, &dtemp) != TCL_OK) { + SWIG_fail; + } + temp = ($*1_ltype) dtemp; + $1 = &temp; +} + +%typemap(in) const long long & (long long temp) + "temp = (long long) strtoll(Tcl_GetStringFromObj($input,NULL),0,0); + $1 = &temp;"; + +%typemap(in) const unsigned long long & (unsigned long long temp) + "temp = (unsigned long long) strtoull(Tcl_GetStringFromObj($input,NULL),0,0); + $1 = &temp;"; + +%typemap(in) const char &(char temp) { + char *stemp = Tcl_GetStringFromObj($input,NULL); + temp = *stemp; + $1 = &temp; +} + +/* Output values */ + +%typemap(out) bool, int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE + "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) $1));"; + +%typemap(out) long long { + char temp[256]; + sprintf(temp,"%lld", $1); + Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); +} + +%typemap(out) unsigned long long { + char temp[256]; + sprintf(temp,"%llu", $1); + Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); +} + +%typemap(out) char + "Tcl_SetObjResult(interp,Tcl_NewStringObj(&$1,1));"; + +%typemap(out) float, double + "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) $1));"; + +%typemap(out) char * + "Tcl_SetObjResult(interp,Tcl_NewStringObj($1,-1));"; + +%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) $1, $1_descriptor,0));"; + +%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { + swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); + Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) $1, ty,0)); +} + +%typemap(out) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] + "Tcl_SetObjResult(interp,SWIG_NewInstanceObj(interp, (void *) $1, $1_descriptor,0));"; + +%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + "Tcl_SetObjResult(interp,SWIG_NewInstanceObj(interp, (void *) $1, $1_descriptor,0));"; + +%typemap(out) void ""; + +/* Primitive types--return by value */ +%typemap(out) SWIGTYPE NOINSTANCE +#ifdef __cplusplus +{ + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + Tcl_SetObjResult(interp,SWIG_NewPointerObj((void*) resultptr, $&1_descriptor,0)); +} +#else +{ + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + Tcl_SetObjResult(interp,SWIG_NewPointerObj((void*) resultptr, $&1_descriptor,0)); +} +#endif + +/* Primitive types--return by value */ +%typemap(out) SWIGTYPE INSTANCE +#ifdef __cplusplus +{ + $&1_ltype resultptr; + resultptr = new $1_ltype(($1_ltype &) $1); + Tcl_SetObjResult(interp,SWIG_NewInstanceObj(interp,(void*) resultptr, $&1_descriptor,1)); +} +#else +{ + $&1_ltype resultptr; + resultptr = ($&1_ltype) malloc(sizeof($1_type)); + memmove(resultptr, &$1, sizeof($1_type)); + Tcl_SetObjResult(interp,SWIG_NewInstanceObj(interp,(void*) resultptr, $&1_descriptor,1)); +} +#endif + +%typemap(out) SWIGTYPE = SWIGTYPE INSTANCE; + +/* Special typemap for character array returns */ +%typemap(out) char [ANY] "Tcl_SetObjResult(interp,Tcl_NewStringObj($1,-1));" + + +/* Primitive references */ + +%typemap(out) const int &, const unsigned int &, + const short &, const unsigned short &, + const long &, const unsigned long &, + const signed char &, const unsigned char &, + const bool & + "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) *($1)));"; + +%typemap(out) const float &, const double & + "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) *($1)));"; + +%typemap(out) const long long & { + char temp[256]; + sprintf(temp,"%lld", *($1)); + Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); +} + +%typemap(out) const unsigned long long & +{ + char temp[256]; + sprintf(temp,"%llu", *($1)); + Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); +} + +%typemap(out) const char & + "Tcl_SetObjResult(interp,Tcl_NewStringObj($1,1));"; + + +/* --- Variable output --- */ + +%typemap(varout) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE + "$result = Tcl_NewIntObj((long) $1);"; + +%typemap(varout) long long { + char temp[256]; + sprintf(temp,"%lld", $1); + $result = Tcl_NewStringObj(temp,-1); +} + +%typemap(varout) unsigned long long { + char temp[256]; + sprintf(temp,"%llu", $1); + $result = Tcl_NewStringObj(temp,-1); +} + +%typemap(varout) double,float "$result = Tcl_NewDoubleObj((double) $1);"; +%typemap(varout) char * "$result = Tcl_NewStringObj((char*) $1,-1);"; +%typemap(varout) char [ANY] "$result = Tcl_NewStringObj((char *) $1,-1);"; +%typemap(varout) char "$result = Tcl_NewStringObj(&$1,1);"; +%typemap(varout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor,0);"; + +%typemap(varout) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] + "$result = SWIG_NewInstanceObj(interp, (void *) $1, $1_descriptor,0);"; + +%typemap(varout) SWIGTYPE "$result = SWIG_NewPointerObj((void *) &$1, $&1_descriptor,0);"; +%typemap(varout) SWIGTYPE INSTANCE "$result = SWIG_NewInstanceObj(interp, (void *) &$1, $&1_descriptor,0);"; +%typemap(varout) SWIGTYPE "$result = SWIG_NewInstanceObj(interp, (void *) &$1, $&1_descriptor,0);"; + +/* -- Variable input --- */ + +%typemap(varin) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE +{ + long temp; + if (Tcl_GetLongFromObj(interp, $input, &temp) != TCL_OK) { + return (char*) "Type error. expected an integer"; + } + $1 = ($1_type) temp; +} + +%typemap(varin) long long "$1 = (long long) strtoll(Tcl_GetStringFromObj($input,NULL),0,0);"; +%typemap(varin) unsigned long long "$1 = (unsigned long long) strtoull(Tcl_GetStringFromObj($input,NULL),0,0);"; + +%typemap(varin) double, float { + double temp; + if (Tcl_GetDoubleFromObj(interp, $input, &temp) != TCL_OK) { + return (char*) "Type error. expected a double."; + } + $1 = ($1_type) temp; +} + +%typemap(varin) char * +#ifdef __cplusplus +{ + char *temp = Tcl_GetStringFromObj($input,NULL); + if ($1) delete [] $1; + $1 = ($1_type) new char[strlen(temp)+1]; + strcpy((char *) $1,temp); +} +#else +{ + char *temp = Tcl_GetStringFromObj($input,NULL); + if ($1) free((char*)$1); + $1 = ($1_type) malloc(strlen(temp)+1); + strcpy((char *) $1,temp); +} +#endif + +%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * +#ifdef __cplusplus +{ + char *temp = Tcl_GetStringFromObj($input,NULL); + $1 = ($1_type) new char[strlen(temp)+1]; + strcpy((char *) $1,temp); +} +#else +{ + char *temp = Tcl_GetStringFromObj($input,NULL); + $1 = ($1_type) malloc(strlen(temp)+1); + strcpy((char *) $1,temp); +} +#endif + +%typemap(varin) char [ANY] { + char *temp = Tcl_GetStringFromObj($input,NULL); + strncpy((char*)$1,temp,$1_dim0); +} + +%typemap(varin) char +{ + char *temp = Tcl_GetStringFromObj($input,NULL); + $1 = *temp; +} + +%typemap(varin) SWIGTYPE * { + void *temp; + if (SWIG_ConvertPtr(interp,$input,&temp,$1_descriptor, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN) != TCL_OK) { + return (char*)"Type error. Expected $1_ltype"; + } + $1 = ($1_type) temp; +} + +%typemap(varin) void * { + void *temp; + if (SWIG_ConvertPtr(interp,$input,&temp,0, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN) != TCL_OK) { + return (char*)"Type error. Expected $1_ltype"; + } + $1 = ($1_type) temp; +} + +%typemap(varin) SWIGTYPE & { + void *temp; + if (SWIG_ConvertPtr(interp,$input,&temp,$1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { + return (char*)"Type error. Expected $1_ltype"; + } + $1 = *(($&1_type) temp); +} + +%typemap(varin) SWIGTYPE { + void *temp; + if (SWIG_ConvertPtr(interp,$input,&temp,$&1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { + return (char*)"Type error. Expected $&1_ltype"; + } + $1 = *(($&1_type) temp); +} + +%typemap(varin) SWIGTYPE [] { + void *temp; + if (SWIG_ConvertPtr(interp,$input,&temp,$1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { + return (char *)"Type error. Expected $1_ltype"; + } + memmove((void *) $1,temp,$1_size*sizeof($1_basetype)); +} + +/* --- Constants --- */ + +%typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE + { SWIG_TCL_INT, (char *)"$symname", (long) $value, 0, 0, 0} + +%typemap(consttab) float, double + { SWIG_TCL_FLOAT, (char*)"$symname", 0, (double) $value, 0, 0} + +%typemap(consttab) char, char * + { SWIG_TCL_STRING, (char*)"$symname", 0, 0, (void *)"$value", 0} + +%typemap(consttab) long long, unsigned long long + { SWIG_TCL_STRING, (char *) "$symname", 0, 0, (void *)"$value", 0} + +%typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] + { SWIG_TCL_POINTER, (char*)"$symname", 0, 0, (void *)$value, &$1_descriptor} + +%typemap(consttab) SWIGTYPE (CLASS::*) + { SWIG_TCL_BINARY, (char *)"$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor} + + + + +/* ------------------------------------------------------------ + * String & length + * ------------------------------------------------------------ */ + +%typemap(in) (char *STRING, int LENGTH) { + int temp; + $1 = ($1_ltype) Tcl_GetStringFromObj($input,&temp); + $2 = ($2_ltype) temp; +} + +/* ------------------------------------------------------------ + * ANSI C typemaps + * ------------------------------------------------------------ */ + +%typemap(in) size_t (int temp) "if (Tcl_GetIntFromObj(interp,$input,&temp) == TCL_ERROR) return TCL_ERROR; + $1 = (size_t) temp;"; + +%typemap(out) size_t = long; +%typemap(varin) size_t = long; +%typemap(varout) size_t = long; +%typemap(consttab) size_t = long; + + + +/* ------------------------------------------------------------ + * Typechecking rules + * ------------------------------------------------------------ */ + +%typecheck(SWIG_TYPECHECK_INTEGER) + int, short, long, + unsigned int, unsigned short, unsigned long, + signed char, unsigned char, + long long, unsigned long long, + const int &, const short &, const long &, + const unsigned int &, const unsigned short &, const unsigned long &, + const long long &, const unsigned long long &, + enum SWIGTYPE, + bool, const bool & +{ + long tmp; + if (Tcl_GetLongFromObj(NULL,$input,&tmp) == TCL_ERROR) $1 = 0; + else $1 = 1; +} + +%typecheck(SWIG_TYPECHECK_DOUBLE) + float, double, + const float &, const double & +{ + double tmp; + if (Tcl_GetDoubleFromObj(NULL,$input,&tmp) == TCL_ERROR) $1 = 0; + else $1 = 1; +} + +%typecheck(SWIG_TYPECHECK_CHAR) char { + char *tmp; + int len; + tmp = Tcl_GetStringFromObj($input,&len); + (len == 1) ? 1 : 0; +} + +%typecheck(SWIG_TYPECHECK_STRING) char * { + $1 = 1; +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { + void *ptr; + if (SWIG_ConvertPtr(interp, $input, (void **) &ptr, $1_descriptor, 0) == TCL_ERROR) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { + void *ptr; + if (SWIG_ConvertPtr(interp, $input, (void **) &ptr, $&1_descriptor, 0) == TCL_ERROR) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_VOIDPTR) void * { + void *ptr; + if (SWIG_ConvertPtr(interp, $input, (void **) &ptr, 0, 0) == TCL_ERROR) { + $1 = 0; + } else { + $1 = 1; + } +} + +/* ------------------------------------------------------------ + * Exception handling + * ------------------------------------------------------------ */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + Tcl_SetObjResult(interp, Tcl_NewIntObj((long) $1)); + SWIG_fail; +} + +%typemap(throws) SWIGTYPE CLASS { + $&1_ltype temp = new $1_ltype($1); + Tcl_SetObjResult(interp, SWIG_NewInstanceObj(interp, (void *) temp, $&1_descriptor, 1)); + SWIG_fail; +} + +%typemap(throws) SWIGTYPE { + Tcl_SetObjResult(interp, Tcl_NewStringObj((char*) "$1_type", -1)); + SWIG_fail; +} + +%typemap(throws) char * { + Tcl_SetObjResult(interp, Tcl_NewStringObj((char*) $1, -1)); + SWIG_fail; +} + +// Some special reserved words in classes + +%namewarn("314:cget is a reserved method name") *::cget; +%namewarn("314:configure is a reserved method name") *::configure; + +/* C++ overloaded operators. + + These declarations define how SWIG is going to rename C++ + overloaded operators in Tcl. Since Tcl allows identifiers + to be essentially any valid string, we'll just use the + normal operator names */ + +#ifdef __cplusplus +%rename("+") *::operator+; +//%rename("u+") *::operator+(); // Unary + +//%rename("u+") *::operator+() const; // Unary + +%rename("-") *::operator-; +//%rename("u-") *::operator-(); // Unary - +//%rename("u-") *::operator-() const; // Unary - +%rename("*") *::operator*; +%rename("/") *::operator/; +%rename("<<") *::operator<<; +%rename(">>") *::operator>>; +%rename("&") *::operator&; +%rename("|") *::operator|; +%rename("^") *::operator^; +%rename("%") *::operator%; +%rename("=") *::operator=; +#endif + + +/* This initialization code exports the module initialization function */ + +%header %{ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef MAC_TCL +#pragma export on +#endif +SWIGEXPORT(int) SWIG_init(Tcl_Interp *); +#ifdef MAC_TCL +#pragma export off +#endif +#ifdef __cplusplus +} +#endif + +%} + +/* Start the initialization function */ + +%init %{ +SWIGEXPORT(int) SWIG_init(Tcl_Interp *interp) { + int i; + static int _init = 0; + if (interp == 0) return TCL_ERROR; +#ifdef USE_TCL_STUBS + if (Tcl_InitStubs(interp, (char*)"8.1", 0) == NULL) { + return TCL_ERROR; + } +#endif + + Tcl_PkgProvide(interp, (char*)SWIG_name, (char*)SWIG_version); + +#ifdef SWIG_namespace + Tcl_Eval(interp, "namespace eval " SWIG_namespace " { }"); +#endif + if (!_init) { + for (i = 0; swig_types_initial[i]; i++) { + swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); + } + _init = 1; + } + for (i = 0; swig_commands[i].name; i++) { + Tcl_CreateObjCommand(interp, (char *) swig_commands[i].name, (swig_wrapper_func) swig_commands[i].wrapper, swig_commands[i].clientdata, NULL); + } + for (i = 0; swig_variables[i].name; i++) { + Tcl_SetVar(interp, (char *) swig_variables[i].name, (char *) "", TCL_GLOBAL_ONLY); + Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_READS | TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) swig_variables[i].get, (ClientData) swig_variables[i].addr); + Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) swig_variables[i].set, (ClientData) swig_variables[i].addr); + } + SWIG_InstallConstants(interp, swig_constants); +%} + +/* Note: the initialization function is closed after all code is generated */ diff --git a/Lib/tcl/tclsh.i b/Lib/tcl/tclsh.i index 839de3be9..6301b2024 100644 --- a/Lib/tcl/tclsh.i +++ b/Lib/tcl/tclsh.i @@ -48,12 +48,12 @@ int Tcl_AppInit(Tcl_Interp *interp){ if (SWIG_init(interp) == TCL_ERROR) return TCL_ERROR; #if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5 - Tcl_SetVar(interp,"tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); #else tcl_RcFileName = SWIG_RcFileName; #endif #ifdef SWIG_RcRsrcName - Tcl_SetVar(interp,"tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL); + Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL); #endif return TCL_OK; diff --git a/Lib/tcl/typemaps.i b/Lib/tcl/typemaps.i index e0e7101f8..9b2e33758 100644 --- a/Lib/tcl/typemaps.i +++ b/Lib/tcl/typemaps.i @@ -8,35 +8,19 @@ * * ----------------------------------------------------------------------------- */ -#ifdef AUTODOC -%section "Typemap Library (Tcl)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 -%text %{ -%include typemaps.i - +/* The SWIG typemap library provides a language independent mechanism for supporting output arguments, input values, and other C function calling mechanisms. The primary use of the library is to provide a better interface to certain C function--especially those involving pointers. -%} - -#endif - -// ------------------------------------------------------------------------ -// Pointer handling -// -// These mappings provide support for input/output arguments and common -// uses for C/C++ pointers. -// ------------------------------------------------------------------------ +*/ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. -#ifdef AUTODOC -%subsection "Input Methods" - -%text %{ +/* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. @@ -68,97 +52,116 @@ or you can use the %apply directive : %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); -%} -#endif +*/ -%typemap(tcl8,in) double *INPUT(double temp) +%typemap(in) double *INPUT(double temp), double &INPUT(double temp) { - if (Tcl_GetDoubleFromObj(interp,$source,&temp) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetDoubleFromObj(interp,$input,&temp) == TCL_ERROR) { + SWIG_fail; } - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) float *INPUT(double dvalue, float temp) +%typemap(in) float *INPUT(double dvalue, float temp), float &INPUT(double dvalue, float temp) { - if (Tcl_GetDoubleFromObj(interp,$source,&dvalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetDoubleFromObj(interp,$input,&dvalue) == TCL_ERROR) { + SWIG_fail; } temp = (float) dvalue; - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) int *INPUT(int temp) +%typemap(in) int *INPUT(int temp), int &INPUT(int temp) { - if (Tcl_GetIntFromObj(interp,$source,&temp) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&temp) == TCL_ERROR) { + SWIG_fail; } - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) short *INPUT(int ivalue, short temp) +%typemap(in) short *INPUT(int ivalue, short temp), short &INPUT(int ivalue, short temp) { - if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; } temp = (short) ivalue; - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) long *INPUT(int ivalue, long temp) +%typemap(in) long *INPUT(int ivalue, long temp), long &INPUT(int ivalue, long temp) { - if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; } temp = (long) ivalue; - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) unsigned int *INPUT(int ivalue, unsigned int temp) +%typemap(in) unsigned int *INPUT(int ivalue, unsigned int temp), + unsigned int &INPUT(int ivalue, unsigned int temp) { - if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; } temp = (unsigned int) ivalue; - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) unsigned short *INPUT(int ivalue, unsigned short temp) +%typemap(in) unsigned short *INPUT(int ivalue, unsigned short temp), + unsigned short &INPUT(int ivalue, unsigned short temp) { - if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; } temp = (unsigned short) ivalue; - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) unsigned long *INPUT(int ivalue, unsigned long temp) +%typemap(in) unsigned long *INPUT(int ivalue, unsigned long temp), + unsigned long &INPUT(int ivalue, unsigned long temp) { - if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; } temp = (unsigned long) ivalue; - $target = &temp; + $1 = &temp; } -%typemap(tcl8,in) unsigned char *INPUT(int ivalue, unsigned char temp) +%typemap(in) unsigned char *INPUT(int ivalue, unsigned char temp), + unsigned char &INPUT(int ivalue, unsigned char temp) { - if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { - return TCL_ERROR; + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; } temp = (unsigned char) ivalue; - $target = &temp; + $1 = &temp; +} + +%typemap(in) signed char *INPUT(int ivalue, signed char temp), + signed char &INPUT(int ivalue, signed char temp) +{ + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; + } + temp = (signed char) ivalue; + $1 = &temp; +} + +%typemap(in) bool *INPUT(int ivalue, bool temp), + bool &INPUT(int ivalue, bool temp) +{ + if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { + SWIG_fail; + } + temp = (bool) ivalue; + $1 = &temp; } // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. - -#ifdef AUTODOC -%subsection "Output Methods" - -%text %{ +/* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of @@ -194,67 +197,74 @@ or you can use the %apply directive : The Tcl output of the function would be a list containing both output values. -%} +*/ -#endif - - -%typemap(tcl8,ignore) int *OUTPUT(int temp), +%typemap(in,numinputs=0) int *OUTPUT(int temp), short *OUTPUT(short temp), long *OUTPUT(long temp), unsigned int *OUTPUT(unsigned int temp), unsigned short *OUTPUT(unsigned short temp), unsigned long *OUTPUT(unsigned long temp), unsigned char *OUTPUT(unsigned char temp), + signed char *OUTPUT(signed char temp), + bool *OUTPUT(bool temp), float *OUTPUT(float temp), - double *OUTPUT(double temp) -{ - $target = &temp; -} + double *OUTPUT(double temp), + int &OUTPUT(int temp), + short &OUTPUT(short temp), + long &OUTPUT(long temp), + unsigned int &OUTPUT(unsigned int temp), + unsigned short &OUTPUT(unsigned short temp), + unsigned long &OUTPUT(unsigned long temp), + signed char &OUTPUT(signed char temp), + bool &OUTPUT(bool temp), + unsigned char &OUTPUT(unsigned char temp), + float &OUTPUT(float temp), + double &OUTPUT(double temp) +"$1 = &temp;"; -%typemap(tcl8,argout) int *OUTPUT, - short *OUTPUT, - long *OUTPUT, - unsigned int *OUTPUT, - unsigned short *OUTPUT, - unsigned long *OUTPUT, - unsigned char *OUTPUT +%typemap(argout) int *OUTPUT, int &OUTPUT, + short *OUTPUT, short &OUTPUT, + long *OUTPUT, long &OUTPUT, + unsigned int *OUTPUT, unsigned int &OUTPUT, + unsigned short *OUTPUT, unsigned short &OUTPUT, + unsigned long *OUTPUT, unsigned long &OUTPUT, + unsigned char *OUTPUT, unsigned char &OUTPUT, + signed char *OUTPUT, signed char &OUTPUT, + bool *OUTPUT, bool &OUTPUT { Tcl_Obj *o; - o = Tcl_NewIntObj((int) *($source)); + o = Tcl_NewIntObj((int) *($1)); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); } -%typemap(tcl8,argout) float *OUTPUT, - double *OUTPUT +%typemap(argout) float *OUTPUT, float &OUTPUT, + double *OUTPUT, double &OUTPUT { Tcl_Obj *o; - o = Tcl_NewDoubleObj((double) *($source)); + o = Tcl_NewDoubleObj((double) *($1)); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); } -// BOTH +// INOUT // Mappings for an argument that is both an input and output // parameter -#ifdef AUTODOC -%subsection "Input/Output Methods" - -%text %{ +/* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a Tcl list. - int *BOTH - short *BOTH - long *BOTH - unsigned int *BOTH - unsigned short *BOTH - unsigned long *BOTH - unsigned char *BOTH - float *BOTH - double *BOTH + int *INOUT + short *INOUT + long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned char *INOUT + float *INOUT + double *INOUT For example, suppose you were trying to wrap the following function : @@ -265,12 +275,12 @@ For example, suppose you were trying to wrap the following function : You could wrap it with SWIG as follows : %include typemaps.i - void neg(double *BOTH); + void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i - %apply double *BOTH { double *x }; + %apply double *INOUT { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value (since @@ -280,30 +290,56 @@ to a Tcl variable you might do this : set x [neg $x] -%} - -#endif +*/ -%typemap(tcl8,in) int *BOTH = int *INPUT; -%typemap(tcl8,in) short *BOTH = short *INPUT; -%typemap(tcl8,in) long *BOTH = long *INPUT; -%typemap(tcl8,in) unsigned int *BOTH = unsigned int *INPUT; -%typemap(tcl8,in) unsigned short *BOTH = unsigned short *INPUT; -%typemap(tcl8,in) unsigned long *BOTH = unsigned long *INPUT; -%typemap(tcl8,in) unsigned char *BOTH = unsigned char *INPUT; -%typemap(tcl8,in) float *BOTH = float *INPUT; -%typemap(tcl8,in) double *BOTH = double *INPUT; +%typemap(in) int *INOUT = int *INPUT; +%typemap(in) short *INOUT = short *INPUT; +%typemap(in) long *INOUT = long *INPUT; +%typemap(in) unsigned int *INOUT = unsigned int *INPUT; +%typemap(in) unsigned short *INOUT = unsigned short *INPUT; +%typemap(in) unsigned long *INOUT = unsigned long *INPUT; +%typemap(in) unsigned char *INOUT = unsigned char *INPUT; +%typemap(in) signed char *INOUT = signed char *INPUT; +%typemap(in) bool *INOUT = bool *INPUT; +%typemap(in) float *INOUT = float *INPUT; +%typemap(in) double *INOUT = double *INPUT; -%typemap(tcl8,argout) int *BOTH = int *OUTPUT; -%typemap(tcl8,argout) short *BOTH = short *OUTPUT; -%typemap(tcl8,argout) long *BOTH = long *OUTPUT; -%typemap(tcl8,argout) unsigned int *BOTH = unsigned int *OUTPUT; -%typemap(tcl8,argout) unsigned short *BOTH = unsigned short *OUTPUT; -%typemap(tcl8,argout) unsigned long *BOTH = unsigned long *OUTPUT; -%typemap(tcl8,argout) unsigned char *BOTH = unsigned char *OUTPUT; -%typemap(tcl8,argout) float *BOTH = float *OUTPUT; -%typemap(tcl8,argout) double *BOTH = double *OUTPUT; +%typemap(in) int &INOUT = int &INPUT; +%typemap(in) short &INOUT = short &INPUT; +%typemap(in) long &INOUT = long &INPUT; +%typemap(in) unsigned int &INOUT = unsigned int &INPUT; +%typemap(in) unsigned short &INOUT = unsigned short &INPUT; +%typemap(in) unsigned long &INOUT = unsigned long &INPUT; +%typemap(in) unsigned char &INOUT = unsigned char &INPUT; +%typemap(in) signed char &INOUT = signed char &INPUT; +%typemap(in) bool &INOUT = bool &INPUT; +%typemap(in) float &INOUT = float &INPUT; +%typemap(in) double &INOUT = double &INPUT; + +%typemap(argout) int *INOUT = int *OUTPUT; +%typemap(argout) short *INOUT = short *OUTPUT; +%typemap(argout) long *INOUT = long *OUTPUT; +%typemap(argout) unsigned int *INOUT = unsigned int *OUTPUT; +%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; +%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; +%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; +%typemap(argout) signed char *INOUT = signed char *OUTPUT; +%typemap(argout) bool *INOUT = bool *OUTPUT; +%typemap(argout) float *INOUT = float *OUTPUT; +%typemap(argout) double *INOUT = double *OUTPUT; + +%typemap(argout) int &INOUT = int &OUTPUT; +%typemap(argout) short &INOUT = short &OUTPUT; +%typemap(argout) long &INOUT = long &OUTPUT; +%typemap(argout) unsigned int &INOUT = unsigned int &OUTPUT; +%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; +%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; +%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; +%typemap(argout) signed char &INOUT = signed char &OUTPUT; +%typemap(argout) bool &INOUT = bool &OUTPUT; +%typemap(argout) float &INOUT = float &OUTPUT; +%typemap(argout) double &INOUT = double &OUTPUT; // -------------------------------------------------------------------- // Special types @@ -312,10 +348,7 @@ to a Tcl variable you might do this : // If interp * appears as a function argument, we ignore it and get // it from the wrapper function. -#ifdef AUTODOC -%subsection "Special Methods" - -%text %{ +/* The typemaps.i library also provides the following mappings : Tcl_Interp *interp @@ -343,20 +376,67 @@ int Tcl_Result %apply int Tcl_Result { int foo }; int foo(); -%} +*/ -#endif - -%typemap(tcl8,ignore) Tcl_Interp *interp { - $target = interp; +%typemap(in,numinputs=0) Tcl_Interp *interp { + $1 = interp; } // If return code is a Tcl_Result, simply pass it on -%typemap(tcl8,out) int Tcl_Result { - return $source; +%typemap(out) int Tcl_Result { + return $1; } +/* Overloading information */ + +%typemap(typecheck) double *INPUT = double; +%typemap(typecheck) bool *INPUT = bool; +%typemap(typecheck) signed char *INPUT = signed char; +%typemap(typecheck) unsigned char *INPUT = unsigned char; +%typemap(typecheck) unsigned long *INPUT = unsigned long; +%typemap(typecheck) unsigned short *INPUT = unsigned short; +%typemap(typecheck) unsigned int *INPUT = unsigned int; +%typemap(typecheck) long *INPUT = long; +%typemap(typecheck) short *INPUT = short; +%typemap(typecheck) int *INPUT = int; +%typemap(typecheck) float *INPUT = float; + +%typemap(typecheck) double &INPUT = double; +%typemap(typecheck) bool &INPUT = bool; +%typemap(typecheck) signed char &INPUT = signed char; +%typemap(typecheck) unsigned char &INPUT = unsigned char; +%typemap(typecheck) unsigned long &INPUT = unsigned long; +%typemap(typecheck) unsigned short &INPUT = unsigned short; +%typemap(typecheck) unsigned int &INPUT = unsigned int; +%typemap(typecheck) long &INPUT = long; +%typemap(typecheck) short &INPUT = short; +%typemap(typecheck) int &INPUT = int; +%typemap(typecheck) float &INPUT = float; + +%typemap(typecheck) double *INOUT = double; +%typemap(typecheck) bool *INOUT = bool; +%typemap(typecheck) signed char *INOUT = signed char; +%typemap(typecheck) unsigned char *INOUT = unsigned char; +%typemap(typecheck) unsigned long *INOUT = unsigned long; +%typemap(typecheck) unsigned short *INOUT = unsigned short; +%typemap(typecheck) unsigned int *INOUT = unsigned int; +%typemap(typecheck) long *INOUT = long; +%typemap(typecheck) short *INOUT = short; +%typemap(typecheck) int *INOUT = int; +%typemap(typecheck) float *INOUT = float; + +%typemap(typecheck) double &INOUT = double; +%typemap(typecheck) bool &INOUT = bool; +%typemap(typecheck) signed char &INOUT = signed char; +%typemap(typecheck) unsigned char &INOUT = unsigned char; +%typemap(typecheck) unsigned long &INOUT = unsigned long; +%typemap(typecheck) unsigned short &INOUT = unsigned short; +%typemap(typecheck) unsigned int &INOUT = unsigned int; +%typemap(typecheck) long &INOUT = long; +%typemap(typecheck) short &INOUT = short; +%typemap(typecheck) int &INOUT = int; +%typemap(typecheck) float &INOUT = float; diff --git a/Lib/tcl/wish.i b/Lib/tcl/wish.i index 201a438b9..183acb149 100644 --- a/Lib/tcl/wish.i +++ b/Lib/tcl/wish.i @@ -7,6 +7,12 @@ // /* Revision History * $Log$ + * Revision 1.2 2002/11/30 22:01:08 beazley + * The great merge + * + * Revision 1.1.2.1 2001/06/20 11:47:29 mkoeppe + * Portability fixes + * * Revision 1.1 2000/01/11 21:15:54 beazley * Added files * @@ -122,7 +128,7 @@ int Tcl_AppInit(Tcl_Interp *interp) */ #if TCL_MAJOR_VERSION >= 8 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5 - Tcl_SetVar(interp,"tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); #else tcl_RcFileName = SWIG_RcFileName; #endif @@ -131,7 +137,7 @@ int Tcl_AppInit(Tcl_Interp *interp) #ifdef MAC_TCL #ifdef SWIG_RcRsrcName - Tcl_SetVar(interp,"tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL_ONLY); #endif #endif return TCL_OK; diff --git a/Lib/timers.i b/Lib/timers.i deleted file mode 100644 index 996408c89..000000000 --- a/Lib/timers.i +++ /dev/null @@ -1,173 +0,0 @@ -// -// $Header$ -// -// timers.i -// A SWIG file for adding various timing functions. -// Really, this is modeled after the timers in the CMMD -// message passing library for the CM-5. -// -// Dave Beazley -// April 2, 1996 -// -/* Revision history - * $Log$ - * Revision 1.1 2000/01/11 21:15:49 beazley - * Added files - * - * Revision 1.1.1.1 1999/02/28 02:00:53 beazley - * Swig1.1 - * - * Revision 1.1 1996/05/22 17:27:01 beazley - * Initial revision - * - */ - -%module timers -%{ - -#include -#define SWIG_NTIMERS 64 - -static clock_t telapsed[SWIG_NTIMERS]; -static clock_t tstart[SWIG_NTIMERS]; -static clock_t tend[SWIG_NTIMERS]; - -/*----------------------------------------------------------------- - * SWIG_timer_clear(int i) - * - * Clears timer i. - *----------------------------------------------------------------- */ - -void -SWIG_timer_clear(int i) -{ - if ((i >= 0) && (i < SWIG_NTIMERS)) - telapsed[i] = 0; -} - - -/*----------------------------------------------------------------- - * SWIG_timer_start(int i) - * - * Starts timer i - *----------------------------------------------------------------- */ - -void -SWIG_timer_start(int i) -{ - if ((i >= 0) && (i < SWIG_NTIMERS)) - tstart[i] = clock(); -} - - -/*----------------------------------------------------------------- - * SWIG_timer_stop(int i) - * - * Stops timer i and accumulates elapsed time - *----------------------------------------------------------------- */ - -void -SWIG_timer_stop(int i) -{ - if ((i >= 0) && (i < SWIG_NTIMERS)) { - tend[i] = clock(); - telapsed[i] += (tend[i] - tstart[i]); - } -} - -/*----------------------------------------------------------------- - * SWIG_timer_elapsed(int i) - * - * Returns the time elapsed on timer i in seconds. - *----------------------------------------------------------------- */ - -double -SWIG_timer_elapsed(int i) -{ - double t; - if ((i >= 0) && (i < SWIG_NTIMERS)) { - t = (double) telapsed[i]/(double) CLOCKS_PER_SEC; - return(t); - } else { - return 0; - } -} - -%} - -%section "Timer Functions",pre,after,chop_left=3,nosort,info,chop_right = 0, chop_top=0,chop_bottom=0 - -%text %{ -%include timers.i - -This module provides a collection of timing functions designed for -performance analysis and benchmarking of different code fragments. - -A total of 64 different timers are available. Each timer can be -managed independently using four functions : - - timer_clear(int n) Clears timer n - timer_start(int n) Start timer n - timer_stop(int n) Stop timer n - timer_elapsed(int n) Return elapsed time (in seconds) - -All timers measure CPU time. - -Since each timer can be accessed independently, it is possible -to use groups of timers for measuring different aspects of code -performance. To use a timer, simply use code like this : -%} - -#if defined(SWIGTCL) -%text %{ - timer_clear 0 - timer_start 0 - .. a bunch of Tcl code ... - timer_stop 0 - puts "[timer_elapsed 0] seconds of CPU time" -%} -#elif defined(SWIGPERL) -%text %{ - timer_clear(0); - timer_start(0); - .. a bunch of Perl code ... - timer_stop(0); - print timer_elapsed(0)," seconds of CPU time\n"; -%} -#elif defined(SWIGPYTHON) -%text %{ - timer_clear(0) - timer_start(0) - ... a bunch of Python code ... - timer_stop(0) - print timer_elapsed(0)," seconds of CPU time" -%} -#endif - -%text %{ -A single timer can be stopped and started repeatedly to provide -a cummulative timing effect. - -As a general performance note, making frequent calls to the timing -functions can severely degrade performance (due to operating system -overhead). The resolution of the timers may be poor for extremely -short code fragments. Therefore, the timers work best for -computationally intensive operations. -%} - - -%name(timer_clear) void SWIG_timer_clear(int n); -/* Clears timer n. */ - -%name(timer_start) void SWIG_timer_start(int n); -/* Starts timer n. */ - -%name(timer_stop) void SWIG_timer_stop(int n); -/* Stops timer n. */ - -%name(timer_elapsed) double SWIG_timer_elapsed(int n); -/* Return the elapsed time (in seconds) of timer n */ - - - - diff --git a/Makefile.in b/Makefile.in index 5a7e0b5ec..3ec6331a3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,57 +15,56 @@ CC = @CC@ CFLAGS = @CFLAGS@ CXX = @CXX@ LIBS = @LIBS@ +SWIGLIBS = @SWIGLIBS@ AR = @AR@ RANLIB = @RANLIB@ -LINKFORSHARED = @LINKFORSHARED@ # Note: Files in `SWIG_LIB' are machine independent so we use `prefix' # instead of `exec_prefix' or, derivatively, `libdir'. -SWIG_LIB = $(prefix)/lib/swig1.3 +SWIG_LIB = @swig_lib@ BIN_DIR = @bindir@ -TARGET = swig +INCLUDE_DIR = $(prefix)/include +RELEASESUFFIX = @release_suffix@ +TARGET = swig$(RELEASESUFFIX) SOURCE = Source SOURCEDIRS = `ls $(SOURCE)` -swig: Modules1.1 Swig Modules Preprocessor LParse DOH +swig: Modules1.1 Swig Preprocessor CParse DOH runtime swig.spec $(CXX) -o $(TARGET) \ - $(SOURCE)/Modules/libmodules.a \ $(SOURCE)/Modules1.1/libmodules11.a \ - $(SOURCE)/LParse/liblparse.a \ + $(SOURCE)/CParse/libcparse.a \ $(SOURCE)/Preprocessor/libcpp.a \ $(SOURCE)/Swig/libswig.a \ - $(SOURCE)/DOH/libdoh.a \ - $(LIBS) + $(SOURCE)/DOH/libdoh.a @SWIGLIBS@ -Modules1.1: +Modules1.1: Source/Include/swigconfig.h @cd $(SOURCE)/Modules1.1; $(MAKE) -Swig: +Swig: Source/Include/swigconfig.h @cd $(SOURCE)/Swig; $(MAKE) -Preprocessor: +Preprocessor: Source/Include/swigconfig.h @cd $(SOURCE)/Preprocessor; $(MAKE) -LParse: - @cd $(SOURCE)/LParse; $(MAKE) +CParse: Source/Include/swigconfig.h + @cd $(SOURCE)/CParse; $(MAKE) -DOH: +swig.spec: swig.spec.in config.status + @CONFIG_HEADERS= CONFIG_LINKS= CONFIG_FILES=swig.spec $(SHELL) ./config.status + +DOH: Source/Include/swigconfig.h @cd $(SOURCE)/DOH; $(MAKE) -Modules: - @cd $(SOURCE)/Modules; $(MAKE) +.PHONY: SWIG1.1 Modules1.1 Swig Preprocessor DOH runtime -.PHONY: Modules1.1 Modules Swig Preprocessor LParse DOH +# Config file must be generated at make time, rather than at configure +# time because it paths need to be substituted. + +Source/Include/swigconfig.h: Source/Include/swigconfig.h.in Makefile.in config.status + sed 's|@-swig_lib-@|$(SWIG_LIB)|g;s|@-exec_prefix-@|$(exec_prefix)|g;s|@-release_suffix-@|$(RELEASESUFFIX)|g' Source/Include/swigconfig.h.in > $@ ##################################################################### -# Runtime libraries -##################################################################### - -runtime: - @cd Runtime; $(MAKE) - -##################################################################### -# CHECK +# All the languages SWIG speaks (when it wants to) ##################################################################### skip-tcl = [ -z "@TCLINCLUDE@" -o -z "@TCLLIB@" ] @@ -75,108 +74,187 @@ skip-java = [ -z "@JAVA@" -o -z "@JAVAC@" -o -z "@JAVAINC@" ] skip-guile = [ -z "@GUILEINCLUDE@" -o -z "@GUILELIB@" ] skip-mzscheme = [ -z "@MZC@" ] skip-ruby = [ -z "@RUBY@" -o -z "@RUBYINCLUDE@" -o -z "@RUBYLIB@" ] +skip-php4 = [ -z "@PHP4@" -o -z "@PHP4INC@" ] +skip-ocaml = [ -z "@OCAMLBIN@" -o -z "@OCAMLINC@" ] +skip-pike = [ -z "@PIKE@" -o -z "@PIKEINCLUDE@" ] -chk-swiglib = @ROOT_DIR@/Lib -chk = $(MAKE) SWIG_LIB=$(chk-swiglib) check +##################################################################### +# Runtime libraries +##################################################################### + +runtime: + @-$(skip-tcl) || (cd Runtime; $(MAKE) tcl) + @-$(skip-python) || (cd Runtime; $(MAKE) python) + @-$(skip-perl) || (cd Runtime; $(MAKE) perl5) + @-$(skip-ruby) || (cd Runtime; $(MAKE) ruby) + @-$(skip-guile) || (cd Runtime; $(MAKE) guile) + @-$(skip-mzscheme) || (cd Runtime; $(MAKE) mzscheme) + @-$(skip-php4) || (cd Runtime; $(MAKE) php4) + @-$(skip-ocaml) || (cd Runtime; $(MAKE) ocaml) +# @-$(skip-pike) || (cd Runtime; $(MAKE) pike) + +##################################################################### +# CHECK +##################################################################### + +ACTION = check + +chk-set-swiglib = SWIG_LIB=@ROOT_DIR@/Lib +chk-set-runtimelib = RUNTIMEDIR=@ROOT_DIR@/Runtime/.libs +chk-set-swig = SWIG=@ROOT_DIR@/$(TARGET) + +chk-set-env = $(chk-set-swiglib) $(chk-set-swig) $(chk-set-runtimelib) + +chk = $(MAKE) -k -s $(chk-set-env) $(ACTION) check-aliveness: - test -x ./swig - ./swig -version - ./swig -help - $(skip-tcl) || ./swig -tcl -help - $(skip-perl) || ./swig -perl -help - $(skip-python) || ./swig -python -help - $(skip-java) || ./swig -java -help - $(skip-guile) || ./swig -guile -help - $(skip-mzscheme) || ./swig -mzscheme -help - $(skip-ruby) || ./swig -ruby -help + test -x ./$(TARGET) + ./$(TARGET) -version + ./$(TARGET) -help + @$(skip-tcl) || ./$(TARGET) -tcl -help + @$(skip-perl) || ./$(TARGET) -perl -help + @$(skip-python) || ./$(TARGET) -python -help + @$(skip-java) || ./$(TARGET) -java -help + @$(skip-guile) || ./$(TARGET) -guile -help + @$(skip-mzscheme) || ./$(TARGET) -mzscheme -help + @$(skip-ruby) || ./$(TARGET) -ruby -help + @$(skip-ocaml) || ./$(TARGET) -ocaml -help + @$(skip-php4) || ./$(TARGET) -php4 -help +# @$(skip-pike) || ./$(TARGET) -pike -help -check-examples: - $(skip-tcl) || (cd Examples/tcl/class && $(chk)) - $(skip-tcl) || (cd Examples/tcl/constants && $(chk)) - $(skip-tcl) || (cd Examples/tcl/pointer && $(chk)) - $(skip-tcl) || (cd Examples/tcl/reference && $(chk)) - $(skip-tcl) || (cd Examples/tcl/simple && $(chk)) - $(skip-tcl) || (cd Examples/tcl/value && $(chk)) - $(skip-tcl) || (cd Examples/tcl/variables && $(chk)) - $(skip-perl) || (cd Examples/perl5/class && $(chk)) - $(skip-perl) || (cd Examples/perl5/constants && $(chk)) - $(skip-perl) || (cd Examples/perl5/pointer && $(chk)) - $(skip-perl) || (cd Examples/perl5/reference && $(chk)) - $(skip-perl) || (cd Examples/perl5/simple && $(chk)) - $(skip-perl) || (cd Examples/perl5/value && $(chk)) - $(skip-perl) || (cd Examples/perl5/variables && $(chk)) - $(skip-python) || (cd Examples/python/class && $(chk)) - $(skip-python) || (cd Examples/python/constants && $(chk)) - $(skip-python) || (cd Examples/python/pointer && $(chk)) - $(skip-python) || (cd Examples/python/reference && $(chk)) - $(skip-python) || (cd Examples/python/simple && $(chk)) - $(skip-python) || (cd Examples/python/value && $(chk)) - $(skip-python) || (cd Examples/python/variables && $(chk)) - $(skip-java) || (cd Examples/java/native && $(chk)) - $(skip-java) || (cd Examples/java/simple && $(chk)) - $(skip-java) || (cd Examples/java/typemap && $(chk)) - $(skip-guile) || (cd Examples/guile/matrix && $(chk)) - $(skip-guile) || (cd Examples/guile/simple && $(chk)) - $(skip-guile) || (cd Examples/guile/port && $(chk)) - $(skip-mzscheme) || (cd Examples/mzscheme/simple && $(chk)) - $(skip-ruby) || (cd Examples/ruby/class && $(chk)) - $(skip-ruby) || (cd Examples/ruby/constants && $(chk)) - $(skip-ruby) || (cd Examples/ruby/pointer && $(chk)) - $(skip-ruby) || (cd Examples/ruby/reference && $(chk)) - $(skip-ruby) || (cd Examples/ruby/simple && $(chk)) - $(skip-ruby) || (cd Examples/ruby/value && $(chk)) - $(skip-ruby) || (cd Examples/ruby/variables && $(chk)) +check-examples: \ + check-tcl-examples \ + check-perl-examples \ + check-python-examples \ + check-java-examples \ + check-guile-examples \ + check-mzscheme-examples \ + check-ruby-examples \ + check-ocaml-examples \ + check-php4-examples \ +# check-pike-examples -Examples/GIFPlot/libgifplot.a: - cd Examples/GIFPlot/Lib ; $(MAKE) +check-%-examples: + @passed=true; \ + dir="Examples/$*"; \ + if $(skip-$*); then \ + echo skipping $* $(ACTION); \ + elif [ ! -f $$dir/check.list ]; then \ + echo skipping $* $(ACTION) "(no $$dir/check.list)"; \ + else \ + all=`sed '/^#/d' $$dir/check.list`; \ + for a in $$all; do \ + echo $(ACTION)ing $$dir/$$a; \ + (cd $$dir/$$a && $(chk)) \ + || passed=false; \ + done; \ + fi; \ + test $$passed = true -check-gifplot-example: Examples/GIFPlot/libgifplot.a - $(skip-perl) || (cd Examples/GIFPlot/Perl/full && $(chk)) - $(skip-perl) || (cd Examples/GIFPlot/Perl/simple && $(chk)) - $(skip-perl) || (cd Examples/GIFPlot/Perl/shadow && $(chk)) - $(skip-python) || (cd Examples/GIFPlot/Python/full && $(chk)) - $(skip-python) || (cd Examples/GIFPlot/Python/simple && $(chk)) - $(skip-tcl) || (cd Examples/GIFPlot/Tcl/full && $(chk)) - $(skip-tcl) || (cd Examples/GIFPlot/Tcl/mandel && $(chk)) - $(skip-tcl) || (cd Examples/GIFPlot/Tcl/simple && $(chk)) - $(skip-guile) || (cd Examples/GIFPlot/Guile/full && $(chk)) - $(skip-guile) || (cd Examples/GIFPlot/Guile/simple && $(chk)) - $(skip-ruby) || (cd Examples/GIFPlot/Ruby/full && $(chk)) - $(skip-ruby) || (cd Examples/GIFPlot/Ruby/simple && $(chk)) - $(skip-ruby) || (cd Examples/GIFPlot/Ruby/shadow && $(chk)) +check-test-suite: \ + check-tcl-test-suite \ + check-perl-test-suite \ + check-python-test-suite \ + check-java-test-suite \ + check-guile-test-suite \ + check-mzscheme-test-suite \ + check-ruby-test-suite \ + check-ocaml-test-suite \ + check-php4-test-suite \ +# check-pike-test-suite -check-c++-examples: - $(skip-python) || (cd Examples/C++/Python && $(chk)) - $(skip-java) || (cd Examples/C++/Java && $(chk)) +check-%-test-suite: + @passed=true; \ + dir="Examples/test-suite/$*"; \ + if $(skip-$*); then \ + echo skipping $* test-suite $(ACTION); \ + elif [ ! -d $$dir ]; then \ + echo skipping $* test-suite $(ACTION) "(no dir $$dir)"; \ + else \ + (cd $$dir && $(chk)) \ + || passed=false; \ + fi; \ + test $$passed = true -check-xml: - cd Examples/xml && $(chk) +gifplot-library: + @echo $(ACTION)ing Examples/GIFPlot/Lib + @cd Examples/GIFPlot/Lib ; $(MAKE) -k -s $(ACTION) -check: check-aliveness \ - check-examples check-gifplot-example check-c++-examples \ - check-xml +check-gifplot: \ + check-tcl-gifplot \ + check-perl-gifplot \ + check-python-gifplot \ + check-java-gifplot \ + check-guile-gifplot \ + check-mzscheme-gifplot \ + check-ruby-gifplot \ + check-ocaml-gifplot \ + check-php4-gifplot \ +# check-pike-gifplot + +check-%-gifplot: gifplot-library + @passed=true; \ + up=`Tools/capitalize $*`; \ + dir="Examples/GIFPlot/$$up"; \ + if $(skip-$*); then \ + echo skipping $$up $(ACTION); \ + elif [ ! -f $$dir/check.list ]; then \ + echo skipping $$up $(ACTION) "(no $$dir/check.list)"; \ + else \ + all=`sed '/^#/d' $$dir/check.list`; \ + for a in $$all; do \ + echo $(ACTION)ing $$dir/$$a; \ + (cd $$dir/$$a && $(chk)) \ + || passed=false; \ + done; \ + fi; \ + test $$passed = true + +check: check-aliveness check-examples check-gifplot check-test-suite ##################################################################### # CLEAN ##################################################################### -clean: +clean: clean-objects clean-examples clean-gifplot clean-test-suite + +clean-objects: @for i in $(SOURCEDIRS) ; \ do \ + echo cleaning $(SOURCE)/$$i; \ if [ -d $(SOURCE)/$$i -a -f $(SOURCE)/$$i/Makefile ]; then \ - (cd $(SOURCE)/$$i; $(MAKE) clean) ; \ + (cd $(SOURCE)/$$i; $(MAKE) -s clean) ; \ fi \ done; - @cd Runtime; $(MAKE) clean - rm -f swig + @echo cleaning Runtime + @cd Runtime; $(MAKE) -s clean + @rm -f $(TARGET) -distclean-dead = config.status config.log config.cache \ +distclean-dead = config.status config.log config.cache swig.spec \ @configure_substituted_files@ distclean: clean rm -f $(distclean-dead) +clean-examples: + @$(MAKE) -k -s check-examples ACTION=clean + +clean-gifplot: + @$(MAKE) -k -s check-gifplot ACTION=clean + +clean-test-suite: + @echo cleaning Examples/test-suite + @$(MAKE) -k -s check-test-suite ACTION=clean + +clean-%-examples: + @$(MAKE) -k -s check-$*-examples ACTION=clean + +clean-%-test-suite: + @$(MAKE) -k -s check-$*-test-suite ACTION=clean + +clean-%-gifplot: + @$(MAKE) -k -s check-$*-gifplot ACTION=clean + ##################################################################### # TARGETS: install & friends @@ -192,75 +270,77 @@ install: install-main install-lib install-runtime install-main: @echo "Installing $(BIN_DIR)/swig" - @$(MKINSTDIRS) $(BIN_DIR) - @if [ -f swig.exe ]; then \ - $(INSTALL_PROGRAM) swig.exe $(BIN_DIR)/swig.exe; \ - else \ - $(INSTALL_PROGRAM) swig $(BIN_DIR)/swig; \ - fi + @$(MKINSTDIRS) $(DESTDIR)$(BIN_DIR) + @if [ -f swig.exe ]; then swig=swig.exe; else swig=$(TARGET); fi; \ + $(INSTALL_PROGRAM) $$swig $(DESTDIR)$(BIN_DIR)/$$swig + +lib-languages = tcl perl5 python guile java mzscheme ruby php4 ocaml pike install-lib: @echo "Installing the SWIG library" - @$(MKINSTDIRS) $(SWIG_LIB) + @$(MKINSTDIRS) $(DESTDIR)$(SWIG_LIB) # cd $(SWIG_LIB); rm -rf * -# The following line has `*.swg' removed -- add it back if needed. @cd $(srcdir)/Lib; for i in *.i *.swg; \ do \ echo "Installing Lib/$$i"; \ - ../$(INSTALL_DATA) $$i $(SWIG_LIB)/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/tcl - @cd $(srcdir)/Lib/tcl; for i in *.i *.swg; \ - do \ - echo "Installing Lib/tcl/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/tcl/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/perl5 - @cd $(srcdir)/Lib/perl5; for i in *.i *.swg Makefile.pl; \ - do \ - echo "Installing Lib/perl5/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/perl5/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/python - @cd $(srcdir)/Lib/python; for i in *.i *.swg; \ - do \ - echo "Installing Lib/python/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/python/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/guile - @cd $(srcdir)/Lib/guile; for i in *.i *.swg; \ - do \ - echo "Installing Lib/guile/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/guile/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/java - @cd $(srcdir)/Lib/java; for i in *.i *.swg; \ - do \ - echo "Installing Lib/java/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/java/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/mzscheme - @cd $(srcdir)/Lib/mzscheme; for i in *.i *.swg; \ - do \ - echo "Installing Lib/mzscheme/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/mzscheme/$$i; \ - done; - @$(MKINSTDIRS) $(SWIG_LIB)/ruby - @cd $(srcdir)/Lib/ruby; for i in *.i *.swg Makefile.swig extconf.rb; \ - do \ - echo "Installing Lib/ruby/$$i"; \ - ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/ruby/$$i; \ + ../$(INSTALL_DATA) $$i $(DESTDIR)$(SWIG_LIB)/$$i; \ done; + @for lang in $(lib-languages); \ + do \ + dst=$(DESTDIR)$(SWIG_LIB)/$$lang; \ + $(MKINSTDIRS) $$dst; \ + ( cd $(srcdir)/Lib/$$lang; \ + doti="`ls *.i 2>/dev/null`"; \ + dotswg="`ls *.swg 2>/dev/null`"; \ + if [ -f extra-install.list ]; then \ + extra="`sed '/^#/d' extra-install.list`"; \ + fi; \ + files="`echo $$doti $$dotswg $$extra`"; \ + if [ x"$$files" = x ]; then \ + echo "Installing nothing from Lib/$$lang"; \ + else for file in $$doti $$dotswg $$extra; \ + do \ + echo "Installing Lib/$$lang/$$file"; \ + ../../$(INSTALL_DATA) $$file $$dst/$$file; \ + done; \ + fi ); \ + done + install-runtime: @cd Runtime; $(MAKE) install + +##################################################################### +# TARGETS: uninstall & friends +##################################################################### + +uninstall: uninstall-main uninstall-lib uninstall-runtime + @echo "Uninstall complete" + +uninstall-main: + @echo "Uninstalling $(BIN_DIR)/swig" + @if [ -f swig.exe ]; then \ + rm -f $(DESTDIR)$(BIN_DIR)/swig.exe; \ + else \ + rm -f $(DESTDIR)$(BIN_DIR)/$(TARGET); \ + fi + +uninstall-lib: + @echo "Uninstalling the SWIG library" + rm -rf $(DESTDIR)$(SWIG_LIB)/; + +uninstall-runtime: + @cd Runtime; $(MAKE) uninstall + + ############################################################################ # DIST and other maintenance ############################################################################ # distribution directory dd = @PACKAGE@-@VERSION@ +srpm = @PACKAGE@-@SWIG_MAJOR_VERSION@.@SWIG_MINOR_VERSION@.@SWIG_SPIN@ dist: @echo 'Dave, what do you want to do w/ "make dist"?' @@ -274,4 +354,12 @@ dist-suggested: tar cf - $(dd) | gzip --best > $(dd).tar.gz rm -rf $(dd) +srcrpm: swig.spec + rm -fr $(srpm) $(srpm).src.rpm + cvs export -d $(srpm) -r HEAD SWIG + cp swig.spec $(srpm) + tar -cf - $(srpm) | gzip --best > $(srpm).tar.gz + rm -fr $(srpm) + rpm -ts $(srpm).tar.gz + # Makefile ends here diff --git a/Runtime/.cvsignore b/Runtime/.cvsignore new file mode 100644 index 000000000..cda4e782d --- /dev/null +++ b/Runtime/.cvsignore @@ -0,0 +1,7 @@ +.libs +Makefile +lib*.c +lib*.lo +lib*.la +swigtcl8.c +swigtcl8.lo diff --git a/Runtime/Makefile.in b/Runtime/Makefile.in index 6b6031c62..54fe4c604 100644 --- a/Runtime/Makefile.in +++ b/Runtime/Makefile.in @@ -8,27 +8,52 @@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ +top_srcdir = @top_srcdir@ VPATH = @srcdir@ CC = @CC@ LIBTOOL = ../Tools/libtool -SWIGLIB = ../Lib -LIBS = libswigpl.la libswigpy.la libswigtcl8.la libswigrb.la +SWIGLIB = $(top_srcdir)/Lib +RELEASESUFFIX = @release_suffix@ +LIBS = libswigpl$(RELEASESUFFIX).la libswigpy$(RELEASESUFFIX).la \ + libswigtcl8$(RELEASESUFFIX).la libswigrb$(RELEASESUFFIX).la \ + libswigguile$(RELEASESUFFIX).la libswigocaml$(RELEASESUFFIX).la LIB_DIR = $(exec_prefix)/lib -all: - @sh $(srcdir)/make.sh +MKINSTDIRS = $(top_srcdir)/mkinstalldirs +INSTALL = $(top_srcdir)/install-sh -c +all: + -$(MAKE) perl5 + -$(MAKE) python + -$(MAKE) tcl + -$(MAKE) ruby + -$(MAKE) guile + -$(MAKE) mzscheme + -$(MAKE) php4 + -$(MAKE) ocaml install: @echo "Installing runtime libraries" + @$(MKINSTDIRS) $(DESTDIR)$(LIB_DIR) @for i in $(LIBS); \ do \ if [ -f $$i ]; then \ - $(LIBTOOL) install -c $$i $(LIB_DIR)/$$i; \ + echo $(LIBTOOL) $(INSTALL) $$i $(DESTDIR)$(LIB_DIR)/$$i; \ + $(LIBTOOL) $(INSTALL) $$i $(DESTDIR)$(LIB_DIR)/$$i; \ fi; \ done; +uninstall: + @echo "Uninstalling runtime libraries" + @for i in $(LIBS); \ + do \ + if [ -f $$i ]; then \ + echo $(LIBTOOL) --mode=uninstall /bin/rm -f $(DESTDIR)$(LIB_DIR)/$$i; \ + $(LIBTOOL) --mode=uninstall /bin/rm -f $(DESTDIR)$(LIB_DIR)/$$i; \ + fi; \ + done; + clean:: rm -rf *.o *.lo *.la *.a *.c *.swg *~ core .libs @@ -42,65 +67,153 @@ TCL_INCLUDE = @TCLINCLUDE@ TCL_RUNTIME = $(SWIGLIB)/tcl/swigtcl8.swg # Tcl 8.x -tcl: libswigtcl8.la +tcl: libswigtcl8$(RELEASESUFFIX).la -libswigtcl8.la: +libswigtcl8$(RELEASESUFFIX).la: rm -f swigtcl8.c cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(TCL_RUNTIME) >> swigtcl8.c # -cp $(srcdir)/$(TCL_RUNTIME) swigtcl8.c $(LIBTOOL) $(CC) -c $(TCL_INCLUDE) -DSWIG_GLOBAL swigtcl8.c - $(LIBTOOL) $(CC) -o libswigtcl8.la swigtcl8.lo -rpath $(LIB_DIR) -avoid-version + $(LIBTOOL) $(CC) -o libswigtcl8$(RELEASESUFFIX).la swigtcl8.lo -rpath $(LIB_DIR) -avoid-version # ---------------------------------------------------------------------- # Python run-time library # ---------------------------------------------------------------------- PYTHON_INCLUDE = -DHAVE_CONFIG_H @PYINCLUDE@ -PYTHON_RUNTIME = $(SWIGLIB)/python/python.swg +PYTHON_RUNTIME = $(SWIGLIB)/python/pyrun.swg # Python shared -python: libswigpy.la +python: libswigpy$(RELEASESUFFIX).la -libswigpy.la: +libswigpy$(RELEASESUFFIX).la: rm -f libpy.c - cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PYTHON_RUNTIME) >> libpy.c + echo '#include "Python.h"' >> libpy.c + cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PYTHON_RUNTIME) >> libpy.c # -cp $(srcdir)/$(PYTHON_RUNTIME) libpy.c $(LIBTOOL) $(CC) -c $(PYTHON_INCLUDE) -DSWIG_GLOBAL libpy.c - $(LIBTOOL) $(CC) -o libswigpy.la libpy.lo -rpath $(LIB_DIR) -avoid-version + $(LIBTOOL) $(CC) -o libswigpy$(RELEASESUFFIX).la libpy.lo -rpath $(LIB_DIR) -avoid-version # ---------------------------------------------------------------------- # Perl run-time library # ---------------------------------------------------------------------- PERL5_INCLUDE = -I@PERL5EXT@ -PERL5_RUNTIME = $(SWIGLIB)/perl5/perl5.swg +PERL5_RUNTIME = $(SWIGLIB)/perl5/perlrun.swg # Perl shared -perl5: libswigpl.la +perl5: libswigpl$(RELEASESUFFIX).la -libswigpl.la: +libswigpl$(RELEASESUFFIX).la: $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PERL5_RUNTIME) @rm -f libperl.c # cat $(srcdir)/perlrun.h >> libperl.c cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PERL5_RUNTIME) >> libperl.c $(LIBTOOL) $(CC) -c $(PERL5_INCLUDE) -DSWIG_GLOBAL -Dbool=char -Dexplicit= libperl.c - $(LIBTOOL) $(CC) -o libswigpl.la libperl.lo -rpath $(LIB_DIR) -avoid-version + $(LIBTOOL) $(CC) -o libswigpl$(RELEASESUFFIX).la libperl.lo -rpath $(LIB_DIR) -avoid-version # ---------------------------------------------------------------------- # Ruby run-time library # ---------------------------------------------------------------------- +RUBY_CFLAGS = @RUBYCCDLFLAGS@ -DHAVE_CONFIG_H RUBY_INCLUDE = @RUBYINCLUDE@ -RUBY_RUNTIME = $(SWIGLIB)/ruby/ruby.swg +RUBY_RUNTIME = $(SWIGLIB)/ruby/rubyhead.swg +RUBY_DLNK = @RUBYDYNAMICLINKING@ # Ruby shared -ruby: libswigrb.la +ruby: libswigrb$(RELEASESUFFIX).la -libswigrb.la: +libswigrb$(RELEASESUFFIX).la: rm -f librb.c -# cp $(srcdir)/$(RUBY_RUNTIME) librb.c cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(RUBY_RUNTIME) $(SWIGLIB)/ruby/rubydef.swg >> librb.c - $(LIBTOOL) $(CC) -c $(RUBY_INCLUDE) -DSWIG_GLOBAL librb.c - $(LIBTOOL) $(CC) -o libswigrb.la librb.lo -rpath $(LIB_DIR) -avoid-version + $(LIBTOOL) $(CC) $(RUBY_CFLAGS) -c $(RUBY_INCLUDE) -DSWIG_GLOBAL librb.c + $(LIBTOOL) $(CC) -o libswigrb$(RELEASESUFFIX).la librb.lo -rpath $(LIB_DIR) $(RUBY_DLNK) -avoid-version + +# ---------------------------------------------------------------------- +# Guile run-time library +# ---------------------------------------------------------------------- + +GUILE_INCLUDE = @GUILEINCLUDE@ +GUILE_RUNTIME = $(SWIGLIB)/guile/guiledec.swg $(SWIGLIB)/guile/guile.swg + +# Guile shared + +guile: libswigguile$(RELEASESUFFIX).la + +libswigguile$(RELEASESUFFIX).la: $(GUILE_RUNTIME) + rm -f libguile.c + cat $(srcdir)/$(GUILE_RUNTIME) >> libguile.c + $(LIBTOOL) $(CC) -c $(GUILE_INCLUDE) -DSWIG_GLOBAL libguile.c + $(LIBTOOL) $(CC) -o libswigguile$(RELEASESUFFIX).la libguile.lo -rpath $(LIB_DIR) -avoid-version + +# ---------------------------------------------------------------------- +# MzScheme run-time library +# ---------------------------------------------------------------------- + +MZSCHEME_RUNTIME = $(SWIGLIB)/mzscheme/mzschemedec.swg $(SWIGLIB)/mzscheme/mzscheme.swg +MZC = @MZC@ +SO = @SO@ + +# MzScheme shared + +mzscheme: libswigmz$(RELEASESUFFIX).la + +libswigmz$(RELEASESUFFIX).la: $(MZSCHEME_RUNTIME) + rm -f libmz.c + cat $(srcdir)/$(MZSCHEME_RUNTIME) >> libmz.c + $(MZC) ++ccf "-DSWIG_GLOBAL" --cc libmz.c + if [ ! -d .libs ] ; then mkdir .libs; fi + $(MZC) --ld .libs/libswigmz$(RELEASESUFFIX)$(SO) libmz.o + +# ---------------------------------------------------------------------- +# PHP4 run-time library +# ---------------------------------------------------------------------- + +PHP4_INCLUDE = @PHP4INC@ +PHP4_RUNTIME = $(SWIGLIB)/php4/php4run.swg + +php4: libswigphp4$(RELEASESUFFIX).la + +libswigphp4$(RELEASESUFFIX).la: $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PHP4_RUNTIME) + @rm -f libphp4.c + cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PHP4_RUNTIME) >> libphp4.c + $(LIBTOOL) $(CC) -c $(PHP4_INCLUDE) -DSWIG_GLOBAL libphp4.c + $(LIBTOOL) $(CC) -o libswigphp4$(RELEASESUFFIX).la libphp4.lo -rpath $(LIB_DIR) -avoid-version + +# ---------------------------------------------------------------------- +# Ocaml run-time library +# ---------------------------------------------------------------------- + +OCAML_CFLAGS = +OCAML_INCLUDE = @OCAMLINC@ -I$(SWIGLIB)/ocaml +OCAML_RUNTIME = $(SWIGLIB)/ocaml/libswigocaml.swg + +# Ocaml shared + +ocaml: libswigocaml$(RELEASESUFFIX).la + +libswigocaml$(RELEASESUFFIX).la: + rm -f libswigocaml.c + cat $(srcdir)/$(OCAML_RUNTIME) >> libswigocaml.c + $(LIBTOOL) $(CC) $(OCAML_CFLAGS) -c $(OCAML_INCLUDE) -DSWIG_GLOBAL libswigocaml.c + $(LIBTOOL) $(CC) -o libswigocaml$(RELEASESUFFIX).la libswigocaml.lo -rpath $(LIB_DIR) + +# ---------------------------------------------------------------------- +# Pike run-time library +# ---------------------------------------------------------------------- + +PIKE_INCLUDE = -DHAVE_CONFIG_H @PIKEINCLUDE@ +PIKE_RUNTIME = $(SWIGLIB)/pike/pikerun.swg + +# Pike shared + +pike: libswigpike$(RELEASESUFFIX).la + +libswigpike$(RELEASESUFFIX).la: + rm -f libpike.c + cat $(srcdir)/$(SWIG_TYPECHECK) $(srcdir)/$(PIKE_RUNTIME) >> libpike.c + $(LIBTOOL) $(CC) -c $(PIKE_INCLUDE) -DSWIG_GLOBAL libpike.c + $(LIBTOOL) $(CC) -o libswigpike$(RELEASESUFFIX).la libpike.lo -rpath $(LIB_DIR) -avoid-version diff --git a/Source/CParse/.cvsignore b/Source/CParse/.cvsignore new file mode 100644 index 000000000..82e5e2e10 --- /dev/null +++ b/Source/CParse/.cvsignore @@ -0,0 +1,9 @@ +Makefile +.deps +parser.c +parser.h +libcparse.a +cscanner.o +parser.o +y.tab.c +y.tab.h diff --git a/Source/CParse/Makefile.in b/Source/CParse/Makefile.in new file mode 100644 index 000000000..648d1b9f9 --- /dev/null +++ b/Source/CParse/Makefile.in @@ -0,0 +1,69 @@ +####################################################################### +# $Header$ +####################################################################### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +SHELL = /bin/sh +CC = @CC@ +CFLAGS = @CFLAGS@ +YACC = @YACC@ +AR = @AR@ +RANLIB = @RANLIB@ + +TARGET = libcparse.a + +OBJS = parser.@OBJEXT@ cscanner.@OBJEXT@ templ.@OBJEXT@ util.@OBJEXT@ + +SRCS = cscanner.c templ.c util.c + +PARSER = $(srcdir)/parser.y +INCLUDES = -I$(srcdir)/../Include \ + -I$(srcdir)/. \ + -I$(srcdir)/../Swig \ + -I$(srcdir)/../Preprocessor \ + -I$(srcdir)/../DOH/Include \ + -I../Include \ + -I. + +.c.@OBJEXT@: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $*.@OBJEXT@ $< + +cparse: $(TARGET) + +$(TARGET): $(OBJS) + $(AR) cr $(TARGET) $(OBJS) + $(RANLIB) $(TARGET) + +parser.@OBJEXT@: parser.c + $(CC) $(INCLUDES) $(CFLAGS) $< -c -o parser.@OBJEXT@ + +parser.c parser.h: $(PARSER) + $(YACC) @YFLAGS@ $(PARSER) + @cp y.tab.h parser.h + @cp y.tab.c parser.c + +scanner.@OBJEXT@: parser.h + +parser:: + @cp y.tab.c.bison parser.c + @cp y.tab.h.bison parser.h + @cp y.tab.h.bison y.tab.h + $(CC) $(CFLAGS) parser.c -c -o parser.@OBJEXT@ + +clean:: + rm -f *.@OBJEXT@ $(TARGET) y.tab.c y.tab.h + +nuke:: + rm -f Makefile *~ + + + + + + + + + + diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h new file mode 100644 index 000000000..fa323768e --- /dev/null +++ b/Source/CParse/cparse.h @@ -0,0 +1,12 @@ +#include "swig.h" +#include "swigwarn.h" +#include "swigver.h" + +extern char *cparse_file; +extern int cparse_line; +extern int cparse_cplusplus; +extern int cparse_start_line; +extern void Swig_cparse_replace_descriptor(String *s); +extern void Swig_cparse_cplusplus(int); +extern void Swig_cparse_debug_templates(int); + diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c new file mode 100644 index 000000000..1d185f597 --- /dev/null +++ b/Source/CParse/cscanner.c @@ -0,0 +1,1290 @@ +/* ----------------------------------------------------------------------------- + * scanner.cxx + * + * SWIG1.1 tokenizer. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1998-2000. The University of Chicago + * Copyright (C) 1995-1998. The University of Utah and The Regents of the + * University of California. + * + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_cscanner_c[] = "$Header$"; + +#include "cparse.h" +#include "parser.h" +#include +#include + +#define YYBSIZE 8192 + +typedef struct InFile { + DOHFile *f; + int line_number; + char *in_file; + struct InFile *prev; +} InFile; + +InFile *in_head; + +DOHFile *LEX_in = 0; +static DOHString *header = 0; +static DOHString *comment = 0; +DOHString *scanner_ccode = 0; /* String containing C code */ +static char *yybuffer = 0; + +static char yytext[YYBSIZE]; +static int yylen = 0; +int cparse_line = 1; +char *cparse_file; +int cparse_start_line = 0; +static int comment_start; +static int scan_init = 0; +static int num_brace = 0; +static int last_brace = 0; +static int last_id = 0; +static int rename_active = 0; + int cparse_cplusplus; + +/* ----------------------------------------------------------------------------- + * Swig_cparse_cplusplus() + * ----------------------------------------------------------------------------- */ + +void +Swig_cparse_cplusplus(int v) { + cparse_cplusplus = v; +} + +/* ---------------------------------------------------------------------- + * locator() + * + * Support for locator strings. These are strings of the form + * @filename,line,id@ emitted by the SWIG preprocessor. They + * are primarily used for macro line number reporting + * ---------------------------------------------------------------------- */ + +typedef struct Locator { + char *filename; + int line_number; + struct Locator *next; +} Locator; + +static Locator *locs = 0; + +static void +scanner_locator(String *loc) { + int c; + Locator *l; + Seek(loc,1,SEEK_SET); + c = Getc(loc); + if (c == '@') { + /* Empty locator. We pop the last location off */ + if (locs) { + cparse_file = locs->filename; + cparse_line = locs->line_number; + l = locs->next; + free(locs); + locs = l; + } + /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line);*/ + return; + } + + /* We're going to push a new location */ + l = (Locator *) malloc(sizeof(Locator)); + l->filename = cparse_file; + l->line_number = cparse_line; + l->next = locs; + locs = l; + + /* Now, parse the new location out of the locator string */ + { + String *fn = NewString(""); + Putc(c,fn); + + while ((c = Getc(loc)) != EOF) { + if ((c == '@') || (c == ',')) break; + Putc(c,fn); + } + + cparse_file = Swig_copy_string(Char(fn)); + Clear(fn); + + cparse_line = 1; + /* Get the line number */ + while ((c = Getc(loc)) != EOF) { + if ((c == '@') || (c == ',')) break; + Putc(c,fn); + } + + cparse_line = atoi(Char(fn)); + Clear(fn); + + /* Get the rest of it */ + while (( c= Getc(loc)) != EOF) { + if (c == '@') break; + Putc(c,fn); + } + /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line); */ + Delete(fn); + } +} + +/************************************************************** + * scanner_init() + * + * Initialize buffers + **************************************************************/ + +void scanner_init() { + yybuffer = (char *) malloc(YYBSIZE); + scan_init = 1; + header = NewString(""); + comment = NewString(""); + scanner_ccode = NewString(""); +} + +/************************************************************** + * scanner_file(FILE *f) + * + * Start reading from new file + **************************************************************/ +void scanner_file(DOHFile *f) { + InFile *in; + + in = (InFile *) malloc(sizeof(InFile)); + in->f = f; + in->in_file = cparse_file; + in->line_number = 1; + if (!in_head) in->prev = 0; + else in->prev = in_head; + in_head = in; + LEX_in = f; + cparse_line = 1; +} + +/************************************************************** + * scanner_close() + * + * Close current input file and go to next + **************************************************************/ + +void scanner_close() { + InFile *p; + if (!in_head) return; + Delete(LEX_in); + p = in_head->prev; + if (p != 0) { + LEX_in = p->f; + cparse_line = p->line_number; + cparse_file = p->in_file; + } else { + LEX_in = 0; + } + free(in_head); + in_head = p; +} + +/************************************************************** + * char nextchar() + * + * gets next character from input. + * If we're in inlining mode, we actually retrieve a character + * from inline_yybuffer instead. + **************************************************************/ + +char nextchar() { + int c = 0; + + while (LEX_in) { + c = Getc(LEX_in); + if (c == EOF) { + scanner_close(); + } else { + break; + } + } + if (!LEX_in) return 0; + if (yylen >= YYBSIZE) { + Printf(stderr,"** FATAL ERROR. Buffer overflow in scanner.cxx.\nReport this to swig-dev@cs.uchicago.edu.\n"); + exit (EXIT_FAILURE); + } + yytext[yylen] = c; + yylen++; + if (c == '\n') { + cparse_line++; + } + return(c); +} + +void retract(int n) { + int i; + for (i = 0; i < n; i++) { + yylen--; + if (yylen >= 0) { + Ungetc(yytext[yylen],LEX_in); + if (yytext[yylen] == '\n') { + cparse_line--; + } + } + } + if (yylen < 0) yylen = 0; +} + +/************************************************************** + * start_inline(char *text, int line) + * + * This grabs a chunk of text and tries to inline it into + * the current file. (This is kind of wild, but cool when + * it works). + * + * If we're already in inlining mode, we will save the code + * as a new fragment. + **************************************************************/ + +void start_inline(char *text, int line) { + InFile *in; + + /* Save current state */ + in_head->line_number = cparse_line; + in_head->in_file = cparse_file; + + in = (InFile *) malloc(sizeof(InFile)); + in->f = NewString(text); + Seek(in->f,0,SEEK_SET); + in->in_file = Swig_copy_string(cparse_file); + in->line_number = line; + in->prev = in_head; + in_head = in; + LEX_in = in->f; + cparse_line = line; +} + +/************************************************************** + * yycomment(char *, int line) + * + * Inserts a comment into a documentation entry. + **************************************************************/ + +void yycomment(char *a, int b, int c) { +} + + +/* ----------------------------------------------------------------------------- + * skip_balanced() + * + * Skips a piece of code enclosed in begin/end symbols such as '{...}' or + * (...). Ignores symbols inside comments or strings. + * ----------------------------------------------------------------------------- */ + +void +skip_balanced(int startchar, int endchar) { + char c; + int num_levels = 1; + int state = 0; + char temp[2] = {0,0}; + int start_line = cparse_line; + + Clear(scanner_ccode); + Putc(startchar,scanner_ccode); + temp[0] = (char) startchar; + while (num_levels > 0) { + c = nextchar(); + if (c == 0) { + Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar); + return; + } + Putc(c,scanner_ccode); + switch(state) { + case 0: + if (c == startchar) num_levels++; + else if (c == endchar) num_levels--; + else if (c == '/') state = 10; + else if (c == '\"') state = 20; + else if (c == '\'') state = 30; + break; + case 10: + if (c == '/') state = 11; + else if (c == '*') state = 12; + else state = 0; + break; + case 11: + if (c == '\n') state = 0; + else state = 11; + break; + case 12: + if (c == '*') state = 13; + break; + case 13: + if (c == '*') state = 13; + else if (c == '/') state = 0; + else state = 12; + break; + case 20: + if (c == '\"') state = 0; + else if (c == '\\') state = 21; + break; + case 21: + state = 20; + break; + case 30: + if (c == '\'') state = 0; + else if (c == '\\') state = 31; + break; + case 31: + state = 30; + break; + default: + break; + } + yylen = 0; + } + if (endchar == '}') num_brace--; + return; +} + +/************************************************************** + * void skip_decl(void) + * + * This tries to skip over an entire declaration. For example + * + * friend ostream& operator<<(ostream&, const char *s); + * + * or + * friend ostream& operator<<(ostream&, const char *s) { }; + * + **************************************************************/ + +void skip_decl(void) { + char c; + int done = 0; + while (!done) { + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,cparse_line,"Missing semicolon. Reached end of input.\n"); + return; + } + if (c == '{') { + last_brace = num_brace; + num_brace++; + break; + } + yylen = 0; + if (c == ';') done = 1; + } + if (!done) { + while (num_brace > last_brace) { + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,cparse_line,"Missing '}'. Reached end of input.\n"); + return; + } + if (c == '{') num_brace++; + if (c == '}') num_brace--; + yylen = 0; + } + } +} + +/* This function is called when a backslash is found in a string */ +static void get_escape() { + int result = 0; + int state = 0; + char c; + + while(1) { + c = nextchar(); + if (c == 0) break; + switch(state) { + case 0: + if (c == 'n') { + yytext[yylen-1] = '\n'; + return; + } + if (c == 'r') { + yytext[yylen-1] = '\r'; + return; + } + if (c == 't') { + yytext[yylen-1] = '\t'; + return; + } + if (c == 'a') { + yytext[yylen-1] = '\a'; + return; + } + if (c == 'b') { + yytext[yylen-1] = '\b'; + return; + } + if (c == 'f') { + yytext[yylen-1] = '\f'; + return; + } + if (c == '\\') { + yytext[yylen-1] = '\\'; + return; + } + if (c == 'v') { + yytext[yylen-1] = '\v'; + return; + } + if (c == 'e') { + yytext[yylen-1] = '\033'; + return; + } + if (c == '\'') { + yytext[yylen-1] = '\''; + return; + } + if (c == '\"') { + yytext[yylen-1] = '\"'; + return; + } + if (c == '\n') { + yylen--; + return; + } + if (c == '0') { + state = 10; + } + else if (c == 'x') { + state = 20; + } else { + yytext[yylen-1] = '\\'; + yytext[yylen] = c; + yylen++; + return; + } + break; + case 10: + if (!isdigit(c)) { + retract(1); + yytext[yylen-1] = (char) result; + return; + } + result = (result << 3) + (c - '0'); + yylen--; + break; + case 20: + if (!isxdigit(c)) { + retract(1); + yytext[yylen-1] = (char) result; + return; + } + if (isdigit(c)) + result = (result << 4) + (c - '0'); + else + result = (result << 4) + (10 + tolower(c) - 'a'); + yylen--; + break; + } + } + return; +} + +/************************************************************** + * int yylook() + * + * Lexical scanner. + * See Aho,Sethi, and Ullman, pg. 106 + **************************************************************/ + +int yylook(void) { + + int state; + char c = 0; + + state = 0; + yylen = 0; + while(1) { + +/* printf("State = %d\n", state); */ + switch(state) { + + case 0 : + if((c = nextchar()) == 0) return (0); + + /* Process delimeters */ + + if (c == '\n') { + state = 0; + yylen = 0; + last_id = 0; + } else if (isspace(c) || (c=='\\')) { + state = 0; + yylen = 0; + last_id = 0; + } + + else if ((isalpha(c)) || (c == '_')) state = 7; + else if (c == '$') state = 75; + + /* Look for single character symbols */ + + else if (c == '(') return (LPAREN); + else if (c == ')') return (RPAREN); + else if (c == ';') return (SEMI); + else if (c == ',') return (COMMA); + else if (c == '*') return (STAR); + else if (c == '}') { + num_brace--; + if (num_brace < 0) { + Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n"); + state = 0; + num_brace = 0; + } else { + return (RBRACE); + } + } + else if (c == '{') { + last_brace = num_brace; + num_brace++; + return (LBRACE); + } + else if (c == '=') return (EQUAL); + else if (c == '+') return (PLUS); + else if (c == '-') return (MINUS); + else if (c == '&') { + state = 300; + } + else if (c == '|') { + state = 301; + } + else if (c == '^') return (XOR); + else if (c == '<') state = 60; + else if (c == '>') state = 61; + else if (c == '~') { + return (NOT); + } + else if (c == '!') return (LNOT); + else if (c == '\\') { + state = 99; + } + else if (c == '[') return (LBRACKET); + else if (c == ']') return (RBRACKET); + + /* Look for multi-character sequences */ + + else if (c == '/') state = 1; /* Comment (maybe) */ + else if (c == '\"') state = 2; /* Possibly a string */ + else if (c == '#') state = 3; /* CPP */ + else if (c == '%') state = 4; /* Directive */ + else if (c == '@') state = 4; /* Objective C keyword */ + else if (c == ':') state = 5; /* maybe double colon */ + else if (c == '0') state = 83; /* An octal or hex value */ + else if (c == '\'') state = 9; /* A character constant */ + else if (c == '.') state = 100; /* Maybe a number, maybe just a period */ + else if (c == '`') { + state = 200; /* Back-tick type */ + yylen = 0; + } + else if (isdigit(c)) state = 8; /* A numerical value */ + + else state = 99; + break; + case 1: /* Comment block */ + if ((c = nextchar()) == 0) return(0); + if (c == '/') { + comment_start = cparse_line; + Clear(comment); + state = 10; /* C++ style comment */ + } else if (c == '*') { + comment_start = cparse_line; + Clear(comment); + state = 12; /* C style comment */ + } else { + retract(1); + return(SLASH); + } + break; + case 300: /* & or && */ + if ((c = nextchar()) == 0) return(AND); + if (c == '&') return(LAND); + else { + retract(1); + return(AND); + } + + case 301: /* | or || */ + if ((c = nextchar()) == 0) return(OR); + if (c == '|') return(LOR); + else { + retract(1); + return(OR); + } + case 10: /* C++ style comment */ + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,-1, "Unterminated comment detected.\n"); + return 0; + } + if (c == '\n') { + Putc(c,comment); + /* Add the comment to documentation */ + /* yycomment(Char(comment),comment_start, column_start);*/ + yylen = 0; + state = 0; + } else { + state = 10; + Putc(c,comment); + yylen = 0; + } + break; + + case 12: /* C style comment block */ + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,-1,"Unterminated comment detected.\n"); + return 0; + } + if (c == '*') { + state = 13; + } else { + Putc(c,comment); + yylen = 0; + state = 12; + } + break; + case 13: /* Still in C style comment */ + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,-1,"Unterminated comment detected.\n"); + return 0; + } + if (c == '*') { + Putc(c,comment); + state = 13; + } else if (c == '/') { + + /* Look for locator markers */ + { + char *loc = Char(comment); + if (Len(comment)) { + if ((*loc == '@') && (*(loc+Len(comment)-1) == '@')) { + /* Locator */ + scanner_locator(comment); + } + } + } + /* yycomment(Char(comment),comment_start,column_start); */ + yylen = 0; + state = 0; + } else { + Putc('*',comment); + Putc(c,comment); + yylen = 0; + state = 12; + } + break; + + case 2: /* Processing a string */ + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,-1, "Unterminated string detected.\n"); + return 0; + } + if (c == '\"') { + yytext[yylen-1] = 0; + yylval.id = Swig_copy_string(yytext+1); + return(STRING); + } else if (c == '\\') { + yylen--; + get_escape(); + break; + } else state = 2; + break; + + case 3: /* a CPP directive */ + if (( c= nextchar()) == 0) return 0; + if (c == '\n') { + retract(1); + yytext[yylen] = 0; + yylval.id = yytext; + return(POUND); + } + break; + + case 4: /* A wrapper generator directive (maybe) */ + if (( c= nextchar()) == 0) return 0; + if (c == '{') { + state = 40; /* Include block */ + Clear(header); + cparse_start_line = cparse_line; + } else if ((isalpha(c)) || (c == '_')) state = 7; + else if (c == '}') { + Swig_error(cparse_file,cparse_line, "Misplaced %%}.\n"); + return 0; + } else { + retract(1); + return(MODULO); + } + break; + + case 40: /* Process an include block */ + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,-1, "Unterminated include block detected.\n"); + return 0; + } + yylen = 0; + if (c == '%') state = 41; + else { + Putc(c,header); + yylen = 0; + state = 40; + } + break; + case 41: /* Still processing include block */ + if ((c = nextchar()) == 0) { + Swig_error(cparse_file,-1, "Unterminated include block detected.\n"); + return 0; + } + if (c == '}') { + yylval.str = NewString(header); + return(HBLOCK); + } else { + Putc('%',header); + Putc(c,header); + yylen = 0; + state = 40; + } + break; + + case 5: /* Maybe a double colon */ + + if (( c= nextchar()) == 0) return 0; + if ( c == ':') { + state = 51; + } else { + retract(1); + return COLON; + } + break; + case 51: /* Maybe a ::*, ::~, or :: */ + if (( c = nextchar()) == 0) return 0; + if (c == '*') { + return DSTAR; + } if (c == '~') { + return DCNOT; + } else { + retract(1); + if (!last_id) { + retract(2); + return NONID; + } else { + return DCOLON; + } + } + + case 60: /* shift operators */ + if ((c = nextchar()) == 0) return (0); + if (c == '<') return LSHIFT; + else { + retract(1); + return LESSTHAN; + } + break; + case 61: + if ((c = nextchar()) == 0) return (0); + if (c == '>') return RSHIFT; + else { + retract(1); + return GREATERTHAN; + } + break; + case 7: /* Identifier */ + if ((c = nextchar()) == 0) return(0); + if (isalnum(c) || (c == '_') || (c == '.') || (c == '$')) { + state = 7; + } else { + retract(1); + return(ID); + } + break; + case 75: /* Special identifier $*/ + if ((c = nextchar()) == 0) return(0); + if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) { + state = 7; + } else { + retract(1); + return(ID); + } + break; + + case 8: /* A numerical digit */ + if ((c = nextchar()) == 0) return(0); + if (c == '.') {state = 81;} + else if ((c == 'e') || (c == 'E')) {state = 86;} + else if ((c == 'f') || (c == 'F')) { + return(NUM_FLOAT); + } + else if (isdigit(c)) { state = 8;} + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + return(NUM_INT); + } + break; + case 81: /* A floating pointer number of some sort */ + if ((c = nextchar()) == 0) return(0); + if (isdigit(c)) state = 81; + else if ((c == 'e') || (c == 'E')) state = 82; + else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { + return(NUM_FLOAT); + } else { + retract(1); + return(NUM_FLOAT); + } + break; + case 82: + if ((c = nextchar()) == 0) return(0); + if ((isdigit(c)) || (c == '-') || (c == '+')) state = 86; + else { + retract(2); + yytext[yylen-1] = 0; + return(NUM_INT); + } + break; + case 83: + /* Might be a hexidecimal or octal number */ + if ((c = nextchar()) == 0) return(0); + if (isdigit(c)) state = 84; + else if ((c == 'x') || (c == 'X')) state = 85; + else if (c == '.') state = 81; + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + return(NUM_INT); + } + break; + case 84: + /* This is an octal number */ + if ((c = nextchar()) == 0) return (0); + if (isdigit(c)) state = 84; + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + return(NUM_INT); + } + break; + case 85: + /* This is an hex number */ + if ((c = nextchar()) == 0) return (0); + if ((isdigit(c)) || (c=='a') || (c=='b') || (c=='c') || + (c=='d') || (c=='e') || (c=='f') || (c=='A') || + (c=='B') || (c=='C') || (c=='D') || (c=='E') || + (c=='F')) + state = 85; + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + return(NUM_INT); + } + break; + + case 86: + /* Rest of floating point number */ + + if ((c = nextchar()) == 0) return (0); + if (isdigit(c)) state = 86; + else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { + return(NUM_FLOAT); + } else { + retract(1); + return(NUM_FLOAT); + } + /* Parse a character constant. ie. 'a' */ + break; + + case 87 : + /* A long integer of some sort */ + if ((c = nextchar()) == 0) return (NUM_LONG); + if ((c == 'u') || (c == 'U')) { + return(NUM_ULONG); + } else if ((c == 'l') || (c == 'L')) { + state = 870; + } else { + retract(1); + return(NUM_LONG); + } + break; + + case 870: + if ((c = nextchar()) == 0) return (NUM_LONGLONG); + if ((c == 'u') || (c == 'U')) { + return (NUM_ULONGLONG); + } else { + retract(1); + return(NUM_LONGLONG); + } + + case 88: + /* An unsigned integer of some sort */ + if ((c = nextchar()) == 0) return (NUM_UNSIGNED); + if ((c == 'l') || (c == 'L')) { + state = 880; + } else { + retract(1); + return(NUM_UNSIGNED); + } + break; + + case 880: + if ((c = nextchar()) == 0) return (NUM_ULONG); + if ((c == 'l') || (c == 'L')) return (NUM_ULONGLONG); + else { + retract(1); + return(NUM_ULONG); + } + + case 9: + if ((c = nextchar()) == 0) return (0); + if (c == '\\') { + yylen--; + get_escape(); + } else if (c == '\'') { + yytext[yylen-1] = 0; + yylval.str = NewString(yytext+1); + if (yylen == 2) { + Swig_error(cparse_file, cparse_line, "Empty character constant\n"); + } + return(CHARCONST); + } + break; + + case 100: + if ((c = nextchar()) == 0) return (0); + if (isdigit(c)) state = 81; + else { + retract(1); + return(PERIOD); + } + break; + case 200: + if ((c = nextchar()) == 0) return (0); + if (c == '`') { + yytext[yylen-1] = 0; + yylval.type = NewString(yytext); + return(TYPE_RAW); + } + break; + + default: + Swig_error(cparse_file, cparse_line, "Illegal character '%c'=%d.\n",c,c); + state = 0; + return(ILLEGAL); + } + } +} + +static int check_typedef = 0; + +void scanner_check_typedef() { + check_typedef = 1; +} + +void scanner_ignore_typedef() { + check_typedef = 0; +} + +void scanner_last_id(int x) { + last_id = x; +} + +void scanner_clear_rename() { + rename_active = 0; +} + +static int next_token = 0; +void scanner_next_token(int tok) { + next_token = tok; +} + +/************************************************************** + * int yylex() + * + * Gets the lexene and returns tokens. + *************************************************************/ + +int yylex(void) { + + int l; + + if (!scan_init) { + scanner_init(); + } + + if (next_token) { + l = next_token; + next_token = 0; + return l; + } + l = yylook(); + + + if (l == NONID) { + last_id = 1; + } else { + last_id = 0; + } + + /* We got some sort of non-white space object. We set the start_line + variable unless it has already been set */ + + if (!cparse_start_line) { + cparse_start_line = cparse_line; + } + + /* Copy the lexene */ + + yytext[yylen] = 0; + switch(l) { + + case NUM_INT: + case NUM_FLOAT: + case NUM_ULONG: + case NUM_LONG: + case NUM_UNSIGNED: + case NUM_LONGLONG: + case NUM_ULONGLONG: + if (l == NUM_INT) yylval.dtype.type = T_INT; + if (l == NUM_FLOAT) yylval.dtype.type = T_DOUBLE; + if (l == NUM_ULONG) yylval.dtype.type = T_ULONG; + if (l == NUM_LONG) yylval.dtype.type = T_LONG; + if (l == NUM_UNSIGNED) yylval.dtype.type = T_UINT; + if (l == NUM_LONGLONG) yylval.dtype.type = T_LONGLONG; + if (l == NUM_ULONGLONG) yylval.dtype.type = T_ULONGLONG; + yylval.dtype.val = NewString(yytext); + yylval.dtype.bitfield = 0; + yylval.dtype.throws = 0; + return(l); + break; + + case ID: + + if (yytext[0] != '%') { + /* Look for keywords now */ + + if (strcmp(yytext,"int") == 0) { + yylval.type = NewSwigType(T_INT); + return(TYPE_INT); + } + if (strcmp(yytext,"double") == 0) { + yylval.type = NewSwigType(T_DOUBLE); + return(TYPE_DOUBLE); + } + if (strcmp(yytext,"void") == 0) { + yylval.type = NewSwigType(T_VOID); + return(TYPE_VOID); + } + if (strcmp(yytext,"char") == 0) { + yylval.type = NewSwigType(T_CHAR); + return(TYPE_CHAR); + } + if (strcmp(yytext,"short") == 0) { + yylval.type = NewSwigType(T_SHORT); + return(TYPE_SHORT); + } + if (strcmp(yytext,"long") == 0) { + yylval.type = NewSwigType(T_LONG); + return(TYPE_LONG); + } + if (strcmp(yytext,"float") == 0) { + yylval.type = NewSwigType(T_FLOAT); + return(TYPE_FLOAT); + } + if (strcmp(yytext,"signed") == 0) { + yylval.type = NewSwigType(T_INT); + return(TYPE_SIGNED); + } + if (strcmp(yytext,"unsigned") == 0) { + yylval.type = NewSwigType(T_UINT); + return(TYPE_UNSIGNED); + } + if (strcmp(yytext,"bool") == 0) { + yylval.type = NewSwigType(T_BOOL); + return(TYPE_BOOL); + } + /* C++ keywords */ + + if (cparse_cplusplus) { + if (strcmp(yytext,"class") == 0) return(CLASS); + if (strcmp(yytext,"private") == 0) return(PRIVATE); + if (strcmp(yytext,"public") == 0) return(PUBLIC); + if (strcmp(yytext,"protected") == 0) return(PROTECTED); + if (strcmp(yytext,"friend") == 0) return(FRIEND); + if (strcmp(yytext,"virtual") == 0) return(VIRTUAL); + if (strcmp(yytext,"operator") == 0) { + String *s = NewString("operator"); + int c; + int state = 0; + int sticky = 0; + int isconversion = 0; + int count = 0; + while ((c = nextchar())) { + if (((c == '(') || (c == ';')) && state) { + retract(1); + break; + } + count++; + if (!isspace(c)) { + if ((!state) && (isalpha(c))) isconversion = 1; + if (!state && !sticky) Putc(' ',s); + Putc(c,s); + sticky = 0; + state = 1; + } else { + if (!sticky) Putc(' ',s); + sticky = 1; + } + } + Chop(s); + yylval.str = s; + while(Replaceall(s,"[ ", "[")); + if (isconversion) { + String *ns = Swig_symbol_string_qualify(s,0); + yylval.str = ns; + } + if (isconversion && !rename_active) { + char *t = Char(s) + 9; + if (!((strcmp(t,"new") == 0) || (strcmp(t,"delete") == 0) + || (strcmp(t,"new[]") == 0) || (strcmp(t,"delete[]") == 0))) { + /* retract(strlen(t));*/ + retract(count); + return COPERATOR; + } + } + return(OPERATOR); + } + if (strcmp(yytext,"throw") == 0) return(THROW); + if (strcmp(yytext,"try") == 0) return (yylex()); + if (strcmp(yytext,"catch") == 0) return (CATCH); + if (strcmp(yytext,"inline") == 0) return(yylex()); + if (strcmp(yytext,"mutable") == 0) return(yylex()); + if (strcmp(yytext,"explicit") == 0) return(yylex()); + if (strcmp(yytext,"export") == 0) return(yylex()); + if (strcmp(yytext,"typename") == 0) return (TYPENAME); + if (strcmp(yytext,"template") == 0) { + yylval.ivalue = cparse_line; + return(TEMPLATE); + } + if (strcmp(yytext,"delete") == 0) { + return(DELETE); + } + if (strcmp(yytext,"using") == 0) { + return(USING); + } + if (strcmp(yytext,"namespace") == 0) { + return(NAMESPACE); + } + } else { + if (strcmp(yytext,"class") == 0) { + Swig_warning(WARN_PARSE_CLASS_KEYWORD,cparse_file,cparse_line, "class keyword used, but not in C++ mode.\n"); + } + } + + /* Objective-C keywords */ +#ifdef OBJECTIVEC + if ((ObjC) && (yytext[0] == '@')) { + if (strcmp(yytext,"@interface") == 0) return (OC_INTERFACE); + if (strcmp(yytext,"@end") == 0) return (OC_END); + if (strcmp(yytext,"@public") == 0) return (OC_PUBLIC); + if (strcmp(yytext,"@private") == 0) return (OC_PRIVATE); + if (strcmp(yytext,"@protected") == 0) return (OC_PROTECTED); + if (strcmp(yytext,"@class") == 0) return(OC_CLASS); + if (strcmp(yytext,"@implementation") == 0) return(OC_IMPLEMENT); + if (strcmp(yytext,"@protocol") == 0) return(OC_PROTOCOL); + } +#endif + + /* Misc keywords */ + + if (strcmp(yytext,"extern") == 0) return(EXTERN); + if (strcmp(yytext,"const") == 0) return(CONST); + if (strcmp(yytext,"static") == 0) return(STATIC); + if (strcmp(yytext,"struct") == 0) return(STRUCT); + if (strcmp(yytext,"union") == 0) return(UNION); + if (strcmp(yytext,"enum") == 0) return(ENUM); + if (strcmp(yytext,"sizeof") == 0) return(SIZEOF); + + if (strcmp(yytext,"typedef") == 0) { + yylval.ivalue = 0; + return(TYPEDEF); + } + + /* Ignored keywords */ + + if (strcmp(yytext,"volatile") == 0) return(VOLATILE); + + /* SWIG directives */ + } else { + if (strcmp(yytext,"%module") == 0) return(MODULE); + if (strcmp(yytext,"%insert") == 0) return(INSERT); + if (strcmp(yytext,"%name") == 0) return(NAME); + if (strcmp(yytext,"%rename") == 0) { + rename_active = 1; + return(RENAME); + } + if (strcmp(yytext,"%namewarn") == 0) { + rename_active = 1; + return (NAMEWARN); + } + if (strcmp(yytext,"%includefile") == 0) return(INCLUDE); + if (strcmp(yytext,"%val") == 0) { + Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n"); + return (yylex()); + } + if (strcmp(yytext,"%out") == 0) { + Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n"); + return(yylex()); + } + if (strcmp(yytext,"%constant") == 0) return(CONSTANT); + if (strcmp(yytext,"%typedef") == 0) { + yylval.ivalue = 1; + return(TYPEDEF); + } + if (strcmp(yytext,"%native") == 0) return(NATIVE); + if (strcmp(yytext,"%pragma") == 0) return(PRAGMA); + if (strcmp(yytext,"%extend") == 0) return(EXTEND); + if (strcmp(yytext,"%fragment") == 0) return(FRAGMENT); + if (strcmp(yytext,"%inline") == 0) return(INLINE); + if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP); + if (strcmp(yytext,"%feature") == 0) return(FEATURE); + if (strcmp(yytext,"%except") == 0) return(EXCEPT); + if (strcmp(yytext,"%importfile") == 0) return(IMPORT); + if (strcmp(yytext,"%echo") == 0) return(ECHO); + if (strcmp(yytext,"%apply") == 0) return(APPLY); + if (strcmp(yytext,"%clear") == 0) return(CLEAR); + if (strcmp(yytext,"%types") == 0) return(TYPES); + if (strcmp(yytext,"%parms") == 0) return(PARMS); + if (strcmp(yytext,"%varargs") == 0) return(VARARGS); + if (strcmp(yytext,"%template") == 0) return (SWIGTEMPLATE); + if (strcmp(yytext,"%warn") == 0) return(WARN); + } + /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */ + + /* Need to fix this */ + if (check_typedef) { + if (SwigType_istypedef(yytext)) { + yylval.type = NewString(yytext); + return(TYPE_TYPEDEF); + } + } + yylval.id = Swig_copy_string(yytext); + last_id = 1; + return(ID); + case POUND: + return yylex(); + default: + return(l); + } +} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y new file mode 100644 index 000000000..350e4cdc4 --- /dev/null +++ b/Source/CParse/parser.y @@ -0,0 +1,4568 @@ +%{ +/* ----------------------------------------------------------------------------- + * parser.y + * + * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++. + * This file is a bit of a mess and probably needs to be rewritten at + * some point. Beware. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1998-2001. The University of Chicago + * Copyright (C) 1995-1998. The University of Utah and The Regents of the + * University of California. + * + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +#define yylex yylex + +char cvsroot_parser_y[] = "$Header$"; + +#include "cparse.h" +#include "preprocessor.h" +#include + +/* We do this for portability */ +#undef alloca +#define alloca malloc + +/* ----------------------------------------------------------------------------- + * Externals + * ----------------------------------------------------------------------------- */ + +extern int yylex(); +extern void yyerror (const char *s); + +/* scanner.cxx */ + +extern int cparse_line; +extern int cparse_start_line; +extern void skip_balanced(int startchar, int endchar); +extern void skip_decl(void); +extern void scanner_check_typedef(void); +extern void scanner_ignore_typedef(void); +extern void scanner_last_id(int); +extern void scanner_clear_rename(void); +extern void start_inline(char *, int); +extern String *scanner_ccode; +extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms); +extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms); + +/* NEW Variables */ + +extern void generate_all(Node *); + +static Node *top = 0; /* Top of the generated parse tree */ +static int unnamed = 0; /* Unnamed datatype counter */ +static Hash *extendhash = 0; /* Hash table of added methods */ +static Hash *classes = 0; /* Hash table of classes */ +static Symtab *prev_symtab = 0; +static Node *current_class = 0; + String *ModuleName = 0; +static Node *module_node = 0; +static String *Classprefix = 0; +static String *Namespaceprefix = 0; +static int inclass = 0; +static char *last_cpptype = 0; +static int inherit_list = 0; +static Parm *template_parameters = 0; + +/* ----------------------------------------------------------------------------- + * Assist Functions + * ----------------------------------------------------------------------------- */ + +static Node *new_node(const String_or_char *tag) { + Node *n = NewHash(); + set_nodeType(n,tag); + Setfile(n,cparse_file); + Setline(n,cparse_line); + return n; +} + +/* Copies a node. Does not copy tree links or symbol table data (except for + sym:name) */ + +static Node *copy_node(Node *n) { + Node *nn; + String *key; + nn = NewHash(); + Setfile(nn,Getfile(n)); + Setline(nn,Getline(n)); + for (key = Firstkey(n); key; key = Nextkey(n)) { + if ((Strcmp(key,"nextSibling") == 0) || + (Strcmp(key,"previousSibling") == 0) || + (Strcmp(key,"parentNode") == 0) || + (Strcmp(key,"lastChild") == 0)) { + continue; + } + if (Strncmp(key,"csym:",5) == 0) continue; + /* We do copy sym:name. For templates */ + if ((Strcmp(key,"sym:name") == 0) || + (Strcmp(key,"sym:weak") == 0) || + (Strcmp(key,"sym:typename") == 0)) { + Setattr(nn,key, Copy(Getattr(n,key))); + continue; + } + if (Strcmp(key,"sym:symtab") == 0) { + Setattr(nn,"sym:needs_symtab", "1"); + } + /* We don't copy any other symbol table attributes */ + if (Strncmp(key,"sym:",4) == 0) { + continue; + } + /* If children. We copy them recursively using this function */ + if (Strcmp(key,"firstChild") == 0) { + /* Copy children */ + Node *cn = Getattr(n,key); + while (cn) { + appendChild(nn,copy_node(cn)); + cn = nextSibling(cn); + } + continue; + } + /* We don't copy the symbol table. But we drop an attribute + requires_symtab so that functions know it needs to be built */ + + if (Strcmp(key,"symtab") == 0) { + /* Node defined a symbol table. */ + Setattr(nn,"requires_symtab","1"); + continue; + } + /* Can't copy nodes */ + if (Strcmp(key,"node") == 0) { + continue; + } + if ((Strcmp(key,"parms") == 0) || (Strcmp(key,"pattern") == 0) || (Strcmp(key,"throws") == 0)) { + Setattr(nn,key,CopyParmList(Getattr(n,key))); + continue; + } + /* Looks okay. Just copy the data using Copy */ + Setattr(nn, key, Copy(Getattr(n,key))); + } + return nn; +} + +/* ----------------------------------------------------------------------------- + * Variables + * ----------------------------------------------------------------------------- */ + + char *typemap_lang = 0; /* Current language setting */ + +static int cplus_mode = 0; +static String *class_rename = 0; + +/* C++ modes */ + +#define CPLUS_PUBLIC 1 +#define CPLUS_PRIVATE 2 +#define CPLUS_PROTECTED 3 + +void SWIG_typemap_lang(const char *tm_lang) { + typemap_lang = Swig_copy_string(tm_lang); +} + +/* ----------------------------------------------------------------------------- + * Assist functions + * ----------------------------------------------------------------------------- */ + +/* Perform type-promotion for binary operators */ +static int promote(int t1, int t2) { + return t1 > t2 ? t1 : t2; +} + +static String *yyrename = 0; + +/* Forward renaming operator */ +static Hash *rename_hash = 0; +static Hash *namewarn_hash = 0; +static Hash *features_hash = 0; + +static String *feature_identifier_fix(String *s) { + if (SwigType_istemplate(s)) { + String *tp, *ts, *ta, *tq; + tp = SwigType_templateprefix(s); + ts = SwigType_templatesuffix(s); + ta = SwigType_templateargs(s); + tq = Swig_symbol_type_qualify(ta,0); + Append(tp,tq); + Append(tp,ts); + Delete(ts); + Delete(ta); + Delete(tq); + return tp; + } else { + return NewString(s); + } +} + +static void +rename_add(char *name, SwigType *decl, char *newname) { + String *nname; + if (!rename_hash) rename_hash = NewHash(); + if (Namespaceprefix) { + nname = NewStringf("%s::%s",Namespaceprefix, name); + } else { + nname = NewString(name); + } + Swig_name_object_set(rename_hash,nname,decl,NewString(newname)); + Delete(nname); +} + +static void +namewarn_add(char *name, SwigType *decl, char *warning) { + String *nname; + if (!namewarn_hash) namewarn_hash = NewHash(); + if (Namespaceprefix) { + nname = NewStringf("%s::%s",Namespaceprefix, name); + } else { + nname = NewString(name); + } + + Swig_name_object_set(namewarn_hash,nname,decl,NewString(warning)); + Delete(nname); +} + +static void +rename_inherit(String *base, String *derived) { + /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ + Swig_name_object_inherit(rename_hash,base,derived); + Swig_name_object_inherit(namewarn_hash,base,derived); + Swig_name_object_inherit(features_hash,base,derived); +} + +/* Generate the symbol table name for an object */ +/* This is a bit of a mess. Need to clean up */ +static String *add_oldname = 0; + +static String *make_name(String *name,SwigType *decl) { + String *rn = 0; + String *origname = name; + int destructor = 0; + + if (name && (*(Char(name)) == '~')) { + destructor = 1; + } + if (yyrename) { + String *s = yyrename; + yyrename = 0; + if (destructor) { + Insert(s,0,"~"); + } + return s; + } + if (!name) return 0; + /* Check to see if the name is in the hash */ + if (!rename_hash) { + if (add_oldname) return Copy(add_oldname); + return origname; + } + rn = Swig_name_object_get(rename_hash, Namespaceprefix, name, decl); + if (!rn) { + if (add_oldname) return Copy(add_oldname); + return name; + } + if (destructor) { + if (Strcmp(rn,"$ignore") != 0) { + String *s = NewStringf("~%s", rn); + return s; + } + } + return Copy(rn); +} + +/* Generate an unnamed identifier */ +static String *make_unnamed() { + unnamed++; + return NewStringf("$unnamed%d$",unnamed); +} + +/* Generate the symbol table name for an object */ +static String *name_warning(String *name,SwigType *decl) { + String *rn = 0; + if (!name) return 0; + + /* Check to see if the name is in the hash */ + if (!namewarn_hash) return 0; + rn = Swig_name_object_get(namewarn_hash, Namespaceprefix,name,decl); + if (!rn) return 0; + return rn; +} + +/* Add declaration list to symbol table */ +static int add_only_one = 0; + + +static void add_symbols(Node *n) { + String *decl; + String *wrn = 0; + + /* Don't add symbols for private/protected members */ + if (inclass && (cplus_mode != CPLUS_PUBLIC)) { + while (n) { + Swig_symbol_add(0, n); /* Add to C symbol table */ + if (cplus_mode == CPLUS_PRIVATE) { + Setattr(n,"access", "private"); + } else { + Setattr(n,"access", "protected"); + } + if (add_only_one) break; + n = nextSibling(n); + } + return; + } + while (n) { + String *symname; + if (Getattr(n,"sym:name")) { + n = nextSibling(n); + continue; + } + decl = Getattr(n,"decl"); + if (!SwigType_isfunction(decl)) { + symname = make_name(Getattr(n,"name"),0); + if (!symname) { + symname = Getattr(n,"unnamed"); + } + if (symname) { + wrn = name_warning(symname,0); + Swig_features_get(features_hash, Namespaceprefix, Getattr(n,"name"), 0, n); + } + } else { + SwigType *fdecl = Copy(decl); + SwigType *fun = SwigType_pop_function(fdecl); + symname = make_name(Getattr(n,"name"),fun); + wrn = name_warning(symname,fun); + + Swig_features_get(features_hash,Namespaceprefix,Getattr(n,"name"),fun,n); + Delete(fdecl); + Delete(fun); + } + if (!symname) { + n = nextSibling(n); + continue; + } + if (strncmp(Char(symname),"$ignore",7) == 0) { + char *c = Char(symname)+7; + Setattr(n,"feature:ignore","1"); + if (strlen(c)) { + Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1); + } + Swig_symbol_add(0, n); + } else { + Node *c; + if ((wrn) && (Len(wrn))) { + Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn); + } + if (Strcmp(nodeType(n),"enum") != 0) { + c = Swig_symbol_add(symname,n); + if (c != n) { + if (Getattr(n,"sym:weak")) { + Setattr(n,"sym:name",symname); + } else if ((Strcmp(nodeType(n),"template") == 0) && (Strcmp(Getattr(n,"templatetype"),"cdecl") == 0)) { + Setattr(n,"sym:name",symname); + } else { + String *e = NewString(""); + Printf(e,"Identifier '%s' redeclared (ignored).", symname); + if (Cmp(symname,Getattr(n,"name"))) { + Printf(e," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name"))); + } + Printf(e,"\n%s:%d: Previous declaration of '%s'", Getfile(c),Getline(c),symname); + if (Cmp(symname,Getattr(c,"name"))) { + Printf(e," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name"))); + } + Swig_warning(WARN_PARSE_REDEFINED,Getfile(n), Getline(n),"%s\n", e); + Setattr(n,"error",e); + } + } + } else { + Setattr(n,"sym:name", symname); + } + } + if (add_only_one) return; + n = nextSibling(n); + } +} + + +/* add symbols a parse tree node copy */ + +void add_symbols_copy(Node *n) { + String *name; + int emode = 0; + + while (n) { + + if (Strcmp(nodeType(n),"access") == 0) { + String *kind = Getattr(n,"kind"); + if (Strcmp(kind,"public") == 0) { + cplus_mode = CPLUS_PUBLIC; + } else if (Strcmp(kind,"private") == 0) { + cplus_mode = CPLUS_PRIVATE; + } else if (Strcmp(kind,"protected") == 0) { + cplus_mode = CPLUS_PROTECTED; + } + n = nextSibling(n); + continue; + } + + add_oldname = Getattr(n,"sym:name"); + if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) { + if (add_oldname) { + DohIncref(add_oldname); + /* If already renamed, we used that name */ + if (Strcmp(add_oldname, Getattr(n,"name")) != 0) { + yyrename = add_oldname; + } + } + Delattr(n,"sym:needs_symtab"); + Delattr(n,"sym:name"); + + add_only_one = 1; + add_symbols(n); + + if (Getattr(n,"partialargs")) { + Swig_symbol_cadd(Getattr(n,"partialargs"),n); + } + add_only_one = 0; + name = Getattr(n,"name"); + if (Getattr(n,"requires_symtab")) { + Swig_symbol_newscope(); + Swig_symbol_setscopename(name); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + } + if (Strcmp(nodeType(n),"class") == 0) { + inclass = 1; + if (Strcmp(Getattr(n,"kind"),"class") == 0) { + cplus_mode = CPLUS_PRIVATE; + } else { + cplus_mode = CPLUS_PUBLIC; + } + } + if (Strcmp(nodeType(n),"extend") == 0) { + emode = cplus_mode; + cplus_mode = CPLUS_PUBLIC; + } + add_symbols_copy(firstChild(n)); + if (Strcmp(nodeType(n),"extend") == 0) { + cplus_mode = emode; + } + if (Getattr(n,"requires_symtab")) { + Setattr(n,"symtab", Swig_symbol_popscope()); + Delattr(n,"requires_symtab"); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + } + if (add_oldname) { + Delete(add_oldname); + } + if (Strcmp(nodeType(n),"class") == 0) { + inclass = 0; + } + add_oldname = 0; + } else { + if (Strcmp(nodeType(n),"extend") == 0) { + emode = cplus_mode; + cplus_mode = CPLUS_PUBLIC; + } + add_symbols_copy(firstChild(n)); + if (Strcmp(nodeType(n),"extend") == 0) { + cplus_mode = emode; + } + } + n = nextSibling(n); + } +} + +/* Extension merge. This function is used to handle the %extend directive + when it appears before a class definition. To handle this, the %extend + actually needs to take precedence. Therefore, we will selectively nuke symbols + from the current symbol table, replacing them with the added methods */ + +static void merge_extensions(Node *am) { + Node *n; + Node *csym; + + n = firstChild(am); + while (n) { + String *symname; + symname = Getattr(n,"sym:name"); + DohIncref(symname); + if ((symname) && (!Getattr(n,"error"))) { + /* Remove node from its symbol table */ + Swig_symbol_remove(n); + csym = Swig_symbol_add(symname,n); + if (csym != n) { + /* Conflict with previous definition. Nuke previous definition */ + String *e = NewString(""); + Printf(e,"Identifier '%s' redeclared (ignored).\n", symname); + Printf(e,"%s:%d: Previous definition of tag '%s'", Getfile(n),Getline(n), symname); + Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym), Getline(csym), "%s\n", e); + Setattr(csym,"error",e); + Swig_symbol_remove(csym); /* Remove class definition */ + Swig_symbol_add(symname,n); /* Insert extend definition */ + } + } + n = nextSibling(n); + } +} + +/* Check for unused %extend. Special case, don't report unused + extensions for templates */ + + static void check_extensions() { + String *key; + if (!extendhash) return; + for (key = Firstkey(extendhash); key; key = Nextkey(extendhash)) { + Node *n = Getattr(extendhash,key); + if (!Strstr(key,"<")) { + Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(n), Getline(n), "%%extend defined for an undeclared class %s.\n", key); + } + } + } + +/* Check a set of declarations to see if any are pure-abstract */ + + static List *pure_abstract(Node *n) { + List *abs = 0; + while (n) { + if (Cmp(nodeType(n),"cdecl") == 0) { + String *decl = Getattr(n,"decl"); + if (SwigType_isfunction(decl)) { + String *init = Getattr(n,"value"); + if (Cmp(init,"0") == 0) { + if (!abs) { + abs = NewList(); + } + Append(abs,n); + Setattr(n,"abstract","1"); + } + } + } else if (Cmp(nodeType(n),"destructor") == 0) { + if (Cmp(Getattr(n,"value"),"0") == 0) { + if (!abs) { + abs = NewList(); + } + Append(abs,n); + Setattr(n,"abstract","1"); + } + } + n = nextSibling(n); + } + return abs; + } + + /* Make a classname */ + + static String *make_class_name(String *name) { + String *nname = 0; + if (Namespaceprefix) { + nname= NewStringf("%s::%s", Namespaceprefix, name); + } else { + nname = NewString(name); + } + if (SwigType_istemplate(nname)) { + String *prefix, *args, *qargs; + prefix = SwigType_templateprefix(nname); + args = SwigType_templateargs(nname); + qargs = Swig_symbol_type_qualify(args,0); + Append(prefix,qargs); + Delete(nname); + nname = prefix; + } + return nname; + } + + static List *make_inherit_list(String *clsname, List *names) { + int i; + String *derived; + List *bases = NewList(); + + if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname); + else derived = NewString(clsname); + + for (i = 0; i < Len(names); i++) { + Node *s; + String *base; + String *n = Getitem(names,i); + /* Try to figure out where this symbol is */ + s = Swig_symbol_clookup(n,0); + if (s) { + while (s && (Strcmp(nodeType(s),"class") != 0)) { + /* Not a class. Could be a typedef though. */ + String *storage = Getattr(s,"storage"); + if (storage && (Strcmp(storage,"typedef") == 0)) { + String *nn = Getattr(s,"type"); + s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab")); + } else { + break; + } + } + if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) { + String *q = Swig_symbol_qualified(s); + Append(bases,s); + if (q) { + base = NewStringf("%s::%s", q, Getattr(s,"name")); + } else { + base = NewString(Getattr(s,"name")); + } + } else { + base = NewString(n); + } + } else { + base = NewString(n); + } + if (base) { + rename_inherit(base,derived); + Delete(base); + } + } + return bases; + } + +/* Structures for handling code fragments built for nested classes */ + +typedef struct Nested { + String *code; /* Associated code fragment */ + int line; /* line number where it starts */ + char *name; /* Name associated with this nested class */ + char *kind; /* Kind of class */ + SwigType *type; /* Datatype associated with the name */ + struct Nested *next; /* Next code fragment in list */ +} Nested; + +/* Some internal variables for saving nested class information */ + +static Nested *nested_list = 0; + +/* Add a function to the nested list */ + +static void add_nested(Nested *n) { + Nested *n1; + if (!nested_list) nested_list = n; + else { + n1 = nested_list; + while (n1->next) n1 = n1->next; + n1->next = n; + } +} + +/* Dump all of the nested class declarations to the inline processor + * However. We need to do a few name replacements and other munging + * first. This function must be called before closing a class! */ + +static Node *dump_nested(char *parent) { + Nested *n,*n1; + Node *ret = 0; + n = nested_list; + if (!parent) { + nested_list = 0; + return 0; + } + while (n) { + char temp[256]; + Node *retx; + /* Token replace the name of the parent class */ + Replace(n->code, "$classname", parent, DOH_REPLACE_ANY); + /* Fix up the name of the datatype (for building typedefs and other stuff) */ + sprintf(temp,"%s_%s", parent,n->name); + + Append(n->type,parent); + Append(n->type,"_"); + Append(n->type,n->name); + + /* Add the appropriate declaration to the C++ processor */ + retx = new_node("cdecl"); + Setattr(retx,"name",n->name); + Setattr(retx,"type",Copy(n->type)); + Setattr(retx,"nested",parent); + add_symbols(retx); + if (ret) { + set_nextSibling(retx,ret); + } + ret = retx; + + /* Insert a forward class declaration */ + /* Disabled: [ 597599 ] union in class: incorrect scope + retx = new_node("classforward"); + Setattr(retx,"kind",n->kind); + Setattr(retx,"name",Copy(n->type)); + Setattr(retx,"sym:name", make_name(n->type,0)); + set_nextSibling(retx,ret); + ret = retx; + */ + + /* Make all SWIG created typedef structs/unions/classes unnamed else + redefinition errors occur - nasty hack alert.*/ + + { + const char* types_array[3] = {"struct", "union", "class"}; + int i; + for (i=0; i<3; i++) { + char* code_ptr = Char(n->code); + while (code_ptr) { + /* Replace struct name (as in 'struct name {' ) with whitespace + name will be between struct and { */ + + code_ptr = strstr(code_ptr, types_array[i]); + if (code_ptr) { + char *open_bracket_pos; + code_ptr += strlen(types_array[i]); + open_bracket_pos = strstr(code_ptr, "{"); + if (open_bracket_pos) { + /* Make sure we don't have something like struct A a; */ + char* semi_colon_pos = strstr(code_ptr, ";"); + if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos))) + while (code_ptr < open_bracket_pos) + *code_ptr++ = ' '; + } + } + } + } + } + + { + /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */ + char* code_ptr = Char(n->code); + while (code_ptr) { + code_ptr = strstr(code_ptr, "%constant"); + if (code_ptr) { + char* directive_end_pos = strstr(code_ptr, ";"); + if (directive_end_pos) { + while (code_ptr <= directive_end_pos) + *code_ptr++ = ' '; + } + } + } + } + { + Node *head; + head = new_node("insert"); + Setattr(head,"code",NewStringf("\n%s\n",n->code)); + set_nextSibling(head,ret); + ret = head; + } + + /* Dump the code to the scanner */ + start_inline(Char(n->code),n->line); + + n1 = n->next; + Delete(n->code); + free(n); + n = n1; + } + nested_list = 0; + return ret; +} + +Node *Swig_cparse(File *f) { + extern void scanner_file(File *); + extern int yyparse(); + scanner_file(f); + top = 0; + yyparse(); + return top; +} + +%} + +%union { + char *id; + List *bases; + struct Define { + String *val; + String *rawval; + int type; + String *qualifier; + String *bitfield; + Parm *throws; + } dtype; + struct { + char *type; + char *filename; + int line; + } loc; + struct { + char *id; + SwigType *type; + String *defarg; + ParmList *parms; + short have_parms; + ParmList *throws; + } decl; + Parm *tparms; + struct { + String *op; + Hash *kwargs; + } tmap; + struct { + String *type; + String *us; + } ptype; + SwigType *type; + String *str; + Parm *p; + ParmList *pl; + int ivalue; + Node *node; +}; + +%token ID +%token HBLOCK +%token POUND +%token STRING +%token INCLUDE IMPORT INSERT +%token CHARCONST +%token NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG +%token TYPEDEF +%token TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_TYPEDEF TYPE_RAW +%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD +%token CONST VOLATILE STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET +%token ILLEGAL CONSTANT +%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS +%token ENUM +%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH +%token USING +%token NAMESPACE +%token NATIVE INLINE +%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT +%token WARN +%token LESSTHAN GREATERTHAN MODULO DELETE +%token TYPES PARMS +%token NONID DSTAR DCNOT +%token TEMPLATE +%token OPERATOR +%token COPERATOR +%token PARSETYPE + +%left CAST +%left LOR +%left LAND +%left OR +%left XOR +%left AND +%left LSHIFT RSHIFT +%left PLUS MINUS +%left STAR SLASH +%left UMINUS NOT LNOT +%left DCOLON + +%type program interface declaration swig_directive ; + +/* SWIG directives */ +%type extend_directive apply_directive clear_directive constant_directive ; +%type echo_directive except_directive fragment_directive include_directive inline_directive ; +%type insert_directive module_directive name_directive native_directive ; +%type pragma_directive rename_directive feature_directive varargs_directive typemap_directive ; +%type types_directive template_directive warn_directive ; + +/* C declarations */ +%type c_declaration c_decl c_decl_tail c_enum_decl c_constructor_decl ; +%type enumlist edecl; + +/* C++ declarations */ +%type cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl; +%type cpp_members cpp_member; +%type cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator; +%type cpp_swig_directive cpp_temp_possible cpp_nested cpp_opt_declarators ; +%type cpp_using_decl cpp_namespace_decl cpp_catch_decl ; +%type kwargs options; + +/* Misc */ +%type initializer cpp_const ; +%type storage_class; +%type parms ptail rawparms varargs_parms ; +%type

      parm valparm rawvalparms valparms valptail ; +%type

      typemap_parm tm_list tm_tail ; +%type cpptype access_specifier; +%type base_specifier +%type type rawtype type_right ; +%type base_list inherit raw_inherit; +%type definetype def_args etype; +%type expr exprnum exprcompound ; +%type ename ; +%type template_decl; +%type type_qualifier ; +%type type_qualifier_raw; +%type idstring idstringopt; +%type pragma_lang; +%type pragma_arg; +%type includetype; +%type pointer primitive_type; +%type declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl; +%type abstract_declarator direct_abstract_declarator ctor_end; +%type typemap_type; +%type idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi; +%type string stringnum ; +%type template_parms; +%type cpp_vend; +%type rename_namewarn; +%type type_specifier primitive_type_list ; + +%% + +/* ====================================================================== + * High-level Interface file + * + * An interface is just a sequence of declarations which may be SWIG directives + * or normal C declarations. + * ====================================================================== */ + +program : interface { + Setattr($1,"classes",classes); + Setattr($1,"name",ModuleName); + + if ((!module_node) && ModuleName) { + module_node = new_node("module"); + Setattr(module_node,"name",ModuleName); + } + Setattr($1,"module",module_node); + check_extensions(); + top = $1; + } + | PARSETYPE parm SEMI { + top = Getattr($2,"type"); + } + | PARSETYPE error { + top = 0; + } + ; + +interface : interface declaration { + appendChild($1,$2); + $$ = $1; + } + | empty { + $$ = new_node("top"); + } + ; + +declaration : swig_directive { $$ = $1; } + | c_declaration { $$ = $1; } + | cpp_declaration { $$ = $1; } + | SEMI { $$ = 0; } + | error { + $$ = 0; + if (!Swig_error_count()) { + static int last_error_line = -1; + if (last_error_line != cparse_line) { + Swig_error(cparse_file, cparse_line,"Syntax error in input.\n"); + last_error_line = cparse_line; + skip_decl(); + } + } + } +/* Out of class constructor/destructor declarations */ + | c_constructor_decl { + if ($$) { + add_symbols($$); + } + $$ = $1; + } + ; + + +/* ====================================================================== + * SWIG DIRECTIVES + * ====================================================================== */ + +swig_directive : extend_directive { $$ = $1; } + | apply_directive { $$ = $1; } + | clear_directive { $$ = $1; } + | constant_directive { $$ = $1; } + | echo_directive { $$ = $1; } + | except_directive { $$ = $1; } + | fragment_directive { $$ = $1; } + | include_directive { $$ = $1; } + | inline_directive { $$ = $1; } + | insert_directive { $$ = $1; } + | module_directive { $$ = $1; } + | name_directive { $$ = $1; } + | native_directive { $$ = $1; } + | pragma_directive { $$ = $1; } + | rename_directive { $$ = $1; } + | feature_directive { $$ = $1; } + | varargs_directive { $$ = $1; } + | typemap_directive { $$ = $1; } + | types_directive { $$ = $1; } + | template_directive { $$ = $1; } + | warn_directive { $$ = $1; } + ; + +/* ------------------------------------------------------------ + %extend classname { ... } + ------------------------------------------------------------ */ + +extend_directive : EXTEND options idcolon LBRACE { + Node *cls; + String *clsname; + cplus_mode = CPLUS_PUBLIC; + if (!classes) classes = NewHash(); + if (!extendhash) extendhash = NewHash(); + clsname = make_class_name($3); + /* Printf(stdout,"clsname = '%s'\n",clsname);*/ + cls = Getattr(classes,clsname); + if (!cls) { + /* No previous definition. Create a new scope */ + Node *am = Getattr(extendhash,clsname); + if (!am) { + Swig_symbol_newscope(); + Swig_symbol_setscopename($3); + prev_symtab = 0; + } else { + prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab")); + } + current_class = 0; + } else { + /* Previous class definition. Use its symbol table */ + prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab")); + current_class = cls; + } + Classprefix = NewString($3); + Namespaceprefix= Swig_symbol_qualifiedscopename(0); + Delete(clsname); + } cpp_members RBRACE { + String *clsname; + $$ = new_node("extend"); + Setattr($$,"symtab",Swig_symbol_popscope()); + if (prev_symtab) { + Swig_symbol_setscope(prev_symtab); + } + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + clsname = make_class_name($3); + Setattr($$,"name",clsname); + + /* Mark members as extend */ + + Swig_tag_nodes($6,"feature:extend",(char*) "1"); + if (current_class) { + /* We add the extension to the previously defined class */ + appendChild($$,$6); + appendChild(current_class,$$); + } else { + /* We store the extensions in the extensions hash */ + Node *am = Getattr(extendhash,clsname); + if (am) { + /* Append the members to the previous extend methods */ + appendChild(am,$6); + } else { + appendChild($$,$6); + Setattr(extendhash,clsname,$$); + } + } + current_class = 0; + Delete(Classprefix); + Delete(clsname); + Classprefix = 0; + prev_symtab = 0; + $$ = 0; + } + ; + +/* ------------------------------------------------------------ + %apply + ------------------------------------------------------------ */ + +apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE { + $$ = new_node("apply"); + Setattr($$,"pattern",Getattr($2,"pattern")); + appendChild($$,$4); + }; + +/* ------------------------------------------------------------ + %clear + ------------------------------------------------------------ */ + +clear_directive : CLEAR tm_list SEMI { + $$ = new_node("clear"); + appendChild($$,$2); + } + ; + +/* ------------------------------------------------------------ + %constant name = value; + %constant type name = value; + ------------------------------------------------------------ */ + +constant_directive : CONSTANT ID EQUAL definetype SEMI { + if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { + $$ = new_node("constant"); + Setattr($$,"name",$2); + Setattr($$,"type",NewSwigType($4.type)); + Setattr($$,"value",$4.val); + Setattr($$,"storage","%constant"); + Setattr($$,"feature:immutable","1"); + add_symbols($$); + } else { + if ($4.type == T_ERROR) { + Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n"); + } + $$ = 0; + } + + } + + | CONSTANT type declarator def_args SEMI { + if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { + SwigType_push($2,$3.type); + /* Sneaky callback function trick */ + if (SwigType_isfunction($2)) { + SwigType_add_pointer($2); + } + $$ = new_node("constant"); + Setattr($$,"name",$3.id); + Setattr($$,"type",$2); + Setattr($$,"value",$4.val); + Setattr($$,"storage","%constant"); + Setattr($$,"feature:immutable","1"); + add_symbols($$); + } else { + if ($4.type == T_ERROR) { + Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n"); + } + $$ = 0; + } + } + | CONSTANT error SEMI { + Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n"); + $$ = 0; + } + ; + +/* ------------------------------------------------------------ + %echo "text" + %echo %{ ... %} + ------------------------------------------------------------ */ + +echo_directive : ECHO HBLOCK { + char temp[64]; + Replace($2,"$file",cparse_file, DOH_REPLACE_ANY); + sprintf(temp,"%d", cparse_line); + Replace($2,"$line",temp,DOH_REPLACE_ANY); + Printf(stderr,"%s\n", $2); + Delete($2); + $$ = 0; + } + | ECHO string { + char temp[64]; + String *s = NewString($2); + Replace(s,"$file",cparse_file, DOH_REPLACE_ANY); + sprintf(temp,"%d", cparse_line); + Replace(s,"$line",temp,DOH_REPLACE_ANY); + Printf(stderr,"%s\n", s); + Delete(s); + $$ = 0; + } + ; + +/* ------------------------------------------------------------ + %except(lang) { ... } + %except { ... } + %except(lang); + %except; + ------------------------------------------------------------ */ + +except_directive : EXCEPT LPAREN ID RPAREN LBRACE { + skip_balanced('{','}'); + $$ = 0; + Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead."); + } + + | EXCEPT LBRACE { + skip_balanced('{','}'); + $$ = 0; + Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead."); + } + + | EXCEPT LPAREN ID RPAREN SEMI { + $$ = 0; + Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead."); + } + + | EXCEPT SEMI { + $$ = 0; + Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead."); + } + ; + +/* ------------------------------------------------------------ + %fragment(name,location) { ... } + ------------------------------------------------------------ */ + +fragment_directive: FRAGMENT LPAREN idstring COMMA idstring RPAREN HBLOCK { + $$ = new_node("fragment"); + Setattr($$,"section", $5); + Setattr($$,"name",$3); + Setattr($$,"code",$7); + } + | FRAGMENT LPAREN idstring COMMA idstring RPAREN LBRACE { + skip_balanced('{','}'); + $$ = new_node("fragment"); + Setattr($$,"section",$5); + Setattr($$,"name",$3); + Delitem(scanner_ccode,0); + Delitem(scanner_ccode,DOH_END); + Setattr($$,"code",Copy(scanner_ccode)); + } + ; + +/* ------------------------------------------------------------ + %includefile "filename" [ declarations ] + %importfile "filename" [ declarations ] + ------------------------------------------------------------ */ + +include_directive: includetype options string LBRACKET { + $1.filename = Swig_copy_string(cparse_file); + $1.line = cparse_line; + cparse_file = Swig_copy_string($3); + cparse_line = 0; + } interface RBRACKET { + $$ = $6; + cparse_file = $1.filename; + cparse_line = $1.line; + if (strcmp($1.type,"include") == 0) set_nodeType($$,"include"); + if (strcmp($1.type,"import") == 0) set_nodeType($$,"import"); + Setattr($$,"name",$3); + /* Search for the module (if any) */ + { + Node *n = firstChild($$); + while (n) { + if (Strcmp(nodeType(n),"module") == 0) { + Setattr($$,"module",Getattr(n,"name")); + break; + } + n = nextSibling(n); + } + } + Setattr($$,"options",$2); + } + ; + +includetype : INCLUDE { $$.type = (char *) "include"; } + | IMPORT { $$.type = (char *) "import"; } + ; + +/* ------------------------------------------------------------ + %inline %{ ... %} + ------------------------------------------------------------ */ + +inline_directive : INLINE HBLOCK { + String *cpps; + if (Namespaceprefix) { + Swig_error(cparse_file, cparse_start_line, "Error. %%inline directive inside a namespace is disallowed.\n"); + + $$ = 0; + } else { + $$ = new_node("insert"); + Setattr($$,"code",$2); + /* Need to run through the preprocessor */ + Setline($2,cparse_start_line); + Setfile($2,cparse_file); + Seek($2,0,SEEK_SET); + cpps = Preprocessor_parse($2); + start_inline(Char(cpps), cparse_start_line); + Delete($2); + Delete(cpps); + } + } + ; + +/* ------------------------------------------------------------ + %{ ... %} + %insert(section) "filename" + %insert("section") "filename" + %insert(section) %{ ... %} + %insert("section") %{ ... %} + ------------------------------------------------------------ */ + +insert_directive : HBLOCK { + $$ = new_node("insert"); + Setattr($$,"code",$1); + } + | INSERT LPAREN idstring RPAREN string { + String *code = NewString(""); + $$ = new_node("insert"); + Setattr($$,"section",$3); + Setattr($$,"code",code); + if (Swig_insert_file($5,code) < 0) { + Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5); + $$ = 0; + } + } + | INSERT LPAREN idstring RPAREN HBLOCK { + $$ = new_node("insert"); + Setattr($$,"section",$3); + Setattr($$,"code",$5); + } + | INSERT LPAREN idstring RPAREN LBRACE { + skip_balanced('{','}'); + $$ = new_node("insert"); + Setattr($$,"section",$3); + Delitem(scanner_ccode,0); + Delitem(scanner_ccode,DOH_END); + Setattr($$,"code", Copy(scanner_ccode)); + } + ; + +/* ------------------------------------------------------------ + %module modname + %module "modname" + ------------------------------------------------------------ */ + +module_directive: MODULE options idstring { + $$ = new_node("module"); + Setattr($$,"name",$3); + if ($2) Setattr($$,"options",$2); + if (!ModuleName) ModuleName = NewString($3); + if (!module_node) module_node = $$; + } + ; + +/* ------------------------------------------------------------ + %name(newname) declaration + %name("newname") declaration + ------------------------------------------------------------ */ + +name_directive : NAME LPAREN idstring RPAREN { + yyrename = NewString($3); + $$ = 0; + } + | NAME LPAREN RPAREN { + $$ = 0; + Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n"); + } + ; + + +/* ------------------------------------------------------------ + %native(scriptname) name; + %native(scriptname) type name (parms); + ------------------------------------------------------------ */ + +native_directive : NATIVE LPAREN ID RPAREN storage_class ID SEMI { + $$ = new_node("native"); + Setattr($$,"name",$3); + Setattr($$,"wrap:name",$6); + add_symbols($$); + } + | NATIVE LPAREN ID RPAREN storage_class type declarator SEMI { + if (!SwigType_isfunction($7.type)) { + Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id); + $$ = 0; + } else { + Delete(SwigType_pop_function($7.type)); + /* Need check for function here */ + SwigType_push($6,$7.type); + $$ = new_node("native"); + Setattr($$,"name",$3); + Setattr($$,"wrap:name",$7.id); + Setattr($$,"type",$6); + Setattr($$,"parms",$7.parms); + Setattr($$,"decl",$7.type); + } + add_symbols($$); + } + ; + +/* ------------------------------------------------------------ + %pragma(lang) name=value + %pragma(lang) name + %pragma name = value + %pragma name + ------------------------------------------------------------ */ + +pragma_directive : PRAGMA pragma_lang ID EQUAL pragma_arg { + $$ = new_node("pragma"); + Setattr($$,"lang",$2); + Setattr($$,"name",$3); + Setattr($$,"value",$5); + } + | PRAGMA pragma_lang ID { + $$ = new_node("pragma"); + Setattr($$,"lang",$2); + Setattr($$,"name",$3); + } + ; + +pragma_arg : string { $$ = NewString($1); } + | HBLOCK { $$ = $1; } + ; + +pragma_lang : LPAREN ID RPAREN { $$ = $2; } + | empty { $$ = (char *) "swig"; } + ; + +/* ------------------------------------------------------------ + %rename identifier newname; + %rename identifier "newname"; + ------------------------------------------------------------ */ + +rename_directive : rename_namewarn declarator idstring SEMI { + SwigType *t = $2.type; + if (!Len(t)) t = 0; + if ($1) { + rename_add($2.id,t,$3); + } else { + namewarn_add($2.id,t,$3); + } + $$ = 0; + scanner_clear_rename(); + } + | rename_namewarn LPAREN idstring RPAREN declarator cpp_const SEMI { + String *fixname; + SwigType *t = $5.type; + fixname = feature_identifier_fix($5.id); + if (!Len(t)) t = 0; + /* Special declarator check */ + if (t) { + if ($6.qualifier) SwigType_push(t,$6.qualifier); + if (SwigType_isfunction(t)) { + SwigType *decl = SwigType_pop_function(t); + if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",fixname); + if ($1) { + rename_add(Char(nname),decl,$3); + } else { + namewarn_add(Char(nname),decl,$3); + } + Delete(nname); + } else { + if ($1) { + rename_add(Char(fixname),decl,$3); + } else { + namewarn_add(Char(fixname),decl,$3); + } + } + } else if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",fixname); + if ($1) { + rename_add(Char(nname),0,$3); + } else { + namewarn_add(Char(nname),0,$3); + } + Delete(nname); + } + } else { + if ($1) { + rename_add(Char(fixname),0,$3); + } else { + namewarn_add(Char(fixname),0,$3); + } + } + $$ = 0; + scanner_clear_rename(); + } + | rename_namewarn LPAREN idstring RPAREN string SEMI { + if ($1) { + rename_add($5,0,$3); + } else { + namewarn_add($5,0,$3); + } + $$ = 0; + scanner_clear_rename(); + } + ; + +rename_namewarn : RENAME { + $$ = 1; + } + | NAMEWARN { + $$ = 0; + }; + + +/* ------------------------------------------------------------ + %feature(featurename) name { val } + %feature(featurename) name "val"; + %feature(featurename) name %{ val % } + %feature(featurename,val) name; + ------------------------------------------------------------ */ + + +feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi { + String *fname; + String *val; + String *name; + String *fixname; + SwigType *t; + if (!features_hash) features_hash = NewHash(); + fname = NewStringf("feature:%s",$3); + fixname = feature_identifier_fix($5.id); + if (Namespaceprefix) { + name = NewStringf("%s::%s",Namespaceprefix, fixname); + } else { + name = fixname; + } + val = $7 ? NewString($7) : NewString("1"); + if ($5.parms) { + Setmeta(val,"parms",$5.parms); + } + t = $5.type; + if ($5.parms) Setmeta(val,"parms",$5.parms); + if (!Len(t)) t = 0; + if (t) { + if ($6.qualifier) SwigType_push(t,$6.qualifier); + if (SwigType_isfunction(t)) { + SwigType *decl = SwigType_pop_function(t); + if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",name); + Swig_feature_set(features_hash, nname, decl, fname, val); + Delete(nname); + } else { + Swig_feature_set(features_hash, name, decl, fname, val); + } + } else if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",name); + Swig_feature_set(features_hash,nname,0,fname,val); + Delete(nname); + } + } else { + Swig_feature_set(features_hash,name,0,fname,val); + } + Delete(fname); + Delete(name); + $$ = 0; + } + + /* Special form where value is included in (...) part */ + + | FEATURE LPAREN idstring COMMA idstring RPAREN declarator cpp_const SEMI { + String *fname; + String *val; + String *name; + String *fixname; + SwigType *t; + + if (!features_hash) features_hash = NewHash(); + fname = NewStringf("feature:%s",$3); + fixname = feature_identifier_fix($7.id); + if (Namespaceprefix) { + name = NewStringf("%s::%s",Namespaceprefix, fixname); + } else { + name = fixname; + } + if (Len($5)) { + val = NewString($5); + } else { + val = 0; + } + if ($7.parms) { + Setmeta(val,"parms",$7.parms); + } + t = $7.type; + if ($7.parms) Setmeta(val,"parms",$7.parms); + if (!Len(t)) t = 0; + if (t) { + if ($8.qualifier) SwigType_push(t,$8.qualifier); + if (SwigType_isfunction(t)) { + SwigType *decl = SwigType_pop_function(t); + if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",name); + Swig_feature_set(features_hash, nname, decl, fname, val); + Delete(nname); + } else { + Swig_feature_set(features_hash, name, decl, fname, val); + } + } else if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",name); + Swig_feature_set(features_hash,nname,0,fname,val); + Delete(nname); + } + } else { + Swig_feature_set(features_hash,name,0,fname,val); + } + Delete(fname); + Delete(name); + $$ = 0; + } + + /* Global feature */ + + | FEATURE LPAREN idstring RPAREN stringbracesemi { + String *name; + String *fname = NewStringf("feature:%s",$3); + if (!features_hash) features_hash = NewHash(); + if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix); + else name = NewString(""); + Swig_feature_set(features_hash,name,0,fname,($5 ? NewString($5) : NewString("1"))); + Delete(name); + Delete(fname); + $$ = 0; + } + | FEATURE LPAREN idstring COMMA idstring RPAREN SEMI { + String *name; + String *fname = NewStringf("feature:%s",$3); + if (!features_hash) features_hash = NewHash(); + if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix); + else name = NewString(""); + Swig_feature_set(features_hash,name,0,fname,(Len($5) ? NewString($5) : 0)); + Delete(name); + Delete(fname); + $$ = 0; + } + ; + +stringbracesemi : stringbrace { $$ = $1; } + | SEMI { $$ = 0; } + | PARMS LPAREN parms RPAREN SEMI { $$ = $3; } + ; + +/* %varargs() directive. */ + +varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI { + Parm *val; + String *name; + SwigType *t; + if (!features_hash) features_hash = NewHash(); + if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id); + else name = NewString($5.id); + val = $3; + if ($5.parms) { + Setmeta(val,"parms",$5.parms); + } + t = $5.type; + if (!Len(t)) t = 0; + if (t) { + if ($6.qualifier) SwigType_push(t,$6.qualifier); + if (SwigType_isfunction(t)) { + SwigType *decl = SwigType_pop_function(t); + if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",name); + Swig_feature_set(features_hash, nname, decl, "feature:varargs", val); + Delete(nname); + } else { + Swig_feature_set(features_hash, name, decl, "feature:varargs", val); + } + } else if (SwigType_ispointer(t)) { + String *nname = NewStringf("*%s",name); + Swig_feature_set(features_hash,nname,0,"feature:varargs",val); + Delete(nname); + } + } else { + Swig_feature_set(features_hash,name,0,"feature:varargs",val); + } + Delete(name); + $$ = 0; + }; + +varargs_parms : parms { $$ = $1; } + | NUM_INT COMMA parm { + int i; + int n; + Parm *p; + n = atoi(Char($1.val)); + if (n <= 0) { + Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n"); + $$ = 0; + } else { + $$ = Copy($3); + Setattr($$,"name","VARARGS_SENTINEL"); + for (i = 0; i < n; i++) { + p = Copy($3); + set_nextSibling(p,$$); + $$ = p; + } + } + } + ; + + +/* ------------------------------------------------------------ + %typemap(method) type { ... } + %typemap(method) type "..." + %typemap(method) type; - typemap deletion + %typemap(method) type1,type2,... = type; - typemap copy + %typemap type1,type2,... = type; - typemap copy + ------------------------------------------------------------ */ + +typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace { + $$ = 0; + if ($3.op) { + $$ = new_node("typemap"); + Setattr($$,"method",$3.op); + Setattr($$,"code",NewString($6)); + if ($3.kwargs) { + Setattr($$,"kwargs", $3.kwargs); + } + appendChild($$,$5); + } + } + | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI { + $$ = 0; + if ($3.op) { + $$ = new_node("typemap"); + Setattr($$,"method",$3.op); + appendChild($$,$5); + } + } + | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI { + $$ = 0; + if ($3.op) { + $$ = new_node("typemapcopy"); + Setattr($$,"method",$3.op); + Setattr($$,"pattern", Getattr($7,"pattern")); + appendChild($$,$5); + } + } + ; + +/* typemap method type (lang,method) or (method) */ + +typemap_type : kwargs { + Hash *p; + String *name; + p = nextSibling($1); + if (p && (!Getattr(p,"value"))) { + /* two argument typemap form */ + name = Getattr($1,"name"); + if (!name || (Strcmp(name,typemap_lang))) { + $$.op = 0; + $$.kwargs = 0; + } else { + $$.op = Getattr(p,"name"); + $$.kwargs = nextSibling(p); + } + } else { + /* one-argument typemap-form */ + $$.op = Getattr($1,"name"); + $$.kwargs = p; + } + } + ; + +tm_list : typemap_parm tm_tail { + $$ = $1; + set_nextSibling($$,$2); + } + ; + +tm_tail : COMMA typemap_parm tm_tail { + $$ = $2; + set_nextSibling($$,$3); + } + | empty { $$ = 0;} + ; + +typemap_parm : type typemap_parameter_declarator { + SwigType_push($1,$2.type); + $$ = new_node("typemapitem"); + Setattr($$,"pattern",NewParm($1,$2.id)); + Setattr($$,"parms", $2.parms); + /* $$ = NewParm($1,$2.id); + Setattr($$,"parms",$2.parms); */ + } + | LPAREN parms RPAREN { + $$ = new_node("typemapitem"); + Setattr($$,"pattern",$2); + /* Setattr($$,"multitype",$2); */ + } + | LPAREN parms RPAREN LPAREN parms RPAREN { + $$ = new_node("typemapitem"); + Setattr($$,"pattern", $2); + /* Setattr($$,"multitype",$2); */ + Setattr($$,"parms",$5); + } + ; + +/* ------------------------------------------------------------ + %types(parmlist); + ------------------------------------------------------------ */ + +types_directive : TYPES LPAREN parms RPAREN SEMI { + $$ = new_node("types"); + Setattr($$,"parms",$3); + } + ; + +/* ------------------------------------------------------------ + %template(name) tname; + ------------------------------------------------------------ */ + +template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI { + Parm *p, *tp; + Node *n; + Node *nspace = 0, *nspace_inner = 0; + Node *tnode = 0; + Symtab *tscope = 0; + int specialized = 0; + $$ = 0; + + tscope = Swig_symbol_current(); /* Get the current scope */ + + /* If the template name is qualified. We need to create or lookup namespace entries */ + if (Swig_scopename_check($5)) { + String *prefix, *base; + Node *ns; + prefix = Swig_scopename_prefix($5); + base = Swig_scopename_last($5); + + /* Try to locate the scope */ + ns = Swig_symbol_clookup(prefix,0); + if (!ns) { + Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix); + } else { + if (Strcmp(nodeType(ns),"namespace") != 0) { + Swig_error(cparse_file,cparse_line,"'%s' is not defined as namespace.\n", prefix); + ns = 0; + } else { + /* Swig_symbol_setscope(Getattr(ns,"symtab")); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); */ + } + } + + /* Create namespace nodes to enclose the template declaration */ + if (ns) { + List *scopes; + String *sname; + String *name = NewString(prefix); + scopes = NewList(); + while (name) { + String *tprefix; + String *base = Swig_scopename_last(name); + Insert(scopes,0,base); + tprefix = Swig_scopename_prefix(name); + Delete(name); + name = tprefix; + } + for (sname = Firstitem(scopes); sname; sname = Nextitem(scopes)) { + Node *ns1,*ns2; + + ns1 = Swig_symbol_clookup(sname,0); + assert(ns1); + if (Strcmp(nodeType(ns1),"namespace") == 0) { + if (Getattr(ns1,"alias")) { + ns1 = Getattr(ns1,"namespace"); + } + } else { + assert(0); + } + ns2 = new_node("namespace"); + Setattr(ns2,"name",sname); + Setattr(ns2,"symtab", Getattr(ns1,"symtab")); + add_symbols(ns2); + Swig_symbol_setscope(Getattr(ns1,"symtab")); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + if (nspace_inner) { + appendChild(nspace_inner,ns2); + } + nspace_inner = ns2; + if (!nspace) nspace = ns2; + } + $5 = base; + } + } + + n = Swig_cparse_template_locate($5,$7); + + /* Patch the argument types to respect namespaces */ + p = $7; + while (p) { + if (!Getattr(p,"value")) { + SwigType *ty = Getattr(p,"type"); + if (ty) { + ty = Swig_symbol_type_qualify(ty,0); + /* ty = Swig_symbol_typedef_reduce(ty,0); */ + Setattr(p,"type",ty); + } + } + p = nextSibling(p); + } + /* Look for the template */ + + if (n && (Strcmp(nodeType(n),"template") == 0)) { + Parm *tparms = Getattr(n,"templateparms"); + if (!tparms) specialized = 1; + if (!specialized && ((ParmList_len($7) > ParmList_len(tparms)))) { + Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms)); + } else if (!specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) { + Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms)); + } else { + int def_supplied = 0; + /* Expand the template */ + ParmList *temparms; + if (specialized) temparms = CopyParmList($7); + else temparms = CopyParmList(tparms); + /* Create typedef's and arguments */ + p = $7; + tp = temparms; + while (p) { + String *value = Getattr(p,"value"); + if (def_supplied) { + Setattr(p,"default","1"); + } + if (value) { + Setattr(tp,"value",value); + } else { + SwigType *ty = Getattr(p,"type"); + if (ty) { + Setattr(tp,"type",ty); + } + Delattr(tp,"value"); + } + p = nextSibling(p); + tp = nextSibling(tp); + if (!p && tp) { + p = tp; + def_supplied = 1; + } + } + + $$ = copy_node(n); + /* We need to set the node name based on name used to instantiate */ + Setattr($$,"name",Copy($5)); + if (!specialized) { + Delattr($$,"sym:typename"); + } else { + Setattr($$,"sym:typename","1"); + } + if ($3) { + Swig_cparse_template_expand($$,$3,temparms); + Setattr($$,"sym:name",$3); + } else { + static int cnt = 0; + String *nname = NewStringf("__dummy_%d__", cnt++); + Swig_cparse_template_expand($$,nname,temparms); + Setattr($$,"sym:name",nname); + Setattr($$,"feature:ignore","1"); + } + Delattr($$,"templatetype"); + Setattr($$,"template",n); + tnode = $$; + Setfile($$,cparse_file); + Setline($$,cparse_line); + Delete(temparms); + + add_symbols_copy($$); + if (Strcmp(nodeType($$),"class") == 0) { + + /* Identify pure abstract methods */ + Setattr($$,"abstract", pure_abstract(firstChild($$))); + + /* Set up inheritance in symbol table */ + { + Symtab *csyms; + List *baselist = Getattr($$,"baselist"); + csyms = Swig_symbol_current(); + Swig_symbol_setscope(Getattr($$,"symtab")); + if (baselist) { + List *bases = make_inherit_list(Getattr($$,"name"),baselist); + if (bases) { + Node *s; + for (s = Firstitem(bases); s; s = Nextitem(bases)) { + Symtab *st = Getattr(s,"symtab"); + if (st) { + Swig_symbol_inherit(st); + } + } + } + } + Swig_symbol_setscope(csyms); + } + + /* Merge in addmethods for this class */ + + /* !!! This may be broken. We may have to + add the addmethods at the beginning of + the class */ + + if (extendhash) { + String *clsname; + Node *am; + if (Namespaceprefix) { + clsname = NewStringf("%s::%s", Namespaceprefix, Getattr($$,"name")); + } else { + clsname = Getattr($$,"name"); + } + am = Getattr(extendhash,clsname); + if (am) { + merge_extensions(am); + appendChild($$,am); + Delattr(extendhash,clsname); + } + } + /* Add to classes hash */ + if (!classes) classes = NewHash(); + Setattr(classes,Swig_symbol_qualifiedscopename($$),$$); + } + } + if ($$ && nspace) { + appendChild(nspace_inner,$$); + $$ = nspace; + } + } + Swig_symbol_setscope(tscope); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + + } + ; + +/* ------------------------------------------------------------ + %warn "text" + %warn(no) + ------------------------------------------------------------ */ + +warn_directive : WARN string { + Swig_warning(0,cparse_file, cparse_line,"%s\n", $2); + $$ = 0; + } + ; + +/* ====================================================================== + * C Parsing + * ====================================================================== */ + +c_declaration : c_decl { + $$ = $1; + if ($$) { + add_symbols($$); + } + } + | c_enum_decl { $$ = $1; } + +/* A an extern C type declaration. Does nothing, but is ignored */ + + | EXTERN string LBRACE interface RBRACE { + if (Strcmp($2,"C") == 0) { + $$ = new_node("extern"); + Setattr($$,"name",$2); + appendChild($$,firstChild($4)); + } else { + Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", $2); + $$ = 0; + } + } + ; + +/* ------------------------------------------------------------ + A C global declaration of some kind (may be variable, function, typedef, etc.) + ------------------------------------------------------------ */ + +c_decl : storage_class type declarator initializer c_decl_tail { + $$ = new_node("cdecl"); + if ($4.qualifier) SwigType_push($3.type,$4.qualifier); + Setattr($$,"type",$2); + Setattr($$,"storage",$1); + Setattr($$,"name",$3.id); + Setattr($$,"decl",$3.type); + Setattr($$,"parms",$3.parms); + Setattr($$,"value",$4.val); + Setattr($$,"throws",$4.throws); + if (!$5) { + if (Len(scanner_ccode)) { + Setattr($$,"code",Copy(scanner_ccode)); + } + } else { + Node *n = $5; + /* Inherit attributes */ + while (n) { + Setattr(n,"type",Copy($2)); + Setattr(n,"storage",$1); + n = nextSibling(n); + } + } + if ($4.bitfield) { + Setattr($$,"bitfield", $4.bitfield); + } + + /* Look for "::" declarations (ignored) */ + if (Strstr($3.id,"::")) { + Delete($$); + $$ = $5; + } else { + set_nextSibling($$,$5); + } + } + ; + +/* Allow lists of variables and functions to be built up */ + +c_decl_tail : SEMI { + $$ = 0; + Clear(scanner_ccode); + } + | COMMA declarator initializer c_decl_tail { + $$ = new_node("cdecl"); + if ($3.qualifier) SwigType_push($2.type,$3.qualifier); + Setattr($$,"name",$2.id); + Setattr($$,"decl",$2.type); + Setattr($$,"parms",$2.parms); + Setattr($$,"value",$3.val); + Setattr($$,"throws",$3.throws); + if ($3.bitfield) { + Setattr($$,"bitfield", $3.bitfield); + } + if (!$4) { + if (Len(scanner_ccode)) { + Setattr($$,"code",Copy(scanner_ccode)); + } + } else { + set_nextSibling($$,$4); + } + } + | LBRACE { + skip_balanced('{','}'); + $$ = 0; + } + ; + +initializer : def_args { + $$ = $1; + $$.qualifier = 0; + $$.throws = 0; + } + | type_qualifier def_args { + $$ = $2; + $$.qualifier = $1; + $$.throws = 0; + } + | THROW LPAREN parms RPAREN def_args { + $$ = $5; + $$.qualifier = 0; + $$.throws = $3; + } + | type_qualifier THROW LPAREN parms RPAREN def_args { + $$ = $6; + $$.qualifier = $1; + $$.throws = $4; + } + ; + + +/* ------------------------------------------------------------ + enum { ... } + * ------------------------------------------------------------ */ + +c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI { + $$ = new_node("enum"); + Setattr($$,"name",$3); + appendChild($$,$5); + add_symbols($$); /* Add to tag space */ + add_symbols($5); /* Add enum values to id space */ + } + + | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail { + Node *n; + SwigType *ty = 0; + String *unnamed = 0; + + $$ = new_node("enum"); + if ($3) { + Setattr($$,"name",$3); + ty = NewStringf("enum %s", $3); + } else if ($7.id){ + unnamed = make_unnamed(); + ty = NewStringf("enum %s", unnamed); + Setattr($$,"unnamed",unnamed); + /* WF 20/12/2001: Cannot get sym:name and symtab set without setting name - fix! + // I don't think sym:name should be set. */ + Setattr($$,"name",$7.id); + Setattr($$,"tdname",$7.id); + Setattr($$,"storage",$1); + } + appendChild($$,$5); + n = new_node("cdecl"); + Setattr(n,"type",ty); + Setattr(n,"name",$7.id); + Setattr(n,"storage",$1); + Setattr(n,"decl",$7.type); + Setattr(n,"parms",$7.parms); + Setattr(n,"unnamed",unnamed); + if ($8) { + Node *p = $8; + set_nextSibling(n,p); + while (p) { + Setattr(p,"type",Copy(ty)); + Setattr(p,"unnamed",unnamed); + Setattr(p,"storage",$1); + p = nextSibling(p); + } + } else { + if (Len(scanner_ccode)) { + Setattr(n,"code",Copy(scanner_ccode)); + } + } + add_symbols($$); /* Add enum to tag space */ + set_nextSibling($$,n); + add_symbols($5); /* Add to id space */ + add_symbols(n); + } + ; + +c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { + /* This is a sick hack. If the ctor_end has parameters, + and the parms paremeter only has 1 parameter, this + could be a declaration of the form: + + type (id)(parms) + + Otherwise it's an error. */ + int err = 0; + $$ = 0; + + if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) { + SwigType *ty = Getattr($4,"type"); + String *name = Getattr($4,"name"); + err = 1; + if (!name) { + $$ = new_node("cdecl"); + Setattr($$,"type",$2); + Setattr($$,"storage",$1); + Setattr($$,"name",ty); + + if ($6.have_parms) { + SwigType *decl = NewString(""); + SwigType_add_function(decl,$6.parms); + Setattr($$,"decl",decl); + Setattr($$,"parms",$6.parms); + if (Len(scanner_ccode)) { + Setattr($$,"code",Copy(scanner_ccode)); + } + } + if ($6.defarg) { + Setattr($$,"value",$6.defarg); + } + Setattr($$,"throws",$6.throws); + err = 0; + } + } + if (err) { + Swig_error(cparse_file,cparse_line,"Syntax error in input.\n"); + } + } + ; + +/* ====================================================================== + * C++ Support + * ====================================================================== */ + +cpp_declaration : cpp_class_decl { $$ = $1; } + | cpp_forward_class_decl { $$ = $1; } + | cpp_template_decl { $$ = $1; } + | cpp_using_decl { $$ = $1; } + | cpp_namespace_decl { $$ = $1; } + | cpp_catch_decl { $$ = 0; } + ; + +cpp_class_decl : + +/* A simple class/struct/union definition */ + storage_class cpptype idcolon inherit LBRACE { + List *bases = 0; + class_rename = make_name($3,0); + Classprefix = NewString($3); + /* Deal with inheritance */ + if ($4) { + bases = make_inherit_list($3,$4); + } + if (SwigType_istemplate($3)) { + String *fbase, *tbase, *prefix; + prefix = SwigType_templateprefix($3); + if (Namespaceprefix) { + fbase = NewStringf("%s::%s", Namespaceprefix,$3); + tbase = NewStringf("%s::%s", Namespaceprefix, prefix); + } else { + fbase = Copy($3); + tbase = Copy(prefix); + } + rename_inherit(tbase,fbase); + Delete(fbase); + Delete(tbase); + Delete(prefix); + } + if (strcmp($2,"class") == 0) { + cplus_mode = CPLUS_PRIVATE; + } else { + cplus_mode = CPLUS_PUBLIC; + } + Swig_symbol_newscope(); + Swig_symbol_setscopename($3); + if (bases) { + Node *s; + for (s = Firstitem(bases); s; s = Nextitem(bases)) { + Symtab *st = Getattr(s,"symtab"); + if (st) { + Swig_symbol_inherit(st); + } + } + } + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + cparse_start_line = cparse_line; + + /* If there are active template parameters, we need to make sure they are + placed in the class symbol table so we can catch shadows */ + + if (template_parameters) { + Parm *tp = template_parameters; + while(tp) { + Node *tn = new_node("templateparm"); + Setattr(tn,"name",Getattr(tp,"name")); + Swig_symbol_cadd(Copy(Getattr(tp,"name")),tn); + tp = nextSibling(tp); + } + } + inclass = 1; + } cpp_members RBRACE cpp_opt_declarators { + Node *p; + SwigType *ty; + inclass = 0; + $$ = new_node("class"); + Setline($$,cparse_start_line); + Setattr($$,"name",$3); + Setattr($$,"kind",$2); + Setattr($$,"baselist",$4); + Setattr($$,"allows_typedef","1"); + /* Check for pure-abstract class */ + Setattr($$,"abstract", pure_abstract($7)); + + /* This bit of code merges in a previously defined %extend directive (if any) */ + if (extendhash) { + String *clsname = Swig_symbol_qualifiedscopename(0); + Node *am = Getattr(extendhash,clsname); + if (am) { + merge_extensions(am); + appendChild($$,am); + Delattr(extendhash,clsname); + } + Delete(clsname); + } + if (!classes) classes = NewHash(); + Setattr(classes,Swig_symbol_qualifiedscopename(0),$$); + + + appendChild($$,$7); + p = $9; + if (p) { + set_nextSibling($$,p); + } + + if (cparse_cplusplus) { + ty = NewString($3); + } else { + ty = NewStringf("%s %s", $2,$3); + } + while (p) { + Setattr(p,"storage",$1); + Setattr(p,"type",ty); + p = nextSibling(p); + } + /* Dump nested classes */ + { + String *name = $3; + if ($9) { + SwigType *decltype = Getattr($9,"decl"); + if (Cmp($1,"typedef") == 0) { + if (!decltype || !Len(decltype)) { + name = Getattr($9,"name"); + Setattr($$,"tdname",Copy(name)); + + /* Use typedef name as class name */ + if (class_rename && (Strcmp(class_rename,$3) == 0)) { + class_rename = NewString(name); + } + if (!Getattr(classes,name)) { + Setattr(classes,name,$$); + } + Setattr($$,"decl",decltype); + } + } + } + appendChild($$,dump_nested(Char(name))); + } + Setattr($$,"symtab",Swig_symbol_popscope()); + + yyrename = NewString(class_rename); + Classprefix = 0; + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + add_symbols($$); + if ($9) + add_symbols($9); + + } + +/* An unnamed struct, possibly with a typedef */ + + | storage_class cpptype LBRACE { + class_rename = make_name(0,0); + if (strcmp($2,"class") == 0) { + cplus_mode = CPLUS_PRIVATE; + } else { + cplus_mode = CPLUS_PUBLIC; + } + Swig_symbol_newscope(); + cparse_start_line = cparse_line; + inclass = 1; + Classprefix = NewString(""); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + } cpp_members RBRACE declarator c_decl_tail { + String *unnamed; + Node *n, *p, *pp = 0; + Classprefix = 0; + inclass = 0; + unnamed = make_unnamed(); + $$ = new_node("class"); + Setline($$,cparse_start_line); + Setattr($$,"kind",$2); + Setattr($$,"storage",$1); + Setattr($$,"unnamed",unnamed); + Setattr($$,"allows_typedef","1"); + + /* Check for pure-abstract class */ + Setattr($$,"abstract", pure_abstract($5)); + + n = new_node("cdecl"); + Setattr(n,"name",$7.id); + Setattr(n,"unnamed",unnamed); + Setattr(n,"type",unnamed); + Setattr(n,"decl",$7.type); + Setattr(n,"parms",$7.parms); + Setattr(n,"storage",$1); + pp = n; + if ($8) { + set_nextSibling(n,$8); + p = $8; + while (p) { + pp = p; + Setattr(p,"unnamed",unnamed); + Setattr(p,"type",Copy(unnamed)); + Setattr(p,"storage",$1); + p = nextSibling(p); + } + } + set_nextSibling($$,n); + { + /* If a proper typedef name was given, we'll use it to set the scope name */ + String *name = 0; + if ($1 && (strcmp($1,"typedef") == 0)) { + if (!Len($7.type)) { + name = $7.id; + Setattr($$,"tdname",name); + Setattr($$,"name",name); + if (!class_rename) class_rename = NewString(name); + Swig_symbol_setscopename(name); + + /* If a proper name given, we use that as the typedef, not unnamed */ + Clear(unnamed); + Append(unnamed, name); + + n = nextSibling(n); + set_nextSibling($$,n); + + /* Check for previous extensions */ + if (extendhash) { + String *clsname = Swig_symbol_qualifiedscopename(0); + Node *am = Getattr(extendhash,clsname); + if (am) { + /* Merge the extension into the symbol table */ + merge_extensions(am); + appendChild($$,am); + Delattr(extendhash,clsname); + } + Delete(clsname); + } + if (!classes) classes = NewHash(); + Setattr(classes,Swig_symbol_qualifiedscopename(0),$$); + } else { + Swig_symbol_setscopename((char*)""); + } + } + appendChild($$,$5); + appendChild($$,dump_nested(Char(name))); + } + /* Pop the scope */ + Setattr($$,"symtab",Swig_symbol_popscope()); + if (class_rename) { + yyrename = NewString(class_rename); + } + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + add_symbols($$); + add_symbols(n); + } + ; + +cpp_opt_declarators : SEMI { $$ = 0; } + | declarator c_decl_tail { + $$ = new_node("cdecl"); + Setattr($$,"name",$1.id); + Setattr($$,"decl",$1.type); + Setattr($$,"parms",$1.parms); + set_nextSibling($$,$2); + } + ; +/* ------------------------------------------------------------ + class Name; + ------------------------------------------------------------ */ + +cpp_forward_class_decl : storage_class cpptype idcolon SEMI { + if ($1 && (Strcmp($1,"friend") == 0)) { + /* Ignore */ + $$ = 0; + } else { + $$ = new_node("classforward"); + Setattr($$,"kind",$2); + Setattr($$,"name",$3); + Setattr($$,"sym:weak", "1"); + add_symbols($$); + } + } + ; + +/* ------------------------------------------------------------ + template<...> decl + ------------------------------------------------------------ */ + +cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible { + String *tname = 0; + int error = 0; + + template_parameters = 0; + $$ = $6; + if ($$) tname = Getattr($$,"name"); + + /* Check if the class is a template specialization */ + if (($$) && (Strstr(tname,"<")) && (Strncmp(tname,"operator ",9) != 0)) { + /* If a specialization. Check if defined. */ + Node *tempn = 0; + { + String *tbase = SwigType_templateprefix(tname); + tempn = Swig_symbol_clookup_local(tbase,0); + if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) { + Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase); + tempn = 0; + error = 1; + } + Delete(tbase); + } + Setattr($$,"specialization","1"); + Setattr($$,"templatetype",nodeType($$)); + set_nodeType($$,"template"); + /* Template partial specialization */ + if (tempn && ($3) && ($6)) { + List *tlist; + String *targs = SwigType_templateargs(tname); + tlist = SwigType_parmlist(targs); + /* Printf(stdout,"targs = '%s'\n", targs); */ + if (!Getattr($$,"sym:weak")) { + Setattr($$,"sym:typename","1"); + } + /* Patch the parameter list */ + if (tempn) { + Parm *p,*p1; + ParmList *tp = CopyParmList(Getattr(tempn,"templateparms")); + p = $3; + p1 = tp; + while (p && p1) { + String *pn = Getattr(p,"name"); + if (pn) Setattr(p1,"name",pn); + pn = Getattr(p,"type"); + if (pn) Setattr(p1,"type",pn); + p = nextSibling(p); + p1 = nextSibling(p1); + } + Setattr($$,"templateparms",tp); + } else { + Setattr($$,"templateparms",$3); + } + Delattr($$,"specialization"); + Setattr($$,"partialspecialization","1"); + /* Create a specialized name for matching */ + { + Parm *p = $3; + String *fname = NewString(Getattr($$,"name")); + String *ffname = 0; + + char tmp[32]; + int i; + while (p) { + String *n = Getattr(p,"name"); + if (!n) { + p = nextSibling(p); + continue; + } + for (i = 0; i < Len(tlist); i++) { + if (Strstr(Getitem(tlist,i),n)) { + sprintf(tmp,"$%d",i+1); + Replaceid(fname,n,tmp); + } + } + p = nextSibling(p); + } + /* Patch argument names with typedef */ + { + SwigType *tt; + List *tparms = SwigType_parmlist(fname); + ffname = SwigType_templateprefix(fname); + Append(ffname,"<("); + for (tt = Firstitem(tparms); tt; ) { + SwigType *ttr = Swig_symbol_typedef_reduce(tt,0); + ttr = Swig_symbol_type_qualify(ttr,0); + Append(ffname,ttr); + tt = Nextitem(tparms); + if (tt) Putc(',',ffname); + } + Append(ffname,")>"); + } + { + String *partials = Getattr(tempn,"partials"); + if (!partials) { + partials = NewList(); + Setattr(tempn,"partials",partials); + } + /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */ + Append(partials,ffname); + } + Setattr($$,"partialargs",ffname); + Swig_symbol_cadd(ffname,$$); + } + Delete(tlist); + Delete(targs); + } else { + /* Need to resolve exact specialization name */ + /* This needs to be rewritten */ + List *tparms; + String *fname; + SwigType *tt; + fname = SwigType_templateprefix(tname); + tparms = SwigType_parmlist(tname); + Append(fname,"<("); + for (tt = Firstitem(tparms); tt; ) { + SwigType *ttr = Swig_symbol_typedef_reduce(tt,0); + ttr = Swig_symbol_type_qualify(ttr,0); + Append(fname,ttr); + tt = Nextitem(tparms); + if (tt) Putc(',',fname); + } + Append(fname,")>"); + Swig_symbol_cadd(fname,$$); + } + } else if ($$) { + Setattr($$,"templatetype",nodeType($6)); + set_nodeType($$,"template"); + Setattr($$,"templateparms", $3); + if (!Getattr($$,"sym:weak")) { + Setattr($$,"sym:typename","1"); + } + add_symbols($$); + /* We also place a fully parameterized version in the symbol table */ + { + Parm *p; + String *fname = NewStringf("%s<(",Getattr($$,"name")); + p = $3; + while (p) { + String *n = Getattr(p,"name"); + if (!n) n = Getattr(p,"type"); + Printf(fname,"%s", n); + p = nextSibling(p); + if (p) Putc(',',fname); + } + Printf(fname,")>"); + Swig_symbol_cadd(fname,$$); + } + } + if (error) $$ = 0; + } + ; + +cpp_temp_possible: c_decl { + $$ = $1; + } + | cpp_class_decl { + $$ = $1; + } + | cpp_constructor_decl { + $$ = $1; + } + | cpp_template_decl { + $$ = 0; + } + | cpp_forward_class_decl { + $$ = $1; + } + ; + +template_parms : rawparms { + /* Rip out the parameter names */ + Parm *p = $1; + $$ = $1; + + while (p) { + String *name = Getattr(p,"name"); + if (!name) { + /* Hmmm. Maybe it's a 'class T' parameter */ + char *type = Char(Getattr(p,"type")); + /* Template template parameter */ + if (strncmp(type,"template ",16) == 0) { + type += 16; + } + if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) { + char *t = strchr(type,' '); + Setattr(p,"name", t+1); + } else { + /* + Swig_error(cparse_file, cparse_line, "Missing template parameter name\n"); + $$.rparms = 0; + $$.parms = 0; + break; */ + } + } + p = nextSibling(p); + } + } + ; + +/* Namespace support */ + +cpp_using_decl : USING idcolon SEMI { + $$ = new_node("using"); + Setattr($$,"uname",$2); + Setattr($$,"name", Swig_scopename_last($2)); + add_symbols($$); + } + | USING NAMESPACE idcolon SEMI { + Node *n = Swig_symbol_clookup($3,0); + if (!n) { + Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3); + $$ = 0; + } else { + + while (Strcmp(nodeType(n),"using") == 0) { + n = Getattr(n,"node"); + } + if (n) { + if (Strcmp(nodeType(n),"namespace") == 0) { + $$ = new_node("using"); + Setattr($$,"node",n); + Setattr($$,"namespace", $3); + Swig_symbol_inherit(Getattr(n,"symtab")); + } else { + Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3); + $$ = 0; + } + } else { + $$ = 0; + } + } + } + ; + +cpp_namespace_decl : NAMESPACE idcolon LBRACE { + Hash *h; + $1 = Swig_symbol_current(); + h = Swig_symbol_clookup($2,0); + if (h && (Strcmp(nodeType(h),"namespace") == 0)) { + if (Getattr(h,"alias")) { + h = Getattr(h,"namespace"); + Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n", + $2, Getattr(h,"name")); + $2 = Getattr(h,"name"); + } + Swig_symbol_setscope(Getattr(h,"symtab")); + } else { + Swig_symbol_newscope(); + Swig_symbol_setscopename($2); + } + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + } interface RBRACE { + Node *n = $5; + set_nodeType(n,"namespace"); + Setattr(n,"name",$2); + Setattr(n,"symtab", Swig_symbol_popscope()); + Swig_symbol_setscope($1); + $$ = n; + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + add_symbols($$); + } + | NAMESPACE LBRACE { + Hash *h; + $1 = Swig_symbol_current(); + h = Swig_symbol_clookup("",0); + if (h && (Strcmp(nodeType(h),"namespace") == 0)) { + Swig_symbol_setscope(Getattr(h,"symtab")); + } else { + Swig_symbol_newscope(); + Swig_symbol_setscopename("__unnamed__"); + } + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + } interface RBRACE { + $$ = $4; + set_nodeType($$,"namespace"); + Setattr($$,"unnamed","1"); + Setattr($$,"symtab", Swig_symbol_popscope()); + Swig_symbol_setscope($1); + Namespaceprefix = Swig_symbol_qualifiedscopename(0); + add_symbols($$); + } + | NAMESPACE ID EQUAL idcolon SEMI { + /* Namespace alias */ + Node *n; + $$ = new_node("namespace"); + Setattr($$,"name",$2); + Setattr($$,"alias",$4); + n = Swig_symbol_clookup($4,0); + if (!n) { + Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4); + $$ = 0; + } else { + if (Strcmp(nodeType(n),"namespace") != 0) { + Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4); + $$ = 0; + } else { + while (Getattr(n,"alias")) { + n = Getattr(n,"namespace"); + } + Setattr($$,"namespace",n); + add_symbols($$); + /* Set up a scope alias */ + Swig_symbol_alias($2,Getattr(n,"symtab")); + } + } + } + ; + +cpp_members : cpp_member cpp_members { + $$ = $1; + if ($$) { + Node *p = $$; + Node *pp =0; + while (p) { + pp = p; + p = nextSibling(p); + } + set_nextSibling(pp,$2); + } else { + $$ = $2; + } + } + | EXTEND LBRACE { + if (cplus_mode != CPLUS_PUBLIC) { + Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n"); + } + } cpp_members RBRACE cpp_members { + $$ = new_node("extend"); + Swig_tag_nodes($4,"feature:extend",(char*) "1"); + appendChild($$,$4); + set_nextSibling($$,$6); + } + | empty { $$ = 0;} + | error { + skip_decl(); + { + static int last_error_line = -1; + if (last_error_line != cparse_line) { + Swig_error(cparse_file, cparse_line,"Syntax error in input.\n"); + last_error_line = cparse_line; + } + } + } cpp_members { + $$ = $3; + } + ; + +/* ====================================================================== + * C++ Class members + * ====================================================================== */ + +/* A class member. May be data or a function. Static or virtual as well */ + +cpp_member : c_declaration { $$ = $1; } + | cpp_constructor_decl { + $$ = $1; + add_symbols($$); + } + | cpp_destructor_decl { $$ = $1; } + | cpp_protection_decl { $$ = $1; } + | cpp_swig_directive { $$ = $1; } + | cpp_conversion_operator { $$ = $1; } + | cpp_forward_class_decl { $$ = $1; } + | cpp_nested { $$ = $1; } + | storage_class idcolon SEMI { $$ = 0; } + | cpp_using_decl { $$ = $1; } + | cpp_template_decl { $$ = $1; } + | cpp_catch_decl { $$ = 0; } + | template_directive { $$ = $1; } + | warn_directive { $$ = $1; } + | SEMI { $$ = 0; } + ; + +/* Possibly a constructor */ +/* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example: + typedef Foo (); + typedef Foo (*ptr)(); +*/ + +cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { + if (Classprefix) { + SwigType *decl = NewString(""); + $$ = new_node("constructor"); + + /* Since the parse performs type-corrections in template mode, we + have to undo the correction here. Ugh. */ + + /* Check for template names. If the class is a template + and the constructor is missing the template part, we + add it */ + /* { + char *c = Strstr(Classprefix,"<"); + if (c) { + if (!Strstr($2,"<")) { + Append($2,c); + } + } + } + */ + Setattr($$,"name",$2); + Setattr($$,"parms",$4); + SwigType_add_function(decl,$4); + Setattr($$,"decl",decl); + Setattr($$,"throws",$6.throws); + if (Len(scanner_ccode)) { + Setattr($$,"code",Copy(scanner_ccode)); + } + Setattr($$,"feature:new","1"); + } else { + $$ = 0; + } + } + ; + +/* A destructor (hopefully) */ + +cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end { + $$ = new_node("destructor"); + Setattr($$,"name",NewStringf("~%s",$2)); + if (Len(scanner_ccode)) { + Setattr($$,"code",Copy(scanner_ccode)); + } + { + String *decl = NewString(""); + SwigType_add_function(decl,$4); + Setattr($$,"decl",decl); + } + add_symbols($$); + } + +/* A virtual destructor */ + + | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend { + $$ = new_node("destructor"); + /* Check for template names. If the class is a template + and the constructor is missing the template part, we + add it */ + { + char *c = Strstr(Classprefix,"<"); + if (c) { + if (!Strstr($3,"<")) { + $3 = NewStringf("%s%s",$3,c); + } + } + } + Setattr($$,"storage","virtual"); + Setattr($$,"name",NewStringf("~%s",$3)); + if ($7.val) { + Setattr($$,"value","0"); + } + if (Len(scanner_ccode)) { + Setattr($$,"code",Copy(scanner_ccode)); + } + { + String *decl = NewString(""); + SwigType_add_function(decl,$5); + Setattr($$,"decl",decl); + } + + add_symbols($$); + } + ; + + +/* C++ type conversion operator */ +cpp_conversion_operator : storage_class COPERATOR type pointer LPAREN parms RPAREN cpp_vend { + $$ = new_node("cdecl"); + Setattr($$,"type",$3); + Setattr($$,"name",$2); + + SwigType_add_function($4,$6); + if ($8.qualifier) { + SwigType_push($4,$8.qualifier); + } + Setattr($$,"decl",$4); + Setattr($$,"parms",$6); + Setattr($$,"conversion_operator","1"); + add_symbols($$); + } + | storage_class COPERATOR type AND LPAREN parms RPAREN cpp_vend { + SwigType *decl; + $$ = new_node("cdecl"); + Setattr($$,"type",$3); + Setattr($$,"name",$2); + decl = NewString(""); + SwigType_add_reference(decl); + SwigType_add_function(decl,$6); + if ($8.qualifier) { + SwigType_push(decl,$8.qualifier); + } + Setattr($$,"decl",decl); + Setattr($$,"parms",$6); + Setattr($$,"conversion_operator","1"); + add_symbols($$); + } + + | storage_class COPERATOR type LPAREN parms RPAREN cpp_vend { + String *t = NewString(""); + $$ = new_node("cdecl"); + Setattr($$,"type",$3); + Setattr($$,"name",$2); + SwigType_add_function(t,$5); + if ($7.qualifier) { + SwigType_push(t,$7.qualifier); + } + Setattr($$,"decl",t); + Setattr($$,"parms",$5); + Setattr($$,"conversion_operator","1"); + add_symbols($$); + } + ; + +/* isolated catch clause. */ + +cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE { + skip_balanced('{','}'); + $$ = 0; + } + ; + +/* public: */ +cpp_protection_decl : PUBLIC COLON { + $$ = new_node("access"); + Setattr($$,"kind","public"); + cplus_mode = CPLUS_PUBLIC; + } + +/* private: */ + | PRIVATE COLON { + $$ = new_node("access"); + Setattr($$,"kind","private"); + cplus_mode = CPLUS_PRIVATE; + } + +/* protected: */ + + | PROTECTED COLON { + $$ = new_node("access"); + Setattr($$,"kind","protected"); + cplus_mode = CPLUS_PROTECTED; + } + ; + + +/* ---------------------------------------------------------------------- + Nested structure. This is a sick "hack". If we encounter + a nested structure, we're going to grab the text of its definition and + feed it back into the scanner. In the meantime, we need to grab + variable declaration information and generate the associated wrapper + code later. Yikes! + + This really only works in a limited sense. Since we use the + code attached to the nested class to generate both C/C++ code, + it can't have any SWIG directives in it. It also needs to be parsable + by SWIG or this whole thing is going to puke. + ---------------------------------------------------------------------- */ + +/* A struct sname { } id; declaration */ + +cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); + } nested_decl SEMI { + $$ = 0; + if (cplus_mode == CPLUS_PUBLIC) { + if ($6.id) { + if (strcmp($2,"class") == 0) { + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested classes not currently supported (ignored).\n"); + /* Generate some code for a new class */ + } else { + Nested *n = (Nested *) malloc(sizeof(Nested)); + n->code = NewString(""); + Printv(n->code, "typedef ", $2, " ", + Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL); + + n->name = Swig_copy_string($6.id); + n->line = cparse_start_line; + n->type = NewString(""); + n->kind = $2; + SwigType_push(n->type, $6.type); + n->next = 0; + add_nested(n); + } + } else { + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); + } + } + } + +/* An unnamed nested structure definition */ + | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); + } nested_decl SEMI { + $$ = 0; + if (cplus_mode == CPLUS_PUBLIC) { + if (strcmp($2,"class") == 0) { + Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); + /* Generate some code for a new class */ + } else if ($5.id) { + /* Generate some code for a new class */ + Nested *n = (Nested *) malloc(sizeof(Nested)); + n->code = NewString(""); + Printv(n->code, "typedef ", $2, " " , + Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL); + n->name = Swig_copy_string($5.id); + n->line = cparse_start_line; + n->type = NewString(""); + n->kind = $2; + SwigType_push(n->type,$5.type); + n->next = 0; + add_nested(n); + } else { + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); + } + } + } + ; + +nested_decl : declarator { $$ = $1;} + | empty { $$.id = 0; } + ; + + +/* These directives can be included inside a class definition */ + +cpp_swig_directive: pragma_directive { $$ = $1; } + +/* A constant (includes #defines) inside a class */ + | constant_directive { $$ = $1; } + +/* This is the new style rename */ + + | name_directive { $$ = $1; } + +/* rename directive */ + | rename_directive { $$ = $1; } + | feature_directive { $$ = $1; } + | varargs_directive { $$ = $1; } + | insert_directive { $$ = $1; } + | typemap_directive { $$ = $1; } + | apply_directive { $$ = $1; } + | clear_directive { $$ = $1; } + | echo_directive { $$ = $1; } + ; + +cpp_end : cpp_const SEMI { + Clear(scanner_ccode); + } + | cpp_const LBRACE { skip_balanced('{','}'); } + ; + +cpp_vend : cpp_const SEMI { + Clear(scanner_ccode); + $$.val = 0; + $$.qualifier = $1.qualifier; + $$.bitfield = 0; + $$.throws = $1.throws; + } + | cpp_const EQUAL definetype SEMI { + Clear(scanner_ccode); + $$.val = $3.val; + $$.qualifier = $1.qualifier; + $$.bitfield = 0; + $$.throws = $1.throws; + } + | cpp_const LBRACE { + skip_balanced('{','}'); + $$.val = 0; + $$.qualifier = $1.qualifier; + $$.bitfield = 0; + $$.throws = $1.throws; + } + ; + + +/* ====================================================================== + * PRIMITIVES + * ====================================================================== */ + +storage_class : EXTERN { $$ = "extern"; } + | EXTERN string { + if (strcmp($2,"C") == 0) { + $$ = "externc"; + } else { + Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", $2); + $$ = 0; + } + } + | STATIC { $$ = "static"; } + | TYPEDEF { $$ = "typedef"; } + | VIRTUAL { $$ = "virtual"; } + | FRIEND { $$ = "friend"; } + | empty { $$ = 0; } + ; + +/* ------------------------------------------------------------------------------ + Function parameter lists + ------------------------------------------------------------------------------ */ + +parms : rawparms { + Parm *p; + $$ = $1; + p = $1; + while (p) { + Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); + p = nextSibling(p); + } + } + ; + +rawparms : parm ptail { + if (1) { + set_nextSibling($1,$2); + $$ = $1; + } else { + $$ = $2; + } + } + | empty { $$ = 0; } + ; + +ptail : COMMA parm ptail { + set_nextSibling($2,$3); + $$ = $2; + } + | empty { $$ = 0; } + ; + + +parm : rawtype parameter_declarator { + SwigType_push($1,$2.type); + $$ = NewParm($1,$2.id); + Setfile($$,cparse_file); + Setline($$,cparse_line); + if ($2.defarg) { + Setattr($$,"value",$2.defarg); + } + } + + | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon { + $$ = NewParm(NewStringf("template %s %s", $5,$6), 0); + Setfile($$,cparse_file); + Setline($$,cparse_line); + } + | PERIOD PERIOD PERIOD { + SwigType *t = NewString("v(...)"); + $$ = NewParm(t, 0); + Setfile($$,cparse_file); + Setline($$,cparse_line); + } + ; + +valparms : rawvalparms { + Parm *p; + $$ = $1; + p = $1; + while (p) { + if (Getattr(p,"type")) { + Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); + } + p = nextSibling(p); + } + } + ; + +rawvalparms : valparm valptail { + if (1) { + set_nextSibling($1,$2); + $$ = $1; + } else { + $$ = $2; + } + } + | empty { $$ = 0; } + ; + +valptail : COMMA valparm valptail { + set_nextSibling($2,$3); + $$ = $2; + } + | empty { $$ = 0; } + ; + + +valparm : parm { + $$ = $1; + { + /* We need to make a possible adjustment for integer parameters. */ + SwigType *type; + Node *n = 0; + + while (!n) { + type = Getattr($1,"type"); + n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */ + if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) { + SwigType *decl = Getattr(n,"decl"); + if (!SwigType_isfunction(decl)) { + String *value = Getattr(n,"value"); + if (value) { + Setattr($1,"type",Copy(value)); + n = 0; + } + } + } else { + break; + } + } + } + + } + | exprnum { + $$ = NewParm(0,0); + Setfile($$,cparse_file); + Setline($$,cparse_line); + Setattr($$,"value",$1.val); + } + | STRING { + $$ = NewParm(0,0); + Setfile($$,cparse_file); + Setline($$,cparse_line); + Setattr($$,"value",NewString($1)); + } + ; + +def_args : EQUAL definetype { + $$ = $2; + if ($2.type == T_ERROR) { + Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n"); + $$.val = 0; + $$.rawval = 0; + $$.bitfield = 0; + $$.throws = 0; + } + } + | EQUAL AND idcolon { + Node *n = Swig_symbol_clookup($3,0); + if (n) { + String *q = Swig_symbol_qualified(n); + if (Getattr(n,"access")) { + if (cplus_mode == CPLUS_PUBLIC) { + Swig_warning(WARN_PARSE_PRIVATE, cparse_file, cparse_line,"'%s' is private in this context.\n", $3); + Swig_warning(WARN_PARSE_BAD_DEFAULT, cparse_file, cparse_line,"Can't set default argument value (ignored)\n"); + } + $$.val = 0; + } else { + if (q) { + $$.val = NewStringf("&%s::%s", q,Getattr(n,"name")); + Delete(q); + } else { + $$.val = NewStringf("&%s", $3); + } + } + } else { + $$.val = NewStringf("&%s",$3); + } + $$.rawval = 0; + $$.type = T_USER; + $$.bitfield = 0; + $$.throws = 0; + } + | EQUAL LBRACE { + skip_balanced('{','}'); + $$.val = 0; + $$.rawval = 0; + $$.type = T_INT; + $$.bitfield = 0; + $$.throws = 0; + } + | COLON NUM_INT { + $$.val = 0; + $$.rawval = 0; + $$.type = 0; + $$.bitfield = $2.val; + $$.throws = 0; + } + | empty { + $$.val = 0; + $$.rawval = 0; + $$.type = T_INT; + $$.bitfield = 0; + $$.throws = 0; + } + ; + +parameter_declarator : declarator def_args { + $$ = $1; + $$.defarg = $2.rawval ? $2.rawval : $2.val; + } + | abstract_declarator def_args { + $$ = $1; + $$.defarg = $2.rawval ? $2.rawval : $2.val; + } + | def_args { + $$.type = 0; + $$.id = 0; + $$.defarg = $1.rawval ? $1.rawval : $1.val; + } + ; + +typemap_parameter_declarator : declarator { + $$ = $1; + if (SwigType_isfunction($1.type)) { + Delete(SwigType_pop_function($1.type)); + } else if (SwigType_isarray($1.type)) { + SwigType *ta = SwigType_pop_arrays($1.type); + if (SwigType_isfunction($1.type)) { + Delete(SwigType_pop_function($1.type)); + } else { + $$.parms = 0; + } + SwigType_push($1.type,ta); + Delete(ta); + } else { + $$.parms = 0; + } + } + | abstract_declarator { + $$ = $1; + if (SwigType_isfunction($1.type)) { + Delete(SwigType_pop_function($1.type)); + } else if (SwigType_isarray($1.type)) { + SwigType *ta = SwigType_pop_arrays($1.type); + if (SwigType_isfunction($1.type)) { + Delete(SwigType_pop_function($1.type)); + } else { + $$.parms = 0; + } + SwigType_push($1.type,ta); + Delete(ta); + } else { + $$.parms = 0; + } + } + | empty { + $$.type = 0; + $$.id = 0; + $$.parms = 0; + } + ; + + +declarator : pointer notso_direct_declarator { + $$ = $2; + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } + | pointer AND notso_direct_declarator { + $$ = $3; + SwigType_add_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } + | direct_declarator { + $$ = $1; + if (!$$.type) $$.type = NewString(""); + } + | AND notso_direct_declarator { + $$ = $2; + $$.type = NewString(""); + SwigType_add_reference($$.type); + if ($2.type) { + SwigType_push($$.type,$2.type); + Delete($2.type); + } + } + | idcolon DSTAR notso_direct_declarator { + SwigType *t = NewString(""); + + $$ = $3; + SwigType_add_memberpointer(t,$1); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | pointer idcolon DSTAR notso_direct_declarator { + SwigType *t = NewString(""); + $$ = $4; + SwigType_add_memberpointer(t,$2); + SwigType_push($1,t); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + Delete(t); + } + | pointer idcolon DSTAR AND notso_direct_declarator { + $$ = $5; + SwigType_add_memberpointer($1,$2); + SwigType_add_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } + | idcolon DSTAR AND notso_direct_declarator { + SwigType *t = NewString(""); + $$ = $4; + SwigType_add_memberpointer(t,$1); + SwigType_add_reference(t); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + ; + +notso_direct_declarator : idcolon { + /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ + $$.id = Char($1); + $$.type = 0; + $$.parms = 0; + $$.have_parms = 0; + } + + | NOT idcolon { + $$.id = Char(NewStringf("~%s",$2)); + $$.type = 0; + $$.parms = 0; + $$.have_parms = 0; + } + +/* This generate a shift-reduce conflict with constructors */ + | LPAREN idcolon RPAREN { + $$.id = Char($2); + $$.type = 0; + $$.parms = 0; + $$.have_parms = 0; + } + +/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */ + | LPAREN pointer notso_direct_declarator RPAREN { + $$ = $3; + if ($$.type) { + SwigType_push($2,$$.type); + Delete($$.type); + } + $$.type = $2; + } + | LPAREN idcolon DSTAR notso_direct_declarator RPAREN { + SwigType *t; + $$ = $4; + t = NewString(""); + SwigType_add_memberpointer(t,$2); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | notso_direct_declarator LBRACKET RBRACKET { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_array(t,(char*)""); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | notso_direct_declarator LBRACKET expr RBRACKET { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_array(t,$3.val); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | notso_direct_declarator LPAREN parms RPAREN { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_function(t,$3); + if (!$$.have_parms) { + $$.parms = $3; + $$.have_parms = 1; + } + if (!$$.type) { + $$.type = t; + } else { + SwigType_push(t, $$.type); + Delete($$.type); + $$.type = t; + } + } + ; + +direct_declarator : idcolon { + /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ + $$.id = Char($1); + $$.type = 0; + $$.parms = 0; + $$.have_parms = 0; + } + + | NOT idcolon { + $$.id = Char(NewStringf("~%s",$2)); + $$.type = 0; + $$.parms = 0; + $$.have_parms = 0; + } + +/* This generate a shift-reduce conflict with constructors */ +/* + | LPAREN idcolon RPAREN { + $$.id = Char($2); + $$.type = 0; + $$.parms = 0; + $$.have_parms = 0; + } +*/ +/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */ + | LPAREN pointer direct_declarator RPAREN { + $$ = $3; + if ($$.type) { + SwigType_push($2,$$.type); + Delete($$.type); + } + $$.type = $2; + } + | LPAREN idcolon DSTAR direct_declarator RPAREN { + SwigType *t; + $$ = $4; + t = NewString(""); + SwigType_add_memberpointer(t,$2); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | direct_declarator LBRACKET RBRACKET { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_array(t,(char*)""); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | direct_declarator LBRACKET expr RBRACKET { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_array(t,$3.val); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | direct_declarator LPAREN parms RPAREN { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_function(t,$3); + if (!$$.have_parms) { + $$.parms = $3; + $$.have_parms = 1; + } + if (!$$.type) { + $$.type = t; + } else { + SwigType_push(t, $$.type); + Delete($$.type); + $$.type = t; + } + } + ; + +abstract_declarator : pointer { + $$.type = $1; + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + } + | pointer direct_abstract_declarator { + $$ = $2; + SwigType_push($1,$2.type); + $$.type = $1; + Delete($2.type); + } + | pointer AND { + $$.type = $1; + SwigType_add_reference($$.type); + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + } + | pointer AND direct_abstract_declarator { + $$ = $3; + SwigType_add_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } + | direct_abstract_declarator { + $$ = $1; + } + | AND direct_abstract_declarator { + $$ = $2; + $$.type = NewString(""); + SwigType_add_reference($$.type); + if ($2.type) { + SwigType_push($$.type,$2.type); + Delete($2.type); + } + } + | AND { + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + $$.type = NewString(""); + SwigType_add_reference($$.type); + } + | idcolon DSTAR { + $$.type = NewString(""); + SwigType_add_memberpointer($$.type,$1); + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + } + | pointer idcolon DSTAR { + SwigType *t = NewString(""); + $$.type = $1; + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + SwigType_add_memberpointer(t,$2); + SwigType_push($$.type,t); + Delete(t); + } + | pointer idcolon DSTAR direct_abstract_declarator { + $$ = $4; + SwigType_add_memberpointer($1,$2); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } + ; + +direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_array(t,(char*)""); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | direct_abstract_declarator LBRACKET expr RBRACKET { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_array(t,$3.val); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } + | LBRACKET RBRACKET { + $$.type = NewString(""); + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + SwigType_add_array($$.type,(char*)""); + } + | LBRACKET expr RBRACKET { + $$.type = NewString(""); + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + SwigType_add_array($$.type,$2.val); + } + | LPAREN abstract_declarator RPAREN { + $$ = $2; + } + | direct_abstract_declarator LPAREN parms RPAREN { + SwigType *t; + $$ = $1; + t = NewString(""); + SwigType_add_function(t,$3); + if (!$$.type) { + $$.type = t; + } else { + SwigType_push(t,$$.type); + Delete($$.type); + $$.type = t; + } + if (!$$.have_parms) { + $$.parms = $3; + $$.have_parms = 1; + } + } + | LPAREN parms RPAREN { + $$.type = NewString(""); + SwigType_add_function($$.type,$2); + $$.parms = $2; + $$.have_parms = 1; + $$.id = 0; + } + ; + + +pointer : STAR type_qualifier pointer { + $$ = NewString(""); + SwigType_add_pointer($$); + SwigType_push($$,$2); + SwigType_push($$,$3); + Delete($3); + } + | STAR pointer { + $$ = NewString(""); + SwigType_add_pointer($$); + SwigType_push($$,$2); + Delete($2); + } + | STAR type_qualifier { + $$ = NewString(""); + SwigType_add_pointer($$); + SwigType_push($$,$2); + } + | STAR { + $$ = NewString(""); + SwigType_add_pointer($$); + } + ; + +type_qualifier : type_qualifier_raw { + $$ = NewString(""); + SwigType_add_qualifier($$,$1); + } + | type_qualifier_raw type_qualifier { + $$ = $2; + SwigType_add_qualifier($$,$1); + } + ; + +type_qualifier_raw : CONST { $$ = "const"; } + | VOLATILE { $$ = "volatile"; } + ; + +/* Data type must be a built in type or an identifier for user-defined types + This type can be preceded by a modifier. */ + +type : rawtype { + $$ = $1; + Replace($$,"typename ","", DOH_REPLACE_ANY); + } + ; + +rawtype : type_qualifier type_right { + $$ = $2; + SwigType_push($$,$1); + } + | type_right { $$ = $1; } + ; + +type_right : primitive_type { $$ = $1; + /* Printf(stdout,"primitive = '%s'\n", $$);*/ + } + | TYPE_BOOL { $$ = $1; } + | TYPE_VOID { $$ = $1; } + | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } + | ENUM idcolon { $$ = NewStringf("enum %s", $2); } + | TYPE_RAW { $$ = $1; } + | type_right type_qualifier { + $$ = $1; + SwigType_push($$,$2); + } + + | idcolon { + $$ = $1; + } + | cpptype idcolon { + $$ = NewStringf("%s %s", $1, $2); + } + ; + +primitive_type : primitive_type_list { + if (!$1.type) $1.type = NewString("int"); + if ($1.us) { + $$ = NewStringf("%s %s", $1.us, $1.type); + Delete($1.us); + Delete($1.type); + } else { + $$ = $1.type; + } + if (Cmp($$,"signed int") == 0) { + Delete($$); + $$ = NewString("int"); + } else if (Cmp($$,"signed long") == 0) { + Delete($$); + $$ = NewString("long"); + } else if (Cmp($$,"signed short") == 0) { + Delete($$); + $$ = NewString("short"); + } else if (Cmp($$,"signed long long") == 0) { + Delete($$); + $$ = NewString("long long"); + } + } + ; + +primitive_type_list : type_specifier { + $$ = $1; + } + | type_specifier primitive_type_list { + if ($1.us && $2.us) { + Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us); + } + $$ = $2; + if ($1.us) $$.us = $1.us; + if ($1.type) { + if (!$2.type) $$.type = $1.type; + else { + int err = 0; + if ((Cmp($1.type,"long") == 0)) { + if ((Cmp($2.type,"long") == 0) || (Cmp($2.type,"double") == 0)) { + $$.type = NewStringf("long %s", $2.type); + } else if (Cmp($2.type,"int") == 0) { + $$.type = $1.type; + } else { + err = 1; + } + } else if ((Cmp($1.type,"short")) == 0) { + if (Cmp($2.type,"int") == 0) { + $$.type = $1.type; + } else { + err = 1; + } + } else if (Cmp($1.type,"int") == 0) { + $$.type = $2.type; + } else if (Cmp($1.type,"double") == 0) { + if (Cmp($2.type,"long") == 0) { + $$.type = NewString("long double"); + } else { + err = 1; + } + } + if (err) { + Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type); + } + } + } + } + ; + + +type_specifier : TYPE_INT { + $$.type = NewString("int"); + $$.us = 0; + } + | TYPE_SHORT { + $$.type = NewString("short"); + $$.us = 0; + } + | TYPE_LONG { + $$.type = NewString("long"); + $$.us = 0; + } + | TYPE_CHAR { + $$.type = NewString("char"); + $$.us = 0; + } + | TYPE_FLOAT { + $$.type = NewString("float"); + $$.us = 0; + } + | TYPE_DOUBLE { + $$.type = NewString("double"); + $$.us = 0; + } + | TYPE_SIGNED { + $$.us = NewString("signed"); + $$.type = 0; + } + | TYPE_UNSIGNED { + $$.us = NewString("unsigned"); + $$.type = 0; + } + ; + +definetype : { /* scanner_check_typedef(); */ } expr { + $$ = $2; + $$.rawval = 0; + $$.bitfield = 0; + $$.throws = 0; + scanner_ignore_typedef(); + } + | string { + $$.val = NewString($1); + $$.rawval = NewStringf("\"%(escape)s\"",$$.val); + $$.type = T_STRING; + $$.bitfield = 0; + $$.throws = 0; + } + | CHARCONST { + $$.val = NewString($1); + if (Len($$.val)) { + $$.rawval = NewStringf("\'%(escape)s\'",$$.val); + } else { + $$.rawval = NewString("\'\\0'"); + } + $$.type = T_CHAR; + $$.bitfield = 0; + $$.throws; + } + ; + +/* Some stuff for handling enums */ + +ename : ID { $$ = $1; } + | empty { $$ = (char *) 0;} + ; + +/* SWIG enum list */ + +enumlist : enumlist COMMA edecl { + Node *n = Getattr($1,"_last"); + if (!n) { + set_nextSibling($1,$3); + Setattr($1,"_last",$3); + } else { + set_nextSibling(n,$3); + Setattr($1,"_last",$3); + } + $$ = $1; + } + | edecl { $$ = $1; } + ; + +edecl : ID { + $$ = new_node("enumitem"); + Setattr($$,"name",$1); + Setattr($$,"type",NewSwigType(T_INT)); + Setattr($$,"feature:immutable","1"); + } + | ID EQUAL etype { + $$ = new_node("enumitem"); + Setattr($$,"name",$1); + Setattr($$,"enumvalue", $3.val); + if ($3.type == T_CHAR) { + Setattr($$,"value",$3.val); + Setattr($$,"type",NewSwigType(T_CHAR)); + } else { + Setattr($$,"value",$1); + Setattr($$,"type",NewSwigType(T_INT)); + } + Setattr($$,"feature:immutable","1"); + } + | empty { $$ = 0; } + ; + +etype : expr { + $$ = $1; + if (($$.type != T_INT) && ($$.type != T_UINT) && + ($$.type != T_LONG) && ($$.type != T_ULONG) && + ($$.type != T_SHORT) && ($$.type != T_USHORT) && + ($$.type != T_SCHAR) && ($$.type != T_UCHAR)) { + Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n"); + } + } + | CHARCONST { + $$.val = NewString($1); + $$.type = T_INT; + } + ; + +/* Arithmetic expressions. Used for constants and other cool stuff. + Really, we're not doing anything except string concatenation, but + this does allow us to parse many constant declarations. + */ + +expr : exprnum { $$ = $1; } + | SIZEOF LPAREN type parameter_declarator RPAREN { + SwigType_push($3,$4.type); + $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0)); + $$.type = T_INT; + } + | exprcompound { $$ = $1; } + | type { + Node *n; + $$.val = $1; + $$.type = T_INT; + /* Check if value is in scope */ + n = Swig_symbol_clookup($1,0); + if (n) { + if (Getattr(n,"access")) { + if (cplus_mode == CPLUS_PUBLIC) { + Swig_warning(WARN_PARSE_PRIVATE,cparse_file, cparse_line, "'%s' is private in this context.\n", $1); + $$.type = T_ERROR; + } + + } + } + } + +/* grouping */ + | LPAREN expr RPAREN %prec CAST { + $$.val = NewStringf("(%s)",$2.val); + $$.type = $2.type; + } + +/* A few common casting operations */ + + | LPAREN expr RPAREN expr %prec CAST { + $$ = $4; + $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val); + } + | LPAREN expr pointer RPAREN expr %prec CAST { + $$ = $5; + SwigType_push($2.val,$3); + $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); + } + | LPAREN expr AND RPAREN expr %prec CAST { + $$ = $5; + SwigType_add_reference($2.val); + $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); + } + | LPAREN expr pointer AND RPAREN expr %prec CAST { + $$ = $6; + SwigType_push($2.val,$3); + SwigType_add_reference($2.val); + $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val); + } + ; + +exprnum : NUM_INT { $$ = $1; } + | NUM_FLOAT { $$ = $1; } + | NUM_UNSIGNED { $$ = $1; } + | NUM_LONG { $$ = $1; } + | NUM_ULONG { $$ = $1; } + | NUM_LONGLONG { $$ = $1; } + | NUM_ULONGLONG { $$ = $1; } + ; + +exprcompound : expr PLUS expr { + $$.val = NewStringf("%s+%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr MINUS expr { + $$.val = NewStringf("%s-%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr STAR expr { + $$.val = NewStringf("%s*%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr SLASH expr { + $$.val = NewStringf("%s/%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr AND expr { + $$.val = NewStringf("%s&%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr OR expr { + $$.val = NewStringf("%s|%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr XOR expr { + $$.val = NewStringf("%s^%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr LSHIFT expr { + $$.val = NewStringf("%s<<%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr RSHIFT expr { + $$.val = NewStringf("%s>>%s",$1.val,$3.val); + $$.type = promote($1.type,$3.type); + } + | expr LAND expr { + $$.val = NewStringf("%s&&%s",$1.val,$3.val); + $$.type = T_INT; + } + | expr LOR expr { + $$.val = NewStringf("%s||%s",$1.val,$3.val); + $$.type = T_INT; + } + | MINUS expr %prec UMINUS { + $$.val = NewStringf("-%s",$2.val); + $$.type = $2.type; + } + | NOT expr { + $$.val = NewStringf("~%s",$2.val); + $$.type = $2.type; + } + | LNOT expr { + $$.val = NewStringf("!%s",$2.val); + $$.type = T_INT; + } + | type LPAREN { + skip_balanced('(',')'); + if (SwigType_istemplate($1)) { + $1 = SwigType_namestr($1); + } + $$.val = NewStringf("%s%s",$1,scanner_ccode); + Clear(scanner_ccode); + $$.type = T_INT; + } + ; + +inherit : raw_inherit { + $$ = $1; + } + ; + +raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; } + | empty { $$ = 0; } + ; + +base_list : base_specifier { + $$ = NewList(); + if ($1) Append($$,$1); + } + + | base_list COMMA base_specifier { + $$ = $1; + if ($3) Append($$,$3); + } + ; + +base_specifier : opt_virtual idcolon { + if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) { + Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file, cparse_line,"No access specifier given for base class %s (ignored).\n",$2); + $$ = (char *) 0; + } else { + $$ = $2; + Setfile($$,cparse_file); + Setline($$,cparse_line); + } + } + | opt_virtual access_specifier opt_virtual idcolon { + $$ = 0; + if (strcmp($2,"public") == 0) { + $$ = $4; + Setfile($$, cparse_file); + Setline($$, cparse_line); + } else { + Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file, cparse_line, "%s inheritance ignored.\n", $2); + } + } + ; + +access_specifier : PUBLIC { $$ = (char*)"public"; } + | PRIVATE { $$ = (char*)"private"; } + | PROTECTED { $$ = (char*)"protected"; } + ; + + +cpptype : CLASS { + $$ = (char*)"class"; + if (!inherit_list) last_cpptype = $$; + } + | STRUCT { + $$ = (char*)"struct"; + if (!inherit_list) last_cpptype = $$; + } + | UNION { + $$ = (char*)"union"; + if (!inherit_list) last_cpptype = $$; + } + | TYPENAME { + $$ = (char *)"typename"; + if (!inherit_list) last_cpptype = $$; + } + ; + +opt_virtual : VIRTUAL + | empty + ; + +cpp_const : type_qualifier { + $$.qualifier = $1; + $$.throws = 0; + } + | THROW LPAREN parms RPAREN { + $$.qualifier = 0; + $$.throws = $3; + } + | type_qualifier THROW LPAREN parms RPAREN { + $$.qualifier = $1; + $$.throws = $4; + } + | empty { + $$.qualifier = 0; + $$.throws = 0; + } + ; + +ctor_end : cpp_const ctor_initializer SEMI { + Clear(scanner_ccode); + $$.have_parms = 0; + $$.defarg = 0; + $$.throws = $1.throws; + } + | cpp_const ctor_initializer LBRACE { + skip_balanced('{','}'); + $$.have_parms = 0; + $$.defarg = 0; + $$.throws = $1.throws; + } + | LPAREN parms RPAREN SEMI { + Clear(scanner_ccode); + $$.parms = $2; + $$.have_parms = 1; + $$.defarg = 0; + $$.throws = 0; + } + | LPAREN parms RPAREN LBRACE { + skip_balanced('{','}'); + $$.parms = $2; + $$.have_parms = 1; + $$.defarg = 0; + $$.throws = 0; + } + | EQUAL definetype SEMI { + $$.have_parms = 0; + $$.defarg = $2.val; + $$.throws = 0; + } + ; + +ctor_initializer : COLON mem_initializer_list + | empty + ; + +mem_initializer_list : mem_initializer + | mem_initializer_list COMMA mem_initializer + ; + +mem_initializer : idcolon LPAREN { + skip_balanced('(',')'); + Clear(scanner_ccode); + } + ; + +template_decl : LESSTHAN valparms GREATERTHAN { + String *s = NewString(""); + SwigType_add_template(s,$2); + $$ = Char(s); + } + | empty { $$ = (char*)""; } + ; + +idstring : ID { $$ = $1; } + | string { $$ = $1; } + ; + +idstringopt : idstring { $$ = $1; } + | empty { $$ = 0; } + ; + +idcolon : idtemplate idcolontail { + $$ = 0; + if (!$$) $$ = NewStringf("%s%s", $1,$2); + Delete($2); + } + | NONID DCOLON idtemplate idcolontail { + $$ = NewStringf("::%s%s",$3,$4); + Delete($4); + } + | idtemplate { + $$ = NewString($1); + } + | NONID DCOLON idtemplate { + $$ = NewStringf("::%s",$3); + } + | OPERATOR { + $$ = NewString($1); + } + | NONID DCOLON OPERATOR { + $$ = NewStringf("::%s",$3); + } + ; + +idcolontail : DCOLON idtemplate idcolontail { + $$ = NewStringf("::%s%s",$2,$3); + Delete($3); + } + | DCOLON idtemplate { + $$ = NewStringf("::%s",$2); + } + | DCOLON OPERATOR { + $$ = NewStringf("::%s",$2); + } + | DCNOT idtemplate { + $$ = NewStringf("::~%s",$2); + } + ; + + +idtemplate : ID template_decl { + $$ = NewStringf("%s%s",$1,$2); + scanner_last_id(1); + } + ; + +/* Identifier, but no templates */ +idcolonnt : ID idcolontailnt { + $$ = 0; + if (!$$) $$ = NewStringf("%s%s", $1,$2); + Delete($2); + } + | NONID DCOLON ID idcolontailnt { + $$ = NewStringf("::%s%s",$3,$4); + Delete($4); + } + | ID { + $$ = NewString($1); + } + | NONID DCOLON ID { + $$ = NewStringf("::%s",$3); + } + | OPERATOR { + $$ = NewString($1); + } + | NONID DCOLON OPERATOR { + $$ = NewStringf("::%s",$3); + } + ; + +idcolontailnt : DCOLON ID idcolontailnt { + $$ = NewStringf("::%s%s",$2,$3); + Delete($3); + } + | DCOLON ID { + $$ = NewStringf("::%s",$2); + } + | DCOLON OPERATOR { + $$ = NewStringf("::%s",$2); + } + | DCNOT ID { + $$ = NewStringf("::~%s",$2); + } + ; + +/* Concatenated strings */ +string : string STRING { + $$ = (char *) malloc(strlen($1)+strlen($2)+1); + strcpy($$,$1); + strcat($$,$2); + } + | STRING { $$ = $1;} + ; + +stringbrace : string { + $$ = NewString($1); + } + | LBRACE { + skip_balanced('{','}'); + $$ = NewString(scanner_ccode); + } + | HBLOCK { + $$ = $1; + } + ; + +options : LPAREN kwargs RPAREN { + Hash *n; + $$ = NewHash(); + n = $2; + while(n) { + String *name, *value; + name = Getattr(n,"name"); + value = Getattr(n,"value"); + if (!value) value = (String *) "1"; + Setattr($$,name, value); + n = nextSibling(n); + } + } + | empty { $$ = 0; }; + + +/* Keyword arguments */ +kwargs : idstring EQUAL stringnum { + $$ = NewHash(); + Setattr($$,"name",$1); + Setattr($$,"value",$3); + } + | idstring EQUAL stringnum COMMA kwargs { + $$ = NewHash(); + Setattr($$,"name",$1); + Setattr($$,"value",$3); + set_nextSibling($$,$5); + } + | idstring { + $$ = NewHash(); + Setattr($$,"name",$1); + } + | idstring COMMA kwargs { + $$ = NewHash(); + Setattr($$,"name",$1); + set_nextSibling($$,$3); + } + ; + +stringnum : string { + $$ = $1; + } + | exprnum { + $$ = $1.val; + } + ; + +empty : ; + +%% + +/* Called by the parser (yyparse) when an error is found.*/ +void yyerror (const char *e) { +} + +SwigType *Swig_cparse_type(String *s) { + String *ns; + extern void scanner_file(File *); + extern int yyparse(); + extern void scanner_next_token(int); + ns = NewStringf("%s;",s); + Seek(ns,0,SEEK_SET); + scanner_file(ns); + top = 0; + scanner_next_token(PARSETYPE); + yyparse(); + /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ + return top; +} + + + + + + + + + diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c new file mode 100644 index 000000000..b9b7fb4cd --- /dev/null +++ b/Source/CParse/templ.c @@ -0,0 +1,495 @@ +/* ----------------------------------------------------------------------------- + * templ.c + * + * Expands a template into a specialized version. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_templ_c[] = "$Header$"; + +#include "swig.h" +#include "cparse.h" + +static int template_debug = 0; + +static void add_parms(ParmList *p, List *patchlist, List *typelist) { + while (p) { + SwigType *ty = Getattr(p,"type"); + SwigType *val = Getattr(p,"value"); + Append(typelist,ty); + Append(patchlist,val); + p = nextSibling(p); + } +} + +void Swig_cparse_debug_templates(int x) { + template_debug = x; +} + +/* ----------------------------------------------------------------------------- + * Swig_cparse_template_expand() + * + * Expands a template node into a specialized version. This is done by + * patching typenames and other aspects of the node according to a list of + * template parameters + * ----------------------------------------------------------------------------- */ + +static int +cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { + static int expanded = 0; + int ret; + + if (!n) return 0; + if (Getattr(n,"error")) return 0; + + if (Strcmp(nodeType(n),"template") == 0) { + /* Change the node type back to normal */ + if (!expanded) { + expanded = 1; + set_nodeType(n,Getattr(n,"templatetype")); + ret = cparse_template_expand(n,tname, rname, templateargs, patchlist,typelist, cpatchlist); + expanded = 0; + return ret; + } else { + /* Called when template appears inside another template */ + /* Member templates */ + + set_nodeType(n,Getattr(n,"templatetype")); + ret = cparse_template_expand(n,tname, rname, templateargs, patchlist,typelist, cpatchlist); + set_nodeType(n,"template"); + return ret; + } + } else if (Strcmp(nodeType(n),"cdecl") == 0) { + /* A simple C declaration */ + SwigType *t, *v, *d; + String *code; + t = Getattr(n,"type"); + v = Getattr(n,"value"); + d = Getattr(n,"decl"); + + code = Getattr(n,"code"); + + Append(typelist,t); + Append(typelist,d); + Append(patchlist,v); + Append(cpatchlist,code); + + if (Getattr(n,"conversion_operator")) { + Append(cpatchlist, Getattr(n,"name")); + if (Getattr(n,"sym:name")) { + Append(cpatchlist, Getattr(n,"sym:name")); + } + } + + add_parms(Getattr(n,"parms"), cpatchlist, typelist); + add_parms(Getattr(n,"throws"), cpatchlist, typelist); + + } else if (Strcmp(nodeType(n),"class") == 0) { + /* Patch base classes */ + { + List *bases = Getattr(n,"baselist"); + if (bases) { + int i; + for (i = 0; i < Len(bases); i++) { + String *name = Copy(Getitem(bases,i)); + Setitem(bases,i,name); + Append(typelist,name); + } + } + } + /* Patch children */ + { + Node *cn = firstChild(n); + while (cn) { + cparse_template_expand(cn,tname, rname, templateargs, patchlist,typelist,cpatchlist); + cn = nextSibling(cn); + } + } + } else if (Strcmp(nodeType(n),"constructor") == 0) { + String *name = Getattr(n,"name"); + if (!(Getattr(n,"templatetype"))) { + String *symname; + String *stripped_name = SwigType_templateprefix(name); + if (Strstr(tname,stripped_name)) { + Replaceid(name,stripped_name,tname); + } + Delete(stripped_name); + symname = Getattr(n,"sym:name"); + if (symname) { + stripped_name = SwigType_templateprefix(symname); + if (Strstr(tname,stripped_name)) { + Replaceid(symname,stripped_name,tname); + } + Delete(stripped_name); + } + if (Strstr(name,"<")) { + Append(patchlist,Getattr(n,"name")); + } else { + Append(name,templateargs); + } + name = Getattr(n,"sym:name"); + if (name && (Strstr(name,"<"))) { + Clear(name); + Append(name,rname); + } else { + Replace(name,tname,rname, DOH_REPLACE_ANY); + } + Setattr(n,"sym:name",name); + } + Append(cpatchlist,Getattr(n,"code")); + Append(typelist, Getattr(n,"decl")); + add_parms(Getattr(n,"parms"), cpatchlist, typelist); + add_parms(Getattr(n,"throws"), cpatchlist, typelist); + } else if (Strcmp(nodeType(n),"destructor") == 0) { + String *name = Getattr(n,"name"); + if (Strstr(name,"<")) { + Append(patchlist,Getattr(n,"name")); + } else { + Append(name,templateargs); + } + name = Getattr(n,"sym:name"); + if (name && Strstr(name,"<")) { + Setattr(n,"sym:name", Copy(tname)); + } else { + Replace(name,tname,rname, DOH_REPLACE_ANY); + } + Setattr(n,"sym:name",name); + Append(cpatchlist,Getattr(n,"code")); + } else if (Strcmp(nodeType(n),"using") == 0) { + String *uname = Getattr(n,"uname"); + if (uname) { + if (Strstr(uname,"<")) { + Append(patchlist, uname); + } + } + if (Getattr(n,"namespace")) { + /* Namespace link. This is nasty. Is other namespace defined? */ + + } + } else { + /* Look for obvious parameters */ + Node *cn; + Append(cpatchlist,Getattr(n,"code")); + Append(typelist, Getattr(n,"type")); + Append(typelist, Getattr(n,"decl")); + add_parms(Getattr(n,"parms"), cpatchlist, typelist); + add_parms(Getattr(n,"pattern"), cpatchlist, typelist); + add_parms(Getattr(n,"throws"), cpatchlist, typelist); + cn = firstChild(n); + while (cn) { + cparse_template_expand(cn,tname, rname, templateargs, patchlist, typelist, cpatchlist); + cn = nextSibling(cn); + } + } + return 0; +} + +int +Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms) { + List *patchlist, *cpatchlist, *typelist; + String *templateargs; + String *tname; + String *iname; + String *tbase; + patchlist = NewList(); + cpatchlist = NewList(); + typelist = NewList(); + + { + String *tmp = NewString(""); + if (tparms) { + SwigType_add_template(tmp,tparms); + } + templateargs = Copy(tmp); + Delete(tmp); + } + + tname = Copy(Getattr(n,"name")); + tbase = Swig_scopename_last(tname); + + if (0) { + Parm *p = tparms; + while (p) { + Printf(stdout,"tparm: '%s' '%s'\n", Getattr(p,"name"), Getattr(p,"value")); + p = nextSibling(p); + } + } + + cparse_template_expand(n,tname, rname, templateargs, patchlist, typelist, cpatchlist); + + /* Set the name */ + { + String *name = Getattr(n,"name"); + if (name) { + Append(name,templateargs); + } + iname = name; + } + + /* Patch all of the types */ + { + Parm *tp = Getattr(n,"templateparms"); + Parm *p = tparms; + + if (tp) { + while (p && tp) { + String *name, *value, *valuestr, *tydef, *tmp, *tmpr; + int sz, i; + + name = Getattr(tp,"name"); + value = Getattr(p,"value"); + tydef = Getattr(p,"typedef"); + if (name) { + if (!value) { + value = Getattr(p,"type"); + valuestr = SwigType_str(value,0); + } else { + valuestr = SwigType_namestr(value); + } + assert(value); + /* Need to patch default arguments */ + { + Parm *rp = nextSibling(p); + while (rp) { + String *rvalue = Getattr(rp,"value"); + if (rvalue) { + Replace(rvalue,name,value, DOH_REPLACE_ID); + } + rp = nextSibling(rp); + } + } + sz = Len(patchlist); + for (i = 0; i < sz; i++) { + String *s = Getitem(patchlist,i); + Replace(s,name,value, DOH_REPLACE_ID); + } + sz = Len(typelist); + for (i = 0; i < sz; i++) { + String *s = Getitem(typelist,i); + Replace(s,name,value, DOH_REPLACE_ID); + SwigType_typename_replace(s,tbase,iname); + } + + if (!tydef) { + tydef = value; + } + tmp = NewStringf("#%s",name); + tmpr = NewStringf("\"%s\"", value); + + sz = Len(cpatchlist); + for (i = 0; i < sz; i++) { + String *s = Getitem(cpatchlist,i); + Replace(s,tmp,tmpr, DOH_REPLACE_ID); + /* Replace(s,name,tydef, DOH_REPLACE_ID); */ + Replace(s,name,valuestr, DOH_REPLACE_ID); + } + Delete(tmp); + Delete(tmpr); + Delete(valuestr); + } + p = nextSibling(p); + tp = nextSibling(tp); + if (!p) p = tp; + } + } else { + /* No template parameters at all. This could be a specialization */ + int i, sz; + sz = Len(typelist); + for (i = 0; i < sz; i++) { + String *s = Getitem(typelist,i); + SwigType_typename_replace(s,tbase,iname); + } + } + } + + /* Patch bases */ + { + List *bases = Getattr(n,"baselist"); + if (bases) { + String *b; + for (b = Firstitem(bases); b; b = Nextitem(bases)) { + String *qn = Swig_symbol_type_qualify(b,0); + Clear(b); + Append(b,qn); + } + } + } + Delete(patchlist); + Delete(cpatchlist); + Delete(typelist); + Delete(tbase); + + /* set_nodeType(n,"template");*/ + return 0; +} + +/* ----------------------------------------------------------------------------- + * cparse_template_locate() + * + * Search for a template that matches name with given parameters. + * ----------------------------------------------------------------------------- */ + +Node * +Swig_cparse_template_locate(String *name, Parm *tparms) { + Node *n; + String *tname, *rname = 0; + Node *templ; + List *mpartials = 0; + Parm *p; + Parm *parms; + + tname = NewString(name); + parms = CopyParmList(tparms); + + p = parms; + while (p) { + SwigType *ty = Getattr(p,"type"); + if (ty) { + SwigType *nt = Swig_symbol_typedef_reduce(ty,0); + nt = Swig_symbol_type_qualify(nt,0); + Setattr(p,"type",nt); + } + p = nextSibling(p); + } + + SwigType_add_template(tname,parms); + + if (template_debug) { + Printf(stdout,"\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname); + } + + /* Search for an exact specialization. + Example: template<> class name { ... } */ + { + if (template_debug) { + Printf(stdout," searching: '%s' (exact specialization)\n", tname); + } + n = Swig_symbol_clookup_local(tname,0); + if (n) { + Node *tn; + if (Strcmp(nodeType(n),"template") == 0) goto success; + tn = Getattr(n,"template"); + if (tn) { + n = tn; + goto success; /* Previously wrapped by a template return that */ + } + Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); + Delete(tname); + Delete(parms); + return 0; /* Found a match, but it's not a template of any kind. */ + } + } + + /* Search for generic template */ + templ = Swig_symbol_clookup_local(name,0); + + /* Search for partial specialization. + Example: template class name { ... } */ + + /* Generate reduced template name (stripped of extraneous pointers, etc.) */ + + rname = NewStringf("%s<(",name); + p = parms; + while (p) { + String *t; + t = Getattr(p,"type"); + if (t) { + String *tbase = SwigType_base(t); + t = SwigType_default(t); + Replaceid(t,"SWIGTYPE",tbase); + Replaceid(t,"SWIGENUM",tbase); + Printf(rname,"%s",t); + Delete(t); + } else { + String *v = Getattr(p,"value"); + Printf(rname,"%s",v); + } + p = nextSibling(p); + if (p) { + Printf(rname,","); + } + } + Printf(rname,")>"); + + mpartials = NewList(); + if (templ) { + /* First, we search using an exact type prototype */ + Parm *p; + char tmp[32]; + int i; + List *partials; + String *s, *ss; + + partials = Getattr(templ,"partials"); + if (partials) { + for (s = Firstitem(partials); s; s= Nextitem(partials)) { + ss = Copy(s); + p = parms; + i = 1; + while (p) { + String *t,*tn; + sprintf(tmp,"$%d",i); + t = Getattr(p,"type"); + if (t) { + tn = SwigType_base(t); + Replaceid(ss,tmp,tn); + Delete(tn); + } else { + String *v = Getattr(p,"value"); + Replaceid(ss,tmp,v); + } + i++; + p = nextSibling(p); + } + if (template_debug) { + Printf(stdout," searching: '%s' (partial specialization - %s)\n", ss, s); + } + if ((Strcmp(ss,tname) == 0) || (Strcmp(ss,rname) == 0)) { + Append(mpartials,s); + } + Delete(ss); + } + } + } + + if (template_debug) { + Printf(stdout," Matched partials: %s\n", mpartials); + } + + if (Len(mpartials)) { + String *s = Getitem(mpartials,0); + n = Swig_symbol_clookup_local(s,0); + if (Len(mpartials) > 1) { + if (n) { + Swig_warning(WARN_PARSE_TEMPLATE_AMBIG,cparse_file,cparse_line,"Instantiation of template %s is ambiguous. Using %s at %s:%d\n", + SwigType_namestr(tname), SwigType_namestr(Getattr(n,"name")), Getfile(n),Getline(n)); + } + } + } + + if (!n) { + n = templ; + } + if (!n) { + Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); + } else if (n && (Strcmp(nodeType(n),"template") != 0)) { + Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); + n = 0; + } + success: + Delete(tname); + Delete(rname); + Delete(mpartials); + if ((template_debug) && (n)) { + Printf(stdout,"Node: %x\n", n); + Swig_print_node(n); + } + Delete(parms); + return n; +} + + diff --git a/Source/CParse/util.c b/Source/CParse/util.c new file mode 100644 index 000000000..33f4976c8 --- /dev/null +++ b/Source/CParse/util.c @@ -0,0 +1,71 @@ +/* ----------------------------------------------------------------------------- + * util.c + * + * Parsing utilities + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_util_c[] = "$Header$"; + +#include "swig.h" + +extern SwigType *Swig_cparse_type(String *); + +/* ----------------------------------------------------------------------------- + * Swig_cparse_replace_descriptor() + * + * Replaces type descriptor string $descriptor() with the SWIG type descriptor + * string. + * ----------------------------------------------------------------------------- */ + +void Swig_cparse_replace_descriptor(String *s) { + char tmp[512]; + String *arg = 0; + SwigType *t; + + while (Strstr(s,"$descriptor(")) { + char *d = tmp; + int level = 0; + char *c = Strstr(s,"$descriptor("); + while (*c) { + if (*c == '(') level++; + if (*c == ')') { + level--; + if (level == 0) { + break; + } + } + *d = *c; + d++; + c++; + } + *d = 0; + arg = NewString(tmp+12); + t = Swig_cparse_type(arg); + Delete(arg); + arg = 0; + + if (t) { + String *mangle; + String *descriptor; + + mangle = SwigType_manglestr(t); + descriptor = NewStringf("SWIGTYPE%s",mangle); + SwigType_remember(t); + *d = ')'; + d++; + *d = 0; + Replace(s,tmp,descriptor,DOH_REPLACE_ANY); + Delete(mangle); + Delete(descriptor); + } else { + Swig_error(Getfile(s),Getline(s),"Bad $descriptor() macro.\n"); + break; + } + } +} + diff --git a/Source/DOH/.cvsignore b/Source/DOH/.cvsignore index 3e4a1f00a..2599bc761 100644 --- a/Source/DOH/.cvsignore +++ b/Source/DOH/.cvsignore @@ -2,3 +2,4 @@ Makefile config.* *.tar.gz configure +autom4te.cache diff --git a/Source/DOH/Doh/Makefile b/Source/DOH/Doh/Makefile deleted file mode 100644 index 0908946e0..000000000 --- a/Source/DOH/Doh/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# Generated automatically from Makefile.in by configure. -####################################################################### -# $Header$ -# DOH -####################################################################### - -#.KEEP_STATE: - -# Set your C++ compiler here. g++ works on most machines, -# but you might have to change it depending on your installation. -# -CC = cc -prefix = /r0/beazley/Projects - -# Comment out the following line if you're on an SGI or don't have ranlib! -RANLIB = ranlib -AR = ar - -######################################################################## -# Normally, you shouldn't have to change anything below this point # -######################################################################## - -LIBOBJS = callable.o void.o fio.o memory.o base.o file.o list.o hash.o string.o - -LIBSRCS = callable.c void.c fio.c memory.c base.c file.c list.c hash.c string.c - -LIBHEADERS = ../Include/doh.h -LIB = ../libdoh.a -INCLUDE = -I../Include -CFLAGS = -DDOH_STRING_UPDATE_LINES -SHELL = /bin/sh - -# -# Rules for creation of a .o file from .cxx -.SUFFIXES: .c -.c.o: - $(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $< - -all: $(LIB) - -$(LIB): $(LIBOBJS) - @echo "Building library" - $(AR) cr $(LIB) $(LIBOBJS) - $(RANLIB) $(LIB) - -clean:: - rm -f *.o ../libdoh.a -nuke:: - rm -f Makefile *~ #* core a.out - diff --git a/Source/DOH/Doh/Makefile.in b/Source/DOH/Doh/Makefile.in index fadad36e2..44078fd2f 100644 --- a/Source/DOH/Doh/Makefile.in +++ b/Source/DOH/Doh/Makefile.in @@ -24,21 +24,21 @@ DOHOPT = # Normally, you shouldn't have to change anything below this point # ######################################################################## -LIBOBJS = void.o fio.o memory.o base.o file.o list.o hash.o string.o +LIBOBJS = void.@OBJEXT@ fio.@OBJEXT@ memory.@OBJEXT@ base.@OBJEXT@ file.@OBJEXT@ list.@OBJEXT@ hash.@OBJEXT@ string.@OBJEXT@ LIBSRCS = void.c fio.c memory.c base.c file.c list.c hash.c string.c LIBHEADERS = $(srcdir)/../Include/doh.h LIB = libdoh.a -INCLUDE = -I$(srcdir)/../Include +INCLUDES = -I$(srcdir)/../Include CFLAGS = @CFLAGS@ SHELL = /bin/sh # -# Rules for creation of a .o file from .c +# Rules for creation of a .@OBJEXT@ file from .c .SUFFIXES: .c -.c.o: - $(CC) $(DOHOPT) $(INCLUDE) $(CFLAGS) -c -o $*.o $< +.c.@OBJEXT@: + $(CC) $(DOHOPT) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $< all: $(LIB) @@ -49,6 +49,6 @@ $(LIB): $(LIBOBJS) cp -f $(LIB) .. clean:: - rm -f *.o $(LIB) ../$(LIB) + rm -f *.@OBJEXT@ $(LIB) ../$(LIB) nuke:: - rm -f Makefile *~ #* core a.out + rm -f Makefile *~ diff --git a/Source/DOH/Doh/base.c b/Source/DOH/Doh/base.c index 8787d6204..a5063389d 100644 --- a/Source/DOH/Doh/base.c +++ b/Source/DOH/Doh/base.c @@ -10,21 +10,10 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_base_c[] = "$Header$"; #include "dohint.h" -static DohObjInfo *dohtypes[MAX_DOHTYPE]; - -/* ----------------------------------------------------------------------------- - * DohRegisterType() - * ----------------------------------------------------------------------------- */ - -void -DohRegisterType(int type, DohObjInfo *objinfo) { - dohtypes[type] = objinfo; -} - /* ----------------------------------------------------------------------------- * DohDelete() * ----------------------------------------------------------------------------- */ @@ -43,7 +32,7 @@ DohDelete(DOH *obj) { assert(b->refcount > 0); b->refcount--; if (b->refcount <= 0) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_del) { (objinfo->doh_del)(b); } else { @@ -63,9 +52,14 @@ DohCopy(const DOH *obj) { DohObjInfo *objinfo; if (!obj) return 0; - objinfo = dohtypes[b->type]; - if (objinfo->doh_copy) - return (objinfo->doh_copy)(b); + objinfo = b->type; + if (objinfo->doh_copy) { + DohBase *bc = (DohBase *) (objinfo->doh_copy)(b); + if ((bc) && b->meta) { + bc->meta = Copy(b->meta); + } + return (DOH *) bc; + } return 0; } @@ -81,7 +75,7 @@ DohIncref(DOH *obj) { void DohClear(DOH *obj) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_clear) (objinfo->doh_clear)(b); } @@ -96,11 +90,11 @@ DohStr(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(b)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_str) { return (objinfo->doh_str)(b); } - sprintf(buffer,"", objinfo->objname, b); + sprintf(buffer,"", objinfo->objname, (unsigned int)b); return NewString(buffer); } else { return NewString(obj); @@ -114,7 +108,7 @@ DohStr(const DOH *obj) { int DohDump(const DOH *obj, DOH *out) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_dump) { return (objinfo->doh_dump)(b,out); } @@ -130,7 +124,7 @@ DohLen(const DOH *obj) { DohObjInfo *objinfo; if (!b) return 0; if (DohCheck(b)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_len) { return (objinfo->doh_len)(b); } @@ -149,7 +143,7 @@ DohHashval(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(b)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_hashval) { return (objinfo->doh_hashval)(b); } @@ -166,7 +160,7 @@ DohData(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_data) { return (objinfo->doh_data)(b); } @@ -191,8 +185,8 @@ DohCmp(const DOH *obj1, const DOH *obj2) { if (!b1 && b2) return -1; return strcmp((char *) DohData(b1),(char *) DohData(b2)); } - b1info = dohtypes[b1->type]; - b2info = dohtypes[b2->type]; + b1info = b1->type; + b2info = b2->type; if ((b1info == b2info) && (b1info->doh_cmp)) return (b1info->doh_cmp)(b1,b2); return 1; @@ -206,7 +200,7 @@ DohIsMapping(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_hash) return 1; else return 0; } @@ -218,7 +212,7 @@ DohIsMapping(const DOH *obj) { DOH * DohGetattr(DOH *obj, const DOH *name) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) { return (objinfo->doh_hash->doh_getattr)(b,(DOH *) name); } @@ -232,7 +226,7 @@ DohGetattr(DOH *obj, const DOH *name) { int DohSetattr(DOH *obj, const DOH *name, const DOH *value) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) { return (objinfo->doh_hash->doh_setattr)(b,(DOH *) name,(DOH *) value); } @@ -243,13 +237,14 @@ DohSetattr(DOH *obj, const DOH *name, const DOH *value) { * DohDelattr() * ----------------------------------------------------------------------------- */ -void +int DohDelattr(DOH *obj, const DOH *name) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) { - (objinfo->doh_hash->doh_delattr)(b,(DOH *) name); + return (objinfo->doh_hash->doh_delattr)(b,(DOH *) name); } + return 0; } /* ----------------------------------------------------------------------------- @@ -259,7 +254,7 @@ DohDelattr(DOH *obj, const DOH *name) { DOH * DohFirstkey(DOH *obj) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_firstkey) { return (objinfo->doh_hash->doh_firstkey)(b); } @@ -273,13 +268,27 @@ DohFirstkey(DOH *obj) { DOH * DohNextkey(DOH *obj) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo && objinfo->doh_hash->doh_nextkey) { return (objinfo->doh_hash->doh_nextkey)(b); } return 0; } +/* ----------------------------------------------------------------------------- + * DohNextkey() + * ----------------------------------------------------------------------------- */ + +DOH * +DohKeys(DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo && objinfo->doh_hash->doh_keys) { + return (objinfo->doh_hash->doh_keys)(b); + } + return 0; +} + /* ----------------------------------------------------------------------------- * DohGetInt() * ----------------------------------------------------------------------------- */ @@ -388,7 +397,7 @@ DohIsSequence(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_list) return 1; else return 0; } @@ -400,7 +409,7 @@ DohIsSequence(const DOH *obj) { DOH * DohGetitem(DOH *obj, int index) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_getitem) { return (objinfo->doh_list->doh_getitem)(b,index); } @@ -414,7 +423,7 @@ DohGetitem(DOH *obj, int index) { int DohSetitem(DOH *obj, int index, const DOH *value) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_setitem) { return (objinfo->doh_list->doh_setitem)(b,index,(DOH *) value); } @@ -428,7 +437,7 @@ DohSetitem(DOH *obj, int index, const DOH *value) { int DohDelitem(DOH *obj, int index) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_delitem) { return (objinfo->doh_list->doh_delitem)(b,index); } @@ -442,7 +451,7 @@ DohDelitem(DOH *obj, int index) { int DohInsertitem(DOH *obj, int index, const DOH *value) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_insitem) { return (objinfo->doh_list->doh_insitem)(b,index,(DOH *) value); } @@ -456,7 +465,7 @@ DohInsertitem(DOH *obj, int index, const DOH *value) { DOH * DohFirstitem(DOH *obj) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_firstitem) { return (objinfo->doh_list->doh_firstitem)(b); } @@ -470,7 +479,7 @@ DohFirstitem(DOH *obj) { DOH * DohNextitem(DOH *obj) { DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = dohtypes[b->type]; + DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_nextitem) { return (objinfo->doh_list->doh_nextitem)(b); } @@ -486,7 +495,7 @@ DohIsFile(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_file) return 1; else return 0; } @@ -500,7 +509,7 @@ DohRead(DOH *obj, void *buffer, int length) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) { return (objinfo->doh_file->doh_read)(b,buffer,length); } @@ -519,7 +528,7 @@ DohWrite(DOH *obj, void *buffer, int length) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) { return (objinfo->doh_file->doh_write)(b,buffer,length); } @@ -538,7 +547,7 @@ DohSeek(DOH *obj, long offset, int whence) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) { return (objinfo->doh_file->doh_seek)(b,offset,whence); } @@ -556,7 +565,7 @@ DohTell(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) { return (objinfo->doh_file->doh_tell)(b); } @@ -575,11 +584,11 @@ DohGetc(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (obj == lastdoh) { - objinfo = dohtypes[b->type]; + objinfo = b->type; return (objinfo->doh_file->doh_getc)(b); } if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_file->doh_getc) { lastdoh = obj; return (objinfo->doh_file->doh_getc)(b); @@ -600,11 +609,11 @@ DohPutc(int ch, DOH *obj) { DohObjInfo *objinfo; if (obj == lastdoh) { - objinfo = dohtypes[b->type]; + objinfo = b->type; return (objinfo->doh_file->doh_putc)(b,ch); } if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_file->doh_putc) { lastdoh = obj; return (objinfo->doh_file->doh_putc)(b,ch); @@ -623,7 +632,7 @@ DohUngetc(int ch, DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_file->doh_ungetc) { return (objinfo->doh_file->doh_ungetc)(b,ch); } @@ -641,7 +650,7 @@ DohClose(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_file->doh_close) { return (objinfo->doh_file->doh_close)(b); } @@ -659,7 +668,7 @@ DohIsString(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_string) return 1; else return 0; } @@ -672,8 +681,10 @@ int DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) { DohBase *b = (DohBase *) src; DohObjInfo *objinfo; + if (!token) return 0; + if (!rep) rep = ""; if (DohIsString(src)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_string->doh_replace) { return (objinfo->doh_string->doh_replace)(b,(DOH *) token, (DOH *) rep,flags); } @@ -690,7 +701,7 @@ DohChop(DOH *src) { DohBase *b = (DohBase *) src; DohObjInfo *objinfo; if (DohIsString(src)) { - objinfo = dohtypes[b->type]; + objinfo = b->type; if (objinfo->doh_string->doh_chop) { (objinfo->doh_string->doh_chop)(b); } @@ -705,7 +716,7 @@ DohSetfile(DOH *ho, DOH *file) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return; - objinfo = dohtypes[h->type]; + objinfo = h->type; if (objinfo->doh_setfile) (objinfo->doh_setfile)(h,file); } @@ -718,7 +729,7 @@ DohGetfile(DOH *ho) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return 0; - objinfo = dohtypes[h->type]; + objinfo = h->type; if (objinfo->doh_getfile) return (objinfo->doh_getfile)(h); return 0; @@ -732,7 +743,7 @@ DohSetline(DOH *ho, int l) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return; - objinfo = dohtypes[h->type]; + objinfo = h->type; if (objinfo->doh_setline) (objinfo->doh_setline)(h,l); } @@ -745,12 +756,60 @@ DohGetline(DOH *ho) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return 0; - objinfo = dohtypes[h->type]; + objinfo = h->type; if (objinfo->doh_getline) return (objinfo->doh_getline)(h); return 0; } +/* ----------------------------------------------------------------------------- + * DohGetmeta() + * ----------------------------------------------------------------------------- */ +DOH * +DohGetmeta(DOH *ho, const DOH *name) { + DohBase *h = (DohBase *) ho; + if (!DohCheck(ho)) return 0; + if (!h->meta) return 0; + return DohGetattr(h->meta,name); +} +/* ----------------------------------------------------------------------------- + * DohGetmeta() + * ----------------------------------------------------------------------------- */ +int +DohSetmeta(DOH *ho, const DOH *name, const DOH *value) { + DohBase *h = (DohBase *) ho; + if (!DohCheck(ho)) return 0; + if (!h->meta) h->meta = NewHash(); + return DohSetattr(h->meta, name, value); +} + +/* ----------------------------------------------------------------------------- + * DohDelmeta() + * ----------------------------------------------------------------------------- */ + +int +DohDelmeta(DOH *ho, const DOH *name) { + DohBase *h = (DohBase *) ho; + if (!DohCheck(ho)) return 0; + if (!h->meta) return 0; + return DohDelattr(h->meta, name); +} + +/* ----------------------------------------------------------------------------- + * DohSetmark() + * ----------------------------------------------------------------------------- */ + +void +DohSetmark(DOH *ho, int x) { + DohBase *h = (DohBase *) ho; + h->flag_usermark = x; +} + +int +DohGetmark(DOH *ho) { + DohBase *h = (DohBase *) ho; + return h->flag_usermark; +} diff --git a/Source/DOH/Doh/file.c b/Source/DOH/Doh/file.c index 4e901e91c..70e8c3d4e 100644 --- a/Source/DOH/Doh/file.c +++ b/Source/DOH/Doh/file.c @@ -10,7 +10,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_file_c[] = "$Header$"; #include "dohint.h" @@ -41,6 +41,7 @@ DelFile(DOH *fo) { } #endif } + DohFree(f); } /* ----------------------------------------------------------------------------- @@ -118,12 +119,12 @@ File_tell(DOH *fo) { static int File_putc(DOH *fo, int ch) { - char c; DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fputc(ch,f->filep); } else if (f->fd) { #ifdef DOH_INTFILE + char c; c = (char) ch; return write(f->fd,&c,1); #endif @@ -137,12 +138,12 @@ File_putc(DOH *fo, int ch) { static int File_getc(DOH *fo) { - char c; DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fgetc(f->filep); } else if (f->fd) { #ifdef DOH_INTFILE + char c; if (read(f->fd,&c,1) < 0) return EOF; return c; #endif @@ -169,6 +170,28 @@ File_ungetc(DOH *fo, int ch) { return -1; } +/* ----------------------------------------------------------------------------- + * File_close() + * + * Close the file + * ----------------------------------------------------------------------------- */ + +static int +File_close(DOH *fo) { + int ret = 0; + DohFile *f = (DohFile *) ObjData(fo); + if (f->filep) { + ret = fclose(f->filep); + f->filep = 0; + } else if (f->fd) { +#ifdef DOH_INTFILE + ret = close(f->fd); + f->fd = 0; +#endif + } + return ret; +} + static DohFileMethods FileFileMethods = { File_read, File_write, @@ -177,7 +200,7 @@ static DohFileMethods FileFileMethods = { File_ungetc, File_seek, File_tell, - 0, /* close */ + File_close, /* close */ }; static DohObjInfo DohFileType = { @@ -209,20 +232,13 @@ static DohObjInfo DohFileType = { * Create a new file from a given filename and mode. * ----------------------------------------------------------------------------- */ -static int init = 0; - DOH * -NewFile(DOH *fn, char *mode) +DohNewFile(DOH *fn, const char *mode) { DohFile *f; FILE *file; char *filename; - if (!init) { - DohRegisterType(DOHTYPE_FILE, &DohFileType); - init = 1; - } - filename = Char(fn); file = fopen(filename,mode); if (!file) return 0; @@ -235,7 +251,7 @@ NewFile(DOH *fn, char *mode) f->filep = file; f->fd = 0; f->closeondel = 1; - return DohObjMalloc(DOHTYPE_FILE,f); + return DohObjMalloc(&DohFileType,f); } /* ----------------------------------------------------------------------------- @@ -245,20 +261,15 @@ NewFile(DOH *fn, char *mode) * ----------------------------------------------------------------------------- */ DOH * -NewFileFromFile(FILE *file) +DohNewFileFromFile(FILE *file) { DohFile *f; - - if (!init) { - DohRegisterType(DOHTYPE_FILE, &DohFileType); - init = 1; - } f = (DohFile *) DohMalloc(sizeof(DohFile)); if (!f) return 0; f->filep = file; f->fd = 0; f->closeondel = 0; - return DohObjMalloc(DOHTYPE_FILE,f); + return DohObjMalloc(&DohFileType,f); } /* ----------------------------------------------------------------------------- @@ -268,17 +279,13 @@ NewFileFromFile(FILE *file) * ----------------------------------------------------------------------------- */ DOH * -NewFileFromFd(int fd) +DohNewFileFromFd(int fd) { DohFile *f; - if (!init) { - DohRegisterType(DOHTYPE_FILE, &DohFileType); - init = 1; - } f = (DohFile *) DohMalloc(sizeof(DohFile)); if (!f) return 0; f->filep = 0; f->fd = fd; f->closeondel = 0; - return DohObjMalloc(DOHTYPE_FILE,f); + return DohObjMalloc(&DohFileType,f); } diff --git a/Source/DOH/Doh/fio.c b/Source/DOH/Doh/fio.c index 2d8e03efd..db7e5eb1c 100644 --- a/Source/DOH/Doh/fio.c +++ b/Source/DOH/Doh/fio.c @@ -10,7 +10,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_fio_c[] = "$Header$"; #include "dohint.h" @@ -265,7 +265,7 @@ DohvPrintf(DOH *so, const char *format, va_list ap) doh = va_arg(ap, DOH *); if (DohCheck(doh)) { /* Is a DOH object. */ - if (DohIsString(doh) && (ObjType(doh) == DOHTYPE_STRING)) { + if (DohIsString(doh)) { Sval = doh; } else { Sval = Str(doh); @@ -411,7 +411,7 @@ int DohPrintv(DOHFile *f, ...) { va_start(ap,f); while(1) { obj = va_arg(ap,void *); - if (!obj) break; + if ((!obj) || (obj == DohNone)) break; if (DohCheck(obj)) { ret += DohDump(obj,f); } else { @@ -459,12 +459,12 @@ DohCopyto(DOH *in, DOH *out) { /* ----------------------------------------------------------------------------- * DohSplit() * - * Split an input stream into a list of strings delimeted by characters in a - * string. Optionally accepts a maximum number of splits to perform. + * Split an input stream into a list of strings delimited by the specified + * character. Optionally accepts a maximum number of splits to perform. * ----------------------------------------------------------------------------- */ DOH * -DohSplit(DOH *in, char *chs, int nsplits) { +DohSplit(DOH *in, char ch, int nsplits) { DOH *list; DOH *str; int c; @@ -479,17 +479,18 @@ DohSplit(DOH *in, char *chs, int nsplits) { str = NewString(""); do { c = Getc(in); - } while ((c != EOF) && (c == *chs)); + } while ((c != EOF) && (c == ch)); if (c != EOF) { Putc(c,str); while (1) { c = Getc(in); - if ((c == EOF) || ((c == *chs) && (nsplits != 0))) break; + if ((c == EOF) || ((c == ch) && (nsplits != 0))) break; Putc(c,str); } nsplits--; } Append(list,str); + Delete(str); if (c == EOF) break; } return list; diff --git a/Source/DOH/Doh/hash.c b/Source/DOH/Doh/hash.c index 246242c20..4738a2312 100644 --- a/Source/DOH/Doh/hash.c +++ b/Source/DOH/Doh/hash.c @@ -9,10 +9,12 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_hash_c[] = "$Header$"; #include "dohint.h" +extern DohObjInfo DohHashType; + /* Hash node */ typedef struct HashNode { DOH *key; @@ -46,6 +48,9 @@ static DOH *find_key (DOH *doh_c) { char *c = (char *) doh_c; KeyValue *r, *s; int d = 0; + /* OK, sure, we use a binary tree for maintaining interned + symbols. Then we use their hash values for accessing secondary + hash tables. */ r = root; s = 0; while (r) { @@ -199,8 +204,10 @@ Hash_setattr(DOH *ho, DOH *k, DOH *obj) { int hv; HashNode *n, *prev; Hash *h = (Hash *) ObjData(ho); - - if (!obj) return 0; + + if (!obj) { + return DohDelattr(ho,k); + } if (!DohCheck(k)) k = find_key(k); if (!DohCheck(obj)) { obj = NewString((char *) obj); @@ -211,16 +218,15 @@ Hash_setattr(DOH *ho, DOH *k, DOH *obj) { prev = 0; while (n) { if (Cmp(n->key,k) == 0) { - HashNode *nn; - if (prev) { - prev->next = n->next; - } else { - h->hashtable[hv] = n->next; + /* Node already exists. Just replace its contents */ + if (n->object == obj) { + /* Whoa. Same object. Do nothing */ + return 1; } - nn = n->next; - DelNode(n); - h->nitems--; - n = nn; + Delete(n->object); + n->object = obj; + Incref(obj); + return 1; /* Return 1 to indicate a replacement */ } else { prev = n; n = n->next; @@ -276,11 +282,17 @@ Hash_delattr(DOH *ho, DOH *k) { while (n) { if (Cmp(n->key, k) == 0) { /* Found it, kill it */ + if (prev) { prev->next = n->next; } else { h->hashtable[hv] = n->next; } + /* Need to check for iterator location */ + if (n == h->current) { + h->current = prev; /* Move back to previous node. When next is called, will move to next node */ + if (!h->current) h->currentindex--; /* No previous node. Move back one slot */ + } DelNode(n); h->nitems--; return 1; @@ -307,10 +319,12 @@ hash_first(DOH *ho) { static HashNode * hash_next(DOH *ho) { Hash *h = (Hash *) ObjData(ho); - if (h->currentindex < 0) return hash_first(h); + if (h->currentindex < 0) return hash_first(ho); /* Try to move to the next entry */ - h->current = h->current->next; + if (h->current) { + h->current = h->current->next; + } if (h->current) { return h->current; } @@ -348,6 +362,26 @@ Hash_nextkey(DOH *ho) { return 0; } +/* ----------------------------------------------------------------------------- + * Hash_keys(DOH *) + * + * Return a list of keys + * ----------------------------------------------------------------------------- */ + +static DOH * +Hash_keys(DOH *so) { + DOH *keys; + DOH *k; + + keys = NewList(); + k = Firstkey(so); + while (k) { + Append(keys,k); + k = Nextkey(so); + } + return keys; +} + /* ----------------------------------------------------------------------------- * Hash_str() * @@ -397,26 +431,6 @@ Hash_len(DOH *ho) { return h->nitems; } -/* ----------------------------------------------------------------------------- - * Hash_keys(DOH *) - * - * Return a list of keys - * ----------------------------------------------------------------------------- */ -DOH * -Hash_keys(DOH *so) { - DOH *keys; - DOH *k; - - keys = NewList(); - k = Firstkey(so); - while (k) { - Append(keys,k); - k = Nextkey(so); - } - /* List_sort(keys); */ - return keys; -} - /* ----------------------------------------------------------------------------- * CopyHash() * @@ -444,7 +458,7 @@ CopyHash(DOH *ho) { nh->file = h->file; if (nh->file) Incref(nh->file); - nho = DohObjMalloc(DOHTYPE_HASH, nh); + nho = DohObjMalloc(&DohHashType, nh); for (i = 0; i < h->hashsize; i++) { if ((n = h->hashtable[i])) { while (n) { @@ -458,7 +472,8 @@ CopyHash(DOH *ho) { -void Hash_setfile(DOH *ho, DOH *file) { +static void +Hash_setfile(DOH *ho, DOH *file) { DOH *fo; Hash *h = (Hash *) ObjData(ho); @@ -471,17 +486,20 @@ void Hash_setfile(DOH *ho, DOH *file) { h->file = fo; } -DOH *Hash_getfile(DOH *ho) { +static DOH * +Hash_getfile(DOH *ho) { Hash *h = (Hash *) ObjData(ho); return h->file; } -void Hash_setline(DOH *ho, int line) { +static void +Hash_setline(DOH *ho, int line) { Hash *h = (Hash *) ObjData(ho); h->line = line; } -int Hash_getline(DOH *ho) { +static int +Hash_getline(DOH *ho) { Hash *h = (Hash *) ObjData(ho); return h->line; } @@ -496,9 +514,10 @@ static DohHashMethods HashHashMethods = { Hash_delattr, Hash_firstkey, Hash_nextkey, + Hash_keys, }; -static DohObjInfo HashType = { +DohObjInfo DohHashType = { "Hash", /* objname */ DelHash, /* doh_del */ CopyHash, /* doh_copy */ @@ -528,14 +547,9 @@ static DohObjInfo HashType = { * ----------------------------------------------------------------------------- */ DOH * -NewHash() { +DohNewHash() { Hash *h; int i; - static int init = 0; - if (!init) { - DohRegisterType(DOHTYPE_HASH, &HashType); - init = 1; - } h = (Hash *) DohMalloc(sizeof(Hash)); h->hashsize = HASH_INIT_SIZE; h->hashtable = (HashNode **) DohMalloc(h->hashsize*sizeof(HashNode *)); @@ -547,6 +561,5 @@ NewHash() { h->nitems = 0; h->file = 0; h->line = 0; - return DohObjMalloc(DOHTYPE_HASH,h); + return DohObjMalloc(&DohHashType,h); } - diff --git a/Source/DOH/Doh/list.c b/Source/DOH/Doh/list.c index 876fd9120..fff505b39 100644 --- a/Source/DOH/Doh/list.c +++ b/Source/DOH/Doh/list.c @@ -9,7 +9,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_list_c[] = "$Header$"; #include "dohint.h" @@ -22,6 +22,8 @@ typedef struct List { DOH **items; } List; +extern DohObjInfo DohListType; + /* Doubles amount of memory in a list */ static void more(List *l) { @@ -52,7 +54,7 @@ CopyList(DOH *lo) { nl->file = l->file; if (nl->file) Incref(nl->file); nl->line = l->line; - return DohObjMalloc(DOHTYPE_LIST, nl); + return DohObjMalloc(&DohListType, nl); } /* ----------------------------------------------------------------------------- @@ -261,27 +263,8 @@ List_dump(DOH *lo, DOH *out) { return nsent; } - -/* ----------------------------------------------------------------------------- - * List_sort() - * ----------------------------------------------------------------------------- */ - - -static int objcmp(const void *s1, const void *s2) { - DOH **so1, **so2; - so1 = (DOH **) s1; - so2 = (DOH **) s2; - return Cmp(*so1,*so2); -} - -void -List_sort(DOH *lo, int opt) { - List *l = (List *) ObjData(lo); - qsort(l->items,l->nitems,sizeof(DOH *),objcmp); -} - - -void List_setfile(DOH *lo, DOH *file) { +static void +List_setfile(DOH *lo, DOH *file) { DOH *fo; List *l = (List *) ObjData(lo); @@ -294,17 +277,19 @@ void List_setfile(DOH *lo, DOH *file) { l->file = fo; } -DOH *List_getfile(DOH *lo) { +static DOH * +List_getfile(DOH *lo) { List *l = (List *) ObjData(lo); return l->file; } -void List_setline(DOH *lo, int line) { +static void +List_setline(DOH *lo, int line) { List *l = (List *) ObjData(lo); l->line = line; } -int List_getline(DOH *lo) { +static int List_getline(DOH *lo) { List *l = (List *) ObjData(lo); return l->line; } @@ -316,10 +301,9 @@ static DohListMethods ListListMethods = { List_insert, List_first, List_next, - List_sort }; -static DohObjInfo ListType = { +DohObjInfo DohListType = { "List", /* objname */ DelList, /* doh_del */ CopyList, /* doh_copy */ @@ -351,14 +335,9 @@ static DohObjInfo ListType = { #define MAXLISTITEMS 8 DOH * -NewList() { +DohNewList() { List *l; int i; - static int init = 0; - if (!init) { - DohRegisterType(DOHTYPE_LIST, &ListType); - init = 1; - } l = (List *) DohMalloc(sizeof(List)); l->nitems = 0; l->maxitems = MAXLISTITEMS; @@ -369,5 +348,6 @@ NewList() { l->iter = 0; l->file = 0; l->line = 0; - return DohObjMalloc(DOHTYPE_LIST,l); + return DohObjMalloc(&DohListType,l); } + diff --git a/Source/DOH/Doh/memory.c b/Source/DOH/Doh/memory.c index fcf5ba341..b0ddc5ff1 100644 --- a/Source/DOH/Doh/memory.c +++ b/Source/DOH/Doh/memory.c @@ -10,7 +10,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_memory_c[] = "$Header$"; #include "dohint.h" @@ -30,8 +30,7 @@ typedef struct pool { struct pool *next; /* Next pool */ } Pool; -DohBase *FreeList = 0; /* List of free objects */ - +static DohBase *FreeList = 0; /* List of free objects */ static Pool *Pools = 0; static int pools_initialized = 0; @@ -105,7 +104,7 @@ DohIntern(DOH *obj) { * ---------------------------------------------------------------------- */ DOH * -DohObjMalloc(int type, void *data) { +DohObjMalloc(DohObjInfo *type, void *data) { DohBase *obj; if (!pools_initialized) InitPools(); if (FreeList) { @@ -121,9 +120,12 @@ DohObjMalloc(int type, void *data) { } obj->type = type; obj->data = data; + obj->meta = 0; obj->refcount = 1; obj->flag_intern = 0; obj->flag_marked = 0; + obj->flag_user = 0; + obj->flag_usermark = 0; return (DOH *) obj; } @@ -137,6 +139,10 @@ DohObjFree(DOH *ptr) { b = (DohBase *) ptr; if (b->flag_intern) return; b->data = (void *) FreeList; + if (b->meta) { + Delete(b->meta); + b->meta = 0; + } b->type = 0; FreeList = b; } diff --git a/Source/DOH/Doh/string.c b/Source/DOH/Doh/string.c index 96d11d9a7..04e6d184a 100644 --- a/Source/DOH/Doh/string.c +++ b/Source/DOH/Doh/string.c @@ -10,13 +10,11 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_string_c[] = "$Header$"; #include "dohint.h" -#ifndef DOH_STRING_UPDATE_LINES -#define DOH_STRING_UPDATE_LINES -#endif +extern DohObjInfo DohStringType; typedef struct String { DOH *file; @@ -31,7 +29,9 @@ typedef struct String { /* ----------------------------------------------------------------------------- * void *String_data() - Return as a 'void *' * ----------------------------------------------------------------------------- */ -void *String_data(DOH *so) { + +static void * +String_data(DOH *so) { String *s = (String *) ObjData(so); s->str[s->len] = 0; return (void *) s->str; @@ -41,7 +41,8 @@ void *String_data(DOH *so) { * int String_dump() - Serialize a string onto out * ----------------------------------------------------------------------------- */ -int String_dump(DOH *so, DOH *out) { +static int +String_dump(DOH *so, DOH *out) { int nsent; int ret; String *s = (String *) ObjData(so); @@ -57,32 +58,37 @@ int String_dump(DOH *so, DOH *out) { /* ----------------------------------------------------------------------------- * CopyString() - Copy a string * ----------------------------------------------------------------------------- */ -DOH * + +static DOH * CopyString(DOH *so) { - String *s = (String *) ObjData(so); int max; String *str; + String *s = (String *) ObjData(so); str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; - str->sp = 0; + str->sp = s->sp; str->line = s->line; str->file = s->file; if (str->file) Incref(str->file); max = s->maxsize; - str->str = (char *) DohMalloc(max); + str->str = (char *) DohMalloc(max+1); memmove(str->str, s->str, max); str->maxsize= max; str->len = s->len; str->str[str->len] = 0; - return DohObjMalloc(DOHTYPE_STRING,str); + + return DohObjMalloc(&DohStringType,str); } /* ----------------------------------------------------------------------------- * DelString() - Delete a string * ----------------------------------------------------------------------------- */ -void + +static void DelString(DOH *so) { String *s = (String *) ObjData(so); + s->hashkey = -1; + s->str = 0; DohFree(s->str); DohFree(s); } @@ -91,7 +97,7 @@ DelString(DOH *so) { * String_len() - Length of a string * ----------------------------------------------------------------------------- */ -int +static int String_len(DOH *so) { String *s = (String *) ObjData(so); return s->len; @@ -102,7 +108,7 @@ String_len(DOH *so) { * int String_cmp() - Compare two strings * ----------------------------------------------------------------------------- */ -int +static int String_cmp(DOH *so1, DOH *so2) { String *s1, *s2; @@ -130,7 +136,8 @@ String_cmp(DOH *so1, DOH *so2) * int String_hash() - Compute string hash value * ----------------------------------------------------------------------------- */ -int String_hash(DOH *so) { +static int +String_hash(DOH *so) { String *s = (String *) ObjData(so); char *c; int i, h = 0, len; @@ -179,43 +186,11 @@ add(String *s, const char *newstr) { s->len += l; } -/* Add a single character to s */ -void -String_addchar(String *s, char c) { - register char *tc; - register int len = s->len; - register int maxsize = s->maxsize; - s->hashkey = -1; - if (len > (maxsize-2)) { - s->str = (char *) DohRealloc(s->str,2*maxsize); - assert(s->str); - s->maxsize = 2*maxsize; - } - tc = s->str; - tc[len] = c; - if (s->sp >= len) { - s->sp = len+1; - tc[len+1] = 0; - if (c == '\n') s->line++; - } - s->len++; -} - -/* Expand a string to accomodate a write */ -void -String_expand(String *s, int width) { - if ((s->len + width) > (s->maxsize-1)) { - s->str = (char *) DohRealloc(s->str,(s->len + width)+1); - assert(s->str); - s->maxsize = s->len + width + 1; - } -} - /* ----------------------------------------------------------------------------- * void String_clear() - Clear a string * ----------------------------------------------------------------------------- */ -void +static void String_clear(DOH *so) { String *s = (String *) ObjData(so); @@ -230,7 +205,9 @@ String_clear(DOH *so) * void String_insert() - Insert a string * ----------------------------------------------------------------------------- */ -int String_insert(DOH *so, int pos, DOH *str) { +static int +String_insert(DOH *so, int pos, DOH *str) +{ String *s = (String *) ObjData(so); char *nstr; int len; @@ -274,7 +251,8 @@ int String_insert(DOH *so, int pos, DOH *str) { * int String_delitem() - Delete a character * ----------------------------------------------------------------------------- */ -int String_delitem(DOH *so, int pos) +static int +String_delitem(DOH *so, int pos) { String *s = (String *) ObjData(so); s->hashkey = -1; @@ -297,8 +275,9 @@ int String_delitem(DOH *so, int pos) * DOH *String_str() - Returns a string (used by printing commands) * ----------------------------------------------------------------------------- */ -DOH * -String_str(DOH *so) { +static DOH * +String_str(DOH *so) +{ String *s = (String *) ObjData(so); s->str[s->len] = 0; return NewString(s->str); @@ -307,8 +286,10 @@ String_str(DOH *so) { /* ----------------------------------------------------------------------------- * int String_read() - Read data from a string * ----------------------------------------------------------------------------- */ -int -String_read(DOH *so, void *buffer, int len) { + +static int +String_read(DOH *so, void *buffer, int len) +{ int reallen, retlen; char *cb; String *s = (String *) ObjData(so); @@ -328,8 +309,9 @@ String_read(DOH *so, void *buffer, int len) { /* ----------------------------------------------------------------------------- * int String_write() - Write data to a string * ----------------------------------------------------------------------------- */ -int -String_write(DOH *so, void *buffer, int len) { +static int +String_write(DOH *so, void *buffer, int len) +{ int newlen; String *s = (String *) ObjData(so); s->hashkey = -1; @@ -351,8 +333,10 @@ String_write(DOH *so, void *buffer, int len) { /* ----------------------------------------------------------------------------- * int String_seek() - Seek to a new position * ----------------------------------------------------------------------------- */ -int -String_seek(DOH *so, long offset, int whence) { + +static int +String_seek(DOH *so, long offset, int whence) +{ int pos, nsp, inc; int prev; String *s = (String *) ObjData(so); @@ -391,8 +375,10 @@ String_seek(DOH *so, long offset, int whence) { /* ----------------------------------------------------------------------------- * long String_tell() - Return current position * ----------------------------------------------------------------------------- */ -long -String_tell(DOH *so) { + +static long +String_tell(DOH *so) +{ String *s = (String *) ObjData(so); return (long) (s->sp); } @@ -401,8 +387,9 @@ String_tell(DOH *so) { * int String_putc() * ----------------------------------------------------------------------------- */ -int -String_putc(DOH *so, int ch) { +static int +String_putc(DOH *so, int ch) +{ register int len, maxsize, sp; String *s = (String *) ObjData(so); s->hashkey = -1; @@ -435,7 +422,9 @@ String_putc(DOH *so, int ch) { * int String_getc() * ----------------------------------------------------------------------------- */ -int String_getc(DOH *so) { +static int +String_getc(DOH *so) +{ int c; String *s = (String *) ObjData(so); if (s->sp >= s->len) @@ -450,7 +439,9 @@ int String_getc(DOH *so) { * int String_ungetc() * ----------------------------------------------------------------------------- */ -int String_ungetc(DOH *so, int ch) { +static int +String_ungetc(DOH *so, int ch) +{ String *s = (String *) ObjData(so); if (ch == EOF) return ch; if (s->sp <= 0) return EOF; @@ -466,7 +457,9 @@ int String_ungetc(DOH *so, int ch) { * Replaces count non-overlapping occurrences of token with rep in a string. * ----------------------------------------------------------------------------- */ -static char *end_quote(char *s) { +static char * +end_quote(char *s) +{ char qc; char *q; qc = *s; @@ -478,11 +471,15 @@ static char *end_quote(char *s) { } } -static char *match_simple(char *base, char *s, char *token, int tokenlen) { +static char * +match_simple(char *base, char *s, char *token, int tokenlen) +{ return strstr(s,token); } -static char *match_identifier(char *base, char *s, char *token, int tokenlen) { +static char * +match_identifier(char *base, char *s, char *token, int tokenlen) +{ while (s) { s = strstr(s,token); if (!s) return 0; @@ -499,8 +496,8 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) { return 0; } -static -int replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int)) +static int +replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int)) { int tokenlen; /* Length of the token */ int replen; /* Length of the replacement */ @@ -513,7 +510,10 @@ int replace_simple(String *str, char *token, char *rep, int flags, int count, ch register char *base; int i; + str->hashkey = -1; + /* Figure out if anything gets replaced */ + if (!strlen(token)) return 0; base = str->str; tokenlen = strlen(token); @@ -706,11 +706,12 @@ int replace_simple(String *str, char *token, char *rep, int flags, int count, ch * int String_replace() * ----------------------------------------------------------------------------- */ -int +static int String_replace(DOH *stro, DOH *token, DOH *rep, int flags) { int count = -1; String *str = (String *) ObjData(stro); + if (flags & DOH_REPLACE_FIRST) count = 1; if (flags & DOH_REPLACE_ID) { @@ -724,8 +725,9 @@ String_replace(DOH *stro, DOH *token, DOH *rep, int flags) * void String_chop(DOH *str) * ----------------------------------------------------------------------------- */ -void -String_chop(DOH *so) { +static void +String_chop(DOH *so) +{ char *c; String *str = (String *) ObjData(so); /* Replace trailing whitespace */ @@ -743,7 +745,9 @@ String_chop(DOH *so) { str->hashkey = -1; } -void String_setfile(DOH *so, DOH *file) { +static void +String_setfile(DOH *so, DOH *file) +{ DOH *fo; String *str = (String *) ObjData(so); @@ -756,17 +760,23 @@ void String_setfile(DOH *so, DOH *file) { str->file = fo; } -DOH *String_getfile(DOH *so) { +static DOH * +String_getfile(DOH *so) +{ String *str = (String *) ObjData(so); return str->file; } -void String_setline(DOH *so, int line) { +static void +String_setline(DOH *so, int line) +{ String *str = (String *) ObjData(so); str->line = line; } -int String_getline(DOH *so) { +static int +String_getline(DOH *so) +{ String *str = (String *) ObjData(so); return str->line; } @@ -778,7 +788,6 @@ static DohListMethods StringListMethods = { String_insert, /* doh_insitem */ 0, /* doh_first */ 0, /* doh_next */ - 0, /* doh_sort */ }; static DohFileMethods StringFileMethods = { @@ -797,7 +806,7 @@ static DohStringMethods StringStringMethods = { String_chop, }; -static DohObjInfo StringType = { +DohObjInfo DohStringType = { "String", /* objname */ DelString, /* doh_del */ CopyString, /* doh_copy */ @@ -823,21 +832,16 @@ static DohObjInfo StringType = { #define INIT_MAXSIZE 16 - /* ----------------------------------------------------------------------------- * NewString(const char *c) - Create a new string * ----------------------------------------------------------------------------- */ + DOHString * -NewString(const DOH *so) +DohNewString(const DOH *so) { int l = 0, max; String *str; char *s; - static int init = 0; - if (!init) { - DohRegisterType(DOHTYPE_STRING, &StringType); - init = 1; - } if (DohCheck(so)) s = Char(so); else s = (char *) so; str = (String *) DohMalloc(sizeof(String)); @@ -860,7 +864,7 @@ NewString(const DOH *so) str->str[0] = 0; str->len = 0; } - return DohObjMalloc(DOHTYPE_STRING,str); + return DohObjMalloc(&DohStringType,str); } /* ----------------------------------------------------------------------------- @@ -870,7 +874,7 @@ NewString(const DOH *so) * ----------------------------------------------------------------------------- */ DOHString * -NewStringf(const DOH *fmt, ...) +DohNewStringf(const DOH *fmt, ...) { va_list ap; DOH *r; @@ -880,3 +884,28 @@ NewStringf(const DOH *fmt, ...) va_end(ap); return (DOHString *) r; } + +/* ----------------------------------------------------------------------------- + * Strcmp() + * Strncmp() + * Strstr() + * Strchr() + * + * Some utility functions. + * ----------------------------------------------------------------------------- */ + +int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) { + return strcmp(Char(s1),Char(s2)); +} + +int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) { + return strncmp(Char(s1),Char(s2),n); +} + +char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) { + return strstr(Char(s1),Char(s2)); +} + +char *DohStrchr(const DOHString_or_char *s1, int ch) { + return strchr(Char(s1),ch); +} diff --git a/Source/DOH/Doh/void.c b/Source/DOH/Doh/void.c index 63a94ea91..387062e1f 100644 --- a/Source/DOH/Doh/void.c +++ b/Source/DOH/Doh/void.c @@ -10,7 +10,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_void_c[] = "$Header$"; #include "dohint.h" @@ -88,15 +88,10 @@ static DohObjInfo DohVoidType = { * ----------------------------------------------------------------------------- */ DOH * -NewVoid(void *obj, void (*del)(void *)) { - static int init = 0; +DohNewVoid(void *obj, void (*del)(void *)) { VoidObj *v; - if (!init) { - DohRegisterType(DOHTYPE_VOID, &DohVoidType); - init = 1; - } v = (VoidObj *) DohMalloc(sizeof(VoidObj)); v->ptr = obj; v->del = del; - return DohObjMalloc(DOHTYPE_VOID,v); + return DohObjMalloc(&DohVoidType,v); } diff --git a/Source/DOH/Include/doh.h b/Source/DOH/Include/doh.h index e40ced2f3..29c4acf95 100644 --- a/Source/DOH/Include/doh.h +++ b/Source/DOH/Include/doh.h @@ -14,6 +14,105 @@ #ifndef _DOH_H #define _DOH_H +/* Set the namespace prefix for DOH API functions. This can be used to control + visibility of the functions in libraries */ + +/* Set this macro if you want to change DOH linkage. You would do this if you + wanted to hide DOH in a library using a different set of names. Note: simply + change "Doh" to a new name. */ + +/* +#define DOH_NAMESPACE(x) Doh ## x +*/ + +#ifdef DOH_NAMESPACE + +/* Namespace control. These macros define all of the public API names in DOH */ + +#define DohCheck DOH_NAMESPACE(Check) +#define DohIntern DOH_NAMESPACE(Intern) +#define DohDelete DOH_NAMESPACE(Delete) +#define DohCopy DOH_NAMESPACE(Copy) +#define DohClear DOH_NAMESPACE(Clear) +#define DohStr DOH_NAMESPACE(Str) +#define DohData DOH_NAMESPACE(Data) +#define DohDump DOH_NAMESPACE(Dump) +#define DohLen DOH_NAMESPACE(Len) +#define DohHashval DOH_NAMESPACE(Hashval) +#define DohCmp DOH_NAMESPACE(Cmp) +#define DohIncref DOH_NAMESPACE(Incref) +#define DohGetattr DOH_NAMESPACE(Getattr) +#define DohSetattr DOH_NAMESPACE(Setattr) +#define DohDelattr DOH_NAMESPACE(Delattr) +#define DohFirstkey DOH_NAMESPACE(Firstkey) +#define DohNextkey DOH_NAMESPACE(Nextkey) +#define DohKeys DOH_NAMESPACE(Keys) +#define DohGetInt DOH_NAMESPACE(GetInt) +#define DohGetDouble DOH_NAMESPACE(GetDouble) +#define DohGetChar DOH_NAMESPACE(GetChar) +#define DohSetChar DOH_NAMESPACE(SetChar) +#define DohSetInt DOH_NAMESPACE(SetInt) +#define DohSetDouble DOH_NAMESPACE(SetDouble) +#define DohSetVoid DOH_NAMESPACE(SetVoid) +#define DohGetVoid DOH_NAMESPACE(GetVoid) +#define DohGetitem DOH_NAMESPACE(Getitem) +#define DohSetitem DOH_NAMESPACE(Setitem) +#define DohDelitem DOH_NAMESPACE(Delitem) +#define DohInsertitem DOH_NAMESPACE(Insertitem) +#define DohFirstitem DOH_NAMESPACE(Firstitem) +#define DohNextitem DOH_NAMESPACE(Nextitem) +#define DohWrite DOH_NAMESPACE(Write) +#define DohRead DOH_NAMESPACE(Read) +#define DohSeek DOH_NAMESPACE(Seek) +#define DohTell DOH_NAMESPACE(Tell) +#define DohGetc DOH_NAMESPACE(Getc) +#define DohPutc DOH_NAMESPACE(Putc) +#define DohUngetc DOH_NAMESPACE(Ungetc) +#define DohGetline DOH_NAMESPACE(Getline) +#define DohSetline DOH_NAMESPACE(Setline) +#define DohGetfile DOH_NAMESPACE(Getfile) +#define DohSetfile DOH_NAMESPACE(Setfile) +#define DohReplace DOH_NAMESPACE(Replace) +#define DohChop DOH_NAMESPACE(Chop) +#define DohGetmeta DOH_NAMESPACE(Getmeta) +#define DohSetmeta DOH_NAMESPACE(Setmeta) +#define DohDelmeta DOH_NAMESPACE(Delmeta) +#define DohEncoding DOH_NAMESPACE(Encoding) +#define DohPrintf DOH_NAMESPACE(Printf) +#define DohvPrintf DOH_NAMESPACE(vPrintf) +#define DohPrintv DOH_NAMESPACE(Printv) +#define DohReadline DOH_NAMESPACE(Readline) +#define DohIsMapping DOH_NAMESPACE(IsMapping) +#define DohIsSequence DOH_NAMESPACE(IsSequence) +#define DohIsString DOH_NAMESPACE(IsString) +#define DohIsFile DOH_NAMESPACE(IsFile) +#define DohNewString DOH_NAMESPACE(NewString) +#define DohNewStringf DOH_NAMESPACE(NewStringf) +#define DohStrcmp DOH_NAMESPACE(Strcmp) +#define DohStrncmp DOH_NAMESPACE(Strncmp) +#define DohStrstr DOH_NAMESPACE(Strstr) +#define DohStrchr DOH_NAMESPACE(Strchr) +#define DohNewFile DOH_NAMESPACE(NewFile) +#define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile) +#define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd) +#define DohClose DOH_NAMESPACE(Close) +#define DohCopyto DOH_NAMESPACE(Copyto) +#define DohNewList DOH_NAMESPACE(NewList) +#define DohNewHash DOH_NAMESPACE(NewHash) +#define DohNewVoid DOH_NAMESPACE(NewVoid) +#define DohSplit DOH_NAMESPACE(Split) +#define DohNone DOH_NAMESPACE(None) + +#define DohObjMalloc DOH_NAMESPACE(ObjMalloc) +#define DohObjFree DOH_NAMESPACE(ObjFree) +#define DohStringType DOH_NAMESPACE(StringType) +#define DohListType DOH_NAMESPACE(ListType) +#define DohHashType DOH_NAMESPACE(HashType) +#define DohFileType DOH_NAMESPACE(FileType) +#define DohVoidType DOH_NAMESPACE(VoidType) + +#endif + #include #include @@ -53,8 +152,8 @@ typedef void DOH; #define DohFree free #endif -extern int DohCheck(const DOH *ptr); /* Check if a DOH object */ -extern void DohIntern(DOH *); /* Intern an object */ +extern int DohCheck(const DOH *ptr); /* Check if a DOH object */ +extern void DohIntern(DOH *); /* Intern an object */ /* Basic object methods. Common to most objects */ @@ -71,64 +170,126 @@ extern void DohIncref(DOH *obj); /* Mapping methods */ -extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name); -extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char *value); -extern void DohDelattr(DOH *obj, const DOHString_or_char *name); -extern DOH *DohFirstkey(DOH *obj); -extern DOH *DohNextkey(DOH *obj); -extern int DohGetInt(DOH *obj, const DOHString_or_char *name); -extern double DohGetDouble(DOH *obj, const DOHString_or_char *name); -extern char *DohGetChar(DOH *obj, const DOHString_or_char *name); -extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int); -extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double); -extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name); -extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value); +extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name); +extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char *value); +extern int DohDelattr(DOH *obj, const DOHString_or_char *name); +extern DOH *DohFirstkey(DOH *obj); +extern DOH *DohNextkey(DOH *obj); +extern DOH *DohKeys(DOH *obj); +extern int DohGetInt(DOH *obj, const DOHString_or_char *name); +extern double DohGetDouble(DOH *obj, const DOHString_or_char *name); +extern char *DohGetChar(DOH *obj, const DOHString_or_char *name); +extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int); +extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double); +extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name); +extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value); /* Sequence methods */ -extern DOH *DohGetitem(DOH *obj, int index); -extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char *value); -extern int DohDelitem(DOH *obj, int index); -extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char *value); -extern DOH *DohFirstitem(DOH *obj); -extern DOH *DohNextitem(DOH *obj); +extern DOH *DohGetitem(DOH *obj, int index); +extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char *value); +extern int DohDelitem(DOH *obj, int index); +extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char *value); +extern DOH *DohFirstitem(DOH *obj); +extern DOH *DohNextitem(DOH *obj); /* File methods */ -extern int DohWrite(DOHFile *obj, void *buffer, int length); -extern int DohRead(DOHFile *obj, void *buffer, int length); -extern int DohSeek(DOHFile *obj, long offset, int whence); -extern long DohTell(DOHFile *obj); -extern int DohGetc(DOHFile *obj); -extern int DohPutc(int ch, DOHFile *obj); -extern int DohUngetc(int ch, DOHFile *obj); +extern int DohWrite(DOHFile *obj, void *buffer, int length); +extern int DohRead(DOHFile *obj, void *buffer, int length); +extern int DohSeek(DOHFile *obj, long offset, int whence); +extern long DohTell(DOHFile *obj); +extern int DohGetc(DOHFile *obj); +extern int DohPutc(int ch, DOHFile *obj); +extern int DohUngetc(int ch, DOHFile *obj); /* Positional */ -extern int DohGetline(DOH *obj); -extern void DohSetline(DOH *obj, int line); -extern DOH *DohGetfile(DOH *obj); -extern void DohSetfile(DOH *obj, DOH *file); +extern int DohGetline(DOH *obj); +extern void DohSetline(DOH *obj, int line); +extern DOH *DohGetfile(DOH *obj); +extern void DohSetfile(DOH *obj, DOH *file); /* String Methods */ -extern int DohReplace(DOHString *src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags); -extern void DohChop(DOHString *src); +extern int DohReplace(DOHString *src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags); +extern void DohChop(DOHString *src); + +/* Meta-variables */ +extern DOH *DohGetmeta(DOH *, const DOH *); +extern int DohSetmeta(DOH *, const DOH *, const DOH *value); +extern int DohDelmeta(DOH *, const DOH *); /* Utility functions */ -extern void DohEncoding(char *name, DOH *(*fn)(DOH *s)); -extern int DohPrintf(DOHFile *obj, const char *format, ...); -extern int DohvPrintf(DOHFile *obj, const char *format, va_list ap); -extern int DohPrintv(DOHFile *obj, ...); -extern DOH *DohReadline(DOHFile *in); +extern void DohEncoding(char *name, DOH *(*fn)(DOH *s)); +extern int DohPrintf(DOHFile *obj, const char *format, ...); +extern int DohvPrintf(DOHFile *obj, const char *format, va_list ap); +extern int DohPrintv(DOHFile *obj, ...); +extern DOH *DohReadline(DOHFile *in); /* Miscellaneous */ -extern int DohIsMapping(const DOH *obj); -extern int DohIsSequence(const DOH *obj); -extern int DohIsString(const DOH *obj); -extern int DohIsFile(const DOH *obj); +extern int DohIsMapping(const DOH *obj); +extern int DohIsSequence(const DOH *obj); +extern int DohIsString(const DOH *obj); +extern int DohIsFile(const DOH *obj); + +extern void DohSetmark(DOH *obj, int x); +extern int DohGetmark(DOH *obj); + +/* ----------------------------------------------------------------------------- + * Strings. + * ----------------------------------------------------------------------------- */ + +extern DOHString *DohNewString(const DOH *c); +extern DOHString *DohNewStringf(const DOH *fmt, ...); + +extern int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2); +extern int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n); +extern char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2); +extern char *DohStrchr(const DOHString_or_char *s1, int ch); + +/* String replacement flags */ + +#define DOH_REPLACE_ANY 0x01 +#define DOH_REPLACE_NOQUOTE 0x02 +#define DOH_REPLACE_ID 0x04 +#define DOH_REPLACE_FIRST 0x08 + +#define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY) +#define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID) + +/* ----------------------------------------------------------------------------- + * Files + * ----------------------------------------------------------------------------- */ + +extern DOHFile *DohNewFile(DOH *file, const char *mode); +extern DOHFile *DohNewFileFromFile(FILE *f); +extern DOHFile *DohNewFileFromFd(int fd); +extern int DohClose(DOH *file); +extern int DohCopyto(DOHFile *input, DOHFile *output); + + +/* ----------------------------------------------------------------------------- + * List + * ----------------------------------------------------------------------------- */ + +extern DOHList *DohNewList(); + +/* ----------------------------------------------------------------------------- + * Hash + * ----------------------------------------------------------------------------- */ + +extern DOHHash *DohNewHash(); + +/* ----------------------------------------------------------------------------- + * Void + * ----------------------------------------------------------------------------- */ + +extern DOHVoid *DohNewVoid(void *ptr, void (*del)(void *)); +extern DOHList *DohSplit(DOHFile *input, char ch, int nsplits); +extern DOH *DohNone; #ifndef DOH_LONG_NAMES /* Macros to invoke the above functions. Includes the location of @@ -168,6 +329,7 @@ extern int DohIsFile(const DOH *obj); #define Getc DohGetc #define Putc DohPutc #define Ungetc DohUngetc +#define Close DohClose #define vPrintf DohvPrintf #define GetInt DohGetInt #define GetDouble DohGetDouble @@ -182,57 +344,36 @@ extern int DohIsFile(const DOH *obj); #define Readline DohReadline #define Replace DohReplace #define Chop DohChop +#define Getmeta DohGetmeta +#define Setmeta DohSetmeta +#define Delmeta DohDelmeta +#define NewString DohNewString +#define NewStringf DohNewStringf +#define NewHash DohNewHash +#define NewList DohNewList +#define NewFile DohNewFile +#define NewFileFromFile DohNewFileFromFile +#define NewFileFromFd DohNewFileFromFd +#define Close DohClose +#define NewVoid DohNewVoid +#define Keys DohKeys +#define Strcmp DohStrcmp +#define Strncmp DohStrncmp +#define Strstr DohStrstr +#define Strchr DohStrchr +#define Copyto DohCopyto +#define Split DohSplit +#define Setmark DohSetmark +#define Getmark DohGetmark +#define None DohNone #endif -/* ----------------------------------------------------------------------------- - * Strings. - * ----------------------------------------------------------------------------- */ +#ifdef NIL +#undef NIL +#endif -extern DOHString *NewString(const DOH *c); -extern DOHString *NewStringf(const DOH *fmt, ...); +#define NIL (char *) NULL -/* String replacement flags */ - -#define DOH_REPLACE_ANY 0x01 -#define DOH_REPLACE_NOQUOTE 0x02 -#define DOH_REPLACE_ID 0x04 -#define DOH_REPLACE_FIRST 0x08 - -/* ----------------------------------------------------------------------------- - * Files - * ----------------------------------------------------------------------------- */ - -extern DOHFile *NewFile(DOH *file, char *mode); -extern DOHFile *NewFileFromFile(FILE *f); -extern DOHFile *NewFileFromFd(int fd); - -extern int DohCopyto(DOHFile *input, DOHFile *output); - -#define Copyto DohCopyto - -/* ----------------------------------------------------------------------------- - * List - * ----------------------------------------------------------------------------- */ - -extern DOHList *NewList(); - -/* ----------------------------------------------------------------------------- - * Hash - * ----------------------------------------------------------------------------- */ - -extern DOHHash *NewHash(); -extern DOHList *Hash_keys(DOHHash *); - -/* ----------------------------------------------------------------------------- - * Void - * ----------------------------------------------------------------------------- */ - -extern DOHVoid *NewVoid(void *ptr, void (*del)(void *)); - -extern DOHList *DohSplit(DOHFile *input, char *chs, int nsplits); -#define Split DohSplit - -extern DOH *DohNone; #endif /* DOH_H */ diff --git a/Source/DOH/Include/dohobj.h b/Source/DOH/Include/dohobj.h index da270e855..1f3ff19c7 100644 --- a/Source/DOH/Include/dohobj.h +++ b/Source/DOH/Include/dohobj.h @@ -23,6 +23,7 @@ typedef struct { int (*doh_delattr)(DOH *obj, DOH *name); /* Del attribute */ DOH *(*doh_firstkey)(DOH *obj); /* First key */ DOH *(*doh_nextkey)(DOH *obj); /* Next key */ + DOH *(*doh_keys)(DOH *obj); /* All keys as a list */ } DohHashMethods; /* List objects */ @@ -33,7 +34,6 @@ typedef struct { int (*doh_insitem)(DOH *obj, int index, DOH *value); /* Insert item */ DOH *(*doh_firstitem)(DOH *obj); /* Iterators */ DOH *(*doh_nextitem)(DOH *obj); - void (*doh_sort)(DOH *obj, int opt); /* Sort */ } DohListMethods; /* File methods */ @@ -93,37 +93,29 @@ typedef struct DohObjInfo { } DohObjInfo; typedef struct { - void *data; /* Data pointer */ - unsigned int type : 4; /* Object type (max 16 -- deal with it) */ + void *data; /* Data pointer */ + DohObjInfo *type; + void *meta; /* Meta data */ int flag_intern : 1; /* Interned object */ int flag_marked : 1; /* Mark flag. Used to avoid recursive loops in places */ int flag_user : 1; /* User flag */ - int flag_reserved : 1; /* Reserved flag */ - int refcount : 24; /* Reference count (max 16 million) */ + int flag_usermark : 1; /* User marked */ + int refcount : 28; /* Reference count (max 16 million) */ } DohBase; /* Macros for decrefing and increfing (safe for null objects). */ -#define Decref(a) if (a) ((DohBase *) a)->refcount-- -#define Incref(a) if (a) ((DohBase *) a)->refcount++ -#define Refcount(a) ((DohBase *) a)->refcount +#define Decref(a) if (a) ((DohBase *) a)->refcount-- +#define Incref(a) if (a) ((DohBase *) a)->refcount++ +#define Refcount(a) ((DohBase *) a)->refcount /* Macros for manipulating objects in a safe manner */ -#define ObjData(a) ((DohBase *)a)->data -#define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x -#define ObjGetMark(a) ((DohBase *)a)->flag_marked -#define ObjType(a) ((DohBase *)a)->type +#define ObjData(a) ((DohBase *)a)->data +#define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x +#define ObjGetMark(a) ((DohBase *)a)->flag_marked +#define ObjType(a) ((DohBase *)a)->type -extern DOH *DohObjMalloc(int type, void *data); /* Allocate a DOH object */ +extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */ extern void DohObjFree(DOH *ptr); /* Free a DOH object */ -extern void DohRegisterType(int type, DohObjInfo *objinfo); - -#define MAX_DOHTYPE 16 - -#define DOHTYPE_STRING 1 -#define DOHTYPE_LIST 2 -#define DOHTYPE_HASH 3 -#define DOHTYPE_VOID 4 -#define DOHTYPE_FILE 5 #endif /* DOHOBJ_H */ diff --git a/Source/DOH/Makefile.in b/Source/DOH/Makefile.in index f5d9b775c..bfa253c43 100644 --- a/Source/DOH/Makefile.in +++ b/Source/DOH/Makefile.in @@ -10,8 +10,6 @@ exec_prefix= @exec_prefix@ INCLUDE_DIR = $(prefix)/include LIB_DIR = $(exec_prefix)/lib -DOHOPT = - # Installer INSTALL = ./install-sh -c @@ -19,7 +17,7 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM= ${INSTALL} -m 755 all: - cd Doh; $(MAKE) DOHOPT='$(DOHOPT)' + cd Doh; $(MAKE) install: @echo "Installing $(LIB_DIR)/libdoh.a..." diff --git a/Source/DOH/configure.in b/Source/DOH/configure.in index 61c8240f9..11f2272ea 100644 --- a/Source/DOH/configure.in +++ b/Source/DOH/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(Include/doh.h) -AC_PREREQ(2.0) +AC_PREREQ(2.53) # Set name for machine-dependent library files AC_SUBST(MACHDEP) @@ -41,4 +41,4 @@ dnl Checks for header files. AC_HEADER_STDC dnl Checks for library functions. -AC_OUTPUT(Makefile Doh/Makefile ) +AC_OUTPUT(Makefile Doh/Makefile) diff --git a/Source/Include/.cvsignore b/Source/Include/.cvsignore new file mode 100644 index 000000000..1c3642b87 --- /dev/null +++ b/Source/Include/.cvsignore @@ -0,0 +1,3 @@ +swigconfig.h +swigver.h + diff --git a/Source/Include/swigconfig.h.in b/Source/Include/swigconfig.h.in index 7a02d27fb..f5f3e6e18 100644 --- a/Source/Include/swigconfig.h.in +++ b/Source/Include/swigconfig.h.in @@ -1,6 +1,19 @@ -/* This file contains SWIG specific configuration data for those modules +/* This -*-c-*- file contains SWIG specific configuration data for those modules that care */ -#define SWIG_LIB "@prefix@/lib/swig1.3" -#define SWIG_LANG TCL8 +/* Directory where to find the machine-independent SWIG files */ +#define SWIG_LIB "@-swig_lib-@" + +/* Default language */ + +#define SWIG_LANG "-tcl" + +/* Values returned by swig when invoked with the -ldflags option */ + +#define SWIG_PERL_RUNTIME "-L@-exec_prefix-@/lib -lswigpl@-release_suffix-@" +#define SWIG_PYTHON_RUNTIME "-L@-exec_prefix-@/lib -lswigpy@-release_suffix-@" +#define SWIG_TCL_RUNTIME "-L@-exec_prefix-@/lib -lswigtcl@-release_suffix-@" +#define SWIG_RUBY_RUNTIME "-L@-exec_prefix-@/lib -lswigrb@-release_suffix-@" +#define SWIG_GUILE_RUNTIME "-L@-exec_prefix-@/lib -lswigguile@-release_suffix-@" +#define SWIG_PIKE_RUNTIME "-L@-exec_prefix-@/lib -lswigpike@-release_suffix-@" diff --git a/Source/Include/swigver.h b/Source/Include/swigver.h deleted file mode 100644 index c71b6b080..000000000 --- a/Source/Include/swigver.h +++ /dev/null @@ -1,10 +0,0 @@ - -/* SWIG version information */ - -#ifndef SWIG_VERSION -#define SWIG_VERSION "1.3u-20001219-1815" -#endif - -#ifndef SWIG_SPIN -#define SWIG_SPIN "(Alpha 6)" -#endif diff --git a/Source/Include/swigver.h.in b/Source/Include/swigver.h.in index 3f6f4acdd..7d35580ea 100644 --- a/Source/Include/swigver.h.in +++ b/Source/Include/swigver.h.in @@ -5,6 +5,14 @@ #define SWIG_VERSION "@SWIG_VERSION@" #endif -#ifndef SWIG_SPIN -#define SWIG_SPIN "@SWIG_SPIN@" +#ifndef SWIG_MAJOR_VERSION +#define SWIG_MAJOR_VERSION @SWIG_MAJOR_VERSION@ +#endif + +#ifndef SWIG_MINOR_VERSION +#define SWIG_MINOR_VERSION @SWIG_MINOR_VERSION@ +#endif + +#ifndef SWIG_SPIN +#define SWIG_SPIN @SWIG_SPIN@ #endif diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h new file mode 100644 index 000000000..cb4a96346 --- /dev/null +++ b/Source/Include/swigwarn.h @@ -0,0 +1,186 @@ +/* SWIG warning message numbers + + This file serves as the main registry of warning message numbers. Some of these + numbers are used internally in the C/C++ source code of SWIG. However, some + of the numbers are used in SWIG configuration files (swig.swg and others). + + The numbers are roughly organized into a few different classes by functionality. + + Even though symbolic constants are used in the SWIG source, this is + not always the case in SWIG interface files. Do not change the + numbers in this file. + + */ + + + + +#ifndef _SWIGWARN_H +#define _SWIGWARN_H 1 + +#define WARN_NONE 0 + +/* -- Deprecated features -- */ + +#define WARN_DEPRECATED_EXTERN 101 +#define WARN_DEPRECATED_VAL 102 +#define WARN_DEPRECATED_OUT 103 +#define WARN_DEPRECATED_DISABLEDOC 104 +#define WARN_DEPRECATED_ENABLEDOC 105 +#define WARN_DEPRECATED_DOCONLY 106 +#define WARN_DEPRECATED_STYLE 107 +#define WARN_DEPRECATED_LOCALSTYLE 108 +#define WARN_DEPRECATED_TITLE 109 +#define WARN_DEPRECATED_SECTION 110 +#define WARN_DEPRECATED_SUBSECTION 111 +#define WARN_DEPRECATED_SUBSUBSECTION 112 +#define WARN_DEPRECATED_ADDMETHODS 113 +#define WARN_DEPRECATED_READONLY 114 +#define WARN_DEPRECATED_READWRITE 115 +#define WARN_DEPRECATED_EXCEPT 116 +#define WARN_DEPRECATED_NEW 117 +#define WARN_DEPRECATED_EXCEPT_TM 118 +#define WARN_DEPRECATED_IGNORE_TM 119 + +/* -- Preprocessor -- */ + +#define WARN_PP_MISSING_FILE 201 +#define WARN_PP_EVALUATION 202 + +/* -- C/C++ Parser -- */ + +#define WARN_PARSE_CLASS_KEYWORD 301 +#define WARN_PARSE_REDEFINED 302 +#define WARN_PARSE_EXTEND_UNDEF 303 +#define WARN_PARSE_UNSUPPORTED_VALUE 304 +#define WARN_PARSE_BAD_VALUE 305 +#define WARN_PARSE_PRIVATE 306 +#define WARN_PARSE_BAD_DEFAULT 307 +#define WARN_PARSE_NAMESPACE_ALIAS 308 +#define WARN_PARSE_PRIVATE_INHERIT 309 +#define WARN_PARSE_TEMPLATE_REPEAT 310 +#define WARN_PARSE_TEMPLATE_PARTIAL 311 +#define WARN_PARSE_NESTED_CLASS 312 +#define WARN_PARSE_UNDEFINED_EXTERN 313 +#define WARN_PARSE_KEYWORD 314 +#define WARN_PARSE_USING_UNDEF 315 +#define WARN_PARSE_MODULE_REPEAT 316 +#define WARN_PARSE_TEMPLATE_SP_UNDEF 317 +#define WARN_PARSE_TEMPLATE_AMBIG 318 +#define WARN_PARSE_NO_ACCESS 319 + +#define WARN_IGNORE_OPERATOR_NEW 350 /* new */ +#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */ +#define WARN_IGNORE_OPERATOR_PLUS 352 /* + */ +#define WARN_IGNORE_OPERATOR_MINUS 353 /* - */ +#define WARN_IGNORE_OPERATOR_MUL 354 /* * */ +#define WARN_IGNORE_OPERATOR_DIV 355 /* / */ +#define WARN_IGNORE_OPERATOR_MOD 356 /* % */ +#define WARN_IGNORE_OPERATOR_XOR 357 /* ^ */ +#define WARN_IGNORE_OPERATOR_AND 358 /* & */ +#define WARN_IGNORE_OPERATOR_OR 359 /* | */ +#define WARN_IGNORE_OPERATOR_NOT 360 /* ~ */ +#define WARN_IGNORE_OPERATOR_LNOT 361 /* ! */ +#define WARN_IGNORE_OPERATOR_EQ 362 /* = */ +#define WARN_IGNORE_OPERATOR_LT 363 /* < */ +#define WARN_IGNORE_OPERATOR_GT 364 /* > */ +#define WARN_IGNORE_OPERATOR_PLUSEQ 365 /* += */ +#define WARN_IGNORE_OPERATOR_MINUSEQ 366 /* -= */ +#define WARN_IGNORE_OPERATOR_MULEQ 367 /* *= */ +#define WARN_IGNORE_OPERATOR_DIVEQ 368 /* /= */ +#define WARN_IGNORE_OPERATOR_MODEQ 369 /* %= */ +#define WARN_IGNORE_OPERATOR_XOREQ 370 /* ^= */ +#define WARN_IGNORE_OPERATOR_ANDEQ 371 /* &= */ +#define WARN_IGNORE_OPERATOR_OREQ 372 /* |= */ +#define WARN_IGNORE_OPERATOR_LSHIFT 373 /* << */ +#define WARN_IGNORE_OPERATOR_RSHIFT 374 /* >> */ +#define WARN_IGNORE_OPERATOR_LSHIFTEQ 375 /* <<= */ +#define WARN_IGNORE_OPERATOR_RSHIFTEQ 376 /* >>= */ +#define WARN_IGNORE_OPERATOR_EQUALTO 377 /* == */ +#define WARN_IGNORE_OPERATOR_NOTEQUAL 378 /* != */ +#define WARN_IGNORE_OPERATOR_LTEQUAL 379 /* <= */ +#define WARN_IGNORE_OPERATOR_GTEQUAL 380 /* >= */ +#define WARN_IGNORE_OPERATOR_LAND 381 /* && */ +#define WARN_IGNORE_OPERATOR_LOR 382 /* || */ +#define WARN_IGNORE_OPERATOR_PLUSPLUS 383 /* ++ */ +#define WARN_IGNORE_OPERATOR_MINUSMINUS 384 /* -- */ +#define WARN_IGNORE_OPERATOR_COMMA 385 /* , */ +#define WARN_IGNORE_OPERATOR_ARROWSTAR 386 /* ->* */ +#define WARN_IGNORE_OPERATOR_ARROW 387 /* -> */ +#define WARN_IGNORE_OPERATOR_CALL 388 /* () */ +#define WARN_IGNORE_OPERATOR_INDEX 389 /* [] */ +#define WARN_IGNORE_OPERATOR_UPLUS 390 /* + */ +#define WARN_IGNORE_OPERATOR_UMINUS 391 /* - */ +#define WARN_IGNORE_OPERATOR_UMUL 392 /* * */ +#define WARN_IGNORE_OPERATOR_UAND 393 /* & */ +#define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */ +#define WARN_IGNORE_OEPRATOR_DELARR 395 /* delete [] */ + +/* 394-399 are reserved */ + +/* -- Type system and typemaps -- */ + +#define WARN_TYPE_UNDEFINED_CLASS 401 +#define WARN_TYPE_INCOMPLETE 402 +#define WARN_TYPE_ABSTRACT 403 +#define WARN_TYPE_REDEFINED 404 + +#define WARN_TYPEMAP_SOURCETARGET 450 +#define WARN_TYPEMAP_CHARLEAK 451 +#define WARN_TYPEMAP_SWIGTYPE 452 +#define WARN_TYPEMAP_APPLY_UNDEF 453 + +#define WARN_TYPEMAP_IN_UNDEF 460 +#define WARN_TYPEMAP_OUT_UNDEF 461 +#define WARN_TYPEMAP_VARIN_UNDEF 462 +#define WARN_TYPEMAP_VAROUT_UNDEF 463 +#define WARN_TYPEMAP_CONST_UNDEF 464 +#define WARN_TYPEMAP_UNDEF 465 +#define WARN_TYPEMAP_VAR_UNDEF 466 +#define WARN_TYPEMAP_TYPECHECK 467 +#define WARN_TYPEMAP_THROW 468 + +/* -- General code generation -- */ + +#define WARN_LANG_OVERLOAD_DECL 501 +#define WARN_LANG_OVERLOAD_CONSTRUCT 502 +#define WARN_LANG_IDENTIFIER 503 +#define WARN_LANG_RETURN_TYPE 504 +#define WARN_LANG_VARARGS 505 +#define WARN_LANG_VARARGS_KEYWORD 506 +#define WARN_LANG_NATIVE_UNIMPL 507 +#define WARN_LANG_DEREF_SHADOW 508 +#define WARN_LANG_OVERLOAD_SHADOW 509 +#define WARN_LANG_FRIEND_IGNORE 510 +#define WARN_LANG_OVERLOAD_KEYWORD 511 +#define WARN_LANG_OVERLOAD_CONST 512 +#define WARN_LANG_CLASS_UNNAMED 513 + +/* -- Reserved (600-799) -- */ + +/* -- Language module specific warnings (800 - 999) -- */ + +#define WARN_RUBY_WRONG_NAME 801 +#define WARN_RUBY_MULTIPLE_INHERITANCE 802 + +#define WARN_JAVA_TYPEMAP_JNI_UNDEF 810 +#define WARN_JAVA_TYPEMAP_JTYPE_UNDEF 811 +#define WARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812 +#define WARN_JAVA_MULTIPLE_INHERITANCE 813 +#define WARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814 +#define WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815 +#define WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF 816 +#define WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817 +#define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818 + +/* please leave 810-830 free for Java */ + + + +/* Feel free to claim any number in this space that's not currently being used. Just make sure you + add an entry here */ + +#endif + + + diff --git a/Source/Modules1.1/Makefile.in b/Source/Modules1.1/Makefile.in index 509f7effe..bfa308a2f 100644 --- a/Source/Modules1.1/Makefile.in +++ b/Source/Modules1.1/Makefile.in @@ -7,32 +7,25 @@ VPATH = @srcdir@ SHELL = /bin/sh CXX = @CXX@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ @SWILL@ YACC = @YACC@ AR = @AR@ RANLIB = @RANLIB@ TARGET = libmodules11.a -COREOBJS = main.o emit.o lang.o generate.o -CORESRCS = main.cxx emit.cxx lang.cxx generate.cxx +OBJS = main.@OBJEXT@ module.@OBJEXT@ emit.@OBJEXT@ overload.@OBJEXT@ lang.@OBJEXT@ typepass.@OBJEXT@ allocate.@OBJEXT@ browser.@OBJEXT@ contract.@OBJEXT@ swigmain.@OBJEXT@ tcl8.@OBJEXT@ python.@OBJEXT@ perl5.@OBJEXT@ guile.@OBJEXT@ ruby.@OBJEXT@ mzscheme.@OBJEXT@ java.@OBJEXT@ php4.@OBJEXT@ ocaml.@OBJEXT@ xml.@OBJEXT@ pike.@OBJEXT@ s-exp.@OBJEXT@ +SRCS = main.cxx module.cxx emit.cxx overload.cxx lang.cxx typepass.cxx allocate.cxx browser.cxx contract.cxx swigmain.cxx tcl8.cxx python.cxx perl5.cxx guile.cxx ruby.cxx mzscheme.cxx java.cxx php4.cxx ocaml.cxx xml.cxx pike.cxx s-exp.cxx -LANGOBJS = tcl8.o python.o perl5.o guile.o ruby.o mzscheme.o #java.o -LANGSRCS = tcl8.cxx python.cxx perl5.cxx guile.cxx ruby.cxx mzscheme.cxx #java.cxx - -OBJS = $(COREOBJS) $(LANGOBJS) xml.o -SRCS = $(CORESRCS) $(LANGSRCS) xml.cxx - -INCLUDE = -I$(srcdir)/../Include \ - -I$(srcdir)/../Preprocessor \ - -I$(srcdir)/../LParse \ +INCLUDES = -I$(srcdir)/../Include \ -I$(srcdir)/../DOH/Include \ + -I$(srcdir)/../Preprocessor \ -I$(srcdir)/../Swig \ -I../Include -# Rules for creation of a .o file from .cxx +# Rules for creation of a .@OBJEXT@ file from .cxx .SUFFIXES: .cxx -.cxx.o: - $(CXX) $(INCLUDE) $(CFLAGS) -c -o $*.o $< +.cxx.@OBJEXT@: + $(CXX) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $< swig: $(TARGET) @@ -42,7 +35,7 @@ $(TARGET): $(OBJS) $(RANLIB) $(TARGET) clean:: - rm -f *.o *~ $(TARGET) + rm -f *.@OBJEXT@ *~ $(TARGET) nuke:: - rm -f Makefile *~ #* core a.out + rm -f Makefile *~ diff --git a/Source/Modules1.1/README b/Source/Modules1.1/README new file mode 100644 index 000000000..058779d22 --- /dev/null +++ b/Source/Modules1.1/README @@ -0,0 +1,9 @@ +06/25/2002 + +This directory contains all of the SWIG language modules. Many of these +modules contain code that dates back to SWIG1.0. The module API has changed +a lot in the development releases so this is fairly messy. We're working on +cleaning it up, but you'll have to bear with us until it's done. + +-- Dave + diff --git a/Source/Modules1.1/allocate.cxx b/Source/Modules1.1/allocate.cxx new file mode 100644 index 000000000..4d7db5fae --- /dev/null +++ b/Source/Modules1.1/allocate.cxx @@ -0,0 +1,453 @@ +/* ----------------------------------------------------------------------------- + * allocate.cxx + * + * This module tries to figure out which classes and structures support + * default constructors and destructors in C++. There are several rules that + * define this behavior including pure abstract methods, private sections, + * and non-default constructors in base classes. See the ARM or + * Doc/Manual/SWIGPlus.html for details. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1998-2002. The University of Chicago + * Copyright (C) 1995-1998. The University of Utah and The Regents of the + * University of California. + * + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_allocate_cxx[] = "$Header$"; + +#include "swigmod.h" + +class Allocate : public Dispatcher { + Node *inclass; + enum AccessMode { PUBLIC, PRIVATE, PROTECTED }; + AccessMode cplus_mode; + int extendmode; + + /* Checks to see if a class is abstract through inheritance */ + int is_abstract_inherit(Node *n, Node *base = 0, int first = 0) { + if (!first && (base == n)) return 0; + if (!base) { + /* Root node */ + Symtab *stab = Getattr(n,"symtab"); /* Get symbol table for node */ + Symtab *oldtab = Swig_symbol_setscope(stab); + int ret = is_abstract_inherit(n,n,1); + Swig_symbol_setscope(oldtab); + return ret; + } + List *abstract = Getattr(base,"abstract"); + if (abstract) { + for (int i = 0; i < Len(abstract); i++) { + Node *nn = Getitem(abstract,i); + String *name = Getattr(nn,"name"); + String *base_decl = Getattr(nn,"decl"); + if (Strstr(name,"~")) continue; /* Don't care about destructors */ + int implemented = 0; + Node *dn = Swig_symbol_clookup(name,0); + if (!dn) { + Printf(stdout,"node: %x '%s'. base: %x '%s'. member '%s'\n", n, Getattr(n,"name"), base, Getattr(base,"name"), name); + } + assert(dn); // Assertion of doom + while (dn && !implemented) { + String *local_decl = Getattr(dn,"decl"); + if (local_decl && !Strcmp(local_decl, base_decl)) { + if (Getattr(dn,"abstract")) return 1; + implemented++; + } + dn = Getattr(dn,"csym:nextSibling"); + } + if (!implemented && (Getattr(nn,"abstract"))) { + return 1; + } + /* + if (dn && (Getattr(dn,"abstract"))) { + return 1; + } + */ + } + } + List *bases = Getattr(base,"bases"); + if (!bases) return 0; + for (int i = 0; i < Len(bases); i++) { + if (is_abstract_inherit(n,Getitem(bases,i))) { + return 1; + } + } + return 0; + } + + + /* Grab methods used by smart pointers */ + + List *smart_pointer_methods(Node *cls, List *methods) { + if (!methods) { + methods = NewList(); + } + + Node *c = firstChild(cls); + String *kind = Getattr(cls,"kind"); + int mode; + if (Strcmp(kind,"class") == 0) mode = PRIVATE; + else mode = PUBLIC; + + while (c) { + if (Getattr(c,"error") || Getattr(c,"feature:ignore")) { + c = nextSibling(c); + continue; + } + if (Strcmp(nodeType(c),"cdecl") == 0) { + if (!Getattr(c,"feature:ignore")) { + String *storage = Getattr(c,"storage"); + if (!((Cmp(storage,"static") == 0) || (Cmp(storage,"typedef") == 0))) { + String *name = Getattr(c,"name"); + String *symname = Getattr(c,"sym:name"); + Node *e = Swig_symbol_clookup_local(name,0); + if (e && !Getattr(e,"feature:ignore") && (Cmp(symname, Getattr(e,"sym:name")) == 0)) { + Swig_warning(WARN_LANG_DEREF_SHADOW,Getfile(e),Getline(e),"Declaration of '%s' shadows declaration accessible via operator->() at %s:%d\n", + name, Getfile(c),Getline(c)); + } else { + /* Make sure node with same name doesn't already exist */ + int k; + int match = 0; + for (k = 0; k < Len(methods); k++) { + e = Getitem(methods,k); + if (Cmp(symname,Getattr(e,"sym:name")) == 0) { + match = 1; + break; + } + if ((!symname || (!Getattr(e,"sym:name"))) && (Cmp(name,Getattr(e,"name")) == 0)) { + match = 1; + break; + } + } + if (!match) { + Node *cc = c; + while (cc) { + Append(methods,cc); + cc = Getattr(cc,"sym:nextSibling"); + } + } + } + } + } + } + + if (Strcmp(nodeType(c),"access") == 0) { + kind = Getattr(c,"kind"); + if (Strcmp(kind,"public") == 0) mode = PUBLIC; + else mode = PRIVATE; + } + c = nextSibling(c); + } + /* Look for methods in base classes */ + { + Node *bases = Getattr(cls,"bases"); + int k; + for (k = 0; k < Len(bases); k++) { + smart_pointer_methods(Getitem(bases,k),methods); + } + } + /* Remove protected/private members */ + { + for (int i = 0; i < Len(methods); ) { + Node *n = Getitem(methods,i); + if (checkAttribute(n,"access","protected") || checkAttribute(n,"access","private")) { + Delitem(methods,i); + continue; + } + i++; + } + } + return methods; + } + + void mark_exception_classes(ParmList *p) { + while(p) { + SwigType *ty = Getattr(p,"type"); + SwigType *t = SwigType_typedef_resolve_all(ty); + Node *c = Swig_symbol_clookup(t,0); + if (c) { + Setattr(c,"cplus:exceptionclass","1"); + } + p = nextSibling(p); + } + } + +public: + virtual int top(Node *n) { + cplus_mode = PUBLIC; + inclass = 0; + extendmode = 0; + emit_children(n); + return SWIG_OK; + } + + virtual int importDirective(Node *n) { return emit_children(n); } + virtual int includeDirective(Node *n) { return emit_children(n); } + virtual int externDeclaration(Node *n) { return emit_children(n); } + virtual int namespaceDeclaration(Node *n) { return emit_children(n); } + virtual int extendDirective(Node *n) { + extendmode = 1; + emit_children(n); + extendmode = 0; + return SWIG_OK; + } + + virtual int classDeclaration(Node *n) { + Symtab *symtab = Swig_symbol_current(); + Swig_symbol_setscope(Getattr(n,"symtab")); + + if (!CPlusPlus) { + /* Always have default constructors/destructors in C */ + Setattr(n,"allocate:default_constructor","1"); + Setattr(n,"allocate:default_destructor","1"); + } + + if (Getattr(n,"allocate:visit")) return SWIG_OK; + Setattr(n,"allocate:visit","1"); + + /* Always visit base classes first */ + { + List *bases = Getattr(n,"bases"); + if (bases) { + for (int i = 0; i < Len(bases); i++) { + Node *b = Getitem(bases,i); + classDeclaration(b); + } + } + } + + inclass = n; + String *kind = Getattr(n,"kind"); + if (Strcmp(kind,"class") == 0) { + cplus_mode = PRIVATE; + } else { + cplus_mode = PUBLIC; + } + + emit_children(n); + + /* Check if the class is abstract via inheritance. This might occur if a class didn't have + any pure virtual methods of its own, but it didn't implement all of the pure methods in + a base class */ + + if (is_abstract_inherit(n)) { + if ((!Getattr(n,"abstract")) && ((Getattr(n,"allocate:public_constructor") || (!Getattr(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) { + if (!Getattr(n,"feature:notabstract")) { + Swig_warning(WARN_TYPE_ABSTRACT,Getfile(n),Getline(n),"Class '%s' might be abstract. No constructors generated. \n", SwigType_namestr(Getattr(n,"name"))); + Setattr(n,"abstract",NewList()); + } + } + } + + if (!Getattr(n,"allocate:has_constructor")) { + /* No constructor is defined. We need to check a few things */ + /* If class is abstract. No default constructor. Sorry */ + if (Getattr(n,"abstract")) { + Delattr(n,"allocate:default_constructor"); + } + if (!Getattr(n,"allocate:default_constructor")) { + /* Check base classes */ + List *bases = Getattr(n,"bases"); + int allows_default = 1; + + for (int i = 0; i < Len(bases); i++) { + Node *n = Getitem(bases,i); + /* If base class does not allow default constructor, we don't allow it either */ + if (!Getattr(n,"allocate:default_constructor") && (!Getattr(n,"allocate:default_base_constructor"))) { + allows_default = 0; + } + } + if (allows_default) { + Setattr(n,"allocate:default_constructor","1"); + } + } + } + if (!Getattr(n,"allocate:has_destructor")) { + /* No destructor was defined. We need to check a few things here too */ + List *bases = Getattr(n,"bases"); + int allows_destruct = 1; + + for (int i = 0; i < Len(bases); i++) { + Node *n = Getitem(bases,i); + /* If base class does not allow default destructor, we don't allow it either */ + if (!Getattr(n,"allocate:default_destructor") && (!Getattr(n,"allocate:default_base_destructor"))) { + allows_destruct = 0; + } + } + if (allows_destruct) { + Setattr(n,"allocate:default_destructor","1"); + } + } + + + /* Check if base classes allow smart pointers, but might be hidden */ + if (!Getattr(n,"allocate:smartpointer")) { + Node *sp = Swig_symbol_clookup((char*)"operator ->",0); + if (sp) { + /* Look for parent */ + Node *p = parentNode(sp); + if (Strcmp(nodeType(p),"extend") == 0) { + p = parentNode(p); + } + if (Strcmp(nodeType(p),"class") == 0) { + if (Getattr(p,"feature:ignore")) { + Setattr(n,"allocate:smartpointer",Getattr(p,"allocate:smartpointer")); + } + } + } + } + + /* Only care about default behavior. Remove temporary values */ + Setattr(n,"allocate:visit","1"); + inclass = 0; + Swig_symbol_setscope(symtab); + return SWIG_OK; + } + + virtual int 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; + } + + virtual int cDeclaration(Node *n) { + + mark_exception_classes(Getattr(n,"throws")); + + if (inclass) { + String *name = Getattr(n,"name"); + if (cplus_mode != PUBLIC) { + /* Look for a private assignment operator */ + if (Strcmp(name,"operator =") == 0) { + Setattr(inclass,"allocate:noassign","1"); + } + } else { + /* Look for smart pointer operator */ + if ((Strcmp(name,"operator ->") == 0) && (!Getattr(n,"feature:ignore"))) { + /* Look for version with no parameters */ + Node *sn = n; + while (sn) { + if (!Getattr(sn,"parms")) { + SwigType *type = SwigType_typedef_resolve_all(Getattr(sn,"type")); + SwigType_push(type,Getattr(sn,"decl")); + Delete(SwigType_pop_function(type)); + SwigType *base = SwigType_base(type); + Node *sc = Swig_symbol_clookup(base, 0); + if ((sc) && (Strcmp(nodeType(sc),"class") == 0)) { + if (SwigType_check_decl(type,"p.")) { + List *methods = smart_pointer_methods(sc,0); + Setattr(inclass,"allocate:smartpointer",methods); + break; + } else { + /* Hmmm. The return value is not a pointer. If the type is a value + or reference. We're going to chase it to see if another operator->() + can be found */ + + if ((SwigType_check_decl(type,"")) || (SwigType_check_decl(type,"r."))) { + Node *nn = Swig_symbol_clookup((char*)"operator ->", Getattr(sc,"symtab")); + if (nn) { + sn = nn; + continue; + } else { + break; + } + } else { + break; + } + } + } else { + break; + } + } else { + break; + } + } + } + } + } + return SWIG_OK; + } + + virtual int constructorDeclaration(Node *n) { + if (!inclass) return SWIG_OK; + Parm *parms = Getattr(n,"parms"); + + mark_exception_classes(Getattr(n,"throws")); + if (!extendmode) { + if (!ParmList_numrequired(parms)) { + /* Class does define a default constructor */ + /* However, we had better see where it is defined */ + if (cplus_mode == PUBLIC) { + Setattr(inclass,"allocate:default_constructor","1"); + } else if (cplus_mode == PROTECTED) { + Setattr(inclass,"allocate:default_base_constructor","1"); + } + } + /* Class defines some kind of constructor. May or may not be public */ + Setattr(inclass,"allocate:has_constructor","1"); + if (cplus_mode == PUBLIC) { + Setattr(inclass,"allocate:public_constructor","1"); + } + } + + /* See if this is a copy constructor */ + if (parms && (ParmList_numrequired(parms) == 1)) { + /* Look for a few cases. X(const X &), X(X &), X(X *) */ + + String *cc = NewStringf("r.q(const).%s", Getattr(inclass,"name")); + if (Strcmp(cc,Getattr(parms,"type")) == 0) { + Setattr(n,"copy_constructor","1"); + } + Delete(cc); + cc = NewStringf("r.%s", Getattr(inclass,"name")); + if (Strcmp(cc,Getattr(parms,"type")) == 0) { + Setattr(n,"copy_constructor","1"); + } + Delete(cc); + cc = NewStringf("p.%s", Getattr(inclass,"name")); + String *ty = SwigType_strip_qualifiers(Getattr(parms,"type")); + if (Strcmp(cc,ty) == 0) { + Setattr(n,"copy_constructor","1"); + } + Delete(cc); + Delete(ty); + } + return SWIG_OK; + } + + virtual int destructorDeclaration(Node *n) { + if (!inclass) return SWIG_OK; + if (!extendmode) { + Setattr(inclass,"allocate:has_destructor","1"); + if (cplus_mode == PUBLIC) { + Setattr(inclass,"allocate:default_destructor","1"); + } else if (cplus_mode == PROTECTED) { + Setattr(inclass,"allocate:default_base_destructor","1"); + } + } + return SWIG_OK; + } +}; + +void Swig_default_allocators(Node *n) { + if (!n) return; + Allocate *a = new Allocate; + a->top(n); + delete a; +} + + + + + + + diff --git a/Source/Modules1.1/browser.cxx b/Source/Modules1.1/browser.cxx new file mode 100644 index 000000000..da90a81b8 --- /dev/null +++ b/Source/Modules1.1/browser.cxx @@ -0,0 +1,415 @@ +/* ----------------------------------------------------------------------------- + * browser.cxx + * + * A web-base parse tree browser using SWILL. This is an optional + * feature that's normally disabled. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 2002. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_browser_cxx[] = "$Header$"; + +#include "swigmod.h" + +#ifdef SWIG_SWILL +extern "C" { +#include "swill.h" +} + +static FILE *out = 0; +static Node *view_top = 0; + +class Browser : public Dispatcher { + void show_checkbox(Node *t, Node *n) { + int v = 0; + if (Getmeta(n,"visible")) { + v = 1; + } + if (v) { + Printf(out,"[-] ", n, t, n,n); + } else { + Printf(out,"[+] ", n, t, n,n); + } + } + void show_attributes(Node *obj) { + if (!Getmeta(obj,"visible")) return; + String *os = NewString(""); + String *k; + k = Firstkey(obj); + while (k) { + if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) || + (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) || + (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) { + /* Do nothing */ + } else if (Cmp(k,"parms") == 0) { + String *o = NewString(""); + Printf(o,"%s", ParmList_protostr(Getattr(obj,k))); + Replaceall(o,"&","&"); + Replaceall(o,"<","<"); + Replaceall(o,">",">"); + Printf(os,"? %-12s - %s\n", Getattr(obj,k), k, o); + Delete(o); + } else { + DOH *o; + char *trunc = ""; + if (DohIsString(Getattr(obj,k))) { + o = Str(Getattr(obj,k)); + if (Len(o) > 70) { + trunc = "..."; + } + Replaceall(o,"&","&"); + Replaceall(o,"<","<"); + Printf(os,"? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc); + Delete(o); + } else { + Printf(os,"? %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k)); + } + } + k = Nextkey(obj); + } + Printf(out,"
      \n%s
      \n", Char(os)); + Delete(os); + } + +public: + virtual int emit_one(Node *n) { + char *tag = Char(nodeType(n)); + char *file = Char(Getfile(n)); + int line = Getline(n); + char *name = GetChar(n,"name"); + + show_checkbox(view_top, n); + Printf(out,"%s", n, tag); + if (name) { + Printf(out," (%s)", name); + } + Printf(out,". %s:%d\n", file, line); + Printf(out,"
      "); + Dispatcher::emit_one(n); + return SWIG_OK; + } + virtual int emit_children(Node *n) { + if (Getmeta(n,"visible")) { + Printf(out,"
      \n"); + Dispatcher::emit_children(n); + Printf(out,"
      \n"); + } + return SWIG_OK; + } + virtual int defaultHandler(Node *n) { + show_attributes(n); + return SWIG_OK; + } + virtual int top(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + virtual int includeDirective(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + virtual int importDirective(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + + virtual int extendDirective(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + virtual int classDeclaration(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + + virtual int templateDeclaration(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + + virtual int enumDeclaration(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + virtual int typemapDirective(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + virtual int namespaceDeclaration(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + virtual int usingDeclaration(Node *n) { + show_attributes(n); + emit_children(n); + return SWIG_OK; + } + +}; + +static int browser_exit = 0; +static Node *tree_top = 0; +static Browser *browse = 0; + +/* ---------------------------------------------------------------------- + * exit_handler() - Force the browser to exit + * ---------------------------------------------------------------------- */ + +void exit_handler(FILE *f) { + browser_exit = 1; + Printf(f,"Terminated.\n"); +} + +/* ---------------------------------------------------------------------- + * node_handler() - Generate information about a specific node + * ---------------------------------------------------------------------- */ + +static void display(FILE *f, Node *n) { + /* Print standard HTML header */ + + Printf(f,"SWIG-%s\n", SWIG_VERSION); + Printf(f,"SWIG-%s
      \n", SWIG_VERSION); + Printf(f,"[ Exit ]"); + Printf(f," [ Top ]", tree_top); + if (n != tree_top) { + Printf(f," [ Up ]", parentNode(n)); + } + Printf(f," [ Symbols ]"); + Printf(f,"

      \n"); + + out = f; + + browse->emit_one(n); + + /* Print standard footer */ + Printf(f,"


      \n"); + +} + +void node_handler(FILE *f) { + Node *n = 0; + if (!swill_getargs("p(node)", &n)) { + n = tree_top; + } + view_top = n; + display(f,n); +} + + +/* ---------------------------------------------------------------------- + * hide_handler() - Hide a node + * ---------------------------------------------------------------------- */ + +void hide_handler(FILE *f) { + Node *n = 0; + if (!swill_getargs("p(hn)", &n)) { + n = 0; + } + if (n) { + Delmeta(n,"visible"); + } + node_handler(f); +} + +void show_handler(FILE *f) { + Node *n = 0; + if (!swill_getargs("p(hn)", &n)) { + n = 0; + } + if (n) { + Setmeta(n,"visible","1"); + } + node_handler(f); +} + +void raw_data(FILE *out, Node *obj) { + if (!obj) return; + if (DohIsMapping(obj)) { + String *k; + String *os = NewString(""); + Printf(os,"Hash {\n"); + k = Firstkey(obj); + while (k) { + DOH *o; + const char *trunc = ""; + if (DohIsString(Getattr(obj,k))) { + o = Str(Getattr(obj,k)); + if (Len(o) > 70) { + trunc = "..."; + } + Replaceall(o,"<","<"); + Printf(os," ? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc); + Delete(o); + } else { + Printf(os," ? %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k)); + } + k = Nextkey(obj); + } + Printf(os,"}\n"); + Printf(out,"
      \n%s
      \n", Char(os)); + Delete(os); + } else if (DohIsString(obj)) { + String *o = Str(obj); + Replaceall(o,"<","<"); + Printf(out,"
      \n%s
      \n", Char(o)); + Delete(o); + } else if (DohIsSequence(obj)) { + int i; + String *os = NewString(""); + Printf(os,"List [\n"); + for (i = 0; i < Len(obj); i++) { + DOH *o = Getitem(obj,i); + const char *trunc = ""; + if (DohIsString(o)) { + String *s = Str(o); + if (Len(s) > 70) { + trunc = "..."; + } + Replaceall(o,"<","<"); + Printf(os," ? [%d] - \"%(escape)-0.70s%s\"\n", o,i,s, trunc); + Delete(s); + } else { + Printf(os," ? [%d] - 0x%x\n", o, i, o); + } + } + Printf(os,"\n]\n"); + Printf(out,"
      \n%s
      \n", Char(os)); + Delete(os); + } +} + +void data_handler(FILE *f) { + DOH *n = 0; + if (!swill_getargs("p(n)", &n)) { + n = 0; + } + Printf(f,"SWIG-%s\n", SWIG_VERSION); + Printf(f,"SWIG-%s
      \n", SWIG_VERSION); + Printf(f,"[ Exit ]"); + Printf(f," [ Top ]", tree_top); + Printf(f,"

      \n"); + if (n) { + raw_data(f,n); + } + /* Print standard footer */ + Printf(f,"


      \n"); +} + +void symbol_handler(FILE *f) { + Symtab *sym; + char *name = 0; + + Printf(f,"SWIG-%s\n", SWIG_VERSION); + Printf(f,"SWIG-%s
      \n", SWIG_VERSION); + Printf(f,"[ Exit ]"); + Printf(f," [ Top ]", tree_top); + Printf(f," [ Symbols ]"); + Printf(f,"

      \n"); + + if (!swill_getargs("p(sym)|s(name)", &sym, &name)) { + sym = Swig_symbol_getscope(""); + name = 0; + } + if (!sym) { + Printf(f,"No symbol table specified!\n"); + return; + } + { + String *q = Swig_symbol_qualifiedscopename(sym); + if (!Len(q)) { + Printf(f,"Symbol table: :: (global)
      \n"); + } else { + Printf(f,"Symbol table: %s
      \n", q); + } + Delete(q); + } + + fprintf(f,"

      \n"); + fprintf(f,"Symbol lookup:
      \n"); + fprintf(f,"\n", sym); + fprintf(f,"Submit : \n"); + fprintf(f,"
      "); + + if (name) { + Node *n = Swig_symbol_clookup(name,sym); + Printf(f,"Symbol '%s':\n", name); + Printf(f,"
      \n"); + if (!n) { + Printf(f,"Not defined!\n"); + } else { + raw_data(f,n); + } + Printf(f,"
      \n"); + } + + Printf(f,"

      Nested scopes
      \n"); + Printf(f,"

      \n");
      +  {
      +    Hash   *h;
      +    h = firstChild(sym);
      +    while (h) {
      +      Printf(f,"%s\n", h, Getattr(h,"name"));
      +      h = nextSibling(h);
      +    }
      +  }
      +  Printf(f,"
      \n"); + + Printf(f,"

      Symbol table contents
      \n"); + raw_data(f,Getattr(sym,"symtab")); + Printf(f,"


      \n"); + +} +#endif + +void +Swig_browser(Node *top, int port) { +#ifdef SWIG_SWILL + int sport; + browser_exit = 0; + + /* Initialize the server */ + sport = swill_init(port); + if (sport < 0) { + Printf(stderr,"Couldn't open socket on port %d. Sorry.\n", port); + return; + } + browse = new Browser(); + Setmeta(top,"visible","1"); + tree_top = top; + + Printf(stderr,"SWIG: Tree browser listening on port %d\n", sport); + + swill_handle("exit.html", exit_handler,0); + swill_handle("index.html", node_handler, 0); + swill_handle("hide.html", hide_handler,0); + swill_handle("show.html", show_handler,0); + swill_handle("data.html", data_handler,0); + swill_handle("symbol.html", symbol_handler, 0); + swill_netscape("index.html"); + + while (!browser_exit) { + swill_serve(); + } + Printf(stderr,"Browser terminated.\n"); + swill_close(); + delete browse; + return; +#endif +} + + + + + diff --git a/Source/Modules1.1/contract.cxx b/Source/Modules1.1/contract.cxx new file mode 100644 index 000000000..fba5827aa --- /dev/null +++ b/Source/Modules1.1/contract.cxx @@ -0,0 +1,118 @@ +/* ----------------------------------------------------------------------------- + * contract.cxx + * + * Experimental support for contracts + * + * Author(s) : Aquinas Hobor (aahobor@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_contract_cxx[] = "$Header$"; + +#include "swigmod.h" + +class Contracts : public Dispatcher { + +public: + virtual int top(Node *n) { + emit_children(n); + return SWIG_OK; + } + + virtual int importDirective(Node *n) { return emit_children(n); } + virtual int includeDirective(Node *n) { return emit_children(n); } // ? + virtual int externDeclaration(Node *n) { return emit_children(n); } + + String * strParms(ParmList *l) { + int comma = 0; + int i = 0; + Parm *p = l; + SwigType *pt; + String * returns = NewString(""); + while(p) { + String *pname; + pt = Getattr(p,"type"); + if ((SwigType_type(pt) != T_VOID)) { + if (comma) Printf(returns,","); + pname = Swig_cparm_name(p,i); + Printf(returns,"%s",SwigType_rcaststr(pt,pname)); + comma = 1; + i++; + } + p = nextSibling(p); + } + return returns; + } + + virtual int cDeclaration(Node *n) { + String *name = Getattr(n,"name"); + String *k = Getattr(n,"feature:contract"); + + if(k) + { + /* make the names */ + ParmList *l = Getmeta(k,"parms"); + String *params = ParmList_str(l); + String *transformed = strParms(l); + if(DohStrcmp(params,"")==0) { + DohDelete(params); + params = DohNewString("void"); + } + String *contractName = DohNewStringf("__SWIG_precontract_%s",name); + + /* make the contract */ + String *contract = DohNewStringf("int %s(%s,int rt[2])\n{\n",contractName,params); + SwigScanner * ss = NewSwigScanner(); + SwigScanner_clear(ss); + SwigScanner_push(ss,Copy(k)); + SwigScanner_token(ss); // Get rid of the '{' at the begining + + /* loop over the clauses */ + int clauseNum = 1; + int token = -1; + while(1) { + String *clause = DohNewString(""); /*BUG -- should free*/ + while((token=SwigScanner_token(ss))) { + if ((token==SWIG_TOKEN_SEMI)||(token==SWIG_TOKEN_RBRACE)) + break; + // if (token != SWIG_TOKEN_ENDLINE) + Printf(clause,"%s",SwigScanner_text(ss)); + } + if (DohStrcmp(clause,"\n") != 0) { + Printf(contract,"if (!(%s",clause); + Printf(contract,")) {\nrt[0]=__LINE__;\nrt[1]=%i;\nreturn 1;\n}\n",clauseNum); + } + if(token==SWIG_TOKEN_RBRACE) break; + clauseNum++; + } + + /* finish it off and attach it to the main tree */ + Printf(contract,"return 0;\n}\n"); + Setattr(n,"wrap:code",contract); /*BUG -- WHAT IF SOMETHING IS ALREADY THERE*/ + + /* Generate the calling code */ + String * calling = DohNewString("{\nint cfail[2];\nchar message[255];\n"); + Printf(calling,"if (%s(%s,cfail)) {\n",contractName,transformed); + Printf(calling,"sprintf(message,\"Contract %s failed on clause %%i (line %%i)!\",cfail[1],cfail[0]);\n",contractName); + Printf(calling,"PyErr_SetString(PyExc_Exception,message);return NULL;\n}\n"); + Printf(calling,"}\n"); + /* Setattr(n,"feature:preassert",calling); */ + } + /*There are two attributes "feature:preassert" and "feature:postassert".*/ + + + return SWIG_OK; + } + +}; + +void Swig_contracts(Node *n) { + Printf(stdout,"Applying contracts (experimental v0.09)\n"); + + Contracts *a = new Contracts; + a->top(n); + delete a; + +} diff --git a/Source/Modules1.1/emit.cxx b/Source/Modules1.1/emit.cxx index 02b98855d..1f4bcf8bb 100644 --- a/Source/Modules1.1/emit.cxx +++ b/Source/Modules1.1/emit.cxx @@ -12,26 +12,11 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -#include "swig11.h" +#include "swigmod.h" -static char cvsroot[] = "$Header$"; +char cvsroot_emit_cxx[] = "$Header$"; -/* ----------------------------------------------------------------------------- - * new_create_function() - * - * Create a new function - * ----------------------------------------------------------------------------- */ - -void new_create_function(char *name, char *iname, SwigType *type, ParmList *l) { - Hash *h; - h = NewHash(); - Setattr(h,"name",name); - Setattr(h,"scriptname",iname); - Setattr(h,"type",type); - Setattr(h,"parms",l); - lang->function(h); - Delete(h); -} +extern SwigType *cplus_value_type(SwigType *t); /* ----------------------------------------------------------------------------- * emit_args() @@ -43,210 +28,425 @@ void new_create_function(char *name, char *iname, SwigType *type, ParmList *l) { * Returns the number of parameters associated with a function. * ----------------------------------------------------------------------------- */ -int emit_args(DOH *node, Wrapper *f) { +void emit_args(SwigType *rt, ParmList *l, Wrapper *f) { - SwigType *rt; - ParmList *l; Parm *p; - int i; - char *tm; - SwigType *pt; - DOHString *pvalue; - DOHString *pname; - DOHString *lname; - - rt = Getattr(node,"type"); - l = Getattr(node,"parms"); + String *tm; /* Emit function arguments */ Swig_cargs(f, l); - i = 0; - p = l; - while (p != 0) { - lname = Getlname(p); - pt = Gettype(p); - pname = Getname(p); - pvalue = Getvalue(p); - - tm = Swig_typemap_lookup((char*)"arginit",pt,pname,(char*)"",lname,f); - if (tm) { - Printv(f,tm,"\n",0); - } - /* Check for ignore or default typemaps */ - tm = Swig_typemap_lookup((char*)"default",pt,pname,(char*)"",lname,f); - if (tm) { - Printv(f,tm,"\n",0); - } - tm = Swig_typemap_lookup((char*)"ignore",pt,pname,(char*)"",lname,f); - if (tm) { - Printv(f,tm,"\n",0); - Setignore(p,1); - } - i++; - p = Getnext(p); - } - return(i); -} - -/* ----------------------------------------------------------------------------- - * int emit_func_call(char *decl, DataType *t, ParmList *l, Wrapper*f) - * - * Emits code for a function call (new version). - * - * Exception handling support : - * - * - This function checks to see if any sort of exception mechanism - * has been defined. If so, we emit the function call in an exception - * handling block. - * ----------------------------------------------------------------------------- */ - -static DOH *fcall = 0; - -void emit_set_action(DOHString_or_char *decl) { - if (fcall) Delete (fcall); - fcall = NewString(decl); -} - -void emit_func_call(DOH *node, Wrapper *f) { - char *decl; - SwigType *t; - ParmList *l; - char *tm; - - decl = GetChar(node,"name"); - t = Getattr(node,"type"); - l = Getattr(node,"parms"); - - if ((tm = Swig_typemap_lookup((char*)"except",t,decl,(char*)"result",(char*)"",0))) { - Printv(f,tm,0); - Replace(f,"$name",decl,DOH_REPLACE_ANY); - } else if ((tm = Swig_except_lookup())) { - Printv(f,tm,0); - Replace(f,"$name",decl,DOH_REPLACE_ANY); - } else { - Printv(f,"$function",0); - } - - if (!fcall) fcall = NewString(Swig_cfunction_call(decl,l)); - - if (CPlusPlus) { - Swig_cppresult(f, t, (char*)"result", Char(fcall)); - } else { - Swig_cresult(f, t, (char*)"result", Char(fcall)); - } - Delete(fcall); - fcall = 0; -} - -/* ----------------------------------------------------------------------------- - * void emit_set_get() - * - * Emits a pair of functions to set/get the value of a variable. This is - * only used in the event the target language can't provide variable linking - * on its own. - * - * double foo; - * - * Gets translated into the following : - * - * double foo_set(double x) { - * return foo = x; - * } - * - * double foo_get() { - * return foo; - * } - * ----------------------------------------------------------------------------- */ - -/* How to assign a C allocated string */ - -static char *c_str = (char *)"\ -if ($target) free($target);\n\ -$target = ($rtype) malloc(strlen($source)+1);\n\ -strcpy((char *)$target,$source);\n\ -return $ltype $target;\n"; - -/* How to assign a C allocated string */ - -static char *cpp_str = (char *)"\ -if ($target) delete [] $target;\n\ -$target = ($rtype) (new char[strlen($source)+1]);\n\ -strcpy((char *)$target,$source);\n\ -return ($ltype) $target;\n;"; - - -void emit_set_get(DOH *node) { - char *name, *iname; - SwigType *t; - Wrapper *w; - DOHString *new_iname; - char *code = 0; - - name = GetChar(node,"name"); - iname = GetChar(node,"iname"); - t = Getattr(node,"type"); - - /* First write a function to set the variable of the variable */ - if (!ReadOnly) { - - if (SwigType_type(t) == T_STRING) { - if (CPlusPlus) - code = cpp_str; - else - code = c_str; - } - w = Swig_cvarset_wrapper(name, t, code); - Printf(f_header,"%s", w); - new_iname = Swig_name_set(iname); - DohIncref(new_iname); - new_create_function(GetChar(w,"name"), Char(new_iname), Gettype(w), Getparms(w)); - Delete(new_iname); - Delete(w); - } - - w = Swig_cvarget_wrapper(name,t,0); - Printf(f_header,"%s", w); - new_iname = Swig_name_get(iname); - DohIncref(new_iname); - new_create_function(GetChar(w,"name"), Char(new_iname), Gettype(w), Getparms(w)); - Delete(new_iname); - Delete(w); -} - -/* ------------------------------------------------------------------ - * int check_numopt() - * - * Gets the number of optional arguments for a ParmList. - * ------------------------------------------------------------------ */ - -int check_numopt(ParmList *p) { - int n = 0; - int i = 0; - int state = 0; - - for (;p; p = Getnext(p),i++) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - if (Getvalue(p)) { - n++; - state = 1; - } else if (Swig_typemap_search((char*)"default",pt,pn)) { - n++; - state = 1; - } else if (Swig_typemap_search((char*)"ignore",pt,pn)) { - n++; + /* Handle return type */ + if (rt && (SwigType_type(rt) != T_VOID)) { + if (!CPlusPlus || (CPlusPlus && !SwigType_isclass(rt))) { + Wrapper_add_local(f,"result", SwigType_lstr(rt,"result")); } else { - if (state) { - Printf(stderr,"%s:%d. Argument %d must have a default value!\n", Getfile(p), Getline(p),i+1); + SwigType *vt = 0; + vt = cplus_value_type(rt); + if (!vt) { + Wrapper_add_local(f,"result", SwigType_lstr(rt,"result")); + } else { + Wrapper_add_local(f,"result", SwigType_lstr(vt,"result")); + Delete(vt); } } } - return n; + + /* Attach typemaps to parameters */ + /* Swig_typemap_attach_parms("ignore",l,f); */ + + Swig_typemap_attach_parms("default",l,f); + Swig_typemap_attach_parms("arginit",l,f); + + /* Apply the arginit and default */ + p = l; + while (p) { + tm = Getattr(p,"tmap:arginit"); + if (tm) { + Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:arginit:next"); + } else { + p = nextSibling(p); + } + } + + /* Apply the default typemap */ + p = l; + while (p) { + tm = Getattr(p,"tmap:default"); + if (tm) { + Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:default:next"); + } else { + p = nextSibling(p); + } + } + +#ifdef DEPRECATED + /* Apply the ignore typemap */ + p = l; + while (p) { + tm = Getattr(p,"tmap:ignore"); + if (tm) { + Parm *np; + Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY); + Printv(f->code,tm,"\n",NIL); + np = Getattr(p,"tmap:ignore:next"); + + /* Deprecate this part later */ + while (p && (p != np)) { + Setattr(p,"ignore","1"); + p = nextSibling(p); + } + /* -- end deprecate */ + + } else { + p = nextSibling(p); + } + } +#endif + return; +} + +/* ----------------------------------------------------------------------------- + * emit_attach_parmmaps() + * + * Attach the standard parameter related typemaps. + * ----------------------------------------------------------------------------- */ + +void emit_attach_parmmaps(ParmList *l, Wrapper *f) { + Swig_typemap_attach_parms("in",l,f); + Swig_typemap_attach_parms("typecheck",l,0); + Swig_typemap_attach_parms("argout",l,f); + Swig_typemap_attach_parms("check",l,f); + Swig_typemap_attach_parms("freearg",l,f); + + { + /* This is compatibility code to deal with the deprecated "ignore" typemap */ + Parm *p = l; + Parm *np; + String *tm; + while (p) { + tm = Getattr(p,"tmap:in"); + if (tm && checkAttribute(p,"tmap:in:numinputs","0")) { + Replaceall(tm,"$target", Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + np = Getattr(p,"tmap:in:next"); + while (p && (p != np)) { + Setattr(p,"ignore","1"); + p = nextSibling(p); + } + } else if (tm) { + p = Getattr(p,"tmap:in:next"); + } else { + p = nextSibling(p); + } + } + } + + /* Perform a sanity check on "in" and "freearg" typemaps. These + must exactly match to avoid chaos. If a mismatch occurs, we + nuke the freearg typemap */ + + { + Parm *p = l; + Parm *npin, *npfreearg; + while (p) { + npin = Getattr(p,"tmap:in:next"); + + /* + if (Getattr(p,"tmap:ignore")) { + npin = Getattr(p,"tmap:ignore:next"); + } else if (Getattr(p,"tmap:in")) { + npin = Getattr(p,"tmap:in:next"); + } + */ + + if (Getattr(p,"tmap:freearg")) { + npfreearg = Getattr(p,"tmap:freearg:next"); + if (npin != npfreearg) { + while (p != npin) { + Delattr(p,"tmap:freearg"); + Delattr(p,"tmap:freearg:next"); + p = nextSibling(p); + } + } + } + p = npin; + } + } + + /* Check for variable length arguments with no input typemap. + If no input is defined, we set this to ignore and print a + message. + */ + { + Parm *p = l; + Parm *lp = 0; + while (p) { + if (!checkAttribute(p,"tmap:in:numinputs","0")) { + lp = p; + p = Getattr(p,"tmap:in:next"); + continue; + } + if (SwigType_isvarargs(Getattr(p,"type"))) { + Swig_warning(WARN_LANG_VARARGS,input_file,line_number,"Variable length arguments discarded.\n"); + Setattr(p,"tmap:in",""); + } + lp = 0; + p = nextSibling(p); + } + + /* Check if last input argument is variable length argument */ + if (lp) { + p = lp; + while (p) { + if (SwigType_isvarargs(Getattr(p,"type"))) { + Setattr(l,"emit:varargs",lp); + break; + } + p = nextSibling(p); + } + } + } +} + +/* ----------------------------------------------------------------------------- + * emit_num_arguments() ** new in 1.3.10 + * + * Calculate the total number of arguments. This function is safe for use + * with multi-valued typemaps which may change the number of arguments in + * strange ways. + * ----------------------------------------------------------------------------- */ + +int emit_num_arguments(ParmList *parms) { + Parm *p = parms; + int nargs = 0; + + while (p) { + if (Getattr(p,"tmap:in")) { + nargs += GetInt(p,"tmap:in:numinputs"); + p = Getattr(p,"tmap:in:next"); + } else { + p = nextSibling(p); + } + } + +#ifdef DEPRECATED + while (p) { + /* Ignored arguments */ + if (Getattr(p,"tmap:ignore")) { + p = Getattr(p,"tmap:ignore:next"); + } else { + /* Marshalled arguments */ + nargs++; + if (Getattr(p,"tmap:in")) { + p = Getattr(p,"tmap:in:next"); + } else { + p = nextSibling(p); + } + } + } +#endif + if (parms && (p = Getattr(parms,"emit:varargs"))) { + if (!nextSibling(p)) { + nargs--; + } + } + return nargs; +} + +/* ----------------------------------------------------------------------------- + * emit_num_required() ** new in 1.3.10 + * + * Computes the number of required arguments. This is function is safe for + * use with multi-valued typemaps and knows how to skip over everything + * properly. + * ----------------------------------------------------------------------------- */ + +int emit_num_required(ParmList *parms) { + Parm *p = parms; + int nargs = 0; + + while (p) { + if (Getattr(p,"tmap:in") && checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } else { + if (Getattr(p,"value")) break; + if (Getattr(p,"tmap:default")) break; + nargs+= GetInt(p,"tmap:in:numinputs"); + if (Getattr(p,"tmap:in")) { + p = Getattr(p,"tmap:in:next"); + } else { + p = nextSibling(p); + } + } + } + + /* Print message for non-default arguments */ + while (p) { + if (Getattr(p,"tmap:in") && checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } else { + if (!Getattr(p,"value") && (!Getattr(p,"tmap:default"))) { + Swig_error(Getfile(p),Getline(p),"Error. Non-optional argument '%s' follows an optional argument.\n",Getattr(p,"name")); + } + if (Getattr(p,"tmap:in")) { + p = Getattr(p,"tmap:in:next"); + } else { + p = nextSibling(p); + } + } + } + + if (parms && (p = Getattr(parms,"emit:varargs"))) { + if (!nextSibling(p)) { + nargs--; + } + } + return nargs; +} + +/* ----------------------------------------------------------------------------- + * emit_isvarargs() + * + * Checks if a function is a varargs function + * ----------------------------------------------------------------------------- */ + +int +emit_isvarargs(ParmList *p) { + if (!p) return 0; + if (Getattr(p,"emit:varargs")) return 1; + return 0; +} + +/* ----------------------------------------------------------------------------- + * replace_args() + * ----------------------------------------------------------------------------- */ + +static +void replace_args(Parm *p, String *s) { + while (p) { + String *n = Getattr(p,"name"); + if (n) { + Replace(s,n,Getattr(p,"lname"), DOH_REPLACE_ID); + } + p = nextSibling(p); + } +} + +/* ----------------------------------------------------------------------------- + * int emit_action() + * + * Emits action code for a wrapper and checks for exception handling + * ----------------------------------------------------------------------------- */ + +void emit_action(Node *n, Wrapper *f) { + String *tm; + String *action; + String *wrap; + Parm *p; + SwigType *rt; + ParmList *throws = Getattr(n,"throws"); + + /* Look for fragments */ + { + String *f; + f = Getattr(n,"feature:fragment"); + if (f) { + char *c, *tok; + String *t = Copy(f); + c = Char(t); + tok = strtok(c,","); + while (tok) { + Swig_fragment_emit(tok); + tok = strtok(NULL,","); + } + Delete(t); + } + } + + /* Emit wrapper code (if any) */ + wrap = Getattr(n,"wrap:code"); + if (wrap && Swig_filebyname("header")!=Getattr(n,"wrap:code:done") ) { + File *f_code = Swig_filebyname("header"); + if (f_code) { + Printv(f_code,wrap,NIL); + } + Setattr(n,"wrap:code:done",f_code); + } + action = Getattr(n,"feature:action"); + if (!action) + action = Getattr(n,"wrap:action"); + assert(action); + + /* Get the return type */ + + rt = Getattr(n,"type"); + + /* Preassert -- EXPERIMENTAL */ + tm = Getattr(n,"feature:preassert"); + if (tm) { + p = Getattr(n,"parms"); + replace_args(p,tm); + Printv(f->code,tm,"\n",NIL); + } + + /* Exception handling code */ + + /* If we are in C++ mode and there is a throw specifier. We're going to + enclose the block in a try block */ + + if (throws) { + Printf(f->code,"try {\n"); + } + + /* Look for except typemap (Deprecated) */ + tm = Swig_typemap_lookup_new("except",n,"result",0); + + /* Look for except feature */ + if (!tm) { + tm = Getattr(n,"feature:except"); + if (tm) tm = Copy(tm); + } + if ((tm) && Len(tm) && (Strcmp(tm,"1") != 0)) { + Replaceall(tm,"$name",Getattr(n,"name")); + Replaceall(tm,"$symname", Getattr(n,"sym:name")); + Replaceall(tm,"$function", action); + Replaceall(tm,"$action", action); + Printv(f->code,tm,"\n", NIL); + Delete(tm); + } else { + Printv(f->code, action, "\n",NIL); + } + + if (throws) { + Printf(f->code,"}\n"); + for (Parm *ep = throws; ep; ep = nextSibling(ep)) { + String *em = Swig_typemap_lookup_new("throws",ep,"_e",0); + if (em) { + Printf(f->code,"catch(%s) {\n", SwigType_str(Getattr(ep,"type"),"&_e")); + Printv(f->code,em,"\n",NIL); + Printf(f->code,"}\n"); + } else { + Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), + "No 'throw' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep,"type"),0)); + } + } + Printf(f->code,"catch(...) { throw; }\n"); + } + + /* Postassert - EXPERIMENTAL */ + tm = Getattr(n,"feature:postassert"); + if (tm) { + p = Getattr(n,"parms"); + replace_args(p,tm); + Printv(f->code,tm,"\n",NIL); + } } - - diff --git a/Source/Modules1.1/generate.cxx b/Source/Modules1.1/generate.cxx deleted file mode 100644 index 51b885ed4..000000000 --- a/Source/Modules1.1/generate.cxx +++ /dev/null @@ -1,909 +0,0 @@ -/* ----------------------------------------------------------------------------- - * generate.cxx - * - * This file manages the code generation process and serves as a bridge between - * the new SWIG parser and the old set of C++-based language modules. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1999-2000. The University of Chicago - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -#include "swig11.h" - -static char cvstag[] = "$Header$"; - -int ReadOnly = 0; -int WrapExtern = 0; - -/* Access permissions: public, private, protected */ -enum { PUBLIC, PRIVATE, PROTECTED }; -int Access = PUBLIC; - -/* Miscellaneous modes */ -int Native = 0; - -/* This function tries to locate the module name within the parse tree */ -static String *find_module(DOH *node) { - DOH *n; - - if (!node) return 0; - n = node; - while (n) { - if (Swig_tag_check(n,"module")) { - return Getname(n); - } - if (Swig_tag_check(n,"file")) { - String *ty; - ty = Getattr(n,"type"); - if (Cmp(ty,"include") == 0) { - DOH *m; - /* Might be in an include file */ - m = find_module(Getchild(n)); - if (m) return m; - } - } - n = Getnext(n); - } - return find_module(Getchild(node)); -} - -/* This helper function emits external function declarations */ -static -void emit_extern_func(DOH *node, File *f) { - Parm *p; - SwigType *tc; - char *c; - String *storage; - storage = Getattr(node,"storage"); - if (!storage) return; - c = Char(storage); - if (strncmp(c,"extern",6) == 0) { - List *tl = NewList(); - p = Getparms(node); - while (p) { - Append(tl,Gettype(p)); - p = Getnext(p); - } - tc = Copy(Gettype(node)); - SwigType_add_function(tc,tl); - Printf(f,"%s %s;\n", storage, SwigType_str(tc,Getname(node))); - Delete(tc); - Delete(tl); - } -} - -/* Test if static */ -static int -check_static(DOH *node) { - String *storage = Getattr(node,"storage"); - if (!storage) return 0; - if (Cmp(storage,"static") == 0) return 1; - return 0; -} - -/* Test if extern */ -static int -check_extern(DOH *node) { - String *storage = Getattr(node,"storage"); - if (!storage) return 0; - if (strncmp(Char(storage),"extern",6) == 0) return 1; - return 0; -} - -static String *new_name = 0; - -/* Handle renaming */ -static -void set_scriptname(DOH *node) { - if (new_name) { - Setattr(node,"scriptname",new_name); - } else { - String *aname = Getattr(node,"altname"); - if (aname) { - Setattr(node,"scriptname",aname); - } else { - Setattr(node,"scriptname", Getname(node)); - } - } - new_name = 0; -} - -/* ----------------------------------------------------------------------------- - * C++ Support - * ----------------------------------------------------------------------------- */ - -static DOH *class_hash = 0; /* Hash table of classes that have been seen so far */ -static DOH *current_class = 0; /* Set when wrapping a class */ -static DOH *class_name = 0; /* Real name of current class */ -static DOH *class_types = 0; /* Types defined within this class */ -static String *construct_name = 0; /* Expected name of a constructor */ -int AddMethods = 0; /* Set when in addmethods mode */ -int Abstract = 0; /* Set when the class is determined to be abstract */ -static int have_destructor = 0; -static int have_constructor = 0; - -/* Check for abstract classes */ - -int cplus_check_abstract(DOH *node) { - while (node) { - if (Getattr(node,"abstract")) return 1; - node = Getnext(node); - } - return 0; -} - -/* Given a class object, this function builds an internal symbol table */ -void cplus_build_symbols(DOH *node) { - Hash *sym; - DOH *c; - sym = Getattr(node,"symbols"); - if (!sym) { - sym = NewHash(); - Setattr(node,"symbols",sym); - } - c = Getchild(node); - while (c) { - String *name = Getname(c); - String *tag = Gettag(c); - if (Cmp(tag,"c:destructor") == 0) { - name = NewStringf("~%s",name); - } - if (name) { - DOH *pnode = Getattr(sym,name); - if (pnode) { - Printf(stderr,"%s:%d. '%s' redefined. Previous definition at %s:%d.\n", - Getfile(c),Getline(c), name, Getfile(pnode), Getline(pnode)); - } else { - Setattr(sym,name,c); - } - } - c = Getnext(c); - } - return; -} - -/* Inherit certain types of declarations from another class */ - - - -/* Add a class type */ -static void -class_addtype(String *name, String *cname) { - String *s; - if (!cname) - s = NewStringf("%s::%s", class_name, name); - else - s = NewStringf("%s::%s", cname, name); - - if (!class_types) class_types = NewHash(); - Setattr(class_types,name,s); -} - -/* Updates a type with a fully qualified version */ -static void -class_update_type(String *type) { - String *base, *rep; - if (!type) return; - base = SwigType_base(type); - if (!class_types) return; - rep = Getattr(class_types,base); - if (rep) { - SwigType_setbase(type,rep); - /* Printf(stdout,"updated type = '%s'\n", type); */ - } -} - -/* Updates a list of parms with fully qualified names */ -static void -class_update_parms(ParmList *p) { - while (p) { - class_update_type(Gettype(p)); - p = Getnext(p); - } -} - -/* Traverse the inheritance hierarchy of a class */ -void -cplus_walk_inherit(DOH *cls, void (*action)(DOH *base, void *clientdata), void *clientdata) { - DOH *base; - List *bases; - int i, nbase; - - bases = Getattr(cls,"bases"); - if (bases) { - nbase = Len(bases); - for (i = 0; i < nbase; i++) { - base = Getattr(class_hash, Getitem(bases,i)); - if (base) { - (*action)(base,clientdata); - - } - } - } -} - -/* Action for inheriting type definitions */ -static void inherit_types(DOH *cls, void *clientdata) { - DOH *ty; - ty = Getattr(cls,"types"); - if (ty) { - String *key; - SwigType_merge_scope(ty,0); - for (key = Firstkey(ty); key; key = Nextkey(ty)) { - class_addtype(key, Getname(cls)); - } - } - cplus_walk_inherit(cls,inherit_types,clientdata); -} - -/* Action for inheriting typemaps */ -static void inherit_typemaps(DOH *cls, void *clientdata) { - DOH *ty; - - cplus_walk_inherit(cls,inherit_typemaps,clientdata); - ty = Getattr(cls,"typemaps"); - if (ty) { - if (!clientdata) - Swig_typemap_new_scope(ty); - else - Swig_typemap_pop_scope(); - } -} - -extern "C" { -int swig11_unknown(DOH *node, void *clientdata) { - Printf(stdout,"::: Unknown tag - '%s'\n", Getattr(node,"tag")); - return 0; -} - -int swig11_nil(DOH *node, void *clientdata) { - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_file() - * - * File inclusion directives. %include, %extern, and %import. - * ----------------------------------------------------------------------------- */ - -int swig11_file(DOH *node, void *clientdata) { - DOH *c; - String *type; - int old_we = WrapExtern; - - type = Getattr(node,"type"); - if ((Cmp(type, "extern") == 0) || (Cmp(type,"import") == 0)) { - WrapExtern = 1; - } - c = Getchild(node); - if (Cmp(type,"import") == 0) { - /* If importing a module, we try to find the module name and pass it to - the language modules */ - String *modname; - modname = find_module(c); - if (modname) { - lang->import(modname); - } - } - Swig_emit_all(c,clientdata); - WrapExtern = old_we; - return 0; -} -/* ----------------------------------------------------------------------------- - * swig11_scope() - * - * Handle the %scope directive. This is a new feature not present in SWIG1.1. - * Creates a new typemap scope and has other side effects. - * ----------------------------------------------------------------------------- */ - -int swig11_scope(DOH *node, void *clientdata) { - DOH *c; - String *name; - - c = Getchild(node); - name = Getname(node); - - Swig_typemap_new_scope(0); - if (name) { - if (Cmp(name,"native") == 0) { - int oldnative = Native; - Native = 1; - Swig_emit_all(c,clientdata); - Native = oldnative; - } else if (Cmp(name,"readonly") == 0) { - int oldro = ReadOnly; - ReadOnly = 1; - Swig_emit_all(c,clientdata); - ReadOnly = oldro; - } else { - Swig_emit_all(c,clientdata); - } - } - Hash *scp = Swig_typemap_pop_scope(); - Setattr(node,"typemaps", scp); - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_insert() - * - * Code insertion with various %{ %} directives. - * ----------------------------------------------------------------------------- */ - -int swig11_insert(DOH *node, void *clientdata) { - String *section; - String *filename; - String *code; - File *out; - - if (WrapExtern) return 0; - - section = Getattr(node,"section"); - if (!section) { - section = (void *) "header"; - } - out = Swig_filebyname(section); - if (!out) { - Printf(stderr,"%s:%d. Can't insert code into unknown section '%s'\n", Getfile(node), Getline(node), section); - return 0; - } - filename = Getattr(node,"filename"); - if (filename) { - /* The user is inserting the contents of a file */ - if (Swig_insert_file(filename,out) < 0) { - Printf(stderr,"%s:%d. File '%s' not found.\n", Getfile(node), Getline(node), filename); - } - return 0; - } - code = Getattr(node,"code"); - if (code) { - Printf(out,"%s",code); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_pragma() - * - * %pragma directive. - * ----------------------------------------------------------------------------- */ - -int swig11_pragma(DOH *node, void *clientdata) { - String *name; - String *value; - - if (WrapExtern) return 0; - - name = Getname(node); - value = Getvalue(node); - - if (Cmp(name,"readonly") == 0) { - ReadOnly = 1; - } else if (Cmp(name,"readwrite") == 0) { - ReadOnly = 0; - } else if (Cmp(name,"name") == 0) { - new_name = value; - } - lang->pragma(node); - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_typemap() - * - * Handle the %typemap directive. - * ----------------------------------------------------------------------------- */ - -int swig11_typemap(DOH *node, void *clientdata) { - String *name; - SwigType *type; - String *code; - DOH *parms; - String *method; - - if (WrapExtern) return 0; - method = Getattr(node,"method"); - name = Getname(node); - type = Gettype(node); - code = Getattr(node,"code"); - parms = Getparms(node); - - if (current_class) { - class_update_type(type); - class_update_type(parms); - } - - if (code) { - Swig_typemap_register(method,type,name,code,parms); - } else { - String *srcname; - String *srctype; - srcname = Getattr(node,"srcname"); - srctype = Getattr(node,"srctype"); - if (srcname && srctype) { - Swig_typemap_copy(method,srctype,srcname,type,name); - } else { - Swig_typemap_clear(method,type,name); - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_apply() - * - * The %apply directive. - * ----------------------------------------------------------------------------- */ - -int swig11_apply(DOH *node, void *clientdata) { - DOH *parms; - String *name; - SwigType *type; - - if (WrapExtern) return 0; - - name = Getname(node); - type = Gettype(node); - parms = Getparms(node); - - while (parms) { - Swig_typemap_apply(type,name,Gettype(parms),Getname(parms)); - parms = Getnext(parms); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_exception() - * - * The %except directive. - * ----------------------------------------------------------------------------- */ - -int swig11_exception(DOH *node, void *clientdata) { - String *code = Getattr(node,"code"); - if (WrapExtern) return 0; - if (code) { - Swig_except_register(code); - } else { - Swig_except_clear(); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_clear() - * - * The %clear directive. - * ----------------------------------------------------------------------------- */ - -int swig11_clear(DOH *node, void *clientdata) { - DOH *parms = Getattr(node,"parms"); - if (WrapExtern) return 0; - while (parms) { - Swig_typemap_clear_apply(Gettype(parms),Getname(parms)); - parms = Getnext(parms); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_constant - * - * The %constant directive - * ----------------------------------------------------------------------------- */ - -int swig11_constant(DOH *node, void *clientdata) { - if (WrapExtern) return 0; - if (Access != PUBLIC) return 0; - - set_scriptname(node); - lang->constant(node); - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_function() - * - * Emit a wrapper function. - * ----------------------------------------------------------------------------- */ - -int swig11_function(DOH *node, void *clientdata) { - int is_static; - if (WrapExtern) return 0; - if (Access != PUBLIC) return 0; - - is_static = check_static(node); - set_scriptname(node); - - /* Will need some kind of class check in here */ - - if (current_class) { - /* Function has been declared inside a class definition. */ - class_update_parms(Getparms(node)); - class_update_type(Gettype(node)); - String *name = Getname(node); - if (Cmp(name,construct_name) == 0) { - have_constructor =1; - if (!Abstract) { - lang->cpp_constructor(node); - } - } else { - if (is_static) lang->cpp_staticfunction(node); - else lang->cpp_memberfunction(node); - } - } else { - - /* Can't wrap a static function. Oh well. */ - if (is_static) return 0; - emit_extern_func(node,f_header); - - if (Native) { - lang->nativefunction(node); - } else { - lang->function(node); - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_variable() - * - * Wrap a variable. - * ----------------------------------------------------------------------------- */ - -int swig11_variable(DOH *node, void *clientdata) { - int is_static; - SwigType *type; - - if (WrapExtern) return 0; - if (Access != PUBLIC) return 0; - - if (Native) { - Printf(stderr,"%s:%d. Can't wrap variables in %%native mode (ignored).\n", Getfile(node),Getline(node)); - return 0; - } - - type = Gettype(node); - - is_static = check_static(node); - set_scriptname(node); - - if (current_class) { - /* Inside a class definition */ - if (is_static) { - lang->cpp_staticvariable(node); - } else { - lang->cpp_variable(node); - } - } else { - if (check_extern(node)) { - Printf(f_header,"extern %s;\n", SwigType_str(type, Getname(node))); - } - if (is_static) return 0; - - if (SwigType_isconst(type)) { - swig11_constant(node,clientdata); - } else { - lang->variable(node); - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_typedef() - * - * Handle a typedef declaration. - * ----------------------------------------------------------------------------- */ - -int swig11_typedef(DOH *node, void *clientdata) { - String *name; - SwigType *type; - - type = Gettype(node); - name = Getname(node); - SwigType_typedef(type,name); - - if (current_class) { - class_addtype(name,0); - } - lang->add_typedef(type, Char(name)); - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_enum() - * - * Support for enumerations. - * ----------------------------------------------------------------------------- */ - -int swig11_enum(DOH *node, void *clientdata) { - DOH *c; - String *name; - if (WrapExtern) return 0; - if (Access != PUBLIC) return 0; - - name = Getname(node); - if (name && CPlusPlus) { - /* Add a typedef */ - String *t = NewStringf("enum %s", name); - SwigType_typedef(t,name); - class_addtype(name,0); - Delete(t); - } - c = Getchild(node); - Swig_emit_all(c,clientdata); - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_enumvalue() - * - * Create a constant corresponding to an enum value. - * ----------------------------------------------------------------------------- */ -int swig11_enumvalue(DOH *node, void *clientdata) { - set_scriptname(node); - Setattr(node,"type","int"); /* Enums wrapped as ints */ - if (!Getvalue(node)) { /* If no value, use the name itself */ - if (class_name) { - Setvalue(node,NewStringf("%s::%s",class_name, Getname(node))); - } else { - Setvalue(node,Getname(node)); - } - } - if (current_class) { - lang->cpp_constant(node); - } else { - swig11_constant(node,clientdata); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_class() - * - * Wrapping of C++ classes - * ----------------------------------------------------------------------------- */ - -int swig11_class(DOH *node, void *clientdata) { - DOH *c; - List *bases; - - /* Save the class */ - String *name = Getname(node); - Setattr(class_hash,name,node); - if (WrapExtern) return 0; - - if (Native) { - Printf(stderr,"%s:%d. Can't wrap structures or classes in %%native mode (ignored).\n", Getfile(node),Getline(node)); - return 0; - } - - set_scriptname(node); - class_name = name; - class_types = 0; - - have_destructor = 0; - have_constructor = 0; - - /* Need to merge in data from other scopes. For typemaps, can include scopes - for each base class one after the other. For types, need to merge type information */ - - SwigType_new_scope(); - if (name) { - SwigType_set_scope_name(name); - } - - cplus_walk_inherit(node, inherit_types, 0); - - /* Merge in typemaps */ - cplus_walk_inherit(node, inherit_typemaps, 0); - - /* Create a typemap scope for this class */ - Swig_typemap_new_scope(0); - - cplus_build_symbols(node); - lang->cpp_open_class(node); - current_class = node; - - construct_name = Getname(node); - if (!CPlusPlus) { - String *altname = Getattr(node,"altname"); - if (altname) construct_name = altname; - } - - c = Getchild(node); - Abstract = cplus_check_abstract(c); - - Swig_emit_all(c,clientdata); - - bases = Getattr(node,"bases"); - if (bases) { - String *b; - lang->cpp_inherit(bases); - b = Firstitem(bases); - while (b) { - SwigType_inherit(Getname(current_class),b); - b = Nextitem(bases); - } - } - - /* Check for constructors and destructors */ - - if (CPlusPlus) { - if (!have_constructor && !Abstract) { - DOH *cn = NewHash(); - Setname(cn, Getname(current_class)); - Setattr(cn,"scriptname", Getname(current_class)); - lang->cpp_constructor(cn); - } - if (!have_destructor) { - DOH *dn = NewHash(); - Setname(dn, Getname(current_class)); - Setattr(dn,"scriptname", Getname(current_class)); - lang->cpp_destructor(dn); - } - } - - lang->cpp_close_class(); - - /* Pop the type scope and save with the class */ - - Hash *scp = SwigType_pop_scope(); - Setattr(node,"types",scp); - - scp = Swig_typemap_pop_scope(); - Setattr(node,"typemaps",scp); - Setattr(node,"classtypes",class_types); - - /* Pop off all of the typemap scopes we added */ - cplus_walk_inherit(node,inherit_typemaps, (void *) 1); - - current_class = 0; - construct_name = 0; - class_name = 0; - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_classdecl() - * - * Empty class declaration. Used to register classes with language modules. - * ----------------------------------------------------------------------------- */ - -int swig11_classdecl(DOH *node, void *clientdata) { - if (WrapExtern) return 0; - set_scriptname(node); - - lang->cpp_class_decl(node); - return 0; -} - -int swig11_addmethods(DOH *node, void *clientdata) { - DOH *c; - int oldaddmethods = AddMethods; - if (WrapExtern) return 0; - if (!current_class) { - Printf(stderr,"%s:%d. %%addmethods ignored (does not appear inside a class).\n", Getfile(node),Getline(node)); - return 0; - } - AddMethods = 1; - c = Getchild(node); - Swig_emit_all(c,clientdata); - AddMethods = oldaddmethods;; - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_destructor() - * - * C++ Destructor - * ----------------------------------------------------------------------------- */ - -int swig11_destructor(DOH *node, void *clientdata) { - if (WrapExtern) return 0; - if (Access != PUBLIC) return 0; - if (!current_class) return 0; - - set_scriptname(node); - lang->cpp_destructor(node); - have_destructor = 1; - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_access() - * - * Handle an access specifier (public, private, protected) - * ----------------------------------------------------------------------------- */ - -int swig11_access(DOH *node, void *clientdata) { - String *name = Getname(node); - if (Cmp(name,"public") == 0) Access = PUBLIC; - else if (Cmp(name,"private") == 0) Access = PRIVATE; - else if (Cmp(name,"protected") == 0) Access = PROTECTED; - return 0; -} - -/* ----------------------------------------------------------------------------- - * swig11_types() - * - * Handle the types directive. - * ----------------------------------------------------------------------------- */ - -int swig11_types(DOH *node, void *clientdata) { - Parm *p; - p = Getparms(node); - while (p) { - SwigType *t = Gettype(p); - SwigType_remember(t); - p = Getnext(p); - } - return 0; -} - -static SwigRule rules[] = { - { "file", swig11_file}, - { "scope", swig11_scope}, - { "insert", swig11_insert}, - { "pragma", swig11_pragma}, - { "typemap", swig11_typemap}, - { "apply", swig11_apply}, - { "exception", swig11_exception}, - { "clear", swig11_clear}, - { "addmethods", swig11_addmethods}, - { "constant", swig11_constant}, - { "function", swig11_function}, - { "variable", swig11_variable}, - { "typedef", swig11_typedef}, - { "enum", swig11_enum}, - { "enumvalue", swig11_enumvalue}, - { "class", swig11_class}, - { "classdecl", swig11_classdecl}, - { "destructor", swig11_destructor}, - { "access", swig11_access}, - { "types", swig11_types}, - { "module", swig11_nil}, - { "*", swig11_unknown}, - { 0 } -}; - -} - -/* ----------------------------------------------------------------------------- - * generate() - * - * Called by the SWIG1.1 system to emit code - * ----------------------------------------------------------------------------- */ - -void generate(DOH *node) { - DOH *c; - extern String *swig_module; - - /* Initialize globals */ - class_hash = NewHash(); - - Swig_add_rules(rules); - c = Getattr(node,"child"); - - /* Find the module name */ - if (!swig_module) { - swig_module = find_module(c); - } - if (!swig_module) { - Printf(stderr,"SWIG: No module name specified! Please use %%module or -module.\n"); - Swig_exit(EXIT_FAILURE); - } - - lang->initialize(swig_module); - Swig_emit_all(c,0); - lang->close(); - - /* Swig_dump_tags(node,0); */ - -} - - diff --git a/Source/Modules1.1/guile.cxx b/Source/Modules1.1/guile.cxx index 18d59f5b8..a6b53b536 100644 --- a/Source/Modules1.1/guile.cxx +++ b/Source/Modules1.1/guile.cxx @@ -13,7 +13,7 @@ * can be used and distributed. *****************************************************************************/ -static char cvsroot[] = "$Header$"; +char cvsroot_guile_cxx[] = "$Header$"; /*********************************************************************** * $Header$ @@ -23,895 +23,1186 @@ static char cvsroot[] = "$Header$"; * Definitions for adding functions to Guile ***********************************************************************/ -#include "swig11.h" -#include "guile.h" +#include "swigmod.h" -static char *guile_usage = (char*)"\ +#ifndef MACSWIG +#include "swigconfig.h" +#endif +#include + +static const char *guile_usage = (char*)"\ Guile Options (available with -guile)\n\ - -module name - Set base name of module\n\ + -ldflags - Print runtime libraries to link with\n\ -prefix name - Use NAME as prefix [default \"gswig_\"]\n\ -package name - Set the path of the module [default NULL]\n\ - -Linkage lstyle - Use linkage protocol LSTYLE [default `ltdlmod']\n\ - -procdoc file - Output procedure documentation to file\n\ + -emit-setters - Emit procedures-with-setters for variables\n\ + and structure slots.\n\ + -linkage lstyle - Use linkage protocol LSTYLE [default `module']\n\ + -procdoc file - Output procedure documentation to FILE\n\ + -procdocformat format - Output procedure documentation in FORMAT;\n\ + one of `guile-1.4', `plain', `texinfo'\n\ + -scmstub file - Output Scheme FILE with module declaration and\n\ + exports; only with `passive' and `simple' linkage\n\ \n\ - The module option does not create a guile module with a separate name\n\ - space. It specifies the name of the initialization function and is\n\ - called a module here so that it is compadible with the rest of SWIG.\n\ -\n\ - When unspecified, the default LSTYLE is `ltdlmod' for libtool ltdl\n\ - modules. Other LSTYLE values are: `hobbit' for hobbit modules.\n\ + When unspecified, the default LSTYLE is `simple'. For native Guile\n\ + module linking (for Guile versions >=1.5.0), use `module'. Other\n\ + LSTYLE values are: `passive' for passive linking (no C-level\n\ + module-handling code), `ltdlmod' for Guile's old dynamic module\n\ + convention (versions <= 1.4), or `hobbit' for hobbit modules.\n\ \n"; -// --------------------------------------------------------------------- -// GUILE () -// --------------------------------------------------------------------- +static File *f_runtime = 0; +static File *f_header = 0; +static File *f_wrappers = 0; +static File *f_init = 0; -GUILE::GUILE () -{ - // Set class vars +static char *prefix = (char *) "gswig_"; +static char *module = 0; +static char *package = 0; +static enum { + GUILE_LSTYLE_SIMPLE, // call `SWIG_init()' + GUILE_LSTYLE_PASSIVE, // passive linking (no module code) + GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1) + GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention + GUILE_LSTYLE_HOBBIT // use (hobbit4d link) +} linkage = GUILE_LSTYLE_SIMPLE; - prefix = (char*)"gswig_"; - module = NULL; - package = NULL; - linkage = GUILE_LSTYLE_SIMPLE; - procdoc = NULL; - emit_setters = 0; - struct_member = 0; -} +static File *procdoc = 0; +static File *scmstub = 0; +static String *scmtext; -// --------------------------------------------------------------------- -// GUILE::parse_args(int argc, char *argv[]) -// -// Parse arguments. -// --------------------------------------------------------------------- +static enum { + GUILE_1_4, + PLAIN, + TEXINFO +} docformat = GUILE_1_4; -void -GUILE::parse_args (int argc, char *argv[]) -{ - int i, orig_len; +static int emit_setters = 0; +static int struct_member = 0; - Swig_swiglib_set("guile"); +static String *beforereturn = 0; +static String *return_nothing_doc = 0; +static String *return_one_doc = 0; +static String *return_multi_doc = 0; + +static String *exported_symbols = 0; + +class GUILE : public Language { +public: + + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ + + virtual void main (int argc, char *argv[]) { + int i, orig_len; + + SWIG_library_directory("guile"); + SWIG_typemap_lang("guile"); // Look for certain command line options - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp (argv[i], "-help") == 0) { - fputs (guile_usage, stderr); - Swig_exit (EXIT_SUCCESS); - } - else if (strcmp (argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = new char[strlen (argv[i + 1]) + 2]; - strcpy (prefix, argv[i + 1]); - Swig_mark_arg (i); - Swig_mark_arg (i + 1); + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp (argv[i], "-help") == 0) { + fputs (guile_usage, stderr); + SWIG_exit (EXIT_SUCCESS); + } + else if (strcmp (argv[i], "-prefix") == 0) { + if (argv[i + 1]) { + prefix = new char[strlen (argv[i + 1]) + 2]; + strcpy (prefix, argv[i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } + } + else if (strcmp (argv[i], "-package") == 0) { + if (argv[i + 1]) { + package = new char[strlen (argv[i + 1]) + 2]; + strcpy (package, argv [i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } + } + else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_GUILE_RUNTIME); + SWIG_exit (EXIT_SUCCESS); + } + else if (strcmp (argv[i], "-Linkage") == 0 + || strcmp (argv[i], "-linkage") == 0) { + if (argv[i + 1]) { + if (0 == strcmp (argv[i + 1], "ltdlmod")) + linkage = GUILE_LSTYLE_LTDLMOD_1_4; + else if (0 == strcmp (argv[i + 1], "hobbit")) + linkage = GUILE_LSTYLE_HOBBIT; + else if (0 == strcmp (argv[i + 1], "simple")) + linkage = GUILE_LSTYLE_SIMPLE; + else if (0 == strcmp (argv[i + 1], "passive")) + linkage = GUILE_LSTYLE_PASSIVE; + else if (0 == strcmp (argv[i + 1], "module")) + linkage = GUILE_LSTYLE_MODULE; + else + Swig_arg_error (); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } + } + else if (strcmp (argv[i], "-procdoc") == 0) { + if (argv[i + 1]) { + procdoc = NewFile(argv[i + 1], (char *) "w"); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } + } + else if (strcmp (argv[i], "-procdocformat") == 0) { + if (strcmp(argv[i+1], "guile-1.4") == 0) + docformat = GUILE_1_4; + else if (strcmp(argv[i+1], "plain") == 0) + docformat = PLAIN; + else if (strcmp(argv[i+1], "texinfo") == 0) + docformat = TEXINFO; + else Swig_arg_error(); + Swig_mark_arg(i); + Swig_mark_arg(i+1); i++; - } else { - Swig_arg_error(); + } + else if (strcmp (argv[i], "-emit-setters") == 0) { + emit_setters = 1; + Swig_mark_arg (i); + } + else if (strcmp (argv[i], "-scmstub") == 0) { + if (argv[i + 1]) { + scmstub = NewFile(argv[i + 1], (char *) "w"); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } } } - else if (strcmp (argv[i], "-package") == 0) { - if (argv[i + 1]) { - package = new char[strlen (argv[i + 1]) + 2]; - strcpy (package, argv [i + 1]); - Swig_mark_arg (i); - Swig_mark_arg (i + 1); - i++; - } else { - Swig_arg_error(); - } - } - /* Bogus upcase requirement due to top-level parsing not respecting - language specification. Top-level should stop when it sees "-guile" - or other languages. */ - else if (strcmp (argv[i], "-Linkage") == 0) { - if (argv[i + 1]) { - if (0 == strcmp (argv[i + 1], "ltdlmod")) - linkage = GUILE_LSTYLE_LTDLMOD; - else if (0 == strcmp (argv[i + 1], "hobbit")) - linkage = GUILE_LSTYLE_HOBBIT; - else - Swig_arg_error (); - Swig_mark_arg (i); - Swig_mark_arg (i + 1); - i++; - } else { - Swig_arg_error(); - } - } - else if (strcmp (argv[i], "-procdoc") == 0) { - if (argv[i + 1]) { - procdoc = NewFile(argv[i + 1], "w"); - Swig_mark_arg (i); - Swig_mark_arg (i + 1); - i++; - } else { - Swig_arg_error(); - } - } - else if (strcmp (argv[i], "-emit-setters") == 0) { - emit_setters = 1; - Swig_mark_arg (i); - } } - } - // Make sure `prefix' ends in an underscore + // Make sure `prefix' ends in an underscore - orig_len = strlen (prefix); - if (prefix[orig_len - 1] != '_') { - prefix[1 + orig_len] = 0; - prefix[orig_len] = '_'; - } - - /* Add a symbol for this module */ - Preprocessor_define ((void *) "SWIGGUILE",0); - - /* Read in default typemaps */ - Swig_set_config_file("guile.i"); -} - -// -------------------------------------------------------------------- -// GUILE::initialize() -// -// Output initialization code that registers functions with the -// interface. -// --------------------------------------------------------------------- - -void -GUILE::initialize (String *modname) -{ - printf ("Generating wrappers for Guile\n"); - - Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); - Swig_banner (f_runtime); - - Printf (f_runtime, "/* Implementation : GUILE */\n\n"); - - // Write out directives and declarations - - if (NoInclude) { - Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); - } - - if (!module) { - module = new char[Len(modname)+1]; - strcpy(module, Char(modname)); - } - - switch (linkage) { - case GUILE_LSTYLE_SIMPLE: - /* Simple linkage; we have to export the SWIG_init function. The user can - rename the function by a #define. */ - Printf (f_runtime, "extern void\nSWIG_init (void)\n;\n"); - Printf (f_init, "extern void\nSWIG_init (void)\n{\n"); - break; - default: - /* Other linkage; we make the SWIG_init function static */ - Printf (f_runtime, "static void\nSWIG_init (void)\n;\n"); - Printf (f_init, "static void\nSWIG_init (void)\n{\n"); - break; - } - Printf (f_init, "\tSWIG_Guile_Init();\n"); -} - -void -GUILE::emit_linkage (char *module_name) -{ - DOHString *module_func = NewString(""); - - Printv(module_func,module_name,0); - Replace(module_func,"-", "_", DOH_REPLACE_ANY); - - switch (linkage) { - case GUILE_LSTYLE_SIMPLE: - Printf (f_init, "\n/* Linkage: simple */\n"); - break; - case GUILE_LSTYLE_LTDLMOD: - Printf (f_init, "\n/* Linkage: ltdlmod */\n"); - Replace(module_func,"/", "_", DOH_REPLACE_ANY); - Insert(module_func,0, "scm_init_"); - Append(module_func,"_module"); - Printf (f_init, "SCM\n%s (void)\n{\n", module_func); - { - DOHString *mod = NewString(module_name); - Replace(mod,"/", " ", DOH_REPLACE_ANY); - Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", - mod); - Printf (f_init, " return SCM_UNSPECIFIED;\n"); - Delete(mod); + orig_len = strlen (prefix); + if (prefix[orig_len - 1] != '_') { + prefix[1 + orig_len] = 0; + prefix[orig_len] = '_'; } - Printf (f_init, "}\n"); - break; - case GUILE_LSTYLE_HOBBIT: - Printf (f_init, "\n/* Linkage: hobbit */\n"); - Replace(module_func,"/", "_slash_", DOH_REPLACE_ANY); - Insert(module_func,0, "scm_init_"); - Printf (f_init, "SCM\n%s (void)\n{\n", module_func); - { - DOHString *mod = NewString(module_name); - Replace(mod,"/", " ", DOH_REPLACE_ANY); - Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", - mod); - Printf (f_init, " return SCM_UNSPECIFIED;\n"); - Delete(mod); + + /* Add a symbol for this module */ + Preprocessor_define ("SWIGGUILE 1",0); + /* Read in default typemaps */ + SWIG_config_file("guile.i"); + allow_overloading(); + + } + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); + + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); } - Printf (f_init, "}\n"); - break; - default: - abort(); // for now - } - Delete(module_func); -} - -// --------------------------------------------------------------------- -// GUILE::close(void) -// -// Wrap things up. Close initialization function. -// --------------------------------------------------------------------- - -void -GUILE::close (void) -{ - SwigType_emit_type_table (f_runtime, f_wrappers); - - Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types);\n"); - Printf (f_init, "}\n\n"); - char module_name[256]; - - if (!module) - sprintf(module_name, "swig"); - else { - if (package) - sprintf(module_name,"%s/%s", package,module); - else - strcpy(module_name,module); - } - emit_linkage (module_name); - - if (procdoc) { - Delete(procdoc); - procdoc = NULL; - } -} - -// ---------------------------------------------------------------------- -// get_pointer() -// -// Emits code to get a pointer from a parameter and do type checking. -// parm is the parameter number. This function is only used -// in create_function(). -// ---------------------------------------------------------------------- - -static void -get_pointer (char *iname, int parm, SwigType *t, - Wrapper *f, DOHString_or_char *proc_name, - int num_scheme_parm) -{ - SwigType_remember(t); - /* Pointers are smobs */ - Printf(f, " if (SWIG_Guile_GetPtr(s_%d,(void **) &arg%d", parm, parm); - if (SwigType_type(t) == T_VOID) - Printf(f, ", NULL)) {\n"); - else - Printv(f, ", SWIGTYPE", SwigType_manglestr(t), ")) {\n", 0); - /* Raise exception */ - Printv(f, - tab8, - "scm_wrong_type_arg(\"",proc_name, "\", ", - 0); - Printf(f,"%d, s_%d);\n", num_scheme_parm, parm); - Printv(f, tab4, "}\n", 0); -} - -/* Return true iff T is a pointer type */ - -static int -is_a_pointer (SwigType *t) -{ - return SwigType_ispointer(SwigType_typedef_resolve_all(t)); -} - -/* Same as Swig_typemap_lookup but fall back to `int' when `enum' is - requested -- enum handling is somewhat broken in the 1.1 parser. - But we don't want to change it now since it is deprecated. */ - -static char * -guile_typemap_lookup(const char *op, SwigType *type, const String_or_char *pname, String_or_char *source, - String_or_char *target, Wrapper *f) -{ - char *tm; - tm = Swig_typemap_lookup((char*) op, type, (char*)pname, source, target, f); - if (!tm) { - SwigType *base = SwigType_typedef_resolve_all(type); - if (strncmp(Char(base), "enum ", 5)==0) - tm = Swig_typemap_lookup((char*) op, (char*) "int", (char*)pname, source, target, f); - } - return tm; -} - -/* Lookup a typemap, replace all relevant parameters and write it to - the given generalized file. Return 0 if no typemap found. */ - -static int -guile_do_typemap(DOHFile *file, const char *op, - SwigType *type, const String_or_char *arg, - String_or_char *source, String_or_char *target, - int argnum, DOHString *name, Wrapper *f, - int nonewline_p) -{ - char *tm; - if ((tm = guile_typemap_lookup(op, type, arg, - source, target, f))) { - String *s = NewString(tm); - char argnum_s[10]; - sprintf(argnum_s, "%d", argnum); - Replace(s,"$argnum", argnum_s, DOH_REPLACE_ANY); - Replace(s,"$arg", arg, DOH_REPLACE_ANY); - Replace(s,"$name", name, DOH_REPLACE_ANY); - if (nonewline_p) - Printv(file, s, 0); - else Printv(file, s, "\n", 0); - Delete(s); - return 1; - } - else return 0; -} - -/* Lookup a documentation typemap, replace all relevant parameters and - write it to the given generalized file, providing a sensible - default value. */ - -static void -guile_do_doc_typemap(DOHFile *file, const char *op, - SwigType *type, const String_or_char *arg, - int argnum, DOHString *name, Wrapper *f) -{ - if (!guile_do_typemap(file, op, type, arg, - NULL, NULL, argnum, name, f, 1)) { - /* FIXME: Can't we provide this default via a typemap as well? */ - String *s = NewString(SwigType_str(type, 0)); - Chop(s); - if (arg) Printf(file, "(%s <%s>)", arg, s); - else Printf(file, "<%s>", s); - Delete(s); - } -} - -/* Report an error handling the given type. */ - -static void -throw_unhandled_guile_type_error (SwigType *d) -{ - Printf (stderr, "%s:%d. Unable to handle type %s.\n",Getfile(d), Getline(d), SwigType_str(d,0)); -} - -// ---------------------------------------------------------------------- -// GUILE::create_function() -// Create a function declaration and register it with the interpreter. -// ---------------------------------------------------------------------- - -void -GUILE::function (DOH *node) { - char *name, *iname; - SwigType *d; - ParmList *l; - Parm *p; - DOHString *proc_name = 0; - char source[256], target[256]; - Wrapper *f = NewWrapper();; - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *signature = NewString(""); - String *returns = NewString(""); - int returns_list = 0; - String *tmp = NewString(""); - int i; - int numargs = 0; - int numopt = 0; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - d = Getattr(node,"type"); - l = Getattr(node,"parms"); - - // Make a wrapper name for this - char * wname = new char [strlen (prefix) + strlen (iname) + 2]; - sprintf (wname, "%s%s", prefix, iname); - - // Build the name for scheme. - proc_name = NewString(iname); - Replace(proc_name,"_", "-", DOH_REPLACE_ANY); - - /* Emit locals etc. into f; figure out which args to ignore */ - emit_args (node, f); - - /* Declare return variable */ - - Wrapper_add_local (f,"gswig_result", "SCM gswig_result"); - - if (procdoc) - guile_do_doc_typemap(returns, "outdoc", d, NULL, - 0, proc_name, f); - - /* Open prototype and signature */ - - /* The function prototype must be produced first */ - - Printv(f, "static SCM\n", wname," (", 0); - for (p = l, i = 0; p; p = Getnext(p), i++) { - if (i != 0) Printf(f,", "); - Printf(f,"SCM s_%d", i); - } - Printf(f,")\n{\n"); - - /* Define the scheme name in C. This define is used by several Guile - macros. */ - - Printv(f,"#define FUNC_NAME \"", proc_name, "\"\n", 0); - - Printv(signature, "(", proc_name, 0); - /* Now write code to extract the parameters */ - - for (p = l, i = 0; p; p=Getnext(p), i++) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - int opt_p = (Getvalue(p) - || Swig_typemap_search((char*)"default",pt,pn)); - - // Produce names of source and target - sprintf(source,"s_%d",i); - sprintf(target,"%s", Char(Getlname(p))); - - // Handle parameter types. - - if (Getignore(p)) - Printv(f, "/* ", pn, " ignored... */\n", 0); + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",f_init); + + scmtext = NewString(""); + Swig_register_filebyname("scheme", scmtext); + exported_symbols = NewString(""); + + Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); + Swig_banner (f_runtime); + + Printf (f_runtime, "/* Implementation : GUILE */\n\n"); + + /* Write out directives and declarations */ + + if (NoInclude) { + Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); + } + + module = Swig_copy_string(Char(Getattr(n,"name"))); + + if (CPlusPlus) { + Printf(f_runtime, "extern \"C\" {\n\n"); + } + + switch (linkage) { + case GUILE_LSTYLE_SIMPLE: + /* Simple linkage; we have to export the SWIG_init function. The user can + rename the function by a #define. */ + Printf (f_runtime, "extern void\nSWIG_init (void)\n;\n"); + Printf (f_init, "extern void\nSWIG_init (void)\n{\n"); + break; + default: + /* Other linkage; we make the SWIG_init function static */ + Printf (f_runtime, "static void\nSWIG_init (void)\n;\n"); + Printf (f_init, "static void\nSWIG_init (void)\n{\n"); + break; + } + Printf (f_init, "\tSWIG_Guile_Init();\n"); + if (CPlusPlus) { + Printf(f_runtime, "\n}\n"); + } + + Language::top(n); + + /* Close module */ + + Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); + + SwigType_emit_type_table (f_runtime, f_wrappers); + + Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n"); + + Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types, swig_types_initial);\n"); + Printf (f_init, "}\n\n"); + char module_name[256]; + + if (!module) + sprintf(module_name, "swig"); else { + if (package) + sprintf(module_name,"%s/%s", package,module); + else + strcpy(module_name,module); + } + emit_linkage (module_name); + + if (procdoc) { + Delete(procdoc); + procdoc = NULL; + } + if (scmstub) { + Delete(scmstub); + scmstub = NULL; + } + + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + return SWIG_OK; + } + + void emit_linkage (char *module_name) { + String *module_func = NewString(""); + + if (CPlusPlus) { + Printf(f_init, "extern \"C\" {\n\n"); + } + + Printv(module_func,module_name,NIL); + Replaceall(module_func,"-", "_"); + + switch (linkage) { + case GUILE_LSTYLE_SIMPLE: + Printf (f_init, "\n/* Linkage: simple */\n"); + break; + case GUILE_LSTYLE_PASSIVE: + Printf (f_init, "\n/* Linkage: passive */\n"); + Replaceall(module_func,"/", "_"); + Insert(module_func,0, "scm_init_"); + Append(module_func,"_module"); + + Printf (f_init, "SCM\n%s (void)\n{\n", module_func); + Printf (f_init, " SWIG_init();\n"); + Printf (f_init, " return SCM_UNSPECIFIED;\n"); + Printf (f_init, "}\n"); + break; + case GUILE_LSTYLE_LTDLMOD_1_4: + Printf (f_init, "\n/* Linkage: ltdlmod */\n"); + Replaceall(module_func,"/", "_"); + Insert(module_func,0, "scm_init_"); + Append(module_func,"_module"); + Printf (f_init, "SCM\n%s (void)\n{\n", module_func); + { + String *mod = NewString(module_name); + Replaceall(mod,"/", " "); + Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", + mod); + Printf (f_init, " return SCM_UNSPECIFIED;\n"); + Delete(mod); + } + Printf (f_init, "}\n"); + break; + case GUILE_LSTYLE_MODULE: + Printf (f_init, "\n/* Linkage: module */\n"); + Replaceall(module_func,"/", "_"); + Insert(module_func,0, "scm_init_"); + Append(module_func,"_module"); + + Printf (f_init, "static void SWIG_init_helper(void *data)\n"); + Printf (f_init, "{\n SWIG_init();\n"); + if (Len(exported_symbols) > 0) + Printf (f_init, " scm_c_export(%sNULL);", + exported_symbols); + Printf (f_init, "\n}\n\n"); + + Printf (f_init, "SCM\n%s (void)\n{\n", module_func); + { + String *mod = NewString(module_name); + Replaceall(mod,"/", " "); + Printf(f_init, " SCM module = scm_c_define_module(\"%s\",\n", mod); + Printf(f_init, " SWIG_init_helper, NULL);\n"); + Printf(f_init, " return SCM_UNSPECIFIED;\n"); + Delete(mod); + } + Printf (f_init, "}\n"); + break; + case GUILE_LSTYLE_HOBBIT: + Printf (f_init, "\n/* Linkage: hobbit */\n"); + Replaceall(module_func,"/", "_slash_"); + Insert(module_func,0, "scm_init_"); + Printf (f_init, "SCM\n%s (void)\n{\n", module_func); + { + String *mod = NewString(module_name); + Replaceall(mod,"/", " "); + Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", + mod); + Printf (f_init, " return SCM_UNSPECIFIED;\n"); + Delete(mod); + } + Printf (f_init, "}\n"); + break; + default: + abort(); // for now + } + + if (scmstub) { + /* Emit Scheme stub if requested */ + String *mod = NewString(module_name); + Replaceall(mod, "/", " "); + Printf (scmstub, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n"); + Printf (scmstub, ";;; Automatically generated by SWIG; do not edit.\n\n"); + if (linkage == GUILE_LSTYLE_SIMPLE + || linkage == GUILE_LSTYLE_PASSIVE) + Printf (scmstub, "(define-module (%s))\n\n", mod); + Delete(mod); + Printf (scmstub, "%s", scmtext); + if ((linkage == GUILE_LSTYLE_SIMPLE + || linkage == GUILE_LSTYLE_PASSIVE) + && Len(exported_symbols) > 0) { + String *ex = NewString(exported_symbols); + Replaceall(ex, ", ", "\n "); + Replaceall(ex, "\"", ""); + Chop(ex); + Printf(scmstub, "\n(export %s)\n", ex); + Delete(ex); + } + } + + Delete(module_func); + if (CPlusPlus) { + Printf(f_init, "\n}\n"); + } + } + + /* Return true iff T is a pointer type */ + + int is_a_pointer (SwigType *t) { + return SwigType_ispointer(SwigType_typedef_resolve_all(t)); + } + + /* Report an error handling the given type. */ + + void throw_unhandled_guile_type_error (SwigType *d) { + Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, + "Unable to handle type %s.\n", SwigType_str(d,0)); + } + + /* Write out procedure documentation */ + + void write_doc(const String *proc_name, + const String *signature, + const String *doc, + const String *signature2 = NULL) { + switch (docformat) { + case GUILE_1_4: + Printv(procdoc, "\f\n", NIL); + Printv(procdoc, "(", signature, ")\n", NIL); + if (signature2) + Printv(procdoc, "(", signature2, ")\n", NIL); + Printv(procdoc, doc, "\n", NIL); + break; + case PLAIN: + Printv(procdoc, "\f", proc_name, "\n\n", NIL); + Printv(procdoc, "(", signature, ")\n", NIL); + if (signature2) + Printv(procdoc, "(", signature2, ")\n", NIL); + Printv(procdoc, doc, "\n\n", NIL); + break; + case TEXINFO: + Printv(procdoc, "\f", proc_name, "\n", NIL); + Printv(procdoc, "@deffn primitive ", signature, "\n", NIL); + if (signature2) + Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL); + Printv(procdoc, doc, "\n", NIL); + Printv(procdoc, "@end deffn\n\n", NIL); + break; + } + } + + /* returns false if the typemap is an empty string */ + bool handle_documentation_typemap(String *output, + const String *maybe_delimiter, + Parm *p, + const String *typemap, + const String *default_doc) + { + String *tmp = NewString(""); + String *tm; + if (!(tm = Getattr(p, typemap))) { + Printf(tmp, "%s", default_doc); + tm = tmp; + } + bool result = (Len(tm) > 0); + if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) { + Printv(output, maybe_delimiter, NIL); + } + String *pn = Getattr(p,"name"); + String *pt = Getattr(p,"type"); + Replaceall(tm, "$name", pn); // legacy for $parmname + Replaceall(tm, "$type", SwigType_str(pt,0)); + /* $NAME is like $name, but marked-up as a variable. */ + String *ARGNAME = NewString(""); + if (docformat == TEXINFO) + Printf(ARGNAME, "@var{%s}", pn); + else Printf(ARGNAME, "%(upper)s", pn); + Replaceall(tm, "$NAME", ARGNAME); + Replaceall(tm, "$PARMNAME", ARGNAME); + Printv(output,tm,NIL); + Delete(tmp); + return result; + } + + /* ------------------------------------------------------------ + * functionWrapper() + * Create a function declaration and register it with the interpreter. + * ------------------------------------------------------------ */ + + virtual int functionWrapper(Node *n) { + String *iname = Getattr(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + Parm *p; + String *proc_name = 0; + char source[256], target[256]; + Wrapper *f = NewWrapper();; + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *signature = NewString(""); + String *doc_body = NewString(""); + String *returns = NewString(""); + int num_results = 1; + String *tmp = NewString(""); + String *tm; + int i; + int numargs = 0; + int numreq = 0; + String *overname = 0; + int args_passed_as_array = 0; + + // Make a wrapper name for this + String *wname = Swig_name_wrapper(iname); + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); + args_passed_as_array = 1; + } else { + if (!addSymbol(iname,n)) return SWIG_ERROR; + } + if (overname) { + Append(wname, overname); + } + Setattr(n,"wrap:name",wname); + + // Build the name for scheme. + proc_name = NewString(iname); + Replaceall(proc_name,"_", "-"); + + /* Emit locals etc. into f->code; figure out which args to ignore */ + emit_args (d, l, f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + + /* Get number of required and total arguments */ + numargs = emit_num_arguments(l); + numreq = emit_num_required(l); + + /* Declare return variable */ + + Wrapper_add_local (f,"gswig_result", "SCM gswig_result"); + Wrapper_add_local (f,"gswig_list_p", "int gswig_list_p = 0"); + + /* Get the output typemap so we can start generating documentation. Don't + worry, the returned string is saved as 'tmap:out' */ + + Swig_typemap_lookup_new("out",n,"result",0); + + if ((tm = Getattr(n,"tmap:out:doc"))) { + Printv(returns,tm,NIL); + if (Len(tm) > 0) num_results = 1; + else num_results = 0; + } else { + String *s = SwigType_str(d,0); + Chop(s); + Printf(returns,"<%s>",s); + Delete(s); + num_results = 1; + } + + /* Open prototype and signature */ + + Printv(f->def, "static SCM\n", wname," (", NIL); + if (args_passed_as_array) { + Printv(f->def, "int argc, SCM *argv", NIL); + } + Printv(signature, proc_name, NIL); + + /* Now write code to extract the parameters */ + + for (i = 0, p = l; i < numargs; i++) { + + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + int opt_p = (i >= numreq); + + // Produce names of source and target + if (args_passed_as_array) + sprintf(source, "argv[%d]", i); + else + sprintf(source,"s_%d",i); + sprintf(target,"%s", Char(ln)); + + if (!args_passed_as_array) { + if (i!=0) Printf(f->def,", "); + Printf(f->def,"SCM s_%d", i); + } if (opt_p) { - numopt++; - Printf(f," if (s_%d != GH_NOT_PASSED) {\n", i); + Printf(f->code," if (%s != GH_NOT_PASSED) {\n", source); } - ++numargs; - if (guile_do_typemap(f, "in", pt, pn, - source, target, numargs, proc_name, f, 0)) { - /* nothing to do */ - } - else if (is_a_pointer(pt)) { - get_pointer (iname, i, pt, f, proc_name, numargs); - } - else { - throw_unhandled_guile_type_error (pt); - } - if (procdoc) { - /* Add to signature */ - Printf(signature, " "); - guile_do_doc_typemap(signature, "indoc", pt, pn, - numargs, proc_name, f); + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$source",source); + Replaceall(tm,"$target",target); + Replaceall(tm,"$input",source); + Setattr(p,"emit:input", source); + Printv(f->code,tm,"\n",NIL); + + if (procdoc) { + /* Add to signature (arglist) */ + handle_documentation_typemap(signature, " ", p, "tmap:in:arglist", + "$name"); + /* Document the type of the arg in the documentation body */ + handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc", + "$NAME is of type <$type>"); + } + p = Getattr(p,"tmap:in:next"); + } else { + throw_unhandled_guile_type_error (pt); + p = nextSibling(p); } if (opt_p) - Printf(f," }\n"); + Printf(f->code," }\n"); + } + if (Len(doc_body) > 0) + Printf(doc_body, ".\n"); + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } } - - /* Check if there are any constraints. */ - - guile_do_typemap(f, "check", pt, pn, - source, target, numargs, proc_name, f, 0); - /* Pass output arguments back to the caller. */ - - guile_do_typemap(outarg, "argout", pt, pn, - source, target, numargs, proc_name, f, 0); - - if (procdoc) { - /* Document output arguments */ - Clear(tmp); - if (guile_do_typemap(tmp, "argoutdoc", pt, pn, - source, target, numargs, proc_name, f, 1)) { - if (Len(returns) == 0) { /* unspecified -> singleton */ - Printv(returns, tmp, 0); - } - else { /* append to list */ - Printv(returns, " ", tmp, 0); - returns_list = 1; + + /* Insert argument output code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$target",Getattr(p,"lname")); + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + if (procdoc) { + if (handle_documentation_typemap(returns, ", ", + p, "tmap:argout:doc", + "$NAME (of type $type)")) { + /* A documentation typemap that is not the empty string + indicates that a value is returned to Scheme. */ + num_results++; + } } + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); } } - - // free up any memory allocated for the arguments. - - guile_do_typemap(cleanup, "freearg", pt, pn, - source, target, numargs, proc_name, f, 0); - } - - /* Close prototype and signature */ - - Printv(signature, ")\n", 0); - - - // Now write code to make the function call - Printv(f, tab4, "gh_defer_ints();\n", 0); - emit_func_call (node, f); - Printv(f, tab4, "gh_allow_ints();\n", 0); - - // Now have return value, figure out what to do with it. - - if (guile_do_typemap(f, "out", d, name, - (char*)"result", (char*)"gswig_result", - 0, proc_name, f, 0)) { - /* nothing */ - } - else if (is_a_pointer(d)) { - SwigType_remember(d); - Printv(f, tab4, - "gswig_result = SWIG_Guile_MakePtr (", - "result, ", - "SWIGTYPE", SwigType_manglestr(d), - ");\n", - 0); - } - else { - throw_unhandled_guile_type_error (d); - } - - // Dump the argument output code - Printv(f,outarg,0); - - // Dump the argument cleanup code - Printv(f,cleanup,0); - - // Look for any remaining cleanup - - if (NewObject) { - guile_do_typemap(f, "newfree", d, iname, - (char*)"result", (char*)"", 0, proc_name, f, 0); - } - - // Free any memory allocated by the function being wrapped.. - - guile_do_typemap(f, "ret", d, name, - (char*)"result", (char*)"", 0, proc_name, f, 0); - - // Wrap things up (in a manner of speaking) - - Printv(f, "return gswig_result;\n", 0); - - // Undefine the scheme name - - Printf(f, "#undef FUNC_NAME\n"); - Printf(f, "}\n"); - - Printf(f_wrappers,"%s", f); - - if (numargs > 10) { - int i; - /* gh_new_procedure would complain: too many args */ - /* Build a wrapper wrapper */ - Printv(f_wrappers, "static SCM\n", wname,"_rest (SCM rest)\n", 0); - Printv(f_wrappers, "{\n", 0); - Printf(f_wrappers, "SCM arg[%d];\n", numargs); - Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n", - numargs-numopt, numopt, proc_name); - Printv(f_wrappers, "return ", wname, "(", 0); - Printv(f_wrappers, "arg[0]", 0); - for (i = 1; i3) { - int len = Len(proc_name); - const char *pc = Char(proc_name); - /* MEMBER-set and MEMBER-get functions. */ - int is_setter = (pc[len - 3] == 's'); - if (is_setter) { - Printf(f_init, "SCM setter = "); - struct_member = 2; /* have a setter */ + + /* Insert cleanup code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } } - else Printf(f_init, "SCM getter = "); - Printf (f_init, "gh_new_procedure(\"%s\", %s, %d, %d, 0);\n", - proc_name, wname, numargs-numopt, numopt); - if (!is_setter) { - /* Strip off "-get" */ - char *pws_name = (char*) malloc(sizeof(char) * (len - 3)); - strncpy(pws_name, pc, len - 3); - pws_name[len - 4] = 0; - if (struct_member==2) { - /* There was a setter, so create a procedure with setter */ - Printf (f_init, "gh_define(\"%s\", " - "scm_make_procedure_with_setter(getter, setter));\n", - pws_name); + + /* Close prototype */ + + Printf(f->def, ")\n{\n"); + + /* Define the scheme name in C. This define is used by several Guile + macros. */ + Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); + + // Now write code to make the function call + Printv(f->code, tab4, "gh_defer_ints();\n", NIL); + emit_action(n,f); + Printv(f->code, tab4, "gh_allow_ints();\n", NIL); + + // Now have return value, figure out what to do with it. + + if ((tm = Getattr(n,"tmap:out"))) { + Replaceall(tm,"$result","gswig_result"); + Replaceall(tm,"$target","gswig_result"); + Replaceall(tm,"$source","result"); + Printv(f->code,tm,"\n",NIL); + } + else { + throw_unhandled_guile_type_error (d); + } + + // Dump the argument output code + Printv(f->code,outarg,NIL); + + // Dump the argument cleanup code + Printv(f->code,cleanup,NIL); + + // Look for any remaining cleanup + + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printv(f->code,tm,"\n",NIL); + } + } + + // Free any memory allocated by the function being wrapped.. + if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printv(f->code,tm,"\n",NIL); + } + + // Wrap things up (in a manner of speaking) + + if (beforereturn) + Printv(f->code, beforereturn, "\n", NIL); + Printv(f->code, "return gswig_result;\n", NIL); + + // Undefine the scheme name + + Printf(f->code, "#undef FUNC_NAME\n"); + Printf(f->code, "}\n"); + + Wrapper_print (f, f_wrappers); + + if (!Getattr(n, "sym:overloaded")) { + if (numargs > 10) { + int i; + /* gh_new_procedure would complain: too many args */ + /* Build a wrapper wrapper */ + Printv(f_wrappers, "static SCM\n", wname,"_rest (SCM rest)\n", NIL); + Printv(f_wrappers, "{\n", NIL); + Printf(f_wrappers, "SCM arg[%d];\n", numargs); + Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n", + numreq, numargs-numreq, proc_name); + Printv(f_wrappers, "return ", wname, "(", NIL); + Printv(f_wrappers, "arg[0]", NIL); + for (i = 1; i3) { + int len = Len(proc_name); + const char *pc = Char(proc_name); + /* MEMBER-set and MEMBER-get functions. */ + int is_setter = (pc[len - 3] == 's'); + if (is_setter) { + Printf(f_init, "SCM setter = "); + struct_member = 2; /* have a setter */ + } + else Printf(f_init, "SCM getter = "); + Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", + proc_name, wname, numreq, numargs-numreq); + if (!is_setter) { + /* Strip off "-get" */ + char *pws_name = (char*) malloc(sizeof(char) * (len - 3)); + strncpy(pws_name, pc, len - 3); + pws_name[len - 4] = 0; + if (struct_member==2) { + /* There was a setter, so create a procedure with setter */ + Printf (f_init, "gh_define(\"%s\", " + "scm_make_procedure_with_setter(getter, setter));\n", + pws_name); + } + else { + /* There was no setter, so make an alias to the getter */ + Printf (f_init, "gh_define(\"%s\", getter);\n", + pws_name); + } + Printf (exported_symbols, "\"%s\", ", pws_name); + free(pws_name); + } + } + else { + /* Register the function */ + Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", + proc_name, wname, numreq, numargs-numreq); + } + } + else { /* overloaded function; don't export the single methods */ + if (!Getattr(n,"sym:nextSibling")) { + /* Emit overloading dispatch function */ + + int maxargs; + String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *df = NewWrapper(); + String *dname = Swig_name_wrapper(iname); + + Printv(df->def, + "static SCM\n", dname, + "(SCM rest)\n{\n", + NIL); + Printf(df->code, "SCM argv[%d];\n", maxargs); + Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n", + 0, maxargs, proc_name); + Printv(df->code,dispatch,"\n",NIL); + Printf(df->code,"scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname); + Printv(df->code,"}\n",NIL); + Wrapper_print(df,f_wrappers); + Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 0, 1);\n", + proc_name, dname); + DelWrapper(df); + Delete(dispatch); + Delete(dname); + } + } + Printf (exported_symbols, "\"%s\", ", proc_name); + if (procdoc) { + String *returns_text = NewString(""); + if (num_results == 0) Printv(returns_text, return_nothing_doc, NIL); + else if (num_results == 1) Printv(returns_text, return_one_doc, NIL); + else Printv(returns_text, return_multi_doc, NIL); + /* Substitute documentation variables */ + static const char *numbers[] = {"zero", "one", "two", "three", + "four", "five", "six", "seven", + "eight", "nine", "ten", "eleven", + "twelve"}; + if (num_results <= 12) + Replaceall(returns_text, "$num_values", numbers[num_results]); + else { + String *num_results_str = NewStringf("%d", num_results); + Replaceall(returns_text, "$num_values", num_results_str); + Delete(num_results_str); + } + Replaceall(returns_text, "$values", returns); + Printf(doc_body, "\n%s", returns_text); + write_doc(proc_name, signature, doc_body); + Delete(returns_text); + } + + Delete(proc_name); + Delete(outarg); + Delete(cleanup); + Delete(signature); + Delete(doc_body); + Delete(returns); + Delete(tmp); + DelWrapper(f); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * variableWrapper() + * + * Create a link to a C variable. + * This creates a single function PREFIX_var_VARNAME(). + * This function takes a single optional argument. If supplied, it means + * we are setting this variable to some value. If omitted, it means we are + * simply evaluating this variable. Either way, we return the variables + * value. + * ------------------------------------------------------------ */ + + virtual int variableWrapper(Node *n) { + + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + + String *proc_name; + char var_name[256]; + Wrapper *f; + String *tm; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + f = NewWrapper(); + // evaluation function names + + strcpy(var_name, Char(Swig_name_wrapper(iname))); + + // Build the name for scheme. + proc_name = NewString(iname); + Replaceall(proc_name,"_", "-"); + + if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) { + + Printf (f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name); + + /* Define the scheme name in C. This define is used by several Guile + macros. */ + Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); + + Wrapper_add_local (f, "gswig_result", "SCM gswig_result"); + + if (!Getattr(n,"feature:immutable")) { + /* Check for a setting of the variable value */ + Printf (f->code, "if (s_0 != GH_NOT_PASSED) {\n"); + if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { + Replaceall(tm,"$source","s_0"); + Replaceall(tm,"$input","s_0"); + Replaceall(tm,"$target",name); + Printv(f->code,tm,"\n",NIL); + } + else { + throw_unhandled_guile_type_error (t); + } + Printf (f->code, "}\n"); + } + + // Now return the value of the variable (regardless + // of evaluating or setting) + + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$source",name); + Replaceall(tm,"$target","gswig_result"); + Replaceall(tm,"$result", "gswig_result"); + Printv(f->code,tm,"\n",NIL); } else { - /* There was no setter, so make an alias to the getter */ - Printf (f_init, "gh_define(\"%s\", getter);\n", - pws_name); + throw_unhandled_guile_type_error (t); } - free(pws_name); - } - } - else { - /* Register the function */ - Printf (f_init, "gh_new_procedure(\"%s\", %s, %d, %d, 0);\n", - proc_name, wname, numargs-numopt, numopt); - } - if (procdoc) { - /* Write out procedure documentation */ - Printv(signature, "Returns ", 0); - if (Len(returns)==0) Printv(signature, "unspecified", 0); - else if (returns_list) Printv(signature, "list (", returns, ")", 0); - else Printv(signature, returns, 0); - Printv(signature, "\n", 0); - Printv(procdoc, "\f\n", signature, 0); - } - - Delete(proc_name); - Delete(outarg); - Delete(cleanup); - Delete(signature); - Delete(returns); - Delete(tmp); - Delete(f); - delete[] wname; -} - -// ----------------------------------------------------------------------- -// GUILE::variable() -// -// Create a link to a C variable. -// This creates a single function PREFIX_var_VARNAME(). -// This function takes a single optional argument. If supplied, it means -// we are setting this variable to some value. If omitted, it means we are -// simply evaluating this variable. Either way, we return the variables -// value. -// ----------------------------------------------------------------------- - -void -GUILE::variable (DOH *node) -{ - char *name, *iname; - SwigType *t; - - DOHString *proc_name; - char var_name[256]; - char *tm; - Wrapper *f; - - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - - f = NewWrapper(); - // evaluation function names - - sprintf (var_name, "%svar_%s", prefix, iname); - - // Build the name for scheme. - proc_name = NewString(iname); - Replace(proc_name,"_", "-",DOH_REPLACE_ANY); - - if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { - - Printf (f_wrappers, "SCM %s(SCM s_0) {\n", var_name); - - if (!(ReadOnly) && SwigType_type(t) == T_STRING) { - Printf (f_wrappers, "\t char *_temp;\n"); - Printf (f_wrappers, "\t int _len;\n"); - } - Printf (f_wrappers, "\t SCM gswig_result;\n"); - - // Check for a setting of the variable value - - Printf (f_wrappers, "\t if (s_0 != GH_NOT_PASSED) {\n"); - - // Yup. Extract the type from s_0 and set variable value - - if (ReadOnly) { - Printf (f_wrappers, "\t\t scm_misc_error(\"%s\", " - "\"Unable to set %s. Variable is read only.\", SCM_EOL);\n", - proc_name, proc_name); - } - else if ((tm = guile_typemap_lookup ("varin", - t, name, (char*)"s_0", name, f))) { - Printf (f_wrappers, "%s\n", tm); - } - else if (is_a_pointer(t)) { - if (SwigType_type(t) == T_STRING) { - Printf (f_wrappers, "\t\t _temp = gh_scm2newstr(s_0, &_len);\n"); - Printf (f_wrappers, "\t\t if (%s) { free(%s);}\n", name, name); - Printf (f_wrappers, "\t\t %s = (char *) " - "malloc((_len+1)*sizeof(char));\n", name); - Printf (f_wrappers, "\t\t strncpy(%s,_temp,_len);\n", name); - Printf (f_wrappers, "\t\t %s[_len] = 0;\n", name); - } else { - // Set the value of a pointer - Printf (f_wrappers, "\t if (SWIG_Guile_GetPtr(s_0, " - "(void **) &%s, ", name); - if (SwigType_type(t) == T_VOID) - Printf (f_wrappers, "NULL)) {\n"); - else - Printf (f_wrappers, "SWIGTYPE%s)) {\n", SwigType_manglestr(t)); - /* Raise exception */ - Printf(f_wrappers, "\tscm_wrong_type_arg(\"%s\", " - "%d, s_0);\n", proc_name, 1); - Printf (f_wrappers, "\t}\n"); - } - } - else { - throw_unhandled_guile_type_error (t); - } - Printf (f_wrappers, "\t}\n"); - - // Now return the value of the variable (regardless - // of evaluating or setting) - - if ((tm = guile_typemap_lookup ("varout", - t, name, name, (char*)"gswig_result", f))) { - Printf (f_wrappers, "%s\n", tm); - } - else if (is_a_pointer(t)) { - if (SwigType_type(t) == T_STRING) { - Printf (f_wrappers, "\t gswig_result = gh_str02scm(%s);\n", name); - } else { - // Is an ordinary pointer type. - Printf (f_wrappers, "\t gswig_result = SWIG_Guile_MakePtr (" - "%s, SWIGTYPE%s);\n", name, SwigType_manglestr(t)); - } - } - else { - throw_unhandled_guile_type_error (t); - } - Printf (f_wrappers, "\t return gswig_result;\n"); - Printf (f_wrappers, "}\n"); - - // Now add symbol to the Guile interpreter - - if (!emit_setters - || ReadOnly) { - /* Read-only variables become a simple procedure returning the - value. */ - Printf (f_init, "\t gh_new_procedure(\"%s\", %s, 0, 1, 0);\n", - proc_name, var_name); - } - else { - /* Read/write variables become a procedure with setter. */ - Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", %s, 0, 1, 0);\n", - proc_name, var_name); - Printf (f_init, "\t gh_define(\"%s\", " - "scm_make_procedure_with_setter(p, p)); }\n", - proc_name); - } - - if (procdoc) { - /* Compute documentation */ - String *signature = NewString(""); - - if (ReadOnly) { - Printv(signature, "(", proc_name, ")\n", 0); - Printv(signature, "Returns constant ", 0); - guile_do_doc_typemap(signature, "varoutdoc", t, NULL, - 0, proc_name, f); - Printv(signature, "\n", 0); + Printf (f->code, "\nreturn gswig_result;\n"); + Printf (f->code, "#undef FUNC_NAME\n"); + Printf (f->code, "}\n"); + + Wrapper_print (f, f_wrappers); + + // Now add symbol to the Guile interpreter + + if (!emit_setters + || Getattr(n,"feature:immutable")) { + /* Read-only variables become a simple procedure returning the + value; read-write variables become a simple procedure with + an optional argument. */ + Printf (f_init, "\t gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, %d, 0);\n", + proc_name, var_name, Getattr(n,"feature:immutable") ? 0 : 1); } else { - Printv(signature, "(", proc_name, - " #:optional ", 0); - guile_do_doc_typemap(signature, "varindoc", t, "new-value", - 1, proc_name, f); - Printv(signature, ")\n", 0); - Printv(signature, "If NEW-VALUE is provided, " - "set C variable to this value.\n", 0); - Printv(signature, "Returns variable value ", 0); - guile_do_doc_typemap(signature, "varoutdoc", t, NULL, - 0, proc_name, f); - Printv(signature, "\n", 0); + /* Read/write variables become a procedure with setter. */ + Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 1, 0);\n", + proc_name, var_name); + Printf (f_init, "\t gh_define(\"%s\", " + "scm_make_procedure_with_setter(p, p)); }\n", + proc_name); } - Printv(procdoc, "\f\n", signature, 0); - Delete(signature); - } - - } else { - Printf (stderr, "%s:%d. ** Warning. Unable to link with " - " type %s (ignored).\n", - Getfile(node), Getline(node), SwigType_str(t,0)); - } - Delete(proc_name); - Delete(f); -} - -// ----------------------------------------------------------------------- -// GUILE::constant() -// -// Makes a constant. Not sure how this is really supposed to work. -// I'm going to fake out SWIG and create a variable instead. -// ------------------------------------------------------------------------ - -void -GUILE::constant(DOH *node) -{ - char *name; - SwigType *type; - char *value; - int OldStatus = ReadOnly; // Save old status flags - DOHString *proc_name; - char var_name[256]; - DOHString *rvalue; - char *tm; - Wrapper *f; - - name = GetChar(node,"name"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - - f = NewWrapper(); - ReadOnly = 1; // Enable readonly mode. - - // Make a static variable; - - sprintf (var_name, "%sconst_%s", prefix, name); - - // Build the name for scheme. - proc_name = NewString(name); - Replace(proc_name,"_", "-", DOH_REPLACE_ANY); - - if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { - Printf (stderr, "%s:%d. Unsupported constant value.\n", - Getfile(node), Getline(node)); - return; - } - - // See if there's a typemap - - if (SwigType_type(type) == T_STRING) { - rvalue = NewStringf("\"%s\"", value); - } else if (SwigType_type(type) == T_CHAR) { - rvalue = NewStringf("\'%s\'", value); - } else { - rvalue = NewString(value); - } - if ((tm = guile_typemap_lookup ("const", type, name, - Char(rvalue), name, f))) { - Printf (f_init, "%s\n", tm); - } else { - // Create variable and assign it a value - - Printf (f_header, "static %s %s = ", SwigType_lstr(type,0), var_name); - if (SwigType_type(type) == T_STRING) { - Printf (f_header, "\"%s\";\n", value); - } else if (SwigType_type(type) == T_CHAR) { - Printf (f_header, "\'%s\';\n", value); + Printf (exported_symbols, "\"%s\", ", proc_name); + + if (procdoc) { + /* Compute documentation */ + String *signature = NewString(""); + String *signature2 = NULL; + String *doc = NewString(""); + + if (Getattr(n,"feature:immutable")) { + Printv(signature, proc_name, NIL); + Printv(doc, "Returns constant ", NIL); + if ((tm = Getattr(n,"tmap:varout:doc"))) { + Printv(doc,tm,NIL); + } else { + String *s = SwigType_str(t,0); + Chop(s); + Printf(doc,"<%s>",s); + Delete(s); + } + } + else if (emit_setters) { + Printv(signature, proc_name, NIL); + signature2 = NewString(""); + Printv(signature2, "set! (", proc_name, ") ", NIL); + handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist", + "new-value"); + Printv(doc, "Get or set the value of the C variable, \n", NIL); + Printv(doc, "which is of type ", NIL); + handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc", + "$1_type"); + Printv(doc, "."); + } + else { + Printv(signature, proc_name, + " #:optional ", NIL); + if ((tm = Getattr(n,"tmap:varin:doc"))) { + Printv(signature,tm,NIL); + } else { + String *s = SwigType_str(t,0); + Chop(s); + Printf(signature,"new-value <%s>",s); + Delete(s); + } + + Printv(doc, "If NEW-VALUE is provided, " + "set C variable to this value.\n", NIL); + Printv(doc, "Returns variable value ", NIL); + if ((tm = Getattr(n,"tmap:varout:doc"))) { + Printv(doc,tm,NIL); + } else { + String *s = SwigType_str(t,0); + Chop(s); + Printf(doc,"<%s>",s); + Delete(s); + } + } + write_doc(proc_name, signature, doc, signature2); + Delete(signature); + if (signature2) Delete(signature2); + Delete(doc); + } + } else { - Printf (f_header, "%s;\n", value); + Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, + "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); } - // Now create a variable declaration + Delete(proc_name); + DelWrapper(f); + return SWIG_OK; + } - Hash *nnode = Copy(node); - Setattr(nnode,"name",var_name); - variable(nnode); - Delete(nnode); - ReadOnly = OldStatus; - } - Delete(proc_name); - Delete(rvalue); - Delete(f); -} + /* ------------------------------------------------------------ + * constantWrapper() + * + * We create a read-only variable. + * ------------------------------------------------------------ */ -void GUILE::cpp_variable(DOH *node) -{ - if (emit_setters) { - struct_member = 1; - Printf(f_init, "{\n"); - Language::cpp_variable(node); - Printf(f_init, "}\n"); - struct_member = 0; + virtual int constantWrapper(Node *n) { + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + + String *proc_name; + char var_name[256]; + String *rvalue; + Wrapper *f; + SwigType *nctype; + String *tm; + + f = NewWrapper(); + + // Make a static variable; + + sprintf (var_name, "%sconst_%s", prefix, iname); + + // Strip const qualifier from type if present + + nctype = NewString(type); + if (SwigType_isconst(nctype)) { + Delete(SwigType_pop(nctype)); + } + + // Build the name for scheme. + proc_name = NewString(iname); + Replaceall(proc_name,"_", "-"); + + if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) { + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value.\n"); + return SWIG_NOWRAP; + } + + // See if there's a typemap + + if (SwigType_type(nctype) == T_STRING) { + rvalue = NewStringf("\"%s\"", value); + } else if (SwigType_type(nctype) == T_CHAR) { + rvalue = NewStringf("\'%s\'", value); + } else { + rvalue = NewString(value); + } + + if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) { + Replaceall(tm,"$source",rvalue); + Replaceall(tm,"$value",rvalue); + Replaceall(tm,"$target",name); + Printv(f_header,tm,"\n",NIL); + } else { + // Create variable and assign it a value + Printf (f_header, "static %s = %s;\n", SwigType_lstr(nctype,var_name), + rvalue); + } + { + /* Hack alert: will cleanup later -- Dave */ + Node *n = NewHash(); + Setattr(n,"name",var_name); + Setattr(n,"sym:name",iname); + Setattr(n,"type", nctype); + Setattr(n,"feature:immutable", "1"); + variableWrapper(n); + Delete(n); + } + Delete(nctype); + Delete(proc_name); + Delete(rvalue); + DelWrapper(f); + return SWIG_OK; } - else { - /* Only emit traditional VAR-get and VAR-set procedures */ - Language::cpp_variable(node); + + /* ------------------------------------------------------------ + * membervariableHandler() + * ------------------------------------------------------------ */ + virtual int membervariableHandler(Node *n) { + if (emit_setters) { + struct_member = 1; + Printf(f_init, "{\n"); + Language::membervariableHandler(n); + Printf(f_init, "}\n"); + struct_member = 0; + } + else { + /* Only emit traditional VAR-get and VAR-set procedures */ + Language::membervariableHandler(n); + } + return SWIG_OK; } + + /* ------------------------------------------------------------ + * pragmaDirective() + * ------------------------------------------------------------ */ + + virtual int pragmaDirective(Node *n) + { + if (!ImportMode) { + String *lang = Getattr(n,"lang"); + String *cmd = Getattr(n,"name"); + String *value = Getattr(n,"value"); + +# define store_pragma(PRAGMANAME) \ + if (Strcmp(cmd, #PRAGMANAME) == 0) { \ + if (PRAGMANAME) Delete(PRAGMANAME); \ + PRAGMANAME = value ? NewString(value) : NULL; \ + } + + if (Strcmp(lang,"guile") == 0) { + store_pragma(beforereturn) + store_pragma(return_nothing_doc) + store_pragma(return_one_doc) + store_pragma(return_multi_doc); +# undef store_pragma + } + } + return Language::pragmaDirective(n); + } + + /* ------------------------------------------------------------ + * validIdentifier() + * ------------------------------------------------------------ */ + + virtual int validIdentifier(String *s) { + char *c = Char(s); + /* Check whether we have an R5RS identifier. Guile supports a + superset of R5RS identifiers, but it's probably a bad idea to use + those. */ + /* --> * | */ + /* --> | */ + if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') + || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') + || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') + || (*c == '^') || (*c == '_') || (*c == '~'))) { + /* --> + | - | ... */ + if ((strcmp(c, "+") == 0) + || strcmp(c, "-") == 0 + || strcmp(c, "...") == 0) return 1; + else return 0; + } + /* --> | | */ + while (*c) { + if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') + || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') + || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') + || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') + || (*c == '-') || (*c == '.') || (*c == '@'))) return 0; + c++; + } + return 1; + } +}; + +/* ----------------------------------------------------------------------------- + * swig_guile() - Instantiate module + * ----------------------------------------------------------------------------- */ + +extern "C" Language * +swig_guile(void) { + return new GUILE(); } diff --git a/Source/Modules1.1/guile.h b/Source/Modules1.1/guile.h deleted file mode 100644 index a9aef3374..000000000 --- a/Source/Modules1.1/guile.h +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************** - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - *****************************************************************************/ - -/************************************************************************** - * $Header$ - * - * class GUILE - * - * Guile implementation - * - **************************************************************************/ - -#include "swig.h" - -class GUILE : public Language -{ -private: - char *prefix; - char *module; - char *package; - enum { - GUILE_LSTYLE_SIMPLE, // call `SWIG_init()' - GUILE_LSTYLE_LTDLMOD, // "native" guile? - GUILE_LSTYLE_HOBBIT // use (hobbit4d link) - } linkage; - File *procdoc; - int emit_setters; - int struct_member; - void emit_linkage(char *module_name); - -public : - GUILE (); - void parse_args (int, char *argv[]); - void initialize(String *module); - void function (DOH *node); - void variable (DOH *node); - void constant (DOH *node); - void close (void); - void create_command (String *, String *) { }; - void cpp_variable(DOH *node); -}; - -/* guile.h ends here */ diff --git a/Source/Modules1.1/java.cxx b/Source/Modules1.1/java.cxx index 18b7011d5..499a58b24 100644 --- a/Source/Modules1.1/java.cxx +++ b/Source/Modules1.1/java.cxx @@ -1,1347 +1,1900 @@ -/******************************************************************************* - * SWIG Java module - * Author: Harco de Hilster - * AT Consultancy - * Toernooiveld 104 - * P.O. Box 1428 - * 6501 BK Nijmegen - * +31 24 3527282 - * harcoh@ATConsultancy.nl +/* ----------------------------------------------------------------------------- + * java.cxx * - * thanks to the following persons for submitting bug-reports: + * Java wrapper module. * - * James Hicks - * Lars Schmidt-Thieme - * Per OEyvind Hvidsten Per-Oyvind.Hvidsten@ffi.no - * Geoff Dillon - * Michael Haller - * "Simon J. Julier" - * "Pritam Kamat" - * Marc Hadley - ******************************************************************************* -*/ + * Author(s) : Harco de Hilster + * William Fulton + * + * Copyright (C) 1999-2002. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ -/* !!!!!!! - * DB 7/24/00: Is there any way to clean up the implementation of this module? - * I've tried to bring it as far as I can with core changes, but it's getting - * to be a little rough. - * !!!!!!! - */ +char cvsroot_java_cxx[] = "$Header$"; #include +#include // for INT_MAX +#include "swigmod.h" -#include "mod11.h" -#include "java.h" +class JAVA : public Language { + static const char *usage; + const String *empty_string; -char bigbuf[1024]; + Hash *swig_types_hash; + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; -static char *usage = (char*)"\ -Java Options\n\ - -jnic - use c syntax for jni calls\n\ - -jnicpp - use c++ syntax for jni calls\n\ - -module name - set name of module\n\ - -package name - set name of package\n\ - -shadow - enable shadow classes\n\ - -finalize - generate finalize methods\n\ - -rn - generate register natives code\n\n"; + bool proxy_flag; // Flag for generating shadow classes + bool have_default_constructor_flag; + bool native_function_flag; // Flag for when wrapping a native function + bool enum_constant_flag; // Flag for when wrapping an enum or constant + bool static_flag; // Flag for when wrapping a static functions or member variables + bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable + bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const + bool global_variable_flag; // Flag for when wrapping a global variable -static char *module = 0; // Name of the module -static char *java_path = (char*)"java"; -static char *package = 0; // Name of the package -static char *c_pkgstr; // Name of the package -static char *jni_pkgstr; // Name of the package -static char *shadow_classname; -static char *jimport = 0; -static char *method_modifiers = (char*)"public final static"; -static FILE *f_java = 0; -static FILE *f_shadow = 0; -static int shadow = 0; -static DOHHash *shadow_classes; -static DOHString *shadow_classdef; -static char *shadow_name = 0; -static char *shadow_baseclass = 0; -static int classdef_emitted = 0; -static int shadow_classdef_emitted = 0; -static int have_default_constructor = 0; -static int native_func = 0; // Set to 1 when wrapping a native function -static int member_func = 0; // Set to 1 when wrapping a member function -static int jnic = -1; // 1: use c syntax jni; 0: use c++ syntax jni -static int finalize = 0; // generate finalize methods -static int useRegisterNatives = 0; // Set to 1 when doing stuff with register natives -static DOHString *registerNativesList = 0; + String *jniclass_name; // JNI class name + String *module_class_name; // module class name + String *jniclass_class_code; // JNI class Java code - that is the native methods + String *shadow_classdef; + String *shadow_code; + String *module_class_code; + String *shadow_classname; + String *variable_name; //Name of a variable being wrapped + String *shadow_constants_code; + String *module_constants_code; + String *package; // Package name + String *jnipackage; // JNI package name + String *jniclass_imports; //jniclass imports from %pragma + String *module_imports; //module imports from %pragma + String *jniclass_baseclass; //inheritance for jniclass class from %pragma + String *module_baseclass; //inheritance for module class from %pragma + String *jniclass_interfaces; //interfaces for jniclass class from %pragma + String *module_interfaces; //interfaces for module class from %pragma + String *jniclass_class_modifiers; //class modifiers for jniclass class overriden by %pragma + String *module_class_modifiers; //class modifiers for module class overriden by %pragma + String *wrapper_conversion_code; //C++ casts for inheritance hierarchies JNI code + String *jniclass_cppcasts_code; //C++ casts up inheritance hierarchies JNI class Java code + String *destructor_call; //Destructor (delete) call if any -char *JAVA::SwigTcToJniType(DataType *t, int ret) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"jintArray"; - case T_SHORT: return (char*)"jshortArray"; - case T_LONG: return (char*)"jlongArray"; - case T_CHAR: return (char*)"jstring"; - case T_FLOAT: return (char*)"jfloatArray"; - case T_DOUBLE: return (char*)"jdoubleArray"; - case T_UINT: return (char*)"jintArray"; - case T_USHORT: return (char*)"jshortArray"; - case T_ULONG: return (char*)"jlongArray"; - case T_UCHAR: return (char*)"jbyteArray"; - case T_SCHAR: return (char*)"jbyteArray"; - case T_BOOL: return (char*)"jbooleanArray"; - case T_VOID: - case T_USER: return (char*)"jlong"; - } - } else if(DataType_is_pointer(t) > 1) { - if(ret) - return (char*)"jlong"; - else return (char*)"jlongArray"; - } else { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"jint"; - case T_SHORT: return (char*)"jshort"; - case T_LONG: return (char*)"jlong"; - case T_CHAR: return (char*)"jbyte"; - case T_FLOAT: return (char*)"jfloat"; - case T_DOUBLE: return (char*)"jdouble"; - case T_UINT: return (char*)"jint"; - case T_USHORT: return (char*)"jshort"; - case T_ULONG: return (char*)"jlong"; - case T_UCHAR: return (char*)"jbyte"; - case T_SCHAR: return (char*)"jbyte"; - case T_BOOL: return (char*)"jboolean"; - case T_VOID: return (char*)"void"; - case T_USER: return (char*)"jlong"; - } - } - Printf(stderr, "SwigTcToJniType: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; -} + enum type_additions {none, pointer, reference}; -char *JAVA::SwigTcToJavaType(DataType *t, int ret, int inShadow) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"int []"; - case T_SHORT: return (char*)"short []"; - case T_LONG: return (char*)"long []"; - case T_CHAR: return (char*)"String"; - case T_FLOAT: return (char*)"float []"; - case T_DOUBLE: return (char*)"double []"; - case T_UINT: return (char*)"int []"; - case T_USHORT: return (char*)"short []"; - case T_ULONG: return (char*)"long []"; - case T_UCHAR: return (char*)"byte []"; - case T_SCHAR: return (char*)"byte []"; - case T_BOOL: return (char*)"boolean []"; - case T_VOID: - case T_USER: if(inShadow && Getattr(shadow_classes,DataType_Getname(t))) - return GetChar(shadow_classes,DataType_Getname(t)); - else return (char*)"long"; - } - } else if(DataType_is_pointer(t) > 1) { - if(ret) - return (char*)"long"; - else return (char*)"long []"; - } else { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"int"; - case T_SHORT: return (char*)"short"; - case T_LONG: return (char*)"long"; - case T_CHAR: return (char*)"byte"; - case T_FLOAT: return (char*)"float"; - case T_DOUBLE: return (char*)"double"; - case T_UINT: return (char*)"int"; - case T_USHORT: return (char*)"short"; - case T_ULONG: return (char*)"long"; - case T_UCHAR: return (char*)"byte"; - case T_SCHAR: return (char*)"byte"; - case T_BOOL: return (char*)"boolean"; - case T_VOID: return (char*)"void"; - case T_USER: return (char*)"long"; - } - } - Printf(stderr, "SwigTcToJavaType: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; -} + public: -char *JAVA::SwigTcToJniScalarType(DataType *t) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"Int"; - case T_SHORT: return (char*)"Short"; - case T_LONG: return (char*)"Long"; - case T_CHAR: return (char*)"Byte"; - case T_FLOAT: return (char*)"Float"; - case T_DOUBLE: return (char*)"Double"; - case T_UINT: return (char*)"Int"; - case T_USHORT: return (char*)"Short"; - case T_ULONG: return (char*)"Long"; - case T_UCHAR: return (char*)"Byte"; - case T_SCHAR: return (char*)"Byte"; - case T_BOOL: return (char*)"Boolean"; - case T_VOID: - case T_USER: return (char*)"Long"; - } - } else { - return (char*)"Long"; - } + /* ----------------------------------------------------------------------------- + * JAVA() + * ----------------------------------------------------------------------------- */ - Printf(stderr, "SwigTcToJniScalarType: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; -} + JAVA() : + empty_string(NewString("")), -char *JAVA::JavaMethodSignature(DataType *t, int ret, int inShadow) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"[I"; - case T_SHORT: return (char*)"[S"; - case T_LONG: return (char*)"[J"; - case T_CHAR: return (char*)"Ljava/lang/String;"; - case T_FLOAT: return (char*)"[F"; - case T_DOUBLE: return (char*)"[D"; - case T_UINT: return (char*)"[I"; - case T_USHORT: return (char*)"[S"; - case T_ULONG: return (char*)"[J"; - case T_UCHAR: return (char*)"[B"; - case T_SCHAR: return (char*)"[B"; - case T_BOOL: return (char*)"[Z"; - case T_VOID: - case T_USER: if(inShadow && Getattr(shadow_classes,DataType_Getname(t))) - return GetChar(shadow_classes,DataType_Getname(t)); - else return (char*)"J"; - } - } else if(DataType_is_pointer(t) > 1) { - if(ret) return (char*)"J"; - else return (char*)"[J"; - } else { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"I"; - case T_SHORT: return (char*)"S"; - case T_LONG: return (char*)"J"; - case T_CHAR: return (char*)"B"; - case T_FLOAT: return (char*)"F"; - case T_DOUBLE: return (char*)"D"; - case T_UINT: return (char*)"I"; - case T_USHORT: return (char*)"S"; - case T_ULONG: return (char*)"J"; - case T_UCHAR: return (char*)"B"; - case T_SCHAR: return (char*)"B"; - case T_BOOL: return (char*)"Z"; - case T_VOID: return (char*)"V"; - case T_USER: return (char*)"J"; - } - } - Printf(stderr, "JavaMethodSignature: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; -} + swig_types_hash(NULL), + f_runtime(NULL), + f_header(NULL), + f_wrappers(NULL), + f_init(NULL), -char *JAVA::JavaTypeFromTypemap(char *op, char *lang, DataType *t, char *pname) { - char *tm; - char *c = bigbuf; - if(!(tm = typemap_lookup(op, lang, t, pname, (char*)"", (char*)""))) return NULL; - while(*tm && (isspace(*tm) || *tm == '{')) tm++; - while(*tm && *tm != '}') *c++ = *tm++; - *c='\0'; + proxy_flag(true), + have_default_constructor_flag(false), + native_function_flag(false), + enum_constant_flag(false), + static_flag(false), + variable_wrapper_flag(false), + wrapping_member_flag(false), + global_variable_flag(false), - return strdup(bigbuf); -} + jniclass_name(NULL), + module_class_name(NULL), + jniclass_class_code(NULL), + shadow_classdef(NULL), + shadow_code(NULL), + module_class_code(NULL), + shadow_classname(NULL), + variable_name(NULL), + shadow_constants_code(NULL), + module_constants_code(NULL), + package(NULL), + jnipackage(NULL), + jniclass_imports(NULL), + module_imports(NULL), + jniclass_baseclass(NULL), + module_baseclass(NULL), + jniclass_interfaces(NULL), + module_interfaces(NULL), + jniclass_class_modifiers(NULL), + module_class_modifiers(NULL), + wrapper_conversion_code(NULL), + jniclass_cppcasts_code(NULL), + destructor_call(NULL) -char *JAVA::makeValidJniName(char *name) { - char *c = name; - char *b = bigbuf; + { + } - while(*c) { - *b++ = *c; - if(*c == '_') *b++ = '1'; - c++; - } - *b = '\0'; + /* ----------------------------------------------------------------------------- + * is_shadow() + * + * Test to see if a type corresponds to something wrapped with a shadow/proxy class + * Return NULL if not otherwise the shadow name + * ----------------------------------------------------------------------------- */ - return strdup(bigbuf); -} - -// !! this approach fails for functions without arguments -char *JAVA::JNICALL(DOHString_or_char *func) { - if(jnic) - sprintf(bigbuf, "(*jenv)->%s(jenv, ", Char(func)); - else - sprintf(bigbuf, "jenv->%s(", Char(func)); - - return strdup(bigbuf); -} - -void JAVA::writeRegisterNatives() -{ - if(Len(registerNativesList) == 0) - return; - - Printf(f_wrappers,"\n"); - Printf(f_wrappers,"JNINativeMethod nativeMethods[] = {\n"); - Printv(f_wrappers, registerNativesList, 0); - Printf(f_wrappers, "};\n"); - - Printf(f_wrappers,"\nint numberOfNativeMethods=sizeof(nativeMethods)/sizeof(JNINativeMethod);\n\n"); - - // The registerNatives function - - Printv(f_wrappers, - "jint registerNatives(JNIEnv *jenv) {", "\n", - tab4, "jclass nativeClass = ", JNICALL((char*)"FindClass"), - "\"", jni_pkgstr, module, "\");","\n", - 0); - - Printv(f_wrappers, - tab4, "if (nativeClass == 0)", "\n", tab8, "return -1;", "\n", - tab4, "return ", JNICALL((char*)"RegisterNatives"), "nativeClass, nativeMethods, ", "numberOfNativeMethods);", "\n", - "}", "\n", "\n", - 0); - - // The unregisterNatives function - - Printv(f_wrappers, - "jint unregisterNatives(JNIEnv *jenv) {", "\n", - tab4, "jclass nativeClass = ", JNICALL((char*)"FindClass"), - "\"", jni_pkgstr, module, "\");","\n", - 0); - - Printv(f_wrappers, - tab4, "if (nativeClass == 0)", "\n", tab8, "return -1;", "\n", - tab4, "// Sun documentation suggests that this method should not be invoked in ", - "\"normal native code\".", "\n", - tab4, "// return ", JNICALL((char*)"UnregisterNatives"), "nativeClass);", "\n", - tab4, "return 0;", "\n", - "}", "\n", - 0); -} - -// --------------------------------------------------------------------- -// JAVA::parse_args(int argc, char *argv[]) -// -// Parse my command line options and initialize by variables. -// --------------------------------------------------------------------- - -void JAVA::parse_args(int argc, char *argv[]) { - - // file::set_library(java_path); - sprintf(LibDir,"%s", "java"); - - - // Look for certain command line options - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i],"-module") == 0) { - if (argv[i+1]) { - set_module(argv[i+1],0); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i],"-package") == 0) { - if (argv[i+1]) { - package = new char[strlen(argv[i+1])+1]; - strcpy(package, argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i],"-shadow") == 0) { - Swig_mark_arg(i); - shadow = 1; - } else if (strcmp(argv[i],"-jnic") == 0) { - Swig_mark_arg(i); - jnic = 1; - } else if (strcmp(argv[i],"-finalize") == 0) { - Swig_mark_arg(i); - finalize = 1; - } else if (strcmp(argv[i],"-rn") == 0) { - Swig_mark_arg(i); - useRegisterNatives = 1; - } else if (strcmp(argv[i],"-jnicpp") == 0) { - Swig_mark_arg(i); - jnic = 0; - } else if (strcmp(argv[i],"-help") == 0) { - Printf(stderr,"%s\n", usage); + String *is_shadow(SwigType *t) { + if (proxy_flag) { + Node *n = classLookup(t); + if (n) { + return Getattr(n,"sym:name"); } } + return NULL; } - if(jnic == -1) { - if(CPlusPlus) - jnic = 0; - else jnic = 1; + /* ----------------------------------------------------------------------------- + * makeValidJniName() + * ----------------------------------------------------------------------------- */ + + String *makeValidJniName(const String *name) { + String *valid_jni_name = NewString(name); + Replaceall(valid_jni_name,"_","_1"); + return valid_jni_name; } - // Add a symbol to the parser for conditional compilation - // cpp::define("SWIGJAVA"); - Preprocessor_define((void *) "SWIGJAVA 1",0); + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ - // Add typemap definitions - typemap_lang = (char*)"java"; -} + virtual void main(int argc, char *argv[]) { -// --------------------------------------------------------------------- -// void JAVA::parse() -// -// Start parsing an interface file for JAVA. -// --------------------------------------------------------------------- + SWIG_library_directory("java"); -void JAVA::parse() { - - Printf(stderr,"Generating wrappers for Java\n"); - - shadow_classes = NewHash(); - shadow_classdef = NewString(""); - registerNativesList = NewString(""); - - headers(); // Emit header files and other supporting code - yyparse(); // Run the SWIG parser -} - -// --------------------------------------------------------------------- -// JAVA::set_module(char *mod_name,char **mod_list) -// -// Sets the module name. Does nothing if it's already set (so it can -// be overriddent as a command line option). -// -// mod_list is a NULL-terminated list of additional modules. This -// is really only useful when building static executables. -//---------------------------------------------------------------------- - -void JAVA::set_module(char *mod_name, char **mod_list) { - if (module) return; - module = new char[strlen(mod_name)+1]; - strcpy(module,mod_name); -} - -// --------------------------------------------------------------------- -// JAVA::headers(void) -// -// Generate the appropriate header files for JAVA interface. -// ---------------------------------------------------------------------- - -void JAVA::headers(void) -{ - Swig_banner(f_header); // Print the SWIG banner message - Printf(f_header,"/* Implementation : Java */\n\n"); - - // Include header file code fragment into the output - // if (file::include("java.swg",f_header) == -1) { - if (Swig_insert_file("java.swg",f_header) == -1) { - Printf(stderr,"Fatal Error. Unable to locate 'java.swg'.\n"); - SWIG_exit (EXIT_FAILURE); - } -} - -// -------------------------------------------------------------------- -// JAVA::initialize(void) -// -// Produces an initialization function. Assumes that the init function -// name has already been specified. -// --------------------------------------------------------------------- - -void JAVA::initialize() -{ - if (!module) { - Printf(stderr,"*** Error. No module name specified.\n"); - SWIG_exit(1); - } - - if(package) { - DOHString *s = NewString(package); - Replace(s,".","_", DOH_REPLACE_ANY); - Append(s,"_"); - c_pkgstr = Swig_copy_string(Char(s)); - Delete(s); - - DOHString *s2 = NewString(package); - Replace(s2,".","/", DOH_REPLACE_ANY); - Append(s2,"/"); - jni_pkgstr = Swig_copy_string(Char(s2)); - Delete(s2); - } else { - package = c_pkgstr = jni_pkgstr = (char*)""; - } - - sprintf(bigbuf, "Java_%s%s", c_pkgstr, module); - c_pkgstr = Swig_copy_string(bigbuf); - sprintf(bigbuf, "%s_%%f", c_pkgstr); - Swig_name_register((char*)"wrapper", Swig_copy_string(bigbuf)); - Swig_name_register((char*)"set", (char*)"set_%v"); - Swig_name_register((char*)"get", (char*)"get_%v"); - Swig_name_register((char*)"member", (char*)"%c_%m"); - - // Generate the java class - sprintf(bigbuf, "%s.java", module); - if((f_java = fopen(bigbuf, "w")) == 0) { - Printf(stderr,"Unable to open %s\n", bigbuf); - SWIG_exit(1); - } - - Printf(f_header, "#define J_CLASSNAME %s\n", module); - if(package && *package) { - Printf(f_java, "package %s;\n\n", package); - Printf(f_header, "#define J_PACKAGE %s\n", package); - } else { - Printf(f_header, "#define J_PACKAGE\n"); - } -} - -void JAVA::emit_classdef() { - if(!classdef_emitted) - Printf(f_java, "public class %s {\n", module); - classdef_emitted = 1; -} - -// --------------------------------------------------------------------- -// JAVA::close(void) -// -// Wrap things up. Close initialization function. -// --------------------------------------------------------------------- - -void JAVA::close(void) -{ - if(!classdef_emitted) emit_classdef(); - - // Finish off the java class - Printf(f_java, "}\n"); - fclose(f_java); - - if(useRegisterNatives) - writeRegisterNatives(); -} - -// ---------------------------------------------------------------------- -// JAVA::create_command(char *cname, char *iname) -// -// Creates a JAVA command from a C function. -// ---------------------------------------------------------------------- - -void JAVA::create_command(char *cname, char *iname) { -} - -void JAVA::add_native(char *name, char *iname, DataType *t, ParmList *l) { - native_func = 1; - create_function(name, iname, t, l); - native_func = 0; -} - -// ---------------------------------------------------------------------- -// JAVA::create_function(char *name, char *iname, DataType *d, ParmList *l) -// -// Create a function declaration and register it with the interpreter. -// ---------------------------------------------------------------------- - -void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) -{ - char source[256], target[256]; - char *tm; - DOHString *cleanup, *outarg, *body; - char *javaReturnSignature = 0; - DOHString *javaParameterSignature; - Parm *p; - - cleanup = NewString(""); - outarg = NewString(""); - body = NewString(""); - javaParameterSignature = NewString(""); - - // A new wrapper function object - Wrapper *f = NewWrapper(); - - if(!classdef_emitted) emit_classdef(); - - // Make a wrapper name for this function - - char *jniname = makeValidJniName(iname); - char *wname = Swig_name_wrapper(jniname); - free(jniname); - - char *jnirettype = JavaTypeFromTypemap((char*)"jni", typemap_lang, t, iname); - if(!jnirettype) jnirettype = SwigTcToJniType(t, 1); - char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname); - if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0); - - // If dumping the registerNative outputs, store the method return type - // signature - if (useRegisterNatives) { - javaReturnSignature = JavaMethodSignature(t, 1, 0); - } - - if (DataType_type(t) != T_VOID) { - Wrapper_add_localv(f,"_jresult", jnirettype, "_jresult = 0",0); - } - - Printf(f_java, " %s ", method_modifiers); - Printf(f_java, "native %s %s(", javarettype, iname); - if(shadow && member_func) { - DOHString *member_name = NewString(""); - if(strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, shadow_name))) == 0) - Printf(member_name,"set"); - else Printf(member_name,"get"); - Putc(toupper((int) *shadow_name), member_name); - Printf(member_name, "%s", shadow_name+1); - Printf(f_shadow, " public %s %s(", javarettype, member_name); - Printv(body, tab4, "return ", module, ".", iname, "(_self", 0); - Delete(member_name); - } - - if(!jnic) Printf(f->def,"extern \"C\"\n"); - Printv(f->def, "JNIEXPORT ", jnirettype, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", 0); - - // Emit all of the local variables for holding arguments. - int pcount = emit_args(t,l,f); - - int gencomma = 0; - - // Now walk the function parameter list and generate code to get arguments - p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - char *target_copy = NULL; - char *target_length = NULL; - char *local_i = NULL; - - // Produce string representation of source and target arguments - sprintf(source,"jarg%d",i); - sprintf(target,"%s", Getlname(p)); - - char *jnitype = JavaTypeFromTypemap((char*)"jni", typemap_lang, pt, pn); - if(!jnitype) jnitype = SwigTcToJniType(pt, 0); - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); - if (useRegisterNatives) { - Printv(javaParameterSignature, JavaMethodSignature(pt, 0, 0), 0); - } - - if(Getignore(p)) continue; - - // Add to java function header - if(shadow && member_func) { - if(i > 0) { - if(i>1) Printf(f_shadow, ", "); - Printf(f_shadow, "%s %s", jtype, source); - Printv(body,", ", source, 0); + // Look for certain command line options + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-package") == 0) { + if (argv[i+1]) { + package = NewString(""); + Printf(package, argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) { + Printf(stderr,"Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]); + Swig_mark_arg(i); + proxy_flag = true; + } else if ((strcmp(argv[i],"-noproxy") == 0)) { + Swig_mark_arg(i); + proxy_flag = false; + } else if (strcmp(argv[i],"-jnic") == 0) { + Swig_mark_arg(i); + Printf(stderr,"Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n"); + } else if (strcmp(argv[i],"-nofinalize") == 0) { + Swig_mark_arg(i); + Printf(stderr,"Deprecated command line option: -nofinalize. Use the new javafinalize typemaps instead.\n"); + } else if (strcmp(argv[i],"-jnicpp") == 0) { + Swig_mark_arg(i); + Printf(stderr,"Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n"); + } else if (strcmp(argv[i],"-help") == 0) { + Printf(stderr,"%s\n", usage); } } + } - if(gencomma) Printf(f_java, ", "); - Printf(f_java, "%s %s", jtype, source); + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGJAVA 1",0); + + // Add typemap definitions + SWIG_typemap_lang("java"); + SWIG_config_file("java.swg"); + + allow_overloading(); + } + + /* --------------------------------------------------------------------- + * top() + * --------------------------------------------------------------------- */ + + virtual int top(Node *n) { + + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); + + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"Unable to open %s\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",f_init); + swig_types_hash = NewHash(); + + // Make the JNI class and module class names. The jniclassname can be set in the module directive. + Node* optionsnode = Getattr( Getattr(n,"module") ,"options"); + if (optionsnode) + if (Getattr(optionsnode,"jniclassname")) + jniclass_name = Copy(Getattr(optionsnode,"jniclassname")); + if (!jniclass_name) { + jniclass_name = NewStringf("%sJNI", Getattr(n,"name")); + module_class_name = Copy(Getattr(n,"name")); + } else { + // Rename the module name if it is the same as JNI class name - a backwards compatibility solution + if (Cmp(jniclass_name, Getattr(n,"name")) == 0) + module_class_name = NewStringf("%sModule", Getattr(n,"name")); + else + module_class_name = Copy(Getattr(n,"name")); + } + + + jniclass_class_code = NewString(""); + shadow_classdef = NewString(""); + shadow_code = NewString(""); + module_constants_code = NewString(""); + jniclass_baseclass = NewString(""); + jniclass_interfaces = NewString(""); + jniclass_class_modifiers = NewString(""); // package access only to the JNI class by default + module_class_code = NewString(""); + module_baseclass = NewString(""); + module_interfaces = NewString(""); + module_imports = NewString(""); + module_class_modifiers = NewString("public"); + jniclass_imports = NewString(""); + jniclass_cppcasts_code = NewString(""); + wrapper_conversion_code = NewString(""); + if (!package) package = NewString(""); + jnipackage = NewString(""); + + Swig_banner(f_runtime); // Print the SWIG banner message + + if (NoInclude) { + Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); + } + + String *wrapper_name = NewString(""); + + if(Len(package)) { + String *jniname = makeValidJniName(package); + Printv(jnipackage, jniname, NIL); + Delete(jniname); + Replaceall(jnipackage,".","_"); + Append(jnipackage, "_"); + } + String *jniname = makeValidJniName(jniclass_name); + Printf(wrapper_name, "Java_%s%s_%%f", Char(jnipackage), jniname); + Delete(jniname); + + Swig_name_register((char*)"wrapper", Char(wrapper_name)); + Swig_name_register((char*)"set", (char*)"set_%v"); + Swig_name_register((char*)"get", (char*)"get_%v"); + Swig_name_register((char*)"member", (char*)"%c_%m"); + + Delete(wrapper_name); + + Printf(f_wrappers,"#ifdef __cplusplus\n"); + Printf(f_wrappers,"extern \"C\" {\n"); + Printf(f_wrappers,"#endif\n"); + + /* Emit code */ + Language::top(n); + + // Generate the Java JNI class + { + String *filen = NewStringf("%s.java", jniclass_name); + File *f_java = NewFile(filen,"w"); + if(!f_java) { + Printf(stderr,"Unable to open %s\n", filen); + SWIG_exit(EXIT_FAILURE); + } + Delete(filen); filen = NULL; + + // Start writing out the Java JNI class + if(Len(package) > 0) + Printf(f_java, "package %s;\n\n", package); + + emitBanner(f_java); + if(jniclass_imports) + Printf(f_java, "%s\n", jniclass_imports); + + if (Len(jniclass_class_modifiers) > 0) + Printf(f_java, "%s ", jniclass_class_modifiers); + Printf(f_java, "class %s ", jniclass_name); + + if (jniclass_baseclass && *Char(jniclass_baseclass)) + Printf(f_java, "extends %s ", jniclass_baseclass); + if (Len(jniclass_interfaces) > 0) + Printv(f_java, "implements ", jniclass_interfaces, " ", NIL); + Printf(f_java, "{\n"); + + // Add the native methods + Printv(f_java, jniclass_class_code, NIL); + Printv(f_java, jniclass_cppcasts_code, NIL); + + // Finish off the Java class + Printf(f_java, "}\n"); + Close(f_java); + } + + // Generate the Java module class + { + String *filen = NewStringf("%s.java", module_class_name); + File *f_module = NewFile(filen,"w"); + if(!f_module) { + Printf(stderr,"Unable to open %s\n", filen); + SWIG_exit(EXIT_FAILURE); + } + Delete(filen); filen = NULL; + + // Start writing out the Java module class + if(Len(package) > 0) + Printf(f_module, "package %s;\n\n", package); + + emitBanner(f_module); + if(module_imports) + Printf(f_module, "%s\n", module_imports); + + if (Len(module_class_modifiers) > 0) + Printf(f_module, "%s ", module_class_modifiers); + Printf(f_module, "class %s ", module_class_name); + + if (module_baseclass && *Char(module_baseclass)) + Printf(f_module, "extends %s ", module_baseclass); + if (Len(module_interfaces) > 0) + Printv(f_module, "implements ", module_interfaces, " ", NIL); + Printf(f_module, "{\n"); + + // Add the wrapper methods + Printv(f_module, module_class_code, NIL); + + // Write out all the enums constants + if (Len(module_constants_code) != 0 ) + Printv(f_module, " // enums and constants\n", module_constants_code, NIL); + + // Finish off the Java class + Printf(f_module, "}\n"); + Close(f_module); + } + + if(wrapper_conversion_code) + Printv(f_wrappers,wrapper_conversion_code,NIL); + + Printf(f_wrappers,"#ifdef __cplusplus\n"); + Printf(f_wrappers,"}\n"); + Printf(f_wrappers,"#endif\n"); + + // Output a Java class for each SWIG type + for (String *swig_type = Firstkey(swig_types_hash); swig_type; swig_type = Nextkey(swig_types_hash)) { + emitJavaClass(swig_type, Getattr(swig_types_hash, swig_type)); + } + + Delete(swig_types_hash); swig_types_hash = NULL; + Delete(jniclass_name); jniclass_name = NULL; + Delete(jniclass_class_code); jniclass_class_code = NULL; + Delete(shadow_classdef); shadow_classdef = NULL; + Delete(shadow_code); shadow_code = NULL; + Delete(module_constants_code); module_constants_code = NULL; + Delete(jniclass_baseclass); jniclass_baseclass = NULL; + Delete(jniclass_interfaces); jniclass_interfaces = NULL; + Delete(jniclass_class_modifiers); jniclass_class_modifiers = NULL; + Delete(module_class_name); module_class_name = NULL; + Delete(module_class_code); module_class_code = NULL; + Delete(module_baseclass); module_baseclass = NULL; + Delete(module_interfaces); module_interfaces = NULL; + Delete(module_imports); module_imports = NULL; + Delete(module_class_modifiers); module_class_modifiers = NULL; + Delete(jniclass_imports); jniclass_imports = NULL; + Delete(jniclass_cppcasts_code); jniclass_cppcasts_code = NULL; + Delete(wrapper_conversion_code); wrapper_conversion_code = NULL; + Delete(package); package = NULL; + Delete(jnipackage); jnipackage = NULL; + + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * emitBanner() + * ----------------------------------------------------------------------------- */ + + void emitBanner(File *f) { + Printf(f, "/* ----------------------------------------------------------------------------\n"); + Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n"); + Printf(f, " * Version: %s\n", SWIG_VERSION); + Printf(f, " *\n"); + Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n"); + Printf(f, " * the SWIG interface file instead.\n"); + Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); + } + + /* ---------------------------------------------------------------------- + * nativeWrapper() + * ---------------------------------------------------------------------- */ + + virtual int nativeWrapper(Node *n) { + String *wrapname = Getattr(n,"wrap:name"); + + if (!addSymbol(wrapname,n)) return SWIG_ERROR; + + if (Getattr(n,"type")) { + Swig_save(&n,"name",NIL); + Setattr(n,"name", wrapname); + native_function_flag = true; + functionWrapper(n); + Swig_restore(&n); + native_function_flag = false; + } else { + Printf(stderr,"%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n,"wrap:name")); + } + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * functionWrapper() + * ---------------------------------------------------------------------- */ + + virtual int functionWrapper(Node *n) { + String *symname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + String *tm; + Parm *p; + int i; + String *jnirettype = NewString(""); + String *javarettype = NewString(""); + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *body = NewString(""); + String *javaParameterSignature = NewString(""); + int num_arguments = 0; + int num_required = 0; + bool is_void_return; + String *overloaded_name = getOverloadedName(n); + + if (!Getattr(n,"sym:overloaded")) { + if (!addSymbol(Getattr(n,"sym:name"),n)) return SWIG_ERROR; + } + + /* + Generate the java class wrapper function ie the java shadow class. Only done for public + member variables. That is this generates the getters/setters for member variables. + Not for enums and constants. + */ + if(proxy_flag && wrapping_member_flag && !enum_constant_flag) { + // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name + String *getter_setter_name = NewString(""); + if(Cmp(symname, Swig_name_set(Swig_name_member(shadow_classname, variable_name))) == 0) + Printf(getter_setter_name,"set"); + else + Printf(getter_setter_name,"get"); + Putc(toupper((int) *Char(variable_name)), getter_setter_name); + Printf(getter_setter_name, "%s", Char(variable_name)+1); + + Setattr(n,"java:shadowfuncname", getter_setter_name); + Setattr(n,"java:funcname", symname); + + javaShadowFunctionHandler(n); + + Delete(getter_setter_name); + } + + /* + The rest of this function deals with generating the java wrapper function (that wraps + a c/c++ function) and generating the JNI c code. Each java wrapper function has a + matching JNI c function call. + */ + + // A new wrapper function object + Wrapper *f = NewWrapper(); + + // Make a wrapper name for this function + String *jniname = makeValidJniName(overloaded_name); + String *wname = Swig_name_wrapper(jniname); + Delete(jniname); + + /* Attach the non-standard typemaps to the parameter list. */ + Swig_typemap_attach_parms("jni", l, f); + Swig_typemap_attach_parms("jtype", l, f); + + /* Get Java return types */ + if ((tm = Swig_typemap_lookup_new("jni",n,"",0))) { + Printf(jnirettype,"%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, + "No jni typemap defined for %s\n", SwigType_str(t,0)); + } + + if ((tm = Swig_typemap_lookup_new("jtype",n,"",0))) { + Printf(javarettype,"%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, + "No jtype typemap defined for %s\n", SwigType_str(t,0)); + } + + is_void_return = (Cmp(jnirettype, "void") == 0); + if (!is_void_return) + Wrapper_add_localv(f,"jresult", jnirettype, "jresult = 0",NIL); + + Printf(jniclass_class_code, " public final static native %s %s(", javarettype, overloaded_name); + + Printv(f->def, "JNIEXPORT ", jnirettype, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL); + + // Usually these function parameters are unused - The code below ensures that compilers do not issue such a warning if configured to do so. + Printv(f->code," (void)jenv;\n",NIL); + Printv(f->code," (void)jcls;\n",NIL); + + // Emit all of the local variables for holding arguments. + emit_args(t,l,f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + + /* Get number of required and total arguments */ + num_arguments = emit_num_arguments(l); + num_required = emit_num_required(l); + + int gencomma = 0; + + // Now walk the function parameter list and generate code to get arguments + for (i = 0, p=l; i < num_arguments; i++) { + + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + String *javaparamtype = NewString(""); + String *jni_param_type = NewString(""); + String *arg = NewString(""); + + Printf(arg,"j%s", ln); + + /* Get the jni types of the parameter */ + if ((tm = Getattr(p,"tmap:jni"))) { + Printv(jni_param_type, tm, NIL); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, + "No jni typemap defined for %s\n", SwigType_str(pt,0)); + } + + /* Get the java types of the parameter */ + if ((tm = Getattr(p,"tmap:jtype"))) { + Printv(javaparamtype, tm, NIL); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, + "No jtype typemap defined for %s\n", SwigType_str(pt,0)); + } + + /* Add to java function header */ + if(gencomma) Printf(jniclass_class_code, ", "); + Printf(jniclass_class_code, "%s %s", javaparamtype, arg); gencomma = 1; // Add to Jni function header - Printv(f->def, ", ", jnitype, " ", source, 0); + Printv(f->def, ", ", jni_param_type, " ", arg, NIL); // Get typemap for this argument - tm = typemap_lookup((char*)"in",typemap_lang,pt,pn,source,target,f); - if (tm) { - Printf(f->code,"%s\n", tm); - Replace(f->code,"$arg",source, DOH_REPLACE_ANY); + if ((tm = Getattr(p,"tmap:in"))) { + addThrows(n, "tmap:in", p); + Replaceall(tm,"$source",arg); /* deprecated */ + Replaceall(tm,"$target",ln); /* deprecated */ + Replaceall(tm,"$arg",arg); /* deprecated? */ + Replaceall(tm,"$input", arg); + Setattr(p,"emit:input", arg); + Printf(f->code,"%s\n", tm); + p = Getattr(p,"tmap:in:next"); } else { - if(!DataType_is_pointer(pt)) - Printv(f->code, tab4, target, " = (", DataType_lstr(pt,0), ") ", source, ";\n", 0); - else if((DataType_Gettypecode(pt) == T_VOID && (DataType_is_pointer(pt) == 1)) || - (DataType_Gettypecode(pt) == T_USER && (DataType_is_pointer(pt) == 1))) { - DataType_add_pointer(pt); - Printv(f->code, tab4, target, " = *(", DataType_lstr(pt,0), ")&", source, ";\n", 0); - DataType_del_pointer(pt); - } else { - if(DataType_type(pt) == T_STRING) { - Printv(f->code, tab4, target, " = (", source, ") ? (char *)", JNICALL((char*)"GetStringUTFChars"), source, ", 0) : NULL;\n", 0); - } else { - char *scalarType = SwigTcToJniScalarType(pt); + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); + p = nextSibling(p); + } + Delete(javaparamtype); + Delete(jni_param_type); + Delete(arg); + } - DataType_del_pointer(pt); - const char *basic_jnitype = (DataType_is_pointer(pt) > 0) ? "jlong" : SwigTcToJniType(pt, 0); - char *ctype = DataType_lstr(pt,0); - if(scalarType == NULL || basic_jnitype == NULL) { - Printf(stderr, "\'%s\' does not have a in/jni typemap, and is not a basic type.\n", ctype); - SWIG_exit(1); - }; - DataType_add_pointer(pt); + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + addThrows(n, "tmap:check", p); + Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */ + Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } - DOHString *basic_jniptrtype = NewStringf("%s*",basic_jnitype); - DOHString *source_length = NewStringf("%s%s)", JNICALL((char*)"GetArrayLength"), source); + /* Insert cleanup code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:freearg"))) { + addThrows(n, "tmap:freearg", p); + Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */ + Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } - target_copy = Swig_copy_string(Wrapper_new_localv(f,target,Char(basic_jniptrtype), target, 0)); - target_length = Swig_copy_string(Wrapper_new_localv(f,target,"jsize", target, "=", Char(source_length),0)); - if(local_i == NULL) local_i = Swig_copy_string(Wrapper_new_local(f,"i","int i")); + /* Insert argument output code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:argout"))) { + addThrows(n, "tmap:argout", p); + Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */ + Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */ + Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ + Replaceall(tm,"$result","jresult"); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } - DOHString *scalarFunc = NewStringf("Get%sArrayElements",scalarType); + // Get any Java exception classes in the throw typemap + if (ParmList *throw_parm_list = Getattr(n,"throws")) { + Swig_typemap_attach_parms("throws", throw_parm_list, f); + for (p = throw_parm_list; p; p=nextSibling(p)) { + if ((tm = Getattr(p,"tmap:throws"))) { + addThrows(n, "tmap:throws", p); + } + } + } - Printv(f->code, tab4, target_copy, " = ", JNICALL(scalarFunc), source, ", 0);\n", 0); - Printv(f->code, tab4, target, " = (", DataType_lstr(pt,0), ") malloc(", target_length, " * sizeof(", ctype, "));\n", 0); - Printv(f->code, tab4, "for(i=0; i<", target_length, "; i++)\n", 0); - if(DataType_is_pointer(pt) > 1) { - Printv(f->code, tab8, target, "[i] = *(", DataType_lstr(pt,0), ")&", target_copy, "[i];\n", 0); - } else { - DataType_del_pointer(pt); - Printv(f->code, tab8, target, "[i] = (", DataType_lstr(pt,0), ")", target_copy, "[i];\n", 0); - DataType_add_pointer(pt); - } - Delete(scalarFunc); - Delete(source_length); - Delete(basic_jniptrtype); + if (Cmp(nodeType(n), "constant") == 0) { + // Wrapping a constant hack + Swig_save(&n,"wrap:action",NIL); + + // below based on Swig_VargetToFunction() + SwigType *ty = Swig_wrapped_var_type(Getattr(n,"type")); + Setattr(n,"wrap:action", NewStringf("result = (%s) %s;\n", SwigType_lstr(ty,0), Getattr(n, "value"))); + } + + // Now write code to make the function call + if(!native_function_flag) + emit_action(n,f); + + if (Cmp(nodeType(n), "constant") == 0) + Swig_restore(&n); + + /* Return value if necessary */ + if(!native_function_flag) { + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + addThrows(n, "tmap:out", n); + Replaceall(tm,"$source", "result"); /* deprecated */ + Replaceall(tm,"$target", "jresult"); /* deprecated */ + Replaceall(tm,"$result","jresult"); + Printf(f->code,"%s", tm); + if (Len(tm)) + Printf(f->code,"\n"); + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s in function %s.\n", SwigType_str(t,0), Getattr(n,"name")); + } + } + + /* Output argument output code */ + Printv(f->code,outarg,NIL); + + /* Output cleanup code */ + Printv(f->code,cleanup,NIL); + + /* Look to see if there is any newfree cleanup code */ + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); /* deprecated */ + Printf(f->code,"%s\n",tm); + } + } + + /* See if there is any return cleanup code */ + if(!native_function_flag) { + if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { + Replaceall(tm,"$source","result"); /* deprecated */ + Printf(f->code,"%s\n",tm); + } + } + + /* Finish JNI C function and JNI class native function definitions */ + Printf(jniclass_class_code, ")"); + generateThrowsClause(n, jniclass_class_code); + Printf(jniclass_class_code, ";\n"); + Printf(f->def,") {"); + + if(!is_void_return) + Printv(f->code, " return jresult;\n", NIL); + Printf(f->code, "}\n"); + + /* Substitute the cleanup code */ + Replaceall(f->code,"$cleanup",cleanup); + + if(!is_void_return) + Replaceall(f->code,"$null","0"); + else + Replaceall(f->code,"$null",""); + + /* Dump the function out */ + if(!native_function_flag) + Wrapper_print(f,f_wrappers); + + Setattr(n,"wrap:name", wname); + + /* Emit warnings for the few cases that can't be overloaded in Java */ + if (Getattr(n,"sym:overloaded")) { + if (!Getattr(n,"sym:nextSibling")) + Swig_overload_rank(n); + } + + if(!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) { + moduleClassFunctionHandler(n); + } + + Delete(jnirettype); + Delete(javarettype); + Delete(cleanup); + Delete(outarg); + Delete(body); + Delete(javaParameterSignature); + Delete(overloaded_name); + DelWrapper(f); + return SWIG_OK; + } + + /* ----------------------------------------------------------------------- + * variableWrapper() + * + * Create a JAVA link to a C variable. + * ----------------------------------------------------------------------- */ + + virtual int variableWrapper(Node *n) { + Language::variableWrapper(n); /* Default to functions */ + return SWIG_OK; + } + + /* ----------------------------------------------------------------------- + * globalvariableHandler() + * ------------------------------------------------------------------------ */ + + virtual int globalvariableHandler(Node *n) { + + variable_name = Getattr(n,"sym:name"); + global_variable_flag = true; + int ret = Language::globalvariableHandler(n); + global_variable_flag = false; + return ret; + } + + /* ----------------------------------------------------------------------- + * constantWrapper() + * ------------------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + String *symname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + String *tm; + String *shadowrettype = NewString(""); + String *constants_code = NewString(""); + + if (!addSymbol(symname,n)) return SWIG_ERROR; + + /* Attach the non-standard typemaps to the parameter list. */ + Swig_typemap_attach_parms("jstype", l, NULL); + + /* Get Java return types */ + bool is_return_type_java_class = false; + if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) { + is_return_type_java_class = substituteJavaclassname(t, tm); + Printf(shadowrettype, "%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, + "No jstype typemap defined for %s\n", SwigType_str(t,0)); + } + + // Add the stripped quotes back in + String *new_value = NewString(""); + Swig_save(&n,"value",NIL); + if(SwigType_type(t) == T_STRING) { + Printf(new_value, "\"%s\"", Copy(Getattr(n, "value"))); + Setattr(n, "value", new_value); + } + else if(SwigType_type(t) == T_CHAR) { + Printf(new_value, "\'%s\'", Copy(Getattr(n, "value"))); + Setattr(n, "value", new_value); + } + + // enums are wrapped using a public final static int in java. + // Other constants are wrapped using a public final static [jstype] in Java. + Printf(constants_code, " public final static %s %s = ", shadowrettype, ((proxy_flag && wrapping_member_flag) ? variable_name : symname)); + + // The %javaconst directive determines how the constant value is obtained + String *javaconst = Getattr(n,"feature:java:const"); + if (Cmp(nodeType(n), "enumitem") == 0 || !javaconst || Cmp(javaconst, "0") == 0) { + // Enums and default constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call. + + if(is_return_type_java_class) // This handles function pointers using the %constant directive + Printf(constants_code, "new %s(%s.%s(), false);\n", shadowrettype, jniclass_name, Swig_name_get(symname)); + else + Printf(constants_code, "%s.%s();\n", jniclass_name, Swig_name_get(symname)); + + // Each constant and enum value is wrapped with a separate JNI function call + enum_constant_flag = true; + variableWrapper(n); + enum_constant_flag = false; + } else { + // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code + Printf(constants_code, "%s;\n", Getattr(n,"value")); + } + + if(proxy_flag && wrapping_member_flag) + Printv(shadow_constants_code, constants_code, NIL); + else + Printv(module_constants_code, constants_code, NIL); + + Swig_restore(&n); + Delete(new_value); + Delete(shadowrettype); + Delete(constants_code); + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * pragmaDirective() + * + * Valid Pragmas: + * jniclassbase - base (extends) for the JNI class + * jniclassclassmodifiers - class modifiers for the JNI class + * jniclasscode - text (java code) is copied verbatim to the JNI class + * jniclassimports - import statements for the JNI class + * jniclassinterfaces - interface (implements) for the JNI class + * + * modulebase - base (extends) for the module class + * moduleclassmodifiers - class modifiers for the module class + * modulecode - text (java code) is copied verbatim to the module class + * moduleimports - import statements for the module class + * moduleinterfaces - interface (implements) for the module class + * + * ----------------------------------------------------------------------------- */ + + virtual int pragmaDirective(Node *n) { + if (!ImportMode) { + String *lang = Getattr(n,"lang"); + String *code = Getattr(n,"name"); + String *value = Getattr(n,"value"); + + if(Strcmp(lang, "java") == 0) { + + String *strvalue = NewString(value); + Replaceall(strvalue,"\\\"", "\""); + + if(Strcmp(code, "jniclassbase") == 0) { + Delete(jniclass_baseclass); + jniclass_baseclass = Copy(strvalue); + } + else if(Strcmp(code, "jniclassclassmodifiers") == 0) { + Delete(jniclass_class_modifiers); + jniclass_class_modifiers = Copy(strvalue); + } + else if(Strcmp(code, "jniclasscode") == 0) { + Printf(jniclass_class_code, "%s\n", strvalue); + } + else if(Strcmp(code, "jniclassimports") == 0) { + Delete(jniclass_imports); + jniclass_imports = Copy(strvalue); + } + else if(Strcmp(code, "jniclassinterfaces") == 0) { + Delete(jniclass_interfaces); + jniclass_interfaces = Copy(strvalue); + } + else if(Strcmp(code, "modulebase") == 0) { + Delete(module_baseclass); + module_baseclass = Copy(strvalue); + } + else if(Strcmp(code, "moduleclassmodifiers") == 0) { + Delete(module_class_modifiers); + module_class_modifiers = Copy(strvalue); + } + else if(Strcmp(code, "modulecode") == 0) { + Printf(module_class_code, "%s\n", strvalue); + } + else if(Strcmp(code, "moduleimports") == 0) { + Delete(module_imports); + module_imports = Copy(strvalue); + } + else if(Strcmp(code, "moduleinterfaces") == 0) { + Delete(module_interfaces); + module_interfaces = Copy(strvalue); + } + else if(Strcmp(code, "moduleimport") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use the moduleimports pragma.\n", input_file, line_number); + } + else if(Strcmp(code, "moduleinterface") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use the moduleinterfaces pragma.\n", input_file, line_number); + } + else if(Strcmp(code, "modulemethodmodifiers") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %javamethodmodifiers.\n", input_file, line_number); + } + else if(Strcmp(code, "allshadowimport") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaimports).\n", input_file, line_number); + } + else if(Strcmp(code, "allshadowcode") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javacode).\n", input_file, line_number); + } + else if(Strcmp(code, "allshadowbase") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javabase).\n", input_file, line_number); + } + else if(Strcmp(code, "allshadowinterface") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javainterfaces).\n", input_file, line_number); + } + else if(Strcmp(code, "allshadowclassmodifiers") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaclassmodifiers).\n", input_file, line_number); + } + else if (proxy_flag) { + if (Strcmp(code,"shadowcode") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javacode).\n", input_file, line_number); + } + else if (Strcmp(code,"shadowimport") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaimports).\n", input_file, line_number); + } + else if (Strcmp(code,"shadowbase") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javabase).\n", input_file, line_number); + } + else if (Strcmp(code,"shadowinterface") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javainterfaces).\n", input_file, line_number); + } + else if (Strcmp(code,"shadowclassmodifiers") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaclassmodifiers).\n", input_file, line_number); + } else { + Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } - } - } - - // Check to see if there was any sort of a constaint typemap - if ((tm = typemap_lookup((char*)"check",typemap_lang,pt,pn,source,target))) { - // Yep. Use it instead of the default - Printf(f->code,"%s\n", tm); - Replace(f->code,"$arg",source, DOH_REPLACE_ANY); - } - - // Check if there was any cleanup code (save it for later) - if ((tm = typemap_lookup((char*)"freearg",typemap_lang,pt,pn,source,target))) { - // Yep. Use it instead of the default - Printf(cleanup,"%s\n", tm); - Replace(cleanup,"$arg",source, DOH_REPLACE_ANY); - } - - if ((tm = typemap_lookup((char*)"argout",typemap_lang,pt,pn,source,target))) { - // Yep. Use it instead of the default - Printf(outarg,"%s\n", tm); - Replace(outarg,"$arg",source, DOH_REPLACE_ANY); - } else { - // if(pt->is_pointer && pt->type != T_USER && pt->type != T_VOID) { - if(DataType_is_pointer(pt)) { - if(DataType_type(pt) == T_STRING) { - Printv(outarg, tab4, "if(", target,") ", JNICALL((char*)"ReleaseStringUTFChars"), source, ", ", target, ");\n", 0); - } else if(((DataType_Gettypecode(pt) == T_VOID) && DataType_is_pointer(pt) == 1) || - ((DataType_Gettypecode(pt) == T_USER) && DataType_is_pointer(pt) == 1)) { - // nothing to do - } else { - char *scalarType = SwigTcToJniScalarType(pt); - - DataType_del_pointer(pt); - const char *basic_jnitype = (DataType_is_pointer(pt) > 0) ? "jlong" : SwigTcToJniType(pt, 0); - char *ctype = DataType_lstr(pt,0); - if(scalarType == NULL || basic_jnitype == NULL) { - Printf(stderr, "\'%s\' does not have a argout/jni typemap, and is not a basic type.\n", ctype); - SWIG_exit(1); - }; - DataType_add_pointer(pt); - Printf(outarg, " for(i=0; i< %d; i++)\n", target_length); - if(DataType_is_pointer(pt) > 1) { - Printv(outarg, tab8, "*(", DataType_lstr(pt,0), ")&", target_copy, "[i] = ", target, "[i];\n", 0); - } else { - Printv(outarg, tab8, target_copy, "[i] = (", basic_jnitype, ") ", target, "[i];\n", 0); - } - DOHString *scalarFunc = NewStringf("Release%sArrayElements",scalarType); - Printv(outarg, tab4, JNICALL(scalarFunc), source, ", ", target_copy, ", 0);\n", 0); - Printv(outarg, tab4, "free(", target, ");\n", 0); - Delete(scalarFunc); - free(target_copy); - free(target_length); - free(local_i); - } - } - } - } - - Printf(f_java, ");\n"); - if(shadow && member_func) { - Printf(f_shadow, ") {\n"); - Printf(body,")"); - Printf(f_shadow, "%s;\n }\n\n",body); - } - Printf(f->def,") {"); - - // Now write code to make the function call - - if(!native_func) - emit_func_call(name,t,l,f); - - // Return value if necessary - - if((DataType_type(t) != T_VOID) && !native_func) { - if ((tm = typemap_lookup((char*)"out",typemap_lang,t,iname,(char*)"result",(char*)"_jresult"))) { - Printf(f->code,"%s\n", tm); - } else { - if(DataType_type(t) == T_USER) { /* return by value */ - DataType_add_pointer(t); - DataType_add_pointer(t); - Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0); - DataType_del_pointer(t); - DataType_del_pointer(t); - } else if(DataType_is_pointer(t) == 0 && (DataType_Gettypecode(t) != T_USER)) { - Printv(f->code, tab4, "_jresult = (", jnirettype, ") result;\n", 0); - } else if(((DataType_Gettypecode(t) == T_VOID) && DataType_is_pointer(t) == 1) || - ((DataType_Gettypecode(t) == T_USER) && DataType_is_pointer(t) == 1)) { - DataType_add_pointer(t); - Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0); - DataType_del_pointer(t); - } else { - if(DataType_type(t) == T_STRING) { - Printv(f->code, tab4, "if(result != NULL)\n", 0); - Printv(f->code, tab8, "_jresult = (jstring)", JNICALL((char*)"NewStringUTF"), "result);\n", 0); } else { - Printf(stderr,"%s : Line %d. Warning: no return typemap for datatype %s\n", input_file,line_number,DataType_str(t,0)); - DataType_add_pointer(t); - Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0); - DataType_del_pointer(t); + Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } + Delete(strvalue); } } + return Language::pragmaDirective(n); } - // Dump argument output code; - Printv(f->code, outarg, 0); + /* ----------------------------------------------------------------------------- + * emitShadowClassDefAndCPPCasts() + * ----------------------------------------------------------------------------- */ - // Dump the argument cleanup code - Printv(f->code,cleanup, 0); + void emitShadowClassDefAndCPPCasts(Node *n) { + String *c_classname = SwigType_namestr(Getattr(n,"name")); + String *c_baseclass = NULL; + String *baseclass = NULL; + String *c_baseclassname = NULL; - // Look for any remaining cleanup - - if (NewObject) { - if ((tm = typemap_lookup((char*)"newfree",typemap_lang,t,iname,(char*)"result",(char*)""))) { - Printf(f->code,"%s\n", tm); - } - } - - if((DataType_type(t) != T_VOID) && !native_func) { - if ((tm = typemap_lookup((char*)"ret",typemap_lang,t,iname,(char*)"result",(char*)"_jresult", NULL))) { - Printf(f->code,"%s\n", tm); - } - } - - // Wrap things up (in a manner of speaking) - if(DataType_type(t) != T_VOID) - Printv(f->code, tab4, "return _jresult;\n", 0); - Printf(f->code, "}\n"); - - // Substitute the cleanup code (some exception handlers like to have this) - Replace(f->code,"$cleanup",cleanup, DOH_REPLACE_ANY); - - // Emit the function - - if(!native_func) - Wrapper_print(f,f_wrappers); - - // If registerNatives is active, store the table entry for this method - if (useRegisterNatives) { - Printv(registerNativesList, - tab4, "{", - "\"", name, "\", \"(", javaParameterSignature, ")", javaReturnSignature, "\", ", wname, - "},\n", - 0); - - } - - Delete(cleanup); - Delete(outarg); - Delete(body); - Delete(javaParameterSignature); - DelWrapper(f); -} - -// ----------------------------------------------------------------------- -// JAVA::link_variable(char *name, char *iname, DataType *t) -// -// Create a JAVA link to a C variable. -// ----------------------------------------------------------------------- - -void JAVA::link_variable(char *name, char *iname, DataType *t) -{ - emit_set_get(name,iname, t); -} - -// ----------------------------------------------------------------------- -// JAVA::declare_const(char *name, char *iname, DataType *type, char *value) -// ------------------------------------------------------------------------ - -void JAVA::declare_const(char *name, char *iname, DataType *type, char *value) { - char *tm; - FILE *jfile; - char *jname; - - if(!classdef_emitted) emit_classdef(); - - if(shadow && member_func) { - jfile = f_shadow; - jname = shadow_name; - } else { - jfile = f_java; - jname = name; - } - - if ((tm = typemap_lookup((char*)"const",typemap_lang,type,name,name,iname))) { - DOHString *str = NewString(tm); - Replace(str,"$value",value, DOH_REPLACE_ANY); - Printf(jfile," %s\n\n", str); - Delete(str); - } else { - if((DataType_is_pointer(type) == 0)) { - char *jtype = typemap_lookup((char*)"jtype", typemap_lang, type, name, name, iname); - if(!jtype) jtype = SwigTcToJavaType(type, 0, 0); - if(strcmp(jname, value) == 0 || strstr(value,"::") != NULL) { - Printf(stderr, "ignoring enum constant: %s\n", jname); - } else - Printf(jfile, " public final static %s %s = %s;\n\n", jtype, jname, value); - } else { - if(DataType_type(type) == T_STRING) { - Printf(jfile, " public final static String %s = \"%s\";\n\n", jname, value); - } else { - emit_set_get(name,iname, type); + /* Deal with inheritance */ + List *baselist = Getattr(n,"bases"); + if (baselist) { + Node *base = Firstitem(baselist); + c_baseclassname = Getattr(base,"name"); + baseclass = Copy(is_shadow(c_baseclassname)); + if (baseclass){ + c_baseclass = SwigType_namestr(Getattr(base,"name")); + } + base = Nextitem(baselist); + if (base) { + Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, + "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Java.\n", shadow_classname, Getattr(base,"name")); } } - } -} -void emit_shadow_banner(FILE *f) { - Printf(f, "/*\n"); - Printf(f, " *\n"); - Printf(f, " * This file was automatically generated by :\n"); - Printf(f, " * Simplified Wrapper and Interface Generator (SWIG)\n"); - Printf(f, " * Version: %s\n", SWIG_VERSION); - Printf(f, " *\n"); - Printf(f, " * Portions Copyright (c) 1995-1997\n"); - Printf(f, " * The University of Utah and The Regents of the University of California.\n"); - Printf(f, " * Permission is granted to distribute this file in any manner provided\n"); - Printf(f, " * this notice remains intact.\n"); - Printf(f, " *\n"); - Printf(f, " * Portions Copyright (c) 1997-1999\n"); - Printf(f, " * Harco de Hilster, Harco.de.Hilster@ATConsultancy.nl\n"); - Printf(f, " *\n"); - Printf(f, " * Do not make changes to this file--changes will be lost!\n"); - Printf(f, " *\n"); - Printf(f, " */\n\n\n"); -} + bool derived = baseclass && is_shadow(c_baseclassname); + if (!baseclass) + baseclass = NewString(""); -void JAVA::pragma(char *lang, char *code, char *value) { - if(strcmp(lang, "java") != 0) return; - - DOHString *s = NewString(value); - Replace(s,"\\\"", "\"", DOH_REPLACE_ANY); - if(strcmp(code, "import") == 0) { - jimport = Swig_copy_string(Char(s)); - Printf(f_java, "// pragma\nimport %s;\n\n", jimport); - } else if(strcmp(code, "module") == 0) { - if(!classdef_emitted) emit_classdef(); - Printf(f_java, "// pragma\n"); - Printf(f_java, "%s", s); - Printf(f_java, "\n\n"); - } else if(strcmp(code, "shadow") == 0) { - if(shadow && f_shadow) { - Printf(f_shadow, "// pragma\n"); - Printf(f_shadow, "%s", s); - Printf(f_shadow, "\n\n"); + // Inheritance from pure Java classes + const String *pure_java_baseclass = javaTypemapLookup("javabase", shadow_classname, WARN_NONE); + if (Len(pure_java_baseclass) > 0 && Len(baseclass) > 0) { + Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, + "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Java.\n", shadow_classname, pure_java_baseclass); } - } else if(strcmp(code, "modifiers") == 0) { - method_modifiers = Swig_copy_string(value); - } else { - Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number); - } - Delete(s); -} -// --------------------------------------------------------------------- -// C++ Handling -// -// The following functions provide some support for C++ classes and -// C structs. -// --------------------------------------------------------------------- - -void JAVA::add_typedef(DataType *t, char *name) { - if(!shadow) return; - - // First check to see if there aren't too many pointers - - if (DataType_is_pointer(t) > 1) return; - - if(Getattr(shadow_classes,name)) return; // Already added - - // Now look up the datatype in our shadow class hash table - - if (Getattr(shadow_classes,DataType_Getname(t))) { - - // Yep. This datatype is in the hash - // Put this types 'new' name into the hash - Setattr(shadow_classes,name,GetChar(shadow_classes,DataType_Getname(t))); - } -} - -void JAVA::cpp_open_class(char *classname, char *rename, char *ctype, int strip) { - - this->Language::cpp_open_class(classname,rename,ctype,strip); - - if(!shadow) return; - - if(rename) - shadow_classname = Swig_copy_string(rename); - else shadow_classname = Swig_copy_string(classname); - - if (strcmp(shadow_classname, module) == 0) { - Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname); - SWIG_exit(1); - } - - Setattr(shadow_classes,classname, shadow_classname); - if(ctype && strcmp(ctype, "struct") == 0) { - sprintf(bigbuf, "struct %s", classname); - Setattr(shadow_classes, bigbuf, shadow_classname); - } - - sprintf(bigbuf, "%s.java", shadow_classname); - if(!(f_shadow = fopen(bigbuf, "w"))) { - Printf(stderr, "Unable to create shadow class file: %s\n", bigbuf); - } - - emit_shadow_banner(f_shadow); - - if(*package) - Printf(f_shadow, "package %s;\n\n", package); - else Printf(f_shadow, "import %s;\n\n", module); - if(jimport != NULL) - Printf(f_shadow, "import %s;\n\n", jimport); - - Clear(shadow_classdef); - Printv(shadow_classdef, "public class ", shadow_classname, " %BASECLASS% ", "{\n", 0); - - shadow_baseclass = (char*) ""; - shadow_classdef_emitted = 0; - have_default_constructor = 0; -} - -void JAVA::emit_shadow_classdef() { - if(*shadow_baseclass) { - sprintf(bigbuf, "extends %s", shadow_baseclass); - Replace(shadow_classdef,"%BASECLASS%", bigbuf, DOH_REPLACE_ANY); - Printv(shadow_classdef, " public ", shadow_classname, "(java.lang.Long obj) {\n", tab4, "_self = obj.longValue();\n }\n\n", 0); - } else { - Replace(shadow_classdef,"%BASECLASS%", "",DOH_REPLACE_ANY); + // Pure Java interfaces + const String *pure_java_interfaces = javaTypemapLookup("javainterfaces", shadow_classname, WARN_NONE); + // Start writing the shadow class Printv(shadow_classdef, - " public long _self = 0;\n", - " public boolean _selfown = false;\n\n", - " public static Object newInstance(long p) {\n", - " return new ", shadow_classname, "(new Long(p));\n", - " };\n\n", + javaTypemapLookup("javaimports", shadow_classname, WARN_NONE), // Import statements + "\n", + javaTypemapLookup("javaclassmodifiers", shadow_classname, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers + " class $javaclassname", // Class name and bases + (derived || *Char(pure_java_baseclass)) ? + " extends " : + "", + baseclass, + pure_java_baseclass, + *Char(pure_java_interfaces) ? // Pure Java interfaces + " implements " : + "", + pure_java_interfaces, + " {\n", + " private long swigCPtr;\n", // Member variables for memory handling + derived ? + "" : + " protected boolean swigCMemOwn;\n", + "\n", + " ", + javaTypemapLookup("javaptrconstructormodifiers", shadow_classname, WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers + " $javaclassname(long cPtr, boolean cMemoryOwn) {\n", // Constructor used for wrapping pointers + derived ? + " super($jniclassname.SWIG$javaclassnameTo$baseclass(cPtr), cMemoryOwn);\n" : + " swigCMemOwn = cMemoryOwn;\n", + " swigCPtr = cPtr;\n", + " }\n", + NIL); - " public ", shadow_classname, "(java.lang.Long obj) {\n", tab4, "_self = obj.longValue();\n }\n\n", - 0); - } - Printv(shadow_classdef, " public Class _selfClass() {\n", tab4, "return ", shadow_classname, ".class;\n", " };\n\n", 0); - - Printv(f_shadow, shadow_classdef,0); - shadow_classdef_emitted = 1; -} - -void JAVA::cpp_close_class() { - this->Language::cpp_close_class(); - if(!shadow) return; - - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - if(have_default_constructor == 0) { - Printf(f_shadow, " public %s() {}\n\n", shadow_classname); - } - - Printf(f_shadow, "}\n"); - fclose(f_shadow); - f_shadow = NULL; - - free(shadow_classname); - shadow_classname = NULL; -} - -void JAVA::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { - char arg[256]; - DOHString *nativecall; - - nativecall = NewString(""); - - this->Language::cpp_member_func(name,iname,t,l); - - if(!shadow) return; - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname); - if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0); - char *shadowrettype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, t, iname); - if(!shadowrettype && (DataType_Gettypecode(t) == T_USER) && DataType_is_pointer(t) <= 1) { - shadowrettype = GetChar(shadow_classes,DataType_Getname(t)); - } - - Printf(f_shadow, " public %s %s(", (shadowrettype) ? shadowrettype : javarettype, iname); - - if(DataType_type(t) != T_VOID) { - Printf(nativecall,"return "); - if(shadowrettype) { - Printv(nativecall, "new ", shadowrettype, "(new Long(", 0); - } - } - Printv(nativecall, module, ".", Swig_name_member(shadow_classname,iname), "(_self", 0); - - int pcount = ParmList_len(l); - - Parm *p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - - // Produce string representation of source and target arguments - if(pn && *(pn)) - strcpy(arg,pn); - else { - sprintf(arg,"arg%d",i); + if(!have_default_constructor_flag) { // All Java classes need a constructor + Printv(shadow_classdef, + "\n", + " protected $javaclassname() {\n", + " this(0, false);\n", + " }\n", + NIL); } - if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) { - Printv(nativecall, ", ", arg, "._self", 0); - } else Printv(nativecall, ", ", arg, 0); + Printv(shadow_classdef, + javaTypemapLookup("javafinalize", shadow_classname, WARN_NONE), // finalize method + "\n", + *Char(destructor_call) ? + " public void delete() {\n" : + " protected void delete() {\n", + " if(swigCPtr != 0 && swigCMemOwn) {\n", + destructor_call, + "", + " swigCMemOwn = false;\n", + derived ? // Zero all pointers up any inheritance hierarchy + " super.delete();\n" : + "", + " }\n", + " swigCPtr = 0;\n", + " }\n", + javaTypemapLookup("javagetcptr", shadow_classname, WARN_JAVA_TYPEMAP_GETCPTR_UNDEF), // getCPtr method + javaTypemapLookup("javacode", shadow_classname, WARN_NONE), // extra Java code + "\n", + NIL); - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); + // Substitute various strings into the above template + Replaceall(shadow_code, "$javaclassname", shadow_classname); + Replaceall(shadow_classdef, "$javaclassname", shadow_classname); - char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn); - if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) { - jstype = GetChar(shadow_classes,DataType_Getname(pt)); + Replaceall(shadow_classdef, "$baseclass", baseclass); + Replaceall(shadow_code, "$baseclass", baseclass); + + Replaceall(shadow_classdef, "$jniclassname", jniclass_name); + Replaceall(shadow_code, "$jniclassname", jniclass_name); + + // Add JNI code to do C++ casting to base class (only for classes in an inheritance hierarchy) + if(derived){ + Printv(jniclass_cppcasts_code," public final static native long ", + "SWIG$javaclassnameTo$baseclass(long jarg1);\n", + NIL); + + Replaceall(jniclass_cppcasts_code, "$javaclassname", shadow_classname); + Replaceall(jniclass_cppcasts_code, "$baseclass", baseclass); + + Printv(wrapper_conversion_code, + "JNIEXPORT jlong JNICALL Java_$jnipackage$jnijniclass_SWIG$jniclazznameTo$jnibaseclass", + "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " *($cbaseclass **)&baseptr = *($cclass **)&jarg1;\n" + " return baseptr;\n" + "}\n", + "\n", + NIL); + + String *jnijniclass = makeValidJniName(jniclass_name); + String *jniclazzname = makeValidJniName(shadow_classname); + String *jnibaseclass = makeValidJniName(baseclass); + Replaceall(wrapper_conversion_code, "$jnibaseclass",jnibaseclass); + Replaceall(wrapper_conversion_code, "$cbaseclass", c_baseclass); + Replaceall(wrapper_conversion_code, "$jniclazzname",jniclazzname); + Replaceall(wrapper_conversion_code, "$cclass", c_classname); + Replaceall(wrapper_conversion_code, "$jnipackage", jnipackage); + Replaceall(wrapper_conversion_code, "$jnijniclass", jnijniclass); + + Delete(jnibaseclass); + Delete(jniclazzname); + Delete(jnijniclass); + } + Delete(baseclass); + } + + /* ---------------------------------------------------------------------- + * classHandler() + * ---------------------------------------------------------------------- */ + + virtual int classHandler(Node *n) { + + File *f_shadow = NULL; + if (proxy_flag) { + shadow_classname = NewString(Getattr(n,"sym:name")); + + if (!addSymbol(shadow_classname,n)) return SWIG_ERROR; + + if (Cmp(shadow_classname, jniclass_name) == 0) { + Printf(stderr, "Class name cannot be equal to JNI class name: %s\n", shadow_classname); + SWIG_exit(EXIT_FAILURE); } - // Add to java function header - Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg); - if(i != pcount-1) { - Printf(f_shadow, ", "); + if (Cmp(shadow_classname, module_class_name) == 0) { + Printf(stderr, "Class name cannot be equal to module class name: %s\n", shadow_classname); + SWIG_exit(EXIT_FAILURE); } + + String *filen = NewStringf("%s.java", shadow_classname); + f_shadow = NewFile(filen,"w"); + if(!f_shadow) { + Printf(stderr, "Unable to create proxy class file: %s\n", filen); + SWIG_exit(EXIT_FAILURE); + } + Delete(filen); filen = NULL; + + emitBanner(f_shadow); + + if(Len(package) > 0) + Printf(f_shadow, "package %s;\n\n", package); + + Clear(shadow_classdef); + Clear(shadow_code); + + have_default_constructor_flag = false; + destructor_call = NewString(""); + shadow_constants_code = NewString(""); + } + Language::classHandler(n); + + if (proxy_flag) { + + emitShadowClassDefAndCPPCasts(n); + + Printv(f_shadow, shadow_classdef, shadow_code, NIL); + + // Write out all the enums and constants + if (Len(shadow_constants_code) != 0 ) + Printv(f_shadow, " // enums and constants\n", shadow_constants_code, NIL); + + Printf(f_shadow, "}\n"); + Close(f_shadow); + f_shadow = NULL; + + Delete(shadow_classname); shadow_classname = NULL; + Delete(destructor_call); destructor_call = NULL; + Delete(shadow_constants_code); shadow_constants_code = NULL; + } + return SWIG_OK; } - if((DataType_Gettypecode(t) != T_VOID) && shadowrettype) - Printf(nativecall, "))"); + /* ---------------------------------------------------------------------- + * memberfunctionHandler() + * ---------------------------------------------------------------------- */ - Printf(nativecall,");\n"); + virtual int memberfunctionHandler(Node *n) { + Language::memberfunctionHandler(n); - Printf(f_shadow, ") {\n"); - Printf(f_shadow, "\t%s\n", nativecall); - Printf(f_shadow, " }\n\n"); - Delete(nativecall); - -} - -void JAVA::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) { - char arg[256]; - DOHString *nativecall; - - this->Language::cpp_static_func(name,iname,t,l); - - if(!shadow) return; - nativecall = NewString(""); - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname); - if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0); - char *shadowrettype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, t, iname); - if(!shadowrettype && (DataType_Gettypecode(t) == T_USER) && (DataType_is_pointer(t) <= 1)) { - shadowrettype = GetChar(shadow_classes,DataType_Getname(t)); + if (proxy_flag) { + String *overloaded_name = getOverloadedName(n); + String *java_function_name = Swig_name_member(shadow_classname, overloaded_name); + Setattr(n,"java:shadowfuncname", Getattr(n, "sym:name")); + Setattr(n,"java:funcname", java_function_name); + javaShadowFunctionHandler(n); + Delete(overloaded_name); + } + return SWIG_OK; } - Printf(f_shadow, " public static %s %s(", (shadowrettype) ? shadowrettype : javarettype, iname); + /* ---------------------------------------------------------------------- + * staticmemberfunctionHandler() + * ---------------------------------------------------------------------- */ - if(DataType_type(t) != T_VOID) { - Printf(nativecall, "return "); - if(shadowrettype) { - Printv(nativecall, "new ", shadowrettype, "(new Long(", 0); + virtual int staticmemberfunctionHandler(Node *n) { + + static_flag = true; + Language::staticmemberfunctionHandler(n); + + if (proxy_flag) { + String *overloaded_name = getOverloadedName(n); + String *java_function_name = Swig_name_member(shadow_classname, overloaded_name); + Setattr(n,"java:shadowfuncname", Getattr(n,"sym:name")); + Setattr(n,"java:funcname", java_function_name); + javaShadowFunctionHandler(n); + Delete(overloaded_name); } + static_flag = false; + + return SWIG_OK; } - Printv(nativecall, module, ".", Swig_name_member(shadow_classname,iname), "(", 0); - int pcount = ParmList_len(l); - int gencomma = 0; + /* ----------------------------------------------------------------------------- + * javaShadowFunctionHandler() + * + * Function called for creating a java class wrapper function around a c++ function in the + * java wrapper class. Used for both static and non static functions. + * C++ static functions map to java static functions. + * Two extra attributes in the Node must be available. These are "java:shadowfuncname" - the name of the java class shadow + * function, which in turn will call "java:funcname" - the java native function name which wraps the c++ function. + * ----------------------------------------------------------------------------- */ - Parm *p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); + void javaShadowFunctionHandler(Node *n) { + SwigType *t = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + String *java_function_name = Getattr(n,"java:funcname"); + String *java_shadow_function_name = Getattr(n,"java:shadowfuncname"); + String *tm; + Parm *p; + int i; + String *nativecall = NewString(""); + String *shadowrettype = NewString(""); + String *user_arrays = NewString(""); - // Produce string representation of source and target arguments - if(pn && *(pn)) - strcpy(arg,pn); - else { - sprintf(arg,"arg%d",i); + if(!proxy_flag) return; + + if (l) { + if (SwigType_type(Getattr(l,"type")) == T_VOID) { + l = nextSibling(l); + } } - if(gencomma) Printf(nativecall,", "); + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms("in", l, NULL); + Swig_typemap_attach_parms("jstype", l, NULL); + Swig_typemap_attach_parms("javain", l, NULL); - if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) { - Printv(nativecall, arg, "._self", 0); - } else Printv(nativecall,arg,0); - - gencomma = 1; - - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); - - char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn); - if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) { - jstype = GetChar(shadow_classes, DataType_Getname(pt)); + /* Get Java return types */ + if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) { + substituteJavaclassname(t, tm); + Printf(shadowrettype, "%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, + "No jstype typemap defined for %s\n", SwigType_str(t,0)); } - // Add to java function header - Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg); - if(i != pcount-1) { - Printf(f_shadow, ", "); + /* Start generating the shadow function */ + Printf(shadow_code, " %s ", Getattr(n,"feature:java:methodmodifiers")); + if (static_flag) + Printf(shadow_code, "static "); + Printf(shadow_code, "%s %s(", shadowrettype, java_shadow_function_name); + + Printv(nativecall, jniclass_name, ".", java_function_name, "(", NIL); + if (!static_flag) + Printv(nativecall, "swigCPtr", NIL); + + int gencomma = !static_flag; + + /* Output each parameter */ + for (i = 0, p=l; p; i++) { + + /* Ignored parameters */ + if (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + continue; + } + + /* Ignore the 'this' argument for variable wrappers */ + if (!(variable_wrapper_flag && i==0)) + { + SwigType *pt = Getattr(p,"type"); + String *javaparamtype = NewString(""); + + /* Get the java type of the parameter */ + if ((tm = Getattr(p,"tmap:jstype"))) { + substituteJavaclassname(pt, tm); + Printf(javaparamtype, "%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, + "No jstype typemap defined for %s\n", SwigType_str(pt,0)); + } + + if (gencomma) + Printf(nativecall, ", "); + + String *arg = makeParameterName(n, p, i); + + // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in native function (in JNI class) + if ((tm = Getattr(p,"tmap:javain"))) { + substituteJavaclassname(pt, tm); + Replaceall(tm, "$javainput", arg); + Printv(nativecall, tm, NIL); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, + "No javain typemap defined for %s\n", SwigType_str(pt,0)); + } + + /* Add to java shadow function header */ + if (gencomma >= 2) + Printf(shadow_code, ", "); + gencomma = 2; + Printf(shadow_code, "%s %s", javaparamtype, arg); + + Delete(arg); + Delete(javaparamtype); + } + p = Getattr(p,"tmap:in:next"); + } + + Printf(nativecall, ")"); + Printf(shadow_code, ")"); + generateThrowsClause(n, shadow_code); + + // Transform return type used in native function (in JNI class) to type used in Java wrapper function (in proxy class) + if ((tm = Swig_typemap_lookup_new("javaout",n,"",0))) { + if (Getattr(n,"feature:new")) + Replaceall(tm,"$owner","true"); + else + Replaceall(tm,"$owner","false"); + substituteJavaclassname(t, tm); + Replaceall(tm, "$jnicall", nativecall); + Printf(shadow_code, " %s\n\n", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, + "No javaout typemap defined for %s\n", SwigType_str(t,0)); + } + + Delete(shadowrettype); + Delete(nativecall); + Delete(user_arrays); + } + + /* ---------------------------------------------------------------------- + * constructorHandler() + * ---------------------------------------------------------------------- */ + + virtual int constructorHandler(Node *n) { + + ParmList *l = Getattr(n,"parms"); + String *tm; + Parm *p; + int i; + String *user_arrays = NewString(""); + + Language::constructorHandler(n); + + if(proxy_flag) { + String *overloaded_name = getOverloadedName(n); + String *nativecall = NewString(""); + + Printf(shadow_code, " %s %s(", Getattr(n,"feature:java:methodmodifiers"), shadow_classname); + Printv(nativecall, "this(", jniclass_name, ".", Swig_name_construct(overloaded_name), "(", NIL); + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms("in", l, NULL); + Swig_typemap_attach_parms("jstype", l, NULL); + Swig_typemap_attach_parms("javain", l, NULL); + + int gencomma = 0; + + /* Output each parameter */ + for (i = 0, p=l; p; i++) { + + /* Ignored parameters */ + if (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + continue; + } + + SwigType *pt = Getattr(p,"type"); + String *javaparamtype = NewString(""); + + /* Get the java type of the parameter */ + if ((tm = Getattr(p,"tmap:jstype"))) { + substituteJavaclassname(pt, tm); + Printf(javaparamtype, "%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, + "No jstype typemap defined for %s\n", SwigType_str(pt,0)); + } + + if (gencomma) + Printf(nativecall, ", "); + + String *arg = makeParameterName(n, p, i); + + // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in native function (in JNI class) + if ((tm = Getattr(p,"tmap:javain"))) { + substituteJavaclassname(pt, tm); + Replaceall(tm, "$javainput", arg); + Printv(nativecall, tm, NIL); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, + "No javain typemap defined for %s\n", SwigType_str(pt,0)); + } + + /* Add to java shadow function header */ + if(gencomma) + Printf(shadow_code, ", "); + Printf(shadow_code, "%s %s", javaparamtype, arg); + gencomma = 1; + + Delete(arg); + Delete(javaparamtype); + p = Getattr(p,"tmap:in:next"); + } + + Printf(nativecall, "), true);\n"); + + Printf(shadow_code, ")"); + generateThrowsClause(n, shadow_code); + Printf(shadow_code, " {\n"); + Printv(shadow_code, user_arrays, NIL); + Printf(shadow_code, " %s", nativecall); + Printf(shadow_code, " }\n\n"); + + if(!gencomma) // We must have a default constructor + have_default_constructor_flag = true; + + Delete(overloaded_name); + Delete(nativecall); + } + + Delete(user_arrays); + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * destructorHandler() + * ---------------------------------------------------------------------- */ + + virtual int destructorHandler(Node *n) { + Language::destructorHandler(n); + String *symname = Getattr(n,"sym:name"); + + if(proxy_flag) { + Printv(destructor_call, " ", jniclass_name, ".", Swig_name_destroy(symname), "(swigCPtr);\n", NIL); + } + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * membervariableHandler() + * ---------------------------------------------------------------------- */ + + virtual int membervariableHandler(Node *n) { + variable_name = Getattr(n,"sym:name"); + wrapping_member_flag = true; + variable_wrapper_flag = true; + Language::membervariableHandler(n); + wrapping_member_flag = false; + variable_wrapper_flag = false; + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * staticmembervariableHandler() + * ---------------------------------------------------------------------- */ + + virtual int staticmembervariableHandler(Node *n) { + variable_name = Getattr(n,"sym:name"); + wrapping_member_flag = true; + static_flag = true; + Language::staticmembervariableHandler(n); + wrapping_member_flag = false; + static_flag = false; + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * memberconstantHandler() + * ---------------------------------------------------------------------- */ + + virtual int memberconstantHandler(Node *n) { + variable_name = Getattr(n,"sym:name"); + wrapping_member_flag = true; + Language::memberconstantHandler(n); + wrapping_member_flag = false; + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * getOverloadedName() + * ----------------------------------------------------------------------------- */ + + String *getOverloadedName(Node *n) { + + /* Although the JNI is designed to handle overloaded Java functions, a Java long is used for all classes in the SWIG + * JNI native interface. The JNI native interface function is thus mangled when overloaded to give a unique name. */ + String *overloaded_name = NewStringf("%s", Getattr(n,"sym:name")); + + if (Getattr(n,"sym:overloaded")) { + Printv(overloaded_name, Getattr(n,"sym:overname"), NIL); + } + + return overloaded_name; + } + + /* ----------------------------------------------------------------------------- + * moduleClassFunctionHandler() + * ----------------------------------------------------------------------------- */ + + void moduleClassFunctionHandler(Node *n) { + SwigType *t = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + String *tm; + Parm *p; + int i; + String *nativecall = NewString(""); + String *shadowrettype = NewString(""); + String *user_arrays = NewString(""); + int num_arguments = 0; + int num_required = 0; + String *overloaded_name = getOverloadedName(n); + String *func_name = NULL; + + if (l) { + if (SwigType_type(Getattr(l,"type")) == T_VOID) { + l = nextSibling(l); + } + } + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms("jstype", l, NULL); + Swig_typemap_attach_parms("javain", l, NULL); + + /* Get Java return types */ + if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) { + substituteJavaclassname(t, tm); + Printf(shadowrettype, "%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, + "No jstype typemap defined for %s\n", SwigType_str(t,0)); + } + + /* Change function name for global variables */ + if (proxy_flag && global_variable_flag) { + // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name + func_name = NewString(""); + if(Cmp(Getattr(n,"sym:name"), Swig_name_set(variable_name)) == 0) + Printf(func_name,"set"); + else + Printf(func_name,"get"); + Putc(toupper((int) *Char(variable_name)), func_name); + Printf(func_name, "%s", Char(variable_name)+1); + } else { + func_name = Copy(Getattr(n,"sym:name")); + } + + /* Start generating the function */ + Printf(module_class_code, " %s static %s %s(", Getattr(n,"feature:java:methodmodifiers"), shadowrettype, func_name); + Printv(nativecall, jniclass_name, ".", overloaded_name, "(", NIL); + + /* Get number of required and total arguments */ + num_arguments = emit_num_arguments(l); + num_required = emit_num_required(l); + + int gencomma = 0; + + /* Output each parameter */ + for (i = 0, p=l; i < num_arguments; i++) { + + /* Ignored parameters */ + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *javaparamtype = NewString(""); + + /* Get the java type of the parameter */ + if ((tm = Getattr(p,"tmap:jstype"))) { + substituteJavaclassname(pt, tm); + Printf(javaparamtype, "%s", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, + "No jstype typemap defined for %s\n", SwigType_str(pt,0)); + } + + if (gencomma) + Printf(nativecall, ", "); + + String *arg = makeParameterName(n, p, i); + + // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in native function (in JNI class) + if ((tm = Getattr(p,"tmap:javain"))) { + substituteJavaclassname(pt, tm); + Replaceall(tm, "$javainput", arg); + Printv(nativecall, tm, NIL); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, + "No javain typemap defined for %s\n", SwigType_str(pt,0)); + } + + /* Add to java shadow function header */ + if (gencomma >= 2) + Printf(module_class_code, ", "); + gencomma = 2; + Printf(module_class_code, "%s %s", javaparamtype, arg); + + p = Getattr(p,"tmap:in:next"); + Delete(arg); + Delete(javaparamtype); + } + + Printf(nativecall, ")"); + Printf(module_class_code, ")"); + generateThrowsClause(n, module_class_code); + + // Transform return type used in native function (in JNI class) to type used in Java wrapper function (in module class) + if ((tm = Swig_typemap_lookup_new("javaout",n,"",0))) { + if (Getattr(n,"feature:new")) + Replaceall(tm,"$owner","true"); + else + Replaceall(tm,"$owner","false"); + substituteJavaclassname(t, tm); + Replaceall(tm, "$jnicall", nativecall); + Printf(module_class_code, " %s\n\n", tm); + } else { + Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, + "No javaout typemap defined for %s\n", SwigType_str(t,0)); + } + + Delete(shadowrettype); + Delete(nativecall); + Delete(user_arrays); + Delete(func_name); + } + + /* ----------------------------------------------------------------------------- + * substituteJavaclassname() + * + * Substitute $javaclassname with either the shadow class name for classes/structs/unions that SWIG knows about. + * Otherwise use the $descriptor name for the Java class name. Note that the $&javaclassname substitution + * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. + * Inputs: + * pt - parameter type + * tm - jstype typemap + * Outputs: + * tm - jstype typemap with $javaclassname substitution + * Return: + * is_java_class - flag indicating if a substitution was performed + * ----------------------------------------------------------------------------- */ + + bool substituteJavaclassname(SwigType *pt, String *tm) { + bool is_java_class = false; + if (Strstr(tm, "$javaclassname") || Strstr(tm,"$&javaclassname")) { + String *javaclassname = is_shadow(pt); + if (javaclassname) { + Replaceall(tm,"$&javaclassname", javaclassname); // is_shadow() works for pointers to classes too + Replaceall(tm,"$javaclassname", javaclassname); + } + else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. + String *descriptor = NULL; + SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); + + if (Strstr(tm, "$&javaclassname")) { + SwigType_add_pointer(type); + descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); + Replaceall(tm, "$&javaclassname", descriptor); + } + else { // $javaclassname + descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); + Replaceall(tm, "$javaclassname", descriptor); + } + + // Add to hash table so that the SWIGTYPE Java classes can be created later + Setattr(swig_types_hash, descriptor, type); + Delete(descriptor); + Delete(type); + } + is_java_class = true; + } + return is_java_class; + } + + /* ----------------------------------------------------------------------------- + * makeParameterName() + * + * Inputs: + * n - Node + * p - parameter node + * arg_num - parameter argument number + * Return: + * arg - a unique parameter name + * ----------------------------------------------------------------------------- */ + + String *makeParameterName(Node *n, Parm *p, int arg_num) { + + // Use C parameter name unless it is a duplicate or an empty parameter name + String *pn = Getattr(p,"name"); + int count = 0; + ParmList *plist = Getattr(n,"parms"); + while (plist) { + if ((Cmp(pn, Getattr(plist,"name")) == 0)) + count++; + plist = nextSibling(plist); + } + String *arg = (!pn || (count > 1)) ? NewStringf("arg%d",arg_num) : Copy(Getattr(p,"name")); + + return arg; + } + + /* ----------------------------------------------------------------------------- + * emitJavaClass() + * ----------------------------------------------------------------------------- */ + + void emitJavaClass(String *javaclassname, SwigType *type) { + String *filen = NewStringf("%s.java", javaclassname); + File *f_swigtype = NewFile(filen,"w"); + String *swigtype = NewString(""); + + // Emit banner and package name + emitBanner(f_swigtype); + if(Len(package) > 0) + Printf(f_swigtype, "package %s;\n\n", package); + + // Pure Java baseclass and interfaces + const String *pure_java_baseclass = javaTypemapLookup("javabase", type, WARN_NONE); + const String *pure_java_interfaces = javaTypemapLookup("javainterfaces", type, WARN_NONE); + + // Emit the class + Printv(swigtype, + javaTypemapLookup("javaimports", type, WARN_NONE), // Import statements + "\n", + javaTypemapLookup("javaclassmodifiers", type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers + " class $javaclassname", // Class name and bases + *Char(pure_java_baseclass) ? + " extends " : + "", + pure_java_baseclass, + *Char(pure_java_interfaces) ? // Pure Java interfaces + " implements " : + "", + pure_java_interfaces, + " {\n", + " private long swigCPtr;\n", + "\n", + " ", + javaTypemapLookup("javaptrconstructormodifiers", type, WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers + " $javaclassname(long cPtr, boolean bFutureUse) {\n", // Constructor used for wrapping pointers + " swigCPtr = cPtr;\n", + " }\n", + "\n", + " protected $javaclassname() {\n", // Default constructor + " swigCPtr = 0;\n", + " }\n", + javaTypemapLookup("javagetcptr", type, WARN_JAVA_TYPEMAP_GETCPTR_UNDEF), // getCPtr method + javaTypemapLookup("javacode", type, WARN_NONE), // extra Java code + "}\n", + "\n", + NIL); + + Replaceall(swigtype, "$javaclassname", javaclassname); + Printv(f_swigtype, swigtype, NIL); + + Close(f_swigtype); + Delete(filen); + Delete(swigtype); + } + + /* ----------------------------------------------------------------------------- + * javaTypemapLookup() + * ----------------------------------------------------------------------------- */ + + const String *javaTypemapLookup(const String *op, String *type, int warning) { + String *tm = NULL; + const String *code = NULL; + + if((tm = Swig_typemap_search(op, type, NULL, NULL))) { + code = Getattr(tm,"code"); + } + + if (!code) { + code = empty_string; + if (warning != WARN_NONE) + Swig_warning(warning, input_file, line_number, "No %s typemap defined for %s\n", op, type); + } + + return code ? code : empty_string; + } + + /* ----------------------------------------------------------------------------- + * addThrows() + * ----------------------------------------------------------------------------- */ + + void addThrows(Node *n, const String *typemap, Node *parameter) { + // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in + String *throws_attribute = NewStringf("%s:throws", typemap); + String *throws = Getattr(parameter,throws_attribute); + + if (throws) { + String *throws_list = Getattr(n,"java:throwslist"); + if (!throws_list) { + throws_list = NewList(); + Setattr(n,"java:throwslist", throws_list); + } + + // Put the exception classes in the throws clause into a temporary List + List *temp_classes_list = Split(throws,',',INT_MAX); + + // Add the exception classes to the node throws list, but don't duplicate if already in list + if (temp_classes_list && Len(temp_classes_list) > 0) { + for (String *cls = Firstitem(temp_classes_list); cls; cls = Nextitem(temp_classes_list)) { + String *javacls = NewString(cls); + Replaceall(javacls," ",""); // remove spaces + Replaceall(javacls,"\t",""); // remove tabs + if (Len(javacls) > 0) { + // $javaclassname substitution + SwigType *pt = Getattr(parameter,"type"); + substituteJavaclassname(pt, javacls); + + // Don't duplicate the Java class in the throws clause + bool found_flag = false; + for (String *item = Firstitem(throws_list); item; item = Nextitem(throws_list)) { + if (Strcmp(item, javacls) == 0) + found_flag = true; + } + if (!found_flag) + Append(throws_list, javacls); + } + Delete(javacls); + } + } + Delete(temp_classes_list); + } + Delete(throws_attribute); + } + + /* ----------------------------------------------------------------------------- + * generateThrowsClause() + * ----------------------------------------------------------------------------- */ + + void generateThrowsClause(Node *n, String *code) { + // Add the throws clause into code + List *throws_list = Getattr(n,"java:throwslist"); + if (throws_list) { + String *cls = Firstitem(throws_list); + Printf(code, " throws %s", cls); + while ( (cls = Nextitem(throws_list)) ) + Printf(code, ", %s", cls); } } +}; /* class JAVA */ - if((DataType_type(t) != T_VOID) && shadowrettype) - Printf(nativecall,"))"); +/* ----------------------------------------------------------------------------- + * swig_java() - Instantiate module + * ----------------------------------------------------------------------------- */ - Printf(nativecall,");\n"); - - Printf(f_shadow, ") {\n"); - Printf(f_shadow, "\t%s\n", nativecall); - Printf(f_shadow, " }\n\n"); - Delete(nativecall); +extern "C" Language * +swig_java(void) { + return new JAVA(); } -void JAVA::cpp_constructor(char *name, char *iname, ParmList *l) { - this->Language::cpp_constructor(name,iname,l); - - if(!shadow) return; - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - DOHString *nativecall = NewString(""); - char arg[256]; - - Printf(f_shadow, " public %s(", shadow_classname); - - Printv(nativecall, " if(_self == 0 && ", shadow_classname, ".class == _selfClass()) {\n", 0); - if (iname != NULL) - Printv(nativecall, tab8, " _self = ", module, ".", Swig_name_construct(iname), "(", 0); - else - Printv(nativecall, tab8, " _self = ", module, ".", Swig_name_construct(shadow_classname), "(", 0); - - int pcount = ParmList_len(l); - if(pcount == 0) // We must have a default constructor - have_default_constructor = 1; - - Parm *p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - - // Produce string representation of source and target arguments - if(pn && *(pn)) - strcpy(arg,pn); - else { - sprintf(arg,"arg%d",i); - } - - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); - - char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn); - if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) { - jstype = GetChar(shadow_classes, DataType_Getname(pt)); - } - - // Add to java function header - Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg); - - if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) { - Printv(nativecall,arg, "._self", 0); - } else Printv(nativecall, arg, 0); - - if(i != pcount-1) { - Printf(nativecall, ", "); - Printf(f_shadow, ", "); - } - } - - - Printf(f_shadow, ") {\n"); - Printv(nativecall, - ");\n", - tab8, " _selfown = true;\n", - " }\n", - 0); - - Printf(f_shadow, "%s", nativecall); - Printf(f_shadow, " }\n\n"); - Delete(nativecall); -} - -void JAVA::cpp_destructor(char *name, char *newname) { - this->Language::cpp_destructor(name,newname); - - if(!shadow) return; - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - char *realname = (newname) ? newname : name; - - if(finalize) { - Printf(f_shadow, " protected void finalize() {\n"); - Printf(f_shadow, " if(_selfown) {\n"); - Printf(f_shadow, " _delete();\n"); - Printf(f_shadow, " }\n"); - Printf(f_shadow, " };\n\n"); - } - - Printf(f_shadow, " public void _delete() {\n"); - Printf(f_shadow, " if(_self != 0 && %s.class == _selfClass()) {\n", shadow_classname); - Printf(f_shadow, "\t%s.%s(_self);\n", module, Swig_name_destroy(realname)); - Printf(f_shadow, "\t_self = 0;\n"); - Printf(f_shadow, " }\n"); - Printf(f_shadow, " }\n\n"); -} - -void JAVA::cpp_class_decl(char *name, char *rename, char *type) { - this->Language::cpp_class_decl(name,rename, type); - - if(!shadow) return; - - char *realname = (rename) ? rename : name; - - Setattr(shadow_classes,name, realname); - if(type && strcmp(type, "struct") == 0) { - sprintf(bigbuf, "struct %s", name); - Setattr(shadow_classes, bigbuf, rename); - } -} - -void JAVA::cpp_inherit(char **baseclass, int) { - this->Language::cpp_inherit(baseclass, 0); - - if(!shadow) return; - - int cnt = 0; - char **bc = baseclass; - while(*bc++) cnt++; - - if(cnt > 1) - Printf(stderr, "Warning: %s inherits from multiple base classes. Multiple inheritance is not supported.\n", shadow_classname); - - shadow_baseclass = Swig_copy_string(*baseclass); -} - -void JAVA::cpp_variable(char *name, char *iname, DataType *t) { - if(shadow && !shadow_classdef_emitted) emit_shadow_classdef(); - - if(shadow) member_func = 1; - shadow_name = Swig_copy_string((iname) ? iname : name); - this->Language::cpp_variable(name, iname, t); - member_func = 0; -} - -void JAVA::cpp_static_var(char *name, char *iname, DataType *t) { - if(shadow) member_func = 1; - shadow_name = Swig_copy_string((iname) ? iname : name); - this->Language::cpp_static_var(name, iname, t); - member_func = 0; -} - -void JAVA::cpp_declare_const(char *name, char *iname, DataType *type, char *value) { - if(shadow && !shadow_classdef_emitted) emit_shadow_classdef(); - - if(shadow) member_func = 1; - shadow_name = Swig_copy_string((iname) ? iname : name); - this->Language::cpp_declare_const(name, iname, type, value); - member_func = 0; -} +/* ----------------------------------------------------------------------------- + * Static member variables + * ----------------------------------------------------------------------------- */ +const char *JAVA::usage = (char*)"\ +Java Options (available with -java)\n\ + -package - set name of the Java package\n\ + -noproxy - Generate the low-level functional interface instead of proxy classes\n"; diff --git a/Source/Modules1.1/java.h b/Source/Modules1.1/java.h deleted file mode 100644 index 6c86b452e..000000000 --- a/Source/Modules1.1/java.h +++ /dev/null @@ -1,49 +0,0 @@ - -// ------------------------------------------------------------------------ -// A Java SWIG Language module -// -// ------------------------------------------------------------------------ - -class JAVA : public Language { -public : - - // Virtual functions required by the SWIG parser - - void parse_args(int, char *argv[]); - void parse(); - void add_native(char *, char *, SwigType *, ParmList *); - void create_function(char *, char *, SwigType *, ParmList *); - void link_variable(char *, char *, SwigType *); - void declare_const(char *, char *, SwigType *, char *); - void initialize(void); - void headers(void); - void close(void); - void set_module(char *,char **); - void create_command(char *, char *); - - void pragma(char *lang, char *code, char *value); - void add_typedef(SwigType *t, char *name); - void cpp_open_class(char *classname, char *rename, char *ctype, int strip); - void cpp_close_class(); - void cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l); - void cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l); - void cpp_constructor(char *name, char *iname, ParmList *l); - void cpp_destructor(char *name, char *newname); - void cpp_class_decl(char *name, char *rename, char *type); - void cpp_inherit(char **baseclass, int); - void cpp_variable(char *name, char *iname, SwigType *t); - void cpp_static_var(char *, char *, SwigType *); - void cpp_declare_const(char *name, char *iname, SwigType *type, char *value); - - /* Java Module methods */ - void emit_classdef(); - void emit_shadow_classdef(); - char *JNICALL(DOHString_or_char *func); - char *SwigTcToJniType(SwigType *t, int ret); - char *SwigTcToJavaType(SwigType *t, int ret, int inShadow); - char *SwigTcToJniScalarType(SwigType *t); - char *JavaTypeFromTypemap(char *op, char *lang, SwigType *t, char *pname); - char *makeValidJniName(char *name); - char *JavaMethodSignature(SwigType *t, int ret, int inShadow); - void writeRegisterNatives(); -}; diff --git a/Source/Modules1.1/lang.cxx b/Source/Modules1.1/lang.cxx index faf69918f..4245b7193 100644 --- a/Source/Modules1.1/lang.cxx +++ b/Source/Modules1.1/lang.cxx @@ -12,464 +12,1842 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_lang_cxx[] = "$Header$"; -#include "swig11.h" +#include "swigmod.h" +#include -/* ----------------------------------------------------------------- - * Language::create_command() - * ----------------------------------------------------------------- */ +/* Some status variables used during parsing */ -void Language::create_command(String *, String *) { - Printf(stderr,"SWIG Warning. No command creation procedure defined.\n"); - Printf(stderr,"C++ inheritance may not work correctly.\n"); -} +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 */ +int Abstract = 0; +int ImportMode = 0; +int IsVirtual = 0; +static String *AttributeFunctionGet = 0; +static String *AttributeFunctionSet = 0; +static int cplus_mode = 0; +static Node *CurrentClass = 0; +int line_number = 0; +char *input_file = 0; +int SmartPointer = 0; -/* ----------------------------------------------------------------- - * Language::nativefunction() - * ----------------------------------------------------------------- */ +extern int GenerateDefault; +extern int ForceExtern; +extern int NoExtern; -void -Language::nativefunction(DOH *node) { - Printf(stderr,"%s:%d. Adding native function %s not supported (ignored).\n", Getfile(node), Getline(node), Getattr(node,"scriptname")); -} +/* import modes */ +#define IMPORT_MODE 1 +#define IMPORT_MODULE 2 -/* The following strings are used during code generation and contain various - permutations of the class name: +/* C++ access modes */ - ClassName - This is the name of the class as it appears in C/C++ - source code. It does not include a type specifier - such as "struct" or "class" +#define CPLUS_PUBLIC 0 +#define CPLUS_PROTECTED 1 +#define CPLUS_PRIVATE 2 - ClassRename - If non-NULL, the class has been renamed. - ClassType - The type of the class (struct, class, union) - ClassFullname - The full name of the class including its type specifier. - For example, "class Foo" or "struct Vector". - ClassPrefix - The class prefix as used in the scripting language - interface. This is either ClassName or ClassRename. -*/ +/* ---------------------------------------------------------------------- + * Dispatcher::emit_one() + * + * Dispatch a single node + * ---------------------------------------------------------------------- */ -static String *ClassName = 0; -static String *ClassRename = 0; -static String *ClassType = 0; -static String *ClassFullname = 0; -static String *ClassPrefix = 0; +int Dispatcher::emit_one(Node *n) { + String *wrn; + int ret = SWIG_OK; -/* ----------------------------------------------------------------------------- - * Language::cpp_open_class() - * ----------------------------------------------------------------------------- */ + char *tag = Char(nodeType(n)); + if (!tag) { + Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree node!\n"); + return SWIG_ERROR; + } + + /* Do not proceed if marked with an error */ + + if (Getattr(n,"error")) return SWIG_OK; -void Language::cpp_open_class(DOH *node) { - String *classname; - String *classrename; - String *ctype; - String *altname; - int strip = CPlusPlus; - - classname = Getname(node); - classrename = Getattr(node,"scriptname"); - ctype = Getattr(node,"classtype"); - - altname = Getattr(node,"altname"); - if (altname) { - strip = 1; - classname = altname; /* Use the alt name instead of the class name */ + /* Look for warnings */ + wrn = Getattr(n,"feature:warnfilter"); + if (wrn) { + Swig_warnfilter(wrn,1); } - if (strip) SetInt(node,"strip",1); - - /* Copy the class name */ - if (ClassName) Delete(ClassName); - ClassName = NewString(classname); - - /* Copy the class renaming */ - - if (ClassRename) Delete(ClassRename); - ClassRename = NewString(classrename); - - if (ClassType) Delete(ClassType); - ClassType = strip ? 0 : NewString(ctype); - - if (ClassFullname) Delete(ClassFullname); - - ClassFullname = ClassType ? NewStringf("%s %s", ClassType, ClassName) : NewString(ClassName); - ClassPrefix = ClassRename; -} - -/* ----------------------------------------------------------------------------- - * Language::cpp_close_class() - * ----------------------------------------------------------------------------- */ - -void Language::cpp_close_class() { - - /* Doesn't really do anything */ -} - -/* ----------------------------------------------------------------------------- - * Language::cpp_memberfunction() - * ----------------------------------------------------------------------------- */ - -void Language::cpp_memberfunction(DOH *node) { - String *name; - String *iname; - String *ccode; - String *script_name; - SwigType *type; - ParmList *parms; - Wrapper *w; - - name = Getattr(node,"name"); - iname = Getattr(node,"scriptname"); - type = Getattr(node,"type"); - parms = Getattr(node,"parms"); - ccode = Getattr(node,"code"); - - /* Generate the C wrapper function name and interpreter name of this function*/ - /* Create the actual function name */ - - script_name = Swig_name_member(ClassPrefix, iname ? iname : name); - - /* Now do a symbol table lookup on it */ - - /* Create the C wrapper function for this */ - w = Swig_cmethod_wrapper(ClassFullname, name, type, parms, ccode); - if (AddMethods && ccode) { - /* Dump the C wrappers */ - Printf(f_wrappers,"%s",w); - } else if (!AddMethods) { - /* Just create a string that does what we want */ - emit_set_action(Swig_cmethod_call(name, Getparms(w))); + /* ============================================================ + * 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,"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); } - Setattr(w,"scriptname",script_name); - lang->function(w); - Delete(w); + + /* =============================================================== + * 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; } -/* ----------------------------------------------------------------------------- - * Language::cpp_constructor() - * ----------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + * Dispatcher::emit_children() + * + * Emit all children. + * ---------------------------------------------------------------------- */ -void Language::cpp_constructor(DOH *node) { - String *name; - String *iname; - String *cname; - String *ccode; - ParmList *parms; - Wrapper *w; - - name = Getattr(node,"name"); - iname = Getattr(node,"scriptname"); - parms = Getattr(node,"parms"); - ccode = Getattr(node,"code"); - - if ((Cmp(name,ClassName))) { - Printf(stderr,"%s:%d. Function %s must have a return type.\n", - Getfile(node), Getline(node), name); - return; +int Dispatcher::emit_children(Node *n) { + Node *c; + for (c = firstChild(n); c; c = nextSibling(c)) { + 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::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); } + +/* Allocators */ +Language::Language() { + symbols = NewHash(); + classtypes = NewHash(); + overloading = 0; + multiinput = 0; +} + +Language::~Language() { + Delete(symbols); + Delete(classtypes); +} + +/* ---------------------------------------------------------------------- + emit_one() + ---------------------------------------------------------------------- */ + +int Language::emit_one(Node *n) { + int ret; + int oldext; + if (!n) return SWIG_OK; + + if (Getattr(n,"feature:ignore")) return SWIG_OK; + + oldext = Extend; + if (Getattr(n,"feature:extend")) Extend = 1; - cname = Swig_name_construct(iname ? iname : ClassPrefix); + line_number = Getline(n); + input_file = Char(Getfile(n)); - /* Add this function to the SWIG symbol table */ - - if (CPlusPlus) { - w = Swig_cppconstructor_wrapper(ClassFullname, parms, ccode); - } else { - w = Swig_cconstructor_wrapper(ClassFullname, parms, ccode); - } - Setattr(w,"scriptname", cname); - - if (!AddMethods) { - if (CPlusPlus) { - emit_set_action(Swig_cppconstructor_call(ClassFullname, parms)); - } else { - emit_set_action(Swig_cconstructor_call(ClassFullname)); - } - } else { - if (ccode) { - Printf(f_wrappers,"%s",w); - } - } - lang->function(w); - Delete(w); - - /* Call our default method */ - /* cplus_emit_constructor(Char(ClassName), Char(ClassType), Char(ClassRename), name, iname, l, AddMethods); */ - -} - -/* ----------------------------------------------------------------------------- - * Language::cpp_destructor() - * ----------------------------------------------------------------------------- */ - -void Language::cpp_destructor(DOH *node) { - String *name; - String *iname; - String *cname; - String *ccode; - Wrapper *w; - - name = Getattr(node,"name"); - iname = Getattr(node,"scriptname"); - cname = Swig_name_destroy(ClassRename ? ClassRename : ClassName); - ccode = Getattr(node,"code"); - - /* Add this function to the SWIG symbol table */ - - if (CPlusPlus) { - w = Swig_cppdestructor_wrapper(ClassFullname,ccode); - } else { - w = Swig_cdestructor_wrapper(ClassFullname, ccode); - } - Setattr(w,"scriptname",cname); - if (AddMethods && ccode) { - Printf(f_wrappers,"%s", w); - lang->function(w); - } else if (AddMethods) { - lang->function(w); - } else { - if (CPlusPlus) - emit_set_action(Swig_cppdestructor_call()); - else - emit_set_action(Swig_cdestructor_call()); - lang->function(w); - } - Delete(w); -} - -/* ----------------------------------------------------------------------------- - * Language::cpp_inherit() - * ----------------------------------------------------------------------------- */ - -void Language::cpp_inherit(List *bases) { - - if (!bases) return; /* - while (baseclass[i]) { - // cplus_inherit_members(baseclass[i],mode); - i++; + 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; +} + +/* This is a hack */ +SwigType *cplus_value_type(SwigType *t) { + Node *n; + if (!CPlusPlus) return 0; + if (SwigType_isclass(t)) { + SwigType *td = SwigType_typedef_resolve_all(t); + if ((n = Swig_symbol_clookup(td,0))) { + if ((Strcmp(nodeType(n),"class") == 0) && (!Getattr(n,"allocate:default_constructor") || (Getattr(n,"allocate:noassign")))) { + String *s = NewStringf("SwigValueWrapper< %s >",t); + Delete(td); + return s; + } + } + if (SwigType_issimple(td) && SwigType_istemplate(td)) { + String *s = NewStringf("SwigValueWrapper< %s >",t); + Delete(td); + return s; + } + Delete(td); + } + return 0; +} + +/* Patch C++ pass-by-value */ +void Language::patch_parms(Parm *p) { + while (p) { + SwigType *t = Getattr(p,"type"); + SwigType *s = cplus_value_type(t); + if (s) { + Setattr(p,"alttype",s); + Delete(s); + } + p = nextSibling(p); + } +} + +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))) { + 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; + } + } +} + +/* ---------------------------------------------------------------------- + * Language::top() - Top of parsing tree + * ---------------------------------------------------------------------- */ + +int Language::top(Node *n) { + return emit_children(n); +} + +/* ---------------------------------------------------------------------- + * Language::extendDirective() + * ---------------------------------------------------------------------- */ + +int Language::extendDirective(Node *n) { + int oldam = Extend; + int oldmode = cplus_mode; + Extend = CWRAP_EXTEND; + cplus_mode = CPLUS_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 != CPLUS_PUBLIC)) return SWIG_NOWRAP; + + if (!ImportMode) { + Swig_require(&n,"name", "?value",NIL); + String *name = Getattr(n,"name"); + String *value = Getattr(n,"value"); + if (!value) { + value = Copy(name); + } else { + value = NewStringf("%(escape)s", value); + } + Setattr(n,"value", value); + this->constantWrapper(n); + Swig_restore(&n); + return SWIG_OK; + } + return SWIG_NOWRAP; +} + +/* ---------------------------------------------------------------------- + * Language::fragmentDirective() + * ---------------------------------------------------------------------- */ + +int Language::fragmentDirective(Node *n) { + String *name = Getattr(n,"name"); + String *code = Getattr(n,"code"); + String *section = Getattr(n,"section"); + Swig_fragment_register(name,section,code); + 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) { + /* %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() + * ---------------------------------------------------------------------- */ + +extern "C" void Swig_cparse_replace_descriptor(String *s); + +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"); } */ -} -/* ----------------------------------------------------------------------------- - * Language::cpp_variable() - * ----------------------------------------------------------------------------- */ - -void Language::cpp_variable(DOH *node) { - String *name; - String *iname; - String *cname; - String *setcode, *getcode; - SwigType *type; - Wrapper *w; - - name = Getattr(node,"name"); - iname = Getattr(node,"scriptname"); - type = Getattr(node,"type"); - setcode = Getattr(node,"setcode"); - getcode = Getattr(node,"getcode"); - - /* Set the class prefix */ - - cname = Swig_name_get(Swig_name_member(ClassPrefix, iname ? iname : name)); - - /* Check the symbol table */ - - /* Create a function to set the value of the variable */ - if (!ReadOnly) { - w = Swig_cmemberset_wrapper(ClassFullname, name, type, setcode); - Setattr(w,"scriptname",Swig_name_set(Swig_name_member(ClassPrefix,iname ? iname : name))); - if (AddMethods && setcode) { - Printf(f_wrappers,"%s",w); - } else if (!AddMethods) { - /* Check for a member in typemap here */ - String *target = NewStringf("%s->%s", Swig_cparm_name(0,0),name); - char *tm = Swig_typemap_lookup("memberin",type,name,Swig_cparm_name(0,1),target,0); - if (!tm) - emit_set_action(Swig_cmemberset_call(name,type)); - else - emit_set_action(tm); - Delete(target); + 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; } - lang->function(w); - Delete(w); } - w = Swig_cmemberget_wrapper(ClassFullname, name, type, getcode); - Setattr(w,"scriptname", Swig_name_get(Swig_name_member(ClassPrefix, iname ? iname : name))); - if (AddMethods && getcode) { - Printf(f_wrappers,"%s",w); - } else if (!AddMethods) { - emit_set_action(Swig_cmemberget_call(name,type)); + + 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; } - lang->function(w); - Delete(w); + + /* 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::cpp_static_func() - * ----------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + * Language::typemapcopyDirective() + * ---------------------------------------------------------------------- */ -void Language::cpp_staticfunction(DOH *node) { - String *name; - String *iname; - SwigType *type; - ParmList *parms; - String *ccode; - String *script_name; - String *real_name; - DOH *nnode; - Wrapper *w; - - name = Getattr(node,"name"); - iname = Getattr(node,"scriptname"); - type = Getattr(node,"type"); - parms = Getattr(node,"parms"); - ccode = Getattr(node,"code"); - - /* Set the member function name */ - script_name = Swig_name_member(ClassPrefix,iname ? iname : name); - - /* Now do a symbol table lookup on it : */ - - /* Figure out the name of the function */ - if (AddMethods) { - real_name = Swig_name_member(ClassName, name); - if (!ccode) { - nnode = Copy(node); - Setattr(nnode,"name", real_name); - Setattr(nnode,"scriptname", script_name); - lang->function(nnode); - Delete(nnode); +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 { - w = Swig_cfunction_wrapper(real_name,type,parms,ccode); - Printf(f_wrappers,"%s",w); - Setattr(w,"scriptname",script_name); - lang->function(w); - Delete(w); + 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"); + 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); + } + } + 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; + + if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP; + + if (Cmp(storage,"typedef") == 0) { + Swig_save(&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; + } else if (Cmp(storage,"friend") == 0) { + Swig_warning(WARN_LANG_FRIEND_IGNORE, Getfile(n), Getline(n), + "friend function '%s' ignored.\n", name); + return SWIG_NOWRAP; + } + + /* If in import mode, we proceed no further */ + if (ImportMode) return SWIG_NOWRAP; + + /* 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 (!NoExtern) { + if (f_header) { + if ((Cmp(storage,"extern") == 0) || (ForceExtern && !storage)) { + Printf(f_header,"extern %s;\n", SwigType_str(ty,name)); + } else if (Cmp(storage,"externc") == 0) { + Printf(f_header,"extern \"C\" %s;\n", SwigType_str(ty,name)); + } + } + } + } + /* This needs to check qualifiers */ + if (SwigType_isqualifier(ty)) { + Setattr(n,"qualifier", SwigType_pop(ty)); + } + Delete(SwigType_pop_function(ty)); + DohIncref(type); + Setattr(n,"type",ty); + functionHandler(n); + Setattr(n,"type",type); + Delete(ty); + Delete(type); + return SWIG_OK; + } else { + /* Some kind of variable declaration */ + Delattr(n,"decl"); + if (Getattr(n,"nested")) Setattr(n,"feature:immutable","1"); + if (!CurrentClass) { + if ((Cmp(storage,"extern") == 0) || ForceExtern) { + f_header = Swig_filebyname("header"); + if (!NoExtern) { + if (f_header) { + Printf(f_header,"extern %s;\n", SwigType_str(ty,name)); + } + } + } + } + if (!SwigType_ismutable(ty)) { + Setattr(n,"feature:immutable","1"); + } + /* If an array and elements are const, then read-only */ + if (SwigType_isarray(ty)) { + SwigType *tya = SwigType_array_type(ty); + if (SwigType_isconst(tya)) { + Setattr(n,"feature:immutable","1"); + } + } + DohIncref(type); + Setattr(n,"type",ty); + variableHandler(n); + Setattr(n,"type",type); + Setattr(n,"decl",decl); + Delete(ty); + Delete(type); + Delete(fullty); + return SWIG_OK; + } +} + +/* ---------------------------------------------------------------------- + * Language::functionHandler() + * ---------------------------------------------------------------------- */ + +int +Language::functionHandler(Node *n) { + Parm *p; + p = Getattr(n,"parms"); + if (CPlusPlus) patch_parms(p); + if (!CurrentClass) { + globalfunctionHandler(n); + } else { + String *storage = Getattr(n,"storage"); + if (Cmp(storage,"static") == 0) { + staticmemberfunctionHandler(n); + } else { + memberfunctionHandler(n); + } + } + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::globalfunctionHandler() + * ---------------------------------------------------------------------- */ + +int +Language::globalfunctionHandler(Node *n) { + + Swig_require(&n,"name","sym:name","type","?parms",NIL); + + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *storage = Getattr(n,"storage"); + ParmList *parms = Getattr(n,"parms"); + + if (0 && (Cmp(storage,"static") == 0)) { + Swig_restore(&n); + return SWIG_NOWRAP; /* Can't wrap static functions */ + } else { + /* Check for callback mode */ + String *cb = Getattr(n,"feature:callback"); + if (cb) { + String *cbname = NewStringf(cb,symname); + callbackfunctionHandler(n); + if (Cmp(cbname, symname) == 0) { + Delete(cbname); + Swig_restore(&n); + return SWIG_NOWRAP; + } + Delete(cbname); + } + Setattr(n,"parms",nonvoid_parms(parms)); + Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(name,parms))); + functionWrapper(n); + } + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::callbackfunctionHandler() + * ---------------------------------------------------------------------- */ + +int +Language::callbackfunctionHandler(Node *n) { + Swig_require(&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 = Getattr(n,"feature:callback"); + String *cbname = NewStringf(cb,symname); + SwigType *cbty = Copy(type); + SwigType_add_function(cbty,parms); + SwigType_add_pointer(cbty); + + Setattr(n,"sym:name", cbname); + Setattr(n,"type", cbty); + Setattr(n,"value", name); + + constantWrapper(n); + Delete(cbname); + Delete(cbty); + + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::memberfunctionHandler() + * ---------------------------------------------------------------------- */ + +int +Language::memberfunctionHandler(Node *n) { + + Swig_require(&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; + + if (Cmp(storage,"virtual") == 0) { + if (Cmp(value,"0") == 0) { + IsVirtual = PURE_VIRTUAL; + } else { + IsVirtual = PLAIN_VIRTUAL; } } else { - nnode = Copy(node); - real_name = NewStringf("%s::%s", ClassName, name); - Setattr(nnode,"name", real_name); - Setattr(nnode,"scriptname", script_name); - lang->function(nnode); - Delete(nnode); - Delete(real_name); + IsVirtual = 0; } + cb = Getattr(n,"feature:callback"); + if (cb) { + Node *cb = NewHash(); + String *cbname = NewStringf(cb,symname); + String *cbvalue; + SwigType *cbty = Copy(type); + SwigType_add_function(cbty,parms); + SwigType_add_memberpointer(cbty,ClassName); + cbvalue = NewStringf("&%s::%s",ClassName,name); + Setattr(cb,"sym:name", cbname); + Setattr(cb,"type", cbty); + Setattr(cb,"value", cbvalue); + Setattr(cb,"name", name); + + memberconstantHandler(n); + + Delete(cb); + Delete(cbvalue); + Delete(cbty); + Delete(cbname); + if (Cmp(cbname,symname) == 0) { + Swig_restore(&n); + return SWIG_NOWRAP; + } + } + + String *fname = Swig_name_member(ClassPrefix, symname); + /* Transformation */ + Swig_MethodToFunction(n,ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer); + Setattr(n,"sym:name",fname); + functionWrapper(n); + + /* DelWrapper(w);*/ + Delete(fname); + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::staticmemberfunctionHandler() + * ---------------------------------------------------------------------- */ + +int +Language::staticmemberfunctionHandler(Node *n) { + + Swig_require(&n,"*name","*sym:name","*type",NIL); + Swig_save(&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 *code = Getattr(n,"code"); + String *cname, *mrename; + + if (!Extend) { + cname = NewStringf("%s::%s",ClassName,name); + } else { + cname = Copy(Swig_name_member(ClassPrefix,name)); + } + mrename = Swig_name_member(ClassPrefix, symname); + + Setattr(n,"name",cname); + Setattr(n,"sym:name",mrename); + + if ((Extend) && (code)) { + /* Hmmm. An added static member. We have to create a little wrapper for this */ + String *tmp = NewStringf("%s(%s)", cname, ParmList_str(parms)); + String *wrap = SwigType_str(type,tmp); + Printv(wrap,code,"\n",NIL); + Setattr(n,"wrap:code",wrap); + Delete(tmp); + Delete(wrap); + } + Delattr(n,"storage"); + globalfunctionHandler(n); + + Delete(cname); + Delete(mrename); + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::variableHandler() + * ---------------------------------------------------------------------- */ + +int +Language::variableHandler(Node *n) { + if (!CurrentClass) { + globalvariableHandler(n); + } else { + String *storage = Getattr(n,"storage"); + if ((Cmp(storage,"static") == 0)) { + if (!SmartPointer) { + staticmembervariableHandler(n); + } + } else { + membervariableHandler(n); + } + } + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::globalvariableHandler() + * ---------------------------------------------------------------------- */ + +int +Language::globalvariableHandler(Node *n) { + String *storage = Getattr(n,"storage"); + if (0 && (Cmp(storage,"static") == 0)) return SWIG_NOWRAP; + variableWrapper(n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::membervariableHandler() + * ---------------------------------------------------------------------- */ + +int +Language::membervariableHandler(Node *n) { + + Swig_require(&n,"*name","*sym:name","*type",NIL); + Swig_save(&n,"parms",NIL); + + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + + /* 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 + */ + + if (!(Extend | SmartPointer)) { + Delattr(n,"feature:except"); + } + + if (!AttributeFunctionGet) { + + String *mrename_get, *mrename_set; + + mrename_get = Swig_name_get(Swig_name_member(ClassPrefix, symname)); + mrename_set = Swig_name_set(Swig_name_member(ClassPrefix, symname)); + + /* Create a function to set the value of the variable */ + + if (!Getattr(n,"feature:immutable")) { + int make_wrapper = 1; + String *tm = 0; + String *target = 0; + if (!Extend) { + target = NewStringf("%s->%s", Swig_cparm_name(0,0),name); + tm = Swig_typemap_lookup_new("memberin",n,target,0); + } + Swig_MembersetToFunction(n,ClassType,Extend | SmartPointer); + if (!Extend) { + /* Check for a member in typemap here */ + + /* String *tm = Swig_typemap_lookup((char *) "memberin",type,name,target,Swig_cparm_name(0,1),target,0);*/ + if (!tm) { + if (SwigType_isarray(type)) { + /* Printf(stderr,"%s:%d. Warning. Array member %s will be read-only.\n", input_file, line_number, name);*/ + make_wrapper = 0; + } + } else { + Replace(tm,"$source", Swig_cparm_name(0,1), DOH_REPLACE_ANY); + Replace(tm,"$target", target, DOH_REPLACE_ANY); + Replace(tm,"$input",Swig_cparm_name(0,1),DOH_REPLACE_ANY); + Replace(tm,"$self",Swig_cparm_name(0,0),DOH_REPLACE_ANY); + Setattr(n,"wrap:action", tm); + Delete(tm); + } + Delete(target); + } + if (make_wrapper) { + Setattr(n,"sym:name", mrename_set); + functionWrapper(n); + } else { + Setattr(n,"feature:immutable","1"); + } + /* Restore parameters */ + Setattr(n,"type",type); + Setattr(n,"name",name); + Setattr(n,"sym:name",symname); + } + /* Emit get function */ + { + Swig_MembergetToFunction(n,ClassType,Extend | SmartPointer); + Setattr(n,"sym:name", mrename_get); + 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 = Copy(Swig_name_get(name)); + cpp_member_func(Char(cname),Char(gname),type,0); + Delete(cname); + } + Delete(gname); + if (!Getattr(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 = Copy(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(&n,"*name","*sym:name","*type", "?value", NIL); + String *value = Getattr(n,"value"); + if (!value) { + 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 { + String *name = Getattr(n,"name"); + String *cname = NewStringf("%s::%s", ClassName,name); + 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); + + 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 != CPLUS_PUBLIC)) return SWIG_NOWRAP; + + Swig_require(&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) { + 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::cpp_constant() + * Language::memberconstantHandler() * ----------------------------------------------------------------------------- */ -void Language::cpp_constant(DOH *node) -{ - String *name; - String *iname; - String *value; - SwigType *type; - String *cname; - String *mname; - String *new_value; +int Language::memberconstantHandler(Node *n) { - name = Getattr(node,"name"); - iname = Getattr(node,"scriptname"); - value = Getattr(node,"value"); - type = Getattr(node,"type"); + Swig_require(&n,"*name","*sym:name","*value",NIL); - /* Set the constant name */ + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + String *value = Getattr(n,"value"); - cname = Swig_name_member(ClassPrefix, iname ? iname : name); + String *mrename; + String *new_value; - /* Now do a symbol table lookup on it : */ - - /* Form correct C++ name */ - mname = NewStringf("%s::%s", ClassName,name); - - /* Declare a constant */ - if (!value) { - new_value = NewStringf("%s::%s", ClassName, name); - } else { - new_value = NewString(value); - } - Hash *n; - n = NewHash(); - Setattr(n,"name",cname); - Setattr(n,"scriptname",cname); - Setattr(n,"type",type); - Setattr(n,"value",new_value); - lang->constant(n); - Delete(n); + mrename = Swig_name_member(ClassPrefix, symname); + /* Fixed by namespace-enum patch + if ((!value) || (Cmp(value,name) == 0)) { + new_value = NewStringf("%s::%s",ClassName,name); + } else { + new_value = NewString(value); + } + */ + new_value = Copy(value); + Setattr(n,"sym:name", mrename); + Setattr(n,"value", new_value); + Setattr(n,"name", NewStringf("%s::%s", ClassName,name)); + constantWrapper(n); + Delete(mrename); Delete(new_value); - Delete(mname); + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::typedefHandler() + * ---------------------------------------------------------------------- */ + +int Language::typedefHandler(Node *) { + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::classDeclaration() + * ---------------------------------------------------------------------- */ + +int Language::classDeclaration(Node *n) { + 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 */ + /* Printf(stdout,"sym:name = %s\n", symname); */ + + 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(&n,"name",NIL); + Setattr(n,"name",classname); + + if (Cmp(kind,"class") == 0) { + cplus_mode = CPLUS_PRIVATE; + } else { + cplus_mode = CPLUS_PUBLIC; + } + + ClassName = NewString(classname); + ClassPrefix = NewString(iname); + if (strip) { + ClassType = NewString(classname); + } else { + ClassType = NewStringf("%s %s", kind, classname); + } + Setattr(n,"classtype", SwigType_namestr(ClassType)); + + InClass = 1; + CurrentClass = n; + + if (Getattr(n,"abstract")) { + Abstract = 1; + } else { + Abstract = 0; + } + + /* Call classHandler() here */ + if (!ImportMode) + classHandler(n); + else + Language::classHandler(n); + + InClass = 0; + CurrentClass = 0; + Delete(ClassType); ClassType = 0; + Delete(ClassPrefix); ClassPrefix = 0; + Delete(ClassName); ClassName = 0; + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::classHandler() + * ---------------------------------------------------------------------- */ + +int Language::classHandler(Node *n) { + + /* 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 = CPLUS_PUBLIC; + SmartPointer = CWRAP_SMART_POINTER; + Node *c; + for (c = Firstitem(methods); c; c= Nextitem(methods)) { + /* Swig_print_node(c); */ + emit_one(c); + } + SmartPointer = 0; + } + + cplus_mode = CPLUS_PUBLIC; + if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) { + if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) { + /* Note: will need to change this to support different kinds of classes */ + if (!Abstract) { + Setattr(CurrentClass,"feature:new","1"); + constructorHandler(CurrentClass); + Delattr(CurrentClass,"feature:new"); + } + } + if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) && (Getattr(n,"allocate:default_destructor"))) { + destructorHandler(CurrentClass); + } + } + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::classforwardDeclaration() + * ---------------------------------------------------------------------- */ + +int Language::classforwardDeclaration(Node *n) { + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::constructorDeclaration() + * ---------------------------------------------------------------------- */ + +int Language::constructorDeclaration(Node *n) { + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + + if (!CurrentClass) return SWIG_NOWRAP; + if (cplus_mode != CPLUS_PUBLIC) return SWIG_NOWRAP; + if (ImportMode) return SWIG_NOWRAP; + + /* Name adjustment for %name */ + Swig_save(&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) { + String *oname = NewStringf("%s::%s", ClassName, Swig_scopename_last(SwigType_namestr(name))); + String *cname = NewStringf("%s::%s", ClassName, Swig_scopename_last(SwigType_namestr(Getattr(over,"name")))); + SwigType *decl = Getattr(n,"decl"); + Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number, + "Overloaded constructor ignored. %s\n", SwigType_str(decl,SwigType_namestr(oname))); + Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over), + "Previous declaration is %s\n", SwigType_str(Getattr(over,"decl"),SwigType_namestr(cname))); + Delete(oname); + Delete(cname); + } else { + constructorHandler(n); + } + } + } else { + if (name && (Cmp(name,ClassName)) && !(Getattr(n,"template"))) { + Printf(stdout,"name = '%s', ClassName='%s'\n", name, ClassName); + Swig_warning(WARN_LANG_RETURN_TYPE, input_file,line_number,"Function %s must have a return type.\n", + name); + Swig_restore(&n); + return SWIG_NOWRAP; + } + constructorHandler(n); + } + } + Setattr(CurrentClass,"has_constructor","1"); + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::constructorHandler() + * ---------------------------------------------------------------------- */ + +int +Language::constructorHandler(Node *n) { + Swig_require(&n,"?name","*sym:name","?type","?parms",NIL); + String *symname = Getattr(n,"sym:name"); + String *mrename; + Parm *parms = Getattr(n,"parms"); + + mrename = Swig_name_construct(symname); + if (CPlusPlus) patch_parms(parms); + Swig_ConstructorToFunction(n,ClassType,CPlusPlus,Getattr(n,"template") ? 0 :Extend); + Setattr(n,"sym:name", mrename); + functionWrapper(n); + Delete(mrename); + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::copyconstructorHandler() + * ---------------------------------------------------------------------- */ + +int +Language::copyconstructorHandler(Node *n) { + Swig_require(&n,"?name","*sym:name","?type","?parms", NIL); + String *symname = Getattr(n,"sym:name"); + String *mrename; + Parm *parms = Getattr(n,"parms"); + if (CPlusPlus) patch_parms(parms); + mrename = Swig_name_copyconstructor(symname); + Swig_ConstructorToFunction(n,ClassType, CPlusPlus, Getattr(n,"template") ? 0 : Extend); + Setattr(n,"sym:name", mrename); + functionWrapper(n); + Delete(mrename); + Swig_restore(&n); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::destructorDeclaration() + * ---------------------------------------------------------------------- */ + +int Language::destructorDeclaration(Node *n) { + + if (!CurrentClass) return SWIG_NOWRAP; + if (cplus_mode != CPLUS_PUBLIC) return SWIG_NOWRAP; + if (ImportMode) return SWIG_NOWRAP; + + Swig_save(&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(&n,"?name","*sym:name",NIL); + Swig_save(&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 = CPLUS_PUBLIC; + } else if (Cmp(kind,"private") == 0) { + cplus_mode = CPLUS_PRIVATE; + } else if (Cmp(kind,"protected") == 0) { + cplus_mode = CPLUS_PROTECTED; + } + return SWIG_OK; } /* ----------------------------------------------------------------------------- - * Language::cpp_staticvariable() + * Language::namespaceDeclaration() * ----------------------------------------------------------------------------- */ -void Language::cpp_staticvariable(DOH *node) { - char *name, *iname; - SwigType *t; - char *cname; - char mname[256]; +int Language::namespaceDeclaration(Node *n) { + if (Getattr(n,"alias")) return SWIG_OK; + emit_children(n); + return SWIG_OK; +} - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - - /* Create the variable name */ - - cname = Char(Swig_name_member(ClassPrefix, iname ? iname : name)); - - /* Now do a symbol table lookup on it : */ - - /* Form correct C++ name */ - sprintf(mname,"%s::%s",Char(ClassName),name); - - /* Link with this variable */ - - Hash *n = NewHash(); - Setattr(n,"name",mname); - Setattr(n,"scriptname", cname); - Setattr(n,"type",t); - lang->variable(n); - Delete(n); +int Language::validIdentifier(String *s) { + char *c = Char(s); + while (*c) { + if (!(isalnum(*c) || (*c == '_'))) return 0; + c++; + } + return 1; } /* ----------------------------------------------------------------------------- - * Language::cpp_class_decl() + * Language::usingDeclaration() * ----------------------------------------------------------------------------- */ -void Language::cpp_class_decl(DOH *) { - /* Does nothing by default */ +int Language::usingDeclaration(Node *n) { + if (cplus_mode == CPLUS_PUBLIC) { + emit_children(n); + } + return SWIG_OK; +} + +/* Stubs. Language modules need to implement these */ + +/* ---------------------------------------------------------------------- + * Language::constantWrapper() + * ---------------------------------------------------------------------- */ + +int Language::constantWrapper(Node *n) { + String *name = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + + Printf(stdout,"constantWrapper : %s = %s\n", SwigType_str(type,name), value); + return SWIG_OK; +} + +/* ---------------------------------------------------------------------- + * Language::variableWrapper() + * ---------------------------------------------------------------------- */ +int Language::variableWrapper(Node *n) { + Swig_require(&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 */ + if (!Getattr(n,"feature:immutable")) { + int make_wrapper = 1; + String *tm = Swig_typemap_lookup_new("globalin", n, name, 0); + + Swig_VarsetToFunction(n); + Setattr(n,"sym:name", Swig_name_set(symname)); + + /* String *tm = Swig_typemap_lookup((char *) "globalin",type,name,name,Swig_cparm_name(0,0),name,0);*/ + + if (!tm) { + if (SwigType_isarray(type)) { + /* Printf(stderr,"%s:%d. Warning. Array member %s will be read-only.\n", input_file, line_number, name);*/ + make_wrapper = 0; + } + } else { + Replace(tm,"$source", Swig_cparm_name(0,0), DOH_REPLACE_ANY); + Replace(tm,"$target", name, DOH_REPLACE_ANY); + Replace(tm,"$input",Swig_cparm_name(0,0),DOH_REPLACE_ANY); + Setattr(n,"wrap:action", tm); + Delete(tm); + } + if (make_wrapper) { + functionWrapper(n); + } + Setattr(n,"sym:name",symname); + Setattr(n,"type",type); + Setattr(n,"name",name); + } + Swig_VargetToFunction(n); + Setattr(n,"sym:name", Swig_name_get(symname)); + 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(parms)))); + Printf(stdout," action : %s\n", Getattr(n,"wrap:action")); + return SWIG_OK; } /* ----------------------------------------------------------------------------- - * Language::add_typedef() + * Language::nativeWrapper() * ----------------------------------------------------------------------------- */ -void Language::add_typedef(SwigType *, String *) { - /* Does nothing by default */ +int Language::nativeWrapper(Node *n) { + return SWIG_OK; +} + +void Language::main(int argc, char *argv[]) { } /* ----------------------------------------------------------------------------- - * Language::pragma() + * 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. * ----------------------------------------------------------------------------- */ -void Language::pragma(DOH *node) { - /* Does nothing by default */ +int +Language::addSymbol(String *s, Node *n) { + Node *c = Getattr(symbols,s); + if (c && (c != n)) { + Swig_error(input_file, line_number, "Error. '%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::import() + * Language::symbolLookup() * ----------------------------------------------------------------------------- */ -void Language::import(String *) { - /* Does nothing by default */ +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; + SwigType *lt, *ty1,*ty2; + String *base; + String *prefix; + Symtab *stab = 0; + /* Look in hash of cached values */ + n = Getattr(classtypes,s); + if (n) return n; + + lt = SwigType_ltype(s); + ty1 = SwigType_typedef_resolve_all(lt); + ty2 = SwigType_strip_qualifiers(ty1); + Delete(lt); + Delete(ty1); + + base = SwigType_base(ty2); + + Replaceall(base,"class ",""); + Replaceall(base,"struct ",""); + Replaceall(base,"union ",""); + + prefix = SwigType_prefix(ty2); + + 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; + } + /* Do a symbol table search on the base type */ + /* n = Swig_symbol_clookup(base,0); */ + if (n) { + /* Found a match. Look at the prefix. We only allow + a few cases: pointers, references, and simple */ + if ((Len(prefix) == 0) || /* Simple type */ + (Strcmp(prefix,"p.") == 0) || /* pointer */ + (Strcmp(prefix,"r.") == 0)) { /* reference */ + Setattr(classtypes,Copy(s),n); + } else { + n = 0; + } + } + Delete(ty2); + Delete(base); + Delete(prefix); + + if (n && (Getattr(n,"feature:ignore"))) return 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::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; +} diff --git a/Source/Modules1.1/main.cxx b/Source/Modules1.1/main.cxx index c3e221f61..2cbdbec66 100644 --- a/Source/Modules1.1/main.cxx +++ b/Source/Modules1.1/main.cxx @@ -12,54 +12,77 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_main_cxx[] = "$Header$"; -#include "swig11.h" +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include "swigmod.h" #ifndef MACSWIG #include "swigconfig.h" #endif -#include -#include -#include -#include +#include "swigwarn.h" + extern "C" { #include "preprocessor.h" } -#ifndef SWIG_LANG -#define SWIG_LANG PYTHON +#include + +#ifndef SWIG_LIB +#define SWIG_LIB "/usr/local/lib/swig1.3" #endif -#include "tcl8.h" -#include "python.h" -#include "perl5.h" -#include "guile.h" -#ifdef OLD -#include "java.h" +#ifndef SWIG_CC +#define SWIG_CC "CC" #endif -#include "mzscheme.h" -#include "ruby.h" -#include "xml.h" // Global variables - FILE *f_runtime = 0; - DOH *f_header = 0; // Some commonly used - DOH *f_wrappers = 0; // FILE pointers - DOH *f_init = 0; + char LibDir[512]; // Library directory Language *lang; // Language method int CPlusPlus = 0; - int NewObject = 0; // NewObject flag + int Extend = 0; // Extend flag int ForceExtern = 0; // Force extern mode - int GenerateDefault = 0; // Generate default constructors + int GenerateDefault = 1; // Generate default constructors + char *Config = 0; int NoInclude = 0; int Verbose = 0; - String *swig_module = 0; + int NoExtern = 0; + int NoExcept = 0; + +extern "C" { +extern String *ModuleName; +} static char *usage = (char*)"\ -\nSWIG1.1 Options\n\ -"; +\nGeneral Options\n\ + -c - Produce raw wrapper code (omit support code)\n\ + -c++ - Enable C++ processing\n\ + -co - Check a file out of the SWIG library\n\ + -Dsymbol - Define a symbol (for conditional compilation)\n\ + -I - Look for SWIG files in \n\ + -includeall - Follow all #include statements\n\ + -importall - Follow all #include statements as imports\n\ + -ignoremissing - Ignore missing include files.\n\ + -l - Include SWIG library file.\n\ + -M - List all dependencies. \n\ + -MM - List dependencies, but omit files in SWIG library.\n\ + -makedefault - Create default constructors/destructors (the default)\n\ + -module - Set module name\n\ + -nodefault - Do not generate constructors/destructors\n\ + -noexcept - Do not wrap exception specifiers.\n\ + -noextern - Do not generate extern declarations.\n\ + -o outfile - Set name of the output file.\n\ + -swiglib - Report location of SWIG library and exit\n\ + -v - Run in verbose mode\n\ + -version - Print SWIG version number\n\ + -Wall - Enable all warning messages\n\ + -wn - Suppress warning number n\n\ + -help - This output.\n\n"; // ----------------------------------------------------------------------------- // check_suffix(char *name) @@ -67,18 +90,11 @@ static char *usage = (char*)"\ // Checks the suffix of a file to see if we should emit extern declarations. // ----------------------------------------------------------------------------- -static int check_suffix(char *name) { char *c; if (!name) return 0; - if (strlen(name) == 0) return 0; - c = name+strlen(name)-1; - while (c != name) { - if (*c == '.') break; - c--; - } - if (c == name) return 0; + c = Swig_file_suffix(name); if ((strcmp(c,".c") == 0) || (strcmp(c,".C") == 0) || (strcmp(c,".cc") == 0) || @@ -90,208 +106,517 @@ check_suffix(char *name) { return 0; } +// ----------------------------------------------------------------------------- +// install_opts(int argc, char *argv[]) +// Install all command line options as preprocessor symbols +// ----------------------------------------------------------------------------- + +static void +install_opts(int argc, char *argv[]) { + int i; + int noopt = 0; + char *c; + for (i = 1; i < (argc-1); i++) { + if (argv[i]) { + if ((*argv[i] == '-') && (!isupper(*(argv[i]+1)))) { + String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]); + Replaceall(opt,"-","_"); + c = Char(opt); + noopt = 0; + while (*c) { + if (!(isalnum(*c) || (*c == '_'))) { + noopt = 1; + break; + } + c++; + } + if (((i+1) < (argc-1)) && (argv[i+1]) && (*argv[i+1] != '-')) { + Printf(opt," %s", argv[i+1]); + i++; + } else { + Printf(opt," 1"); + } + if (!noopt) { + /* Printf(stdout,"%s\n", opt); */ + Preprocessor_define(opt, 0); + } + } + } + } +} //----------------------------------------------------------------- // main() // // Main program. Initializes the files and starts the parser. //----------------------------------------------------------------- -char infilename[256]; -char filename[256]; -char output_dir[512]; -char fn_runtime[256]; -static char *outfile_name = 0; - char *SwigLib; +static int freeze = 0; +static String *lang_config = 0; +static char *cpp_extension = (char *) "cxx"; -extern "C" -int swig11_init(int argc, char *argv[]) { +/* This function sets the name of the configuration file */ + +void SWIG_config_file(const String_or_char *filename) { + lang_config = NewString(filename); +} + +void SWIG_library_directory(const char *filename) { + strcpy(LibDir,filename); +} + +void SWIG_config_cppext(const char *ext) { + cpp_extension = (char *) ext; +} + +extern "C" Node *Swig_cparse(File *); +extern "C" void Swig_cparse_cplusplus(int); +extern "C" void Swig_cparse_debug_templates(int); + +int SWIG_main(int argc, char *argv[], Language *l) { int i; char *c; - char infile[512]; + char temp[512]; + char *outfile_name = 0; int help = 0; + int checkout = 0; + int cpp_only = 0; + int tm_debug = 0; + char *includefiles[256]; + int includecount = 0; + extern int check_suffix(char *); + int dump_tags = 0; + int dump_tree = 0; + int contracts = 0; + int browse = 0; + int dump_typedef = 0; + int dump_classes = 0; + int werror = 0; + int depend = 0; - lang = new SWIG_LANG; - f_wrappers = 0; - f_init = 0; - f_header = 0; + DOH *libfiles = 0; + DOH *cpps = 0 ; + extern void Swig_contracts(Node *n); + extern void Swig_browser(Node *n, int); + extern void Swig_default_allocators(Node *n); + extern void Swig_process_types(Node *n); + + + /* Initialize the SWIG core */ + Swig_init(); + + /* Suppress warning messages for private inheritance, preprocessor evaluation, + might be abstract, and overloaded const */ + + Swig_warnfilter("202,309,403,512",1); + + // Initialize the preprocessor + Preprocessor_init(); + + lang = l; + + // Set up some default symbols (available in both SWIG interface files + // and C files) + + Preprocessor_define((DOH *) "SWIG 1", 0); + Preprocessor_define((DOH *) "__STDC__", 0); +#ifdef MACSWIG + Preprocessor_define((DOH *) "SWIGMAC 1", 0); +#endif +#ifdef SWIGWIN32 + Preprocessor_define((DOH *) "SWIGWIN32 1", 0); +#endif + + // Set the SWIG version value + String *vers; + vers = NewStringf("SWIG_VERSION 0x%02d%02d%02d", SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN); + Preprocessor_define(vers,0); + + // Check for SWIG_LIB environment variable + + if ((c = getenv("SWIG_LIB")) == (char *) 0) { +#if defined(_WIN32) + char buf[MAX_PATH]; + char *p; + if (GetModuleFileName(0, buf, MAX_PATH) == 0 + || (p = strrchr(buf, '\\')) == 0) { + Printf(stderr, "Warning: Could not determine SWIG library location. Assuming " SWIG_LIB "\n"); + sprintf(LibDir,"%s",SWIG_LIB); // Build up search paths + } else { + strcpy(p+1, "Lib"); + strcpy(LibDir, buf); + } +#else + sprintf(LibDir,"%s",SWIG_LIB); // Build up search paths +#endif + } else { + strcpy(LibDir,c); + } + + SwigLib = Swig_copy_string(LibDir); // Make a copy of the real library location + + libfiles = NewList(); // Get options for (i = 1; i < argc; i++) { - if (argv[i]) { - if(strcmp(argv[i],"-tcl") == 0) { - fprintf(stderr,"swig: -tcl option now implies -tcl8\n"); - lang = new TCL8; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-tcl8") == 0) { - lang = new TCL8; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-python") == 0) { - lang = new PYTHON; - Swig_mark_arg(i); - - } else if (strcmp(argv[i],"-perl5") == 0) { - lang = new PERL5; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-guile") == 0) { - lang = new GUILE; - Swig_mark_arg(i); -#ifdef OLD - } else if (strcmp(argv[i],"-java") == 0) { - lang = new JAVA; - Swig_mark_arg(i); -#endif - } else if (strcmp(argv[i],"-mzscheme") == 0) { - lang = new MZSCHEME; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-ruby") == 0) { - lang = new RUBY; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-c++") == 0) { - CPlusPlus=1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-c") == 0) { - NoInclude=1; - Preprocessor_define((void *) "SWIG_NOINCLUDE 1", 0); - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-make_default") == 0) { - GenerateDefault = 1; - Swig_mark_arg(i); - } else if(strcmp(argv[i],"-module") == 0) { - if (argv[i+1]) { - swig_module = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i],"-o") == 0) { - if (argv[i+1]) { - outfile_name = argv[i+1]; - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); - Swig_mark_arg(i); - help = 1; + if (argv[i]) { + if (strncmp(argv[i],"-I",2) == 0) { + // Add a new directory search path + includefiles[includecount++] = Swig_copy_string(argv[i]+2); + Swig_mark_arg(i); + } else if (strncmp(argv[i],"-D",2) == 0) { + DOH *d = NewString(argv[i]+2); + Replace(d,(char*)"=",(char*)" ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST); + Preprocessor_define((DOH *) d,0); + // Create a symbol + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-E") == 0) { + cpp_only = 1; + Swig_mark_arg(i); + } else if ((strcmp(argv[i],"-verbose") == 0) || + (strcmp(argv[i],"-v") == 0)) { + Verbose = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-c++") == 0) { + CPlusPlus=1; + Preprocessor_define((DOH *) "__cplusplus 1", 0); + Swig_cparse_cplusplus(1); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-c") == 0) { + NoInclude=1; + Preprocessor_define((DOH *) "SWIG_NOINCLUDE 1", 0); + Swig_mark_arg(i); + } else if ((strcmp(argv[i],"-make_default") == 0) || (strcmp(argv[i],"-makedefault") == 0)) { + GenerateDefault = 1; + Swig_mark_arg(i); + } else if ((strcmp(argv[i],"-no_default") == 0) || (strcmp(argv[i],"-nodefault") == 0)) { + GenerateDefault = 0; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-noexcept") == 0) { + NoExcept = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-noextern") == 0) { + NoExtern = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-show_templates") == 0) { + Swig_cparse_debug_templates(1); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-swiglib") == 0) { + printf("%s\n", LibDir); + SWIG_exit (EXIT_SUCCESS); + } else if (strcmp(argv[i],"-o") == 0) { + Swig_mark_arg(i); + if (argv[i+1]) { + outfile_name = Swig_copy_string(argv[i+1]); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if (strcmp(argv[i],"-version") == 0) { + fprintf(stderr,"\nSWIG Version %s\n", + SWIG_VERSION); + fprintf(stderr,"Copyright (c) 1995-1998\n"); + fprintf(stderr,"University of Utah and the Regents of the University of California\n"); + fprintf(stderr,"Copyright (c) 1998-2002\n"); + fprintf(stderr,"University of Chicago\n"); + fprintf(stderr,"\nCompiled with %s\n", SWIG_CC); + SWIG_exit (EXIT_SUCCESS); + } else if (strncmp(argv[i],"-l",2) == 0) { + // Add a new directory search path + Append(libfiles,argv[i]+2); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-co") == 0) { + checkout = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-freeze") == 0) { + freeze = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-includeall") == 0) { + Preprocessor_include_all(1); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-importall") == 0) { + Preprocessor_import_all(1); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-ignoremissing") == 0) { + Preprocessor_ignore_missing(1); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-tm_debug") == 0) { + tm_debug = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-module") == 0) { + Swig_mark_arg(i); + if (argv[i+1]) { + ModuleName = NewString(argv[i+1]); + Swig_mark_arg(i+1); + } else { + Swig_arg_error(); + } + } else if (strcmp(argv[i],"-M") == 0) { + depend = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-MM") == 0) { + depend = 2; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-Wall") == 0) { + Swig_mark_arg(i); + Swig_warnall(); + } else if (strcmp(argv[i],"-Werror") == 0) { + werror = 1; + Swig_mark_arg(i); + } else if (strncmp(argv[i],"-w",2) == 0) { + Swig_mark_arg(i); + Swig_warnfilter(argv[i]+2,1); + } else if (strcmp(argv[i],"-dump_tags") == 0) { + dump_tags = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-dump_tree") == 0) { + dump_tree = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-contracts") == 0) { + Swig_mark_arg(i); + contracts = 1; + } else if (strcmp(argv[i],"-browse") == 0) { + browse = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-dump_typedef") == 0) { + dump_typedef = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-dump_classes") == 0) { + dump_classes = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + Swig_mark_arg(i); + help = 1; + } } - } } - // Parse language dependent options - lang->parse_args(argc,argv); - if (help) return 0; - - // Create names of temporary files that are created - sprintf(infilename,"%s", argv[argc-1]); - - // Check the suffix for a .c file. If so, we're going to - // declare everything we see as "extern" - - ForceExtern = check_suffix(infilename); - // Strip off suffix - - c = infilename + strlen(infilename); - while (c != infilename) { - if (*c == '.') { - *c = 0; - break; - } else { - c--; - } + for (i = 0; i < includecount; i++) { + Swig_add_directory((DOH *) includefiles[i]); } - if (!outfile_name) { - char *cc = infilename + strlen(infilename); - while (cc != infilename) { - if (*cc == '/') { - cc++; - break; - } - cc--; - } - sprintf(fn_runtime,"%s_wrap.c",infilename); - strcpy(infile,infilename); - outfile_name = fn_runtime; - } else { - sprintf(fn_runtime,"%s",outfile_name); - } - { - // Try to identify the output directory - char *cc = outfile_name; - char *lastc = outfile_name; - while (*cc) { - if (*cc == '/') lastc = cc+1; - cc++; - } - cc = outfile_name; - char *dd = output_dir; - while (cc != lastc) { - *dd = *cc; - dd++; - cc++; - } - *dd = 0; - // Patch up the input filename - cc = infilename + strlen(infilename); - while (cc != infilename) { - if (*cc == '/') { - cc++; - break; - } - cc--; - } - strcpy(infile,cc); - } - return 0; -} - -extern void generate(DOH *top); - -extern "C" -DOH *swig11_run(DOH *node) { - if ((f_runtime = fopen(fn_runtime,"w")) == 0) { - fprintf(stderr,"Unable to open %s\n", fn_runtime); - Swig_exit(1); - } - f_header = NewString(""); - f_wrappers = NewString(""); - f_init = NewString(""); - - Swig_register_filebyname("header",f_header); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("init", f_init); - - // Set up the typemap for handling new return strings + // Define the __cplusplus symbol if (CPlusPlus) - Swig_typemap_register((char*)"newfree",(char*)"p.char",(char*)"",(char*)"delete [] $source;\n",0); - else - Swig_typemap_register((char*)"newfree",(char*)"p.char",(char*)"",(char*)"free($source);\n",0); + Preprocessor_define((DOH *) "__cplusplus 1", 0); - generate(node); + // Parse language dependent options + lang->main(argc,argv); - Dump(f_header,f_runtime); - Dump(f_wrappers, f_runtime); - Wrapper_pretty_print(f_init,f_runtime); - fclose(f_runtime); - return node; + if (help) SWIG_exit (EXIT_SUCCESS); // Exit if we're in help mode + + // Check all of the options to make sure we're cool. + Swig_check_options(); + + install_opts(argc, argv); + + // Add language dependent directory to the search path + { + DOH *rl = NewString(""); + Printf(rl,"%s%s%s", SwigLib, SWIG_FILE_DELIMETER, LibDir); + Swig_add_directory(rl); + rl = NewString(""); + Printf(rl,".%sswig_lib%s%s", SWIG_FILE_DELIMETER, SWIG_FILE_DELIMETER, LibDir); + Swig_add_directory(rl); + } + + sprintf(temp,"%s%sconfig", SwigLib, SWIG_FILE_DELIMETER); + Swig_add_directory((DOH *) temp); + Swig_add_directory((DOH *) "." SWIG_FILE_DELIMETER "swig_lib" SWIG_FILE_DELIMETER "config"); + Swig_add_directory((DOH *) SwigLib); + Swig_add_directory((DOH *) "." SWIG_FILE_DELIMETER "swig_lib"); + + if (Verbose) { + printf ("LibDir: %s\n", LibDir); + List *sp = Swig_search_path(); + String *s; + for (s = Firstitem(sp); s; s = Nextitem(sp)) { + Printf(stdout," %s\n", s); + } + } + + // If we made it this far, looks good. go for it.... + + input_file = argv[argc-1]; + + // If the user has requested to check out a file, handle that + if (checkout) { + DOH *s; + char *outfile = input_file; + if (outfile_name) + outfile = outfile_name; + + if (Verbose) + printf ("Handling checkout...\n"); + + s = Swig_include(input_file); + if (!s) { + fprintf(stderr,"Unable to locate '%s' in the SWIG library.\n", input_file); + } else { + FILE *f = fopen(outfile,"r"); + if (f) { + fclose(f); + fprintf(stderr,"File '%s' already exists. Checkout aborted.\n", outfile); + } else { + f = fopen(outfile,"w"); + if (!f) { + fprintf(stderr,"Unable to create file '%s'\n", outfile); + } else { + fprintf(stderr,"'%s' checked out from the SWIG library.\n", input_file); + fputs(Char(s),f); + fclose(f); + } + } + } + } else { + // Check the suffix for a .c file. If so, we're going to + // declare everything we see as "extern" + + ForceExtern = check_suffix(input_file); + + // Run the preprocessor + if (Verbose) + printf ("Preprocessing...\n"); + { + int i; + String *fs = NewString(""); + FILE *df = Swig_open(input_file); + if (!df) { + Printf(stderr,"Unable to find '%s'\n", input_file); + SWIG_exit (EXIT_FAILURE); + } + fclose(df); + Printf(fs,"%%include \"swig.swg\"\n"); + if (lang_config) { + Printf(fs,"\n%%include \"%s\"\n", lang_config); + } + Printf(fs,"%%include \"%s\"\n", Swig_last_file()); + for (i = 0; i < Len(libfiles); i++) { + Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i)); + } + Seek(fs,0,SEEK_SET); + cpps = Preprocessor_parse(fs); + if (Swig_error_count()) { + SWIG_exit(EXIT_FAILURE); + } + if (cpp_only) { + Printf(stdout,"%s", cpps); + while (freeze); + SWIG_exit (EXIT_SUCCESS); + } + if (depend) { + String *outfile; + if (!outfile_name) { + if (CPlusPlus) { + outfile = NewStringf("%s_wrap.%s", Swig_file_basename(input_file),cpp_extension); + } else { + outfile = NewStringf("%s_wrap.c", Swig_file_basename(input_file)); + } + } else { + outfile = NewString(outfile_name); + } + Printf(stdout,"%s: ", outfile); + List *files = Preprocessor_depend(); + for (int i = 0; i < Len(files); i++) { + if ((depend != 2) || ((depend == 2) && (Strncmp(Getitem(files,i),SwigLib, Len(SwigLib)) != 0))) { + Printf(stdout,"\\\n %s ", Getitem(files,i)); + } + } + Printf(stdout,"\n"); + SWIG_exit(EXIT_SUCCESS); + } + Seek(cpps, 0, SEEK_SET); + } + + /* Register a null file with the file handler */ + Swig_register_filebyname("null", NewString("")); + + // Pass control over to the specific language interpreter + if (Verbose) { + fprintf (stdout, "Starting language-specific parse...\n"); + fflush (stdout); + } + + Node *top = Swig_cparse(cpps); + + if (Verbose) { + Printf(stdout,"Processing types...\n"); + } + Swig_process_types(top); + + if (Verbose) { + Printf(stdout,"C++ analysis...\n"); + } + Swig_default_allocators(top); + + if (Verbose) { + Printf(stdout,"Generating wrappers...\n"); + } + + if (dump_classes) { + Hash *classes = Getattr(top,"classes"); + if (classes) { + Printf(stdout,"Classes\n"); + Printf(stdout,"------------\n"); + String *key; + for (key = Firstkey(classes); key; key = Nextkey(classes)) { + Printf(stdout,"%s\n", key); + } + } + } + + if (dump_typedef) { + SwigType_print_scope(0); + } + if (dump_tags) { + Swig_print_tags(top,0); + } + if (dump_tree) { + Swig_print_tree(top); + } + if (top) { + if (!Getattr(top,"name")) { + Printf(stderr,"*** No module name specified using %%module or -module.\n"); + SWIG_exit(EXIT_FAILURE); + } else { + /* Set some filename information on the object */ + Setattr(top,"infile", input_file); + if (!outfile_name) { + if (CPlusPlus) { + Setattr(top,"outfile", NewStringf("%s_wrap.%s", Swig_file_basename(input_file),cpp_extension)); + } else { + Setattr(top,"outfile", NewStringf("%s_wrap.c", Swig_file_basename(input_file))); + } + } else { + Setattr(top,"outfile", outfile_name); + } + if (contracts) { + Swig_contracts(top); + } + lang->top(top); + if (browse) { + Swig_browser(top,0); + } + } + } + } + if (tm_debug) Swig_typemap_debug(); + while (freeze); + if ((werror) && (Swig_warn_count())) { + return Swig_warn_count(); + } + return Swig_error_count(); } -extern "C" -void swig11module() { - Swig_register_module("tcl8","swig:top", swig11_init, swig11_run); - Swig_register_module("python","swig:top", swig11_init, swig11_run); - Swig_register_module("perl5","swig:top", swig11_init, swig11_run); - Swig_register_module("ruby","swig:top", swig11_init, swig11_run); - Swig_register_module("guile","swig:top", swig11_init, swig11_run); - Swig_register_module("mzscheme","swig:top", swig11_init, swig11_run); - Swig_register_module("swig11","swig:top", swig11_init, swig11_run); - Swig_register_module("xml","swig:top", xml_init, xml_run); +// -------------------------------------------------------------------------- +// SWIG_exit(int exit_code) +// +// Cleanup and either freeze or exit +// -------------------------------------------------------------------------- + +void SWIG_exit(int exit_code) { + while (freeze); + exit (exit_code); } + diff --git a/Source/Modules1.1/module.cxx b/Source/Modules1.1/module.cxx new file mode 100644 index 000000000..57aa6c304 --- /dev/null +++ b/Source/Modules1.1/module.cxx @@ -0,0 +1,57 @@ +/* ----------------------------------------------------------------------------- + * module.cxx + * + * This file is responsible for the module system. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_module_cxx[] = "$Header$"; + +#include "swigmod.h" + +struct Module { + ModuleFactory fac; + char *name; + Module *next; + Module(const char *n, ModuleFactory f) { + fac = f; + name = new char[strlen(n)+1]; + strcpy(name, n); + next = 0; + } +}; + +static Module *modules = 0; + +/* ----------------------------------------------------------------------------- + * void Swig_register_module() + * + * Register a module. + * ----------------------------------------------------------------------------- */ + +void Swig_register_module(const char *n, ModuleFactory f) { + Module *m = new Module(n,f); + m->next = modules; + modules = m; +} + +/* ----------------------------------------------------------------------------- + * Language *Swig_find_module() + * + * Given a command line option, locates the factory function. + * ----------------------------------------------------------------------------- */ + +ModuleFactory Swig_find_module(const char *name) { + Module *m = modules; + while (m) { + if (strcmp(m->name,name) == 0) { + return m->fac; + } + m = m->next; + } + return 0; +} diff --git a/Source/Modules1.1/mzscheme.cxx b/Source/Modules1.1/mzscheme.cxx index f3ac22096..14e4a3ac2 100644 --- a/Source/Modules1.1/mzscheme.cxx +++ b/Source/Modules1.1/mzscheme.cxx @@ -13,7 +13,7 @@ * can be used and distributed. *****************************************************************************/ -static char cvsroot[] = "$Header$"; +char cvsroot_mzscheme_cxx[] = "$Header$"; /*********************************************************************** * $Header$ @@ -23,751 +23,646 @@ static char cvsroot[] = "$Header$"; * Definitions for adding functions to Mzscheme 101 ***********************************************************************/ -#include "swig11.h" -#include "mzscheme.h" +#include "swigmod.h" -static char *mzscheme_usage = (char*)"\ +#include + +static const char *mzscheme_usage = (char*)"\ \n\ Mzscheme Options (available with -mzscheme)\n\ -help - Print this help\n\ --module name - Set base name of module (not implemented) \n\ --prefix name - Set a prefix to be appended to all name\n\ +-prefix name - Set a prefix to be appended to all names\n\ +-declaremodule - Create extension that declares a module\n\ \n" ; static char *prefix=0; -static char *module=0; +static bool declaremodule = false; +static String *module=0; static char *mzscheme_path=(char*)"mzscheme"; static String *init_func_def = 0; -// --------------------------------------------------------------------- -// MZSCHEME::parse_args(int argc, char *argv[]) -// -// Parse arguments. -// --------------------------------------------------------------------- +static File *f_runtime = 0; +static File *f_header = 0; +static File *f_wrappers = 0; +static File *f_init = 0; -void -MZSCHEME::parse_args (int argc, char *argv[]) -{ - int i; +class MZSCHEME : public Language { +public: - Swig_swiglib_set("mzscheme"); + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ - // Look for certain command line options - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp (argv[i], "-help") == 0) { - fputs (mzscheme_usage, stderr); - Swig_exit (0); - } - else if (strcmp (argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = new char[strlen(argv[i + 1]) + 2]; - strcpy(prefix, argv[i + 1]); - Swig_mark_arg (i); - Swig_mark_arg (i + 1); - i++; - } else { - Swig_arg_error(); + virtual void main (int argc, char *argv[]) { + + int i; + + SWIG_library_directory(mzscheme_path); + + // Look for certain command line options + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp (argv[i], "-help") == 0) { + fputs (mzscheme_usage, stderr); + SWIG_exit (0); + } + else if (strcmp (argv[i], "-prefix") == 0) { + if (argv[i + 1]) { + prefix = new char[strlen(argv[i + 1]) + 2]; + strcpy(prefix, argv[i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } + } + else if (strcmp (argv[i], "-declaremodule") == 0) { + declaremodule = true; + Swig_mark_arg (i); } } } - } - - // If a prefix has been specified make sure it ends in a '_' - - if (prefix) { - if (prefix[strlen (prefix)] != '_') { - prefix[strlen (prefix) + 1] = 0; - prefix[strlen (prefix)] = '_'; - } - } else - prefix = (char*)"swig_"; - - // Add a symbol for this module - - Preprocessor_define ((void *) "SWIGMZSCHEME",0); -} - -// -------------------------------------------------------------------- -// MZSCHEME::initialize() -// -// Output initialization code that registers functions with the -// interface. -// --------------------------------------------------------------------- - -void -MZSCHEME::initialize (String *modname) -{ - init_func_def = NewString(""); - printf ("Generating wrappers for Mzscheme\n"); - init_func_def = NewString(""); - - Swig_banner (f_header); - - Printf (f_header, "/* Implementation : MZSCHEME */\n\n"); - Printf (f_header, "#include \n"); - Printf (f_header, "#include \n"); - Printf (f_header, "#include \n"); - - // insert mzscheme.swg - - if (!NoInclude) { - if (Swig_insert_file ("mzscheme.swg", f_header) == -1) { - Printf (stderr, "SWIG : Fatal error. "); - Printf (stderr, "Unable to locate 'mzscheme.swg' in SWIG library.\n"); - Swig_exit (1); - } - } - - if (!module) { - module = new char[Len(modname)+1]; - strcpy(module, Char(modname)); - } - - Printf (f_init, "static void\nSWIG_init (void)\n{\n"); -} - -// --------------------------------------------------------------------- -// MZSCHEME::close(void) -// -// Wrap things up. Close initialization function. -// --------------------------------------------------------------------- - -void -MZSCHEME::close (void) -{ - Printf (f_init, "}\n\n"); - Printf(f_init, "Scheme_Object *scheme_reload(Scheme_Env *env) {\n"); - Printf(f_init, "%s\n", Char(init_func_def)); - Printf (f_init, "\treturn scheme_void;\n}\n"); - Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n"); - Printf(f_init, "\treturn scheme_reload(env);\n"); - Printf (f_init, "}\n"); -} - -// ---------------------------------------------------------------------- -// MZSCHEME::get_pointer(int parm, SwigType *t, Wrapper *f) -// -// Emits code to get a pointer from a parameter and do type checking. -// parm is the parameter number. This function is only used -// in create_function(). -// ---------------------------------------------------------------------- - -void -MZSCHEME::get_pointer (String *name, int parm, SwigType *t, Wrapper *f) -{ - char p[256]; - sprintf(p, "%d", parm); - Printv(f, tab4, "if (!swig_get_c_pointer(argv[", p, "], \"", SwigType_manglestr(t), - "\", (void **) &arg", p, "))\n",0); - Printv(f, tab8, "scheme_wrong_type(\"", name, - "\", \"", SwigType_manglestr(t), "\", ", p, ", argc, argv);\n",0); -} -// ---------------------------------------------------------------------- -// MZSCHEME::create_function() -// -// Create a function declaration and register it with the interpreter. -// ---------------------------------------------------------------------- - -static void -mreplace (String *s, String *argnum, String *arg, String *proc_name) -{ - Replace(s, "$argnum", argnum, DOH_REPLACE_ANY); - Replace(s, "$arg", arg, DOH_REPLACE_ANY); - Replace(s, "$name", proc_name, DOH_REPLACE_ANY); -} - -static void -throw_unhandled_mzscheme_type_error (SwigType *d) -{ - fflush (stdout); - fprintf (stderr, "ERROR: Unhandled MZSCHEME type error.\n"); - fprintf (stderr, "str: %s\n", Char(SwigType_str(d,0))); - fprintf (stderr, "lstr: %s\n", Char(SwigType_lstr(d,0))); - fprintf (stderr, "manglestr: %s\n", Char(SwigType_manglestr(d))); - Printf (stderr, "\n\nBAILING...\n"); // for now -ttn - abort(); // for now -ttn -} - -void -MZSCHEME::function(DOH *node) -{ - char *name, *iname; - SwigType *d; - ParmList *l; - Parm *p; - Wrapper *f = NewWrapper(); - String *proc_name = NewString(""); - String *source = NewString(""); - String *target = NewString(""); - String *argnum = NewString(""); - String *arg = NewString(""); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *build = NewString(""); - SwigType *t; - char *tm; - int need_len = 0; - int need_tempc = 0; - int have_build = 0; - int argout_set = 0; - int i = 0; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - d = Getattr(node,"type"); - l = Getattr(node,"parms"); - - // Make a wrapper name for this - char *wname = Char(Swig_name_wrapper(iname)); - - // Build the name for Scheme. - Printv(proc_name, iname,0); - Replace(proc_name, "_", "-", DOH_REPLACE_ANY); - - // writing the function wrapper function - Printv(f, "static Scheme_Object *", wname, " (", 0); - Printv(f, "int argc, Scheme_Object **argv", 0); - Printv(f, ")\n{\n", 0); - - // Declare return variable and arguments - // number of parameters - // they are called arg0, arg1, ... - // the return value is called result - - int pcount = emit_args(node, f); - int numargs = 0; - int numopt = 0; - - // adds local variables - Wrapper_add_local(f, "_tempc", "char *_tempc"); - Wrapper_add_local(f, "_len", "int _len"); - Wrapper_add_local(f, "swig_result", "Scheme_Object *swig_result"); - - // Now write code to extract the parameters (this is super ugly) - - for(p = l; p; p = Getnext(p)) { - // Produce names of source and target - Clear(source); - Clear(target); - Clear(argnum); - Clear(arg); - Printf(source, "argv[%d]", i); - Printf(target, "arg%d", i); - Printf(argnum, "%d", i); - Printv(arg, Getname(p),0); - - // Handle parameter types. - - if (Getignore(p)) - Printv(f, "/* ", Char(Getname(p)), " ignored... */\n", 0); - else { - ++numargs; - if ((tm = Swig_typemap_lookup ((char*)"in", - Gettype(p), Getname(p), source, target, f))) { - Printv(f, tm, "\n", 0); - mreplace (f, argnum, arg, proc_name); + + // If a prefix has been specified make sure it ends in a '_' + + if (prefix) { + if (prefix[strlen (prefix)] != '_') { + prefix[strlen (prefix) + 1] = 0; + prefix[strlen (prefix)] = '_'; } - // no typemap found - // check if typedef and resolve - else if (SwigType_istypedef(Gettype(p))) { - t = SwigType_typedef_resolve(Gettype(p)); + } else + prefix = (char*)"swig_"; + + // Add a symbol for this module + + Preprocessor_define ("SWIGMZSCHEME 1",0); + + // Set name of typemaps + + SWIG_typemap_lang("mzscheme"); - // if a pointer then get it - if (SwigType_ispointer(t)) { - get_pointer (proc_name, i, t, f); + // Read in default typemaps */ + SWIG_config_file("mzscheme.i"); + allow_overloading(); + + } + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); + + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + + init_func_def = NewString(""); + Swig_register_filebyname("init",init_func_def); + + Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); + Swig_banner (f_runtime); + + if (NoInclude) { + Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); + } + + module = Getattr(n,"name"); + + Language::top(n); + + SwigType_emit_type_table (f_runtime, f_wrappers); + Printf(f_init, "Scheme_Object *scheme_reload(Scheme_Env *env) {\n"); + Printf(f_init, "\tScheme_Env *menv = env;\n"); + if (declaremodule) { + Printf(f_init, "\tmenv = scheme_primitive_module(scheme_intern_symbol(\"%s\"), env);\n", module); } - // not a pointer - else throw_unhandled_mzscheme_type_error (Gettype(p)); - } - } + Printf (f_init, "\tSWIG_RegisterTypes(swig_types, swig_types_initial);\n"); + Printf(f_init, "%s\n", Char(init_func_def)); + if (declaremodule) { + Printf(f_init, "\tscheme_finish_primitive_module(menv);\n"); + } + Printf (f_init, "\treturn scheme_void;\n}\n"); + Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n"); + Printf(f_init, "\treturn scheme_reload(env);\n"); + Printf (f_init, "}\n"); + + Printf(f_init,"Scheme_Object *scheme_module_name(void) {\n"); + if (declaremodule) { + Printf(f_init, " return scheme_intern_symbol((char*)\"%s\");\n", module); + } + else { + Printf(f_init," return scheme_make_symbol((char*)\"%s\");\n", module); + } + Printf(f_init,"}\n"); - // Check if there are any constraints. + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * functionWrapper() + * Create a function declaration and register it with the interpreter. + * ------------------------------------------------------------ */ - if ((tm = Swig_typemap_lookup ((char*)"check", - Gettype(p), Getname(p), source, target, f))) { - // Yep. Use it instead of the default - Printv(f, tm, "\n", 0); - mreplace (f, argnum, arg, proc_name); - } - - // Pass output arguments back to the caller. - - if ((tm = Swig_typemap_lookup ((char*)"argout", - Gettype(p), Getname(p), source, target, f))) { - // Yep. Use it instead of the default - Printv(outarg, tm, "\n",0); - mreplace (outarg, argnum, arg, proc_name); - argout_set = 1; - } - - // Free up any memory allocated for the arguments. - if ((tm = Swig_typemap_lookup ((char*)"freearg", - Gettype(p), Getname(p), source, target, f))) { - // Yep. Use it instead of the default - Printv(cleanup, tm, "\n",0); - mreplace (cleanup, argnum, arg, proc_name); - } - i++; + void throw_unhandled_mzscheme_type_error (SwigType *d) + { + Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, + "Unable to handle type %s.\n", SwigType_str(d,0)); } - // Now write code to make the function call + /* Return true iff T is a pointer type */ - emit_func_call (node, f); - - // Now have return value, figure out what to do with it. - - if (SwigType_type(d) == T_VOID) { - if(!argout_set) - Printv(f, tab4, "swig_result = scheme_void;\n",0); + int + is_a_pointer (SwigType *t) + { + return SwigType_ispointer(SwigType_typedef_resolve_all(t)); } - else if ((tm = Swig_typemap_lookup ((char*)"out", - d, name, (char*)"result", (char*)"swig_result", f))) { - Printv(f, tm, "\n",0); - mreplace (f, argnum, arg, proc_name); - } - // no typemap found and not void then create a Scheme_Object holding - // the C pointer and return it - else if (SwigType_ispointer(d)) { - Printv(f, tab4, - "swig_result = swig_make_c_pointer(", - "result, \"", - SwigType_manglestr(d), - "\");\n", 0); - } - else { - throw_unhandled_mzscheme_type_error (d); - } + virtual int functionWrapper(Node *n) { + char *iname = GetChar(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + Parm *p; + + Wrapper *f = NewWrapper(); + String *proc_name = NewString(""); + String *source = NewString(""); + String *target = NewString(""); + String *arg = NewString(""); + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *build = NewString(""); + String *tm; + int argout_set = 0; + int i = 0; + int numargs; + int numreq; + String *overname = 0; - // Dump the argument output code - Printv(f, Char(outarg),0); - - // Dump the argument cleanup code - Printv(f, Char(cleanup),0); - - // Look for any remaining cleanup - - if (NewObject) { - if ((tm = Swig_typemap_lookup ((char*)"newfree", - d, iname, (char*)"result", (char*)"", f))) { - Printv(f, tm, "\n",0); - mreplace (f, argnum, arg, proc_name); - } - } - - // Free any memory allocated by the function being wrapped.. - - if ((tm = Swig_typemap_lookup ((char*)"ret", - d, name, (char*)"result", (char*)"", f))) { - // Yep. Use it instead of the default - Printv(f, tm, "\n",0); - mreplace (f, argnum, arg, proc_name); - } - - // returning multiple values - if(argout_set) { - if(SwigType_type(d) == T_VOID) { - Wrapper_add_local(f, "_lenv", "int _lenv = 0"); - Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); - Printv(f, tab4, "swig_result = scheme_values(_lenv, _values);\n",0); - } - else { - Wrapper_add_local(f, "_lenv", "int _lenv = 1"); - Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); - Printv(f, tab4, "_values[0] = swig_result;\n",0); - Printv(f, tab4, "swig_result = scheme_values(_lenv, _values);\n",0); - } - } - - // Wrap things up (in a manner of speaking) - - Printv(f, tab4, "return swig_result;\n",0); - Printv(f, "}\n",0); - - Printf(f_wrappers,"%s", f); - - // Now register the function - char temp[256]; - sprintf(temp, "%d", numargs); - Printv(init_func_def, "scheme_add_global(\"", proc_name, - "\", scheme_make_prim_w_arity(", wname, - ", \"", proc_name, "\", ", temp, ", ", temp, - "), env);\n",0); - - Delete(proc_name); - Delete(source); - Delete(target); - Delete(argnum); - Delete(arg); - Delete(outarg); - Delete(cleanup); - Delete(build); - Delete(f); -} - -// ----------------------------------------------------------------------- -// MZSCHEME::variable() -// -// Create a link to a C variable. -// This creates a single function _wrap_swig_var_varname(). -// This function takes a single optional argument. If supplied, it means -// we are setting this variable to some value. If omitted, it means we are -// simply evaluating this variable. Either way, we return the variables -// value. -// ----------------------------------------------------------------------- - -void -MZSCHEME::variable (DOH *node) -{ - char *name, *iname; - SwigType *t; - String *proc_name = NewString(""); - char var_name[256]; - char *tm; - String *tm2 = NewString("");; - String *argnum = NewString("0"); - String *arg = NewString("argv[0]"); - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - - // evaluation function names - - sprintf (var_name, "_wrap_%svar_%s", prefix, iname); - - // Build the name for scheme. - Printv(proc_name, iname,0); - Replace(proc_name, "_", "-", DOH_REPLACE_ANY); - - if ((SwigType_type(t) != T_USER) || (SwigType_ispointer(t))) { - - Printf (f_wrappers, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name); - - if ((SwigType_type(t) == T_CHAR) || (SwigType_ispointer(t))){ - Printf (f_wrappers, "\t char *_temp, _ptemp[128];\n"); - Printf (f_wrappers, "\t int _len;\n"); - } - Printf (f_wrappers, "\t Scheme_Object *swig_result;\n"); - - // Check for a setting of the variable value - - Printf (f_wrappers, "\t if (argc) {\n"); - - // Yup. Extract the type from argv[0] and set variable value - - // if (Status & STAT_READONLY) { - // Printf (f_wrappers, "\t\t GSWIG_ASSERT(0,\"Unable to set %s. " - // "Variable is read only.\", argv[0]);\n", iname); - // } - if (ReadOnly) { - Printf (f_wrappers, "\t\t scheme_signal_error(\"Unable to set %s. " - "Variable is read only.\");\n", iname); - } - else if ((tm = Swig_typemap_lookup ((char*)"varin", - t, name, (char*)"argv[0]", name,0))) { - Printv(tm2, tm,0); - mreplace(tm2, argnum, arg, proc_name); - Printv(f_wrappers, tm2, "\n",0); - } - else if (SwigType_ispointer(t)) { - if ((SwigType_type(t) == T_CHAR) && (SwigType_ispointer(t) == 1)) { - Printf (f_wrappers, "\t\t _temp = SCHEME_STR_VAL(argv[0]);\n"); - Printf (f_wrappers, "\t\t _len = SCHEME_STRLEN_VAL(argv[0]);\n"); - Printf (f_wrappers, "\t\t if (%s) { free(%s);}\n", name, name); - Printf (f_wrappers, "\t\t %s = (char *) " - "malloc((_len+1)*sizeof(char));\n", name); - Printf (f_wrappers, "\t\t strncpy(%s,_temp,_len);\n", name); - } else { - // Set the value of a pointer - Printf(f_wrappers, "\t\tif (!swig_get_c_pointer(argv[0], \"%s\", (void **) &arg0))\n", - SwigType_manglestr(t)); - Printf(f_wrappers, "\t\t\tscheme_wrong_type(\"%s\", %s, 0, argc, argv", \ - var_name, SwigType_manglestr(t)); - } - } - else { - throw_unhandled_mzscheme_type_error (t); - } - Printf (f_wrappers, "\t}\n"); - - // Now return the value of the variable (regardless - // of evaluating or setting) - - if ((tm = Swig_typemap_lookup ((char*)"varout", - t, name, name, (char*)"swig_result",0))) { - Printf (f_wrappers, "%s\n", tm); - } - else if (SwigType_ispointer(t)) { - if ((SwigType_type(t) == T_CHAR) && (SwigType_ispointer(t) == 1)) { - Printf (f_wrappers, "\t swig_result = scheme_make_string(%s);\n", name); - } else { - // Is an ordinary pointer type. - Printf(f_wrappers, "\tswig_result = swig_make_c_pointer(%s, \"%s\");\n", - name, SwigType_manglestr(t)); - } - } - else { - throw_unhandled_mzscheme_type_error (t); - } - Printf (f_wrappers, "\t return swig_result;\n"); - Printf (f_wrappers, "}\n"); - - // Now add symbol to the MzScheme interpreter - - Printv(init_func_def, - "scheme_add_global(\"", - proc_name, - "\", scheme_make_prim_w_arity(", - var_name, - ", \"", - proc_name, - "\", ", - "0", - ", ", - "1", - "), env);\n",0); - - } else { - Printf (stderr, "%s:%d. ** Warning. Unable to link with " - " type %s (ignored).\n", - Getfile(node), Getline(node), SwigType_manglestr(t)); - } - Delete(proc_name); - Delete(argnum); - Delete(arg); - Delete(tm2); -} - -// ----------------------------------------------------------------------- -// MZSCHEME::constant() -// -// Makes a constant. Not sure how this is really supposed to work. -// I'm going to fake out SWIG and create a variable instead. -// ------------------------------------------------------------------------ - -void -MZSCHEME::constant(DOH *node) -{ - char *name; - SwigType *type; - char *value; - - int OldStatus = ReadOnly; // Save old status flags - char var_name[256]; - String *proc_name = NewString(""); - String *rvalue = NewString(""); - String *temp = NewString(""); - char *tm; - - name = GetChar(node,"name"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - - ReadOnly = 1; - - // Make a static variable; - - sprintf (var_name, "_wrap_const_%s", name); - - // Build the name for scheme. - Printv(proc_name, name,0); - Replace(proc_name, "_", "-", DOH_REPLACE_ANY); - - if ((SwigType_type(type) == T_USER) && (!SwigType_ispointer(type))) { - fprintf (stderr, "%s:%d. Unsupported constant value.\n", - Getfile(node), Getline(node)); - return; - } - - // See if there's a typemap - - Printv(rvalue, value,0); - if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) == 1)) { - temp = Copy(rvalue); - Clear(rvalue); - Printv(rvalue, "\"", temp, "\"",0); - } - if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) == 0)) { - Delete(temp); - temp = Copy(rvalue); - Clear(rvalue); - Printv(rvalue, "'", temp, "'",0); - } - if ((tm = Swig_typemap_lookup ((char*)"const", type, name, - rvalue, name,0))) { - // Yep. Use it instead of the default - Printf (f_init, "%s\n", tm); - } else { - // Create variable and assign it a value - - Printf (f_header, "static %s %s = ", SwigType_str(type,0), var_name); - if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) <= 1)) { - Printf (f_header, "\"%s\";\n", value); + // Make a wrapper name for this + String *wname = Swig_name_wrapper(iname); + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); } else { - Printf (f_header, "%s;\n", value); + if (!addSymbol(iname,n)) return SWIG_ERROR; } + if (overname) { + Append(wname, overname); + } + Setattr(n,"wrap:name",wname); + + // Build the name for Scheme. + Printv(proc_name, iname,NIL); + Replaceall(proc_name, "_", "-"); + + // writing the function wrapper function + Printv(f->def, "static Scheme_Object *", wname, " (", NIL); + Printv(f->def, "int argc, Scheme_Object **argv", NIL); + Printv(f->def, ")\n{", NIL); + + /* Define the scheme name in C. This define is used by several + macros. */ + Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); + + // Declare return variable and arguments + // number of parameters + // they are called arg0, arg1, ... + // the return value is called result + + emit_args(d, l, f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + + numargs = emit_num_arguments(l); + numreq = emit_num_required(l); + + // adds local variables + Wrapper_add_local(f, "_len", "int _len"); + Wrapper_add_local(f, "lenv", "int lenv = 1"); + Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); + + // Now write code to extract the parameters (this is super ugly) + + for (i = 0, p = l; i < numargs; i++) { + /* Skip ignored arguments */ - // Now create a variable declaration + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + + // Produce names of source and target + Clear(source); + Clear(target); + Clear(arg); + Printf(source, "argv[%d]", i); + Printf(target, "%s",ln); + Printv(arg, Getattr(p,"name"),NIL); + + if (i >= numreq) { + Printf(f->code,"if (argc > %d) {\n",i); + } + // Handle parameter types. + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$source",source); + Replaceall(tm,"$target",target); + Replaceall(tm,"$input",source); + Setattr(p,"emit:input",source); + Printv(f->code, tm, "\n", NIL); + p = Getattr(p,"tmap:in:next"); + } else { + // no typemap found + // check if typedef and resolve + throw_unhandled_mzscheme_type_error (pt); + p = nextSibling(p); + } + if (i >= numreq) { + Printf(f->code,"}\n"); + } + } + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + // Pass output arguments back to the caller. + + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */ + Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */ + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + argout_set = 1; + } else { + p = nextSibling(p); + } + } + + // Free up any memory allocated for the arguments. + + /* Insert cleanup code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + // Now write code to make the function call + + emit_action(n,f); + + // Now have return value, figure out what to do with it. + + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + Replaceall(tm,"$source","result"); + Replaceall(tm,"$target","values[0]"); + Replaceall(tm,"$result","values[0]"); + Printv(f->code, tm, "\n",NIL); + } else { + throw_unhandled_mzscheme_type_error (d); + } + + // Dump the argument output code + Printv(f->code, Char(outarg),NIL); + + // Dump the argument cleanup code + Printv(f->code, Char(cleanup),NIL); + + // Look for any remaining cleanup + + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printv(f->code, tm, "\n",NIL); + } + } + + // Free any memory allocated by the function being wrapped.. + + if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printv(f->code, tm, "\n",NIL); + } + + // Wrap things up (in a manner of speaking) + + Printv(f->code, tab4, "return swig_package_values(lenv, values);\n", NIL); + Printf(f->code, "#undef FUNC_NAME\n"); + Printv(f->code, "}\n",NIL); + + Wrapper_print(f, f_wrappers); + + if (!Getattr(n,"sym:overloaded")) { + + // Now register the function + char temp[256]; + sprintf(temp, "%d", numargs); + Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", + proc_name, wname, proc_name, numreq, numargs); - Hash *nnode = Copy(node); - Setattr(nnode,"name",var_name); - variable (nnode); - Delete(nnode); - ReadOnly = OldStatus; + } else { + if (!Getattr(n,"sym:nextSibling")) { + /* Emit overloading dispatch function */ + + int maxargs; + String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *df = NewWrapper(); + String *dname = Swig_name_wrapper(iname); + + Printv(df->def, + "static Scheme_Object *\n", dname, + "(int argc, Scheme_Object **argv) {", + NIL); + Printv(df->code,dispatch,"\n",NIL); + Printf(df->code,"scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname); + Printv(df->code,"}\n",NIL); + Wrapper_print(df,f_wrappers); + Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", + proc_name, dname, proc_name, 0, maxargs); + DelWrapper(df); + Delete(dispatch); + Delete(dname); + } + } + + Delete(proc_name); + Delete(source); + Delete(target); + Delete(arg); + Delete(outarg); + Delete(cleanup); + Delete(build); + DelWrapper(f); + return SWIG_OK; } - Delete(proc_name); - Delete(rvalue); - Delete(temp); -} -// ---------------------------------------------------------------------- -// MZSCHEME::usage_var(char *iname, SwigType *t, String &usage) -// -// Produces a usage string for a MzScheme variable. -// ---------------------------------------------------------------------- + /* ------------------------------------------------------------ + * variableWrapper() + * + * Create a link to a C variable. + * This creates a single function _wrap_swig_var_varname(). + * This function takes a single optional argument. If supplied, it means + * we are setting this variable to some value. If omitted, it means we are + * simply evaluating this variable. Either way, we return the variables + * value. + * ------------------------------------------------------------ */ -void -MZSCHEME::usage_var (char *iname, SwigType *t, String *usage) -{ - // char temp[1024], *c; + virtual int variableWrapper(Node *n) { - // usage << "(" << iname << " [value])"; - // if (!((t->type != T_USER) || (t->is_pointer))) { - // usage << " - unsupported"; - // } -} - -// --------------------------------------------------------------------------- -// MZSCHEME::usage_func(char *iname, SwigType *t, ParmList *l, String &usage) -// -// Produces a usage string for a function in MzScheme -// --------------------------------------------------------------------------- - -void -MZSCHEME::usage_func (char *iname, SwigType *d, ParmList *l, DOHString *usage) -{ - Parm *p; - - // Print the function name. - - Printv(usage,"(",iname,0); - - // Now go through and print parameters - - for (p = l; p != 0; p = Getnext(p)) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - - if (Getignore(p)) - continue; - - // Print the type. If the parameter has been named, use that as well. - - if (SwigType_type(pt) != T_VOID) { - - // Print the type. - Printv(usage," <", Getname(pt), 0); - if (SwigType_ispointer(pt)) { - for (int j = 0; j < SwigType_ispointer(pt); j++) { - Putc('*', usage); + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + + String *proc_name = NewString(""); + char var_name[256]; + String *tm; + String *tm2 = NewString("");; + String *argnum = NewString("0"); + String *arg = NewString("argv[0]"); + Wrapper *f; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + f = NewWrapper(); + + // evaluation function names + + strcpy(var_name, Char(Swig_name_wrapper(iname))); + + // Build the name for scheme. + Printv(proc_name, iname,NIL); + Replaceall(proc_name, "_", "-"); + + if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { + + Printf (f->def, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name); + Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); + + Wrapper_add_local (f, "swig_result", "Scheme_Object *swig_result"); + + if (!Getattr(n,"feature:immutable")) { + /* Check for a setting of the variable value */ + Printf (f->code, "if (argc) {\n"); + if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { + Replaceall(tm,"$source","argv[0]"); + Replaceall(tm,"$target",name); + Replaceall(tm,"$input","argv[0]"); + Printv(f->code, tm, "\n",NIL); } - } - Putc('>',usage); - - // Print the name if it exists. - if (strlen (Char(pn)) > 0) { - Printv(usage," ", pn, 0); - } - } - Delete(pn); - } - Putc(')',usage); -} - - -// --------------------------------------------------------------------------- -// MZSCHEME::usage_returns(char *iname, SwigType *t, ParmList *l, String &usage) -// -// Produces a usage string for a function in MzScheme -// --------------------------------------------------------------------------- - -void -MZSCHEME::usage_returns (char *iname, SwigType *d, ParmList *l, DOHString *usage) -{ - Parm *p; - DOHString *param; - int have_param = 0, j; - - param = NewString(""); - - Clear(usage); - Printf(usage,"returns "); - - // go through and see if any are output. - - for (p = l; p != 0; p = Getnext(p)) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - - if (strcmp (Char(pn),"BOTH") && strcmp (Char(pn),"OUTPUT")) - continue; - - // Print the type. If the parameter has been named, use that as well. - - if (SwigType_type(pt) != T_VOID) { - ++have_param; - - // Print the type. - Printv(param," $", Getname(pt), 0); - if (SwigType_ispointer(pt)) { - for (j = 0; j < SwigType_ispointer(pt) - 1; j++) { - Putc('*',param); + else { + throw_unhandled_mzscheme_type_error (t); } + Printf (f->code, "}\n"); } - Printf(param,"# "); + + // Now return the value of the variable (regardless + // of evaluating or setting) + + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$source",name); + Replaceall(tm,"$target","swig_result"); + Replaceall(tm,"$result","swig_result"); + Printf (f->code, "%s\n", tm); + } + else { + throw_unhandled_mzscheme_type_error (t); + } + Printf (f->code, "\nreturn swig_result;\n"); + Printf (f->code, "#undef FUNC_NAME\n"); + Printf (f->code, "}\n"); + + Wrapper_print (f, f_wrappers); + + // Now add symbol to the MzScheme interpreter + + Printv(init_func_def, + "scheme_add_global(\"", + proc_name, + "\", scheme_make_prim_w_arity(", + var_name, + ", \"", + proc_name, + "\", ", + "0", + ", ", + "1", + "), menv);\n",NIL); + + } else { + Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, + "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); } - Delete(pn); + Delete(proc_name); + Delete(argnum); + Delete(arg); + Delete(tm2); + DelWrapper(f); + return SWIG_OK; } - // See if we stick on the function return type. - if (SwigType_type(d) != T_VOID || have_param == 0) { - ++have_param; - if (SwigType_type(d) == T_VOID) - Insert(param,0," unspecified"); - else { - Insert(param,0,"# "); - Insert(param,0,SwigType_str(d,0)); - Insert(param,0," $"); + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + + String *var_name = NewString(""); + String *proc_name = NewString(""); + String *rvalue = NewString(""); + String *temp = NewString(""); + String *tm; + + // Make a static variable; + + Printf (var_name, "_wrap_const_%s", Swig_name_mangle(iname)); + + // Build the name for scheme. + Printv(proc_name, iname,NIL); + Replaceall(proc_name, "_", "-"); + + if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value.\n"); + return SWIG_NOWRAP; } + + // See if there's a typemap + + Printv(rvalue, value,NIL); + if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) { + temp = Copy(rvalue); + Clear(rvalue); + Printv(rvalue, "\"", temp, "\"",NIL); + } + if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) { + Delete(temp); + temp = Copy(rvalue); + Clear(rvalue); + Printv(rvalue, "'", temp, "'",NIL); + } + if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) { + Replaceall(tm,"$source",rvalue); + Replaceall(tm,"$value",rvalue); + Replaceall(tm,"$target",name); + Printf (f_init, "%s\n", tm); + } else { + // Create variable and assign it a value + + Printf (f_header, "static %s = ", SwigType_lstr(type,var_name)); + if ((SwigType_type(type) == T_STRING)) { + Printf (f_header, "\"%s\";\n", value); + } else if (SwigType_type(type) == T_CHAR) { + Printf (f_header, "\'%s\';\n", value); + } else { + Printf (f_header, "%s;\n", value); + } + + // Now create a variable declaration + + { + /* Hack alert: will cleanup later -- Dave */ + Node *n = NewHash(); + Setattr(n,"name",var_name); + Setattr(n,"sym:name",iname); + Setattr(n,"type", type); + variableWrapper(n); + Delete(n); + } + } + Delete(proc_name); + Delete(rvalue); + Delete(temp); + return SWIG_OK; } - // Kill extra white space. - // Sorry. Not implemented: param.strip(); - Replace(param,"$", "<", DOH_REPLACE_ANY); - Replace(param,"#", ">", DOH_REPLACE_ANY); - Replace(param,"><", "> <", DOH_REPLACE_ANY); - - // If there are multiple return values put them in a list. - if (have_param > 1) { - Insert(param,0,"("); - Append(param,")"); + /* ------------------------------------------------------------ + * validIdentifer() + * ------------------------------------------------------------ */ + + virtual int validIdentifier(String *s) { + char *c = Char(s); + /* Check whether we have an R5RS identifier.*/ + /* --> * | */ + /* --> | */ + if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') + || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') + || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') + || (*c == '^') || (*c == '_') || (*c == '~'))) { + /* --> + | - | ... */ + if ((strcmp(c, "+") == 0) + || strcmp(c, "-") == 0 + || strcmp(c, "...") == 0) return 1; + else return 0; + } + /* --> | | */ + while (*c) { + if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') + || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') + || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') + || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') + || (*c == '-') || (*c == '.') || (*c == '@'))) return 0; + c++; + } + return 1; } - Printv(usage,param,0); - Delete(param); +}; + +/* ----------------------------------------------------------------------------- + * swig_mzscheme() - Instantiate module + * ----------------------------------------------------------------------------- */ + +extern "C" Language * +swig_mzscheme(void) { + return new MZSCHEME(); } -// ---------------------------------------------------------------------- -// MZSCHEME::usage_const(char *iname, SwigType *type, char *value, String &usage) -// -// Produces a usage string for a MzScheme constant -// ---------------------------------------------------------------------- - -void -MZSCHEME::usage_const (char *iname, SwigType *, char *value, DOHString *usage) -{ - Printv(usage,"(", iname, " ", value, ")", 0); -} diff --git a/Source/Modules1.1/mzscheme.h b/Source/Modules1.1/mzscheme.h deleted file mode 100644 index 8aa38ebcb..000000000 --- a/Source/Modules1.1/mzscheme.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - *******************************************************************************/ - -/************************************************************************** - * $Header$ - * - * class MZSCHEME - * - * Mzscheme implementation - * (Caution : This is *somewhat* experimental) - * - **************************************************************************/ - -class MZSCHEME : public Language -{ -private: - void get_pointer(DOHString_or_char *name, int parm, SwigType *t, Wrapper *f); - void usage_var(char *, SwigType *, DOHString *usage); - void usage_func(char *, SwigType *, ParmList *, DOHString *usage); - void usage_returns(char *, SwigType *, ParmList *, DOHString *usage); - void usage_const(char *, SwigType *, char *, DOHString *usage); - -public : - void parse_args (int, char *argv[]); - void initialize(String *module); - void function (DOH *node); - void variable (DOH *node); - void constant (DOH *node); - void close (void); - void create_command (String *, String *) { }; -}; diff --git a/Source/Modules1.1/ocaml.cxx b/Source/Modules1.1/ocaml.cxx new file mode 100755 index 000000000..786fee5dd --- /dev/null +++ b/Source/Modules1.1/ocaml.cxx @@ -0,0 +1,1072 @@ +/* -*- c-indentation-style: gnu -*- */ +/****************************************************************************** + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : Art Yerkes + * Modified from mzscheme.cxx : David Beazley + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *****************************************************************************/ + +char cvsroot_ocaml_cxx[] = "$Header$"; + +/*********************************************************************** + * $Header$ + * + * ocaml.cxx + * + * Definitions for adding functions to Ocaml 101 + ***********************************************************************/ + +#include "swigmod.h" + +#include + +static const char *ocaml_usage = (char*)"\ +\n\ +Ocaml Options (available with -ocaml)\n\ +-help - Print this help\n\ +-prefix name - Set a prefix to be appended to all names\n\ +\n"; + +static int classmode = 0; +static int in_constructor = 0, in_destructor = 0, in_copyconst = 0; +static int const_enum = 0; +static int static_member_function = 0; +static char *prefix=0; +static String *classname=0; +static String *module=0; +static char *ocaml_path=(char*)"ocaml"; +static String *init_func_def = 0; + +static Hash *seen_enums = 0; +static Hash *seen_enumvalues = 0; +static Hash *seen_constructors = 0; + +static File *f_header = 0; +static File *f_runtime = 0; +static File *f_wrappers = 0; +static File *f_init = 0; +static File *f_mlout = 0; +static File *f_mliout = 0; +static File *f_mlbody = 0; +static File *f_mlibody = 0; +static File *f_enumtypes_type = 0; +static File *f_enumtypes_value = 0; +static File *f_class_ctors = 0; +static File *f_class_ctors_end = 0; +static File *f_enum_to_int = 0; +static File *f_int_to_enum = 0; + +class OCAML : public Language { +public: + + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ + + virtual void main (int argc, char *argv[]) { + + int i; + + SWIG_library_directory(ocaml_path); + + // Look for certain command line options + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp (argv[i], "-help") == 0) { + fputs (ocaml_usage, stderr); + SWIG_exit (0); + } + else if (strcmp (argv[i], "-prefix") == 0) { + if (argv[i + 1]) { + prefix = new char[strlen(argv[i + 1]) + 2]; + strcpy(prefix, argv[i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error(); + } + } + } + } + + // If a prefix has been specified make sure it ends in a '_' + + if (prefix) { + if (prefix[strlen (prefix)] != '_') { + prefix[strlen (prefix) + 1] = 0; + prefix[strlen (prefix)] = '_'; + } + } else + prefix = (char*)"swig_"; + + // Add a symbol for this module + + Preprocessor_define ("SWIGOCAML 1",0); + + // Set name of typemaps + + SWIG_typemap_lang("ocaml"); + + // Read in default typemaps */ + SWIG_config_file("ocaml.i"); + allow_overloading(); + + } + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); + + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + f_enumtypes_type = NewString(""); + f_enumtypes_value = NewString(""); + f_mlbody = NewString(""); + f_mlibody = NewString(""); + f_class_ctors = NewString(""); + f_class_ctors_end = NewString(""); + f_enum_to_int = NewString(""); + f_int_to_enum = NewString(""); + + module = Getattr(n,"name"); + + seen_constructors = NewHash(); + seen_enums = NewHash(); + seen_enumvalues = NewHash(); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("mli",f_mlibody); + Swig_register_filebyname("ml",f_mlbody); + + init_func_def = NewString(""); + Swig_register_filebyname("init",init_func_def); + + Swig_name_register("set","%v__set__"); + Swig_name_register("get","%v__get__"); + + Printf(f_runtime, + "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); + Printf( f_runtime, "#define SWIG_MODULE \"%s\"\n", module ); + /* Module name */ + Printf( f_mlbody, "let module_name = \"%s\"\n", module ); + Printf( f_mlibody, "val module_name : string\n" ); + Printf( f_enum_to_int, + "let enum_to_int x v =\n" + " match v with C_enum y -> (\n" + " match (x : c_enum_type) with\n" + " `unknown -> (match (y : c_enum_tag) with\n" + " `int (x : int) -> C_int x\n" + " | _ -> (raise (LabelNotFromThisEnum v)))\n" + ); + + Printf( f_int_to_enum, + "let int_to_enum x y =\n" + " match (x : c_enum_type) with\n" + " `unknown -> C_enum (`int y)\n" ); + + Swig_banner (f_runtime); + + if (NoInclude) { + Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); + } + + /* Produce the enum_to_int and int_to_enum functions */ + + Printf(f_enumtypes_type,"type c_enum_type = [ \n `unknown\n" ); + Printf(f_enumtypes_value,"type c_enum_tag = [ \n `int of int\n" ); + + String *mlfile = NewString(""); + String *mlifile = NewString(""); + + Printv(mlfile,module,".ml",NIL); + Printv(mlifile,module,".mli",NIL); + + f_mlout = NewFile(mlfile,"w"); + f_mliout = NewFile(mlifile,"w"); + + Language::top(n); + + Printf( f_enum_to_int, + ") | _ -> (C_int (get_int v))\n" + "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", + module ); + Printf( f_mlibody, + "val enum_to_int : c_enum_type -> c_obj -> c_obj\n" ); + + Printf( f_int_to_enum, + "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n", + module ); + Printf( f_mlibody, + "val int_to_enum : c_enum_type -> int -> c_obj\n" ); + Printf( f_enumtypes_type, "]\n" ); + Printf( f_enumtypes_value, "]\n" ); + + SwigType_emit_type_table (f_runtime, f_wrappers); + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + + Dump(f_enumtypes_type,f_mlout); + Dump(f_enumtypes_value,f_mlout); + Dump(f_mlbody,f_mlout); + Dump(f_enum_to_int,f_mlout); + Dump(f_int_to_enum,f_mlout); + Delete(f_int_to_enum); + Delete(f_enum_to_int); + Dump(f_class_ctors,f_mlout); + Dump(f_class_ctors_end,f_mlout); + Close(f_mlout); + Delete(f_mlout); + + Dump(f_enumtypes_type,f_mliout); + Dump(f_enumtypes_value,f_mliout); + Dump(f_mlibody,f_mliout); + Close(f_mliout); + Delete(f_mliout); + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * functionWrapper() + * Create a function declaration and register it with the interpreter. + * ------------------------------------------------------------ */ + + void throw_unhandled_ocaml_type_error (SwigType *d) + { + Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, + "Unable to handle type %s.\n", SwigType_str(d,0)); + } + + /* Return true iff T is a pointer type */ + + int + is_a_pointer (SwigType *t) + { + return SwigType_ispointer(SwigType_typedef_resolve_all(t)); + } + + virtual int functionWrapper(Node *n) { + char *iname = GetChar(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + Parm *p; + + Wrapper *f = NewWrapper(); + String *proc_name = NewString(""); + String *source = NewString(""); + String *target = NewString(""); + String *arg = NewString(""); + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *build = NewString(""); + String *tm; + int argout_set = 0; + int i = 0; + int numargs; + int numreq; + int newobj = Getattr(n,"feature:new") ? 1 : 0; + String *overname = 0; + + // Make a wrapper name for this + String *wname = Swig_name_wrapper(iname); + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); + } else { + if (!addSymbol(iname,n)) return SWIG_ERROR; + } + if (overname) { + Append(wname, overname); + } + Setattr(n,"wrap:name",wname); + + // Build the name for Scheme. + Printv(proc_name,"_",iname,NIL); + String *mangled_name = mangleNameForCaml(proc_name); + + if( classmode && in_constructor ) { // Emit constructor for object + String *mangled_name_nounder = + NewString((char *)(Char(mangled_name))+1); + Printf( f_class_ctors_end, + "let %s clst = _%s clst\n", + mangled_name_nounder, mangled_name_nounder ); + Printf(f_mlibody, + "val %s : c_obj -> c_obj\n", + mangled_name_nounder ); + Delete(mangled_name_nounder); + } else if( classmode && in_destructor ) { + Printf(f_class_ctors, + " \"~\", %s ;\n", mangled_name ); + } else if( classmode && !in_constructor && !in_destructor && + !static_member_function ) { + String *opname = Copy(Getattr(n,"name")); + + Replaceall(opname,"operator ",""); + + if( strstr( Char(mangled_name), "__get__" ) ) { + String *set_name = Copy(mangled_name); + if( !Getattr(n,"feature:immutable") ) { + Replaceall(set_name,"__get__","__set__"); + Printf(f_class_ctors, + " \"%s\", (fun args -> " + "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n", + opname, mangled_name, set_name ); + Delete(set_name); + } else { + Printf(f_class_ctors, + " \"%s\", (fun args -> " + "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n", + opname, mangled_name ); + } + } else if( strstr( Char(mangled_name), "__set__" ) ) { + ; /* Nothing ... handled by the case above */ + } else { + Printf(f_class_ctors, + " \"%s\", %s ;\n", + opname, mangled_name); + } + + Delete(opname); + } + + if( classmode && in_constructor ) { + Setattr(seen_constructors,mangled_name,"true"); + } + + // writing the function wrapper function + Printv(f->def, + "#ifdef __cplusplus\n" + "extern \"C\"\n" + "#endif\n" + "value ", wname, " (", NIL); + Printv(f->def, "value args", NIL); + Printv(f->def, ")\n{", NIL); + + /* Define the scheme name in C. This define is used by several + macros. */ + Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL); + + // adds local variables + Wrapper_add_local(f, "args", "CAMLparam1(args)"); + Wrapper_add_local(f, "ret", "CAMLlocal2(swig_result,rv)"); + Wrapper_add_local(f, "_len", "int _len"); + Wrapper_add_local(f, "lenv", "int lenv = 1"); + Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)"); + Wrapper_add_local(f, "argv", "value *argv"); + Wrapper_add_local(f, "i", "int i"); + + Printv( f->code, + "argv = (value *)malloc( argc * sizeof( value ) );\n" + "for( i = 0; i < argc; i++ ) {\n" + " argv[i] = caml_list_nth(args,i);\n" + "}\n", NIL ); + + // Declare return variable and arguments + // number of parameters + // they are called arg0, arg1, ... + // the return value is called result + + emit_args(d, l, f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + + numargs = emit_num_arguments(l); + numreq = emit_num_required(l); + + Printf(f->code,"swig_result = Val_unit;\n" ); + + // Now write code to extract the parameters (this is super ugly) + + for (i = 0, p = l; i < numargs; i++) { + /* Skip ignored arguments */ + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + + // Produce names of source and target + Clear(source); + Clear(target); + Clear(arg); + Printf(source, "caml_list_nth(args,%d)", i); + Printf(target, "%s",ln); + Printv(arg, Getattr(p,"name"),NIL); + + if (i >= numreq) { + Printf(f->code,"if (caml_list_length(args) > %d) {\n",i); + } + // Handle parameter types. + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$source",source); + Replaceall(tm,"$target",target); + Replaceall(tm,"$input",source); + Setattr(p,"emit:input",source); + Printv(f->code, tm, "\n", NIL); + p = Getattr(p,"tmap:in:next"); + } else { + // no typemap found + // check if typedef and resolve + throw_unhandled_ocaml_type_error (pt); + p = nextSibling(p); + } + if (i >= numreq) { + Printf(f->code,"}\n"); + } + } + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + // Pass output arguments back to the caller. + + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */ + Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */ + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + argout_set = 1; + } else { + p = nextSibling(p); + } + } + + // Free up any memory allocated for the arguments. + + /* Insert cleanup code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + // Now write code to make the function call + + emit_action(n,f); + + // Now have return value, figure out what to do with it. + + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + Replaceall(tm,"$source","result"); + Replaceall(tm,"$target","rv"); + Replaceall(tm,"$result","rv"); + Printv(f->code, tm, "\n",NIL); + } else { + throw_unhandled_ocaml_type_error (d); + } + + // Dump the argument output code + Printv(f->code, Char(outarg),NIL); + + // Dump the argument cleanup code + Printv(f->code, Char(cleanup),NIL); + + // Look for any remaining cleanup + + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printv(f->code, tm, "\n",NIL); + } + } + + // Free any memory allocated by the function being wrapped.. + + if ((tm = Swig_typemap_lookup_new("swig_result",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printv(f->code, tm, "\n",NIL); + } + + // Wrap things up (in a manner of speaking) + + Printv(f->code, + tab4, "swig_result = caml_list_append(swig_result,rv);\n" + tab4, "free( argv );\n" + tab4, "if( lenv == 0 )\n" + tab4, "{\n" + tab4, tab4, "CAMLreturn(Val_unit);\n", + tab4, "}\n" + tab4, "else\n" + tab4, "{\n", + tab4, tab4, "CAMLreturn(swig_result);\n", + tab4, "}\n", NIL); + Printf(f->code, "#undef FUNC_NAME\n"); + Printv(f->code, "}\n",NIL); + + Wrapper_print(f, f_wrappers); + + if( Getattr(n,"sym:overloaded") ) { + if( !Getattr(n,"sym:nextSibling") ) { + int maxargs; + Wrapper *df = NewWrapper(); + String *dname = Swig_name_wrapper(iname); + String *dispatch = + Swig_overload_dispatch(n, + "free(argv);\nCAMLreturn(%s(args));\n", + &maxargs); + + Wrapper_add_local(df, "argv", "value *argv"); + + Printv(df->def, + "#ifdef __cplusplus\n" + "extern \"C\"\n" + "#endif\n" + "value ",dname,"(value args) {\n" + " CAMLparam1(args);\n" + " int i;\n" + " int argc = caml_list_length(args);\n",NIL); + Printv( df->code, + "argv = (value *)malloc( argc * sizeof( value ) );\n" + "for( i = 0; i < argc; i++ ) {\n" + " argv[i] = caml_list_nth(args,i);\n" + "}\n", NIL ); + Printv(df->code,dispatch,"\n",NIL); + Printf(df->code,"failwith(\"No matching function for overloaded '%s'\");\n", iname); + Printv(df->code,"}\n",NIL); + Wrapper_print(df,f_wrappers); + + Printf(f_mlbody, + "external %s_f : c_obj list -> c_obj list = \"%s\"\n" + "let %s = fnhelper %s %s_f\n", + mangled_name, dname, mangled_name, + newobj ? "true" : "false", + mangled_name ); + if( !classmode || in_constructor || in_destructor || + static_member_function ) + Printf(f_mlibody, + "(* overload *)\n" + "val %s : c_obj -> c_obj\n", mangled_name ); + + DelWrapper(df); + Delete(dispatch); + Delete(dname); + } + } else { + Printf(f_mlbody, + "external %s_f : c_obj list -> c_obj list = \"%s\"\n" + "let %s = fnhelper %s %s_f\n", + mangled_name, wname, mangled_name, newobj ? "true" : "false", + mangled_name ); + if( !classmode || in_constructor || in_destructor || + static_member_function ) + Printf(f_mlibody, + "(* Non-overload *)\n" + "val %s : c_obj -> c_obj\n", mangled_name ); + } + + Delete(proc_name); + Delete(source); + Delete(target); + Delete(arg); + Delete(outarg); + Delete(cleanup); + Delete(build); + DelWrapper(f); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * variableWrapper() + * + * Create a link to a C variable. + * This creates a single function _wrap_swig_var_varname(). + * This function takes a single optional argument. If supplied, it means + * we are setting this variable to some value. If omitted, it means we are + * simply evaluating this variable. Either way, we return the variables + * value. + * ------------------------------------------------------------ */ + + virtual int variableWrapper(Node *n) { + + char *name = GetChar(n,"name"); + String *iname = Getattr(n,"sym:name"); + String *mname = mangleNameForCaml(iname); + SwigType *t = Getattr(n,"type"); + + String *proc_name = NewString(""); + char var_name[256]; + String *tm; + String *tm2 = NewString("");; + String *argnum = NewString("0"); + String *arg = NewString("Field(args,0)"); + Wrapper *f; + + if (!iname || !addSymbol(iname,n)) return SWIG_ERROR; + + f = NewWrapper(); + + // evaluation function names + + strcpy(var_name, Char(Swig_name_wrapper(iname))); + + // Build the name for scheme. + Printv(proc_name, iname,NIL); + //Replaceall(proc_name, "_", "-"); + + if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { + + Printf (f->def, + "#ifdef __cplusplus\n" + "extern \"C\"\n" + "#endif\n" + "value %s(value args) {\n", var_name); + Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); + + Wrapper_add_local (f, "swig_result", "value swig_result"); + + if (!Getattr(n,"feature:immutable")) { + /* Check for a setting of the variable value */ + Printf (f->code, "if (args != Val_int(0)) {\n"); + if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { + Replaceall(tm,"$source","args"); + Replaceall(tm,"$target",name); + Replaceall(tm,"$input","args"); + Printv(f->code, tm, "\n",NIL); + } else { + throw_unhandled_ocaml_type_error (t); + } + Printf (f->code, "}\n"); + } + + // Now return the value of the variable (regardless + // of evaluating or setting) + + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$source",name); + Replaceall(tm,"$target","swig_result"); + Replaceall(tm,"$result","swig_result"); + Printf (f->code, "%s\n", tm); + } else { + throw_unhandled_ocaml_type_error (t); + } + + Printf (f->code, "\nreturn swig_result;\n"); + Printf (f->code, "#undef FUNC_NAME\n"); + Printf (f->code, "}\n"); + + Wrapper_print (f, f_wrappers); + + // Now add symbol to the Ocaml interpreter + + if( Getattr( n, "feature:immutable" ) ) { + Printf( f_mlbody, + "external __%s : c_obj -> c_obj = \"%s\"\n" + "let _%s = __%s C_void\n", + mname, var_name, mname, mname ); + Printf( f_mlibody, "val _%s : c_obj\n", iname ); + if( const_enum ) { + Printf( f_enum_to_int, + " | `%s -> _%s\n", + mname, mname ); + Printf( f_int_to_enum, + " if y = (get_int _%s) then `%s else\n", + mname, mname ); + } + } else { + Printf( f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n", + mname, var_name ); + Printf( f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n", + mname, var_name ); + } + } else { + Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, + "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); + } + + Delete(proc_name); + Delete(argnum); + Delete(arg); + Delete(tm2); + DelWrapper(f); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmemberfunctionHandler -- + * Overridden to set static_member_function + * ------------------------------------------------------------ */ + + virtual int staticmemberfunctionHandler( Node *n ) { + int rv; + static_member_function = 1; + rv = Language::staticmemberfunctionHandler( n ); + static_member_function = 0; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + + String *var_name = NewString(""); + String *proc_name = NewString(""); + String *rvalue = NewString(""); + String *temp = NewString(""); + String *tm; + + // Make a static variable; + + Printf (var_name, "_wrap_const_%s", Swig_name_mangle(iname)); + + // Build the name for scheme. + Printv(proc_name, iname,NIL); + //Replaceall(proc_name, "_", "-"); + + if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value.\n"); + return SWIG_NOWRAP; + } + + // See if there's a typemap + + Printv(rvalue, value,NIL); + if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) { + temp = Copy(rvalue); + Clear(rvalue); + Printv(rvalue, "\"", temp, "\"",NIL); + } + if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) { + Delete(temp); + temp = Copy(rvalue); + Clear(rvalue); + Printv(rvalue, "'", temp, "'",NIL); + } + if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) { + Replaceall(tm,"$source",rvalue); + Replaceall(tm,"$value",rvalue); + Replaceall(tm,"$target",name); + Printf (f_init, "%s\n", tm); + } else { + // Create variable and assign it a value + + Printf (f_header, "static %s = ", SwigType_lstr(type,var_name)); + if ((SwigType_type(type) == T_STRING)) { + Printf (f_header, "\"%s\";\n", value); + } else if (SwigType_type(type) == T_CHAR) { + Printf (f_header, "\'%s\';\n", value); + } else { + Printf (f_header, "%s;\n", value); + } + + { + /* Hack alert: will cleanup later -- Dave */ + Node *n = NewHash(); + Setattr(n,"name",var_name); + Setattr(n,"sym:name",iname); + Setattr(n,"type", type); + Setattr(n,"feature:immutable","1"); + variableWrapper(n); + Delete(n); + } + } + Delete(proc_name); + Delete(rvalue); + Delete(temp); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * validIdentifer() + * ------------------------------------------------------------ */ + + virtual int validIdentifier(String *s) { +#if 0 + char *c = Char(s); + /* Check whether we have an R5RS identifier.*/ + /* --> * | */ + /* --> | */ + if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') + || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') + || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') + || (*c == '^') || (*c == '_') || (*c == '~'))) { + /* --> + | - | ... */ + if ((strcmp(c, "+") == 0) + || strcmp(c, "-") == 0 + || strcmp(c, "...") == 0) return 1; + else return 0; + } + /* --> | | */ + while (*c) { + if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') + || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') + || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') + || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') + || (*c == '-') || (*c == '.') || (*c == '@'))) return 0; + c++; + } +#endif + return 1; + } + + int constructorHandler(Node *n) { + int ret; + + in_constructor = 1; + ret = Language::constructorHandler(n); + in_constructor = 0; + + return ret; + } + + int destructorHandler(Node *n) { + int ret; + + in_destructor = 1; + ret = Language::destructorHandler(n); + in_destructor = 0; + + return ret; + } + + int copyconstructorHandler(Node *n) { + int ret; + + in_copyconst = 1; + in_constructor = 1; + ret = Language::copyconstructorHandler(n); + in_constructor = 0; + in_copyconst = 0; + + return ret; + } + + int classHandler( Node *n ) { + String *name = Getattr(n,"name"); + String *mangled_sym_name = mangleNameForCaml(name); + + if( !name ) return SWIG_OK; + + classname = mangled_sym_name; + + Printf( f_class_ctors, + "let create_%s_from_ptr raw_ptr =\n" + " C_obj (let rec method_table = [\n" + " \"nop\", (fun args -> C_void) ;\n", + classname ); + + Printf( f_mlibody, + "val create_%s_from_ptr : c_obj -> c_obj\n", + classname ); + + classmode = 1; + int rv = Language::classHandler(n); + classmode = 0; + +#if 0 + Printf(f_mlibody, + "val delete_%s : c_obj -> unit\n", + mangled_sym_name ); +#endif + + /* Handle up-casts in a nice way */ + List *baselist = Getattr(n,"bases"); + if (baselist && Len(baselist)) { + Node *base = Firstitem(baselist); + while (base) { + String *bname = Getattr(base, "ocaml:ctor"); + if (bname) + Printv(f_class_ctors, + " \"::",bname,"\", (fun args -> " + "create_",bname,"_from_ptr raw_ptr) ;\n",NIL); + + base = Nextitem(baselist); + } + } + + Printf(f_class_ctors, + " \"&\", (fun args -> raw_ptr) ;\n" + " \":parents\",\n" + " (fun args -> \n" + " C_list \n" + " (List.map \n" + " (fun (x,y) -> \n" + " C_string (String.sub x 2 ((String.length x) - 2)))\n" + " (List.filter \n" + " (fun (x,y) -> \n" + " ((String.length x) > 2) && \n" + " x.[0] == ':' && \n" + " x.[1] == ':') method_table))) ;\n" + " \":classof\", (fun args -> (C_string \"%s\")) ;\n" + " \":methods\", " + "(fun args -> C_list (List.map (fun (x,y) -> C_string x) " + "method_table)) ] in\n" + " (fun mth arg ->\n" + " try\n" + " let method_name,application = List.hd (List.filter (fun (x,y) -> x = mth) method_table) in\n" + " application \n" + " (match arg with C_list l -> (C_list (raw_ptr :: l)) | C_void -> (C_list [ raw_ptr ]) | v -> (C_list [ raw_ptr ; v ]))\n" + " with (Failure \"hd\") -> \n" + " (* Try parent classes *)\n" + " begin\n" + " let parent_classes = [ \n", + name ); + + /* Handle inheritance -- Mostly stolen from python code */ + baselist = Getattr(n,"bases"); + if (baselist && Len(baselist)) { + Node *base = Firstitem(baselist); + while (base) { + String *bname = Getattr(base, "ocaml:ctor"); + if (bname) + Printv(f_class_ctors, + " create_",bname,"_from_ptr",NIL); + + base = Nextitem(baselist); + if (base) + Printv(f_class_ctors," ;\n",NIL); + else + Printv(f_class_ctors,"\n",NIL); + } + } + + Printv(f_class_ctors," ]\n",NIL); + + Printf(f_class_ctors, + " in let rec try_parent plist raw_ptr = \n" + " match plist with\n" + " p :: tl -> (try\n" + " (invoke (p raw_ptr)) mth arg\n" + " with (BadMethodName (p,m,s)) -> try_parent tl raw_ptr)\n" + " | [] ->\n" + " raise (BadMethodName (raw_ptr,mth,\"%s\"))\n" + " in try_parent parent_classes raw_ptr\n" + " end\n" + " | e -> raise e))\n", + name ); + + Printf( f_class_ctors, + "let _ = Callback.register \"create_%s_from_ptr\" " + "create_%s_from_ptr\n", + classname, classname ); + + Setattr(n,"ocaml:ctor",classname); + + return rv; + } + + String *mangleNameForCaml( String *s ) { + String *out = Copy(s); + Replaceall(out," ","_"); + Replaceall(out,"::","_"); + Replaceall(out,",","_x_"); + Replaceall(out,"+","__plus__"); + Replaceall(out,"-","__minus__"); + Replaceall(out,"<","__ldbrace__"); + Replaceall(out,">","__rdbrace__"); + Replaceall(out,"!","__not__"); + Replaceall(out,"%","__mod__"); + Replaceall(out,"^","__xor__"); + Replaceall(out,"*","__star__"); + Replaceall(out,"&","__amp__"); + Replaceall(out,"|","__or__"); + Replaceall(out,"(","__lparen__"); + Replaceall(out,")","__rparen__"); + Replaceall(out,"[","__lbrace__"); + Replaceall(out,"]","__rbrace__"); + Replaceall(out,"~","__bnot__"); + Replaceall(out,"=","__equals__"); + Replaceall(out,"/","__slash__"); + Replaceall(out,".","__dot__"); + return out; + } + + /* Benedikt Grundmann inspired --> Enum wrap styles */ + + int enumvalueDeclaration(Node *n) { + String *name = Getattr(n,"name"); + + if( const_enum && name && !Getattr(seen_enumvalues,name) ) { + Printf( f_enumtypes_value,"| `%s\n", name ); + Setattr(seen_enumvalues,name,"true"); + Setattr(n,"feature:immutable","1"); + + return constantWrapper(n); + } else return SWIG_OK; + } + + int enumDeclaration(Node *n) { + String *name = Getattr(n,"name"); + + if( name && !Getattr(seen_enums,name) ) { + const_enum = 1; + Printf( f_enum_to_int, "| `%s -> (match (y : c_enum_tag) with\n", name ); + Printf( f_int_to_enum, "| `%s -> C_enum (\n", name ); + Printf( f_mlbody, + "let _ = Callback.register \"%s_marker\" (`%s)\n", + name, name ); + Printf( f_enumtypes_type,"| `%s\n", name ); + Setattr(seen_enumvalues,name,"true"); + } + + int ret = Language::enumDeclaration(n); + + if( const_enum ) { + Printf( f_int_to_enum, "`int y)\n", name ); + Printf( f_enum_to_int, + "| `int (x : int) -> C_int x\n" + "| _ -> raise (Failure \"Unknown enum tag\"))\n" ); + } + + const_enum = 0; + + return ret; + } +}; + +/* ------------------------------------------------------------------------- + * swig_ocaml() - Instantiate module + * ------------------------------------------------------------------------- */ + +extern "C" Language * +swig_ocaml(void) { + return new OCAML(); +} + diff --git a/Source/Modules1.1/overload.cxx b/Source/Modules1.1/overload.cxx new file mode 100644 index 000000000..f62e63f93 --- /dev/null +++ b/Source/Modules1.1/overload.cxx @@ -0,0 +1,338 @@ +/* ----------------------------------------------------------------------------- + * overload.cxx + * + * This file is used to analyze overloaded functions and methods. + * It looks at signatures and tries to gather information for + * building a dispatch function. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_overload_cxx[] = "$Header$"; + +#include "swigmod.h" + +#define MAX_OVERLOAD 256 + +extern int emit_num_required(ParmList *); + +/* ----------------------------------------------------------------------------- + * Swig_overload_rank() + * + * This function takes an overloaded declaration and creates a list that ranks + * all overloaded methods in an order that can be used to generate a dispatch + * function. + * ----------------------------------------------------------------------------- */ + +struct Overloaded { + Node *n; /* Node */ + int argc; /* Argument count */ + ParmList *parms; /* Parameters used for overload check */ + int error; /* Ambiguity error */ +}; + +List * +Swig_overload_rank(Node *n) { + Overloaded nodes[MAX_OVERLOAD]; + int nnodes = 0; + Node *o = Getattr(n,"sym:overloaded"); + Node *c; + + if (!o) return 0; + + c = o; + while (c) { + if (!Getattr(c,"error")) { + if (Getattr(c,"wrap:name")) { + nodes[nnodes].n = c; + nodes[nnodes].parms = Getattr(c,"wrap:parms"); + nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms); + nodes[nnodes].error = 0; + nnodes++; + } + } + c = Getattr(c,"sym:nextSibling"); + } + + /* Sort the declarations by required argument count */ + { + int i,j; + for (i = 0; i < nnodes; i++) { + for (j = i+1; j < nnodes; j++) { + if (nodes[i].argc > nodes[j].argc) { + Overloaded t = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = t; + } + } + } + } + + /* Sort the declarations by argument types */ + { + int i,j; + for (i = 0; i < nnodes-1; i++) { + if (nodes[i].argc == nodes[i+1].argc) { + for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) { + Parm *p1 = nodes[i].parms; + Parm *p2 = nodes[j].parms; + int differ = 0; + int num_checked = 0; + while (p1 && p2 && (num_checked < nodes[i].argc)) { + // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type")); + if (checkAttribute(p1,"tmap:in:numinputs","0")) { + p1 = Getattr(p1,"tmap:in:next"); + continue; + } + if (checkAttribute(p2,"tmap:in:numinputs","0")) { + p2 = Getattr(p2,"tmap:in:next"); + continue; + } + String *t1 = Getattr(p1,"tmap:typecheck:precedence"); + String *t2 = Getattr(p2,"tmap:typecheck:precedence"); + if ((!t1) && (!nodes[i].error)) { + Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n), + "Overloaded %s(%s) not supported (no type checking rule for '%s').\n", + Getattr(nodes[i].n,"name"),ParmList_str(Getattr(nodes[i].n,"parms")), + SwigType_str(Getattr(p1,"type"),0)); + nodes[i].error = 1; + } else if ((!t2) && (!nodes[j].error)) { + Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded %s(%s) not supported (no type checking rule for '%s').\n", + Getattr(nodes[j].n,"name"),ParmList_str(Getattr(nodes[j].n,"parms")), + SwigType_str(Getattr(p2,"type"),0)); + nodes[j].error = 1; + } + if (t1 && t2) { + int t1v, t2v; + t1v = atoi(Char(t1)); + t2v = atoi(Char(t2)); + differ = t1v-t2v; + } + else if (!t1 && t2) differ = 1; + else if (t2 && !t1) differ = -1; + else if (!t1 && !t2) differ = -1; + num_checked++; + if (differ > 0) { + Overloaded t = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = t; + break; + } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) { + t1 = Getattr(p1,"ltype"); + if (!t1) { + t1 = SwigType_ltype(Getattr(p1,"type")); + if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) { + SwigType_add_pointer(t1); + } + Setattr(p1,"ltype",t1); + } + t2 = Getattr(p2,"ltype"); + if (!t2) { + t2 = SwigType_ltype(Getattr(p2,"type")); + if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) { + SwigType_add_pointer(t2); + } + Setattr(p2,"ltype",t2); + } + + /* Need subtype check here. If t2 is a subtype of t1, then we need to change the + order */ + + if (SwigType_issubtype(t2,t1)) { + Overloaded t = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = t; + } + + if (Strcmp(t1,t2) != 0) { + differ = 1; + break; + } + } else if (differ) { + break; + } + if (Getattr(p1,"tmap:in:next")) { + p1 = Getattr(p1,"tmap:in:next"); + } else { + p1 = nextSibling(p1); + } + if (Getattr(p2,"tmap:in:next")) { + p2 = Getattr(p2,"tmap:in:next"); + } else { + p2 = nextSibling(p2); + } + } + if (!differ) { + /* See if declarations differ by const only */ + String *d1 = Getattr(nodes[i].n,"decl"); + String *d2 = Getattr(nodes[j].n,"decl"); + if (d1 && d2) { + String *dq1 = Copy(d1); + String *dq2 = Copy(d2); + if (SwigType_isconst(d1)) { + SwigType_pop(dq1); + } + if (SwigType_isconst(d2)) { + SwigType_pop(dq2); + } + if (Strcmp(dq1,dq2) == 0) { + + if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { + Overloaded t = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = t; + differ = 1; + if (!nodes[j].error) { + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", + Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), + Getfile(nodes[i].n), Getline(nodes[i].n)); + } + nodes[j].error = 1; + } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { + differ = 1; + if (!nodes[j].error) { + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", + Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), + Getfile(nodes[i].n), Getline(nodes[i].n)); + } + nodes[j].error = 1; + } + } + Delete(dq1); + Delete(dq2); + } + } + if (!differ) { + if (!nodes[j].error) { + Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded %s(%s) is shadowed by %s(%s) at %s:%d.\n", + Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), + Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms), + Getfile(nodes[i].n),Getline(nodes[i].n)); + nodes[j].error = 1; + } + } + } + } + } + } + List *result = NewList(); + { + int i; + for (i = 0; i < nnodes; i++) { + Append(result,nodes[i].n); + // Printf(stdout,"[ %d ] %s\n", i, ParmList_protostr(nodes[i].parms)); + // Swig_print_node(nodes[i].n); + } + } + return result; +} + +/* ----------------------------------------------------------------------------- + * Swig_overload_dispatch() + * + * Generate a dispatch function. argc is assumed to hold the argument count. + * argv is the argument vector. + * + * Note that for C++ class member functions, Swig_overload_dispatch() assumes + * that argc includes the "self" argument and that the first element of argv[] + * is the "self" argument. So for a member function: + * + * Foo::bar(int x, int y, int z); + * + * the argc should be 4 (not 3!) and the first element of argv[] would be + * the appropriate scripting language reference to "self". For regular + * functions (and static class functions) the argc and argv only include + * the regular function arguments. + * ----------------------------------------------------------------------------- */ + +static bool print_typecheck(String *f, int j, Parm *pj) +{ + char tmp[256]; + sprintf(tmp,"argv[%d]",j); + String *tm = Getattr(pj,"tmap:typecheck"); + if (tm) { + Replaceid(tm,Getattr(pj,"lname"),"_v"); + Replaceall(tm,"$input", tmp); + Printv(f,tm,"\n",NIL); + return true; + } + else + return false; +} + +String * +Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *maxargs) { + int i,j; + + *maxargs = 1; + + String *f = NewString(""); + + /* Get a list of methods ranked by precedence values and argument count */ + List *dispatch = Swig_overload_rank(n); + int nfunc = Len(dispatch); + + /* Loop over the functions */ + + for (i = 0; i < nfunc; i++) { + Node *ni = Getitem(dispatch,i); + Parm *pi = Getattr(ni,"wrap:parms"); + int num_required = emit_num_required(pi); + int num_arguments = emit_num_arguments(pi); + if (num_arguments > *maxargs) *maxargs = num_arguments; + int varargs = emit_isvarargs(pi); + + if (!varargs) { + if (num_required == num_arguments) { + Printf(f,"if (argc == %d) {\n", num_required); + } else { + Printf(f,"if ((argc >= %d) && (argc <= %d)) {\n", num_required, num_arguments); + } + } else { + Printf(f,"if (argc >= %d) {\n", num_required); + } + + if (num_arguments) { + Printf(f,"int _v;\n"); + } + + int num_braces = 0; + j = 0; + Parm *pj = pi; + while (pj) { + if (checkAttribute(pj,"tmap:in:numinputs","0")) { + pj = Getattr(pj,"tmap:in:next"); + continue; + } + if (j >= num_required) { + Printf(f, "if (argc <= %d) {\n", j); + Printf(f, Char(fmt),Getattr(ni,"wrap:name")); + Printf(f, "}\n"); + } + if (print_typecheck(f, j, pj)) { + Printf(f, "if (_v) {\n"); + num_braces++; + } + Parm *pk = Getattr(pj,"tmap:in:next"); + if (pk) pj = pk; + else pj = nextSibling(pj); + j++; + } + Printf(f, Char(fmt),Getattr(ni,"wrap:name")); + /* close braces */ + for (/* empty */; num_braces > 0; num_braces--) + Printf(f, "}\n"); + Printf(f,"}\n"); /* braces closes "if" for this method */ + } + Delete(dispatch); + return f; +} + + diff --git a/Source/Modules1.1/perl5.cxx b/Source/Modules1.1/perl5.cxx index fb04cafdd..94191080d 100644 --- a/Source/Modules1.1/perl5.cxx +++ b/Source/Modules1.1/perl5.cxx @@ -1,4 +1,4 @@ -/* ----------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- * perl5.cxx * * Generate Perl5 wrappers @@ -7,1950 +7,1588 @@ * Loic Dachary (loic@ceic.com) * David Fletcher * Gary Holt + * Jason Stewart (jason@openinformatics.com) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ + * ------------------------------------------------------------------------- */ -/* DB: I had to take some features related to package naming out of this to - get the new type system to work. These need to be put back in at some point. */ +char cvsroot_perl5_cxx[] = "$Header$"; -static char cvsroot[] = "$Header$"; +#include "swigmod.h" -#include "swig11.h" -#include "perl5.h" +#ifndef MACSWIG +#include "swigconfig.h" +#endif -static char *usage = (char*)"\ +static const char *usage = (char*)"\ Perl5 Options (available with -perl5)\n\ - -module name - Set module name\n\ - -interface name - Set interface name\n\ - -package name - Set package prefix\n\ + -ldflags - Print runtime libraries to link with\n\ -static - Omit code related to dynamic loading.\n\ - -shadow - Create shadow classes.\n\ + -nopm - Do not generate the .pm file.\n\ + -proxy - Create proxy classes.\n\ + -const - Wrap constants as constants and not variables (implies -shadow).\n\ -compat - Compatibility mode.\n\n"; -static String *smodule = 0; static int compat = 0; -static int export_all = 0; -static String *package = 0; +static int no_pmfile = 0; + +static int export_all = 0; + +/* + * pmfile + * set by the -pm flag, overrides the name of the .pm file + */ +static String *pmfile = 0; + +/* + * module + * set by the %module directive, e.g. "Xerces". It will determine + * the name of the .pm file, and the dynamic library. + */ static String *module = 0; -static String *interface = 0; -static String *cmodule = 0; -static String *vinit = 0; -static FILE *f_pm = 0; -static String *pm; /* Package initialization code */ -static String *magic; /* Magic variable wrappers */ + +/* + * fullmodule + * the fully namespace qualified name of the module, e.g. "XML::Xerces" + * it will be used to set the package namespace in the .pm file, as + * well as the name of the initialization methods in the glue library + */ +static String *fullmodule = 0; +/* + * cmodule + * the namespace of the internal glue code, set to the value of + * module with a 'c' appended + */ +static String *cmodule = 0; + +static String *command_tab = 0; +static String *constant_tab = 0; +static String *variable_tab = 0; + +static File *f_runtime = 0; +static File *f_header = 0; +static File *f_wrappers = 0; +static File *f_init = 0; +static File *f_pm = 0; +static String *pm; /* Package initialization code */ +static String *magic; /* Magic variable wrappers */ static int is_static = 0; /* The following variables are used to manage Perl5 classes */ -static int blessed = 0; /* Enable object oriented features */ -static Hash *classes = 0; /* A hash table for storing the classes we've seen so far */ -static Hash *symbols = 0; -static int have_constructor = 0; -static int have_destructor= 0; -static int have_data_members = 0; -static String *class_name = 0; /* Name of the class (what Perl thinks it is) */ -static String *class_type = 0; /* Type of class "struct", "class", "union" */ -static String *real_classname = 0; /* Real name of C/C++ class */ -static String *base_class = 0; /* Base class (if using inheritance) */ -static int class_renamed = 0; +static int blessed = 0; /* Enable object oriented features */ +static int do_constants = 0; /* Constant wrapping */ +static List *classlist = 0; /* List of classes */ +static int have_constructor = 0; +static int have_destructor= 0; +static int have_data_members = 0; +static String *class_name = 0; /* Name of the class (what Perl thinks it is) */ +static String *real_classname = 0; /* Real name of C/C++ class */ static String *fullclassname = 0; static String *pcode = 0; /* Perl code associated with each class */ static String *blessedmembers = 0; /* Member data associated with each class */ static int member_func = 0; /* Set to 1 when wrapping a member function */ -static String *realpackage = 0; /* Name of real module */ -static String *func_stubs = 0; /* Function stubs */ -static String *var_stubs = 0; /* Variable stubs */ -static String *member_keys = 0; /* Keys for all member data */ -static String *exported = 0; /* Exported symbols */ +static String *func_stubs = 0; /* Function stubs */ +static String *const_stubs = 0; /* Constant stubs */ +static int num_consts = 0; /* Number of constants */ +static String *var_stubs = 0; /* Variable stubs */ +static String *exported = 0; /* Exported symbols */ static String *pragma_include = 0; +static Hash *operators = 0; +static int have_operators = 0; +class PERL5 : public Language { +public: -/* Test to see if a type corresponds to something wrapped with a shadow class */ -static DOH *is_shadow(SwigType *t) { - DOH *r; - SwigType *lt = Swig_clocal_type(t); - r = Getattr(classes,lt); - Delete(lt); - return r; -} - -/* ----------------------------------------------------------------------------- - * PERL5::parse_args() - * ----------------------------------------------------------------------------- */ -void -PERL5::parse_args(int argc, char *argv[]) { - int i = 1; - - cmodule = NewString(""); - Swig_swiglib_set("perl5"); - for (i = 1; i < argc; i++) { - if (argv[i]) { - if(strcmp(argv[i],"-package") == 0) { - if (argv[i+1]) { - package = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if(strcmp(argv[i],"-interface") == 0) { - if (argv[i+1]) { - interface = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i],"-exportall") == 0) { - export_all = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-static") == 0) { - is_static = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-shadow") == 0) { - blessed = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-compat") == 0) { - compat = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); - } + /* Test to see if a type corresponds to something wrapped with a shadow class */ + Node *is_shadow(SwigType *t) { + Node *n; + n = classLookup(t); + /* Printf(stdout,"'%s' --> '%x'\n", t, n); */ + if (n) { + if (!Getattr(n,"perl5:proxy")) { + setclassname(n); } + return Getattr(n,"perl5:proxy"); + } + return 0; } - Preprocessor_define((void *) "SWIGPERL 1", 0); - Preprocessor_define((void *) "SWIGPERL5 1", 0); -} + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ -/* ----------------------------------------------------------------------------- - * PERL5::initialize() - * ----------------------------------------------------------------------------- */ -void -PERL5::initialize(String *modname) -{ - char filen[256]; + virtual void main(int argc, char *argv[]) { + int i = 1; - classes = NewHash(); - symbols = NewHash(); + SWIG_library_directory("perl5"); + for (i = 1; i < argc; i++) { + if (argv[i]) { + if(strcmp(argv[i],"-package") == 0) { + Printf(stderr,"*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n"); + SWIG_exit(EXIT_FAILURE); + } else if(strcmp(argv[i],"-interface") == 0) { + Printf(stderr,"*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n"); + SWIG_exit(EXIT_FAILURE); + } else if (strcmp(argv[i],"-exportall") == 0) { + export_all = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-static") == 0) { + is_static = 1; + Swig_mark_arg(i); + } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) { + blessed = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-const") == 0) { + do_constants = 1; + blessed = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-nopm") == 0) { + no_pmfile = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-pm") == 0) { + Swig_mark_arg(i); + i++; + pmfile = NewString(argv[i]); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-compat") == 0) { + compat = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_PERL_RUNTIME); + SWIG_exit (EXIT_SUCCESS); + } + } + } - vinit = NewString(""); - pm = NewString(""); - func_stubs = NewString(""); - var_stubs = NewString(""); - exported = NewString(""); - magic = NewString(""); - pragma_include = NewString(""); - - Swig_banner(f_runtime); - - if (NoInclude) { - Printf(f_header,"#define SWIG_NOINCLUDE\n"); + Preprocessor_define("SWIGPERL 1", 0); + Preprocessor_define("SWIGPERL5 1", 0); + SWIG_typemap_lang("perl5"); + SWIG_config_file("perl5.swg"); + allow_overloading(); } - if (Swig_insert_file("common.swg", f_runtime) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate 'common.swg' in SWIG library.\n"); - Swig_exit (EXIT_FAILURE); - } + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ - if (Swig_insert_file("perl5.swg", f_runtime) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate 'perl5.swg' in SWIG library.\n"); - Swig_exit (EXIT_FAILURE); - } + virtual int top(Node *n) { - if (!module) module = NewString(modname); + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); - /* Create a C module name and put it in 'cmodule' */ - Clear(cmodule); - Append(cmodule,module); - Replace(cmodule,":","_",DOH_REPLACE_ANY); + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); - if (!package) { - package = NewString(module); - } + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",f_init); + + classlist = NewList(); + + pm = NewString(""); + func_stubs = NewString(""); + var_stubs = NewString(""); + const_stubs = NewString(""); + exported = NewString(""); + magic = NewString(""); + pragma_include = NewString(""); + + command_tab = NewString("static swig_command_info swig_commands[] = {\n"); + constant_tab = NewString("static swig_constant_info swig_constants[] = {\n"); + variable_tab = NewString("static swig_variable_info swig_variables[] = {\n"); + + Swig_banner(f_runtime); + + if (NoInclude) { + Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); + } + + module = Copy(Getattr(n,"name")); /* If we're in blessed mode, change the package name to "packagec" */ - if (blessed) { - realpackage = package; - package = interface ? interface : NewStringf("%sc",package); - } else { - realpackage = NewString(package); - } + + if (blessed) { + cmodule = NewStringf("%sc",module); + } else { + cmodule = NewString(module); + } + fullmodule = NewString(module); /* Create a .pm file * Need to strip off any prefixes that might be found in * the module name */ - { - char *m = Char(module) + Len(module); - while (m != Char(module)) { - if (*m == ':') { - m++; - break; + if (no_pmfile) { + f_pm = NewString(0); + } else { + if (pmfile == NULL) { + char *m = Char(module) + Len(module); + while (m != Char(module)) { + if (*m == ':') { + m++; + break; + } + m--; + } + pmfile = NewStringf("%s.pm", m); } - m--; + String *filen = NewStringf("%s%s", Swig_file_dirname(outfile),pmfile); + if ((f_pm = NewFile(filen,"w")) == 0) { + Printf(stderr,"Unable to open %s\n", filen); + SWIG_exit (EXIT_FAILURE); + } + Swig_register_filebyname("pm",f_pm); } - sprintf(filen,"%s%s.pm", output_dir,m); - if ((f_pm = fopen(filen,"w")) == 0) { - Printf(stderr,"Unable to open %s\n", filen); - Swig_exit (EXIT_FAILURE); + { + String *tmp = NewString(fullmodule); + Replaceall(tmp,":","_"); + Printf(f_header,"#define SWIG_init boot_%s\n\n", tmp); + Printf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", cmodule, tmp); + Printf(f_header,"#define SWIG_prefix \"%s::\"\n", cmodule); + Delete(tmp); } - } - if (!blessed) { - smodule = NewString(module); - } else if (is_static) { - smodule = NewStringf("%sc",module); - Append(cmodule,"c"); - Append(cmodule,"c"); - } else { - smodule = NewString(module); - } - { - String *tmp = NewString(realpackage); - Replace(tmp,":","_", DOH_REPLACE_ANY); - Printf(f_header,"#define SWIG_init boot_%s\n\n", tmp); - Printf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", package, tmp); - Delete(tmp); - } - Printf(f_header,"#define SWIG_varinit \"%s::var_%s_init();\"\n", package, cmodule); - Printf(f_header,"#ifdef __cplusplus\n"); - Printf(f_header,"extern \"C\"\n"); - Printf(f_header,"#endif\n"); - Printf(f_header,"#ifndef PERL_OBJECT\n"); - Printf(f_header,"SWIGEXPORT(void) SWIG_init (CV* cv);\n"); - Printf(f_header,"#else\n"); - Printf(f_header,"SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *);\n"); - Printf(f_header,"#endif\n"); - Printf(f_init,"#ifdef __cplusplus\n"); - Printf(f_init,"extern \"C\"\n"); - Printf(f_init,"#endif\n"); - Printf(f_init,"XS(SWIG_init) {\n"); - Printf(f_init,"\t dXSARGS;\n"); - Printf(f_init,"\t int i;\n"); - Printf(f_init,"\t char *file = __FILE__;\n"); - Printv(f_init, - "for (i = 0; swig_types_initial[i]; i++) {\n", - "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", - "}\n", 0); - Printf(f_init,"\t newXS(\"%s::var_%s_init\", _wrap_perl5_%s_var_init, file);\n",package,cmodule, cmodule); + Printf(f_pm,"# This file was automatically generated by SWIG\n"); + Printf(f_pm,"package %s;\n",fullmodule); - Printv(vinit, - "XS(_wrap_perl5_", cmodule, "_var_init) {\n", - tab4, "dXSARGS;\n", - tab4, "SV *sv;\n", - 0); + Printf(f_pm,"require Exporter;\n"); + if (!is_static) { + Printf(f_pm,"require DynaLoader;\n"); + Printf(f_pm,"@ISA = qw(Exporter DynaLoader);\n"); + } else { + Printf(f_pm,"@ISA = qw(Exporter);\n"); + } - Printf(f_pm,"# This file was automatically generated by SWIG\n"); - Printf(f_pm,"package %s;\n",realpackage); - Printf(f_pm,"require Exporter;\n"); - if (!is_static) { - Printf(f_pm,"require DynaLoader;\n"); - Printf(f_pm,"@ISA = qw(Exporter DynaLoader);\n"); - } else { - Printf(f_pm,"@ISA = qw(Exporter);\n"); - } + /* Start creating magic code */ - /* Start creating magic code */ + Printv(magic, + "#ifdef PERL_OBJECT\n", + "#define MAGIC_CLASS _wrap_", module, "_var::\n", + "class _wrap_", module, "_var : public CPerlObj {\n", + "public:\n", + "#else\n", + "#define MAGIC_CLASS\n", + "#endif\n", + "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *sv, MAGIC *mg) {\n", + tab4, "MAGIC_PPERL\n", + tab4, "sv = sv; mg = mg;\n", + tab4, "croak(\"Value is read-only.\");\n", + tab4, "return 0;\n", + "}\n", + NIL); - Printv(magic, - "#ifdef PERL_OBJECT\n", - "#define MAGIC_CLASS _wrap_", module, "_var::\n", - "class _wrap_", module, "_var : public CPerlObj {\n", - "public:\n", - "#else\n", - "#define MAGIC_CLASS\n", - "#endif\n", - "SWIGCLASS_STATIC int swig_magic_readonly(SV *sv, MAGIC *mg) {\n", - tab4, "MAGIC_PPERL\n", - tab4, "sv = sv; mg = mg;\n", - tab4, "croak(\"Value is read-only.\");\n", - tab4, "return 0;\n", - "}\n", - 0); -} + Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); -/* ----------------------------------------------------------------------------- - * PERL5::import() - * ----------------------------------------------------------------------------- */ -void -PERL5::import(String *modname) { - if (blessed) { - Printf(f_pm,"require %s;\n", modname); - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::close() - * ----------------------------------------------------------------------------- */ -void -PERL5::close(void) { - String *base = NewString(""); + /* emit wrappers */ + Language::top(n); + String *base = NewString(""); + /* Dump out variable wrappers */ - Printv(magic, - "\n\n#ifdef PERL_OBJECT\n", - "};\n", - "#endif\n", - 0); + Printv(magic, + "\n\n#ifdef PERL_OBJECT\n", + "};\n", + "#endif\n", + NIL); - Printf(f_header,"%s\n", magic); + Printf(f_header,"%s\n", magic); - String *type_table = NewString(""); - SwigType_emit_type_table(f_runtime,type_table); + String *type_table = NewString(""); + SwigType_emit_type_table(f_runtime,type_table); /* Patch the type table to reflect the names used by shadow classes */ - if (blessed) { - SwigType *type; - for (type = Firstkey(classes); type; type = Nextkey(classes)) { - String *mangle = NewStringf("\"%s\"", SwigType_manglestr(type)); - String *rep = NewStringf("\"%s\"", Getattr(classes,type)); - Replace(type_table,mangle,rep,DOH_REPLACE_ANY); - Delete(mangle); - Delete(rep); - } - } - - Printf(f_wrappers,"%s",type_table); - Delete(type_table); - - /* Printf(stdout,"::: Perl shadow :::\n\n%s",classes); */ - - Printf(f_init,"\t ST(0) = &PL_sv_yes;\n"); - Printf(f_init,"\t XSRETURN(1);\n"); - Printf(f_init,"}\n"); - - Printv(vinit,tab4, "XSRETURN(1);\n", "}\n", 0); - Printf(f_wrappers,"%s", vinit); - - Printf(f_pm,"package %s;\n", package); - - if (!is_static) { - Printf(f_pm,"bootstrap %s;\n", realpackage); - } else { - String *tmp = NewString(realpackage); - Replace(tmp,":","_",DOH_REPLACE_ANY); - Printf(f_pm,"boot_%s();\n", tmp); - Delete(tmp); - } - Printf(f_pm,"var_%s_init();\n", cmodule); - Printf(f_pm,"%s",pragma_include); - Printf(f_pm,"package %s;\n", realpackage); - Printf(f_pm,"@EXPORT = qw(%s );\n",exported); - - if (blessed) { - - Printv(base, - "\n# ---------- BASE METHODS -------------\n\n", - "package ", realpackage, ";\n\n", - 0); - - /* Write out the TIE method */ - - Printv(base, - "sub TIEHASH {\n", - tab4, "my ($classname,$obj) = @_;\n", - tab4, "return bless $obj, $classname;\n", - "}\n\n", - 0); - - /* Output a CLEAR method. This is just a place-holder, but by providing it we - * can make declarations such as - * %$u = ( x => 2, y=>3, z =>4 ); - * - * Where x,y,z are the members of some C/C++ object. */ - - Printf(base,"sub CLEAR { }\n\n"); - - /* Output default firstkey/nextkey methods */ - - Printf(base, "sub FIRSTKEY { }\n\n"); - Printf(base, "sub NEXTKEY { }\n\n"); - - /* Output a 'this' method */ - - Printv(base, - "sub this {\n", - tab4, "my $ptr = shift;\n", - tab4, "return tied(%$ptr);\n", - "}\n\n", - 0); - - Printf(f_pm,"%s",base); - - /* Emit function stubs for stand-alone functions */ - - Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n"); - Printf(f_pm,"package %s;\n\n",realpackage); - Printf(f_pm,"%s",func_stubs); - - /* Emit package code for different classes */ - - Printf(f_pm,"%s",pm); - - /* Emit variable stubs */ - - Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n"); - Printf(f_pm,"package %s;\n\n",realpackage); - Printf(f_pm,"%s",var_stubs); - } - - Printf(f_pm,"1;\n"); - fclose(f_pm); - Delete(base); -} - -/* ----------------------------------------------------------------------------- - * get_pointer() - * ----------------------------------------------------------------------------- */ -static void -get_pointer(char *iname, char *srcname, char *src, char *dest, - SwigType *t, String *f, char *ret) { - - SwigType_remember(t); - SwigType *lt = Swig_clocal_type(t); - Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) &", dest, ",", 0); - - /* If we're passing a void pointer, we give the pointer conversion a NULL - pointer, otherwise pass in the expected type. */ - - if (Cmp(lt,"p.void") == 0) { - Printf(f, " 0 ) < 0) {\n"); - } else { - Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",0); - } - - Printv(f, - "croak(\"Type error in ", srcname, " of ", iname,". Expected %s\", SWIGTYPE", - SwigType_manglestr(t), "->name);\n", - ret, ";\n", - "}\n", - 0); - Delete(lt); -} - -/* ----------------------------------------------------------------------------- - * PERL5::create_command() - * ----------------------------------------------------------------------------- */ -void -PERL5::create_command(String *cname, String *iname) { - Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(cname)); - if (export_all) { - Printf(exported,"%s ",iname); - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::create_function() - * ----------------------------------------------------------------------------- */ -void -PERL5::function(DOH *node) -{ - char *name, *iname; - SwigType *d; - ParmList *l; - Parm *p; - int pcount,i,j; - Wrapper *f; - char source[256],target[256],temp[256], argnum[32]; - char *tm; - String *cleanup, *outarg; - int numopt = 0; - int need_save, num_saved = 0; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - d = Getattr(node,"type"); - l = Getattr(node,"parms"); - - f = NewWrapper(); - cleanup = NewString(""); - outarg = NewString(""); - - Printv(f, "XS(", Swig_name_wrapper(iname), ") {\n", 0); - - pcount = emit_args(node, f); - numopt = check_numopt(l); - - Wrapper_add_local(f,"argvi","int argvi = 0"); - - /* Check the number of arguments */ - - Printf(f," if ((items < %d) || (items > %d)) \n", pcount-numopt, ParmList_numarg(l)); - Printf(f," croak(\"Usage: %s\");\n", usage_func(iname,d,l)); - - /* Write code to extract parameters. */ - i = 0; - j = 0; - for (p = l; p; p = Getnext(p)) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - - /* Produce string representation of source and target arguments */ - sprintf(source,"ST(%d)",j); - sprintf(target,"%s", Char(Getlname(p))); - sprintf(argnum,"%d",j+1); - - /* Check to see if this argument is being ignored */ - if (!Getignore(p)) { - /* Check for optional argument */ - if (j>= (pcount-numopt)) - Printf(f," if (items > %d) {\n", j); - - if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) { - Printf(f,"%s\n",tm); - Replace(f,"$argnum",argnum,DOH_REPLACE_ANY); - Replace(f,"$arg",source,DOH_REPLACE_ANY); - } else { - switch(SwigType_type(pt)) { - case T_BOOL: - case T_INT : - case T_SHORT : - case T_LONG : - case T_SCHAR: - case T_UINT: - case T_USHORT: - case T_ULONG: - case T_UCHAR: - Printf(f," %s = (%s)SvIV(ST(%d));\n", target, SwigType_lstr(pt,0),j); - break; - case T_CHAR : - - Printf(f," %s = (char) *SvPV(ST(%d),PL_na);\n", target, j); - break; - - case T_DOUBLE : - case T_FLOAT : - Printf(f," %s = (%s)SvNV(ST(%d));\n", target, SwigType_lstr(pt,0), j); - break; - - case T_VOID : - break; - - case T_USER: - SwigType_add_pointer(pt); - sprintf(temp,"argument %d", i+1); - get_pointer(iname, temp, source, target, pt, f, (char *)"XSRETURN(1)"); - SwigType_del_pointer(pt); - break; - - case T_STRING: - Printf(f," if (! SvOK((SV*) ST(%d))) { %s = 0; }\n", j, target); - Printf(f," else { %s = (char *) SvPV(ST(%d),PL_na); }\n", target,j); - break; - - case T_POINTER: case T_ARRAY: case T_REFERENCE: - sprintf(temp,"argument %d", i+1); - get_pointer(iname,temp,source,target, pt, f, (char*)"XSRETURN(1)"); - break; - - default : - Printf(stderr,"%s:%d. Unable to use type %s as a function argument.\n",Getfile(node), Getline(node), SwigType_str(pt,0)); - break; + if (blessed) { + Node *cls; + for (cls = Firstitem(classlist); cls; cls = Nextitem(classlist)) { + if (Getattr(cls,"perl5:proxy")) { + SwigType *type = Copy(Getattr(cls,"classtype")); + SwigType_add_pointer(type); + String *mangle = NewStringf("\"%s\"", SwigType_manglestr(type)); + String *rep = NewStringf("\"%s\"", Getattr(cls,"perl5:proxy")); + Replaceall(type_table,mangle,rep); + Delete(mangle); + Delete(rep); + Delete(type); } } - /* The source is going to be an array of saved values. */ - sprintf(temp,"_saved[%d]",num_saved); - if (j>= (pcount-numopt)) - Printf(f," } \n"); - j++; + } + + Printf(f_wrappers,"%s",type_table); + Delete(type_table); + + Printf(constant_tab,"{0}\n};\n"); + Printv(f_wrappers,constant_tab,NIL); + + Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n"); + + Printf(f_init,"\t ST(0) = &PL_sv_yes;\n"); + Printf(f_init,"\t XSRETURN(1);\n"); + Printf(f_init,"}\n"); + + /* Finish off tables */ + Printf(variable_tab, "{0}\n};\n"); + Printv(f_wrappers,variable_tab,NIL); + + Printf(command_tab,"{0,0}\n};\n"); + Printv(f_wrappers,command_tab,NIL); + + + Printf(f_pm,"package %s;\n", cmodule); + + if (!is_static) { + Printf(f_pm,"bootstrap %s;\n", fullmodule); } else { - temp[0] = 0; + String *tmp = NewString(fullmodule); + Replaceall(tmp,":","_"); + Printf(f_pm,"boot_%s();\n", tmp); + Delete(tmp); + } + Printf(f_pm,"%s",pragma_include); + Printf(f_pm,"package %s;\n", fullmodule); + Printf(f_pm,"@EXPORT = qw( %s);\n",exported); + + if (blessed) { + + Printv(base, + "\n# ---------- BASE METHODS -------------\n\n", + "package ", fullmodule, ";\n\n", + NIL); + + /* Write out the TIE method */ + + Printv(base, + "sub TIEHASH {\n", + tab4, "my ($classname,$obj) = @_;\n", + tab4, "return bless $obj, $classname;\n", + "}\n\n", + NIL); + + /* Output a CLEAR method. This is just a place-holder, but by providing it we + * can make declarations such as + * %$u = ( x => 2, y=>3, z =>4 ); + * + * Where x,y,z are the members of some C/C++ object. */ + + Printf(base,"sub CLEAR { }\n\n"); + + /* Output default firstkey/nextkey methods */ + + Printf(base, "sub FIRSTKEY { }\n\n"); + Printf(base, "sub NEXTKEY { }\n\n"); + + /* Output a 'this' method */ + + Printv(base, + "sub this {\n", + tab4, "my $ptr = shift;\n", + tab4, "return tied(%$ptr);\n", + "}\n\n", + NIL); + + Printf(f_pm,"%s",base); + + /* Emit function stubs for stand-alone functions */ + + Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n"); + Printf(f_pm,"package %s;\n\n",fullmodule); + Printf(f_pm,"%s",func_stubs); + + /* Emit package code for different classes */ + Printf(f_pm,"%s",pm); + + if (num_consts > 0) { + /* Emit constant stubs */ + Printf(f_pm,"\n# ------- CONSTANT STUBS -------\n\n"); + Printf(f_pm,"package %s;\n\n",fullmodule); + Printf(f_pm,"%s",const_stubs); + } + + /* Emit variable stubs */ + + Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n"); + Printf(f_pm,"package %s;\n\n",fullmodule); + Printf(f_pm,"%s",var_stubs); } - /* Check if there is any constraint code */ - if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) { - Printf(f,"%s\n", tm); - Replace(f,"$argnum",argnum, DOH_REPLACE_ANY); - } - need_save = 0; + Printf(f_pm,"1;\n"); + Close(f_pm); + Delete(f_pm); + Delete(base); - if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,temp,0))) { - Printf(cleanup,"%s\n", tm); - Replace(cleanup,"$argnum",argnum,DOH_REPLACE_ANY); - Replace(cleanup,"$arg",temp,DOH_REPLACE_ANY); - need_save = 1; - } - if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"ST(argvi)",0))) { - String *tempstr = NewString(tm); - Replace(tempstr,"$argnum",argnum, DOH_REPLACE_ANY); - Replace(tempstr,"$arg",temp, DOH_REPLACE_ANY); - Printf(outarg,"%s\n", tempstr); - Delete(tempstr); - need_save = 1; - } - /* If we need a saved variable, we need to emit to emit some code for that - This only applies if the argument actually existed (not ignore) */ - if ((need_save) && (!Getignore(p))) { - Printv(f, tab4, temp, " = ", source, ";\n", 0); - num_saved++; - } - i++; + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + return SWIG_OK; } - /* If there were any saved arguments, emit a local variable for them */ - if (num_saved) { - sprintf(temp,"_saved[%d]",num_saved); - Wrapper_add_localv(f,"_saved","SV *",temp,0); - } + /* ------------------------------------------------------------ + * importDirective(Node *n) + * ------------------------------------------------------------ */ - /* Now write code to make the function call */ - - emit_func_call(node,f); - - if ((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"ST(argvi)",0))) { - Printf(f, "%s\n", tm); - } else { - if (SwigType_type(d) != T_VOID) { - Printf(f," ST(argvi) = sv_newmortal();\n"); - switch (SwigType_type(d)) { - case T_INT: case T_BOOL: case T_UINT: - case T_SHORT: case T_USHORT: - case T_LONG : case T_ULONG: - case T_SCHAR: case T_UCHAR : - Printf(f," sv_setiv(ST(argvi++),(IV) result);\n"); - break; - case T_DOUBLE : - case T_FLOAT : - Printf(f," sv_setnv(ST(argvi++), (double) result);\n"); - break; - case T_CHAR : - Wrapper_add_local(f,"_ctemp", "char ctemp[2]"); - Printv(f, - tab4, "ctemp[0] = result;\n", - tab4, "ctemp[1] = 0;\n", - tab4, "sv_setpv((SV*)ST(argvi++),ctemp);\n", - 0); - break; - - case T_USER: - SwigType_add_pointer(d); - SwigType_remember(d); - Printv(f, - tab4, "SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE", SwigType_manglestr(d),");\n", 0); - SwigType_del_pointer(d); - break; - - case T_STRING: - Printf(f," sv_setpv((SV*)ST(argvi++),(char *) result);\n"); - break; - - case T_POINTER: case T_ARRAY: case T_REFERENCE: - SwigType_remember(d); - Printv(f, tab4, "SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE", SwigType_manglestr(d), ");\n", 0); - break; - - default : - Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n", Getfile(node), Getline(node), SwigType_str(d,0), name); - break; + virtual int importDirective(Node *n) { + if (blessed) { + String *modname = Getattr(n,"module"); + if (modname) { + Printf(f_pm,"require %s;\n", modname); } } + return Language::importDirective(n); } - /* If there were any output args, take care of them. */ + /* ------------------------------------------------------------ + * functionWrapper() + * ------------------------------------------------------------ */ - Printv(f,outarg,0); + virtual int functionWrapper(Node *n) { + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + String *overname = 0; - /* If there was any cleanup, do that. */ + Parm *p; + int i; + Wrapper *f; + char source[256],target[256],temp[256]; + String *tm; + String *cleanup, *outarg; + int num_saved = 0; + int num_arguments, num_required; + int varargs = 0; - Printv(f,cleanup,0); - - if (NewObject) { - if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) { - Printf(f,"%s\n",tm); + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); + } else { + if (!addSymbol(iname,n)) return SWIG_ERROR; } - } - if ((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char*)"result",(char*)"",0))) { - Printf(f,"%s\n", tm); - } + f = NewWrapper(); + cleanup = NewString(""); + outarg = NewString(""); - Printf(f," XSRETURN(argvi);\n}\n"); + String *wname = Swig_name_wrapper(iname); + if (overname) { + Append(wname,overname); + } + Setattr(n,"wrap:name",wname); + Printv(f->def, "XS(", wname, ") {\n", NIL); + Printv(f->def, "char _swigmsg[SWIG_MAX_ERRMSG] = \"\";\n", NIL); + Printv(f->def, "const char *_swigerr = _swigmsg;\n","{\n",NIL); + + emit_args(d, l, f); + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + + num_arguments = emit_num_arguments(l); + num_required = emit_num_required(l); + varargs = emit_isvarargs(l); + + Wrapper_add_local(f,"argvi","int argvi = 0"); + + /* Check the number of arguments */ + if (!varargs) { + Printf(f->code," if ((items < %d) || (items > %d)) {\n", num_required, num_arguments); + } else { + Printf(f->code," if (items < %d) {\n", num_required); + } + Printf(f->code," SWIG_croak(\"Usage: %s\");\n", usage_func(Char(iname),d,l)); + Printf(f->code,"}\n"); + + /* Write code to extract parameters. */ + i = 0; + for (i = 0, p = l; i < num_arguments; i++) { + + /* Skip ignored arguments */ + + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + + /* Produce string representation of source and target arguments */ + sprintf(source,"ST(%d)",i); + sprintf(target,"%s", Char(ln)); + + if (i >= num_required) { + Printf(f->code," if (items > %d) {\n", i); + } + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$target",target); + Replaceall(tm,"$source",source); + Replaceall(tm,"$input", source); + Setattr(p,"emit:input",source); /* Save input location */ + Printf(f->code,"%s\n",tm); + p = Getattr(p,"tmap:in:next"); + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); + p = nextSibling(p); + } + if (i >= num_required) { + Printf(f->code," }\n"); + } + } + + if (varargs) { + if (p && (tm = Getattr(p,"tmap:in"))) { + sprintf(source,"ST(%d)",i); + Replaceall(tm,"$input", source); + Setattr(p,"emit:input", source); + Printf(f->code,"if (items >= %d) {\n", i); + Printv(f->code, tm, "\n", NIL); + Printf(f->code,"}\n"); + } + } + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert cleanup code */ + for (i = 0, p = l; p; i++) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert argument output code */ + num_saved = 0; + for (i=0,p = l; p;i++) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$target","ST(argvi)"); + Replaceall(tm,"$result","ST(argvi)"); + String *in = Getattr(p,"emit:input"); + if (in) { + sprintf(temp,"_saved[%d]", num_saved); + Replaceall(tm,"$arg",temp); + Replaceall(tm,"$input",temp); + Printf(f->code,"_saved[%d] = %s;\n", num_saved, in); + num_saved++; + } + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + + /* If there were any saved arguments, emit a local variable for them */ + if (num_saved) { + sprintf(temp,"_saved[%d]",num_saved); + Wrapper_add_localv(f,"_saved","SV *",temp,NIL); + } + + /* Now write code to make the function call */ + + emit_action(n,f); + + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + Replaceall(tm,"$source","result"); + Replaceall(tm,"$target","ST(argvi)"); + Replaceall(tm,"$result", "ST(argvi)"); + Printf(f->code, "%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); + } + + /* If there were any output args, take care of them. */ + + Printv(f->code,outarg,NIL); + + /* If there was any cleanup, do that. */ + + Printv(f->code,cleanup,NIL); + + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n",tm); + } + } + + if ((tm = Swig_typemap_lookup_new("ret",n,"result", 0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n", tm); + } + + Printf(f->code," XSRETURN(argvi);\n"); + Printf(f->code,"fail:\n"); + Printv(f->code,cleanup,NIL); + Printv(f->code,"(void) _swigerr;\n", NIL); + Printv(f->code,"}\n",NIL); + Printv(f->code,"croak(_swigerr);\n", NIL); + Printv(f->code,"}\n",NIL); /* Add the dXSARGS last */ - Wrapper_add_local(f,"dXSARGS","dXSARGS"); + Wrapper_add_local(f,"dXSARGS","dXSARGS"); - /* Substitute the cleanup code */ - Replace(f,"$cleanup",cleanup,DOH_REPLACE_ANY); - Replace(f,"$name",iname,DOH_REPLACE_ANY); + /* Substitute the cleanup code */ + Replaceall(f->code,"$cleanup",cleanup); + Replaceall(f->code,"$symname",iname); /* Dump the wrapper function */ - Printf(f_wrappers,"%s", f); + Wrapper_print(f,f_wrappers); - /* Now register the function */ + /* Now register the function */ - Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(iname)); + if (!Getattr(n,"sym:overloaded")) { + Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule, iname, wname); + } else if (!Getattr(n,"sym:nextSibling")) { + /* Generate overloaded dispatch function */ + int maxargs, ii; + String *dispatch = Swig_overload_dispatch(n,"(*PL_markstack_ptr++);SWIG_CALLXS(%s); return;",&maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ - if (export_all) { - Printf(exported,"%s ", iname); - } + Wrapper *df = NewWrapper(); + String *dname = Swig_name_wrapper(iname); - - /* -------------------------------------------------------------------- - * Create a stub for this function, provided it's not a member function - * - * Really we only need to create a stub if this function involves - * complex datatypes. If it does, we'll make a small wrapper to - * process the arguments. If it doesn't, we'll just make a symbol - * table entry. - * -------------------------------------------------------------------- */ - - if ((blessed) && (!member_func)) { - int need_stub = 0; - String *func = NewString(""); - - /* We'll make a stub since we may need it anyways */ - - Printv(func, "sub ", iname, " {\n", - tab4, "my @args = @_;\n", - 0); - - /* Now we have to go through and patch up the argument list. If any - * arguments to our function correspond to other Perl objects, we - * need to extract them from a tied-hash table object.*/ - - Parm *p = l; - int i = 0; - while(p) { - SwigType *pt = Gettype(p); - - if (!Getignore(p)) { - /* Look up the datatype name here */ - char sourceNtarget[256]; - sprintf(sourceNtarget,"$args[%d]",i); - - if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) { - Printf(func,"%s\n", tm); - } else if (is_shadow(pt)) { - /* - if (i >= (pcount - numopt)) - Printf(func," if (scalar(@args) >= %d) {\n ", i); - Printf(func," $args[%d] = tied(%%{$args[%d]});\n", i, i); - if (i >= (pcount - numopt)) - Printf(func," }\n"); + Printv(df->def, + "XS(", dname, ") {\n", NIL); + + Wrapper_add_local(df,"dXSARGS", "dXSARGS"); + Replaceid(dispatch,"argc","items"); + for (ii = 0; ii < maxargs; ii++) { + char pat[128]; + char rep[128]; + sprintf(pat,"argv[%d]",ii); + sprintf(rep,"ST(%d)",ii); + Replaceall(dispatch,pat,rep); + } + Printv(df->code,dispatch,"\n",NIL); + Printf(df->code,"croak(\"No matching function for overloaded '%s'\");\n", iname); + Printf(df->code,"XSRETURN(0);\n"); + Printv(df->code,"}\n",NIL); + Wrapper_print(df,f_wrappers); + Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule, iname, dname); + DelWrapper(df); + Delete(dispatch); + Delete(dname); + } + if (!Getattr(n,"sym:nextSibling")) { + if (export_all) { + Printf(exported,"%s ", iname); + } + + /* -------------------------------------------------------------------- + * Create a stub for this function, provided it's not a member function + * -------------------------------------------------------------------- */ + + if ((blessed) && (!member_func)) { + int need_stub = 0; + String *func = NewString(""); + + /* We'll make a stub since we may need it anyways */ + + Printv(func, "sub ", iname, " {\n", + tab4, "my @args = @_;\n", + NIL); + + Printv(func, tab4, "my $result = ", cmodule, "::", iname, "(@args);\n", NIL); + + /* Now check to see what kind of return result was found. + * If this function is returning a result by 'value', SWIG did an + * implicit malloc/new. We'll mark the object like it was created + * in Perl so we can garbage collect it. */ + + if (is_shadow(d)) { + Printv(func, tab4, "return undef if (!defined($result));\n", NIL); + + /* If we're returning an object by value, put it's reference + into our local hash table */ + + if ((!SwigType_ispointer(d) && !SwigType_isreference(d)) || Getattr(n,"feature:new")) { + Printv(func, tab4, "$", is_shadow(d), "::OWNER{$result} = 1;\n", NIL); + } + + /* We're returning a Perl "object" of some kind. Turn it into a tied hash */ + Printv(func, + tab4, "my %resulthash;\n", + tab4, "tie %resulthash, ref($result), $result;\n", + tab4, "return bless \\%resulthash, ref($result);\n", + "}\n", + NIL); + need_stub = 1; - */ + } else { + /* Hmmm. This doesn't appear to be anything I know about */ + Printv(func, tab4, "return $result;\n", "}\n", NIL); } - i++; + + /* Now check if we needed the stub. If so, emit it, otherwise + * Emit code to hack Perl's symbol table instead */ + + if (need_stub) { + Printf(func_stubs,"%s",func); + } else { + Printv(func_stubs,"*", iname, " = *", cmodule, "::", iname, ";\n", NIL); + } + Delete(func); } - p = Getnext(p); } - - Printv(func, tab4, "my $result = ", package, "::", iname, "(@args);\n", 0); - - /* Now check to see what kind of return result was found. - * If this function is returning a result by 'value', SWIG did an - * implicit malloc/new. We'll mark the object like it was created - * in Perl so we can garbage collect it. */ - - if ((tm = Swig_typemap_lookup((char*)"perl5out",d,(char*)"",name,(char*)"sv",0))) { - Printv(func, - tm, "\n", - tab4, "return $result;\n", - "}\n", - 0); - need_stub = 1; - } else if (is_shadow(d)) { - Printv(func, tab4, "return undef if (!defined($result));\n", 0); - - /* If we're returning an object by value, put it's reference - into our local hash table */ - - if ((!SwigType_ispointer(d)) || NewObject) { - Printv(func, tab4, "$", is_shadow(d), "::OWNER{$result} = 1;\n", 0); - } - - /* We're returning a Perl "object" of some kind. Turn it into a tied hash */ - - Printv(func, - tab4, "my %resulthash;\n", - tab4, "tie %resulthash, ref($result), $result;\n", - tab4, "return bless \\%resulthash, ref($result);\n", - "}\n", - 0); - - need_stub = 1; - } else { - - /* Hmmm. This doesn't appear to be anything I know about */ - Printv(func, tab4, "return $result;\n", "}\n", 0); - } - - /* Now check if we needed the stub. If so, emit it, otherwise - * Emit code to hack Perl's symbol table instead */ - - if (need_stub) { - Printf(func_stubs,"%s",func); - } else { - Printv(func_stubs,"*", iname, " = *", package, "::", iname, ";\n", 0); - } - Delete(func); + Delete(cleanup); + Delete(outarg); + DelWrapper(f); + return SWIG_OK; } - Delete(cleanup); - Delete(outarg); - Delete(f); -} -/* ----------------------------------------------------------------------------- - * PERL5::link_variable() - * ----------------------------------------------------------------------------- */ + /* ------------------------------------------------------------ + * variableWrapper() + * ------------------------------------------------------------ */ -void PERL5::variable(DOH *node) { - char *name, *iname; - SwigType *t; + virtual int variableWrapper(Node *n) { + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + Wrapper *getf, *setf; + String *tm; - char set_name[256]; - char val_name[256]; - Wrapper *getf, *setf; - char *tm; - int setable = 1; + String *set_name = NewStringf("_wrap_set_%s", iname); + String *val_name = NewStringf("_wrap_val_%s", iname); - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); + if (!addSymbol(iname,n)) return SWIG_ERROR; - sprintf(set_name,"_wrap_set_%s",iname); - sprintf(val_name,"_wrap_val_%s",iname); + getf = NewWrapper(); + setf = NewWrapper(); - getf = NewWrapper(); - setf = NewWrapper(); + /* Create a Perl function for setting the variable value */ - /* Create a new scalar that we will attach magic to */ + if (!Getattr(n,"feature:immutable")) { + Printf(setf->def,"SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC *mg) {\n", set_name); + Printv(setf->code, + tab4, "MAGIC_PPERL\n", + tab4, "mg = mg;\n", + NIL); - Printv(vinit, tab4, "sv = perl_get_sv(\"", package, "::", iname, "\",TRUE | 0x2);\n", 0); + /* Check for a few typemaps */ + tm = Swig_typemap_lookup_new("varin",n,name,0); + if (tm) { + Replaceall(tm,"$source","sv"); + Replaceall(tm,"$target",name); + Replaceall(tm,"$input","sv"); + Printf(setf->code,"%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, + "Unable to link with datatype %s (ignored).\n", SwigType_str(t,0)); + return SWIG_NOWRAP; + } + Printf(setf->code," return 1;\n}\n"); + Replaceall(setf->code,"$symname",iname); + Wrapper_print(setf,magic); + } - /* Create a Perl function for setting the variable value */ + /* Now write a function to evaluate the variable */ - if (!ReadOnly) { - Printf(setf,"SWIGCLASS_STATIC int %s(SV* sv, MAGIC *mg) {\n", set_name); - Printv(setf, + Printf(getf->def,"SWIGCLASS_STATIC int %s(pTHX_ SV *sv, MAGIC *mg) {\n", val_name); + Printv(getf->code, tab4, "MAGIC_PPERL\n", tab4, "mg = mg;\n", - 0); + NIL); - /* Check for a few typemaps */ - if ((tm = Swig_typemap_lookup((char*)"varin",t,(char*)"",(char*)"sv",name,0))) { - Printf(setf,"%s\n", tm); - } else if ((tm = Swig_typemap_lookup((char*)"in",t,(char*)"",(char*)"sv",name,0))) { - Printf(setf,"%s\n", tm); + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$target","sv"); + Replaceall(tm,"$result","sv"); + Replaceall(tm,"$source",name); + Printf(getf->code,"%s\n", tm); } else { - switch(SwigType_type(t)) { - case T_INT : case T_BOOL: case T_UINT: - case T_SHORT : case T_USHORT: - case T_LONG : case T_ULONG: - case T_UCHAR: case T_SCHAR: - Printv(setf,tab4, name, " = (", SwigType_str(t,0), ") SvIV(sv);\n", 0); - break; - case T_DOUBLE : - case T_FLOAT : - Printv(setf, tab4, name, " = (", SwigType_str(t,0), ") SvNV(sv);\n", 0); - break; - case T_CHAR : - Printv(setf, tab4, name, " = (char) *SvPV(sv,PL_na);\n", 0); - break; + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, + "Unable to link with datatype %s (ignored).\n", SwigType_str(t,0)); + return SWIG_NOWRAP; + } + Printf(getf->code," return 1;\n}\n"); - case T_USER: + Replaceall(getf->code,"$symname",iname); + Wrapper_print(getf,magic); - SwigType_add_pointer(t); - Wrapper_add_local(setf,"_temp", "void *_temp"); - get_pointer(iname,(char*)"value",(char*)"sv",(char*)"_temp", t, setf, (char*)"return(1)"); - Printv(setf, tab4, name, " = *((", SwigType_str(t,0), ") _temp);\n", 0); - SwigType_del_pointer(t); - break; - - case T_STRING: - Wrapper_add_local(setf,"_a","char *_a"); - Printf(setf," _a = (char *) SvPV(sv,PL_na);\n"); - - if (CPlusPlus) - Printv(setf, - tab4, "if (", name, ") delete [] ", name, ";\n", - tab4, name, " = new char[strlen(_a)+1];\n", - 0); - else - Printv(setf, - tab4, "if (", name, ") free((char*)", name, ");\n", - tab4, name, " = (char *) malloc(strlen(_a)+1);\n", - 0); - Printv(setf,"strcpy((char*)", name, ",_a);\n", 0); - break; - - case T_ARRAY: - { - SwigType *aop; - SwigType *ta = Copy(t); - aop = SwigType_pop(ta); - if (SwigType_type(ta) == T_CHAR) { - String *dim = SwigType_array_getdim(aop,0); - if (dim && Len(dim)) { - Printf(setf, "strncpy(%s,(char*) SvPV(sv,PL_na), %s);\n", name,dim); - setable = 1; - } else { - setable = 0; - } - } else { - setable = 0; - } - Delete(ta); - Delete(aop); - } - break; - - case T_POINTER: case T_REFERENCE: - Wrapper_add_local(setf,"_temp","void *_temp"); - get_pointer(iname,(char*)"value",(char*)"sv",(char*)"_temp", t, setf, (char*)"return(1)"); - Printv(setf,tab4, name, " = (", SwigType_str(t,0), ") _temp;\n", 0); - break; - - default : - Printf(stderr,"%s:%d. Unable to link with datatype %s (ignored).\n", Getfile(node), Getline(node), SwigType_str(t,0)); - return; + String *tt = Getattr(n,"tmap:varout:type"); + if (tt) { + String *tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(t)); + if (Replaceall(tt,"$1_descriptor", tm)) { + SwigType_remember(t); } + Delete(tm); + SwigType *st = Copy(t); + SwigType_add_pointer(st); + tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(st)); + if (Replaceall(tt,"$&1_descriptor", tm)) { + SwigType_remember(st); + } + Delete(tm); + Delete(st); + } else { + tt = (String *) "0"; } - Printf(setf," return 1;\n}\n"); - Replace(setf,"$name",iname, DOH_REPLACE_ANY); - Printf(magic,"%s", setf); + /* Now add symbol to the PERL interpreter */ + if (Getattr(n,"feature:immutable")) { + Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", val_name,",", tt, " },\n",NIL); - } - - /* Now write a function to evaluate the variable */ - - Printf(getf,"SWIGCLASS_STATIC int %s(SV *sv, MAGIC *mg) {\n", val_name); - Printv(getf, - tab4, "MAGIC_PPERL\n", - tab4, "mg = mg;\n", - 0); - - if ((tm = Swig_typemap_lookup((char*)"varout",t,(char*)"",name, (char*)"sv",0))) { - Printf(getf,"%s\n", tm); - } else if ((tm = Swig_typemap_lookup((char*)"out",t,(char*)"",name,(char*)"sv",0))) { - Printf(getf,"%s\n", tm); - } else { - switch(SwigType_type(t)) { - - case T_INT : case T_BOOL: case T_UINT: - case T_SHORT : case T_USHORT: - case T_LONG : case T_ULONG: - case T_UCHAR: case T_SCHAR: - Printv(getf,tab4, "sv_setiv(sv, (IV) ", name, ");\n", 0); - Printv(vinit, tab4, "sv_setiv(sv,(IV)", name, ");\n",0); - break; - case T_DOUBLE : - case T_FLOAT : - Printv(getf, tab4,"sv_setnv(sv, (double) ", name, ");\n", 0); - Printv(vinit, tab4, "sv_setnv(sv,(double)", name, ");\n",0); - break; - case T_CHAR : - Wrapper_add_local(getf,"_ptemp","char _ptemp[2]"); - Printv(getf, - tab4, "_ptemp[0] = ", name, ";\n", - tab4, "_ptemp[1] = 0;\n", - tab4, "sv_setpv((SV*) sv, _ptemp);\n", - 0); - break; - case T_USER: - SwigType_add_pointer(t); - Printv(getf, - tab4, "rsv = SvRV(sv);\n", - tab4, "sv_setiv(rsv,(IV) &", name, ");\n", - 0); - - Wrapper_add_local(getf,"rsv","SV *rsv"); - Printv(vinit, tab4, "SWIG_MakePtr(sv, (void *) &", name, ",SWIGTYPE", SwigType_manglestr(t), ");\n",0); - SwigType_del_pointer(t); - - break; - - case T_STRING: - Printv(getf, tab4, "sv_setpv((SV*) sv, ", name, ");\n", 0); - break; - - case T_ARRAY: - { - SwigType *aop; - SwigType *ta = Copy(t); - aop = SwigType_pop(ta); - if (SwigType_type(ta) == T_CHAR) { - Printv(getf, "sv_setpv((SV*)sv, ", name, ");\n", 0); - Delete(ta); - Delete(aop); - break; - } - Delete(ta); - Delete(aop); - } - /* No break here is intentional */ - case T_POINTER: case T_REFERENCE: - Printv(getf, - tab4, "rsv = SvRV(sv);\n", - tab4, "sv_setiv(rsv,(IV) ", name, ");\n", - 0); - - Wrapper_add_local(getf,"rsv","SV *rsv"); - Printv(vinit, tab4, "SWIG_MakePtr(sv,(void *) 1, SWIGTYPE", SwigType_manglestr(t), ");\n",0); - break; - - default : - break; + } else { + Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", val_name, ",", tt, " },\n",NIL); } - } - Printf(getf," return 1;\n}\n"); - Replace(getf,"$name",iname, DOH_REPLACE_ANY); - Printf(magic,"%s", getf); - - /* Now add symbol to the PERL interpreter */ - if ((ReadOnly) || (!setable)) { - Printv(vinit, tab4, "swig_create_magic(sv,\"", package, "::", iname, "\",MAGIC_CAST MAGIC_CLASS swig_magic_readonly, MAGIC_CAST MAGIC_CLASS ", val_name, ");\n",0); - } else { - Printv(vinit, tab4, "swig_create_magic(sv,\"", package, "::", iname, "\", MAGIC_CAST MAGIC_CLASS ", set_name, ", MAGIC_CAST MAGIC_CLASS ", val_name, ");\n",0); - } - - /* If we're blessed, try to figure out what to do with the variable + /* If we're blessed, try to figure out what to do with the variable 1. If it's a Perl object of some sort, create a tied-hash around it. 2. Otherwise, just hack Perl's symbol table */ - if (blessed) { - if (is_shadow(t)) { - Printv(var_stubs, - "\nmy %__", iname, "_hash;\n", - "tie %__", iname, "_hash,\"", is_shadow(t), "\", $", - package, "::", iname, ";\n", - "$", iname, "= \\%__", iname, "_hash;\n", - "bless $", iname, ", ", is_shadow(t), ";\n", - 0); - } else { - Printv(var_stubs, "*", iname, " = *", package, "::", iname, ";\n", 0); + if (blessed) { + if (is_shadow(t)) { + Printv(var_stubs, + "\nmy %__", iname, "_hash;\n", + "tie %__", iname, "_hash,\"", is_shadow(t), "\", $", + cmodule, "::", iname, ";\n", + "$", iname, "= \\%__", iname, "_hash;\n", + "bless $", iname, ", ", is_shadow(t), ";\n", + NIL); + } else { + Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL); + } } if (export_all) - Printf(exported,"$%s ", name); + Printf(exported,"$%s ", iname); + + DelWrapper(setf); + DelWrapper(getf); + Delete(set_name); + Delete(val_name); + return SWIG_OK; } - Delete(setf); - Delete(getf); -} -/* ----------------------------------------------------------------------------- - * PERL5::constant() - * ----------------------------------------------------------------------------- */ + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ -/* Functions used to create constants */ + virtual int constantWrapper(Node *n) { + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + String *tm; -static const char *setiv = "#ifndef PERL_OBJECT\ -\n#define swig_setiv(a,b) _swig_setiv(a,b)\ -\nstatic void _swig_setiv(char *name, long value) { \ -\n#else\ -\n#define swig_setiv(a,b) _swig_setiv(pPerl,a,b)\ -\nstatic void _swig_setiv(CPerlObj *pPerl, char *name, long value) { \ -\n#endif\ -\n SV *sv; \ -\n sv = perl_get_sv(name,TRUE | 0x2);\ -\n sv_setiv(sv, (IV) value);\ -\n SvREADONLY_on(sv);\ -\n}\n"; + if (!addSymbol(iname,n)) return SWIG_ERROR; -static const char *setnv = "#ifndef PERL_OBJECT\ -\n#define swig_setnv(a,b) _swig_setnv(a,b)\ -\nstatic void _swig_setnv(char *name, double value) { \ -\n#else\ -\n#define swig_setnv(a,b) _swig_setnv(pPerl,a,b)\ -\nstatic void _swig_setnv(CPerlObj *pPerl, char *name, double value) { \ -\n#endif\ -\n SV *sv; \ -\n sv = perl_get_sv(name,TRUE | 0x2);\ -\n sv_setnv(sv, value);\ -\n SvREADONLY_on(sv);\ -\n}\n"; - -static const char *setpv = "#ifndef PERL_OBJECT\ -\n#define swig_setpv(a,b) _swig_setpv(a,b)\ -\nstatic void _swig_setpv(char *name, char *value) { \ -\n#else\ -\n#define swig_setpv(a,b) _swig_setpv(pPerl,a,b)\ -\nstatic void _swig_setpv(CPerlObj *pPerl, char *name, char *value) { \ -\n#endif\ -\n SV *sv; \ -\n sv = perl_get_sv(name,TRUE | 0x2);\ -\n sv_setpv(sv, value);\ -\n SvREADONLY_on(sv);\ -\n}\n"; - -static const char *setrv = "#ifndef PERL_OBJECT\ -\n#define swig_setrv(a,b,c) _swig_setrv(a,b,c)\ -\nstatic void _swig_setrv(char *name, void *value, char *type) { \ -\n#else\ -\n#define swig_setrv(a,b,c) _swig_setrv(pPerl,a,b,c)\ -\nstatic void _swig_setrv(CPerlObj *pPerl, char *name, void *value, char *type) { \ -\n#endif\ -\n SV *sv; \ -\n sv = perl_get_sv(name,TRUE | 0x2);\ -\n sv_setref_pv(sv, type, value);\ -\n SvREADONLY_on(sv);\ -\n}\n"; - -void -PERL5::constant(DOH *node) - { - char *name; - SwigType *type; - char *value; - char *tm; - static int have_int_func = 0; - static int have_double_func = 0; - static int have_char_func = 0; - static int have_ref_func = 0; - - name = GetChar(node,"name"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - - if ((tm = Swig_typemap_lookup((char*)"const",type,name,value,name,0))) { - Printf(f_init,"%s\n",tm); - } else { - switch(SwigType_type(type)) { - case T_INT: case T_UINT: case T_BOOL: - case T_SHORT: case T_USHORT: - case T_LONG: case T_ULONG: - case T_SCHAR: case T_UCHAR: - if (!have_int_func) { - Printf(f_header,"%s\n",setiv); - have_int_func = 1; - } - Printv(vinit, tab4, "swig_setiv(\"", package, "::", name, "\", (long) ", value, ");\n",0); - break; - case T_DOUBLE: - case T_FLOAT: - if (!have_double_func) { - Printf(f_header,"%s\n",setnv); - have_double_func = 1; - } - Printv(vinit, tab4, "swig_setnv(\"", package, "::", name, "\", (double) (", value, "));\n",0); - break; - case T_CHAR : - if (!have_char_func) { - Printf(f_header,"%s\n",setpv); - have_char_func = 1; - } - Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value); - - break; - case T_STRING: - if (!have_char_func) { - Printf(f_header,"%s\n",setpv); - have_char_func = 1; - } - Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value); - break; - - case T_POINTER: case T_ARRAY: case T_REFERENCE: - if (!have_ref_func) { - Printf(f_header,"%s\n",setrv); - have_ref_func = 1; - } - Printv(vinit, tab4, "swig_setrv(\"", package, "::", name, "\", (void *) ", value, ", \"", - SwigType_manglestr(type), "\");\n", 0); - break; - - default: - Printf(stderr,"%s:%d. Unsupported constant value.\n", Getfile(node), Getline(node)); - break; + /* Special hook for member pointer */ + if (SwigType_type(type) == T_MPOINTER) { + String *wname = Swig_name_wrapper(iname); + Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type,wname), value); + value = Char(wname); } - } - if (blessed) { - if (is_shadow(type)) { - Printv(var_stubs, - "\nmy %__", name, "_hash;\n", - "tie %__", name, "_hash,\"", is_shadow(type), "\", $", - package, "::", name, ";\n", - "$", name, "= \\%__", name, "_hash;\n", - "bless $", name, ", ", is_shadow(type), ";\n", - 0); + if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) { + Replaceall(tm,"$source",value); + Replaceall(tm,"$target",name); + Replaceall(tm,"$value",value); + Printf(constant_tab,"%s,\n", tm); + } else if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { + Replaceall(tm,"$source", value); + Replaceall(tm,"$target", name); + Replaceall(tm,"$value",value); + Printf(f_init, "%s\n", tm); } else { - Printv(var_stubs, "*",name," = *", package, "::", name, ";\n", 0); + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value.\n"); + return SWIG_NOWRAP; } - } - if (export_all) - Printf(exported,"$%s ",name); -} -/* ----------------------------------------------------------------------------- - * PERL5::usage_func() - * ----------------------------------------------------------------------------- */ -char * -PERL5::usage_func(char *iname, SwigType *, ParmList *l) { - static String *temp = 0; - Parm *p; - int i; - - if (!temp) temp = NewString(""); - Clear(temp); - Printf(temp,"%s(",iname); - - /* Now go through and print parameters */ - p = l; - i = 0; - while (p != 0) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - if (!Getignore(p)) { - /* If parameter has been named, use that. Otherwise, just print a type */ - if (SwigType_type(pt) != T_VOID) { - if (Len(pn) > 0) { - Printf(temp,"%s",pn); - } else { - Printf(temp,"%s",SwigType_str(pt,0)); - } + if (blessed) { + if (is_shadow(type)) { + Printv(var_stubs, + "\nmy %__", iname, "_hash;\n", + "tie %__", iname, "_hash,\"", is_shadow(type), "\", $", + cmodule, "::", iname, ";\n", + "$", iname, "= \\%__", iname, "_hash;\n", + "bless $", iname, ", ", is_shadow(type), ";\n", + NIL); + } else if (do_constants) { + Printv(const_stubs,"sub ", name, " () { $", + cmodule, "::", name, " }\n", NIL); + num_consts++; + } else { + Printv(var_stubs, "*",iname," = *", cmodule, "::", iname, ";\n", NIL); } - i++; - p = Getnext(p); - if (p) - if (!Getignore(p)) - Putc(',',temp); - } else { - p = Getnext(p); - if (p) - if ((i>0) && (!Getignore(p))) - Putc(',',temp); } - } - Printf(temp,");"); - return Char(temp); -} - -/* ----------------------------------------------------------------------------- - * PERL5::nativefunction() - * ----------------------------------------------------------------------------- */ -void -PERL5::nativefunction(DOH *node) { - char *name, *funcname; - name = GetChar(node,"scriptname"); - funcname = GetChar(node,"name"); - Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package,name, funcname); - if (export_all) - Printf(exported,"%s ",name); - if (blessed) { - Printv(func_stubs,"*", name, " = *", package, "::", name, ";\n", 0); - } -} - -/**************************************************************************** - *** OBJECT-ORIENTED FEATURES - **************************************************************************** - *** These extensions provide a more object-oriented interface to C++ - *** classes and structures. The code here is based on extensions - *** provided by David Fletcher and Gary Holt. - *** - *** I have generalized these extensions to make them more general purpose - *** and to resolve object-ownership problems. - *** - *** The approach here is very similar to the Python module : - *** 1. All of the original methods are placed into a single - *** package like before except that a 'c' is appended to the - *** package name. - *** - *** 2. All methods and function calls are wrapped with a new - *** perl function. While possibly inefficient this allows - *** us to catch complex function arguments (which are hard to - *** track otherwise). - *** - *** 3. Classes are represented as tied-hashes in a manner similar - *** to Gary Holt's extension. This allows us to access - *** member data. - *** - *** 4. Stand-alone (global) C functions are modified to take - *** tied hashes as arguments for complex datatypes (if - *** appropriate). - *** - *** 5. Global variables involving a class/struct is encapsulated - *** in a tied hash. - *** - *** 6. Object ownership is maintained by having a hash table - *** within in each package called "this". It is unlikely - *** that C++ program will use this so it's a somewhat - *** safe variable name. - *** - ****************************************************************************/ - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_open_class() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_open_class(DOH *node) { - - this->Language::cpp_open_class(node); - - char *classname = GetChar(node,"name"); - char *rname = GetChar(node,"scriptname"); - char *ctype = GetChar(node,"classtype"); - - if (blessed) { - have_constructor = 0; - have_destructor = 0; - have_data_members = 0; - - Delete(class_name); class_name = 0; - Delete(class_type); class_type =0; - Delete(real_classname); real_classname = 0; - Delete(base_class); base_class = 0; - Delete(fullclassname); fullclassname = 0; - - /* If the class is being renamed to something else, use the renaming */ - if (rname) { - class_name = NewString(rname); - class_renamed = 1; - } else { - class_name = NewString(classname); - class_renamed = 0; - } - - /* Use the fully qualified name of the Perl class */ - if (!compat) { - fullclassname = NewStringf("%s::%s",realpackage,class_name); - } else { - fullclassname = NewString(class_name); - } - real_classname = NewString(classname); - if (base_class) Delete(base_class); - base_class = 0; - class_type = NewString(ctype); - pcode = NewString(""); - blessedmembers = NewString(""); - member_keys = NewString(""); - - /* Add some symbols to the hash tables */ - Hash *nnode = NewHash(); - Setattr(nnode,"name", classname); - Setattr(nnode,"scriptname", fullclassname); - Setattr(nnode,"classtype", ctype); - cpp_class_decl(nnode); - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_close_class() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_close_class() { - - if (blessed) { - Printv(pm, - "\n############# Class : ", fullclassname, " ##############\n", - "\npackage ", fullclassname, ";\n", - 0); - - /* If we are inheriting from a base class, set that up */ - - if (Cmp(class_name,realpackage)) - Printv(pm, "@ISA = qw( ",realpackage, 0); - else - Printv(pm, "@ISA = qw( ", 0); - - if (base_class) { - Printv(pm, " ", base_class, 0); - } - Printf(pm, " );\n"); - - /* Dump out a hash table containing the pointers that we own */ - - Printf(pm, "%%OWNER = ();\n"); - if (have_data_members) { - Printv(pm, - "%BLESSEDMEMBERS = (\n", blessedmembers, ");\n\n", - 0); - } - if (have_data_members || have_destructor) - Printf(pm, "%%ITERATORS = ();\n"); - - - /* Dump out the package methods */ - - Printv(pm,pcode,0); - Delete(pcode); - - /* Output methods for managing ownership */ - - Printv(pm, - "sub DISOWN {\n", - tab4, "my $self = shift;\n", - tab4, "my $ptr = tied(%$self);\n", - tab4, "delete $OWNER{$ptr};\n", - tab4, "};\n\n", - "sub ACQUIRE {\n", - tab4, "my $self = shift;\n", - tab4, "my $ptr = tied(%$self);\n", - tab4, "$OWNER{$ptr} = 1;\n", - tab4, "};\n\n", - 0); - - /* Only output the following methods if a class has member data */ - - if (have_data_members) { - - /* Output a FETCH method. This is actually common to all classes */ - Printv(pm, - "sub FETCH {\n", - tab4, "my ($self,$field) = @_;\n", - tab4, "my $member_func = \"", package, "::", Swig_name_get(Swig_name_member(class_name,(char*)"${field}")), "\";\n", - tab4, "my $val = &$member_func($self);\n", - tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n", - tab8, "return undef if (!defined($val));\n", - tab8, "my %retval;\n", - tab8, "tie %retval,$BLESSEDMEMBERS{$field},$val;\n", - tab8, "return bless \\%retval, $BLESSEDMEMBERS{$field};\n", - tab4, "}\n", - tab4, "return $val;\n", - "}\n\n", - 0); - - /* Output a STORE method. This is also common to all classes (might move to base class) */ - - Printv(pm, - "sub STORE {\n", - tab4, "my ($self,$field,$newval) = @_;\n", - tab4, "my $member_func = \"", package, "::", Swig_name_set(Swig_name_member(class_name,(char*)"${field}")), "\";\n", - tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n", - tab8, "&$member_func($self,tied(%{$newval}));\n", - tab4, "} else {\n", - tab8, "&$member_func($self,$newval);\n", - tab4, "}\n", - "}\n\n", - 0); - - /* Output a FIRSTKEY method. This is to allow iteration over a structure's keys. */ - - Printv(pm, - "sub FIRSTKEY {\n", - tab4, "my $self = shift;\n", - tab4, "$ITERATORS{$self} = [", member_keys, "];\n", - tab4, "my $first = shift @{$ITERATORS{$self}};\n", - tab4, "return $first;\n", - "}\n\n", - 0); - - /* Output a NEXTKEY method. This is the iterator so that each and keys works */ - - Printv(pm, - "sub NEXTKEY {\n", - tab4, "my $self = shift;\n", - tab4, "$nelem = scalar @{$ITERATORS{$self}};\n", - tab4, "if ($nelem > 0) {\n", - tab8, "my $member = shift @{$ITERATORS{$self}};\n", - tab8, "return $member;\n", - tab4, "} else {\n", - tab8, "$ITERATORS{$self} = [", member_keys, "];\n", - tab8, "return ();\n", - tab4, "}\n", - "}\n\n", - 0); - } - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_member_func() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_memberfunction(DOH *node) { - char *name, *iname; - SwigType *t; - ParmList *l; - String *func; - char *realname; - Parm *p; - int i; - String *cname; - int pcount, numopt; - char *tm; - int need_wrapper = 0; - - member_func = 1; - this->Language::cpp_memberfunction(node); - member_func = 0; - - if (!blessed) return; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - l = Getattr(node,"parms"); - - func = NewString(""); - cname = NewString("perl5:"); - - /* Now emit a Perl wrapper function around our member function, we might need - to patch up some arguments along the way */ - - if (!iname) - realname = name; - else - realname = iname; - - Printf(cname,"%s::%s",class_name,realname); - if (Getattr(symbols,cname)) { - return; /* Forget it, we saw this already */ - } - Setattr(symbols,cname,cname); - - Printv(func, - "sub ", realname, " {\n", - tab4, "my @args = @_;\n", - 0); - - /* Now we have to go through and patch up the argument list. If any - arguments to our function correspond to other Perl objects, we - need to extract them from a tied-hash table object. */ - - p = l; - pcount = ParmList_len(l); - numopt = check_numopt(l); - i = 1; - while(p) { - SwigType *pt = Gettype(p); - if (!Getignore(p)) { - char sourceNtarget[512]; - sprintf(sourceNtarget, "$args[%d]", i); - - if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) { - Printf(func,"%s\n",tm); - need_wrapper = 1; + if (export_all) { + if (do_constants && !is_shadow(type)) { + Printf(exported,"%s ",name); + } else { + Printf(exported,"$%s ",iname); } - i++; } - p = Getnext(p); + return SWIG_OK; } - /* Okay. We've made argument adjustments, now call into the package */ + /* ------------------------------------------------------------ + * usage_func() + * ------------------------------------------------------------ */ + char *usage_func(char *iname, SwigType *, ParmList *l) { + static String *temp = 0; + Parm *p; + int i; - Printv(func, - tab4, "my $result = ", package, "::", Swig_name_member(class_name,realname), - "(@args);\n", - 0); - - /* Now check to see what kind of return result was found. - * If this function is returning a result by 'value', SWIG did an - * implicit malloc/new. We'll mark the object like it was created - * in Perl so we can garbage collect it. */ - - if ((tm = Swig_typemap_lookup((char*)"perl5out",t,(char*)"",name,(char*)"sv",0))) { - Printv(func, - tm, "\n", - tab4,"return $result;\n", - "}\n", - 0); - need_wrapper = 1; - - } else if (is_shadow(t)) { - - Printv(func,tab4, "return undef if (!defined($result));\n", 0); - - /* If we're returning an object by value, put it's reference - into our local hash table */ - - if (!SwigType_ispointer(t) || NewObject) { - Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", 0); - } - - /* We're returning a Perl "object" of some kind. Turn it into - a tied hash */ - - Printv(func, - tab4, "my %resulthash;\n", - tab4, "tie %resulthash, ref($result), $result;\n", - tab4, "return bless \\%resulthash, ref($result);\n", - "}\n", - 0); - - need_wrapper = 1; - } else { - - /* Hmmm. This doesn't appear to be anything I know about so just - return it unmodified */ - - Printv(func, tab4,"return $result;\n", "}\n", 0); - } - - if (need_wrapper) { - Printv(pcode,func,0); - } else { - Printv(pcode,"*",realname," = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0); - } - Delete(func); - Delete(cname); -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_variable() - * - * Adds an instance member. This is a little hairy because data members are - * really added with a tied-hash table that is attached to the object. - * - * On the low level, we will emit a pair of get/set functions to retrieve - * values just like before. These will then be encapsulated in a FETCH/STORE - * method associated with the tied-hash. - * - * In the event that a member is an object that we have already wrapped, then - * we need to retrieve the data a tied-hash as opposed to what SWIG normally - * returns. To determine this, we build an internal hash called 'BLESSEDMEMBERS' - * that contains the names and types of tied data members. If a member name - * is in the list, we tie it, otherwise, we just return the normal SWIG value. - * ----------------------------------------------------------------------------- */ - -void PERL5::cpp_variable(DOH *node) { - char *name, *iname; - SwigType *t; - char *realname; - String *cname; - - cname = NewString("perl5:"); - - /* Emit a pair of get/set functions for the variable */ - - member_func = 1; - this->Language::cpp_variable(node); - member_func = 0; - - - if (blessed) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - - if (iname) realname = iname; - else realname = name; - - Printf(cname,"%s::%s", class_name, realname); - if (Getattr(symbols,cname)) { - Delete(cname); - return; - } - Setattr(symbols,cname,cname); - - /* Store name of key for future reference */ - Printf(member_keys,"'%s', ", realname); - - /* Now we need to generate a little Perl code for this */ - - if (is_shadow(t)) { - - /* This is a Perl object that we have already seen. Add an - entry to the members list*/ - Printv(blessedmembers, - tab4, realname, " => '", is_shadow(t), "',\n", - 0); - - } - } - have_data_members++; - Delete(cname); -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_constructor() - * - * Emits a blessed constructor for our class. In addition to our construct - * we manage a Perl hash table containing all of the pointers created by - * the constructor. This prevents us from accidentally trying to free - * something that wasn't necessarily allocated by malloc or new - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_constructor(DOH *node) { - char *name, *iname; - ParmList *l; - Parm *p; - int i; - String *realname; - String *cname; - - cname = NewString("perl5:constructor:"); - - /* Emit an old-style constructor for this class */ - - member_func = 1; - this->Language::cpp_constructor(node); - - if (blessed) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - l = Getattr(node,"parms"); - if (iname) - realname = iname; - else { - if (class_renamed) realname = class_name; - else realname = class_name; - } - - Printf(cname,"%s::%s", class_name, realname); - if (Getattr(symbols,cname)) { - Delete(cname); - return; - } - Setattr(symbols,cname, cname); - if ((Cmp(realname,class_name) == 0)) { - - /* Emit a blessed constructor */ - - Printf(pcode, "sub new {\n"); - - } else { - - /* Constructor doesn't match classname so we'll just use the normal name */ - - Printv(pcode, "sub ", Swig_name_construct(realname), " () {\n", 0); - - } - - Printv(pcode, tab4, "my $self = shift;\n", - tab4, "my @args = @_;\n", 0); - - /* We are going to need to patch up arguments here if necessary - * Now we have to go through and patch up the argument list. If any - * arguments to our function correspond to other Perl objects, we - * need to extract them from a tied-hash table object. */ + if (!temp) temp = NewString(""); + Clear(temp); + Printf(temp,"%s(",iname); + /* Now go through and print parameters */ p = l; i = 0; - while(p) { - SwigType *pt = Gettype(p); - - if (is_shadow(pt)) { - /* Yep. This smells alot like an object, patch up the arguments */ - Printf(pcode, " $args[%d] = tied(%%{$args[%d]});\n", i, i); + while (p != 0) { + SwigType *pt = Getattr(p,"type"); + String *pn = Getattr(p,"name"); + if (!Getattr(p,"ignore")) { + /* If parameter has been named, use that. Otherwise, just print a type */ + if (SwigType_type(pt) != T_VOID) { + if (Len(pn) > 0) { + Printf(temp,"%s",pn); + } else { + Printf(temp,"%s",SwigType_str(pt,0)); + } + } + i++; + p = nextSibling(p); + if (p) + if (!Getattr(p,"ignore")) + Putc(',',temp); + } else { + p = nextSibling(p); + if (p) + if ((i>0) && (!Getattr(p,"ignore"))) + Putc(',',temp); } - p = Getnext(p); - i++; } - - Printv(pcode, - tab4, "$self = ", package, "::", Swig_name_construct(realname), "(@args);\n", - tab4, "return undef if (!defined($self));\n", - tab4, "bless $self, \"", fullclassname, "\";\n", - tab4, "$OWNER{$self} = 1;\n", - tab4, "my %retval;\n", - tab4, "tie %retval, \"", fullclassname, "\", $self;\n", - tab4, "return bless \\%retval,\"", fullclassname, "\";\n", - "}\n\n", - 0); - - have_constructor = 1; - + Printf(temp,");"); + return Char(temp); } - Delete(cname); - member_func = 0; -} -/* ----------------------------------------------------------------------------- - * PERL5::cpp_destructor() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_destructor(DOH *node) { - String *realname; - char *name, *newname; - member_func = 1; - this->Language::cpp_destructor(node); + /* ------------------------------------------------------------ + * nativeWrapper() + * ------------------------------------------------------------ */ + + virtual int nativeWrapper(Node *n) { + String *name = Getattr(n,"sym:name"); + String *funcname = Getattr(n,"wrap:name"); - if (blessed) { - name = GetChar(node,"name"); - newname = GetChar(node,"scriptname"); + if (!addSymbol(funcname,n)) return SWIG_ERROR; - if (newname) realname = newname; - else { - if (class_renamed) realname = class_name; - else realname = name; + Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule,name,funcname); + if (export_all) + Printf(exported,"%s ",name); + if (blessed) { + Printv(func_stubs,"*", name, " = *", cmodule, "::", name, ";\n", NIL); } - - /* Emit a destructor for this object*/ - - Printv(pcode, - "sub DESTROY {\n", - tab4, "return unless $_[0]->isa('HASH');\n", - tab4, "my $self = tied(%{$_[0]});\n", - tab4, "delete $ITERATORS{$self};\n", - tab4, "if (exists $OWNER{$self}) {\n", - tab8, package, "::", Swig_name_destroy(realname), "($self);\n", - tab8, "delete $OWNER{$self};\n", - tab4, "}\n}\n\n", - 0); - - have_destructor = 1; - - } - member_func = 0; -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_staticfunction() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_staticfunction(DOH *node) { - char *name, *iname; - this->Language::cpp_staticfunction(node); - char *realname; - - if (blessed) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - if (iname) realname = name; - else realname = iname; - - Printv(pcode, "*", realname, " = *", realpackage, "::", Swig_name_member(class_name,realname), ";\n", 0); - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_inherit() - * ------------------------------------------------------------------------------ */ -void -PERL5::cpp_inherit(List *bases) { - String *base; - char *bc; - int have_first = 0; - if (!blessed) { - this->Language::cpp_inherit(bases); - return; + return SWIG_OK; } - /* Inherit variables and constants from base classes, but not - functions (since Perl can handle that okay). */ - - this->Language::cpp_inherit(bases); - - /* Now tell the Perl5 module that we're inheriting from base classes */ - - base_class = NewString(""); - for (base = Firstitem(bases); base; base = Nextitem(bases)) { - /* See if this is a class we know about */ - String *b = NewString(base); - bc = Char(is_shadow(b)); - Delete(b); - if (bc) { - if (have_first) Putc(' ', base_class); - Printf(base_class,bc); - have_first = 1; - } - } - if (!have_first) { - Delete(base_class); - base_class = 0; - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_constant() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_constant(DOH *node) { - char *name, *iname; - String *realname; - int oldblessed = blessed; - char cname[256]; - - /* Create a normal constant */ - blessed = 0; - this->Language::cpp_constant(node); - blessed = oldblessed; - - if (blessed) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - if (!iname) - realname = name; - else - realname = iname; - - sprintf(cname,"%s::%s",Char(class_name),Char(realname)); - if (Getattr(symbols, cname)) { + /**************************************************************************** + *** OBJECT-ORIENTED FEATURES + **************************************************************************** + *** These extensions provide a more object-oriented interface to C++ + *** classes and structures. The code here is based on extensions + *** provided by David Fletcher and Gary Holt. + *** + *** I have generalized these extensions to make them more general purpose + *** and to resolve object-ownership problems. + *** + *** The approach here is very similar to the Python module : + *** 1. All of the original methods are placed into a single + *** package like before except that a 'c' is appended to the + *** package name. + *** + *** 2. All methods and function calls are wrapped with a new + *** perl function. While possibly inefficient this allows + *** us to catch complex function arguments (which are hard to + *** track otherwise). + *** + *** 3. Classes are represented as tied-hashes in a manner similar + *** to Gary Holt's extension. This allows us to access + *** member data. + *** + *** 4. Stand-alone (global) C functions are modified to take + *** tied hashes as arguments for complex datatypes (if + *** appropriate). + *** + *** 5. Global variables involving a class/struct is encapsulated + *** in a tied hash. + *** + ****************************************************************************/ + + + void setclassname(Node *n) { + String *symname = Getattr(n,"sym:name"); + String *fullname; + String *actualpackage; + Node *clsmodule = Getattr(n,"module"); + + if (!clsmodule) { + /* imported module does not define a module name. Oh well */ return; } - Setattr(symbols, cname,cname); - /* Create a symbol table entry for it */ - Printv(pcode, "*", realname, " = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0); - } -} - -/* ----------------------------------------------------------------------------- - * PERL5::cpp_class_decl() - * ----------------------------------------------------------------------------- */ -void -PERL5::cpp_class_decl(DOH *node) { - String *name = Getname(node); - String *rename = Getattr(node,"scriptname"); - String *ctype = Getattr(node,"classtype"); - String *stype; - if (blessed) { - stype = NewString(name); - SwigType_add_pointer(stype); - Setattr(classes,stype,rename); - Delete(stype); - if (Len(ctype) > 0) { - stype = NewStringf("%s %s",ctype,name); - SwigType_add_pointer(stype); - Setattr(classes,stype,rename); - Delete(stype); + /* Do some work on the class name */ + actualpackage = Getattr(clsmodule,"name"); + if ((!compat) && (!Strchr(symname,':'))) { + fullname = NewStringf("%s::%s",actualpackage,symname); + } else { + fullname = NewString(symname); } + Setattr(n,"perl5:proxy", fullname); } -} - -/* ----------------------------------------------------------------------------- - * PERL5::add_typedef() - * ----------------------------------------------------------------------------- */ -void -PERL5::add_typedef(SwigType *t, String *name) { - - if (!blessed) return; - if (is_shadow(t)) { - DOH *node = NewHash(); - Setattr(node,"name",name); - Setattr(node,"scriptname", is_shadow(t)); - Setattr(node,"classtype",""); - cpp_class_decl(node); - } -} - - -/* ----------------------------------------------------------------------------- - * PERL5::pragma() - * - * Pragma directive. - * - * %pragma(perl5) code="String" # Includes a string in the .pm file - * %pragma(perl5) include="file.pl" # Includes a file in the .pm file - * ----------------------------------------------------------------------------- */ - -void PERL5::pragma(DOH *node) { - String *name = Getattr(node,"name"); - String *value = Getattr(node,"value"); - if (Cmp(name,"code") == 0) { - /* Dump the value string into the .pm file */ - if (value) { - Printf(pragma_include, "%s\n", value); + + /* ------------------------------------------------------------ + * classDeclaration() + * ------------------------------------------------------------ */ + virtual int classDeclaration(Node *n) { + /* Do some work on the class name */ + if (blessed) { + setclassname(n); + Append(classlist,n); } - } else if (Cmp(name,"include") == 0) { - /* Include a file into the .pm file */ - if (value) { - FILE *f = Swig_open(value); - if (!f) { - Printf(stderr,"%s:%d. Unable to locate file %s\n", Getfile(node), Getline(node),value); + return Language::classDeclaration(n); + } + + /* ------------------------------------------------------------ + * classHandler() + * ------------------------------------------------------------ */ + + virtual int classHandler(Node *n) { + + if (blessed) { + have_constructor = 0; + have_operators = 0; + have_destructor = 0; + have_data_members = 0; + operators = NewHash(); + + class_name = Getattr(n,"sym:name"); + + if (!addSymbol(class_name,n)) return SWIG_ERROR; + + /* Use the fully qualified name of the Perl class */ + if (!compat) { + fullclassname = NewStringf("%s::%s",fullmodule,class_name); } else { - char buffer[4096]; - while (fgets(buffer,4095,f)) { - Printf(pragma_include,"%s",buffer); + fullclassname = NewString(class_name); + } + real_classname = Getattr(n,"name"); + pcode = NewString(""); + blessedmembers = NewString(""); + } + + /* Emit all of the members */ + Language::classHandler(n); + + + /* Finish the rest of the class */ + if (blessed) { + /* Generate a client-data entry */ + SwigType *ct = NewStringf("p.%s", real_classname); + Printv(f_init,"SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", (void*) \"", + fullclassname, "\");\n", NIL); + SwigType_remember(ct); + Delete(ct); + + Printv(pm, + "\n############# Class : ", fullclassname, " ##############\n", + "\npackage ", fullclassname, ";\n", + NIL); + + if (have_operators) { + Printf(pm, "use overload\n"); + DOH *key; + for (key = Firstkey(operators); key; key = Nextkey(operators)) { + char *name = Char(key); + // fprintf(stderr,"found name: <%s>\n", name); + if (strstr(name, "operator_equal_to")) { + Printv(pm, tab4, "\"==\" => sub { $_[0]->operator_equal_to($_[1])},\n",NIL); + } else if (strstr(name, "operator_not_equal_to")) { + Printv(pm, tab4, "\"!=\" => sub { $_[0]->operator_not_equal_to($_[1])},\n",NIL); + } else if (strstr(name, "operator_assignment")) { + Printv(pm, tab4, "\"=\" => sub { $_[0]->operator_assignment($_[1])},\n",NIL); + } else { + fprintf(stderr,"Unknown operator: %s\n", name); + } + } + Printv(pm, tab4, "\"fallback\" => 1;\n",NIL); + } + /* If we are inheriting from a base class, set that up */ + + Printv(pm, "@ISA = qw( ",fullmodule, NIL); + + /* Handle inheritance */ + List *baselist = Getattr(n,"bases"); + if (baselist && Len(baselist)) { + Node *base = Firstitem(baselist); + while (base) { + String *bname = Getattr(base, "perl5:proxy"); + if (!bname) { + base = Nextitem(baselist); + continue; + } + Printv(pm," ", bname, NIL); + base = Nextitem(baselist); + } + } + Printf(pm, " );\n"); + + /* Dump out a hash table containing the pointers that we own */ + Printf(pm, "%%OWNER = ();\n"); + if (have_data_members) { + Printv(pm, + "%BLESSEDMEMBERS = (\n", blessedmembers, ");\n\n", + NIL); + } + if (have_data_members || have_destructor) + Printf(pm, "%%ITERATORS = ();\n"); + + /* Dump out the package methods */ + + Printv(pm,pcode,NIL); + Delete(pcode); + + /* Output methods for managing ownership */ + + Printv(pm, + "sub DISOWN {\n", + tab4, "my $self = shift;\n", + tab4, "my $ptr = tied(%$self);\n", + tab4, "delete $OWNER{$ptr};\n", + tab4, "};\n\n", + "sub ACQUIRE {\n", + tab4, "my $self = shift;\n", + tab4, "my $ptr = tied(%$self);\n", + tab4, "$OWNER{$ptr} = 1;\n", + tab4, "};\n\n", + NIL); + + /* Only output the following methods if a class has member data */ + + if (have_data_members) { + + /* Output a FETCH method. This is actually common to all classes */ + Printv(pm, + "sub FETCH {\n", + tab4, "my ($self,$field) = @_;\n", + tab4, "my $member_func = \"swig_${field}_get\";\n", + tab4, "my $val = $self->$member_func();\n", + tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n", + tab8, "return undef if (!defined($val));\n", + tab8, "my %retval;\n", + tab8, "tie %retval,$BLESSEDMEMBERS{$field},$val;\n", + tab8, "return bless \\%retval, $BLESSEDMEMBERS{$field};\n", + tab4, "}\n", + tab4, "return $val;\n", + "}\n\n", + NIL); + + /* Output a STORE method. This is also common to all classes (might move to base class) */ + + Printv(pm, + "sub STORE {\n", + tab4, "my ($self,$field,$newval) = @_;\n", + tab4, "my $member_func = \"swig_${field}_set\";\n", + tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n", + tab8, "$self->$member_func(tied(%{$newval}));\n", + tab4, "} else {\n", + tab8, "$self->$member_func($newval);\n", + tab4, "}\n", + "}\n\n", + NIL); + } + Delete(operators); operators = 0; + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int memberfunctionHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + + String *func; + int need_wrapper = 0; + + member_func = 1; + Language::memberfunctionHandler(n); + member_func = 0; + + if ((blessed) && (!Getattr(n,"sym:nextSibling"))) { + func = NewString(""); + + /* Now emit a Perl wrapper function around our member function, we might need + to patch up some arguments along the way */ + + if (Strstr(symname, "operator") == symname) { + if (Strstr(symname, "operator_equal_to")) { + DohSetInt(operators,"operator_equal_to",1); + have_operators = 1; + } else if (Strstr(symname, "operator_not_equal_to")) { + DohSetInt(operators,"operator_not_equal_to",1); + have_operators = 1; + } else if (Strstr(symname, "operator_assignment")) { + DohSetInt(operators,"operator_assignment",1); + have_operators = 1; + } else { + Printf(stderr,"Unknown operator: %s\n", symname); + } + // fprintf(stderr,"Found member_func operator: %s\n", symname); + } + + Printv(func, + "sub ", symname, " {\n", + tab4, "my @args = @_;\n", + NIL); + + /* Okay. We've made argument adjustments, now call into the package */ + + Printv(func, + tab4, "my $result = ", cmodule, "::", Swig_name_member(class_name,symname), + "(@args);\n", + NIL); + + /* Now check to see what kind of return result was found. + * If this function is returning a result by 'value', SWIG did an + * implicit malloc/new. We'll mark the object like it was created + * in Perl so we can garbage collect it. */ + + if (is_shadow(t)) { + Printv(func,tab4, "return undef if (!defined($result));\n", NIL); + + /* If we're returning an object by value, put it's reference + into our local hash table */ + + if ((!SwigType_ispointer(t) && !SwigType_isreference(t)) || Getattr(n,"feature:new")) { + Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", NIL); + } + + /* We're returning a Perl "object" of some kind. Turn it into + a tied hash */ + + Printv(func, + tab4, "my %resulthash;\n", + tab4, "tie %resulthash, ref($result), $result;\n", + tab4, "return bless \\%resulthash, ref($result);\n", + "}\n", + NIL); + + need_wrapper = 1; + } else { + + /* Hmmm. This doesn't appear to be anything I know about so just + return it unmodified */ + + Printv(func, tab4,"return $result;\n", "}\n", NIL); + } + + if (need_wrapper) { + Printv(pcode,func,NIL); + } else { + Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); + } + Delete(func); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * membervariableHandler() + * + * Adds an instance member. This is a little hairy because data members are + * really added with a tied-hash table that is attached to the object. + * + * On the low level, we will emit a pair of get/set functions to retrieve + * values just like before. These will then be encapsulated in a FETCH/STORE + * method associated with the tied-hash. + * + * In the event that a member is an object that we have already wrapped, then + * we need to retrieve the data a tied-hash as opposed to what SWIG normally + * returns. To determine this, we build an internal hash called 'BLESSEDMEMBERS' + * that contains the names and types of tied data members. If a member name + * is in the list, we tie it, otherwise, we just return the normal SWIG value. + * ----------------------------------------------------------------------------- */ + + virtual int membervariableHandler(Node *n) { + + String *symname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + + /* Emit a pair of get/set functions for the variable */ + + member_func = 1; + Language::membervariableHandler(n); + member_func = 0; + + if (blessed) { + + Printv(pcode,"*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(Swig_name_member(class_name,symname)), ";\n", NIL); + Printv(pcode,"*swig_", symname, "_set = *", cmodule, "::", Swig_name_set(Swig_name_member(class_name,symname)), ";\n", NIL); + + /* Now we need to generate a little Perl code for this */ + + if (is_shadow(t)) { + + /* This is a Perl object that we have already seen. Add an + entry to the members list*/ + Printv(blessedmembers, + tab4, symname, " => '", is_shadow(t), "',\n", + NIL); + + } + } + have_data_members++; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constructorDeclaration() + * + * Emits a blessed constructor for our class. In addition to our construct + * we manage a Perl hash table containing all of the pointers created by + * the constructor. This prevents us from accidentally trying to free + * something that wasn't necessarily allocated by malloc or new + * ------------------------------------------------------------ */ + + virtual int constructorHandler(Node *n) { + + String *symname = Getattr(n,"sym:name"); + + member_func = 1; + Language::constructorHandler(n); + + if ((blessed) && (!Getattr(n,"sym:nextSibling"))) { + if ((Cmp(symname,class_name) == 0)) { + /* Emit a blessed constructor */ + Printf(pcode, "sub new {\n"); + } else { + /* Constructor doesn't match classname so we'll just use the normal name */ + Printv(pcode, "sub ", Swig_name_construct(symname), " () {\n", NIL); + } + + Printv(pcode, tab4, "my $pkg = shift;\n", + tab4, "my @args = @_;\n", NIL); + + Printv(pcode, + tab4, "my $self = ", cmodule, "::", Swig_name_construct(symname), "(@args);\n", + tab4, "return undef if (!defined($self));\n", + /* tab4, "bless $self, \"", fullclassname, "\";\n", */ + tab4, "$OWNER{$self} = 1;\n", + tab4, "my %retval;\n", + tab4, "tie %retval, \"", fullclassname, "\", $self;\n", + tab4, "return bless \\%retval, $pkg;\n", + "}\n\n", + NIL); + + have_constructor = 1; + } + member_func = 0; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorHandler() + * ------------------------------------------------------------ */ + + virtual int destructorHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + member_func = 1; + Language::destructorHandler(n); + if (blessed) { + Printv(pcode, + "sub DESTROY {\n", + tab4, "return unless $_[0]->isa('HASH');\n", + tab4, "my $self = tied(%{$_[0]});\n", + tab4, "return unless defined $self;\n", + tab4, "delete $ITERATORS{$self};\n", + tab4, "if (exists $OWNER{$self}) {\n", + tab8, cmodule, "::", Swig_name_destroy(symname), "($self);\n", + tab8, "delete $OWNER{$self};\n", + tab4, "}\n}\n\n", + NIL); + have_destructor = 1; + } + member_func = 0; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmemberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int staticmemberfunctionHandler(Node *n) { + member_func = 1; + Language::staticmemberfunctionHandler(n); + member_func = 0; + if ((blessed) && (!Getattr(n,"sym:nextSibling"))) { + String *symname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + if (is_shadow(t)) { + Printv(pcode, + "sub ", symname, " {\n", + tab4, "my @args = @_;\n", + NIL); + + /* Okay. We've made argument adjustments, now call into the package */ + + Printv(pcode, + tab4, "my $result = ", cmodule, "::", Swig_name_member(class_name,symname), + "(@args);\n", + NIL); + + /* Now check to see what kind of return result was found. + * If this function is returning a result by 'value', SWIG did an + * implicit malloc/new. We'll mark the object like it was created + * in Perl so we can garbage collect it. */ + + Printv(pcode,tab4, "return undef if (!defined($result));\n", NIL); + + /* If we're returning an object by value, put it's reference + into our local hash table */ + + if ((!SwigType_ispointer(t) && !SwigType_isreference(t)) || Getattr(n,"feature:new")) { + Printv(pcode, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", NIL); + } + + /* We're returning a Perl "object" of some kind. Turn it into + a tied hash */ + + Printv(pcode, + tab4, "my %resulthash;\n", + tab4, "tie %resulthash, ref($result), $result;\n", + tab4, "return bless \\%resulthash, ref($result);\n", + "}\n", + NIL); + } else { + Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmembervariableHandler() + * ------------------------------------------------------------ */ + + virtual int staticmembervariableHandler(Node *n) { + Language::staticmembervariableHandler(n); + if (blessed) { + String *symname = Getattr(n,"sym:name"); + Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberconstantHandler() + * ------------------------------------------------------------ */ + + virtual int memberconstantHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + int oldblessed = blessed; + + /* Create a normal constant */ + blessed = 0; + Language::memberconstantHandler(n); + blessed = oldblessed; + + if (blessed) { + Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * pragma() + * + * Pragma directive. + * + * %pragma(perl5) code="String" # Includes a string in the .pm file + * %pragma(perl5) include="file.pl" # Includes a file in the .pm file + * ------------------------------------------------------------ */ + + virtual int pragmaDirective(Node *n) { + String *lang; + String *code; + String *value; + if (!ImportMode) { + lang = Getattr(n,"lang"); + code = Getattr(n,"name"); + value = Getattr(n,"value"); + if (Strcmp(lang,"perl5") == 0) { + if (Strcmp(code,"code") == 0) { + /* Dump the value string into the .pm file */ + if (value) { + Printf(pragma_include, "%s\n", value); + } + } else if (Strcmp(code,"include") == 0) { + /* Include a file into the .pm file */ + if (value) { + FILE *f = Swig_open(value); + if (!f) { + Printf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number,value); + } else { + char buffer[4096]; + while (fgets(buffer,4095,f)) { + Printf(pragma_include,"%s",buffer); + } + } + } + } else { + Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number); } } } + return Language::pragmaDirective(n); } +}; + +/* ----------------------------------------------------------------------------- + * swig_perl5() - Instantiate module + * ----------------------------------------------------------------------------- */ + +extern "C" Language * +swig_perl5(void) { + return new PERL5(); } - - - diff --git a/Source/Modules1.1/perl5.h b/Source/Modules1.1/perl5.h deleted file mode 100644 index 90b35f8e6..000000000 --- a/Source/Modules1.1/perl5.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - ****************************************************************************/ - -/************************************************************************** - * class PERL5 - * - * A Perl 5 implementation - **************************************************************************/ - -class PERL5 : public Language { -private: - char *usage_func(char *, SwigType *, ParmList *); -public : - virtual void parse_args(int, char *argv[]); - virtual void initialize(String *modname); - virtual void function(DOH *node); - virtual void variable(DOH *node); - virtual void constant(DOH *node); - virtual void close(void); - virtual void nativefunction(DOH *); - virtual void create_command(String *, String *); - - // Support for blessed perl thingies.... - - virtual void cpp_open_class(DOH *); - virtual void cpp_close_class(); - virtual void cpp_memberfunction(DOH *); - virtual void cpp_staticfunction(DOH *); - virtual void cpp_variable(DOH *); - virtual void cpp_constructor(DOH *); - virtual void cpp_destructor(DOH *); - virtual void cpp_inherit(List *bases); - virtual void cpp_constant(DOH *); - virtual void cpp_class_decl(DOH *); - virtual void add_typedef(SwigType *t, String *name); - virtual void pragma(DOH *node); - virtual void import(String *filename); -}; - - - diff --git a/Source/Modules1.1/php4.cxx b/Source/Modules1.1/php4.cxx new file mode 100644 index 000000000..051e24601 --- /dev/null +++ b/Source/Modules1.1/php4.cxx @@ -0,0 +1,2113 @@ +/* + * PHP4 Support + * + * Richard Palmer + * richard@magicality.org + * Nov 2001 + * + * Portions copyright Sun Microsystems (c) 2001 + * Tim Hockin + * + * Portions copyright Ananova Ltd (c) 2002 + * Sam Liddicott + * + */ + +char cvsroot_php4_cxx[] = "$Header$"; + +#include + +#include "swigmod.h" +#include "swigconfig.h" + +static const char *usage = (char*)"\ +PHP4 Options (available with -php4)\n\ + -cppext - cpp file extension (default to .cpp)\n\ + -proxy - Create proxy classes.\n\ + -dlname name - Set module prefix.\n\ + -make - Create simple makefile.\n\ + -phpfull - Create full make files.\n\ + -withincs libs - With -phpfull writes needed incs in config.m4\n\ + -withlibs libs - With -phpfull writes needed libs in config.m4\n\n\ + -withc libs - With -phpfull makes extra c files in Makefile.in\n\ + -withcxx libs - With -phpfull makes extra c++ files in Makefile.in\n\n"; + +static int constructors=0; +static String *NOTCLASS=NewString("Not a class"); +static Node *classnode=0; +static String *module = 0; +static String *cap_module = 0; +static String *dlname = 0; +static String *withlibs = 0; +static String *withincs = 0; +static String *withc = 0; +static String *withcxx = 0; +static String *outfile = 0; + +//static char *package = 0; // Name of the package +static char *shadow_classname; + +static Wrapper *f_php; +static int gen_extra = 0; +static int gen_make = 0; + +static File *f_runtime = 0; +static File *f_h = 0; +static File *f_phpcode = 0; +static String *phpfilename =0; + +static String *s_header; +static String *s_wrappers; +static String *s_init; +static String *s_vinit; +static String *s_vdecl; +static String *s_cinit; +static String *s_oinit; +static String *s_entry; +static String *cs_entry; +static String *all_cs_entry; +static String *pragma_incl; +static String *pragma_code; +static String *pragma_phpinfo; + +/* Variables for using PHP classes */ +static String *class_name = 0; +static String *realpackage = 0; +static String *package = 0; + +static Hash *shadow_get_vars; +static Hash *shadow_set_vars; +static String *shadow_classdef; +static String *shadow_code; +static int have_default_constructor = 0; +#define NATIVE_CONSTRUCTOR 1 +#define ALTERNATIVE_CONSTRUCTOR 2 +static int native_constructor=0; +static int destructor=0; +static int enum_flag = 0; // Set to 1 when wrapping an enum +static int static_flag = 0; // Set to 1 when wrapping a static functions or member variables +static int const_flag = 0; // Set to 1 when wrapping a const member variables +static int variable_wrapper_flag = 0; // Set to 1 when wrapping a member variable/enum/const +static int wrapping_member = 0; +static Hash *zend_types = 0; + +static String *shadow_enum_code = 0; +static String *php_enum_code = 0; +static String *all_shadow_extra_code = 0; + //Extra code for all shadow classes from %pragma +static String *this_shadow_extra_code = 0; + //Extra Code for current single shadow class freom %pragma +static String *all_shadow_import = 0; + //import for all shadow classes from %pragma +static String *this_shadow_import = 0; + //import for current shadow classes from %pragma +static String *module_baseclass = 0; + //inheritance for module class from %pragma +static String *all_shadow_baseclass = 0; + //inheritence for all shadow classes from %pragma +static String *this_shadow_baseclass = 0; + //inheritance for shadow class from %pragma and cpp_inherit +static String *this_shadow_multinherit = 0; +static int shadow = 1; + + +extern "C" { +static void (*r_prevtracefunc)(SwigType *t, String *mangled, String *clientdata) = 0; +} + +static const char *php_header = +"/*" +"\n +----------------------------------------------------------------------+" +"\n | PHP version 4.0 |" +"\n +----------------------------------------------------------------------+" +"\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |" +"\n +----------------------------------------------------------------------+" +"\n | This source file is subject to version 2.02 of the PHP license, |" +"\n | that is bundled with this package in the file LICENSE, and is |" +"\n | available at through the world-wide-web at |" +"\n | http://www.php.net/license/2_02.txt. |" +"\n | If you did not receive a copy of the PHP license and are unable to |" +"\n | obtain it through the world-wide-web, please send a note to |" +"\n | license@php.net so we can mail you a copy immediately. |" +"\n +----------------------------------------------------------------------+" +"\n | Authors: |" +"\n | |" +"\n +----------------------------------------------------------------------+" +"\n */\n"; + +void +SwigPHP_emit_resource_registrations() { + DOH *key; + String *destructor=0; + String *classname=0; + String *shadow_classname=0; + + if (!zend_types) return; + key = Firstkey(zend_types); + + if (key) Printf(s_oinit,"\n/* Register resource destructors for pointer types */\n"); + while (key) if (1 /* is pointer type*/) { + Node *class_node; + if ((class_node=Getattr(zend_types,key))) { + // Write out destructor function header + Printf(s_wrappers,"/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n",key); + + // write out body + if ((class_node!=NOTCLASS)) { + classname = Getattr(class_node,"name"); + if (! (shadow_classname = Getattr(class_node,"sym:name"))) shadow_classname=classname; + // Do we have a known destructor for this type? + if ((destructor = Getattr(class_node,"destructor"))) { + Printf(s_wrappers,"/* has destructor: %s */\n",destructor); + Printf(s_wrappers,"%s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n",destructor,key); + } else { + Printf(s_wrappers,"/* bah! No destructor for this wrapped class!! */\n"); + } + } else { + Printf(s_wrappers,"/* bah! No destructor for this simple type!! */\n"); + } + + // close function + Printf(s_wrappers,"}\n"); + + // declare le_swig_ to store php registration + Printf(s_vdecl,"static int le_swig_%s=0; /* handle for %s */\n", key, shadow_classname); + + // register with php + Printf(s_oinit,"le_swig_%s=zend_register_list_destructors_ex" + "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n", + key,key,key); + + // store php type in class struct + Printf(s_oinit,"SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", + key,key); + } + key = Nextkey(zend_types); + } +} + +class PHP4 : public Language { +public: + + /* Test to see if a type corresponds to something wrapped with a shadow class. */ + + String *is_shadow(SwigType *t) { + String *r = 0; + Node *n = classLookup(t); + if (n) { + r = Getattr(n,"php:proxy"); // Set by classDeclaration() + if (!r) { + r = Getattr(n,"sym:name"); // Not seen by classDeclaration yet, but this is the name + } + } + return r; + } + + /* ----------------------------------------------------------------------------- + * get_pointer() + * ----------------------------------------------------------------------------- */ + void + get_pointer(char *iname, char *srcname, char *src, char *dest, + SwigType *t, String *f, char *ret) { + + SwigType_remember(t); + SwigType *lt = SwigType_ltype(t); + Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) ", dest, ",", NIL); + + /* If we're passing a void pointer, we give the pointer conversion a NULL + pointer, otherwise pass in the expected type. */ + + if (Cmp(lt,"p.void") == 0) { + Printf(f, " 0 ) < 0) {\n"); + } else { + Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",NIL); + } + + Printv(f, + "zend_error(E_ERROR, \"Type error in ", srcname, " of ", iname, + " Expected %s\", SWIGTYPE", SwigType_manglestr(t), "->name);\n", ret, + ";\n", + "}\n", + NIL); + Delete(lt); + } + + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ + + virtual void main(int argc, char *argv[]) { + int i; + SWIG_library_directory("php4"); + SWIG_config_cppext("cpp"); + + for(i = 1; i < argc; i++) { + if (argv[i]) { + if(strcmp(argv[i], "-phpfull") == 0) { + gen_extra = 1; + Swig_mark_arg(i); + } else if(strcmp(argv[i], "-dlname") == 0) { + if (argv[i+1]) { + dlname = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if(strcmp(argv[i], "-withlibs") == 0) { + if (argv[i+1]) { + withlibs = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if(strcmp(argv[i], "-withincs") == 0) { + if (argv[i+1]) { + withincs = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if(strcmp(argv[i], "-withc") == 0) { + if (argv[i+1]) { + withc = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if(strcmp(argv[i], "-withcxx") == 0) { + if (argv[i+1]) { + withcxx = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if(strcmp(argv[i], "-cppext") == 0) { + if (argv[i+1]) { + SWIG_config_cppext(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i],"-noproxy") == 0)) { + shadow = 0; + Swig_mark_arg(i); + } else if(strcmp(argv[i], "-make") == 0) { + gen_make = 1; + Swig_mark_arg(i); + } else if(strcmp(argv[i], "-help") == 0) { + fputs(usage, stderr); + } + } + } + + Preprocessor_define((void *) "SWIGPHP 1", 0); + Preprocessor_define((void *) "SWIGPHP4 1", 0); + Preprocessor_define ("SWIG_NO_OVERLOAD 1", 0); + SWIG_typemap_lang("php4"); + /* DB: Suggest using a language configuration file */ + SWIG_config_file("php4.swg"); + } + + void create_simple_make(void) { + File *f_make; + + f_make = NewFile((void *)"makefile", "w"); + if(CPlusPlus) + Printf(f_make, "CC=g++\n"); + else + Printf(f_make, "CC=gcc\n"); + + Printf(f_make, + "OBJS=%s_wrap.o\n" + "PROG=lib%s.so\n" + "CFLAGS=-fpic\n" + "LDFLAGS=-shared\n" + "PHP_INC=`php-config --includes`\n" + "EXTRA_INC=\n" + "EXTRA_LIB=\n\n", + module, module); + + Printf(f_make, + "$(PROG): $(OBJS)\n" + "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n" + "%%.o: %%.%s\n" + "\t$(CC) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n", + (CPlusPlus?"cpp":"c")); + + Close(f_make); + } + + void create_extra_files(void) { + File *f_extra; + + static String *configm4=0; + static String *makefilein=0; + static String *credits=0; + + configm4=NewString(""); + Printv(configm4, Swig_file_dirname(outfile), "config.m4", NIL); + + makefilein=NewString(""); + Printv(makefilein, Swig_file_dirname(outfile), "Makefile.in", NIL); + + credits=NewString(""); + Printv(credits, Swig_file_dirname(outfile), "CREDITS", NIL); + + // are we a --with- or --enable- + int with=(withincs || withlibs)?1:0; + + // Note makefile.in only copes with one source file + // also withincs and withlibs only take one name each now + // the code they generate should be adapted to take multiple lines + + if(gen_extra) { + /* Write out Makefile.in */ + f_extra = NewFile(makefilein, "w"); + if (!f_extra) { + Printf(stderr,"Unable to open %s\n",makefilein); + SWIG_exit(EXIT_FAILURE); + } + + Printf(f_extra, + "# $Id$\n\n" + "LTLIBRARY_NAME = php_%s.la\n", + module); + + // CPP has more and different entires to C in Makefile.in + if (! CPlusPlus) Printf(f_extra,"LTLIBRARY_SOURCES = %s %s\n" + "LTLIBRARY_SOURCES_CPP = %s\n",Swig_file_filename(outfile),withc,withcxx); + else Printf(f_extra,"LTLIBRARY_SOURCES = %s\n" + "LTLIBRARY_SOURCES_CPP = %s %s\n" + "LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n" + ,withc,Swig_file_filename(outfile),withcxx); + + Printf(f_extra,"LTLIBRARY_SHARED_NAME = php_%s.la\n" + "LTLIBRARY_SHARED_LIBADD = $(%(upper)s_SHARED_LIBADD)\n\n" + "include $(top_srcdir)/build/dynlib.mk\n", + module,module); + + Printf(f_extra,"\n# patch in .cxx support to php build system to work like .cpp\n" + ".SUFFIXES: .cxx\n\n" + ".cxx.o:\n" + " $(CXX_COMPILE) -c $<\n\n" + ".cxx.lo:\n" + " $(CXX_PHP_COMPILE)\n\n" + ".cxx.slo:\n" + " $(CXX_SHARED_COMPILE)\n\n"); + + Printf(f_extra,"\n# make it easy to test module\n" + "testmodule:\n" + " php -q -d extension_dir=modules %s\n\n",Swig_file_filename(phpfilename)); + Close(f_extra); + + /* Now config.m4 */ + // Note: # comments are OK in config.m4 if you don't mind them + // appearing in the final ./configure file + // (which can help with ./configure debugging) + + // NOTE2: phpize really ought to be able to write out a sample + // config.m4 based on some simple data, I'll take this up with + // the php folk! + f_extra = NewFile(configm4, "w"); + if (!f_extra) { + Printf(stderr, "Unable to open %s\n",configm4); + SWIG_exit(EXIT_FAILURE); + } + + Printf(f_extra, + "dnl $Id$\n" + "dnl ***********************************************************************\n" + "dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n" + "dnl ** for any part of the rest of the %s build system\n" + "dnl ***********************************************************************\n\n" + ,module); + + if (! with) { // must be enable then + Printf(f_extra, + "PHP_ARG_ENABLE(%s, whether to enable %s support,\n" + "[ --enable-%s Enable %s support])\n\n", + module,module,module,module); + } else { + Printf(f_extra, + "PHP_ARG_WITH(%s, for %s support,\n" + "[ --with-%s[=DIR] Include %s support.])\n\n", + module,module,module,module); + // These tests try and file the library we need + Printf(f_extra,"dnl THESE TESTS try and find the library and header files\n" + "dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n" + "dnl as written they assume your header files are all in the same place\n\n"); + + Printf(f_extra,"dnl ** are we looking for %s_lib.h or something else?\n",module); + if (withincs) Printf(f_extra,"HNAMES=\"%s\"\n\n",withincs); + else Printf(f_extra,"HNAMES=\"\"; # %s_lib.h ?\n\n",module); + + Printf(f_extra,"dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n",module,module); + if (withlibs) Printf(f_extra,"LIBNAMES=\"%s\"\n\n",withlibs); + else Printf(f_extra,"LIBNAMES=\"\"; # lib_%s.so ?\n\n",withlibs); + Printf(f_extra,"dnl IF YOU KNOW one of the symbols in the library and you\n" + "dnl specify it below then we can have a link test to see if it works\n" + "LIBSYMBOL=\"\"\n\n"); + } + + // Now write out tests to find thing.. they may need to extend tests + Printf(f_extra,"if test \"$PHP_%(upper)s\" != \"no\"; then\n\n",module); + + // Ready for when we add libraries as we find them + Printf(f_extra," PHP_SUBST(%(upper)s_SHARED_LIBADD)\n\n",module); + + if (withlibs) { // find more than one library + Printf(f_extra," for LIBNAME in $LIBNAMES ; do\n"); + Printf(f_extra," LIBDIR=\"\"\n"); + // For each path element to try... + Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/lib /usr/lib /usr/local/lib ; do\n",module,module); + Printf(f_extra," if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n" + " LIBDIR=\"$i\"\n" + " break\n" + " fi\n" + " done\n\n"); + Printf(f_extra," dnl ** and $LIBDIR should be the library path\n" + " if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n" + " AC_MSG_RESULT(Library files $LIBNAME not found)\n" + " AC_MSG_ERROR(Is the %s distribution installed properly?)\n" + " else\n" + " AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n" + " PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %(upper)s_SHARED_LIBADD)\n" + " fi\n",module,module); + Printf(f_extra," done\n\n"); + } + + if (withincs) { // Find more than once include + Printf(f_extra," for HNAME in $HNAMES ; do\n"); + Printf(f_extra," INCDIR=\"\"\n"); + // For each path element to try... + Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/include $PHP_%(upper)s/includes $PHP_%(upper)s/inc $PHP_%(upper)s/incs /usr/local/include /usr/include; do\n",module,module,module,module,module); + // Try and find header files + Printf(f_extra," if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n" + " INCDIR=\"$i\"\n" + " break\n" + " fi\n" + " done\n\n"); + + Printf(f_extra, + " dnl ** Now $INCDIR should be the include file path\n" + " if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n" + " AC_MSG_RESULT(Include files $HNAME not found)\n" + " AC_MSG_ERROR(Is the %s distribution installed properly?)\n" + " else\n" + " AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n" + " PHP_ADD_INCLUDE($INCDIR)\n" + " fi\n\n",module); + Printf(f_extra," done\n\n"); + } + + if (CPlusPlus) Printf(f_extra, + " # As this is a C++ module..\n" + " PHP_REQUIRE_CXX\n" + " AC_CHECK_LIB(stdc++, cin)\n"); + + if (with) { + Printf(f_extra," if test \"$LIBSYMBOL\" != \"\" ; then\n" + " old_LIBS=\"$LIBS\"\n" + " LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n" + " AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1, [ ])],\n" + " [AC_MSG_ERROR(wrong test lib version or lib not found)])\n" + " LIBS=\"$old_LIBS\"\n" + " fi\n\n"); + } + + Printf(f_extra," AC_DEFINE(HAVE_%(upper)s, 1, [ ])\n",module); + Printf(f_extra,"dnl AC_DEFINE_UNQUOTED(PHP_%(upper)s_DIR, \"$%(upper)s_DIR\", [ ])\n",module,module); + Printf(f_extra," PHP_EXTENSION(%s, $ext_shared)\n",module); + + // and thats all! + Printf(f_extra,"fi\n"); + + Close(f_extra); + + /* CREDITS */ + f_extra = NewFile(credits, "w"); + if (!f_extra) { + Printf(stderr,"Unable to open %s\n",credits); + SWIG_exit(EXIT_FAILURE); + } + Printf(f_extra, "%s\n", module); + Close(f_extra); + } + } + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + + String *filen; + String *s_type; + + /* Initialize all of the output files */ + outfile = Getattr(n,"outfile"); + + /* main output file */ + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + + Swig_banner(f_runtime); + + /* sections of the output file */ + s_init = NewString("/* init section */\n"); + s_header = NewString("/* header section */\n"); + s_wrappers = NewString("/* wrapper section */\n"); + s_type = NewString(""); + /* subsections of the init section */ + s_vinit = NewString("/* vinit subsection */\n"); + s_vdecl = NewString("/* vdecl subsection */\n"); + s_cinit = NewString("/* cinit subsection */\n"); + s_oinit = NewString("/* oinit subsection */\n"); + pragma_phpinfo = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",s_init); + Swig_register_filebyname("header",s_header); + Swig_register_filebyname("wrapper",s_wrappers); + + shadow_classdef = NewString(""); + shadow_code = NewString(""); + php_enum_code = NewString(""); + module_baseclass = NewString(""); + all_shadow_extra_code = NewString(""); + all_shadow_import = NewString(""); + all_shadow_baseclass = NewString(""); + + /* Set the module name */ + module = Copy(Getattr(n,"name")); + cap_module = NewStringf("%(upper)s",module); + + if(shadow) { + realpackage = module; + package = NewStringf("%sc", module); + } + + /* Set the dlname */ + if (!dlname) { +#if defined(_WIN32) || defined(__WIN32__) + dlname = NewStringf("%s.dll", module); +#else + dlname = NewStringf("%s.so", module); +#endif + } + + /* PHP module file */ + filen = NewString(""); + Printv(filen, Swig_file_dirname(outfile), module, ".php", NIL); + phpfilename = NewString(filen); + + f_phpcode = NewFile(filen, "w"); + if (!f_phpcode) { + Printf(stderr, "*** Can't open '%s'\n", filen); + SWIG_exit(EXIT_FAILURE); + } + + Printf(f_phpcode, "v)\n" + "#define %s_FETCH() zend_%s_globals *%s_globals " + "= ts_resource(%s_globals_id)\n" + "#else\n" + "#define %s_D\n" + "#define %s_DC\n" + "#define %s_C\n" + "#define %s_CC\n" + "#define %s_SG(v) (%s_globals.v)\n" + "#define %s_FETCH()\n" + "#endif\n\n" + "#endif /* PHP_%s_H */\n", + cap_module, module, module, cap_module, cap_module, cap_module, module, + cap_module, cap_module, cap_module, module, cap_module, module, module, + module, cap_module, cap_module, cap_module, cap_module, cap_module, module, + cap_module, cap_module); + + Close(f_h); + + Printf(s_header, "%s\n\n",all_cs_entry); + Printf(s_header, + "%s" + " {NULL, NULL, NULL}\n};\n\n" + "zend_module_entry %s_module_entry = {\n" + "#if ZEND_MODULE_API_NO > 20010900\n" + " STANDARD_MODULE_HEADER,\n" + "#endif\n" + " \"%s\",\n" + " %s_functions,\n" + " PHP_MINIT(%s),\n" + " PHP_MSHUTDOWN(%s),\n" + " PHP_RINIT(%s),\n" + " PHP_RSHUTDOWN(%s),\n" + " PHP_MINFO(%s),\n" + "#if ZEND_MODULE_API_NO > 20010900\n" + " NO_VERSION_YET,\n" + "#endif\n" + " STANDARD_MODULE_PROPERTIES\n" + "};\nzend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", + s_entry, module, module, module, module, module, module, module,module,module); + + String *type_table = NewString(""); + SwigType_emit_type_table(f_runtime,type_table); + Printf(s_header,"%s",type_table); + Delete(type_table); + + /* Oh dear, more things being called in the wrong order. This whole + * function really needs totally redoing. + */ + + Printv(f_runtime, s_header, NIL); + + // Wrapper_print(f_c, s_wrappers); + Wrapper_print(f_php, s_wrappers); + + Printf(s_header, "/* end header section */\n"); + Printf(s_wrappers, "/* end wrapper section */\n"); + Printf(s_vdecl, "/* end vdecl subsection */\n"); + + Printv(f_runtime, s_vdecl, s_wrappers, s_init, NIL); + Delete(s_header); + Delete(s_wrappers); + Delete(s_init); + Delete(s_vdecl); + Close(f_runtime); + Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code); + Close(f_phpcode); + + create_extra_files(); + + if(!gen_extra && gen_make) + create_simple_make(); + + return SWIG_OK; + } + +/* Just need to append function names to function table to register with + PHP +*/ + + void create_command(char *cname, char *iname) { +// char *lower_cname = strdup(cname); +// char *c; + +// for(c = lower_cname; *c != '\0'; c++) { +// if(*c >= 'A' && *c <= 'Z') +// *c = *c + 32; +// } + + Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname); + + // This is for the single main function_entry record + if (! cs_entry) Printf(s_entry, + " ZEND_NAMED_FE(%(lower)s,\n" + " %s, NULL)\n", cname,iname); + +// free(lower_cname); + } + + /* ------------------------------------------------------------ + * functionWrapper() + * ------------------------------------------------------------ */ + + virtual int functionWrapper(Node *n) { + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + int newobject = (Getattr(n,"feature:new"))?1:0; + Parm *p; + char source[256],target[256],temp[256],argnum[32],args[32]; + int i,numopt; + String *tm; + Wrapper *f; + int num_saved = (Getattr(n,"feature:new"))?1:0; + String *cleanup, *outarg; + bool mvr=(shadow && variable_wrapper_flag && !enum_flag); + bool mvrset=0; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + mvrset=(mvr && (strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0)); + + // if shadow and variable wrapper we want to snag the main contents + // of this function to stick in to the property handler.... + if (mvr) { //shadow && variable_wrapper_flag && !enum_flag) { + String *member_function_name = NewString(""); + String *php_function_name = NewString(iname); + if(strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0) { + Setattr(shadow_set_vars, php_function_name, name); + } + if(strcmp(iname, Char(Swig_name_get(Swig_name_member(shadow_classname, name)))) == 0) { + Setattr(shadow_get_vars, php_function_name, name); + } + Putc(toupper((int )*iname), member_function_name); + Printf(member_function_name, "%s", iname+1); + + cpp_func(Char(member_function_name), d, l, php_function_name); + + Delete(php_function_name); + Delete(member_function_name); + } + + outarg = cleanup = NULL; + f = NewWrapper(); + numopt = 0; + + outarg = NewString(""); + cleanup = NewString(""); + + // Special action for shadowing destructors under php. + // The real destructor is the resource list destructor, this is + // merely the thing that actually knows how to destroy... + + if (destructor) { + String *destructorname=NewString(""); + Printf(destructorname,"_%s",Swig_name_wrapper(iname)); + Setattr(classnode,"destructor",destructorname); + + Wrapper *df = NewWrapper(); + Printf(df->def,"/* This function is designed to be called by the zend list destructors to typecast and do the actual destruction */\n" + "void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n",destructorname); + + Wrapper_add_localv(df, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL); + Wrapper_add_localv(df, "ptr", "void *ptr=value->ptr", NIL); + Wrapper_add_localv(df, "newobject", "int newobject=value->newobject", NIL); + // Magic spell nicked from further down. + emit_args(d, l, df); + emit_attach_parmmaps(l,f); + + // Get type of first arg, thing to be destructed + // Skip ignored arguments + { + p=l; + //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + + Printf(df->code, + " efree(value);\n" + " if (! newobject) return; /* can't delete it! */\n" + " SWIG_ZTS_ConvertResourceData(ptr,rsrc->type,type_name,(void **) &arg1,SWIGTYPE%s TSRMLS_CC);\n" + " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n" + ,SwigType_manglestr(pt), shadow_classname); + } + emit_action(n,df); + + Printf(df->code,"}\n"); + + Wrapper_print(df,s_wrappers); + } + + if (mvr) { // do prop[gs]et header + if (mvrset) Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n",iname); + else Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n",iname); + } else { // regular header + create_command(iname, Char(Swig_name_wrapper(iname))); + Printv(f->def, "ZEND_NAMED_FUNCTION(" , Swig_name_wrapper(iname), ") {\n", NIL); + } + + emit_args(d, l, f); + /* Attach standard typemaps */ + + emit_attach_parmmaps(l,f); + + int num_arguments = emit_num_arguments(l); + int num_required = emit_num_required(l); + numopt = num_arguments - num_required; + + // we do +1 because we are going to push in this_ptr as arg0 if present + // or do we need to? + + sprintf(args, "%s[%d]", "zval **args", num_arguments+1); + + Wrapper_add_local(f, "args",args); + Wrapper_add_localv(f, "argbase", "int argbase=0", NIL); + // This generated code may be called + // 1) as an object method, or + // 2) as a class-method/function (without a "this_ptr") + // Option (1) has "this_ptr" for "this", option (2) needs it as + // first parameter + // NOTE: possible we ignore this_ptr as a param for native constructor + + if (native_constructor) { + if (native_constructor==NATIVE_CONSTRUCTOR) Printf(f->code, "/* NATIVE Constructor */\nint self_constructor=1;\n"); + else Printf(f->code, "/* ALTERNATIVE Constructor */\n"); + } + + if (mvr && ! mvrset) { + Wrapper_add_local(f, "_return_value", "zval _return_value"); + Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value"); + }; + + // only let this_ptr count as arg[-1] if we are not a constructor + // if we are a constructor and this_ptr is null we are called as a class + // method and can make one of us + if (! mvr && native_constructor==0) Printf(f->code, + "if (this_ptr && this_ptr->type==IS_OBJECT) {\n" + " /* fake this_ptr as first arg (till we can work out how to do it better */\n" + " argbase++;\n" + "}\n"); + + // I'd like to write out: + //" //args[argbase++]=&this_ptr;\n" + // but zend_get_parameters_array_ex can't then be told to leave + // the first slot alone, so we have to check whether or not to access + // this_ptr explicitly in each case where we normally just read args[] + + if(numopt > 0) { // membervariable wrappers do not have optional args + Wrapper_add_local(f, "arg_count", "int arg_count"); + Printf(f->code, + "arg_count = ZEND_NUM_ARGS();\n" + "if(arg_count<(%d-argbase) || arg_count>(%d-argbase))\n" + "\tWRONG_PARAM_COUNT;\n\n", + num_required, num_arguments); + + /* Verified args, retrieve them... */ + Printf(f->code, + "if(zend_get_parameters_array_ex(arg_count-argbase,args)!=SUCCESS)" + "\n\t\tWRONG_PARAM_COUNT;\n\n"); + + } else if (!mvr) { + Printf(f->code, + "if(((ZEND_NUM_ARGS() + argbase )!= %d) || (zend_get_parameters_array_ex(%d-argbase, args)" + "!= SUCCESS)) {\n" + "WRONG_PARAM_COUNT;\n}\n\n", + num_arguments, num_arguments); + } + + /* Now convert from php to C variables */ + // At this point, argcount if used is the number of deliberatly passed args + // not including this_ptr even if it is used. + // It means error messages may be out by argbase with error + // reports. We can either take argbase into account when raising + // errors, or find a better way of dealing with _thisptr + // I would like, if objects are wrapped, to assume _thisptr is always + // _this and the and not the first argument + // This may mean looking at Lang::memberfunctionhandler + + for (i = 0, p = l; i < num_arguments; i++) { + /* Skip ignored arguments */ + //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");} + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + + + if (mvr) { // do we assert that numargs=2, that i<2 + if (i==0) sprintf(source,"&(property_reference->object)"); + else sprintf(source,"&value"); + } else { + // Do we fake this_ptr as arg0, or just possibly shift other args by 1 if we did fake? + if (i==0) sprintf(source, "((%d= (num_required)) + Printf(f->code,"\tif(arg_count > %d) {\n", i); + + Setattr(p,"emit:input", source); + + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$target",target); + Replaceall(tm,"$source",source); + Replaceall(tm,"$input", source); + Printf(f->code,"%s\n",tm); + p = Getattr(p,"tmap:in:next"); + if (i >= num_required) { + Printf(f->code,"}\n"); + } + continue; + } else { + Printf(stderr,"%s : Line %d, Unable to use type %s as a function argument.\n", input_file, line_number, SwigType_str(pt,0)); + } + if (i>= num_required) + Printf(f->code,"\t}\n"); + } + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert cleanup code */ + for (i = 0, p = l; p; i++) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert argument output code */ + num_saved = 0; + for (i=0,p = l; p;i++) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$input",Getattr(p,"lname")); + Replaceall(tm,"$target","return_value"); + Replaceall(tm,"$result","return_value"); + + String *in = Getattr(p,"emit:input"); + if (in) { + sprintf(temp,"_saved[%d]", num_saved); + Replaceall(tm,"$arg",temp); + Printf(f->code,"_saved[%d] = %s;\n", num_saved, in); + num_saved++; + } + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + + // These are saved for argout again... + if(num_saved) { + sprintf(temp, "_saved[%d]",num_saved); + // Used to be zval *, perhaps above we should use * %s + Wrapper_add_localv(f,"_saved","zval **",temp,NIL); + } + + /* emit function call*/ + if (destructor) { + // If it is a registered resource (and it always should be) + // then destroy it the resource way + + Printf(f->code, + "/*if ((*args[0])->type==IS_RESOURCE) { */\n" + "/* Get zend list destructor to free it */\n" + "/* zend_list_delete(Z_LVAL_PP(args[0])); */\n" + "/* } else {*/ \n",name,name + ); + // but leave the old way in for as long as we accept strings as swig objects + emit_action(n,f); + Printf(f->code,"/*}*/\n"); + } else { + emit_action(n,f); + } + + if((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"result",(char*)"return_value",0))) { + Replaceall(tm, "$input", "result"); + Replaceall(tm, "$source", "result"); + Replaceall(tm, "$target", "return_value"); + Replaceall(tm, "$result", "return_value"); + Replaceall(tm,"$owner", newobject ? "1" : "0"); + Printf(f->code, "%s\n", tm); + // are we returning a wrapable object? + // I don't know if this test is comlete, I nicked it + if(is_shadow(d) && (SwigType_type(d) != T_ARRAY)) { + Printf(f->code,"/* Wrap this return value */\n"); + if (native_constructor==NATIVE_CONSTRUCTOR) { + Printf(f->code, "if (this_ptr) {\n/* NATIVE Constructor, use this_ptr */\n"); + Printf(f->code,"zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n" + "*_cPtr = *return_value;\n" + "INIT_ZVAL(*return_value);\n" + "add_property_zval(this_ptr,\"_cPtr\",_cPtr);\n" + "} else if (! this_ptr) ",shadow_classname); + } + { // THIS CODE only really needs writing out if the object to be returned + // Is being shadow-wrap-thingied + Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n"); + // Make object + String *shadowrettype = NewString(""); + SwigToPhpType(d, iname, shadowrettype, shadow); + + Printf(f->code, + "zval *obj, *_cPtr;\n" + "MAKE_STD_ZVAL(obj);\n" + "MAKE_STD_ZVAL(_cPtr);\n" + "*_cPtr = *return_value;\n" + "INIT_ZVAL(*return_value);\n"); + + if (! shadow) { + Printf(f->code, + "*return_value=*_cPtr;\n"); + } else { + Printf(f->code, + "object_init_ex(obj,ptr_ce_swig_%s);\n" + "add_property_zval(obj,\"_cPtr\",_cPtr);\n" + "*return_value=*obj;\n", + shadowrettype); + } + Printf(f->code, "}\n"); + } + } // end of if-shadow lark + } else { + Printf(stderr,"%s: Line %d, Unable to use return type %s in function %s.\n", input_file, line_number, SwigType_str(d,0), name); + } + + if(outarg) + Printv(f->code,outarg,NIL); + + if(cleanup) + Printv(f->code,cleanup,NIL); + + // Whats this bit for? + if((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char *)"result", (char*)"result",(char*)"",0))) { + Printf(f->code,"%s\n", tm); + } + + Replaceall(f->code,"$cleanup",cleanup); + Replaceall(f->code,"$symname",iname); + + if (mvr) { + if (! mvrset) Printf(f->code,"return _return_value;\n"); + else Printf(f->code,"return SUCCESS;\n"); + } + + Printf(f->code, "}\n"); + Wrapper_print(f,s_wrappers); + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * variableWrapper() + * ------------------------------------------------------------ */ + + virtual int OLDvariableWrapper(Node *n) { + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + String *tm; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + SwigType_remember(t); + + /* First link C variables to PHP */ + + tm = Swig_typemap_lookup_new("varinit", n, name, 0); + if(tm) { + Replaceall(tm, "$target", name); + Printf(s_vinit, "%s\n", tm); + } else { + Printf(stderr,"%s: Line %d, Unable to link with type %s\n", + input_file, line_number, SwigType_str(t,0), name); + } + + /* Now generate PHP -> C sync blocks */ + tm = Swig_typemap_lookup_new("varin", n, name, 0); + /* + if(tm) { + Replaceall(tm, "$symname", iname); + Printf(f_c->code, "%s\n", tm); + } else { + Printf(stderr,"%s: Line %d, Unable to link with type %s\n", + input_file, line_number, SwigType_str(t, 0), name); + } +*/ + /* Now generate C -> PHP sync blocks */ +/* + if(!Getattr(n,"feature:immutable")) { + + tm = Swig_typemap_lookup_new("varout", n, name, 0); + if(tm) { + Replaceall(tm, "$symname", iname); + Printf(f_php->code, "%s\n", tm); + } else { + Printf(stderr,"%s: Line %d, Unable to link with type %s\n", + input_file, line_number, SwigType_str(t, 0), name); + } + } +*/ + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + char *value = GetChar(n,"value"); + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + String *rval; + String *tm; + + SwigType_remember(type); + + switch(SwigType_type(type)) { + case T_STRING: + rval = NewStringf("\"%s\"", value); + break; + case T_CHAR: + rval = NewStringf("\'%s\'", value); + break; + default: + rval = NewString(value); + } + + if((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) { + Replaceall(tm, "$source", value); + Replaceall(tm, "$target", name); + Replaceall(tm, "$value", value); + Printf(s_cinit, "%s\n", tm); + } + return SWIG_OK; + } + + /* + * PHP4::pragma() + * + * Pragma directive. + * + * %pragma(php4) code="String" # Includes a string in the .php file + * %pragma(php4) include="file.pl" # Includes a file in the .php file + */ + + virtual int pragmaDirective(Node *n) { + if (!ImportMode) { + String *lang = Getattr(n,"lang"); + String *type = Getattr(n,"name"); + String *value = Getattr(n,"value"); + + if (Strcmp(lang,"php4") == 0) { + + if (Strcmp(type, "code") == 0) { + if (value) + Printf(pragma_code, "%s\n", value); + } else if (Strcmp(type, "include") == 0) { + if (value) + Printf(pragma_incl, "include \"%s\";\n", value); + } else if (Strcmp(type, "phpinfo") == 0) { + if (value) + Printf(pragma_phpinfo, "%s\n", value); + } else { + Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", + input_file, line_number); + } + } + } + return Language::pragmaDirective(n); + } + + /* ------------------------------------------------------------ + * classDeclaration() + * ------------------------------------------------------------ */ + + virtual int classDeclaration(Node *n) { + String *symname = Getattr(n,"sym:name"); + Setattr(n,"php:proxy",symname); + return Language::classDeclaration(n); + } + + /* ------------------------------------------------------------ + * classHandler() + * ------------------------------------------------------------ */ + + virtual int classHandler(Node *n) { + constructors=0; + //SwigType *t = Getattr(n, "classtype"); + if(class_name) free(class_name); + class_name = Swig_copy_string(GetChar(n, "name")); + // String *use_class_name=SwigType_manglestr(SwigType_ltype(t)); + + if(shadow) { + char *rename = GetChar(n, "sym:name"); + if (!addSymbol(rename,n)) return SWIG_ERROR; + shadow_classname = Swig_copy_string(rename); + cs_entry = NewString(""); + Printf(cs_entry,"/* Function entries for %s */\n" + "static zend_function_entry %s_functions[] = {\n" + ,shadow_classname, shadow_classname); + + if(Strcmp(shadow_classname, module) == 0) { + Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname); + SWIG_exit(1); + } + + Clear(shadow_classdef); + Clear(shadow_code); + + have_default_constructor = 0; + shadow_enum_code = NewString(""); + this_shadow_baseclass = NewString(""); + this_shadow_multinherit = NewString(""); + this_shadow_extra_code = NewString(""); + this_shadow_import = NewString(""); + + shadow_get_vars = NewHash(); + shadow_set_vars = NewHash(); + + /* Deal with inheritance */ + List *baselist = Getattr(n, "bases"); + + if(baselist) { + int class_count = 0; + Node *base = Firstitem(baselist); + + while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist); + + if (base && is_shadow(Getattr(base, "name"))) { + class_count++; + Printf(this_shadow_baseclass, "%s", Getattr(base, "name")); + } + + if (base) for(base = Nextitem(baselist); base; base = Nextitem(baselist)) { + if (Getattr(base,"feature:ignore")) continue; + if(is_shadow(Getattr(base, "name"))) { + class_count++; + Printf(this_shadow_multinherit, "%s ", Getattr(base, "name")); + } + } + + if(class_count > 1) Printf(stderr, "Error: %s inherits from multiple base classes(%s %s). Multiple inheritance is not directly supported by PHP4, SWIG may support it at some point in the future.\n", shadow_classname, base, this_shadow_multinherit); + } + + /* Write out class init code */ + Printf(s_vdecl,"static zend_class_entry ce_swig_%s;\n",shadow_classname); + Printf(s_vdecl,"static zend_class_entry* ptr_ce_swig_%s=NULL;\n",shadow_classname); + } + + classnode=n; + Language::classHandler(n); + classnode=0; + + if(shadow) { + DOH *key; + int gcount, scount; + String *s_propget=NewString(""); + String *s_propset=NewString(""); + List *baselist = Getattr(n, "bases"); + Node *base = NULL; + + // If no constructor was generated (abstract class) we had better + // generate a constructor that raises an error about instantiating + // abstract classes + if (! constructors || Getattr(n,"abstract")) { + // have to write out fake constructor which raises an error when called + abstractConstructorHandler(n); + } + + Printf(s_oinit,"/* Define class %s */\n" + "INIT_OVERLOADED_CLASS_ENTRY(ce_swig_%s,\"%(lower)s\",%s_functions," + "NULL,_wrap_propget_%s,_wrap_propset_%s);\n", + shadow_classname,shadow_classname,shadow_classname, + shadow_classname,shadow_classname,shadow_classname); + + // ******** Write property SET handlers + Printf(s_header,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname); + Printf(s_propset,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n" + " zval * _value;\n" + " zend_llist_element *element = property_reference->elements_list->head;\n" + " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" + " if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n" + " /* set it ourselves as it is %s */\n" + " MAKE_STD_ZVAL(_value);\n" + " *_value=*value;\n" + " INIT_PZVAL(_value);\n" + " zval_copy_ctor(_value);\n" + " return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n" + "}\n", shadow_classname, shadow_classname,shadow_classname); + Printf(s_header,"static int _propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname); + Printf(s_propset,"static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname); + + if (baselist) base=Firstitem(baselist); + else base=NULL; + while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist); + key = Firstkey(shadow_set_vars); + + // Print function header; we only need to find property name if there + // are properties for this class to look up... + if (key || ! base) { // or if we are base class and set it ourselves + Printf(s_propset," /* get the property name */\n" + " zend_llist_element *element = property_reference->elements_list->head;\n" + " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" + " char *propname=Z_STRVAL_P(&(property->element));\n"); + } else { + if (base) { + Printf(s_propset," /* No extra properties for subclass %s */\n",shadow_classname); + } else { + Printf(s_propset," /* No properties for base class %s */\n",shadow_classname); + } + } + + scount=0; + while (key) { + if (scount++) Printf(s_propset," else"); + Printf(s_propset," if (strcmp(propname,\"%s\")==0) {\n" + " return _wrap_%s(property_reference, value);\n" + " }",Getattr(shadow_set_vars,key),key); + + key=Nextkey(shadow_set_vars); + } + + if (scount) Printf(s_propset," else"); + + // If there is a base class then chain it's handler else set directly + // try each base class handler, else set directly... + if (base) { + Printf(s_propset, " {\n /* chain to base class */\n"); + while(base) { + Printf(s_propset," if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", + GetChar(base, "sym:name")); + + base=Nextitem(baselist); + while (base && Getattr(base,"feature:ignore")) base=Nextitem(baselist); + } + Printf(s_propset," }\n"); + } + Printf(s_propset," return FAILURE;\n}\n\n"); + + // ******** Write property GET handlers + Printf(s_header,"static pval _wrap_propget_%s(zend_property_reference *property_reference);\n", shadow_classname); + Printf(s_propget,"static pval _wrap_propget_%s(zend_property_reference *property_reference) {\n" + " pval result;\n" + " pval **_result;\n" + " zend_llist_element *element = property_reference->elements_list->head;\n" + " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" + " result.type = IS_NULL;\n" + " if (_propget_%s(property_reference, &result)==SUCCESS) return result;\n" + " /* return it ourselves */\n" + " if (zend_hash_find(Z_OBJPROP_P(property_reference->object),Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),(void**)&_result)==SUCCESS) {\n" + " zval *_value;\n" + " MAKE_STD_ZVAL(_value);" + " *_value=**_result;\n" + " INIT_PZVAL(_value);\n" + " zval_copy_ctor(_value);\n" + " return *_value;\n" + " }\n" + " result.type = IS_NULL;\n" + " return result;\n" + "}\n", shadow_classname, shadow_classname); + Printf(s_header,"static int _propget_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname); + Printf(s_propget,"static int _propget_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname); + + if (baselist) base=Firstitem(baselist); + else base=NULL; + while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist); + key = Firstkey(shadow_get_vars); + + // Print function header; we only need to find property name if there + // are properties for this class to look up... + if (key || !base ) { // or if we are base class... + Printf(s_propget," /* get the property name */\n" + " zend_llist_element *element = property_reference->elements_list->head;\n" + " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" + " char *propname=Z_STRVAL_P(&(property->element));\n"); + } else { + if (base) { + Printf(s_propget," /* No extra properties for subclass %s */\n",shadow_classname); + } else { + Printf(s_propget," /* No properties for base class %s */\n",shadow_classname); + } + } + + gcount=0; + while (key) { + if (gcount++) Printf(s_propget," else"); + Printf(s_propget," if (strcmp(propname,\"%s\")==0) {\n" + " *value=_wrap_%s(property_reference);\n" + " return SUCCESS;\n" + " }",Getattr(shadow_get_vars,key),key); + + key=Nextkey(shadow_get_vars); + } + + if (gcount) Printf(s_propget," else"); + + // If there is a base class then chain it's handler else return null + if (base) { + Printf(s_propget, " {\n /* chain to base class */\n"); + while(base) { + Printf(s_propget," if (_propget_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", + GetChar(base, "sym:name")); + + base=Nextitem(baselist); + while (base && Getattr(base,"feature:ignore")) base=Nextitem(baselist); + } + Printf(s_propget," }\n"); + } + Printf(s_propget," return FAILURE;\n}\n\n"); + + // wrappers generated now... + + // add wrappers to output code + Printf(s_wrappers,"/* property handler for class %s */\n",shadow_classname); + Printv(s_wrappers,s_propget,s_propset,NIL); + + // Save class in class table + if (baselist) base=Firstitem(baselist); + else base=NULL; + while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist); + + if (base) { + Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n", + shadow_classname,shadow_classname,GetChar(base, "sym:name"), shadow_classname); + } else { + Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n", + shadow_classname,shadow_classname, shadow_classname); + } + Printf(s_oinit,"\n"); + + + Printv(f_phpcode, shadow_classdef, shadow_code, NIL); + + // Write the enum initialisation code in a static block + // These are all the enums defined withing the c++ class. + + // PHP Needs to handle shadow enums properly still + if(strlen(Char(shadow_enum_code)) != 0 ) Printv(f_phpcode, "{\n /* enum */\n", shadow_enum_code, " }\n", NIL); + + free(shadow_classname); + shadow_classname = NULL; + + Delete(shadow_enum_code); shadow_enum_code = NULL; + Delete(this_shadow_baseclass); this_shadow_baseclass = NULL; + Delete(this_shadow_extra_code); this_shadow_extra_code = NULL; + Delete(this_shadow_import); this_shadow_import = NULL; + Delete(shadow_set_vars); shadow_set_vars = NULL; + Delete(shadow_get_vars); shadow_get_vars = NULL; + Delete(this_shadow_multinherit); this_shadow_multinherit = NULL; + + Printf(all_cs_entry,"%s { NULL, NULL, NULL}\n};\n",cs_entry); + //??delete cs_entry; + cs_entry=NULL; + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int memberfunctionHandler(Node *n) { + char *name = GetChar(n, "name"); + char *iname = GetChar(n, "sym:name"); + SwigType *t = Getattr(n, "type"); + ParmList *l = Getattr(n, "parms"); + + this->Language::memberfunctionHandler(n); + + if(shadow) { + char *realname = iname ? iname : name; + String *php_function_name = Swig_name_member(shadow_classname, realname); + + cpp_func(iname, t, l, realname, php_function_name); + + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * membervariableHandler() + * ------------------------------------------------------------ */ + + virtual int membervariableHandler(Node *n) { + + wrapping_member = 1; + variable_wrapper_flag = 1; + Language::membervariableHandler(n); + wrapping_member = 0; + variable_wrapper_flag = 0; + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmemberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int staticmemberfunctionHandler(Node *n) { + char *name = GetChar(n, "name"); + char *iname = GetChar(n, "sym:name"); + + Language::staticmemberfunctionHandler(n); + + if(shadow) { + String *symname = Getattr(n, "sym:name"); + static_flag = 1; + char *realname = iname ? iname : name; + String *php_function_name = Swig_name_member(shadow_classname, realname); + cpp_func(Char(symname), Getattr(n, "type"), Getattr(n, "parms"), symname, php_function_name); + static_flag = 0; + } + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmembervariableHandler() + * ------------------------------------------------------------ */ + + virtual int staticmembervariableHandler(Node *n) { + SwigType *d = Getattr(n, "type"); + char *iname = GetChar(n, "sym:name"); + char *name = GetChar(n, "name"); + String *static_name = NewStringf("%s::%s", class_name, name); +// String *use_class_name=SwigType_manglestr(SwigType_ltype(t)); + Wrapper *f; + + /* A temporary(!) hack for static member variables. + * Php currently supports class functions, but not class variables. + * Until it does, we convert a class variable to a class function + * that returns the current value of the variable. E.g. + * + * class Example { + * public: + * static int ncount; + * }; + * + * would be available in php as Example::ncount() + */ + static_flag = 1; + if(Getattr(n,"feature:immutable")) { + const_flag = 1; + } + cpp_func(iname, d, 0, iname); + static_flag = 0; + + create_command(iname, Char(Swig_name_wrapper(iname))); + + f = NewWrapper(); + + Printv(f->def, "ZEND_NAMED_FUNCTION(", Swig_name_wrapper(iname), ") {\n", NIL); + + /* If a argument is given we set the variable. Then we return + * the current value + */ + + Printf(f->code, + "zval **args[1];\n" + "int argcount;\n\n" + "argcount = ZEND_NUM_ARGS();\n" + "if(argcount > %d) WRONG_PARAM_COUNT;\n\n", (const_flag? 0 : 1)); + + if(!const_flag) { + Printf(f->code, "if(argcount) {\n"); + + Printf(f->code, "if(zend_get_parameters_array_ex(argcount, args) != SUCCESS) WRONG_PARAM_COUNT;\n"); + + switch(SwigType_type(d)) { + case T_BOOL: + case T_INT: + case T_SHORT: + case T_LONG: + case T_SCHAR: + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + Printf(f->code, + "convert_to_long_ex(args[0]);\n" + "%s = Z_LVAL_PP(args[0]);\n", static_name); + break; + case T_CHAR: + Printf(f->code, + "convert_to_string_ex(args[0]);\n" + "%s = estrdup(Z_STRVAL(args[0]));\n", static_name); + break; + case T_DOUBLE: + case T_FLOAT: + Printf(f->code, + "convert_to_double_ex(args[0]);\n" + "%s = Z_DVAL_PP(args[0]);\n", + static_name); + break; + case T_VOID: + break; + case T_USER: + Printf(f->code, "convert_to_string_ex(args[0]);\n"); + get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char *)"RETURN_FALSE"); + break; + case T_POINTER: + case T_ARRAY: + case T_REFERENCE: + Printf(f->code, "convert_to_string_ex(args[0]);\n"); + get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char*)"RETURN_FALSE"); + break; + default: + Printf(stderr,"%s : Line %d, Unable to use type %s as a class variable.\n", input_file, line_number, SwigType_str(d,0)); + break; + } + + Printf(f->code, "}\n\n"); + + } /* end of const_flag */ + + switch(SwigType_type(d)) { + case T_BOOL: + case T_INT: + case T_SHORT: + case T_LONG: + case T_SCHAR: + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + Printf(f->code, + "RETURN_LONG(%s);\n", static_name); + break; + case T_DOUBLE: + case T_FLOAT: + Printf(f->code, + "RETURN_DOUBLE(%s);\n", static_name); + break; + case T_CHAR: + Printf(f->code, + "{\nchar ctemp[2];\n" + "ctemp[0] = %s;\n" + "ctemp[1] = 0;\n" + "RETURN_STRING(ctemp, 1);\n}\n", + static_name); + break; + + case T_USER: + case T_POINTER: + Printf(f->code, + "SWIG_SetPointerZval(return_value, (void *)%s, " + "SWIGTYPE%s);\n", static_name, SwigType_manglestr(d)); + break; + case T_STRING: + Printf(f->code, "RETURN_STRING(%s, 1);\n", static_name); + break; + } + + + Printf(f->code, "}\n"); + + const_flag = 0; + + Wrapper_print(f, s_wrappers); + + return SWIG_OK; + } + + + void SwigToPhpType(SwigType *t, String_or_char *pname, String* php_type, int shadow_flag) { + char *ptype = 0; + + if(shadow_flag) + ptype = PhpTypeFromTypemap((char*)"pstype", t, pname,(char*)""); + if(!ptype) + ptype = PhpTypeFromTypemap((char*)"ptype",t,pname,(char*)""); + + + if(ptype) { + Printf(php_type, ptype); + free(ptype); + } + else { + /* Map type here */ + switch(SwigType_type(t)) { + case T_CHAR: + case T_SCHAR: + case T_UCHAR: + case T_SHORT: + case T_USHORT: + case T_INT: + case T_UINT: + case T_LONG: + case T_ULONG: + case T_FLOAT: + case T_DOUBLE: + case T_BOOL: + case T_STRING: + case T_VOID: + Printf(php_type, ""); + break; + case T_POINTER: + case T_REFERENCE: + case T_USER: + if(shadow_flag && is_shadow(t)) + Printf(php_type, Char(is_shadow(t))); + else + Printf(php_type, ""); + break; + case T_ARRAY: + /* TODO */ + break; + default: + Printf(stderr, "SwigToPhpType: unhandled data type: %s\n", SwigType_str(t,0)); + break; + } + } + } + + + char *PhpTypeFromTypemap(char *op, SwigType *t, String_or_char *pname, String_or_char *lname) { + String *tms; + char bigbuf[1024]; + char *tm; + char *c = bigbuf; + if(!(tms = Swig_typemap_lookup(op, t, pname, lname, (char*)"", (char*)"", NULL))) return NULL; + + tm = Char(tms); + while(*tm && (isspace(*tm) || *tm == '{')) tm++; + while(*tm && *tm != '}') *c++ = *tm++; + *c='\0'; + return Swig_copy_string(bigbuf); + } + + int abstractConstructorHandler(Node *n) { + char *iname = GetChar(n, "sym:name"); + if (shadow) { + Wrapper *f; + f = NewWrapper(); + + // constructor header + if (cs_entry) Printf(cs_entry, + " ZEND_NAMED_FE(%(lower)s,\n" + " _wrap_new_%s, NULL)\n", iname,iname); + // now constructor body + Printf(f_h, "ZEND_NAMED_FUNCTION(_wrap_new_%s);\n",iname); + Printf(f->def, "ZEND_NAMED_FUNCTION(_wrap_new_%s) {\n" + "zend_error(E_ERROR,\"Cannot create swig object type: %s as the underlying object is abstract\");\n" + "}\n\n", iname, iname); + Wrapper_print(f,s_wrappers); + DelWrapper(f); + } + return SWIG_OK; + } + /* ------------------------------------------------------------ + * constructorHandler() + * ------------------------------------------------------------ */ + + virtual int constructorHandler(Node *n) { + char *iname = GetChar(n, "sym:name"); + + if (shadow) native_constructor = (strcmp(iname, shadow_classname) == 0)?\ + NATIVE_CONSTRUCTOR:ALTERNATIVE_CONSTRUCTOR; + else native_constructor=0; + constructors++; + Language::constructorHandler(n); + + if(shadow) { + // But we also need one per wrapped-class + if (cs_entry) Printf(cs_entry, + " ZEND_NAMED_FE(%(lower)s,\n" + " _wrap_new_%s, NULL)\n", iname,iname); + } + + native_constructor = 0; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorHandler() + * ------------------------------------------------------------ */ + + virtual int destructorHandler(Node *n) { + char *iname = GetChar(n, "sym:name"); + + destructor=1; + Language::destructorHandler(n); + destructor=0; + + // we don't give user access to destructors, they have to unset var + // and let php dispose instead + if(0 && shadow) { + // But we also need one per wrapped-class + if (cs_entry) Printf(cs_entry, + " ZEND_NAMED_FE(_destroy_%(lower)s,\n" + " _wrap_delete_%s, NULL)\n", iname,iname); + } + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberconstantHandler() + * ------------------------------------------------------------ */ + + virtual int memberconstantHandler(Node *n) { + wrapping_member = 1; + Language::memberconstantHandler(n); + wrapping_member = 0; + return SWIG_OK; + } + + // This method is quite stale and ought to be factored out + void cpp_func(char *iname, SwigType *t, ParmList *l, String *php_function_name, String *handler_name = NULL) { + if(!shadow) return; + + // if they didn't provide a handler name, use the realname + if (! handler_name) handler_name=php_function_name; + + if(l) { + if(SwigType_type(Getattr(l, "type")) == T_VOID) { + l = nextSibling(l); + } + } + + // But we also need one per wrapped-class + // Printf(f_h, "x ZEND_NAMED_FUNCTION(%s);\n", Swig_name_wrapper(handler_name)); + if (cs_entry && !(variable_wrapper_flag && shadow)) Printf(cs_entry, + " ZEND_NAMED_FE(%(lower)s,\n" + " %s, NULL)\n", php_function_name,Swig_name_wrapper(handler_name)); + + if(variable_wrapper_flag) { return; } + + /* Workaround to overcome Getignore(p) not working - p does not always + * have the Getignore attribute set. Noticeable when cpp_func is called + * from cpp_member_func() + */ + + Wrapper *f = NewWrapper(); + emit_args(NULL, l, f); + DelWrapper(f); + + /*Workaround end */ + + } + +}; /* class PHP4 */ + +/* ----------------------------------------------------------------------------- + * swig_php() - Instantiate module + * ----------------------------------------------------------------------------- */ + +static PHP4 *maininstance=0; + +// We use this function to be able to write out zend_register_list_destructor_ex +// lines for most things in the type table +// NOTE: it's a function NOT A PHP4::METHOD +extern "C" +void typetrace(SwigType *ty, String *mangled, String *clientdata) { + Node *class_node; + if (!zend_types) { + zend_types=NewHash(); + } + // we want to know if the type which reduced to this has a constructor + if ((class_node=maininstance->classLookup(ty))) { + if (! Getattr(zend_types,mangled)) { + // OK it may have been set before by a different SwigType but it would + // have had the same underlying class node I think + // - it is certainly required not to have different originating class + // nodes for the same SwigType + Setattr(zend_types,mangled,class_node); + } + } else { // a non-class pointer + Setattr(zend_types,mangled,NOTCLASS); + } + if (r_prevtracefunc) (*r_prevtracefunc)(ty, mangled, (String *) clientdata); +} + +extern "C" Language * +swig_php(void) { + maininstance=new PHP4(); + if (! r_prevtracefunc) { + r_prevtracefunc=SwigType_remember_trace(typetrace); + } else { + Printf(stderr,"php4 Typetrace vector already saved!\n"); + assert(0); + } + return maininstance; +} + diff --git a/Source/Modules1.1/pike.cxx b/Source/Modules1.1/pike.cxx new file mode 100644 index 000000000..bcd51763e --- /dev/null +++ b/Source/Modules1.1/pike.cxx @@ -0,0 +1,881 @@ +/*********************************************************************** + * Pike language module for SWIG + ***********************************************************************/ + +char cvsroot_pike_cxx[] = "$Header$"; + +#include "swigmod.h" +#ifndef MACSWIG +#include "swigconfig.h" +#endif + +class PIKE : public Language { +private: + + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; + String *PrefixPlusUnderscore; + int current; + + // Wrap modes + enum { + NO_CPP, + MEMBER_FUNC, + CONSTRUCTOR, + DESTRUCTOR, + MEMBER_VAR, + CLASS_CONST, + STATIC_FUNC, + STATIC_VAR + }; + +public: + + /* --------------------------------------------------------------------- + * PIKE() + * + * Initialize member data + * --------------------------------------------------------------------- */ + + PIKE() { + f_runtime = 0; + f_header = 0; + f_wrappers = 0; + f_init = 0; + PrefixPlusUnderscore = 0; + current = NO_CPP; + } + + /* --------------------------------------------------------------------- + * main() + * + * Parse command line options and initializes variables. + * --------------------------------------------------------------------- */ + + virtual void main(int argc, char *argv[]) { + + /* Set location of SWIG library */ + SWIG_library_directory("pike"); + + /* Look for certain command line options */ + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_PIKE_RUNTIME); + SWIG_exit(EXIT_SUCCESS); + } + } + } + + /* Add a symbol to the parser for conditional compilation */ + Preprocessor_define("SWIGPIKE 1", 0); + + /* Set language-specific configuration file */ + SWIG_config_file("pike.swg"); + + /* Set typemap language */ + SWIG_typemap_lang("pike"); + + /* Enable overloaded methods support */ + allow_overloading(); + } + + /* --------------------------------------------------------------------- + * top() + * --------------------------------------------------------------------- */ + + virtual int top(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + + /* Get the output file name */ + String *outfile = Getattr(n, "outfile"); + + /* Open the output file */ + f_runtime = NewFile(outfile, "w"); + if (!f_runtime) { + Printf(stderr, "*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("init", f_init); + + /* Standard stuff for the SWIG runtime section */ + Swig_banner(f_runtime); + if (NoInclude) { + Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); + } + + Printf(f_header, "#define SWIG_init pike_module_init\n"); + Printf(f_header, "#define SWIG_name \"%s\"\n\n", module); + + /* Change naming scheme for constructors and destructors */ + Swig_name_register("construct","%c_create"); + Swig_name_register("destroy","%c_destroy"); + + /* Current wrap type */ + current = NO_CPP; + + /* Emit code for children */ + Language::top(n); + + /* Close the initialization function */ + Printf(f_init, "}\n"); + SwigType_emit_type_table(f_runtime, f_wrappers); + + /* Close all of the files */ + Dump(f_header, f_runtime); + Dump(f_wrappers, f_runtime); + Wrapper_pretty_print(f_init, f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + + /* Done */ + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * importDirective() + * ------------------------------------------------------------ */ + + virtual int importDirective(Node *n) { + String *modname = Getattr(n,"module"); + if (modname) { + Printf(f_init,"pike_require(\"%s\");\n", modname); + } + return Language::importDirective(n); + } + + /* ------------------------------------------------------------ + * strip() + * + * For names that begin with the current class prefix plus an + * underscore (e.g. "Foo_enum_test"), return the base function + * name (i.e. "enum_test"). + * ------------------------------------------------------------ */ + + String *strip(const DOHString_or_char *name) { + String *s = Copy(name); + if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) { + return s; + } + Replaceall(s, PrefixPlusUnderscore, ""); + return s; + } + + /* ------------------------------------------------------------ + * add_method() + * ------------------------------------------------------------ */ + + void add_method(Node *n, const DOHString_or_char *name, const DOHString_or_char *function, const DOHString_or_char *description) { + String *rename; + if (current != NO_CPP) { + rename = strip(name); + } else { + rename = NewString(name); + } + Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description); + Delete(rename); + } + + /* --------------------------------------------------------------------- + * functionWrapper() + * + * Create a function declaration and register it with the interpreter. + * --------------------------------------------------------------------- */ + + virtual int functionWrapper(Node *n) { + + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + + Parm *p; + String *tm; + int i; + + String *overname = 0; + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); + } else { + if (!addSymbol(iname,n)) return SWIG_ERROR; + } + + Wrapper *f = NewWrapper(); + + /* Write code to extract function parameters. */ + emit_args(d, l, f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + + /* Get number of required and total arguments */ + int num_arguments = emit_num_arguments(l); + int varargs = emit_isvarargs(l); + + /* Which input argument to start with? */ + int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0; + + /* Offset to skip over the attribute name */ + // int offset = (current == MEMBER_VAR) ? 1 : 0; + int offset = 0; + + String *wname = Swig_name_wrapper(iname); + if (overname) { + Append(wname,overname); + } + + Printv(f->def, "static void ", wname, "(INT32 args) {", NIL); + + /* Generate code for argument marshalling */ + String *description = NewString(""); + char source[64]; + for (i = 0, p = l; i < num_arguments; i++) { + + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + + if (i < start) { + String *lstr = SwigType_lstr(pt,0); + Printf(f->code, "%s = (%s) THIS;\n", ln, lstr); + Delete(lstr); + } else { + /* Look for an input typemap */ + sprintf(source, "sp[%d-args]", i-start+offset); + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm, "$source", source); + Replaceall(tm, "$target", ln); + Replaceall(tm, "$input", source); + Setattr(p, "emit:input", source); + Printf(f->code, "%s\n", tm); + String *pikedesc = Getattr(p, "tmap:in:pikedesc"); + if (pikedesc) { + Printv(description, pikedesc, " ", NIL); + } + p = Getattr(p,"tmap:in:next"); + continue; + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); + break; + } + } + p = nextSibling(p); + } + + /* Check for trailing varargs */ + if (varargs) { + if (p && (tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$input", "varargs"); + Printv(f->code,tm,"\n",NIL); + } + } + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert cleanup code */ + String *cleanup = NewString(""); + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert argument output code */ + String *outarg = NewString(""); + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$target","resultobj"); + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + + /* Emit the function call */ + emit_action(n,f); + + /* Clear the return stack */ + Printf(f->code, "pop_n_elems(args);\n"); + + /* Return the function value */ + if (current == CONSTRUCTOR) { + Printv(f->code, "THIS = (void *) result;\n", NIL); + Printv(description, ", tVoid", NIL); + } else if (current == DESTRUCTOR) { + Printv(description, ", tVoid", NIL); + } else { + Wrapper_add_local(f, "resultobj", "struct object *resultobj"); + Printv(description, ", ", NIL); + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + Replaceall(tm,"$source", "result"); + Replaceall(tm,"$target", "resultobj"); + Replaceall(tm,"$result", "resultobj"); + if (Getattr(n,"feature:new")) { + Replaceall(tm,"$owner","1"); + } else { + Replaceall(tm,"$owner","0"); + } + String *pikedesc = Getattr(n, "tmap:out:pikedesc"); + if (pikedesc) { + Printv(description, pikedesc, NIL); + } + Printf(f->code,"%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); + } + } + + /* Output argument output code */ + Printv(f->code,outarg,NIL); + + /* Output cleanup code */ + Printv(f->code,cleanup,NIL); + + /* Look to see if there is any newfree cleanup code */ + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n",tm); + } + } + + /* See if there is any return cleanup code */ + if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n",tm); + } + + /* Close the function */ + Printf(f->code, "}\n"); + + /* Substitute the cleanup code */ + Replaceall(f->code,"$cleanup",cleanup); + + /* Substitute the function name */ + Replaceall(f->code,"$symname",iname); + Replaceall(f->code,"$result","resultobj"); + + /* Dump the function out */ + Wrapper_print(f,f_wrappers); + + /* Now register the function with the interpreter. */ + if (!Getattr(n,"sym:overloaded")) { + add_method(n, iname, wname, description); + } else { + Setattr(n,"wrap:name", wname); + if (!Getattr(n,"sym:nextSibling")) { + dispatchFunction(n); + } + } + + Delete(cleanup); + Delete(outarg); + Delete(description); + Delete(wname); + DelWrapper(f); + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * dispatchFunction() + * + * Emit overloading dispatch function + * ------------------------------------------------------------ */ + + void dispatchFunction(Node *n) { + /* Last node in overloaded chain */ + + int maxargs; + String *tmp = NewString(""); + String *dispatch = Swig_overload_dispatch(n,"return %s(self,args);",&maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *f = NewWrapper(); + String *symname = Getattr(n,"sym:name"); + String *wname = Swig_name_wrapper(symname); + + Printv(f->def, + "struct object *", wname, + "(struct object *self, struct object *args) {", + NULL); + + + Wrapper_add_local(f,"argc","INT32 argc"); + Printf(tmp,"struct object *argv[%d]", maxargs+1); + Wrapper_add_local(f,"argv",tmp); + Wrapper_add_local(f,"ii","INT32 ii"); + Printf(f->code,"argc = sizeof(args);\n"); + Printf(f->code,"for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n",maxargs); + Printf(f->code,"argv[ii] = array_index(args,&argv[ii],ii);\n"); + Printf(f->code,"}\n"); + + Replaceall(dispatch,"$args","self,args"); + Printv(f->code,dispatch,"\n",NIL); + Printf(f->code,"No matching function for overloaded '%s'\n", symname); + Printf(f->code,"return NULL;\n"); + Printv(f->code,"}\n",NIL); + Wrapper_print(f,f_wrappers); + add_method(n,symname,wname,0); + + DelWrapper(f); + Delete(dispatch); + Delete(tmp); + Delete(wname); + } + + /* ------------------------------------------------------------ + * variableWrapper() + * ------------------------------------------------------------ */ + + virtual int variableWrapper(Node *n) { + // return Language::variableWrapper(n); + + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + + String *wname; + // static int have_globals = 0; + String *tm; + Wrapper *getf, *setf; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + getf = NewWrapper(); + setf = NewWrapper(); + + wname = Swig_name_wrapper(iname); + + /* Create a function for setting the value of the variable */ + + Printf(setf->def,"static int %s_set(object *_val) {", wname); + if (!Getattr(n,"feature:immutable")) { + if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { + Replaceall(tm,"$source","_val"); + Replaceall(tm,"$target",name); + Replaceall(tm,"$input","_val"); + Printf(setf->code,"%s\n",tm); + Delete(tm); + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, + "Unable to set variable of type %s.\n", SwigType_str(t,0)); + } + Printf(setf->code," return 0;\n"); + } else { + /* Is a readonly variable. Issue an error */ + + Printv(setf->code, + tab4, "Variable $iname is read-only.\n", + tab4, "return 1;\n", + NIL); + + } + + Printf(setf->code,"}\n"); + Wrapper_print(setf,f_wrappers); + + /* Create a function for getting the value of a variable */ + Printf(getf->def,"static object *%s_get() {", wname); + Wrapper_add_local(getf,"pikeobj", "object *pyobj"); + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$source",name); + Replaceall(tm,"$target","pikeobj"); + Replaceall(tm,"$result","pikeobj"); + Printf(getf->code,"%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, + "Unable to link with type %s\n", SwigType_str(t,0)); + } + + Printf(getf->code," return pikeobj;\n}\n"); + Wrapper_print(getf,f_wrappers); + + /* Now add this to the variable linking mechanism */ + Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,(char*)\"%s\",%s_get, %s_set);\n", iname, wname, wname); + + DelWrapper(setf); + DelWrapper(getf); + return SWIG_OK; + + } + + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + + Swig_require(&n, "*sym:name", "type", "value", NIL); + + String *symname = Getattr(n, "sym:name"); + SwigType *type = Getattr(n, "type"); + String *value = Getattr(n, "value"); + + /* Special hook for member pointer */ + if (SwigType_type(type) == T_MPOINTER) { + String *wname = Swig_name_wrapper(symname); + Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value); + value = wname; + } + + /* Perform constant typemap substitution */ + String *tm = Swig_typemap_lookup_new("constant", n, value, 0); + if (tm) { + Replaceall(tm, "$source", value); + Replaceall(tm, "$target", symname); + Replaceall(tm, "$symname", symname); + Replaceall(tm, "$value", value); + Printf(f_init, "%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value); + } + + Swig_restore(&n); + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * nativeWrapper() + * ------------------------------------------------------------ */ + + virtual int nativeWrapper(Node *n) { + // return Language::nativeWrapper(n); + String *name = Getattr(n,"sym:name"); + String *wrapname = Getattr(n,"wrap:name"); + + if (!addSymbol(wrapname,n)) return SWIG_ERROR; + + add_method(n, name, wrapname,0); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * enumDeclaration() + * ------------------------------------------------------------ */ + + virtual int enumDeclaration(Node *n) { + return Language::enumDeclaration(n); + } + + /* ------------------------------------------------------------ + * enumvalueDeclaration() + * ------------------------------------------------------------ */ + + virtual int enumvalueDeclaration(Node *n) { + return Language::enumvalueDeclaration(n); + } + + /* ------------------------------------------------------------ + * classDeclaration() + * ------------------------------------------------------------ */ + + virtual int classDeclaration(Node *n) { + return Language::classDeclaration(n); + } + + /* ------------------------------------------------------------ + * classHandler() + * ------------------------------------------------------------ */ + + virtual int classHandler(Node *n) { + + String *symname = Getattr(n, "sym:name"); + if (!addSymbol(symname, n)) + return SWIG_ERROR; + + PrefixPlusUnderscore = NewStringf("%s_", getClassPrefix()); + + Printf(f_init, "start_new_program();\n"); + + /* Handle inheritance */ + List *baselist = Getattr(n,"bases"); + if (baselist && Len(baselist) > 0) { + Node *base = Firstitem(baselist); + while (base) { + char *basename = Char(Getattr(base,"name")); + if (SwigType_istemplate(basename)) { + basename = Char(SwigType_namestr(basename)); + } + SwigType *basetype = NewString(basename); + SwigType_add_pointer(basetype); + SwigType_remember(basetype); + String *basemangle = SwigType_manglestr(basetype); + Printf(f_init, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle); + Delete(basemangle); + Delete(basetype); + base = Nextitem(baselist); + } + } else { + Printf(f_init, "ADD_STORAGE(swig_object_wrapper);\n"); + } + + Language::classHandler(n); + + /* Accessors for member variables */ + /* + List *membervariables = Getattr(n,"membervariables"); + if (membervariables && Len(membervariables) > 0) { + membervariableAccessors(membervariables); + } + */ + + /* Done, close the class */ + Printf(f_init, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname); + + SwigType *tt = NewString(symname); + SwigType_add_pointer(tt); + SwigType_remember(tt); + String *tm = SwigType_manglestr(tt); + Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) pr);\n", tm); + Delete(tm); + Delete(tt); + + Delete(PrefixPlusUnderscore); PrefixPlusUnderscore = 0; + + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberfunctionHandler() + * + * Method for adding C++ member function + * ------------------------------------------------------------ */ + + virtual int memberfunctionHandler(Node *n) { + current = MEMBER_FUNC; + Language::memberfunctionHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constructorHandler() + * + * Method for adding C++ member constructor + * ------------------------------------------------------------ */ + + virtual int constructorHandler(Node *n) { + current = CONSTRUCTOR; + Language::constructorHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorHandler() + * ------------------------------------------------------------ */ + + virtual int destructorHandler(Node *n) { + current = DESTRUCTOR; + Language::destructorHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * membervariableAccessors() + * ------------------------------------------------------------ */ + + void membervariableAccessors(List *membervariables) { + String *name; + Node *n; + bool need_setter; + String *funcname; + + /* If at least one of them is mutable, we need a setter */ + need_setter = false; + n = Firstitem(membervariables); + while (n) { + if (!Getattr(n, "feature:immutable")) { + need_setter = true; + break; + } + n = Nextitem(membervariables); + } + + /* Create a function to set the values of the (mutable) variables */ + if (need_setter) { + Wrapper *wrapper = NewWrapper(); + String *setter = Swig_name_member(getClassPrefix(), (char *) "`->="); + String *wname = Swig_name_wrapper(setter); + Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL); + Printf(wrapper->locals, "char *name = (char *) STR0(sp[0-args].u.string);\n"); + + n = Firstitem(membervariables); + while (n) { + if (!Getattr(n, "feature:immutable")) { + name = Getattr(n, "name"); + funcname = Swig_name_wrapper(Swig_name_set(Swig_name_member(getClassPrefix(), name))); + Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name); + Printf(wrapper->code, "%s(args);\n", funcname); + Printf(wrapper->code, "return;\n"); + Printf(wrapper->code, "}\n"); + Delete(funcname); + } + n = Nextitem(membervariables); + } + + /* Close the function */ + Printf(wrapper->code, "pop_n_elems(args);\n"); + Printf(wrapper->code, "}\n"); + + /* Dump wrapper code to the output file */ + Wrapper_print(wrapper, f_wrappers); + + /* Register it with Pike */ + String *description = NewString("tStr tFloat, tVoid"); + add_method(Firstitem(membervariables), "`->=", wname, description); + Delete(description); + + /* Clean up */ + Delete(wname); + Delete(setter); + DelWrapper(wrapper); + } + + /* Create a function to get the values of the (mutable) variables */ + Wrapper *wrapper = NewWrapper(); + String *getter = Swig_name_member(getClassPrefix(), (char *) "`->"); + String *wname = Swig_name_wrapper(getter); + Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL); + Printf(wrapper->locals, "char *name = (char *) STR0(sp[0-args].u.string);\n"); + + n = Firstitem(membervariables); + while (n) { + name = Getattr(n, "name"); + funcname = Swig_name_wrapper(Swig_name_get(Swig_name_member(getClassPrefix(), name))); + Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name); + Printf(wrapper->code, "%s(args);\n", funcname); + Printf(wrapper->code, "return;\n"); + Printf(wrapper->code, "}\n"); + Delete(funcname); + n = Nextitem(membervariables); + } + + /* Close the function */ + Printf(wrapper->code, "pop_n_elems(args);\n"); + Printf(wrapper->code, "}\n"); + + /* Dump wrapper code to the output file */ + Wrapper_print(wrapper, f_wrappers); + + /* Register it with Pike */ + String *description = NewString("tStr, tMix"); + add_method(Firstitem(membervariables), "`->", wname, description); + Delete(description); + + /* Clean up */ + Delete(wname); + Delete(getter); + DelWrapper(wrapper); + } + + /* ------------------------------------------------------------ + * membervariableHandler() + * ------------------------------------------------------------ */ + + virtual int membervariableHandler(Node *n) { + List *membervariables = Getattr(getCurrentClass(),"membervariables"); + if (!membervariables) { + membervariables = NewList(); + Setattr(getCurrentClass(),"membervariables",membervariables); + } + Append(membervariables,n); + current = MEMBER_VAR; + Language::membervariableHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ----------------------------------------------------------------------- + * staticmemberfunctionHandler() + * + * Wrap a static C++ function + * ---------------------------------------------------------------------- */ + + virtual int staticmemberfunctionHandler(Node *n) { + current = STATIC_FUNC; + Language::staticmemberfunctionHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberconstantHandler() + * + * Create a C++ constant + * ------------------------------------------------------------ */ + + virtual int memberconstantHandler(Node *n) { + current = CLASS_CONST; + constantWrapper(n); + current = NO_CPP; + return SWIG_OK; + } + + /* --------------------------------------------------------------------- + * staticmembervariableHandler() + * --------------------------------------------------------------------- */ + + virtual int staticmembervariableHandler(Node *n) { + current = STATIC_VAR; + Language::staticmembervariableHandler(n); + current = NO_CPP; + return SWIG_OK; + } +}; + +/* ----------------------------------------------------------------------------- + * swig_pike() - Instantiate module + * ----------------------------------------------------------------------------- */ + +extern "C" Language * +swig_pike(void) { + return new PIKE(); +} + + + + + diff --git a/Source/Modules1.1/python.cxx b/Source/Modules1.1/python.cxx index c58fae78a..6651ace92 100644 --- a/Source/Modules1.1/python.cxx +++ b/Source/Modules1.1/python.cxx @@ -9,1562 +9,1260 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_python_cxx[] = "$Header$"; -#include "swig11.h" -#include "python.h" +#include "swigmod.h" + +#ifndef MACSWIG +#include "swigconfig.h" +#endif + +#include + +#define PYSHADOW_MEMBER 0x2 static String *const_code = 0; static String *shadow_methods = 0; static String *module = 0; +static String *mainmodule = 0; static String *interface = 0; static String *global_name = 0; -static int shadow = 0; -static int have_defarg = 0; -static int have_output; +static int shadow = 1; static int use_kw = 0; -static int noopt = 1; -static FILE *f_shadow; -static Hash *hash; -static Hash *symbols; -static String *classes; -static String *func; -static String *vars; -static String *pragma_include = 0; -static String *methods; -static char *class_name; -static char *usage = (char *)"\ +static File *f_runtime = 0; +static File *f_header = 0; +static File *f_wrappers = 0; +static File *f_init = 0; +static File *f_shadow = 0; +static File *f_shadow_stubs = 0; + +static String *methods; +static String *class_name; +static String *shadow_indent = 0; +static int in_class = 0; +static int classic = 0; + +/* C++ Support + Shadow Classes */ + +static int have_constructor; +static int have_repr; +static String *real_classname; + +static const char *usage = (char *)"\ Python Options (available with -python)\n\ + -ldflags - Print runtime libraries to link with\n\ -globals name - Set name used to access C global variable ('cvar' by default).\n\ - -module name - Set module name\n\ -interface name - Set the lib name\n\ -keyword - Use keyword arguments\n\ - -noopt - No optimized shadows (pre 1.5.2)\n\ - -opt - Optimized shadow classes (1.5.2 or later)\n\ - -shadow - Generate shadow classes. \n\n"; + -classic - Use classic classes only\n\ + -noexcept - No automatic exception handling.\n\ + -noproxy - Don't generate proxy classes. \n\n"; -/* Test to see if a type corresponds to something wrapped with a shadow class */ -static DOH *is_shadow(SwigType *t) { - DOH *r; - SwigType *lt = Swig_clocal_type(t); - r = Getattr(hash,lt); - Delete(lt); - return r; -} +class PYTHON : public Language { +public: -/* ----------------------------------------------------------------------------- - * PYTHON::parse_args() - * ----------------------------------------------------------------------------- */ -void -PYTHON::parse_args(int argc, char *argv[]) { - int i; - Swig_swiglib_set("python"); + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ + + virtual void main(int argc, char *argv[]) { - for (i = 1; i < argc; i++) { + SWIG_library_directory("python"); + + for (int i = 1; i < argc; i++) { if (argv[i]) { - /* Added edz@bsn.com */ if(strcmp(argv[i],"-interface") == 0) { - if (argv[i+1]) { - interface = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - /* end added */ - } else if (strcmp(argv[i],"-globals") == 0) { - if (argv[i+1]) { - global_name = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i],"-shadow") == 0) { - shadow = 1; + if (argv[i+1]) { + interface = NewString(argv[i+1]); Swig_mark_arg(i); - } else if (strcmp(argv[i],"-noopt") == 0) { - noopt = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-opt") == 0) { - noopt = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-keyword") == 0) { - use_kw = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); } + /* end added */ + } else if (strcmp(argv[i],"-globals") == 0) { + if (argv[i+1]) { + global_name = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) { + shadow = 1; + Swig_mark_arg(i); + } else if ((strcmp(argv[i],"-noproxy") == 0)) { + shadow = 0; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-keyword") == 0) { + use_kw = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-classic") == 0) { + classic = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_PYTHON_RUNTIME); + SWIG_exit (EXIT_SUCCESS); + } } + } + if (!global_name) global_name = NewString("cvar"); + Preprocessor_define("SWIGPYTHON 1", 0); + SWIG_typemap_lang("python"); + SWIG_config_file("python.swg"); + allow_overloading(); } - if (!global_name) global_name = NewString("cvar"); - Preprocessor_define((void *) "SWIGPYTHON", 0); -} -/* ----------------------------------------------------------------------------- - * PYTHON::import() - * ----------------------------------------------------------------------------- */ -void -PYTHON::import(String *modname) { - if (shadow) { - Printf(f_shadow,"\nfrom %s import *\n", modname); + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); + + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",f_init); + + const_code = NewString(""); + shadow_methods = NewString(""); + methods = NewString(""); + + Swig_banner(f_runtime); + + Printf(f_runtime,"#define SWIGPYTHON\n"); + if (NoInclude) + Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); + + /* Set module name */ + module = Copy(Getattr(n,"name")); + mainmodule = Getattr(n,"name"); + + char filen[256]; + + /* If shadow classing is enabled, we're going to change the module name to "_module" */ + if (shadow) { + sprintf(filen,"%s%s.py", Swig_file_dirname(outfile), Char(module)); + // If we don't have an interface then change the module name X to _X + if (interface) module = interface; + else Insert(module,0,"_"); + if ((f_shadow = NewFile(filen,"w")) == 0) { + Printf(stderr,"Unable to open %s\n", filen); + SWIG_exit (EXIT_FAILURE); + } + f_shadow_stubs = NewString(""); + + Swig_register_filebyname("shadow",f_shadow); + Swig_register_filebyname("python",f_shadow); + + Printv(f_shadow, + "# This file was created automatically by SWIG.\n", + "# Don't modify this file, modify the SWIG interface instead.\n", + "# This file is compatible with both classic and new-style classes.\n", + NIL); + + Printf(f_shadow,"import %s\n", module); + + // Python-2.2 object hack + + + Printv(f_shadow, + "def _swig_setattr(self,class_type,name,value):\n", + tab4, "if (name == \"this\"):\n", + tab4, tab4, "if isinstance(value, class_type):\n", + tab4, tab8, "self.__dict__[name] = value.this\n", + tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n", + tab4, tab8, "del value.thisown\n", + tab4, tab8, "return\n", + // tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n", + tab4, "method = class_type.__swig_setmethods__.get(name,None)\n", + tab4, "if method: return method(self,value)\n", + tab4, "self.__dict__[name] = value\n\n", + NIL); + + Printv(f_shadow, + "def _swig_getattr(self,class_type,name):\n", + tab4, "method = class_type.__swig_getmethods__.get(name,None)\n", + tab4, "if method: return method(self)\n", + tab4, "raise AttributeError,name\n\n", + NIL); + + if (!classic) { + Printv(f_shadow, + "import types\n", + "try:\n", + " _object = types.ObjectType\n", + " _newclass = 1\n", + "except AttributeError:\n", + " class _object : pass\n", + " _newclass = 0\n", + "\n\n", + NIL); + } + + // Include some information in the code + Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\ + ------------------------------------------------*/\n", module); + + } + + Printf(f_header,"#define SWIG_init init%s\n\n", module); + Printf(f_header,"#define SWIG_name \"%s\"\n", module); + + Printf(f_wrappers,"#ifdef __cplusplus\n"); + Printf(f_wrappers,"extern \"C\" {\n"); + Printf(f_wrappers,"#endif\n"); + Printf(const_code,"static swig_const_info swig_const_table[] = {\n"); + Printf(methods,"static PyMethodDef SwigMethods[] = {\n"); + + /* emit code */ + Language::top(n); + + /* Close language module */ + Printf(methods,"\t { NULL, NULL }\n"); + Printf(methods,"};\n"); + Printf(f_wrappers,"%s\n",methods); + + SwigType_emit_type_table(f_runtime,f_wrappers); + + Printf(const_code, "{0}};\n"); + Printf(f_wrappers,"%s\n",const_code); + Printf(f_init,"}\n"); + + Printf(f_wrappers,"#ifdef __cplusplus\n"); + Printf(f_wrappers,"}\n"); + Printf(f_wrappers,"#endif\n"); + + if (shadow) { + Printv(f_shadow, f_shadow_stubs, "\n",NIL); + Close(f_shadow); + Delete(f_shadow); + } + + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + return SWIG_OK; } -} -/* ----------------------------------------------------------------------------- - * PYTHON::add_method() - * ----------------------------------------------------------------------------- */ -void -PYTHON::add_method(String *name, String *function, int kw) { - if (!kw) - Printf(methods,"\t { \"%s\", %s, METH_VARARGS },\n", name, function); - else - Printf(methods,"\t { \"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", name, function); -} + /* ------------------------------------------------------------ + * importDirective() + * ------------------------------------------------------------ */ -/* ----------------------------------------------------------------------------- - * PYTHON::initialize() - * ----------------------------------------------------------------------------- */ -void -PYTHON::initialize(String *modname) { - char filen[256]; - - hash = NewHash(); - symbols = NewHash(); - const_code = NewString(""); - shadow_methods = NewString(""); - classes = NewString(""); - func = NewString(""); - vars = NewString(""); - pragma_include = NewString(""); - methods = NewString(""); - - Swig_banner(f_runtime); - - Printf(f_runtime,"#define SWIGPYTHON\n"); - if (NoInclude) - Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); - - if (Swig_insert_file("common.swg", f_runtime) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate common.swg. (Possible installation problem).\n"); - Swig_exit (EXIT_FAILURE); + virtual int importDirective(Node *n) { + if (shadow) { + String *modname = Getattr(n,"module"); + if (modname) { + Printf(f_shadow,"import %s\n", modname); + } + } + return Language::importDirective(n); } - if (Swig_insert_file("python.swg", f_runtime) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate python.swg. (Possible installation problem).\n"); - Swig_exit (EXIT_FAILURE); + + /* ------------------------------------------------------------ + * add_method() + * ------------------------------------------------------------ */ + + void add_method(String *name, String *function, int kw) { + if (!kw) + Printf(methods,"\t { (char *)\"%s\", %s, METH_VARARGS },\n", name, function); + else + Printf(methods,"\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", name, function); } - if (!module) module = NewString(modname); + /* ------------------------------------------------------------ + * functionWrapper() + * ------------------------------------------------------------ */ - /* If shadow classing is enabled, we're going to change the module name to "modulec" */ - if (shadow) { + virtual int functionWrapper(Node *n) { + + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *d = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); - sprintf(filen,"%s%s.py", output_dir, Char(module)); - // If we don't have an interface then change the module name X to Xc - if (! interface) - Append(module,"c"); - if ((f_shadow = fopen(filen,"w")) == 0) { - Printf(stderr,"Unable to open %s\n", filen); - Swig_exit (EXIT_FAILURE); + Parm *p; + int i; + char wname[256]; + char source[64]; + Wrapper *f; + String *parse_args; + String *arglist; + String *get_pointers; + String *cleanup; + String *outarg; + String *kwargs; + String *tm; + String *overname = 0; + + int num_required; + int num_arguments; + int varargs = 0; + int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0; + + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); + } else { + if (!addSymbol(iname,n)) return SWIG_ERROR; } - Printf(f_shadow,"# This file was created automatically by SWIG.\n"); - Printf(f_shadow,"import %s\n", interface ? interface : module); - // Include some information in the code - Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\ - ------------------------------------------------*/\n", interface ? interface : module); - - if (!noopt) - Printf(f_shadow,"import new\n"); - } - - Printf(f_header,"#define SWIG_init init%s\n\n", module); - Printf(f_header,"#define SWIG_name \"%s\"\n", module); - - /* Output the start of the init function. */ - Printf(f_init,"static PyObject *SWIG_globals;\n"); - Printf(f_init,"#ifdef __cplusplus\n"); - Printf(f_init,"extern \"C\" \n"); - Printf(f_init,"#endif\n"); - Printf(f_init,"SWIGEXPORT(void) init%s(void) {\n",module); - Printf(f_init,"PyObject *m, *d;\n"); - Printf(f_init,"int i;\n"); - Printf(f_init,"SWIG_globals = SWIG_newvarlink();\n"); - Printf(f_init,"m = Py_InitModule(\"%s\", %sMethods);\n", module, module); - Printf(f_init,"d = PyModule_GetDict(m);\n"); - Printv(f_init, - "for (i = 0; swig_types_initial[i]; i++) {\n", - "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", - "}\n", - 0); - - Printf(f_wrappers,"#ifdef __cplusplus\n"); - Printf(f_wrappers,"extern \"C\" {\n"); - Printf(f_wrappers,"#endif\n"); - Printf(const_code,"static swig_const_info swig_const_table[] = {\n"); - Printf(methods,"static PyMethodDef %sMethods[] = {\n", module); -} - -/* ----------------------------------------------------------------------------- - * PYTHON::close() - * ----------------------------------------------------------------------------- */ -void -PYTHON::close(void) { - Printf(methods,"\t { NULL, NULL }\n"); - Printf(methods,"};\n"); - Printf(f_wrappers,"%s\n",methods); - Printf(f_wrappers,"#ifdef __cplusplus\n"); - Printf(f_wrappers,"}\n"); - Printf(f_wrappers,"#endif\n"); - - SwigType_emit_type_table(f_runtime,f_wrappers); - - Printf(const_code, "{0}};\n"); - Printf(f_wrappers,"%s\n",const_code); - - Printv(f_init, "SWIG_InstallConstants(d,swig_const_table);\n", 0); - Printf(f_init,"}\n"); - - if (shadow) { - Printv(f_shadow, - classes, - "\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n", - func, - "\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n", - vars, - 0); - - if (Len(pragma_include) > 0) { - Printv(f_shadow, - "\n\n#-------------- USER INCLUDE -----------------------\n\n", - pragma_include, - 0); - } - fclose(f_shadow); - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::get_pointer() - * ----------------------------------------------------------------------------- */ -void -PYTHON::get_pointer(char *src, char *dest, SwigType *t, String *f, char *ret) { - SwigType *lt; - SwigType_remember(t); - Printv(f,tab4, "if ((SWIG_ConvertPtr(", src, ",(void **) &", dest, ",", 0); - - lt = Swig_clocal_type(t); - if (Cmp(lt,"p.void") == 0) { - Printv(f, "0,1)) == -1) return ", ret, ";\n", 0); - } - /* if (SwigType_type(t) == T_VOID) Printv(f, "0,1)) == -1) return ", ret, ";\n", 0);*/ - else { - Printv(f,"SWIGTYPE", SwigType_manglestr(t), ",1)) == -1) return ", ret, ";\n", 0); - } - Delete(lt); -} - -/* ----------------------------------------------------------------------------- - * PYTHON::create_command() - * ----------------------------------------------------------------------------- */ -void -PYTHON::create_command(String *cname, String *iname) { - add_method(iname, Swig_name_wrapper(cname), use_kw); -} - -/* ----------------------------------------------------------------------------- - * PYTHON::create_function() - * ----------------------------------------------------------------------------- */ -void -PYTHON::function(DOH *node) { - char *name; - char *iname; - SwigType *d; - ParmList *l; - Parm *p; - int pcount,i,j; - char wname[256]; - char source[64], target[64], argnum[20]; - char *usage = 0; - Wrapper *f; - String *parse_args; - String *arglist; - String *get_pointers; - String *cleanup; - String *outarg; - String *check; - String *kwargs; - char *tm; - int numopt = 0; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - d = Getattr(node,"type"); - l = Getattr(node,"parms"); - f = NewWrapper(); - parse_args = NewString(""); - arglist = NewString(""); - get_pointers = NewString(""); - cleanup = NewString(""); - outarg = NewString(""); - check = NewString(""); - kwargs = NewString(""); - - have_output = 0; - - strcpy(wname,Char(Swig_name_wrapper(iname))); - - if (!use_kw) { - Printv(f, - "static PyObject *", wname, - "(PyObject *self, PyObject *args) {", - 0); - } else { - Printv(f, - "static PyObject *", wname, - "(PyObject *self, PyObject *args, PyObject *kwargs) {", - 0); - } - Wrapper_add_local(f,"resultobj", "PyObject *resultobj"); - - /* Get the function usage string for later use */ - - usage = usage_func(iname,d,l); + f = NewWrapper(); + parse_args = NewString(""); + arglist = NewString(""); + get_pointers = NewString(""); + cleanup = NewString(""); + outarg = NewString(""); + kwargs = NewString(""); + + Wrapper_add_local(f,"resultobj", "PyObject *resultobj"); /* Write code to extract function parameters. */ - pcount = emit_args(node, f); - if (!use_kw) { - Printf(parse_args," if(!PyArg_ParseTuple(args,\""); - } else { - Printf(parse_args," if(!PyArg_ParseTupleAndKeywords(args,kwargs,\""); - Printf(arglist,",kwnames"); - } + emit_args(d, l, f); - i = 0; - j = 0; - numopt = check_numopt(l); - if (numopt) have_defarg = 1; - p = l; - Printf(kwargs,"{ "); - while (p != 0) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - String *pv = Getvalue(p); + /* Attach the standard typemaps */ + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + /* Get number of required and total arguments */ + num_arguments = emit_num_arguments(l); + num_required = emit_num_required(l); + varargs = emit_isvarargs(l); - sprintf(source,"obj%d",i); - sprintf(target,Char(Getlname(p))); - sprintf(argnum,"%d",j+1); + strcpy(wname,Char(Swig_name_wrapper(iname))); + if (overname) { + strcat(wname,Char(overname)); + } + + if (!allow_kwargs || Getattr(n,"sym:overloaded")) { + if (!varargs) { + Printv(f->def, + "static PyObject *", wname, + "(PyObject *self, PyObject *args) {", + NIL); + } else { + Printv(f->def, + "static PyObject *", wname, "__varargs__", + "(PyObject *self, PyObject *args, PyObject *varargs) {", + NIL); + } + if (allow_kwargs) { + Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, + "Can't use keyword arguments with overloaded functions.\n"); + allow_kwargs = 0; + } + } else { + if (varargs) { + Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, + "Can't wrap varargs with keyword arguments enabled\n"); + varargs = 0; + } + Printv(f->def, + "static PyObject *", wname, + "(PyObject *self, PyObject *args, PyObject *kwargs) {", + NIL); + } + if (!allow_kwargs) { + Printf(parse_args," if(!PyArg_ParseTuple(args,(char *)\""); + } else { + Printf(parse_args," if(!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)\""); + Printf(arglist,",kwnames"); + } + + /* Generate code for argument marshalling */ + + Printf(kwargs,"{ "); + for (i = 0, p=l; i < num_arguments; i++) { + + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *pn = Getattr(p,"name"); + String *ln = Getattr(p,"lname"); + + sprintf(source,"obj%d",i); - if (!Getignore(p)) { Putc(',',arglist); - if (j == pcount-numopt) Putc('|',parse_args); /* Optional argument separator */ + if (i == num_required) Putc('|', parse_args); /* Optional argument separator */ + + /* Keyword argument handling */ if (Len(pn)) { Printf(kwargs,"\"%s\",", pn); } else { - Printf(kwargs,"\"arg%d\",", j+1); + Printf(kwargs,"\"arg%d\",", i+1); } - if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) { - Putc('O',parse_args); - Wrapper_add_localv(f, source, "PyObject *",source, " = 0", 0); - Printf(arglist,"&%s",source); - if (i >= (pcount-numopt)) - Printv(get_pointers, tab4, "if (", source, ")\n", 0); - Printv(get_pointers,tm,"\n", 0); - Replace(get_pointers,"$argnum", argnum, DOH_REPLACE_ANY); - Replace(get_pointers,"$arg",source, DOH_REPLACE_ANY); - } else { - int noarg = 0; - - switch(SwigType_type(pt)) { - case T_INT : case T_UINT: - Putc('i',parse_args); - break; - case T_SHORT: case T_USHORT: - Putc('h',parse_args); - break; - case T_LONG : case T_ULONG: - Putc('l',parse_args); - break; - case T_SCHAR : case T_UCHAR : - Putc('b',parse_args); - break; - case T_CHAR: - Putc('c',parse_args); - break; - case T_FLOAT : - Putc('f',parse_args); - break; - case T_DOUBLE: - Putc('d',parse_args); - break; - - case T_BOOL: - { - char tempb[128]; - char tempval[128]; - if (pv) { - sprintf(tempval, "(int) %s", Char(pv)); - } - sprintf(tempb,"tempbool%d",i); - Putc('i',parse_args); - if (!pv) - Wrapper_add_localv(f,tempb,"int",tempb,0); - else - Wrapper_add_localv(f,tempb,"int",tempb, "=",tempval,0); - Printv(get_pointers, tab4, target, " = ( ", tempb, " != 0);\n", 0); - Printf(arglist,"&%s",tempb); - noarg = 1; + /* Look for an input typemap */ + if ((tm = Getattr(p,"tmap:in"))) { + String *parse = Getattr(p,"tmap:in:parse"); + if (!parse) { + Replaceall(tm,"$source",source); + Replaceall(tm,"$target",ln); + Replaceall(tm,"$input", source); + Setattr(p,"emit:input", source); /* Save the location of the object */ + + if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) { + Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); + } else { + Replaceall(tm,"$disown","0"); } - break; - - case T_VOID : - noarg = 1; - break; - - case T_USER: Putc('O',parse_args); - sprintf(source,"argo%d", i); - sprintf(target,Char(Getlname(p))); - - Wrapper_add_localv(f,source,"PyObject *",source,"=0",0); + Wrapper_add_localv(f, source, "PyObject *",source, " = 0", NIL); Printf(arglist,"&%s",source); - SwigType_add_pointer(pt); - get_pointer(source, target, pt, get_pointers, (char*)"NULL"); - SwigType_del_pointer(pt); - noarg = 1; - break; + if (i >= num_required) + Printv(get_pointers, "if (", source, ") {\n", NIL); + Printv(get_pointers,tm,"\n", NIL); + if (i >= num_required) + Printv(get_pointers, "}\n", NIL); - case T_STRING: - Putc('s',parse_args); - Printf(arglist,"&%s", Getlname(p)); - noarg = 1; - break; - - case T_POINTER: case T_ARRAY: case T_REFERENCE: - - /* Have some sort of pointer variable. Create a temporary local - variable for the string and read the pointer value into it. */ - - Putc('O',parse_args); - sprintf(source,"argo%d", i); - sprintf(target,"%s",Char(Getlname(p))); - - Wrapper_add_localv(f,source,"PyObject *",source,"=0",0); - Printf(arglist,"&%s",source); - get_pointer(source, target, pt, get_pointers, (char*)"NULL"); - noarg = 1; - break; - - default : - Printf(stderr,"%s:%d. Unable to use type %s as a function argument.\n",Getfile(node), Getline(node), SwigType_str(pt,0)); - break; + } else { + Printf(parse_args,"%s",parse); + Printf(arglist,"&%s", ln); } - - if (!noarg) - Printf(arglist,"&%s",Getlname(p)); + p = Getattr(p,"tmap:in:next"); + continue; + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); + break; } - j++; + p = nextSibling(p); } - /* Check if there was any constraint code */ - if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) { - Printf(check,"%s\n",tm); - Replace(check,"$argnum", argnum, DOH_REPLACE_ANY); + + /* finish argument marshalling */ + Printf(kwargs," NULL }"); + if (allow_kwargs) { + Printv(f->locals,tab4, "char *kwnames[] = ", kwargs, ";\n", NIL); } - /* Check if there was any cleanup code */ - if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,source,0))) { - Printf(cleanup,"%s\n",tm); - Replace(cleanup,"$argnum", argnum, DOH_REPLACE_ANY); - Replace(cleanup,"$arg",source, DOH_REPLACE_ANY); + + Printf(parse_args,":%s\"", iname); + Printv(parse_args, + arglist, ")) goto fail;\n", + NIL); + + /* Now piece together the first part of the wrapper function */ + Printv(f->code, parse_args, get_pointers, NIL); + + /* Check for trailing varargs */ + if (varargs) { + if (p && (tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$input", "varargs"); + Printv(f->code,tm,"\n",NIL); + } } - /* Check for output arguments */ - if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"resultobj",0))) { - Printf(outarg,"%s\n", tm); - Replace(outarg,"$argnum",argnum,DOH_REPLACE_ANY); - Replace(outarg,"$arg",source, DOH_REPLACE_ANY); - have_output++; + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert cleanup code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } } - p = Getnext(p); - i++; - } - Printf(kwargs," NULL }"); - if (use_kw) { - Wrapper_add_localv(f,"kwnames","char *kwnames[] = ", kwargs, ";\n", 0); - /* Printv(f->locals,tab4, "char *kwnames[] = ", kwargs, ";\n", 0); */ - } + /* Insert argument output code */ + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$target","resultobj"); + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + + /* Emit the function call */ + emit_action(n,f); - Printf(parse_args,":%s\"", iname); - Printv(parse_args, - arglist, ")) return NULL;\n", - 0); - - /* Now slap the whole first part of the wrapper function together */ - Printv(f, parse_args, get_pointers, check, 0); - - /* Emit the function call */ - emit_func_call(node,f); + /* This part below still needs cleanup */ /* Return the function value */ - if ((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"resultobj",0))) { - Printf(f,"%s\n", tm); - } else { - switch(SwigType_type(d)) { - case T_INT: case T_UINT: case T_BOOL: - case T_SHORT: case T_USHORT: - case T_LONG : case T_ULONG: - case T_SCHAR: case T_UCHAR : - Printf(f," resultobj = PyInt_FromLong((long)result);\n"); - break; - case T_DOUBLE : - case T_FLOAT : - Printf(f," resultobj = PyFloat_FromDouble(result);\n"); - break; - case T_CHAR : - Printf(f," resultobj = Py_BuildValue(\"c\",result);\n"); - break; - case T_USER : - SwigType_add_pointer(d); - SwigType_remember(d); - Printv(f,tab4, "resultobj = SWIG_NewPointerObj((void *)result, SWIGTYPE", SwigType_manglestr(d), ");\n",0); - SwigType_del_pointer(d); - break; - case T_STRING: - Printf(f," resultobj = Py_BuildValue(\"s\",result);\n"); - break; - case T_POINTER: case T_ARRAY: case T_REFERENCE: - SwigType_remember(d); - Printv(f, tab4, "resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE", SwigType_manglestr(d), ");\n", 0); - break; - case T_VOID: - Printf(f," Py_INCREF(Py_None);\n"); - Printf(f," resultobj = Py_None;\n"); - break; - default : - Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n", Getfile(node), Getline(node), SwigType_str(d,0), name); - break; - } - } - - /* Output argument output code */ - Printv(f,outarg,0); - - /* Output cleanup code */ - Printv(f,cleanup,0); - - /* Look to see if there is any newfree cleanup code */ - if (NewObject) { - if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) { - Printf(f,"%s\n",tm); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char*)"result",(char*)"",0))) { - Printf(f,"%s\n",tm); - } - - Printf(f," return resultobj;\n}\n"); - - /* Substitute the cleanup code */ - Replace(f,"$cleanup",cleanup, DOH_REPLACE_ANY); - - /* Substitute the function name */ - Replace(f,"$name",iname, DOH_REPLACE_ANY); - - /* Dump the function out */ - Printf(f_wrappers,"%s",f); - - /* Now register the function with the interpreter. */ - add_method(iname, wname, use_kw); - - /* Create a shadow for this function (if enabled and not in a member function) */ - - if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - int need_wrapper = 0; - int munge_return = 0; - - /* Check return code for modification */ - if (is_shadow(d)) { - need_wrapper = 1; - munge_return = 1; - } - - /* If no modification is needed. We're just going to play some - symbol table games instead */ - - if (!need_wrapper) { - Printv(func,iname, " = ", module, ".", iname, "\n\n", 0); + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + Replaceall(tm,"$source", "result"); + Replaceall(tm,"$target", "resultobj"); + Replaceall(tm,"$result", "resultobj"); + if (Getattr(n,"feature:new")) { + Replaceall(tm,"$owner","1"); + } else { + Replaceall(tm,"$owner","0"); + } + Printf(f->code,"%s\n", tm); } else { - Printv(func,"def ", iname, "(*args, **kwargs):\n", 0); - Printv(func, tab4, "val = apply(", module, ".", iname, ",args,kwargs)\n",0); + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); + } - if (munge_return) { - /* If the output of this object has been remapped in any way, we're - going to return it as a bare object */ + /* Output argument output code */ + Printv(f->code,outarg,NIL); - if (!Swig_typemap_search((char*)"out",d,iname)) { + /* Output cleanup code */ + Printv(f->code,cleanup,NIL); - /* If there are output arguments, we are going to return the value - unchanged. Otherwise, emit some shadow class conversion code. */ + /* Look to see if there is any newfree cleanup code */ + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n",tm); + } + } - if (!have_output) { - Printv(func, tab4, "if val: val = ", is_shadow(d), "Ptr(val)", 0); - if ((!SwigType_ispointer(d)) || NewObject) - Printf(func, "; val.thisown = 1\n"); - else - Printf(func,"\n"); - } + /* See if there is any return cleanup code */ + if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n",tm); + } + + Printf(f->code," return resultobj;\n"); + + /* Error handling code */ + + Printf(f->code,"fail:\n"); + Printv(f->code,cleanup,NIL); + Printf(f->code,"return NULL;\n"); + Printf(f->code,"}\n"); + + /* Substitute the cleanup code */ + Replaceall(f->code,"$cleanup",cleanup); + + /* Substitute the function name */ + Replaceall(f->code,"$symname",iname); + Replaceall(f->code,"$result","resultobj"); + + /* Dump the function out */ + Wrapper_print(f,f_wrappers); + + /* If varargs. Need to emit a varargs stub */ + if (varargs) { + DelWrapper(f); + f = NewWrapper(); + Printv(f->def, + "static PyObject *", wname, + "(PyObject *self, PyObject *args) {", + NIL); + Wrapper_add_local(f,"resultobj", "PyObject *resultobj"); + Wrapper_add_local(f,"varargs", "PyObject *varargs"); + Wrapper_add_local(f,"newargs", "PyObject *newargs"); + Printf(f->code,"newargs = PyTuple_GetSlice(args,0,%d);\n", num_arguments); + Printf(f->code,"varargs = PyTuple_GetSlice(args,%d,PyTuple_Size(args)+1);\n", num_arguments); + Printf(f->code,"resultobj = %s__varargs__(self,newargs,varargs);\n", wname); + Printf(f->code,"Py_XDECREF(newargs);\n"); + Printf(f->code,"Py_XDECREF(varargs);\n"); + Printf(f->code,"return resultobj;\n"); + Printf(f->code,"}\n"); + Wrapper_print(f,f_wrappers); + } + + Setattr(n,"wrap:name", wname); + + /* Now register the function with the interpreter. */ + if (!Getattr(n,"sym:overloaded")) { + add_method(iname, wname, allow_kwargs); + + /* Create a shadow for this function (if enabled and not in a member function) */ + if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { + if (in_class) { + Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n\n", NIL); + } else { + Printv(f_shadow,iname, " = ", module, ".", iname, "\n\n", NIL); } } - Printv(func, tab4, "return val\n\n", 0); + } else { + if (!Getattr(n,"sym:nextSibling")) { + dispatchFunction(n); + } } + Delete(parse_args); + Delete(arglist); + Delete(get_pointers); + Delete(cleanup); + Delete(outarg); + Delete(kwargs); + DelWrapper(f); + return SWIG_OK; } - Delete(parse_args); - Delete(arglist); - Delete(get_pointers); - Delete(cleanup); - Delete(outarg); - Delete(check); - Delete(kwargs); - Delete(f); -} -/* ----------------------------------------------------------------------------- - * PYTHON::variable() - * ----------------------------------------------------------------------------- */ -void -PYTHON::variable(DOH *node) { - char *name, *iname; - SwigType *t; - char *wname; + /* ------------------------------------------------------------ + * dispatchFunction() + * ------------------------------------------------------------ */ + void dispatchFunction(Node *n) { + /* Last node in overloaded chain */ + + int maxargs; + String *tmp = NewString(""); + String *dispatch = Swig_overload_dispatch(n,"return %s(self,args);",&maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *f = NewWrapper(); + String *symname = Getattr(n,"sym:name"); + String *wname = Swig_name_wrapper(symname); + + Printv(f->def, + "static PyObject *", wname, + "(PyObject *self, PyObject *args) {", + NIL); + + Wrapper_add_local(f,"argc","int argc"); + Printf(tmp,"PyObject *argv[%d]", maxargs+1); + Wrapper_add_local(f,"argv",tmp); + Wrapper_add_local(f,"ii","int ii"); + Printf(f->code,"argc = PyObject_Length(args);\n"); + Printf(f->code,"for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n",maxargs); + Printf(f->code,"argv[ii] = PyTuple_GetItem(args,ii);\n"); + Printf(f->code,"}\n"); + + Replaceall(dispatch,"$args","self,args"); + Printv(f->code,dispatch,"\n",NIL); + Printf(f->code,"PyErr_SetString(PyExc_TypeError,\"No matching function for overloaded '%s'\");\n", symname); + Printf(f->code,"return NULL;\n"); + Printv(f->code,"}\n",NIL); + Wrapper_print(f,f_wrappers); + add_method(symname,wname,0); + + /* Create a shadow for this function (if enabled and not in a member function) */ + if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { + Printv(f_shadow_stubs,symname, " = ", module, ".", symname, "\n\n", NIL); + } + DelWrapper(f); + Delete(dispatch); + Delete(tmp); + Delete(wname); + } + + /* ------------------------------------------------------------ + * variableWrapper() + * ------------------------------------------------------------ */ + + virtual int variableWrapper(Node *n) { + + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + + String *wname; static int have_globals = 0; - char *tm; + String *tm; Wrapper *getf, *setf; - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); + if (!addSymbol(iname,n)) return SWIG_ERROR; getf = NewWrapper(); setf = NewWrapper(); - /* If this is our first call, add the globals variable to the - Python dictionary. */ + /* If this is our first call, add the globals variable to the + Python dictionary. */ if (!have_globals) { - Printf(f_init,"\t PyDict_SetItemString(d,\"%s\", SWIG_globals);\n",global_name); + Printf(f_init,"\t PyDict_SetItemString(d,(char*)\"%s\", SWIG_globals);\n",global_name); have_globals=1; if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - Printv(vars, global_name, " = ", module, ".", global_name, "\n", 0); + Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name); } } - wname = Char(Swig_name_wrapper(name)); + if ((shadow) && (SwigType_isconst(t))) { + if (!in_class) { + Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname); + } + } + + wname = Swig_name_wrapper(iname); /* Create a function for setting the value of the variable */ - Printf(setf,"static int %s_set(PyObject *val) {\n", wname); - if (!ReadOnly) { - if ((tm = Swig_typemap_lookup((char*)"varin",t,name,(char*)"val",name,0))) { - Printf(setf,"%s\n",tm); - Replace(setf,"$name",iname, DOH_REPLACE_ANY); + Printf(setf->def,"static int %s_set(PyObject *_val) {", wname); + if (!Getattr(n,"feature:immutable")) { + if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { + Replaceall(tm,"$source","_val"); + Replaceall(tm,"$target",name); + Replaceall(tm,"$input","_val"); + Printf(setf->code,"%s\n",tm); + Delete(tm); } else { - switch(SwigType_type(t)) { - - case T_INT: case T_SHORT: case T_LONG : - case T_UINT: case T_USHORT: case T_ULONG: - case T_SCHAR: case T_UCHAR: case T_BOOL: - Wrapper_add_localv(setf,"tval",SwigType_lstr(t,0),"tval",0); - Printv(setf, - "tval = (", SwigType_lstr(t,0), ") PyInt_AsLong(val);\n", - "if (PyErr_Occurred()) {\n", - "PyErr_SetString(PyExc_TypeError,\"C variable '", - iname, "'(", SwigType_str(t,0), ")\");\n", - "return 1; \n", - "}\n", - name, " = tval;\n", - 0); - break; - - case T_FLOAT: case T_DOUBLE: - Wrapper_add_localv(setf,"tval",SwigType_lstr(t,0), "tval",0); - Printv(setf, - "tval = (", SwigType_lstr(t,0), ") PyFloat_AsDouble(val);\n", - "if (PyErr_Occurred()) {\n", - "PyErr_SetString(PyExc_TypeError,\"C variable '", - iname, "'(", SwigType_str(t,0), ")\");\n", - "return 1; \n", - "}\n", - name, " = tval;\n", - 0); - break; - - case T_CHAR: - Wrapper_add_local(setf,"tval","char * tval"); - Printv(setf, - "tval = (char *) PyString_AsString(val);\n", - "if (PyErr_Occurred()) {\n", - "PyErr_SetString(PyExc_TypeError,\"C variable '", - iname, "'(", SwigType_str(t,0), ")\");\n", - "return 1; \n", - "}\n", - name, " = *tval;\n", - 0); - break; - - case T_USER: - SwigType_add_pointer(t); - Wrapper_add_localv(setf,"temp",SwigType_lstr(t,0),"temp",0); - get_pointer((char*)"val",(char*)"temp",t,setf,(char*)"1"); - Printv(setf, name, " = *temp;\n", 0); - SwigType_del_pointer(t); - break; - - case T_STRING: - Wrapper_add_local(setf,"tval","char * tval"); - Printv(setf, - "tval = (char *) PyString_AsString(val);\n", - "if (PyErr_Occurred()) {\n", - "PyErr_SetString(PyExc_TypeError,\"C variable '", - iname, "'(", SwigType_str(t,0), ")\");\n", - "return 1; \n", - "}\n", - 0); - - if (CPlusPlus) { - Printv(setf, - "if (", name, ") delete [] ", name, ";\n", - name, " = new char[strlen(tval)+1];\n", - "strcpy((char *)", name, ",tval);\n", - 0); - } else { - Printv(setf, - "if (", name, ") free((char*)", name, ");\n", - name, " = (char *) malloc(strlen(tval)+1);\n", - "strcpy((char *)", name, ",tval);\n", - 0); - } - break; - - case T_ARRAY: - { - int setable = 0; - SwigType *aop; - SwigType *ta = Copy(t); - aop = SwigType_pop(ta); - if (SwigType_type(ta) == T_CHAR) { - String *dim = SwigType_array_getdim(aop,0); - if (dim && Len(dim)) { - Printf(setf, "strncpy(%s,PyString_AsString(val), %s);\n", name,dim); - setable = 1; - } - } - if (!setable) { - Printv(setf, - "PyErr_SetString(PyExc_TypeError,\"Variable ", iname, - " is read-only.\");\n", - "return 1;\n", - 0); - } - Delete(ta); - Delete(aop); - } - break; - - case T_POINTER: case T_REFERENCE: - Wrapper_add_localv(setf,"temp", SwigType_lstr(t,0), "temp",0); - get_pointer((char*)"val",(char*)"temp",t,setf,(char*)"1"); - Printv(setf, name, " = temp;\n", 0); - break; - - default: - Printf(stderr,"%s:%d. Unable to link with type %s.\n", Getfile(node), Getline(node), SwigType_str(t,0)); - } + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, + "Unable to set variable of type %s.\n", SwigType_str(t,0)); } - Printf(setf," return 0;\n"); + Printf(setf->code," return 0;\n"); } else { /* Is a readonly variable. Issue an error */ - Printv(setf, - "PyErr_SetString(PyExc_TypeError,\"Variable ", iname, + Printv(setf->code, + tab4, "PyErr_SetString(PyExc_TypeError,\"Variable ", iname, " is read-only.\");\n", - "return 1;\n", - 0); + tab4, "return 1;\n", + NIL); } - Printf(setf,"}\n"); - Printf(f_wrappers,"%s", setf); + Printf(setf->code,"}\n"); + Wrapper_print(setf,f_wrappers); /* Create a function for getting the value of a variable */ - Printf(getf,"static PyObject *%s_get() {\n", wname); + Printf(getf->def,"static PyObject *%s_get() {", wname); Wrapper_add_local(getf,"pyobj", "PyObject *pyobj"); - if ((tm = Swig_typemap_lookup((char*)"varout",t,name,name,(char*)"pyobj",0))) { - Printf(getf,"%s\n",tm); - Replace(getf,"$name",iname, DOH_REPLACE_ANY); - } else if ((tm = Swig_typemap_lookup((char*)"out",t,name,name,(char*)"pyobj",0))) { - Printf(getf,"%s\n",tm); - Replace(getf,"$name",iname, DOH_REPLACE_ANY); + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$source",name); + Replaceall(tm,"$target","pyobj"); + Replaceall(tm,"$result","pyobj"); + Printf(getf->code,"%s\n", tm); } else { - switch(SwigType_type(t)) { - case T_INT: case T_UINT: - case T_SHORT: case T_USHORT: - case T_LONG: case T_ULONG: - case T_SCHAR: case T_UCHAR: case T_BOOL: - Printv(getf, "pyobj = PyInt_FromLong((long) ", name, ");\n", 0); - break; - case T_FLOAT: case T_DOUBLE: - Printv(getf, "pyobj = PyFloat_FromDouble((double) ", name, ");\n", 0); - break; - case T_CHAR: - Wrapper_add_local(getf,"ptemp","char ptemp[2]"); - Printv(getf, - "ptemp[0] = ", name, ";\n", - "ptemp[1] = 0;\n", - "pyobj = PyString_FromString(ptemp);\n", - 0); - break; - case T_USER: - SwigType_add_pointer(t); - SwigType_remember(t); - Printv(getf, - "pyobj = SWIG_NewPointerObj((void *) &", name , - ", SWIGTYPE", SwigType_manglestr(t), ");\n", - 0); - SwigType_del_pointer(t); - break; - case T_STRING: - Printv(getf, - "if (", name, ")\n", - "pyobj = PyString_FromString(", name, ");\n", - "else pyobj = PyString_FromString(\"(NULL)\");\n", - 0); - break; - - case T_POINTER: case T_ARRAY: case T_REFERENCE: - { - SwigType *ta = Copy(t); - SwigType_pop(ta); - if (SwigType_type(ta) == T_CHAR) { - Printv(getf,"pyobj = PyString_FromString(", name, ");\n", 0); - } else { - SwigType_remember(t); - Printv(getf, - "pyobj = SWIG_NewPointerObj((void *)", name, - ", SWIGTYPE", SwigType_manglestr(t), ");\n", - 0); - } - Delete(ta); - } - break; - - default: - Printf(stderr,"Unable to link with type %s\n", SwigType_str(t,0)); - break; - } + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, + "Unable to link with type %s\n", SwigType_str(t,0)); } - - Printf(getf," return pyobj;\n}\n"); - Printf(f_wrappers,"%s", getf); + + Printf(getf->code," return pyobj;\n}\n"); + Wrapper_print(getf,f_wrappers); /* Now add this to the variable linking mechanism */ + Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,(char*)\"%s\",%s_get, %s_set);\n", iname, wname, wname); - Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,\"%s\",%s_get, %s_set);\n", iname, wname, wname); + DelWrapper(setf); + DelWrapper(getf); + return SWIG_OK; + } - /* Output a shadow variable. (If applicable and possible) */ + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + String *tm; + int have_tm = 0; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + /* Special hook for member pointer */ + if (SwigType_type(type) == T_MPOINTER) { + String *wname = Swig_name_wrapper(iname); + Printf(f_header, "static %s = %s;\n", SwigType_str(type,wname), value); + value = wname; + } + if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) { + Replaceall(tm,"$source",value); + Replaceall(tm,"$target",name); + Replaceall(tm,"$value", value); + Printf(const_code,"%s,\n", tm); + have_tm = 1; + } + if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { + Replaceall(tm,"$source",value); + Replaceall(tm,"$target",name); + Replaceall(tm,"$value",value); + Printf(f_init, "%s\n", tm); + have_tm = 1; + } + if (!have_tm) { + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value.\n"); + return SWIG_NOWRAP; + } if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - if (is_shadow(t)) { - Printv(vars, - iname, " = ", is_shadow(t), "Ptr(", module, ".", global_name, - ".", iname, ")\n", - 0); + if (!in_class) { + Printv(f_shadow,iname, " = ", module, ".", iname, "\n", NIL); + } else { + Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n", NIL); } } - Delete(setf); - Delete(getf); -} - -/* ----------------------------------------------------------------------------- - * PYTHON::constant() - * ----------------------------------------------------------------------------- */ -void -PYTHON::constant(DOH *node) { - char *name; - SwigType *type; - char *value; - char *tm; - - name = GetChar(node,"name"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - - if ((tm = Swig_typemap_lookup((char*)"const",type,name,value,name,0))) { - Printf(const_code,"%s\n", tm); - } else { - switch(SwigType_type(type)) { - case T_INT: case T_UINT: case T_BOOL: - case T_SHORT: case T_USHORT: - case T_LONG: case T_ULONG: - case T_SCHAR: case T_UCHAR: - Printv(const_code, "{ SWIG_PY_INT, \"", name, "\", (long) ", value, ", 0, 0, 0},\n", 0); - break; - case T_DOUBLE: - case T_FLOAT: - Printv(const_code, "{ SWIG_PY_FLOAT, \"", name, "\", 0, (double) ", value, ", 0,0},\n", 0); - break; - case T_CHAR : - Printf(const_code, "{ SWIG_PY_STRING, \"%s\", 0, 0, (void *) \"%s\", 0 }, \n", name, value); - break; - case T_STRING: - Printf(const_code,"{ SWIG_PY_STRING, \"%s\", 0, 0, (void *) \"%s\", 0 }, \n", name, value); - break; - case T_POINTER: case T_ARRAY: case T_REFERENCE: - SwigType_remember(type); - Printv(const_code, "{ SWIG_PY_POINTER, \"", name, "\", 0, 0, (void *) ", value, ", &SWIGTYPE", SwigType_manglestr(type), "}, \n", 0); - break; - default: - Printf(stderr,"%s:%d. Unsupported constant value. %s, %d\n", Getfile(node), Getline(node), name, SwigType_type(type)); - return; - break; - } + return SWIG_OK; } - if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - Printv(vars,name, " = ", module, ".", name, "\n", 0); - } -} -/* ----------------------------------------------------------------------------- - * PYTHON::usage_func() - Make string showing how to call a function - * ----------------------------------------------------------------------------- */ -char * -PYTHON::usage_func(char *iname, SwigType *, ParmList *l) { - static String *temp = 0; - Parm *p; - int i; - if (!temp) temp = NewString(""); + /* ------------------------------------------------------------ + * nativeWrapper() + * ------------------------------------------------------------ */ - Clear(temp); - Printf(temp,"%s(", iname); + virtual int nativeWrapper(Node *n) { + String *name = Getattr(n,"sym:name"); + String *wrapname = Getattr(n,"wrap:name"); - i = 0; - p = l; - while (p != 0) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - if (!Getignore(p)) { - i++; - /* If parameter has been named, use that. Otherwise, just print a type */ + if (!addSymbol(wrapname,n)) return SWIG_ERROR; - if (SwigType_type(pt) != T_VOID) { - if (Len(pn) > 0) { - Printf(temp,"%s",pn); - } else { - Printf(temp,"%s", SwigType_str(pt,0)); - } - } - p = Getnext(p); - if (p != 0) { - if (!Getignore(p)) - Putc(',',temp); - } - } else { - p = Getnext(p); - if (p) { - if ((!Getignore(p)) && (i > 0)) - Putc(',',temp); - } - } - } - Putc(')',temp); - return Char(temp); -} - -/* ----------------------------------------------------------------------------- - * PYTHON::nativefunctin() - * ----------------------------------------------------------------------------- */ -void -PYTHON::nativefunction(DOH *node) { - char *name; - char *funcname; - name = GetChar(node,"scriptname"); - funcname = GetChar(node,"name"); - - /* Figure out what kind of function this is */ - if (Swig_proto_cmp("f(p.PyObject,p.PyObject).p.PyObject",node) == 0) { - /* Not with keyword arguments */ - add_method(name,funcname,0); - } - if (Swig_proto_cmp("f(p.PyObject,p.PyObject,p.PyObject).p.PyObject",node) == 0) { - add_method(name,funcname,1); - } - if (shadow) { - Printv(func, name, " = ", module, ".", name, "\n\n", 0); - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_class_decl() - Register a class definition - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_class_decl(DOH *node) { - String *name = Getname(node); - String *rename = Getattr(node,"scriptname"); - String *ctype = Getattr(node,"classtype"); - String *stype; - if (shadow) { - stype = NewString(name); - SwigType_add_pointer(stype); - Setattr(hash,stype,rename); - Delete(stype); - /* Add full name of datatype to the hash table */ - if (Len(ctype) > 0) { - stype = NewStringf("%s %s", ctype, name); - SwigType_add_pointer(stype); - Setattr(hash,stype,rename); - Delete(stype); - } - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::pragma() - * ----------------------------------------------------------------------------- */ -void -PYTHON::pragma(DOH *node) { - String *name; - String *value; - name = Getattr(node,"name"); - value = Getattr(node,"value"); - - if (Cmp(name,"code") == 0) { + add_method(name, wrapname,0); if (shadow) { - Printf(f_shadow,"%s\n",value); + Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n\n", NIL); } - } else if (Cmp(name,"include") == 0) { + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * classDeclaration() + * ------------------------------------------------------------ */ + + virtual int classDeclaration(Node *n) { + String *importname; + Node *mod; if (shadow) { - if (value) { - FILE *f = Swig_open(value); - if (!f) { - Printf(stderr,"%s:%d. Unable to locate file %s\n", Getfile(node), Getline(node),value); + mod = Getattr(n,"module"); + if (mod) { + String *modname = Getattr(mod,"name"); + if (Strcmp(modname,mainmodule) != 0) { + importname = NewStringf("%s.%s", modname, Getattr(n,"sym:name")); } else { - char buffer[4096]; - while (fgets(buffer,4095,f)) { - Printv(pragma_include,buffer,0); + importname = NewString(Getattr(n,"sym:name")); + } + Setattr(n,"python:proxy",importname); + } + } + return Language::classDeclaration(n); + } + + /* ------------------------------------------------------------ + * classHandler() + * ------------------------------------------------------------ */ + + virtual int classHandler(Node *n) { + int oldclassic = classic; + + if (shadow) { + + /* Create new strings for building up a wrapper function */ + have_constructor = 0; + have_repr = 0; + + if (Getattr(n,"cplus:exceptionclass")) { + classic = 1; + } + if (Getattr(n,"feature:classic")) classic = 1; + + shadow_indent = (String *) tab4; + + class_name = Getattr(n,"sym:name"); + real_classname = Getattr(n,"name"); + + if (!addSymbol(class_name,n)) return SWIG_ERROR; + + /* Handle inheritance */ + String *base_class = NewString(""); + List *baselist = Getattr(n,"bases"); + if (baselist && Len(baselist)) { + Node *base = Firstitem(baselist); + while (base) { + String *bname = Getattr(base, "python:proxy"); + if (!bname) { + base = Nextitem(baselist); + continue; + } + Printv(base_class,bname,NIL); + base = Nextitem(baselist); + if (base) { + Putc(',',base_class); } } } - } - } -} + Printv(f_shadow,"class ", class_name, NIL); -#ifdef OLD -/* C++ pragmas are no longer handled as a special case. The generic %pragma - directive may used in or outside of a class. Therefore, this functionality - should be moved into the pragma method, not handled here. -- Dave. (12/14/00). -*/ - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_pragma() - Handle C++ pragmas - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_pragma(Pragma *plist) { - PyPragma *pyp1 = 0, *pyp2 = 0; - if (pragmas) { - delete pragmas; - pragmas = 0; - } - while (plist) { - if (strcmp(Char(plist->lang),(char*)"python") == 0) { - if (strcmp(Char(plist->name),"addtomethod") == 0) { - /* parse value, expected to be in the form "methodName:line" */ - String *temp = NewString(plist->value); - char* txtptr = strchr(Char(temp), ':'); - if (txtptr) { - /* add name and line to a list in current_class */ - *txtptr = 0; - txtptr++; - pyp1 = new PyPragma(Char(temp),txtptr); - pyp1->next = 0; - if (pyp2) { - pyp2->next = pyp1; - pyp2 = pyp1; - } else { - pragmas = pyp1; - pyp2 = pragmas; - } - } else { - Printf(stderr,"%s : Line %d. Malformed addtomethod pragma. Should be \"methodName:text\"\n", - Char(plist->filename),plist->lineno); - } - Delete(temp); - } else if (strcmp(Char(plist->name), "addtoclass") == 0) { - pyp1 = new PyPragma((char*)"__class__",Char(plist->value)); - pyp1->next = 0; - if (pyp2) { - pyp2->next = pyp1; - pyp2 = pyp1; - } else { - pragmas = pyp1; - pyp2 = pragmas; + if (Len(base_class)) { + Printf(f_shadow,"(%s)", base_class); + } else { + if (!classic) { + Printf(f_shadow,"(_object)"); } } - } - plist = plist->next; - } -} + Printf(f_shadow,":\n"); -/* ----------------------------------------------------------------------------- - * PYTHON::emitAddPragmas() - * - * Search the current class pragma for any text belonging to name. - * Append the text properly spaced to the output string. - * ----------------------------------------------------------------------------- */ -void -PYTHON::emitAddPragmas(String *output, char* name, char* spacing) { - PyPragma *p = pragmas; - while (p) { - if (strcmp(Char(p->m_method),name) == 0) { - Printv(output,spacing,p->m_text,"\n",0); - } - p = p->next; - } -} - -#endif - -/* C++ Support + Shadow Classes */ - -static String *setattr = 0; -static String *getattr = 0; -static String *csetattr = 0; -static String *cgetattr = 0; -static String *pyclass = 0; -static String *imethod = 0; -static String *construct = 0; -static String *cinit = 0; -static String *additional = 0; -static int have_constructor; -static int have_destructor; -static int have_getattr; -static int have_setattr; -static int have_repr; -static char *class_type; -static char *real_classname; -static String *base_class = 0; -static int class_renamed = 0; - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_open_class() - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_open_class(DOH *node) { - this->Language::cpp_open_class(node); - - char *classname = GetChar(node,"name"); - char *rname = GetChar(node,"scriptname"); - char *ctype = GetChar(node,"classtype"); - - if (shadow) { - /* Create new strings for building up a wrapper function */ - setattr = NewString(""); - getattr = NewString(""); - csetattr = NewString(""); - cgetattr = NewString(""); - pyclass = NewString(""); - imethod = NewString(""); - construct = NewString(""); - cinit = NewString(""); - additional= NewString(""); - base_class = 0; - have_constructor = 0; - have_destructor = 0; - have_getattr = 0; - have_setattr = 0; - have_repr = 0; - if (rname) { - class_name = Swig_copy_string(rname); - class_renamed = 1; - } else { - class_name = Swig_copy_string(classname); - class_renamed = 0; - } - } - - real_classname = Swig_copy_string(classname); - class_type = Swig_copy_string(ctype); - - cpp_class_decl(node); - - if (shadow) { - Printv(setattr, - tab4, "def __setattr__(self,name,value):\n", - tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n", - tab8, "method = ", class_name, ".__setmethods__.get(name,None)\n", - tab8, "if method: return method(self,value)\n", - 0); - - Printv(getattr, tab4, "def __getattr__(self,name):\n", 0); - Printv(csetattr, tab4, "__setmethods__ = {\n", 0); - Printv(cgetattr, tab4, "__getmethods__ = {\n", 0); - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_member_func() - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_memberfunction(DOH *node) { - char *realname; - char *name, *iname; - SwigType *t; - ParmList *l; - int oldshadow; - char cname[1024]; - - /* Create the default member function */ - oldshadow = shadow; /* Disable shadowing when wrapping member functions */ - if (shadow) shadow = shadow | PYSHADOW_MEMBER; - this->Language::cpp_memberfunction(node); - shadow = oldshadow; - if (shadow) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - l = Getattr(node,"parms"); - realname = iname ? iname : name; - - /* Check to see if we've already seen this */ - sprintf(cname,"python:%s::%s",class_name,realname); - if (Getattr(symbols,cname)) return; - Setattr(symbols,cname,cname); - - if (strcmp(realname,"__repr__") == 0) - have_repr = 1; - - if (!is_shadow(t) && !noopt) { - Printv(imethod, - class_name, ".", realname, " = new.instancemethod(", module, ".", Swig_name_member(class_name,realname), ", None, ", class_name, ")\n", - 0); - } else { - if (use_kw) - Printv(pyclass,tab4, "def ", realname, "(*args, **kwargs):\n", 0); - else - Printv(pyclass, tab4, "def ", realname, "(*args):\n", 0); - - if (use_kw) - Printv(pyclass, tab8, "val = apply(", module, ".", Swig_name_member(class_name,realname), ",args, kwargs)\n", 0); - else - Printv(pyclass, tab8, "val = apply(", module, ".", Swig_name_member(class_name,realname), ",args)\n",0); - - /* Check to see if the return type is an object */ - if (is_shadow(t)) { - if (!Swig_typemap_search((char*)"out",t,Swig_name_member(class_name,realname))) { - if (!have_output) { - Printv(pyclass, tab8, "if val: val = ", is_shadow(t), "Ptr(val) ", 0); - if ((!SwigType_ispointer(t) || NewObject)) { - Printf(pyclass, "; val.thisown = 1\n"); - } else { - Printf(pyclass,"\n"); - } - } - } + Printv(f_shadow,tab4,"__swig_setmethods__ = {}\n",NIL); + if (Len(base_class)) { + Printf(f_shadow,"%sfor _s in [%s]: __swig_setmethods__.update(_s.__swig_setmethods__)\n",tab4,base_class); } - Printv(pyclass, tab8, "return val\n", 0); + + Printv(f_shadow, + tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n", + NIL); + + Printv(f_shadow,tab4,"__swig_getmethods__ = {}\n",NIL); + if (Len(base_class)) { + Printf(f_shadow,"%sfor _s in [%s]: __swig_getmethods__.update(_s.__swig_getmethods__)\n",tab4,base_class); + } + + Printv(f_shadow, + tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", + NIL); } - /* emitAddPragmas(*pyclass, realname, tab8); - *pyclass << tab8 << "return val\n"; */ - } -} -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_constructor() - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_constructor(DOH *node) { - char *name, *iname; - ParmList *l; - char *realname; - int oldshadow = shadow; - char cname[1024]; + /* Emit all of the members */ - if (shadow) shadow = shadow | PYSHADOW_MEMBER; - this->Language::cpp_constructor(node); - shadow = oldshadow; + in_class = 1; + Language::classHandler(n); + in_class = 0; - if (shadow) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - l = Getattr(node,"parms"); - realname = iname ? iname : class_name; + /* Complete the class */ + if (shadow) { + /* Generate a class registration function */ + { + SwigType *ct = NewStringf("p.%s", real_classname); + SwigType_remember(ct); + Printv(f_wrappers, + "static PyObject * ", class_name, "_swigregister(PyObject *self, PyObject *args) {\n", + tab4, "PyObject *obj;\n", + tab4, "if (!PyArg_ParseTuple(args,(char*)\"O\", &obj)) return NULL;\n", + tab4, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", obj);\n", + tab4, "Py_INCREF(obj);\n", + tab4, "return Py_BuildValue((char *)\"\");\n", + "}\n",NIL); + String *cname = NewStringf("%s_swigregister", class_name); + add_method(cname, cname, 0); + Delete(cname); + Delete(ct); + } + if (!have_constructor) { + Printv(f_shadow,tab4,"def __init__(self): raise RuntimeError, \"No constructor defined\"\n",NIL); + } - /* Check to see if we've already seen this */ - sprintf(cname,":python:constructor:%s::%s",class_name,realname); - if (Getattr(symbols,cname)) return; - Setattr(symbols,cname,cname); - - if (!have_constructor) { - if (use_kw) - Printv(construct, tab4, "def __init__(self,*args,**kwargs):\n", 0); - else - Printv(construct, tab4, "def __init__(self,*args):\n",0); - - if (use_kw) - Printv(construct, tab8, "self.this = apply(", module, ".", Swig_name_construct(realname), ",args,kwargs)\n", 0); - else - Printv(construct, tab8, "self.this = apply(", module, ".", Swig_name_construct(realname), ",args)\n", 0); - Printv(construct, tab8, "self.thisown = 1\n", 0); - // emitAddPragmas(construct,(char*)"__init__",(char*)tab8); - have_constructor = 1; - } else { - /* Hmmm. We seem to be creating a different constructor. We're just going to create a - function for it. */ - - if (use_kw) - Printv(additional, "def ", realname, "(*args,**kwargs):\n", 0); - else - Printv(additional, "def ", realname, "(*args):\n", 0); - - Printv(additional, tab4, "val = ", class_name, "Ptr(apply(", 0); - if (use_kw) - Printv(additional, module, ".", Swig_name_construct(realname), ",args,kwargs))\n", 0); - else - Printv(additional, module, ".", Swig_name_construct(realname), ",args))\n", 0); - Printv(additional,tab4, "val.thisown = 1\n", - tab4, "return val\n\n", 0); - } - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_destructor() - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_destructor(DOH *node) { - char *name, *newname; - char *realname; - int oldshadow = shadow; - - if (shadow) shadow = shadow | PYSHADOW_MEMBER; - this->Language::cpp_destructor(node); - shadow = oldshadow; - if (shadow) { - name = GetChar(node,"name"); - newname = GetChar(node,"scriptname"); - if (newname) realname = newname; - else realname = class_renamed ? class_name : name; - - Printv(pyclass, tab4, "def __del__(self,", module, "=", module, "):\n", 0); - // emitAddPragmas(pyclass,(char*)"__del__",(char*)tab8); - Printv(pyclass, tab8, "if self.thisown == 1 :\n", - tab8, tab4, module, ".", Swig_name_destroy(realname), "(self)\n", 0); - - have_destructor = 1; - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_close_class() - Close a class and write wrappers - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_close_class() { - String *ptrclass; - String *repr; - - ptrclass = NewString(""); - repr = NewString(""); - - if (shadow) { - if (!have_constructor) { - /* Build a constructor that takes a pointer to this kind of object */ - Printv(construct, + if (!have_repr) { + /* Supply a repr method for this class */ + Printv(f_shadow, + tab4, "def __repr__(self):\n", + tab8, "return \"\" % (self.this,)\n", + NIL); + } + /* Now build the real class with a normal constructor */ + Printv(f_shadow, + "\nclass ", class_name, "Ptr(", class_name, "):\n", tab4, "def __init__(self,this):\n", tab8, "self.this = this\n", - 0); + tab8, "if not hasattr(self,\"thisown\"): self.thisown = 0\n", + // tab8,"try: self.this = this.this; self.thisown = getattr(this,'thisown',0); this.thisown=0\n", + // tab8,"except AttributeError: self.this = this\n" + tab8, "self.__class__ = ", class_name, "\n", + NIL); + + Printf(f_shadow,"%s.%s_swigregister(%sPtr)\n", module, class_name, class_name,0); + shadow_indent = 0; + Printf(f_shadow,"%s\n", f_shadow_stubs); + Clear(f_shadow_stubs); } - /* First, build the pointer base class */ - if (base_class) { - Printv(ptrclass, "class ", class_name, "(", base_class, "):\n", 0); + classic = oldclassic; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * memberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int memberfunctionHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + int oldshadow; + + /* Create the default member function */ + oldshadow = shadow; /* Disable shadowing when wrapping member functions */ + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + Language::memberfunctionHandler(n); + shadow = oldshadow; + + if (!Getattr(n,"sym:nextSibling")) { + if (shadow) { + int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0; + if (Strcmp(symname,"__repr__") == 0) + have_repr = 1; + + if (Getattr(n,"feature:shadow")) { + String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4); + Printv(f_shadow,pycode,"\n",NIL); + } else { + if (allow_kwargs && !Getattr(n,"sym:overloaded")) { + Printv(f_shadow,tab4, "def ", symname, "(*args, **kwargs): ", NIL); + Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args, kwargs)\n", NIL); + } else { + Printv(f_shadow, tab4, "def ", symname, "(*args): ", NIL); + Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args)\n",NIL); + } + } + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmemberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int staticmemberfunctionHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + Language::staticmemberfunctionHandler(n); + if (shadow) { + Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL); + if (!classic) { + Printv(f_shadow, tab4, "if _newclass:", symname, " = staticmethod(", module, ".", + Swig_name_member(class_name, symname), ")\n", NIL); + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constructorDeclaration() + * ------------------------------------------------------------ */ + + virtual int constructorHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + int oldshadow = shadow; + + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + Language::constructorHandler(n); + shadow = oldshadow; + + if (!Getattr(n,"sym:nextSibling")) { + if (shadow) { + int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0; + if (!have_constructor) { + if (Getattr(n,"feature:shadow")) { + String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4); + Printv(f_shadow,pycode,"\n",NIL); + } else { + if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) { + Printv(f_shadow, tab4, "def __init__(self,*args,**kwargs):\n", NIL); + Printv(f_shadow, tab8, "self.this = apply(", module, ".", Swig_name_construct(symname), ",args,kwargs)\n", NIL); + } else { + Printv(f_shadow, tab4, "def __init__(self,*args):\n",NIL); + Printv(f_shadow, tab8, "self.this = apply(", module, ".", Swig_name_construct(symname), ",args)\n", NIL); + } + Printv(f_shadow, + tab8, "self.thisown = 1\n", + NIL); + } + have_constructor = 1; + } else { + /* Hmmm. We seem to be creating a different constructor. We're just going to create a + function for it. */ + + if (Getattr(n,"feature:shadow")) { + String *pycode = pythoncode(Getattr(n,"feature:shadow"),""); + Printv(f_shadow_stubs,pycode,"\n",NIL); + } else { + if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) + Printv(f_shadow_stubs, "def ", symname, "(*args,**kwargs):\n", NIL); + else + Printv(f_shadow_stubs, "def ", symname, "(*args):\n", NIL); + + Printv(f_shadow_stubs, tab4, "val = apply(", NIL); + if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) + Printv(f_shadow_stubs, module, ".", Swig_name_construct(symname), ",args,kwargs)\n", NIL); + else + Printv(f_shadow_stubs, module, ".", Swig_name_construct(symname), ",args)\n", NIL); + Printv(f_shadow_stubs,tab4, "val.thisown = 1\n", + tab4, "return val\n\n", NIL); + } + } + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorHandler() + * ------------------------------------------------------------ */ + + virtual int destructorHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + int oldshadow = shadow; + + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + Language::destructorHandler(n); + shadow = oldshadow; + if (shadow) { + Printv(f_shadow, tab4, "def __del__(self, destroy= ", module, ".", Swig_name_destroy(symname), "):\n", NIL); + Printv(f_shadow, tab8, "try:\n", NIL); + Printv(f_shadow, tab4, tab8, "if self.thisown: destroy(self)\n", NIL); + Printv(f_shadow, tab8, "except: pass\n", NIL); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * membervariableHandler() + * ------------------------------------------------------------ */ + + virtual int membervariableHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + + int oldshadow = shadow; + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + Language::membervariableHandler(n); + shadow = oldshadow; + + if (shadow) { + int immutable = 0; + if (!Getattr(n,"feature:immutable")) { + Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL); + } else { + immutable = 1; + } + Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL); + + if (!classic) { + if (immutable) { + Printv(f_shadow,tab4,"if _newclass:", symname," = property(", module, ".", + Swig_name_get(Swig_name_member(class_name,symname)),")\n", NIL); + } else { + Printv(f_shadow,tab4,"if _newclass:", symname," = property(", + module, ".", Swig_name_get(Swig_name_member(class_name,symname)),",", + module, ".", Swig_name_set(Swig_name_member(class_name,symname)),")\n", NIL); + } + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * staticmembervariableHandler() + * ------------------------------------------------------------ */ + + virtual int staticmembervariableHandler(Node *n) { + String *symname; + SwigType *t; + + Language::staticmembervariableHandler(n); + if (shadow) { + t = Getattr(n,"type"); + symname = Getattr(n,"sym:name"); + if (SwigType_isconst(t) && !Getattr(n, "value")) { + Printf(f_shadow,"%s%s = %s.%s.%s\n", tab4, symname, module, global_name, Swig_name_member(class_name,symname)); + } + } + return SWIG_OK; + + } + + /* ------------------------------------------------------------ + * memberconstantHandler() + * ------------------------------------------------------------ */ + + virtual int memberconstantHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + int oldshadow = shadow; + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + Language::memberconstantHandler(n); + shadow = oldshadow; + + if (shadow) { + Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(class_name,symname), "\n", NIL); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * pythoncode() - Output python code into the shadow file + * ------------------------------------------------------------ */ + + String *pythoncode(String *code, const String *indent) { + String *out = NewString(""); + String *temp; + char *t; + if (!indent) indent = ""; + + temp = NewString(code); + + t = Char(temp); + if (*t == '{') { + Delitem(temp,0); + Delitem(temp,DOH_END); + } + /* Split the input text into lines */ + List *clist = DohSplit(temp,'\n',-1); + Delete(temp); + int initial = 0; + String *s; + + /* Get the initial indentation */ + for (s = Firstitem(clist); s; s = Nextitem(clist)) { + if (Len(s)) { + char *c = Char(s); + while (*c) { + if (!isspace(*c)) break; + initial++; + c++; + } + if (*c && !isspace(*c)) break; + else { + initial = 0; + } + } + } + while (s) { + if (Len(s) > initial) { + char *c = Char(s); + c += initial; + Printv(out,indent,c,"\n",NIL); + } else { + Printv(out,"\n",NIL); + } + s = Nextitem(clist); + } + Delete(clist); + return out; + } + + /* ------------------------------------------------------------ + * insertDirective() + * + * Hook for %insert directive. We're going to look for special %shadow inserts + * as a special case so we can do indenting correctly + * ------------------------------------------------------------ */ + + virtual int insertDirective(Node *n) { + String *code = Getattr(n,"code"); + String *section = Getattr(n,"section"); + + if ((!ImportMode) && ((Cmp(section,"python") == 0) || (Cmp(section,"shadow") == 0))) { + if (shadow) { + String *pycode = pythoncode(code,shadow_indent); + Printv(f_shadow, pycode, "\n", NIL); + Delete(pycode); + } } else { - Printv(ptrclass, "class ", class_name, ":\n", 0); + Language::insertDirective(n); } - Printv(getattr, - tab8, "method = ", class_name, ".__getmethods__.get(name,None)\n", - tab8, "if method: return method(self)\n", - tab8, "raise AttributeError,name\n", - 0); - Printv(setattr, tab8, "self.__dict__[name] = value\n",0); - Printv(cgetattr, tab4, "}\n", 0); - Printv(csetattr, tab4, "}\n", 0); - Printv(ptrclass,cinit,construct,"\n",0); - Printv(classes,ptrclass,pyclass,0); - - if (have_setattr) { - Printv(classes, csetattr, setattr, 0); - } - if (have_getattr) { - Printv(classes,cgetattr,getattr,0); - } - if (!have_repr) { - /* Supply a repr method for this class */ - Printv(repr, - tab4, "def __repr__(self):\n", - tab8, "return \"\" % (self.this,)\n", - 0); - - Printv(classes,repr,0); - // emitAddPragmas(classes,(char*)"__class__",(char*)tab4); - } - - /* Now build the real class with a normal constructor */ - Printv(classes, - "class ", class_name, "Ptr(", class_name, "):\n", - tab4, "def __init__(self,this):\n", - tab8, "self.this = this\n", - tab8, "self.thisown = 0\n", - tab8, "self.__class__ = ", class_name, "\n", - "\n", additional, "\n", - 0); - - Printv(classes,imethod,"\n",0); - Delete(pyclass); - Delete(imethod); - Delete(setattr); - Delete(getattr); - Delete(additional); + return SWIG_OK; } - Delete(ptrclass); - Delete(repr); -} +}; /* ----------------------------------------------------------------------------- - * PYTHON::cpp_inherit() - Handle inheritance + * swig_python() - Instantiate module * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_inherit(List *bases) { - char *bc; - String *base; - int first_base = 0; - if (!shadow) { - this->Language::cpp_inherit(bases); - return; - } - - /* We'll inherit variables and constants, but not methods */ - this->Language::cpp_inherit(bases); - - if (!bases) return; - base_class = NewString(""); - - /* Now tell the Python module that we're inheriting from a base class */ - - for (base = Firstitem(bases); base; base = Nextitem(bases)) { - String *bs = NewString(base); - SwigType_add_pointer(bs); - bc = GetChar(hash,bs); - if (bc) { - if (first_base) Putc(',',base_class); - Printv(base_class,bc,0); - first_base = 1; - } - Delete(bs); - } - if (!first_base) { - Delete(base_class); - base_class = 0; - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_variable() - Add a member variable - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_variable(DOH *node) { - char *name, *iname; - SwigType *t; - char *realname; - int inhash = 0; - int oldshadow = shadow; - char cname[512]; - - if (shadow) shadow = shadow | PYSHADOW_MEMBER; - this->Language::cpp_variable(node); - shadow = oldshadow; - - if (shadow) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - have_getattr = 1; - have_setattr = 1; - realname = iname ? iname : name; - - /* Check to see if we've already seen this */ - sprintf(cname,"python:%s::%s:",class_name,realname); - if (Getattr(symbols,cname)) return; - - Setattr(symbols,cname,cname); - - /* Figure out if we've seen this datatype before */ - if (is_shadow(t)) inhash = 1; - - if (ReadOnly) { - /* *setattr << tab8 << tab4 << "raise RuntimeError, \'Member is read-only\'\n"; */ - } else { - Printv(csetattr, tab8, "\"", realname, "\" : ", module, ".", Swig_name_set(Swig_name_member(class_name,realname)), ",\n", 0); - } - if (inhash) { - Printv(cgetattr, tab8, "\"", realname, "\" : lambda x : ", is_shadow(t), "Ptr(", module, ".", Swig_name_get(Swig_name_member(class_name,realname)), "(x)),\n", 0); - } else { - Printv(cgetattr, tab8, "\"", realname, "\" : ", module, ".", Swig_name_get(Swig_name_member(class_name,realname)),",\n", 0); - } - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::cpp_declare_const() - * ----------------------------------------------------------------------------- */ -void -PYTHON::cpp_constant(DOH *node) { - char *name, *iname, *value; - SwigType *type; - char *realname; - int oldshadow = shadow; - char cname[512]; - - if (shadow) shadow = shadow | PYSHADOW_MEMBER; - this->Language::cpp_constant(node); - shadow = oldshadow; - - if (shadow) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - realname = iname ? iname : name; - - /* Check to see if we've already seen this */ - sprintf(cname,"python:%s::%s", class_name, realname); - if (Getattr(symbols,cname)) return; - Setattr(symbols,cname,cname); - Printv(cinit, tab4, realname, " = ", module, ".", Swig_name_member(class_name,realname), "\n", 0); - } -} - -/* ----------------------------------------------------------------------------- - * PYTHON::add_typedef() - Manage typedef's for shadow classes - * ----------------------------------------------------------------------------- */ -void -PYTHON::add_typedef(SwigType *t, String *name) { - if (!shadow) return; - if (is_shadow(t)) { - DOH *node = NewHash(); - Setname(node,name); - Setattr(node,"scriptname", is_shadow(t)); - Setattr(node,"classtype",""); - cpp_class_decl(node); - } +extern "C" Language * +swig_python(void) { + return new PYTHON(); } diff --git a/Source/Modules1.1/python.h b/Source/Modules1.1/python.h deleted file mode 100644 index 16b0eef1e..000000000 --- a/Source/Modules1.1/python.h +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - *******************************************************************************/ - -/************************************************************************** - * $Header$ - * - * python.h - * - * Header file for Python module. Warning ; this is work in progress. - **************************************************************************/ - -class PYTHON : public Language { -protected: - void get_pointer(char *src, char *dest, SwigType *t, String *f, char *ret); - void add_method(String *name, String *function, int kw); - char *usage_func(char *, SwigType *, ParmList *); - -public : - - // Don't change any of this - virtual void parse_args(int, char *argv[]); - virtual void initialize(String *); - virtual void function(DOH *node); - virtual void variable(DOH *node); - virtual void constant(DOH *node); - virtual void nativefunction(DOH *); - virtual void close(void); - virtual void create_command(String *, String *); - virtual void import(String *modname); - - // C++ extensions---for creating shadow classes - - virtual void cpp_memberfunction(DOH *); - virtual void cpp_constructor(DOH *); - virtual void cpp_destructor(DOH *); - virtual void cpp_open_class(DOH *); - virtual void cpp_close_class(); - virtual void cpp_inherit(List *bases); - virtual void cpp_variable(DOH *); - virtual void cpp_constant(DOH *); - virtual void cpp_class_decl(DOH *); - virtual void pragma(DOH *node); - virtual void add_typedef(SwigType *t, String *name); -}; - -#define PYSHADOW_MEMBER 0x2 - - - - diff --git a/Source/Modules1.1/ruby.cxx b/Source/Modules1.1/ruby.cxx index ffb64a876..f5f0a796a 100644 --- a/Source/Modules1.1/ruby.cxx +++ b/Source/Modules1.1/ruby.cxx @@ -10,16 +10,17 @@ * ********************************************************************/ -static char cvsroot[] = "$Header$"; +char cvsroot_ruby_cxx[] = "$Header$"; -#include "swig11.h" -#include "ruby.h" +#include "swigmod.h" + +#ifndef MACSWIG +#include "swigconfig.h" +#endif #include #include - -/* for debug */ -#define P(obj) printf("\"%s\"\n", Char(Str(obj))) +#include /* for INT_MAX */ class RClass { private: @@ -27,1474 +28,1409 @@ class RClass { public: String *name; /* class name (renamed) */ String *cname; /* original C class/struct name */ + String *mname; /* Mangled name */ String *vname; /* variable name */ String *type; String *prefix; String *header; String *init; - String *aliases; - String *includes; - Hash *freemethods; - Hash *predmethods; + int constructor_defined; int destructor_defined; - RClass(void) { - freemethods = NewHash(); - predmethods = NewHash(); - destructor_defined = 0; + RClass() { + temp = NewString(""); name = NewString(""); cname = NewString(""); + mname = NewString(""); vname = NewString(""); type = NewString(""); prefix = NewString(""); header = NewString(""); init = NewString(""); - aliases = NewString(""); - includes = NewString(""); - temp = NewString(""); + constructor_defined = 0; + destructor_defined = 0; } + ~RClass() { Delete(name); Delete(cname); Delete(vname); + Delete(mname); Delete(type); Delete(prefix); Delete(header); Delete(init); - Delete(aliases); - Delete(includes); - Delete(freemethods); - Delete(predmethods); Delete(temp); } - void set_name(char *cn, char *rn, char *valn) { + void set_name(const String_or_char *cn, const String_or_char *rn, const String_or_char *valn) { Clear(cname); Append(cname,cn); + Delete(mname); + mname = Swig_name_mangle(cname); Clear(name); Append(name,valn); Clear(vname); - Printf(vname,"c%s",name); - Printv(prefix,(rn ? rn : cn), "_", 0); + Printf(vname,"c%s.klass",name); + Clear(prefix); + Printv(prefix,(rn ? rn : cn), "_", NIL); } - char *strip(char *s) { - if (strncmp(s, Char(prefix), Len(prefix)) != 0) - return s; + char *strip(const String_or_char *s) { Clear(temp); - Append(temp,s); - Replace(temp,prefix,"",DOH_REPLACE_ANY); + Append(temp, s); + if (Strncmp(s, prefix, Len(prefix)) == 0) { + Replaceall(temp,prefix,""); + } return Char(temp); } }; -static char *usage = (char*)"\ +#ifdef RUBY_SUPPORTS_KEYWORD_ARGS +static const char * +usage = "\ Ruby Options (available with -ruby)\n\ - -module name - Set module name\n\ + -ldflags - Print runtime libraries to link with\n\ + -feature name - Set feature name (used by `require')\n\ + -keyword - Use keyword arguments\n"; +#else +static const char * +usage = "\ +Ruby Options (available with -ruby)\n\ + -ldflags - Print runtime libraries to link with\n\ -feature name - Set feature name (used by `require')\n"; - -static char *module = 0; -static char *modvar = 0; -static char *feature = 0; -static String *other_extern = 0; -static String *other_init = 0; -static char *import_file; - -static int current; - -enum { - NO_CPP, - MEMBER_FUNC, - CONSTRUCTOR, - DESTRUCTOR, - MEMBER_VAR, - CLASS_CONST, - STATIC_FUNC, - STATIC_VAR -}; - -static Hash *classes; /* key=cname val=RClass */ -static RClass *klass; /* Currently processing class */ -static Hash *special_methods; /* Python style special method name table */ - +#endif #define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0) #define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0)) -/* --------------------------------------------------------------------- - * RUBY::parse_args(int argc, char *argv[]) - * - * Parse command line options and initializes variables. - * --------------------------------------------------------------------- */ -void RUBY::parse_args(int argc, char *argv[]) { - /* Look for certain command line options */ - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i],"-feature") == 0) { - if (argv[i+1]) { - char *name = argv[i+1]; - feature = new char [strlen(name)+1]; - strcpy(feature, name); +class RUBY : public Language { +private: + + String *module; + String *modvar; + String *feature; + int current; + Hash *classes; /* key=cname val=RClass */ + RClass *klass; /* Currently processing class */ + Hash *special_methods; /* Python style special method name table */ + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; + bool use_kw; + + // Wrap modes + enum { + NO_CPP, + MEMBER_FUNC, + CONSTRUCTOR_ALLOCATE, + CONSTRUCTOR_INITIALIZE, + DESTRUCTOR, + MEMBER_VAR, + CLASS_CONST, + STATIC_FUNC, + STATIC_VAR + }; + +public: + + /* --------------------------------------------------------------------- + * RUBY() + * + * Initialize member data + * --------------------------------------------------------------------- */ + + RUBY() { + module = 0; + modvar = 0; + feature = 0; + current = NO_CPP; + classes = 0; + klass = 0; + special_methods = 0; + f_runtime = 0; + f_header = 0; + f_wrappers = 0; + f_init = 0; + use_kw = false; + } + + /* --------------------------------------------------------------------- + * main() + * + * Parse command line options and initializes variables. + * --------------------------------------------------------------------- */ + + virtual void main(int argc, char *argv[]) { + + /* Set location of SWIG library */ + SWIG_library_directory("ruby"); + + /* Look for certain command line options */ + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-feature") == 0) { + if (argv[i+1]) { + char *name = argv[i+1]; + feature = NewString(name); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if (strcmp(argv[i],"-help") == 0) { + Printf(stderr,"%s\n", usage); + } else if (strcmp (argv[i],"-ldflags") == 0) { + printf("%s\n", SWIG_RUBY_RUNTIME); + SWIG_exit (EXIT_SUCCESS); + } else if (strcmp(argv[i],"-keyword") == 0) { + use_kw = true; Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); } - } else if (strcmp(argv[i],"-help") == 0) { - Printf(stderr,"%s\n", usage); } } + + /* Add a symbol to the parser for conditional compilation */ + Preprocessor_define("SWIGRUBY 1", 0); + + /* Add typemap definitions */ + SWIG_typemap_lang("ruby"); + SWIG_config_file("ruby.swg"); + allow_overloading(); } - /* Set location of SWIG library */ - Swig_swiglib_set("ruby"); - /* Add a symbol to the parser for conditional compilation */ - Preprocessor_define((void *) "SWIGRUBY", 0); - Swig_set_config_file("ruby.i"); -} + /* --------------------------------------------------------------------- + * top() + * --------------------------------------------------------------------- */ + virtual int top(Node *n) { -static void insert_file(char *filename, File *file) { - if (Swig_insert_file(filename, file) == -1) { - Printf(stderr, - "SWIG : Fatal error. " - "Unable to locate %s. (Possible installation problem).\n", - filename); - Swig_exit (EXIT_FAILURE); - } -} + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); -/* --------------------------------------------------------------------- - * RUBY::initialize() - * - * Produces an initialization function. Assumes that the module - * name has already been specified. - * --------------------------------------------------------------------- */ + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); -void RUBY::initialize(String *modname) { - import_file = 0; - current = NO_CPP; - klass = 0; - classes = NewHash(); - special_methods = NewHash(); - other_extern = NewString(""); - other_init = NewString(""); + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",f_init); - /* Python style special method name. */ - /* Basic */ - Setattr(special_methods, "__repr__", "inspect"); - Setattr(special_methods, "__str__", "to_s"); - Setattr(special_methods, "__cmp__", "<=>"); - Setattr(special_methods, "__hash__", "hash"); - Setattr(special_methods, "__nonzero__", "nonzero?"); + modvar = 0; + current = NO_CPP; + klass = 0; + classes = NewHash(); + special_methods = NewHash(); + + /* Python style special method name. */ + /* Basic */ + Setattr(special_methods, "__repr__", "inspect"); + Setattr(special_methods, "__str__", "to_s"); + Setattr(special_methods, "__cmp__", "<=>"); + Setattr(special_methods, "__hash__", "hash"); + Setattr(special_methods, "__nonzero__", "nonzero?"); + /* Callable */ - Setattr(special_methods, "__call__", "call"); - /* Collection */ - Setattr(special_methods, "__len__", "length"); - Setattr(special_methods, "__getitem__", "[]"); - Setattr(special_methods, "__setitem__", "[]="); - /* Numeric */ - Setattr(special_methods, "__add__", "+"); - Setattr(special_methods, "__sub__", "-"); - Setattr(special_methods, "__mul__", "*"); - Setattr(special_methods, "__div__", "/"); - Setattr(special_methods, "__mod__", "%"); - Setattr(special_methods, "__divmod__", "divmod"); - Setattr(special_methods, "__pow__", "**"); - Setattr(special_methods, "__lshift__", "<<"); - Setattr(special_methods, "__rshift__", ">>"); - Setattr(special_methods, "__and__", "&"); - Setattr(special_methods, "__xor__", "^"); - Setattr(special_methods, "__or__", "|"); - Setattr(special_methods, "__neg__", "-@"); - Setattr(special_methods, "__pos__", "+@"); - Setattr(special_methods, "__abs__", "abs"); - Setattr(special_methods, "__invert__", "~"); - Setattr(special_methods, "__int__", "to_i"); - Setattr(special_methods, "__float__", "to_f"); - Setattr(special_methods, "__coerce__", "coerce"); + Setattr(special_methods, "__call__", "call"); + + /* Collection */ + Setattr(special_methods, "__len__", "length"); + Setattr(special_methods, "__getitem__", "[]"); + Setattr(special_methods, "__setitem__", "[]="); + + /* Operators */ + Setattr(special_methods, "__add__", "+"); + Setattr(special_methods, "__pos__", "+@"); + Setattr(special_methods, "__sub__", "-"); + Setattr(special_methods, "__neg__", "-@"); + Setattr(special_methods, "__mul__", "*"); + Setattr(special_methods, "__div__", "/"); + Setattr(special_methods, "__mod__", "%"); + Setattr(special_methods, "__lshift__", "<<"); + Setattr(special_methods, "__rshift__", ">>"); + Setattr(special_methods, "__and__", "&"); + Setattr(special_methods, "__or__", "|"); + Setattr(special_methods, "__xor__", "^"); + Setattr(special_methods, "__invert__", "~"); + Setattr(special_methods, "__lt__", "<"); + Setattr(special_methods, "__le__", "<="); + Setattr(special_methods, "__gt__", ">"); + Setattr(special_methods, "__ge__", ">="); + Setattr(special_methods, "__eq__", "=="); - Swig_banner(f_header); + /* Other numeric */ + Setattr(special_methods, "__divmod__", "divmod"); + Setattr(special_methods, "__pow__", "**"); + Setattr(special_methods, "__abs__", "abs"); + Setattr(special_methods, "__int__", "to_i"); + Setattr(special_methods, "__float__", "to_f"); + Setattr(special_methods, "__coerce__", "coerce"); - Printf(f_header,"/* Implementation : RUBY */\n\n"); - Printf(f_header,"#define SWIGRUBY\n"); + Swig_banner(f_runtime); - insert_file((char*)"common.swg", f_header); - insert_file((char*)"ruby.swg", f_header); - if (NoInclude) { - insert_file((char*)"rubydec.swg", f_header); - } else { - insert_file((char*)"rubydef.swg", f_header); - } + if (NoInclude) { + Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); + } - /* typedef void *VALUE */ - SwigType *value = NewSwigType(T_VOID); - SwigType_setbase(value,(char*)"void"); - SwigType_add_pointer(value); - SwigType_typedef(value,(char*)"VALUE"); - Delete(value); + /* typedef void *VALUE */ + SwigType *value = NewSwigType(T_VOID); + SwigType_add_pointer(value); + SwigType_typedef(value,(char*)"VALUE"); + Delete(value); - /* Old set_module code */ + /* Set module name */ + set_module(Char(Getattr(n,"name"))); - if (!module) { - module = new char[Len(modname)+1]; - strcpy(module, Char(modname)); - } - if (!feature) { - feature = new char[strlen(module)+1]; - strcpy(feature, module); - } - /* module name must be a constant. */ - module[0] = toupper(module[0]); - - modvar = new char[1+strlen(module)+1]; - modvar[0] = 'm'; - strcpy(modvar+1, module); - - /* Old init code */ - - Printf(f_header,"#define SWIG_init Init_%s\n", feature); - Printf(f_header,"#define SWIG_name \"%s\"\n\n", module); - Printf(f_header,"static VALUE %s;\n", modvar); - Printf(f_header,"\n%s\n", other_extern); + Printf(f_header,"#define SWIG_init Init_%s\n", feature); + Printf(f_header,"#define SWIG_name \"%s\"\n\n", module); + Printf(f_header,"static VALUE %s;\n", modvar); /* Start generating the initialization function */ - Printv(f_init, - "\n", - "#ifdef __cplusplus\n", - "extern \"C\"\n", - "#endif\n", - "void Init_", feature, "(void) {\n", - "int i;\n", - other_init, - "\n", - 0); + Printv(f_init, + "\n", + "#ifdef __cplusplus\n", + "extern \"C\"\n", + "#endif\n", + "void Init_", feature, "(void) {\n", + "int i;\n", + "\n", + NIL); - Printv(f_init, tab4, modvar, " = rb_define_module(\"", module, "\");\n", - "_mSWIG = rb_define_module_under(", modvar, ", \"SWIG\");\n", - 0); - Printv(f_init, - "\n", - "for (i = 0; swig_types_initial[i]; i++) {\n", - "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", - "SWIG_define_class(swig_types[i]);\n", - "}\n", - 0); - Printf(f_init,"\n"); - klass = new RClass(); -} + Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL); -/* --------------------------------------------------------------------- - * RUBY::close(void) - * - * Finish the initialization function. Close any additional files and - * resources in use. - * --------------------------------------------------------------------- */ - -void RUBY::close(void) { - /* Finish off our init function */ - Printf(f_init,"}\n"); - SwigType_emit_type_table(f_header,f_wrappers); -} - -/* -------------------------------------------------------------------------- - * RUBY::nativefunction() - * -------------------------------------------------------------------------- */ -void -RUBY::nativefunction(DOH *node) { - Printf(stderr,"%s:%d. Adding native function %s not supported (ignored).\n", Getfile(node), Getline(node), Getattr(node,"scriptname")); -} - -/* --------------------------------------------------------------------- - * RUBY::make_wrapper_name(char *cname) - * - * Creates a name for a wrapper function - * iname = Name of the function in scripting language - * --------------------------------------------------------------------- */ - -String *RUBY::make_wrapper_name(char *iname) { - String *wname = Swig_name_wrapper(iname); - Replace(wname, "?", "_p", DOH_REPLACE_ANY); - Replace(wname, "!", "_bang", DOH_REPLACE_ANY); - return wname; -} - -/* --------------------------------------------------------------------- - * RUBY::create_command(char *cname, char *iname) - * - * Creates a new command from a C function. - * cname = Name of the C function - * iname = Name of function in scripting language - * argc = Number of arguments - * --------------------------------------------------------------------- */ - -static int create_argc = 0; - -void RUBY::create_command(String *scname, String *siname) { - char *cname, *iname; - int argc = create_argc; - cname = Char(scname); - iname = Char(siname); - String *wname = make_wrapper_name(iname); - if (CPlusPlus) { - Insert(wname,0,"VALUEFUNC("); - Append(wname,")"); - } - if (current != NO_CPP) - iname = klass->strip(iname); - if (Getattr(special_methods, iname)) { - iname = GetChar(special_methods, iname); - } - - String *s = NewString(""); - String *temp = NewString(""); - char argcs[32]; - sprintf(argcs,"%d",argc); - - switch (current) { - case MEMBER_FUNC: - Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", - iname, "\", ", wname, ", ", argcs, ");\n", 0); - - break; - case CONSTRUCTOR: - Printv(s, tab4, "rb_define_singleton_method(", klass->vname, - ", \"new\", ", wname, ", ", argcs, ");\n", 0); - Replace(klass->init,"$constructor", s, DOH_REPLACE_ANY); - break; - case MEMBER_VAR: - Append(temp,iname); - Replace(temp,"_set", "=", DOH_REPLACE_ANY); - Replace(temp,"_get", "", DOH_REPLACE_ANY); - Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", - temp, "\", ", wname, ", ", argcs, ");\n", 0); - break; - case STATIC_FUNC: - Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname, - ", \"", iname, "\", ", wname, ", ", argcs, ");\n", 0); - break; - default: - Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", - iname, "\", ", wname, ", ", argcs, ");\n",0); - Printv(f_init,s,0); - break; - } - Delete(s); - Delete(temp); -} - -/* --------------------------------------------------------------------- - * RUBY::function() - * - * Create a function declaration and register it with the interpreter. - * --------------------------------------------------------------------- */ - -void RUBY::function(DOH *node) { - char *name, *iname; - SwigType *t; - ParmList *l; - - char source[256], target[256]; - char *tm; - String *cleanup, *outarg; - Wrapper *f; - int i; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - l = Getattr(node,"parms"); - - /* Ruby needs no destructor wrapper */ - if (current == DESTRUCTOR) { - Wrapper *dummy = NewWrapper(); - emit_func_call(node,dummy); - Delete(dummy); - return; - } - - char mname[256], inamebuf[256]; - int predicate = 0, need_result = 0; - - cleanup = NewString(""); - outarg = NewString(""); - f = NewWrapper(); - - switch (current) { - case MEMBER_FUNC: - case MEMBER_VAR: - case STATIC_FUNC: - strcpy(mname, klass->strip(iname)); - if (Getattr(klass->predmethods, mname)) { - predicate = 1; - sprintf(inamebuf,"%s?",iname); - iname = inamebuf; + /* Account for nested modules */ + List *modules = Split(module,':',INT_MAX); + if (modules != 0 && Len(modules) > 0) { + String *mv = 0; + String *m = Firstitem(modules); + while (m != 0) { + if (Len(m) > 0) { + if (mv != 0) { + Printv(f_init, tab4, modvar, + " = rb_define_module_under(", modvar, ", \"", m, "\");\n", NIL); + } else { + Printv(f_init, tab4, modvar, + " = rb_define_module(\"", m, "\");\n", NIL); + mv = NewString(modvar); + } + } + m = Nextitem(modules); + } + Delete(mv); + Delete(modules); } - break; - } - String *wname = make_wrapper_name(iname); - /* Get number of arguments */ - int numarg = ParmList_numarg(l); - int numopt = check_numopt(l); + Printv(f_init, + "\n", + "for (i = 0; swig_types_initial[i]; i++) {\n", + "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", + "SWIG_define_class(swig_types[i]);\n", + "}\n", + NIL); + Printf(f_init,"\n"); - int start = 0; - int use_self = 0; - switch (current) { - case MEMBER_FUNC: - case MEMBER_VAR: - numarg--; - start++; - use_self = 1; - break; + Language::top(n); + + /* Finish off our init function */ + Printf(f_init,"}\n"); + SwigType_emit_type_table(f_runtime,f_wrappers); + + /* Close all of the files */ + Dump(f_header,f_runtime); + Dump(f_wrappers,f_runtime); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + Delete(f_runtime); + return SWIG_OK; } - int numreq = 0; - int numoptreal = 0; - Parm *p = l; - for (i = 0; i < start; i++) p = Getnext(p); - for (i = start; p; i++, p = Getnext(p)) { - if (!Getignore(p)) { - if (i >= ParmList_len(l) - numopt) numoptreal++; - else numreq++; + /* ----------------------------------------------------------------------------- + * importDirective() + * ----------------------------------------------------------------------------- */ + + virtual int importDirective(Node *n) { + String *modname = Getattr(n,"module"); + if (modname) { + Printf(f_init,"rb_require(\"%s\");\n", modname); } + return Language::importDirective(n); } - int vararg = (numoptreal != 0); - /* Now write the wrapper function itself */ - Printv(f, "static VALUE\n", wname, "(", 0); - if (vararg) { - Printv(f, "int argc, VALUE *argv, VALUE self",0); - } else { - Printv(f, "VALUE self", 0); - p = l; - for (i = 0; i < start; i++) p = Getnext(p); - for (i = start; p; i++, p = Getnext(p)) { - if (!Getignore(p)) { - Printf(f,", VALUE varg%d", i); + /* --------------------------------------------------------------------- + * set_module(const char *mod_name) + * + * Sets the module name. Does nothing if it's already set (so it can + * be overridden as a command line option). + *---------------------------------------------------------------------- */ + + void set_module(const char *s) { + String *mod_name = NewString(s); + if (module == 0) { + /* Start with the empty string */ + module = NewString(""); + + /* Account for nested modules */ + List *modules = Split(mod_name,':',INT_MAX); + if (modules != 0 && Len(modules) > 0) { + String *last = 0; + String *m = Firstitem(modules); + while (m != 0) { + if (Len(m) > 0) { + String *cap = NewString(m); + (Char(cap))[0] = toupper((Char(cap))[0]); + if (last != 0) { + Append(module, "::"); + } + Append(module, cap); + last = m; + } + m = Nextitem(modules); + } + if (feature == 0) { + feature = Copy(last); + } + (Char(last))[0] = toupper((Char(last))[0]); + modvar = NewStringf("m%s", last); + Delete(modules); } } + Delete(mod_name); + } + + /* -------------------------------------------------------------------------- + * nativeWrapper() + * -------------------------------------------------------------------------- */ + virtual int nativeWrapper(Node *n) { + String *funcname = Getattr(n,"wrap:name"); + Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, + "Adding native function %s not supported (ignored).\n", funcname); + return SWIG_NOWRAP; } - Printf(f,") {\n"); - /* Emit all of the local variables for holding arguments. */ - if (vararg) { - p = l; - for (i = 0; i < start; i++) p = Getnext(p); - for (i = start; p; i++, p = Getnext(p)) { - if (!Getignore(p)) { - char s[256]; - sprintf(s,"varg%d",i); - Wrapper_add_localv(f,s,"VALUE",s,0); + /* --------------------------------------------------------------------- + * create_command(Node *n, char *iname) + * + * Creates a new command from a C function. + * iname = Name of function in scripting language + * --------------------------------------------------------------------- */ + + void create_command(Node *n, const String_or_char *iname) { + + String *wname = Swig_name_wrapper(iname); + if (CPlusPlus) { + Insert(wname,0,"VALUEFUNC("); + Append(wname,")"); + } + if (current != NO_CPP) + iname = klass->strip(iname); + if (Getattr(special_methods, iname)) { + iname = GetChar(special_methods, iname); + } + + String *s = NewString(""); + String *temp = NewString(""); + + switch (current) { + case MEMBER_FUNC: + Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", + iname, "\", ", wname, ", -1);\n", NIL); + break; + case CONSTRUCTOR_ALLOCATE: + Printv(s, tab4, "rb_define_singleton_method(", klass->vname, + ", \"new\", ", wname, ", -1);\n", NIL); + Replaceall(klass->init,"$allocator", s); + break; + case CONSTRUCTOR_INITIALIZE: + Printv(s, tab4, "rb_define_method(", klass->vname, + ", \"initialize\", ", wname, ", -1);\n", NIL); + Replaceall(klass->init,"$initializer", s); + break; + case MEMBER_VAR: + Append(temp,iname); + Replaceall(temp,"_set", "="); + Replaceall(temp,"_get", ""); + Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", + temp, "\", ", wname, ", -1);\n", NIL); + break; + case STATIC_FUNC: + Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname, + ", \"", iname, "\", ", wname, ", -1);\n", NIL); + break; + default: + Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", + iname, "\", ", wname, ", -1);\n",NIL); + Printv(f_init,s,NIL); + break; + } + + /* Process the comma-separated list of aliases (if any) */ + String *aliasv = Getattr(n,"feature:alias"); + if (aliasv) { + List *aliases = Split(aliasv,',',INT_MAX); + if (aliases && Len(aliases) > 0) { + String *alias = Firstitem(aliases); + while (alias) { + if (Len(alias) > 0) { + Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias, "\", \"", iname, "\");\n", NIL); + } + alias = Nextitem(aliases); + } } - } - } - int pcount = emit_args(node,f); - - /* Emit count to check the number of arguments */ - if (vararg) { - int numscan = 0; - for (p = l, i = 0; i < start; i++) p = Getnext(p); - for (i = start; p; i++, p = Getnext(p)) { - if (!Getignore(p)) numscan++; - } - Printf(f,"rb_scan_args(argc, argv, \"%d%d\"", (numarg-numoptreal), numscan - (numarg-numoptreal)); - for (p = l, i = 0; i < start; i++) p = Getnext(p); - for (i = start; p; i++, p = Getnext(p)) { - if (!Getignore(p)) { - Printf(f,", &varg%d", i); - } - } - Printf(f,");\n"); - } - - /* Now walk the function parameter list and generate code */ - /* to get arguments */ - int j = 0; /* Total number of non-optional arguments */ - - p = l; - for (i = 0; i < pcount ; i++, p = Getnext(p)) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - - /* Produce string representation of source and target arguments */ - int selfp = (use_self && i == 0); - if (selfp) - strcpy(source,"self"); - else - sprintf(source,"varg%d",i); - - sprintf(target,"%s", Char(Getlname(p))); - - if (!Getignore(p)) { - char *tab = (char*)tab4; - if (j >= (pcount-numopt)) { /* Check if parsing an optional argument */ - Printf(f," if (argc > %d) {\n", j - start); - tab = (char*)tab8; - } - - /* Get typemap for this argument */ - tm = ruby_typemap_lookup((char*)"in",pt,pn,source,target,f); - if (tm) { - String *s = NewString(tm); - Printv(f, s, 0); - Replace(f, "$arg", source, DOH_REPLACE_ANY); - Delete(s); - } else { - Printf(stderr,"%s:%d. No typemapping for datatype %s\n", - Getfile(node), Getline(node), SwigType_str(pt,0)); - } - if (j >= (pcount-numopt)) - Printv(f, tab4, "} \n", 0); - j++; + Delete(aliases); } - /* Check to see if there was any sort of a constaint typemap */ - tm = ruby_typemap_lookup((char*)"check",pt,pn,source,target); - if (tm) { - String *s = NewString(tm); - Printv(f, s, 0); - Replace(f, "$arg", source, DOH_REPLACE_ANY); - Delete(s); - } - - /* Check if there was any cleanup code (save it for later) */ - tm = ruby_typemap_lookup((char*)"freearg",pt,pn,target,source); - if (tm) { - String *s = NewString(tm); - Printv(cleanup,s,0); - Replace(cleanup,"$arg",source, DOH_REPLACE_ANY); - Delete(s); - } - - tm = ruby_typemap_lookup((char*)"argout",pt,pn,target,(char*)"vresult"); - if (tm) { - String *s = NewString(tm); - need_result = 1; - Printv(outarg, s, 0); - Replace(outarg, "$arg", source, DOH_REPLACE_ANY); - Delete(s); - } - } - - /* Now write code to make the function call */ - emit_func_call(node,f); - - - /* Return value if necessary */ - if (SwigType_type(t) != T_VOID) { - need_result = 1; - if (predicate) { - Printv(f, tab4, "vresult = (result ? Qtrue : Qfalse);\n", 0); - } else { - tm = ruby_typemap_lookup((char*)"out",t,name,(char*)"result",(char*)"vresult"); - if (tm) { - String *s = NewString(tm); - Printv(f, s, 0); - Delete(s); - } else { - Printf(stderr,"%s:%d. No return typemap for datatype %s\n", - Getfile(node), Getline(node),SwigType_str(t,0)); - } - } - } - - /* Dump argument output code; */ - Printv(f,outarg,0); - - /* Dump the argument cleanup code */ - Printv(f,cleanup,0); - - /* Look for any remaining cleanup. This processes the %new directive */ - if (NewObject) { - tm = ruby_typemap_lookup((char*)"newfree",t,name,(char*)"result",(char*)""); - if (tm) { - String *s = NewString(tm); - Printv(f,s, 0); - Delete(s); - } - } - - /* free pragma */ - if (current == MEMBER_FUNC && Getattr(klass->freemethods, mname)) { - Printv(f, tab4, "DATA_PTR(self) = 0;\n", 0); - } - - /* Special processing on return value. */ - tm = ruby_typemap_lookup((char*)"ret",t,name,(char*)"result",(char*)""); - if (tm) { - String *s = NewString(tm); - Printv(f,s, 0); - } - - /* Wrap things up (in a manner of speaking) */ - if (need_result) { - Wrapper_add_local(f,"vresult","VALUE vresult = Qnil"); - Printv(f, tab4, "return vresult;\n}\n", 0); - } else { - Printv(f, tab4, "return Qnil;\n}\n", 0); - } - - /* Substitute the cleanup code */ - Replace(f,"$cleanup",cleanup, DOH_REPLACE_ANY); - - /* Emit the function */ - Printf(f_wrappers,"%s", f); - - /* Now register the function with the language */ - create_argc = vararg ? -1 : numarg; - create_command(name, iname); - Delete(cleanup); - Delete(outarg); - Delete(f); -} - -/* --------------------------------------------------------------------- - * RUBY::variable() - * - * Create a link to a C variable. - * --------------------------------------------------------------------- */ - -void RUBY::variable(DOH *node) { - char *name, *iname; - SwigType *t; - - char *tm, *source; - - String *getfname, *setfname; - Wrapper *getf, *setf; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - - getf = NewWrapper(); - setf = NewWrapper(); - - /* create getter */ - getfname = NewString(Swig_name_get(name)); - Replace(getfname,"::", "_", DOH_REPLACE_ANY); /* FIXME: Swig_name_get bug? */ - Printv(getf, "static VALUE\n", getfname, "(", 0); - Printf(getf, "VALUE self"); - Printf(getf, ") {\n"); - Wrapper_add_local(getf,"_val","VALUE _val"); - - if (SwigType_type(t) == T_USER) { - /* Hack this into a pointer */ - String *pname = NewString(""); - Printv(pname, "&", name, 0); - source = Char(pname); - } else { - source = name; - } - - tm = ruby_typemap_lookup((char*)"varout",t,name,source,(char*)"_val"); - if (!tm) - tm = ruby_typemap_lookup((char*)"out",t,name,source,(char*)"_val"); - if (tm) { - String *s = NewString(tm); - Printv(getf,s, 0); + Delete(temp); Delete(s); - } else { - Printf(stderr,"%s:%d. Unable to link with variable type %s\n", - Getfile(node), Getline(node),SwigType_str(t,0)); + Delete(wname); } - Printv(getf, tab4, "return _val;\n}\n", 0); - Printf(f_wrappers,"%s", getf); + + /* --------------------------------------------------------------------- + * marshalInputArgs(int numarg, int numreq, int start, Wrapper *f) + * + * Checks each of the parameters in the parameter list for a "check" + * typemap and (if it finds one) inserts the typemapping code into + * the function wrapper. + * --------------------------------------------------------------------- */ + + void marshalInputArgs(ParmList *l, int numarg, int numreq, int start, String *kwargs, bool allow_kwargs, Wrapper *f) { + int i; + Parm *p; + String *tm; + char source[256], target[256]; + + int use_self = (current == MEMBER_FUNC || current == MEMBER_VAR) ? 1 : 0; + int varargs = emit_isvarargs(l); - if (ReadOnly) { - setfname = NewString("NULL"); - } else { - /* create setter */ - char *target; + Printf(kwargs,"{ "); + for (i = 0, p = l; i < numarg; i++) { - setfname = NewString(Swig_name_set(name)); - Replace(setfname,"::", "_", DOH_REPLACE_ANY); /* FIXME: Swig_name_get bug? */ - Printv(setf, "static VALUE\n", setfname, "(VALUE self, ", 0); - Printf(setf, "VALUE _val) {\n"); + /* Skip ignored arguments */ + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } - if (SwigType_type(t) == T_USER) { - SwigType_add_pointer(t); - Wrapper_add_localv(setf,"temp",SwigType_lstr(t,0), "temp",0); - SwigType_del_pointer(t); - target = "temp"; + SwigType *pt = Getattr(p,"type"); + String *pn = Getattr(p,"name"); + String *ln = Getattr(p,"lname"); + + /* Produce string representation of source and target arguments */ + int selfp = (use_self && i == 0); + if (selfp) + strcpy(source,"self"); + else + sprintf(source,"argv[%d]",i-start); + + sprintf(target,"%s", Char(ln)); + + if (i >= (numreq)) { /* Check if parsing an optional argument */ + Printf(f->code," if (argc > %d) {\n", i - start); + } + + /* Record argument name for keyword argument handling */ + if (Len(pn)) { + Printf(kwargs,"\"%s\",", pn); + } else { + Printf(kwargs,"\"arg%d\",", i+1); + } + + /* Look for an input typemap */ + if ((tm = Getattr(p,"tmap:in"))) { + Replaceall(tm,"$target",ln); + Replaceall(tm,"$source",source); + Replaceall(tm,"$input",source); + Setattr(p,"emit:input",source); + Printf(f->code,"%s\n", tm); + p = Getattr(p,"tmap:in:next"); + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument.\n", SwigType_str(pt,0)); + p = nextSibling(p); + } + if (i >= numreq) { + Printf(f->code,"}\n"); + } + } + + /* Finish argument marshalling */ + Printf(kwargs," NULL }"); + if (allow_kwargs) { + Printv(f->locals, tab4, "char *kwnames[] = ", kwargs, ";\n", NIL); + } + + /* Trailing varargs */ + if (varargs) { + if (p && (tm = Getattr(p,"tmap:in"))) { + sprintf(source,"argv[%d]",i-start); + Replaceall(tm,"$input",source); + Setattr(p,"emit:input",source); + Printf(f->code,"if (argc > %d) {\n", i-start); + Printv(f->code,tm,"\n",NIL); + Printf(f->code,"}\n"); + } + } + } + + /* --------------------------------------------------------------------- + * insertConstraintCheckingCode(ParmList *l, Wrapper *f) + * + * Checks each of the parameters in the parameter list for a "check" + * typemap and (if it finds one) inserts the typemapping code into + * the function wrapper. + * --------------------------------------------------------------------- */ + + void insertConstraintCheckingCode(ParmList *l, Wrapper *f) { + Parm *p; + String *tm; + for (p = l; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } + } + } + + /* --------------------------------------------------------------------- + * insertCleanupCode(ParmList *l, String *cleanup) + * + * Checks each of the parameters in the parameter list for a "freearg" + * typemap and (if it finds one) inserts the typemapping code into + * the function wrapper. + * --------------------------------------------------------------------- */ + + void insertCleanupCode(ParmList *l, String *cleanup) { + String *tm; + for (Parm *p = l; p; ) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + } + + /* --------------------------------------------------------------------- + * insertCleanupCode(ParmList *l, String *cleanup) + * + * Checks each of the parameters in the parameter list for a "argout" + * typemap and (if it finds one) inserts the typemapping code into + * the function wrapper. + * --------------------------------------------------------------------- */ + + void insertArgOutputCode(ParmList *l, String *outarg, int& need_result) { + String *tm; + for (Parm *p = l; p; ) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$target","vresult"); + Replaceall(tm,"$result","vresult"); + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + need_result = 1; + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + } + + /* --------------------------------------------------------------------- + * validIdentifier() + * + * Is this a valid identifier in the scripting language? + * Ruby method names can include any combination of letters, numbers + * and underscores. A Ruby method name may optionally end with + * a question mark ("?"), exclamation point ("!") or equals sign ("="). + * + * Methods whose names end with question marks are, by convention, + * predicate methods that return true or false (e.g. Array#empty?). + * + * Methods whose names end with exclamation points are, by convention, + * "mutators" that modify the instance in place (e.g. Array#sort!). + * + * Methods whose names end with an equals sign are attribute setters + * (e.g. Thread#critical=). + * --------------------------------------------------------------------- */ + + virtual int validIdentifier(String *s) { + char *c = Char(s); + while (*c) { + if ( !( isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=') ) ) return 0; + c++; + } + return 1; + } + + /* --------------------------------------------------------------------- + * functionWrapper() + * + * Create a function declaration and register it with the interpreter. + * --------------------------------------------------------------------- */ + + virtual int functionWrapper(Node *n) { + String *symname = Copy(Getattr(n,"sym:name")); + SwigType *t = Getattr(n,"type"); + ParmList *l = Getattr(n,"parms"); + String *tm; + + int need_result = 0; + + /* Ruby needs no destructor wrapper */ + if (current == DESTRUCTOR) + return SWIG_NOWRAP; + + /* If the C++ class constructor is overloaded, we only want to + * write out the "new" singleton method once since it is always + * the same. (It's the "initialize" method that will handle the + * overloading). */ + + if (current == CONSTRUCTOR_ALLOCATE && + Swig_symbol_isoverloaded(n) && + Getattr(n, "sym:nextSibling") != 0) return SWIG_OK; + + String *overname = 0; + if (Getattr(n, "sym:overloaded")) { + overname = Getattr(n, "sym:overname"); } else { - target = name; + if (!addSymbol(symname, n)) + return SWIG_ERROR; } - tm = ruby_typemap_lookup((char*)"varin",t,name,(char*)"_val",target); - if (!tm) - tm = ruby_typemap_lookup((char*)"in",t,name,(char*)"_val",target); + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *kwargs = NewString(""); + Wrapper *f = NewWrapper(); + + /* Rename predicate methods */ + if (Getattr(n, "feature:predicate")) { + Append(symname, "?"); + } + + /* Determine the name of the SWIG wrapper function */ + String *wname = Swig_name_wrapper(symname); + if (overname && current != CONSTRUCTOR_ALLOCATE) { + Append(wname,overname); + } + + /* Emit arguments */ + if (current != CONSTRUCTOR_ALLOCATE) { + emit_args(t,l,f); + } + + /* Attach standard typemaps */ + if (current != CONSTRUCTOR_ALLOCATE) { + emit_attach_parmmaps(l, f); + } + Setattr(n, "wrap:parms", l); + + /* Get number of arguments */ + int numarg = emit_num_arguments(l); + int numreq = emit_num_required(l); + int varargs = emit_isvarargs(l); + bool allow_kwargs = use_kw || Getattr(n,"feature:kwargs"); + + int start = (current == MEMBER_FUNC || current == MEMBER_VAR) ? 1 : 0; + + /* Now write the wrapper function itself */ + Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL); + + if (current != CONSTRUCTOR_ALLOCATE) { + if (!varargs) { + Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start); + } else { + Printf(f->code,"if (argc < %d)\n", numreq-start); + } + Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start); + } + + /* Now walk the function parameter list and generate code */ + /* to get arguments */ + if (current != CONSTRUCTOR_ALLOCATE) { + marshalInputArgs(l, numarg, numreq, start, kwargs, allow_kwargs, f); + } + + /* Insert constraint checking code */ + insertConstraintCheckingCode(l, f); + + /* Insert cleanup code */ + insertCleanupCode(l, cleanup); + + /* Insert argument output code */ + insertArgOutputCode(l, outarg, need_result); + + /* Now write code to make the function call */ + if (current != CONSTRUCTOR_ALLOCATE) { + if (current == CONSTRUCTOR_INITIALIZE) { + String *action = Getattr(n,"wrap:action"); + if (action) { + Append(action,"DATA_PTR(self) = result;"); + } + } + emit_action(n,f); + } + + int newobj = 0; + if (Getattr(n,"feature:new")) newobj = 1; + + /* Return value if necessary */ + if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_ALLOCATE && current != CONSTRUCTOR_INITIALIZE) { + need_result = 1; + if (Getattr(n, "feature:predicate")) { + Printv(f->code, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL); + } else { + tm = Swig_typemap_lookup_new("out",n,"result",0); + if (tm) { + Replaceall(tm,"$result","vresult"); + Replaceall(tm,"$source","result"); + Replaceall(tm,"$target","vresult"); + Replaceall(tm,"$owner", newobj ? "1" : "0"); + Printv(f->code, tm, "\n", NIL); + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s.\n", SwigType_str(t,0)); + } + } + } + + /* Extra code needed for new and initialize methods */ + if (current == CONSTRUCTOR_ALLOCATE) { + need_result = 1; + Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(t))); + Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n"); + } else if (current == CONSTRUCTOR_INITIALIZE) { + need_result = 1; + // Printf(f->code, "DATA_PTR(self) = result;\n"); + } + + /* Dump argument output code; */ + Printv(f->code,outarg,NIL); + + /* Dump the argument cleanup code */ + if (current != CONSTRUCTOR_ALLOCATE) + Printv(f->code,cleanup,NIL); + + /* Look for any remaining cleanup. This processes the %new directive */ + if (newobj) { + tm = Swig_typemap_lookup_new("newfree",n,"result",0); + if (tm) { + Replaceall(tm,"$source","result"); + Printv(f->code,tm, "\n",NIL); + } + } + + /* Special processing on return value. */ + tm = Swig_typemap_lookup_new("ret",n,"result",0); if (tm) { - String *s = NewString(tm); - Printv(setf,s,0); - Delete(s); + Replaceall(tm,"$source","result"); + Printv(f->code,tm, NIL); + } + + /* Wrap things up (in a manner of speaking) */ + if (need_result) { + if (current == CONSTRUCTOR_ALLOCATE) { + Printv(f->code, tab4, "return vresult;\n}\n", NIL); + } else if (current == CONSTRUCTOR_INITIALIZE) { + Printv(f->code, tab4, "return self;\n}\n", NIL); + } else { + Wrapper_add_local(f,"vresult","VALUE vresult = Qnil"); + Printv(f->code, tab4, "return vresult;\n}\n", NIL); + } } else { - Printf(stderr,"%s:%d. Unable to link with variable type %s\n", - Getfile(node), Getline(node),SwigType_str(t,0)); + Printv(f->code, tab4, "return Qnil;\n}\n", NIL); } - if (SwigType_type(t) == T_USER) { - Printv(setf, name, " = *temp;\n",0); + + /* Substitute the cleanup code */ + Replaceall(f->code,"$cleanup",cleanup); + + /* Emit the function */ + Wrapper_print(f, f_wrappers); + + /* Now register the function with the interpreter */ + if (!Swig_symbol_isoverloaded(n)) { + create_command(n, symname); + } else { + if (current == CONSTRUCTOR_ALLOCATE) { + create_command(n, symname); + } else { + Setattr(n, "wrap:name", wname); + if (!Getattr(n, "sym:nextSibling")) + dispatchFunction(n); + } } - Printv(setf, tab4, "return _val;\n",0); - Printf(setf,"}\n"); - Printf(f_wrappers,"%s", setf); + + Delete(kwargs); + Delete(cleanup); + Delete(outarg); + DelWrapper(f); + Delete(symname); + + return SWIG_OK; } - /* define accessor method */ - if (CPlusPlus) { - Insert(getfname,0,"VALUEFUNC("); - Append(getfname,")"); - Insert(setfname,0,"VALUEFUNC("); - Append(setfname,")"); - } + /* ------------------------------------------------------------ + * dispatchFunction() + * ------------------------------------------------------------ */ + + void dispatchFunction(Node *n) { + /* Last node in overloaded chain */ - String *s = NewString(""); - switch (current) { - case STATIC_VAR: - /* C++ class variable */ - Printv(s, - tab4, "rb_define_singleton_method(", klass->vname, ", \"", - klass->strip(iname), "\", ", getfname, ", 0);\n", - 0); - if (!ReadOnly) { + int maxargs; + String *tmp = NewString(""); + String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *f = NewWrapper(); + String *symname = Getattr(n, "sym:name"); + String *wname = Swig_name_wrapper(symname); + + Printv(f->def, + "static VALUE ", wname, + "(int nargs, VALUE *args, VALUE self) {", + NIL); + + Wrapper_add_local(f, "argc", "int argc"); + if (current == MEMBER_FUNC || current == MEMBER_VAR) { + Printf(tmp, "VALUE argv[%d]", maxargs+1); + } else { + Printf(tmp, "VALUE argv[%d]", maxargs); + } + Wrapper_add_local(f, "argv", tmp); + Wrapper_add_local(f, "ii", "int ii"); + if (current == MEMBER_FUNC || current == MEMBER_VAR) { + Printf(f->code, "argc = nargs + 1;\n"); + Printf(f->code, "argv[0] = self;\n"); + Printf(f->code, "for (ii = 1; (ii < argc) && (ii < %d); ii++) {\n", maxargs); + Printf(f->code, "argv[ii] = args[ii-1];\n"); + Printf(f->code, "}\n"); + } else { + Printf(f->code, "argc = nargs;\n"); + Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs); + Printf(f->code, "argv[ii] = args[ii];\n"); + Printf(f->code, "}\n"); + } + + Replaceall(dispatch, "$args", "nargs, args, self"); + Printv(f->code, dispatch, "\n", NIL); + Printf(f->code, "rb_raise(rb_eArgError, \"No matching function for overloaded '%s'\");\n", symname); + Printf(f->code,"return Qnil;\n"); + Printv(f->code, "}\n", NIL); + Wrapper_print(f, f_wrappers); + create_command(n, Char(symname)); + + DelWrapper(f); + Delete(dispatch); + Delete(tmp); + Delete(wname); + } + + /* --------------------------------------------------------------------- + * variableWrapper() + * --------------------------------------------------------------------- */ + + virtual int variableWrapper(Node *n) { + + char *name = GetChar(n,"name"); + char *iname = GetChar(n,"sym:name"); + SwigType *t = Getattr(n,"type"); + String *tm; + String *getfname, *setfname; + Wrapper *getf, *setf; + + getf = NewWrapper(); + setf = NewWrapper(); + + /* create getter */ + getfname = NewString(Swig_name_get(iname)); + Printv(getf->def, "static VALUE\n", getfname, "(", NIL); + Printf(getf->def, "VALUE self"); + Printf(getf->def, ") {"); + Wrapper_add_local(getf,"_val","VALUE _val"); + + tm = Swig_typemap_lookup_new("varout",n, name, 0); + if (tm) { + Replaceall(tm,"$result","_val"); + Replaceall(tm,"$target","_val"); + Replaceall(tm,"$source",name); + Printv(getf->code,tm, NIL); + } else { + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, + "Unable to read variable of type %s\n", SwigType_str(t,0)); + } + Printv(getf->code, tab4, "return _val;\n}\n", NIL); + Wrapper_print(getf,f_wrappers); + + if (Getattr(n,"feature:immutable")) { + setfname = NewString("NULL"); + } else { + /* create setter */ + setfname = NewString(Swig_name_set(iname)); + Printv(setf->def, "static VALUE\n", setfname, "(VALUE self, ", NIL); + Printf(setf->def, "VALUE _val) {"); + + tm = Swig_typemap_lookup_new("varin",n,name,0); + if (tm) { + Replaceall(tm,"$input","_val"); + Replaceall(tm,"$source","_val"); + Replaceall(tm,"$target",name); + Printv(setf->code,tm,"\n",NIL); + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, + "Unable to set variable of type %s\n", SwigType_str(t,0)); + } + Printv(setf->code, tab4, "return _val;\n",NIL); + Printf(setf->code,"}\n"); + Wrapper_print(setf,f_wrappers); + } + + /* define accessor method */ + if (CPlusPlus) { + Insert(getfname,0,"VALUEFUNC("); + Append(getfname,")"); + Insert(setfname,0,"VALUEFUNC("); + Append(setfname,")"); + } + + String *s = NewString(""); + switch (current) { + case STATIC_VAR: + /* C++ class variable */ Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", - klass->strip(iname), "=\", ", setfname, ", 1);\n", - 0); - } - Printv(klass->init,s,0); - break; - default: - /* C global variable */ - /* wrapped in Ruby module attribute */ - Printv(s, - tab4, "rb_define_singleton_method(", modvar, ", \"", - iname, "\", ", getfname, ", 0);\n", - 0); - if (!ReadOnly) { + klass->strip(iname), "\", ", getfname, ", 0);\n", + NIL); + if (!Getattr(n,"feature:immutable")) { + Printv(s, + tab4, "rb_define_singleton_method(", klass->vname, ", \"", + klass->strip(iname), "=\", ", setfname, ", 1);\n", + NIL); + } + Printv(klass->init,s,NIL); + break; + default: + /* C global variable */ + /* wrapped in Ruby module attribute */ Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", - iname, "=\", ", setfname, ", 1);\n", - 0); + iname, "\", ", getfname, ", 0);\n", + NIL); + if (!Getattr(n,"feature:immutable")) { + Printv(s, + tab4, "rb_define_singleton_method(", modvar, ", \"", + iname, "=\", ", setfname, ", 1);\n", + NIL); + } + Printv(f_init,s,NIL); + Delete(s); + break; } - Printv(f_init,s,0); - Delete(s); - break; - } - Delete(getfname); - Delete(setfname); - Delete(setf); - Delete(getf); -} - - -/* --------------------------------------------------------------------- - * RUBY::validate_const_name(char *name) - * - * Validate constant name. - * --------------------------------------------------------------------- */ - -char *RUBY::validate_const_name(char *name) { - if (!name || name[0] == '\0') - return name; - - if (isupper(name[0])) - return name; - - if (islower(name[0])) { - name[0] = toupper(name[0]); - /* Printf(stderr,"%s:%d. Wrong constant/class/module name " - "(corrected to `%s')\n", Getfile(node), Getline(node), name); */ - - Printf(stderr,"?:?. Wrong constant/class/module name (corrected to '%s')\n", name); - return name; + Delete(getfname); + Delete(setfname); + DelWrapper(setf); + DelWrapper(getf); + return SWIG_OK; } - Printf(stderr,"?:?. Wrong constant/class/module name\n"); - return name; -} -/* --------------------------------------------------------------------- - * RUBY::constant() - * - * Makes a constant. - * --------------------------------------------------------------------- */ + /* --------------------------------------------------------------------- + * validate_const_name(char *name) + * + * Validate constant name. + * --------------------------------------------------------------------- */ -void RUBY::constant(DOH *node) { - char *tm; - char *name, *iname; - SwigType *type; - char *value; + char * + validate_const_name(char *name, const char *reason) { + if (!name || name[0] == '\0') + return name; + + if (isupper(name[0])) + return name; + + if (islower(name[0])) { + name[0] = toupper(name[0]); + Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, + "Wrong %s name (corrected to `%s')\n", reason, name); + return name; + } + + Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, + "Wrong %s name\n", reason); + + return name; + } + + /* --------------------------------------------------------------------- + * constantWrapper() + * --------------------------------------------------------------------- */ - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - - if (current == CLASS_CONST) - iname = klass->strip(iname); - - tm = ruby_typemap_lookup((char*)"const",type,name,value,iname); - if (tm) { - String *str = NewString(tm); - Replace(str,"$value",value, DOH_REPLACE_ANY); + virtual int constantWrapper(Node *n) { + Swig_require(&n, "*sym:name", "type", "value", NIL); + + char *iname = GetChar(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + char *value = GetChar(n,"value"); + if (current == CLASS_CONST) { - Replace(str,"$module", klass->vname, DOH_REPLACE_ANY); - Printv(klass->init, str, 0); - } else { - Replace(str,"$module", modvar, DOH_REPLACE_ANY); - Printf(f_init,"%s", str); + iname = klass->strip(iname); } - Delete(str); - } else { - Printf(stderr,"%s:%d. Unable to create constant %s = %s\n", - Getfile(node), Getline(node), SwigType_str(type,0), value); - } -} - -/* --------------------------------------------------------------------- - * RUBY::ruby_typemap_lookup(char *op, SwigType *type, char *pname, char *source, char *target, WrapperFunction *f = 0) - * - * Ruby specific typemap_lookup. - * op = string code for type of mapping - * type = the datatype - * pname = an optional parameter name - * source = a string with the source variable - * target = a string containing the target value - * f = a wrapper function object (optional) - * --------------------------------------------------------------------- */ - -char *RUBY::ruby_typemap_lookup(char *op, SwigType *type, String_or_char *pname, char *source, char *target, Wrapper *f) { - static String *s = 0; - char *tm; - String *target_replace = NewString(target); - target = Char(target_replace); - int type_code, add_pointer = 0; - - if (SwigType_type(type) == T_USER) - add_pointer = 1; - if (add_pointer) - SwigType_add_pointer(type); - type_code = SwigType_type(type); - - RClass *cls = RCLASS(classes, SwigType_base(type)); - - if (!s) s = NewString(""); - Clear(s); - - if ((strcmp("out", op) == 0 || strcmp("in", op) == 0) - && Cmp(SwigType_base(type), "VALUE") == 0) { - Printf(s,"$target = $source;\n"); - } else if (strcmp("out", op) == 0 - && (type_code == T_POINTER || type_code == T_REFERENCE) - && cls) { - const char *vname = (current == CONSTRUCTOR ? "self" : Char(cls->vname)); - Printv(s, "$target = Wrap_", cls->cname, "(", vname, ", $source);\n",0); - } else if (strcmp("in", op)==0 - && (type_code == T_POINTER || type_code == T_REFERENCE) - && cls) { - Printv(s, "Get_", cls->cname, "($source, $target);\n", 0); - } else { - if (add_pointer) { - SwigType_del_pointer(type); - add_pointer = 0; + validate_const_name(iname, "constant"); + SetChar(n, "sym:name", iname); + + /* Special hook for member pointer */ + if (SwigType_type(type) == T_MPOINTER) { + String *wname = Swig_name_wrapper(iname); + Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value); + value = Char(wname); } - - tm = Swig_typemap_lookup(op, type, pname, source, target, f); + String *tm = Swig_typemap_lookup_new("constant", n, value, 0); if (tm) { - Delete(target_replace); - Printv(s, tm, "\n", 0); + Replaceall(tm, "$source", value); + Replaceall(tm, "$target", iname); + Replaceall(tm, "$symname", iname); + Replaceall(tm, "$value", value); + if (current == CLASS_CONST) { + Replaceall(tm, "$module", klass->vname); + Printv(klass->init, tm, "\n", NIL); + } else { + Replaceall(tm,"$module", modvar); + Printf(f_init, "%s\n", tm); + } } else { - Clear(s); - if (strcmp("in", op) == 0) { - String *v = NewString(""); - if (from_VALUE(type, (char*)"$source", (char*)"$target", v)) - Printv(s, v, "\n", 0); - Delete(v); - } else if (strcmp("out", op) == 0) { - String *v = NewString(""); - if (to_VALUE(type, (char*)"$source", v)) - Printv(s, "$target = ", v, ";\n", 0); - Delete(v); - } else if (strcmp("const", op) == 0) { - String *v = NewString(""); - if (to_VALUE(type, (char*)"$value", v, 1)) { - Printv(s, "rb_define_const($module, \"$target\", ", v, ");\n", 0); - validate_const_name(target); - } - Delete(v); - } + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, + "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value); } + Swig_restore(&n); + return SWIG_OK; } - if (source && strlen(source) > 0) - Replace(s,"$source",source, DOH_REPLACE_ANY); - if (target && strlen(target) > 0) - Replace(s,"$target",target, DOH_REPLACE_ANY); - Replace(s,"$type", SwigType_str(type,0), DOH_REPLACE_ANY); + + /* ----------------------------------------------------------------------------- + * classDeclaration() + * + * Records information about classes---even classes that might be defined in + * other modules referenced by %import. + * ----------------------------------------------------------------------------- */ - if (add_pointer) { - SwigType_del_pointer(type); - add_pointer = 0; - } - - if (Len(s) == 0) - return NULL; - return Char(s); -} - - -static void -convert_pointer(char *src, SwigType *t, String *f) { - SwigType_remember(t); - Printv(f, "SWIG_NewPointerObj((void *)", src, ", SWIGTYPE", SwigType_manglestr(t), ")", 0); -} - -/* --------------------------------------------------------------------- - * RUBY::to_VALUE(SwigType *type, char *value, literal) - * - * Makes a VALUE (as a string) - * type = Datatype of the C value - * value = C value (as a string) - * str = resulting code (as a string) - * raw = value is raw string (not quoted) ? - * --------------------------------------------------------------------- */ - -int RUBY::to_VALUE(SwigType *type, char *value, String *str, int raw) { - Clear(str); - switch(SwigType_type(type)) { - case T_INT: - case T_SHORT: - case T_LONG: - case T_SCHAR: - Printv(str, "INT2NUM(", value, ")", 0); - break; - case T_UINT: - case T_USHORT: - case T_ULONG: - case T_UCHAR: - Printv(str,"UINT2NUM(", value, ")", 0); - break; - case T_DOUBLE: - case T_FLOAT: - Printv(str, "rb_float_new(", value, ")", 0); - break; - case T_CHAR: - Printv(str, "rb_str_new(&", value, ", 1)", 0); - break; - case T_BOOL: - Printv(str, "(", value, " ? Qtrue : Qfalse)", 0); - break; - case T_STRING: - if (raw) - Printv(str, "rb_str_new2(\"", value, "\")", 0); - else - Printv(str, "rb_str_new2(", value, ")", 0); - break; - case T_ARRAY: - { - SwigType *aop; - SwigType *ta = Copy(type); - aop = SwigType_pop(ta); - if (SwigType_type(ta) == T_CHAR) { - Printf(str, "rb_str_new2(%s)", value); - break; - } - convert_pointer(value, type, str); - break; + virtual int classDeclaration(Node *n) { + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + String *tdname = Getattr(n,"tdname"); + + name = tdname ? tdname : name; + String *namestr = SwigType_namestr(name); + klass = RCLASS(classes, Char(namestr)); + if (!klass) { + klass = new RClass(); + String *valid_name = NewString(symname ? symname : namestr); + validate_const_name(Char(valid_name), "class"); + klass->set_name(namestr, symname, valid_name); + SET_RCLASS(classes, Char(namestr), klass); + Delete(valid_name); } - case T_POINTER: case T_REFERENCE: - convert_pointer(value, type, str); - break; - case T_USER: - SwigType_add_pointer(type); - convert_pointer(value, type, str); - SwigType_del_pointer(type); - break; - default: - break; + Delete(namestr); + return Language::classDeclaration(n); } - if (Len(str) == 0) - return 0; - return 1; -} + /* ---------------------------------------------------------------------- + * classHandler() + * ---------------------------------------------------------------------- */ -static void -get_pointer(char *src, char *dest, SwigType *t, String *f) { - SwigType *lt; + virtual int classHandler(Node *n) { - SwigType_remember(t); - Printv(f, dest, " = (", SwigType_lstr(t,0), ")SWIG_ConvertPtr(", src, ", ", 0); + String *name = Getattr(n,"name"); + String *symname = Getattr(n,"sym:name"); + String *namestr = SwigType_namestr(name); // does template expansion - lt = Swig_clocal_type(t); - if (Cmp(lt,"p.void") == 0) { - Printv(f, "0);", 0); - } else { - Printv(f, "SWIGTYPE", SwigType_manglestr(t), ");", 0); - } - Delete(lt); -} + klass = RCLASS(classes, Char(namestr)); + assert(klass); + Delete(namestr); + String *valid_name = NewString(symname); + validate_const_name(Char(valid_name), "class"); -/* --------------------------------------------------------------------- - * RUBY::from_VALUE(SwigType *type, char *value) - * - * extract VALUE - * type = Datatype of the C value - * value = Ruby VALUE (as a string) - * target= target C variable (as a string) - * str = resulting code (as a string) - * --------------------------------------------------------------------- */ - -int RUBY::from_VALUE(SwigType *type, char *value, char *target, String *str) { - Clear(str); - switch(SwigType_type(type)) { - case T_INT: - Printv(str, target, " = NUM2INT(", value, ");", 0); - break; - case T_LONG: - Printv(str, target, " = NUM2LONG(", value, ");", 0); - break; - case T_SHORT: - Printv(str, target, " = NUM2SHRT(", value, ");", 0); - break; - case T_UINT: - Printv(str, target, " = NUM2UINT(", value, ");", 0); - break; - case T_ULONG: - Printv(str, target, " = NUM2ULONG(", value, ");", 0); - break; - case T_USHORT: - Printv(str, target, " = NUM2USHRT(", value, ");", 0); - break; - case T_DOUBLE: - case T_FLOAT: - Printv(str, target, " = NUM2DBL(", value, ");", 0); - break; - case T_CHAR: case T_SCHAR: case T_UCHAR: - Printv(str, target, " = NUM2CHR(", value, ");", 0); - break; - case T_BOOL: - Printv(str, target, " = RTEST(", value, ");", 0); - break; - case T_STRING: - Printv(str, target, " = STR2CSTR(", value, ");", 0); - break; - case T_ARRAY: - { - SwigType *aop; - SwigType *ta = Copy(type); - aop = SwigType_pop(ta); - if (SwigType_type(ta) == T_CHAR) { - String *dim = SwigType_array_getdim(aop,0); - if (dim && Len(dim)) { - Printf(str, "strncpy(%s, STR2CSTR(%s), %s);", target, value, dim); - } - break; - } - get_pointer(value, target, type, str); - break; - } - case T_POINTER: case T_REFERENCE: - get_pointer(value, target, type, str); - break; - case T_USER: - SwigType_add_pointer(type); - get_pointer(value, target, type, str); - SwigType_del_pointer(type); - break; - default: - break; - } - if (Len(str) == 0) return 0; - return 1; -} - -/* ---------------------------------------------------------------------- - * void RUBY::cpp_open_class(char *classname, char *classrename, char *ctype, int strip) - * - * Open a new C++ class. - * - * INPUTS: - * name = Real name of the C++ class - * rename = New name of the class (if %name was used) - * ctype = Class type (struct, class, union, etc...) - * strip = Flag indicating whether we should strip the - * class type off - * - * This function is in charge of creating a new class. The SWIG parser has - * already processed the entire class definition prior to calling this - * function (which should simplify things considerably). - * - * ---------------------------------------------------------------------- */ - -void RUBY::cpp_open_class(DOH *node) { - this->Language::cpp_open_class(node); - - char *cname = GetChar(node,"name"); - char *rename = GetChar(node,"scriptname"); - char *ctype = GetChar(node,"classtype"); - int strip = GetInt(node,"strip"); - - klass = RCLASS(classes, cname); - - if (strip) { Clear(klass->type); - Append(klass->type, klass->cname); - } else { - Clear(klass->type); - Printv(klass->type, ctype, " ", klass->cname,0); - } + Printv(klass->type, Getattr(n,"classtype"), NIL); + Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL); + Printv(klass->init, "\n", tab4, NIL); + Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, + ", \"", klass->name, "\", $super);\n", NIL); - Printv(klass->header, "\nstatic VALUE ", klass->vname, ";\n", 0); - Printv(klass->init, "\n", tab4, 0); - Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, - ", \"", klass->name, "\", $super);\n", 0); - Replace(klass->includes,"$class", klass->vname, DOH_REPLACE_ANY); - Printv(klass->init, klass->includes,0); - Printv(klass->init, "$constructor",0); - - Printv(klass->header, - "$markproto", - "$freeproto", - "#define Wrap_", klass->cname, "(klass, ptr) (\\\n", - tab4, "(ptr) ? Data_Wrap_Struct(klass", - ", $markfunc, $freefunc, ptr) : Qnil )\n", - "#define Get_", klass->cname, "(val, ptr) {\\\n", - tab4, "if (NIL_P(val)) ptr = NULL;\\\n", - tab4, "else {\\\n", - tab8, "if (!rb_obj_is_kind_of(val, ", klass->vname, "))\\\n", - tab8, tab4, "rb_raise(rb_eTypeError, \"wrong argument type", - " (expected ", klass->name, ")\");\\\n", - tab8, "Data_Get_Struct(val, ", klass->type, ", ptr);\\\n", - tab8, "if (!ptr) rb_raise(rb_eRuntimeError, \"", - "This ", klass->name, " already released\");\\\n", - tab4, "}\\\n", - "}\n", - 0); - -} - -/* --------------------------------------------------------------------- - * void RUBY::cpp_close_class() - * - * Close the current class - * --------------------------------------------------------------------- */ - -void RUBY::cpp_close_class() { - this->Language::cpp_close_class(); - - Replace(klass->header,"$markfunc", "0", DOH_REPLACE_ANY); - Replace(klass->header,"$markproto", "", DOH_REPLACE_ANY); - if (!klass->destructor_defined) { - Replace(klass->header,"$freefunc", "0", DOH_REPLACE_ANY); - Replace(klass->header,"$freeproto", "", DOH_REPLACE_ANY); - } - Printv(f_header, klass->header,0); - - Replace(klass->aliases,"$class", klass->vname, DOH_REPLACE_ANY); - Printv(klass->init, klass->aliases,0); - - String *s = NewString(""); - Printv(s, tab4, "rb_undef_method(CLASS_OF(", klass->vname, - "), \"new\");\n", 0); - Replace(klass->init,"$constructor", s, DOH_REPLACE_ANY); - Replace(klass->init,"$super", "rb_cObject", DOH_REPLACE_ANY); - - Printv(f_init,klass->init,0); - klass = 0; -} - -/* ---------------------------------------------------------------------- - * void RUBY::cpp_inherit(char **baseclass, int mode) - * - * Inherit attributes from given baseclass. - * - * INPUT: - * baseclass = NULL terminate list of baseclasses - * - * --------------------------------------------------------------------- */ - - -void RUBY::cpp_inherit(List *bases) { - if (!bases) return; - String *base; - for (base = Firstitem(bases); base; base = Nextitem(bases)) { - RClass *super = RCLASS(classes, Char(base)); - if (super) { - Replace(klass->init,"$super", super->vname, DOH_REPLACE_ANY); - break; /* ignore multiple inheritance */ + SwigType *tt = NewString(name); + SwigType_add_pointer(tt); + SwigType_remember(tt); + String *tm = SwigType_manglestr(tt); + Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &c%s);\n", tm, valid_name); + Delete(tm); + Delete(tt); + Delete(valid_name); + + /* Process the comma-separated list of mixed-in module names (if any) */ + String *mixin = Getattr(n,"feature:mixin"); + if (mixin) { + List *modules = Split(mixin,',',INT_MAX); + if (modules && Len(modules) > 0) { + String *mod = Firstitem(modules); + while (mod) { + if (Len(mod) > 0) { + Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod); + } + mod = Nextitem(modules); + } + } + Delete(modules); } - } -} -/* ---------------------------------------------------------------------- - * void RUBY::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) - * - * Method for adding C++ member function - * - * INPUTS: - * name - name of the member function - * iname - renaming (if given) - * t - Return datatype - * l - Parameter list - * - * By default, we're going to create a function of the form : - * - * Foo_bar(this,args) - * - * Where Foo is the classname, bar is the member name and the this pointer - * is explicitly attached to the beginning. - * - * The renaming only applies to the member function part, not the full - * classname. - * - * --------------------------------------------------------------------- */ + Printv(klass->init, "$allocator",NIL); + Printv(klass->init, "$initializer",NIL); -void RUBY::cpp_memberfunction(DOH *node) { - current = MEMBER_FUNC; - this->Language::cpp_memberfunction(node); - current = NO_CPP; -} + Printv(klass->header, + "$freeproto", + NIL); -/* --------------------------------------------------------------------- - * void RUBY::cpp_constructor(char *name, char *iname, ParmList *l) - * - * Method for adding C++ member constructor - * - * INPUTS: - * name - Name of the constructor (usually same as classname) - * iname - Renamed version - * l - parameters - * -------------------------------------------------------------------- */ + Language::classHandler(n); -void RUBY::cpp_constructor(DOH *node) { - current = CONSTRUCTOR; - this->Language::cpp_constructor(node); - current = NO_CPP; -} - -/* --------------------------------------------------------------------- - * void RUBY::cpp_destructor(char *name, char *iname) - * - * Method for adding C++ member destructor - * - * INPUT: - * name - Name of the destructor (classname) - * iname - Renamed destructor - * - * -------------------------------------------------------------------- */ - -void RUBY::cpp_destructor(DOH *node) { - char *name, *newname; - - name = GetChar(node,"name"); - newname = GetChar(node,"scriptname"); - current = DESTRUCTOR; - this->Language::cpp_destructor(node); - - String *freefunc = NewString(""); - String *freeproto = NewString(""); - String *freebody = NewString(""); - - Printv(freefunc, "free_", klass->cname, 0); - Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", 0); - Printv(freebody, "static void\n", - freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n", - tab4, 0); - if (AddMethods) { - Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", 0); - } else { - /* When no addmethods mode, swig emits no destroy function. */ - if (CPlusPlus) - Printv(freebody, Swig_cppdestructor_call(), 0); - else - Printv(freebody, Swig_cdestructor_call(), 0); - } - Printv(freebody, ";\n}\n", 0); - if (CPlusPlus) { - Insert(freefunc,0,"VOIDFUNC("); - Append(freefunc,")"); - } - - Replace(klass->header,"$freefunc", freefunc, DOH_REPLACE_ANY); - Replace(klass->header,"$freeproto", freeproto, DOH_REPLACE_ANY); - Printv(f_wrappers, freebody, 0); - - klass->destructor_defined = 1; - current = NO_CPP; - Delete(freefunc); - Delete(freeproto); - Delete(freebody); -} - -/* --------------------------------------------------------------------- - * void RUBY::cpp_variable(char *name, char *iname, SwigType *t) - * - * Wrap a C++ data member - * - * INPUTS : - * name = Name of the C++ member - * iname = Name as used in the interpreter - * t = Datatype - * - * This creates a pair of functions to set/get the variable of a member. - * -------------------------------------------------------------------- */ - -void RUBY::cpp_variable(DOH *node) { - current = MEMBER_VAR; - this->Language::cpp_variable(node); - current = NO_CPP; -} - -/* ----------------------------------------------------------------------- - * void RUBY::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l) - * - * Wrap a static C++ function - * - * INPUTS: - * name = Real name of the function - * iname = New name in interpreter - * t = Return datatype - * l = Parameters - * ---------------------------------------------------------------------- */ - -void RUBY::cpp_staticfunction(DOH *node) { - current = STATIC_FUNC; - this->Language::cpp_staticfunction(node); - current = NO_CPP; -} - -/* ---------------------------------------------------------------------- - * void RUBY::cpp_declare_const(char *name, char *iname, SwigType *t, char *value) - * - * Create a C++ constant - * - * INPUTS : - * name = Real name of the constant - * iname = new name - * t = Datatype - * value = value as a string - * - * --------------------------------------------------------------------- */ - - -void RUBY::cpp_constant(DOH *node) { - current = CLASS_CONST; - this->Language::cpp_constant(node); - current = NO_CPP; -} - -/* --------------------------------------------------------------------- - * void RUBY::cpp_static_var(char *name, char *iname, SwigType *t) - * - * Wrap a static C++ variable - * - * INPUT : - * name = name of the variable - * iname = interpreter name - * t = Datatype - * - * --------------------------------------------------------------------- */ - -void RUBY::cpp_staticvariable(DOH *node) { - current = STATIC_VAR; - this->Language::cpp_staticvariable(node); - current = NO_CPP; -} - -/* ----------------------------------------------------------------------- - * RUBY::cpp_class_decl(char *name, char *rename, char *type) - * - * A forward class declaration - * ----------------------------------------------------------------------- */ - -void RUBY::cpp_class_decl(DOH *node) { - String *cname = Getattr(node,"name"); - String *rename = Getattr(node,"scriptname"); - String *ctype = Getattr(node,"classtype"); - String *valid_name = NewString((rename ? rename : cname)); - validate_const_name(Char(valid_name)); - klass->set_name(Char(cname), Char(rename), Char(valid_name)); - SET_RCLASS(classes, Char(cname), klass); - if (ctype && Len(ctype) > 0) { - char temp[256]; - sprintf(temp,"%s %s", Char(ctype), Char(cname)); - SET_RCLASS(classes, temp, klass); - } - /* - char s[256]; - sprintf(s,"extern VALUE %s;\n", Char(klass->vname)); - Printf(f_header, s); - */ - klass = new RClass(); - Delete(valid_name); -} - -/* -------------------------------------------------------------------- - * void RUBY::pragma(char *target, char *var, char *value) - * - * A pragma declaration - * -------------------------------------------------------------------- */ - -void RUBY::pragma(DOH *node) { - String *cmd = Getattr(node,"name"); - String *value = Getattr(node,"value"); - if (Cmp(cmd, "free") == 0) { - char name[64]; - if (sscanf(Char(value), " %s ", name) != 1) { - Printf(stderr, "%s:%d. Invalid free pragma.\n", - Getfile(node), Getline(node)); - return; + /* Handle inheritance */ + List *baselist = Getattr(n,"bases"); + if (baselist && Len(baselist)) { + Node *base = Firstitem(baselist); + String *basename = Getattr(base,"name"); + String *basenamestr = SwigType_namestr(basename); + RClass *super = RCLASS(classes, Char(basenamestr)); + Delete(basenamestr); + if (super) { + SwigType *btype = NewString(basename); + SwigType_add_pointer(btype); + SwigType_remember(btype); + String *bmangle = SwigType_manglestr(btype); + Insert(bmangle,0,"((swig_class *) SWIGTYPE"); + Append(bmangle,"->clientdata)->klass"); + Replaceall(klass->init,"$super",bmangle); + Delete(bmangle); + Delete(btype); + } + + /* Warn about multiple inheritance if additional base class(es) listed */ + base = Nextitem(baselist); + while (base) { + basename = Getattr(n,"name"); + Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number, + "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", basename, basename); + base = Nextitem(baselist); + } } - Setattr(klass->freemethods, name, name); - } else if (Cmp(cmd, "include") == 0) { - char name[64]; - if (sscanf(Char(value), " %s ", name) != 1) { - Printf(stderr, "%s:%d. Invalid include pragma.\n", - Getfile(node), Getline(node)); - return; + + /* Check to see if a %markfunc was specified */ + String *markfunc = Getattr(n, "feature:markfunc"); + if (markfunc) { + Printf(klass->init, "c%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc); + } else { + Printf(klass->init, "c%s.mark = 0;\n", klass->name); } - Printv(klass->includes,tab4, "rb_include_module($class, ", - "rb_eval_string(\"", name, "\"));\n", 0); - } else if (Cmp(cmd, "alias") == 0) { - char alias[64], name[64]; - if (sscanf(Char(value), " %s %s ", alias, name) != 2) { - Printf(stderr, "%s:%d. Invalid alias pragma.\n", - Getfile(node), Getline(node)); - return; + + /* Check to see if a %freefunc was specified */ + String *freefunc = Getattr(n, "feature:freefunc"); + if (freefunc) { + Printf(klass->init, "c%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc); + } else { + if (klass->destructor_defined) { + Printf(klass->init, "c%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname); + } } - Printv(klass->aliases, tab4, "rb_define_alias($class, ", - "\"", alias, "\", \"", name, "\");\n", 0); - } else if (Cmp(cmd, "pred") == 0) { - char *tok; - tok = strtok(Char(value), " \t"); - while (tok) { - Setattr(klass->predmethods, tok, tok); - tok = strtok(0, " \t"); - } - } else if (Cmp(cmd, "debug") == 0) { - Printf(f_header, "/* %s */\n", value); - Printf(f_wrappers, "/* %s */\n", value); - Printf(f_init, "/* %s */\n", value); - Printf(stderr, "%s\n", value); + Replaceall(klass->header,"$freeproto", ""); + + Printv(f_header, klass->header,NIL); + + String *s = NewString(""); + Printv(s, tab4, "rb_undef_method(CLASS_OF(", klass->vname, + "), \"new\");\n", NIL); + Replaceall(klass->init,"$allocator", s); + Replaceall(klass->init,"$initializer", ""); + Replaceall(klass->init,"$super", "rb_cObject"); + Delete(s); + + Printv(f_init,klass->init,NIL); + klass = 0; + return SWIG_OK; } + + /* ---------------------------------------------------------------------- + * memberfunctionHandler() + * + * Method for adding C++ member function + * + * By default, we're going to create a function of the form : + * + * Foo_bar(this,args) + * + * Where Foo is the classname, bar is the member name and the this pointer + * is explicitly attached to the beginning. + * + * The renaming only applies to the member function part, not the full + * classname. + * + * --------------------------------------------------------------------- */ + + virtual int memberfunctionHandler(Node *n) { + current = MEMBER_FUNC; + Language::memberfunctionHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* --------------------------------------------------------------------- + * constructorHandler() + * + * Method for adding C++ member constructor + * -------------------------------------------------------------------- */ + + virtual int constructorHandler(Node *n) { + /* First wrap the new singleton method */ + current = CONSTRUCTOR_ALLOCATE; + Swig_name_register((String_or_char *) "construct", (String_or_char *) "%c_allocate"); + Language::constructorHandler(n); + + /* Now do the instance initialize method */ + current = CONSTRUCTOR_INITIALIZE; + Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c"); + Language::constructorHandler(n); + + /* Done */ + Swig_name_unregister((String_or_char *) "construct"); + current = NO_CPP; + klass->constructor_defined = 1; + return SWIG_OK; + } + + /* --------------------------------------------------------------------- + * destructorHandler() + * -------------------------------------------------------------------- */ + + virtual int destructorHandler(Node *n) { + current = DESTRUCTOR; + Language::destructorHandler(n); + + String *freefunc = NewString(""); + String *freeproto = NewString(""); + String *freebody = NewString(""); + + Printv(freefunc, "free_", klass->mname, NIL); + Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", NIL); + Printv(freebody, "static void\n", + freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n", + tab4, NIL); + if (Extend) { + String *wrap = Getattr(n, "wrap:code"); + if (wrap) { + File *f_code = Swig_filebyname("header"); + if (f_code) { + Printv(f_code, wrap, NIL); + } + } + /* Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", NIL); */ + Printv(freebody,Getattr(n,"wrap:action"), NIL); + } else { + /* When no extend mode, swig emits no destroy function. */ + if (CPlusPlus) + Printf(freebody, "delete %s", Swig_cparm_name(0,0)); + else + Printf(freebody, "free((char*) %s)", Swig_cparm_name(0,0)); + } + Printv(freebody, ";\n}\n", NIL); + + Replaceall(klass->header,"$freeproto", freeproto); + Printv(f_wrappers, freebody, NIL); + + klass->destructor_defined = 1; + current = NO_CPP; + Delete(freefunc); + Delete(freeproto); + Delete(freebody); + return SWIG_OK; + } + + /* --------------------------------------------------------------------- + * membervariableHandler() + * + * This creates a pair of functions to set/get the variable of a member. + * -------------------------------------------------------------------- */ + + virtual int + membervariableHandler(Node *n) { + current = MEMBER_VAR; + Language::membervariableHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ----------------------------------------------------------------------- + * staticmemberfunctionHandler() + * + * Wrap a static C++ function + * ---------------------------------------------------------------------- */ + + virtual int + staticmemberfunctionHandler(Node *n) { + current = STATIC_FUNC; + Language::staticmemberfunctionHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * memberconstantHandler() + * + * Create a C++ constant + * --------------------------------------------------------------------- */ + + virtual int + memberconstantHandler(Node *n) { + current = CLASS_CONST; + Language::memberconstantHandler(n); + current = NO_CPP; + return SWIG_OK; + } + + /* --------------------------------------------------------------------- + * staticmembervariableHandler() + * --------------------------------------------------------------------- */ + + virtual int + staticmembervariableHandler(Node *n) { + current = STATIC_VAR; + Language::staticmembervariableHandler(n); + current = NO_CPP; + return SWIG_OK; + } + +}; /* class RUBY */ + +/* ----------------------------------------------------------------------------- + * swig_ruby() - Instantiate module + * ----------------------------------------------------------------------------- */ + +extern "C" Language * +swig_ruby(void) { + return new RUBY(); } -/* --------------------------------------------------------------------- - * RUBY::import(char *filename) - * - * Imports a SWIG module as a separate file. - *---------------------------------------------------------------------- */ - - -void RUBY::import(String *modname) { - Printf(f_init, "rb_f_require(Qnil, rb_str_new2(\"%s\"));\n", modname); -} /* * Local Variables: @@ -1502,7 +1438,3 @@ void RUBY::import(String *modname) { * End: */ - - - - diff --git a/Source/Modules1.1/ruby.h b/Source/Modules1.1/ruby.h deleted file mode 100644 index 8844945ea..000000000 --- a/Source/Modules1.1/ruby.h +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************** - * Ruby module for SWIG - * - * $Header$ - * - * Copyright (C) 2000 Network Applied Communication Laboratory, Inc. - * Copyright (C) 2000 Information-technology Promotion Agency, Japan - * - * Masaki Fukushima - * - ********************************************************************/ - -class RUBY : public Language { - protected: - virtual String *make_wrapper_name(char *cname); - virtual char *validate_const_name(char *name); - virtual char *ruby_typemap_lookup(char *, SwigType *, String_or_char *, char *, char *, Wrapper * = 0); - virtual int to_VALUE(SwigType *, char *, DOHString *, int = 0); - virtual int from_VALUE(SwigType *, char *, char *, DOHString *); - public: - /* Virtual functions required by the SWIG parser */ - virtual void parse_args(int, char *argv[]); - virtual void initialize(String *module); - virtual void function(DOH *node); - virtual void variable(DOH *node); - virtual void constant(DOH *node); - virtual void close(void); - virtual void nativefunction(DOH *); - virtual void create_command(String *, String *); - virtual void import(String *); - - /* C++ language extensions. */ - virtual void cpp_memberfunction(DOH *); - virtual void cpp_constructor(DOH *); - virtual void cpp_destructor(DOH *); - virtual void cpp_open_class(DOH *); - virtual void cpp_close_class(); - virtual void cpp_inherit(List *bases); - virtual void cpp_variable(DOH *); - virtual void cpp_staticfunction(DOH *); - virtual void cpp_constant(DOH *); - virtual void cpp_staticvariable(DOH *); - - /* Declaration of a class, but not a full definition */ - virtual void cpp_class_decl(DOH *); - - /* Pragma directive */ - virtual void pragma(DOH *node); -}; - -/* - * Local Variables: - * c-basic-offset: 2 - * End: - */ diff --git a/Source/Modules1.1/s-exp.cxx b/Source/Modules1.1/s-exp.cxx new file mode 100644 index 000000000..2a9f2dcc1 --- /dev/null +++ b/Source/Modules1.1/s-exp.cxx @@ -0,0 +1,401 @@ +/* ----------------------------------------------------------------------------- + * s-exp.cxx + * + * A parse tree represented as Lisp s-expressions. + * + * Author(s) : Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de) + * + * Copyright (C) 2002. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +/* Derived from xml.cxx 1.1.2.2 */ + +char cvsroot_s_exp_cxx[] = "$Header$"; +static const char *usage = "\ +S-Exp Options (available with -sexp)\n\ + -typemaplang lang - Typemap language.\n\n"; + +#include "swigmod.h" + +//static Node *view_top = 0; +static File *out = 0; + +class Sexp : public Language { +public: + int indent_level; + Sexp() : indent_level( 0 ) {} + virtual ~Sexp() {} + virtual void main(int argc, char *argv[]) { + SWIG_typemap_lang("sexp"); + for( int iX = 0; iX < argc; iX++ ) + { + if( strcmp( argv[iX], "-typemaplang" ) == 0 ) + { + Swig_mark_arg (iX); + iX++; + SWIG_typemap_lang(argv[iX]); + Swig_mark_arg (iX); + continue; + } + if( strcmp( argv[iX], "-help" ) == 0 ) + { + fputs( usage, stderr ); + } + } + } + + DOHHash *print_circle_hash; + int print_circle_count; + int hanging_parens; + bool need_whitespace; + bool need_newline; + + /* Top of the parse tree */ + virtual int top(Node *n) + { + if( out == 0 ) + { + String *outfile = Getattr(n,"outfile"); + Replaceall(outfile,"_wrap.cxx", ".lisp"); + out = NewFile(outfile,"w"); + if (!out) + { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + } + Language::top(n); + Printf( out, ";;; Lisp parse tree produced by SWIG\n" ); + print_circle_hash = DohNewHash(); + print_circle_count = 0; + hanging_parens = 0; + need_whitespace = 0; + need_newline = 0; + Sexp_print_node(n); + flush_parens(); + return SWIG_OK; + } + + void print_indent() + { + int i; + for (i = 0; i < indent_level; i++) + { + Printf(out, " "); + } + } + + void open_paren(const String *oper) + { + flush_parens(); + Printf(out, "("); + if (oper) Printf(out, "%s ", oper); + indent_level += 2; + } + + void close_paren(bool need_newline = false) + { + hanging_parens++; + if (need_newline) + print_lazy_whitespace(); + indent_level -= 2; + } + + void flush_parens() + { + int i; + if (hanging_parens) { + for (i = 0; i", obj); + } + } + } + } + + void Sexp_print_as_keyword(const DOH *k) + { + /* Print key, replacing ":" with "-" because : is CL's package prefix */ + flush_parens(); + String *key = NewString(k); + Replaceall(key, ":", "-"); + Replaceall(key, "_", "-"); + Printf(out,":%s ", key); + Delete(key); + } + + void Sexp_print_plist_noparens(DOH *obj) + { + /* attributes map names to objects */ + String *k; + bool first; + for (k = Firstkey(obj), first = true; k; k = Nextkey(obj), first=false) { + if (!internal_key_p(k)) { + DOH *value = Getattr(obj, k); + flush_parens(); + if (!first) { + Printf(out, " "); + } + Sexp_print_as_keyword(k); + /* Print value */ + Sexp_print_value_of_key(value, k); + } + } + } + + void Sexp_print_plist(DOH *obj) + { + flush_parens(); + if (print_circle(obj, true)) { + open_paren(NIL); + Sexp_print_plist_noparens(obj); + close_paren(); + } + } + + void Sexp_print_attributes(Node * obj) + { + Sexp_print_plist_noparens(obj); + } + + void Sexp_print_node(Node *obj) + { + Node *cobj; + open_paren(nodeType(obj)); + /* A node has an attribute list... */ + Sexp_print_attributes(obj); + /* ... and child nodes. */ + cobj = firstChild(obj); + if (cobj) { + print_lazy_newline(); + flush_parens(); + Sexp_print_as_keyword("children"); + open_paren(NIL); + for (; cobj; cobj = nextSibling(cobj)) { + Sexp_print_node(cobj); + } + close_paren(); + } + close_paren(); + } + + + virtual int functionWrapper(Node *n) + { + ParmList *l = Getattr(n,"parms"); + Wrapper *f = NewWrapper(); + emit_attach_parmmaps(l,f); + Setattr(n,"wrap:parms",l); + return SWIG_OK; + } + +}; + + +extern "C" +{ + Language * swig_sexp( void ) + { + return new Sexp(); + } +} diff --git a/Source/Modules1.1/swig11.h b/Source/Modules1.1/swig11.h deleted file mode 100644 index cfc222861..000000000 --- a/Source/Modules1.1/swig11.h +++ /dev/null @@ -1,121 +0,0 @@ -/* ----------------------------------------------------------------------------- - * swig11.h - * - * Main header file for the SWIG1.1 core. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1998-2000. The University of Chicago - * Copyright (C) 1995-1998. The University of Utah and The Regents of the - * University of California. - * - * See the file LICENSE for information on usage and redistribution. - * - * $Header$ - * ----------------------------------------------------------------------------- */ - -#include -#include -#include - -#include "swigver.h" - -extern "C" { -#include "swig.h" -} - -/* Global variables. */ - -extern FILE *f_runtime; // Runtime code -extern DOH *f_header; // Headers -extern DOH *f_wrappers; // Wrappers -extern DOH *f_init; // Initialization code -extern FILE *f_input; -extern int CPlusPlus; // C++ mode -extern int AddMethods; // AddMethods mode -extern int NewObject; // NewObject mode -extern int NoInclude; // NoInclude flag -extern char output_dir[512]; // Output directory -extern int Verbose; -extern int ReadOnly; // Read only mode -extern int Native; // Native mode - -/* Miscellaneous stuff */ - -#define tab4 " " -#define tab8 " " - -// Modes for different types of inheritance - -#define INHERIT_FUNC 0x1 -#define INHERIT_VAR 0x2 -#define INHERIT_CONST 0x4 -#define INHERIT_ALL (INHERIT_FUNC | INHERIT_VAR | INHERIT_CONST) - -/* Language Class */ -class Language { -public: - virtual void parse_args(int argc, char *argv[]) = 0; - virtual void initialize(String *modname) = 0; - virtual void close(void) = 0; - virtual void import(String *modname); - - /* Basic function, variable, constant API (required) */ - virtual void function(DOH *node) = 0; - virtual void variable(DOH *node) = 0; - virtual void constant(DOH *node) = 0; - virtual void nativefunction(DOH *node); - virtual void create_command(String *cname, String *iname); - - /* Optional C++ handling */ - virtual void cpp_open_class(DOH *node); - virtual void cpp_memberfunction(DOH *node); - virtual void cpp_constructor(DOH *node); - virtual void cpp_destructor(DOH *node); - virtual void cpp_variable(DOH *node); - virtual void cpp_staticfunction(DOH *node); - virtual void cpp_constant(DOH *node); - virtual void cpp_staticvariable(DOH *node); - virtual void cpp_close_class(); - - virtual void cpp_class_decl(DOH *node); - virtual void cpp_inherit(List *bases); - - /* Miscellaneous features */ - - virtual void add_typedef(SwigType *t, String *name); - virtual void pragma(DOH *node); - -}; - -/* Emit functions */ - -extern void new_create_function(char *, char *, SwigType *, ParmList *); -extern void emit_set_get(DOH *node); -extern void emit_set_action(DOHString_or_char *decl); - -/* These are in the new core */ -extern "C" void *Preprocessor_define(void *, int); - -// Misc - -extern int emit_args(DOH *node, Wrapper *f); -extern void emit_func_call(DOH *node, Wrapper *f); -extern int check_numopt(ParmList *); -extern void SWIG_config_file(const String_or_char *); - -/* C++ utility functions */ -extern int cplus_check_abstract(DOH *node); -extern void cplus_walk_inherit(DOH *cls, void (*action)(DOH *base, void *clientdata), void *clientdata); - -extern Language *lang; - -/* swig11.h ends here */ - - - - - - - - diff --git a/Source/Modules1.1/swigmod.h b/Source/Modules1.1/swigmod.h new file mode 100644 index 000000000..2668b0cb5 --- /dev/null +++ b/Source/Modules1.1/swigmod.h @@ -0,0 +1,255 @@ +/* ----------------------------------------------------------------------------- + * swigmod.h + * + * Main header file for SWIG modules + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1998-2000. The University of Chicago + * Copyright (C) 1995-1998. The University of Utah and The Regents of the + * University of California. + * + * See the file LICENSE for information on usage and redistribution. + * + * $Header$ + * ----------------------------------------------------------------------------- */ + +#include +#include +#include + +#include "swigver.h" + +extern "C" { +#include "swig.h" +extern Hash *Preprocessor_define(const String_or_char *str, int swigmacro); +} + +#include "swigwarn.h" + +#define NOT_VIRTUAL 0 +#define PLAIN_VIRTUAL 1 +#define PURE_VIRTUAL 2 + +extern char *input_file; +extern int line_number; +extern int start_line; +extern int CPlusPlus; // C++ mode +extern int Extend; // Extend mode +extern int NoInclude; // NoInclude flag +extern int Verbose; +extern int IsVirtual; +extern int ImportMode; +extern int NoExcept; // -no_except option + +/* Miscellaneous stuff */ + +#define tab2 " " +#define tab4 " " +#define tab8 " " + +class Dispatcher { + public: + + virtual int emit_one(Node *n); + virtual int emit_children(Node *n); + virtual int defaultHandler(Node *n); + + /* Top of the parse tree */ + virtual int top(Node *n) = 0; + + /* SWIG directives */ + + virtual int applyDirective(Node *n); + virtual int clearDirective(Node *n); + virtual int constantDirective(Node *n); + virtual int extendDirective(Node *n); + virtual int fragmentDirective(Node *n); + virtual int importDirective(Node *n); + virtual int includeDirective(Node *n); + virtual int insertDirective(Node *n); + virtual int moduleDirective(Node *n); + virtual int nativeDirective(Node *n); + virtual int pragmaDirective(Node *n); + virtual int typemapDirective(Node *n); + virtual int typemapitemDirective(Node *n); + virtual int typemapcopyDirective(Node *n); + virtual int typesDirective(Node *n); + + /* C/C++ parsing */ + + virtual int cDeclaration(Node *n); + virtual int externDeclaration(Node *n); + virtual int enumDeclaration(Node *n); + virtual int enumvalueDeclaration(Node *n); + virtual int classDeclaration(Node *n); + virtual int classforwardDeclaration(Node *n); + virtual int constructorDeclaration(Node *n); + virtual int destructorDeclaration(Node *n); + virtual int accessDeclaration(Node *n); + virtual int usingDeclaration(Node *n); + virtual int namespaceDeclaration(Node *n); + virtual int templateDeclaration(Node *n); +}; + +/************************************************************************ + * class language: + * + * This class defines the functions that need to be supported by the + * scripting language being used. The translator calls these virtual + * functions to output different types of code for different languages. + *************************************************************************/ + +class Language : public Dispatcher { +public: + Language(); + virtual ~Language(); + virtual int emit_one(Node *n); + + /* Parse command line options */ + + virtual void main(int argc, char *argv[]); + + /* Top of the parse tree */ + + virtual int top(Node *n); + + /* SWIG directives */ + + + virtual int applyDirective(Node *n); + virtual int clearDirective(Node *n); + virtual int constantDirective(Node *n); + virtual int extendDirective(Node *n); + virtual int fragmentDirective(Node *n); + virtual int importDirective(Node *n); + virtual int includeDirective(Node *n); + virtual int insertDirective(Node *n); + virtual int moduleDirective(Node *n); + virtual int nativeDirective(Node *n); + virtual int pragmaDirective(Node *n); + virtual int typemapDirective(Node *n); + virtual int typemapcopyDirective(Node *n); + virtual int typesDirective(Node *n); + + /* C/C++ parsing */ + + virtual int cDeclaration(Node *n); + virtual int externDeclaration(Node *n); + virtual int enumDeclaration(Node *n); + virtual int enumvalueDeclaration(Node *n); + virtual int classDeclaration(Node *n); + virtual int classforwardDeclaration(Node *n); + virtual int constructorDeclaration(Node *n); + virtual int destructorDeclaration(Node *n); + virtual int accessDeclaration(Node *n); + virtual int namespaceDeclaration(Node *n); + virtual int usingDeclaration(Node *n); + + /* Function handlers */ + + virtual int functionHandler(Node *n); + virtual int globalfunctionHandler(Node *n); + virtual int memberfunctionHandler(Node *n); + virtual int staticmemberfunctionHandler(Node *n); + virtual int callbackfunctionHandler(Node *n); + + /* Variable handlers */ + + virtual int variableHandler(Node *n); + virtual int globalvariableHandler(Node *n); + virtual int membervariableHandler(Node *n); + virtual int staticmembervariableHandler(Node *n); + + /* C++ handlers */ + + virtual int memberconstantHandler(Node *n); + virtual int constructorHandler(Node *n); + virtual int copyconstructorHandler(Node *n); + virtual int destructorHandler(Node *n); + virtual int classHandler(Node *n); + + /* Miscellaneous */ + + virtual int typedefHandler(Node *n); + + /* Low-level code generation */ + + virtual int constantWrapper(Node *n); + virtual int variableWrapper(Node *n); + virtual int functionWrapper(Node *n); + virtual int nativeWrapper(Node *n); + + /* Miscellaneous */ + + virtual int validIdentifier(String *s); /* valid identifier? */ + virtual int addSymbol(String *s, Node *n); /* Add symbol */ + virtual Node *symbolLookup(String *s); /* Symbol lookup */ + virtual Node *classLookup(SwigType *s); /* Class lookup */ + + protected: + /* Patch C++ pass-by-value */ + static void patch_parms(Parm *p); + + /* Allow overloaded functions */ + void allow_overloading(int val = 1); + + /* Allow multiple-input typemaps */ + void allow_multiple_input(int val = 1); + + /* Wrapping class query */ + int is_wrapping_class(); + + /* Return the node for the current class */ + Node *getCurrentClass() const; + + /* Return the real name of the current class */ + String *getClassName() const; + + /* Return the current class prefix */ + String *getClassPrefix() const; + + /* Fully qualified type name to use */ + String *getClassType() const; + + private: + Hash *symbols; + Hash *classtypes; + int overloading; + int multiinput; +}; + +extern int SWIG_main(int, char **, Language *); +extern void emit_args(SwigType *, ParmList *, Wrapper *f); +extern void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */ +extern void SWIG_config_file(const String_or_char *); +extern void SWIG_config_cppext(const char *ext); + +extern "C" void SWIG_typemap_lang(const char *); +extern void SWIG_library_directory(const char *); +extern int emit_num_arguments(ParmList *); +extern int emit_num_required(ParmList *); +extern int emit_isvarargs(ParmList *); +extern void emit_attach_parmmaps(ParmList *, Wrapper *f); +extern void emit_action(Node *n, Wrapper *f); +extern List *Swig_overload_rank(Node *n); +extern String *Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *); + + +extern "C" { + typedef Language *(*ModuleFactory)(void); +} + +extern void Swig_register_module(const char *name, ModuleFactory fac); +extern ModuleFactory Swig_find_module(const char *name); + +/* swig11.h ends here */ + + + + + + + + + diff --git a/Source/Modules1.1/tcl8.cxx b/Source/Modules1.1/tcl8.cxx index 7f2913082..0f9738715 100644 --- a/Source/Modules1.1/tcl8.cxx +++ b/Source/Modules1.1/tcl8.cxx @@ -9,1112 +9,824 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_tcl8_cxx[] = "$Header$"; -#include "swig11.h" -#include "tcl8.h" -#include +#include "swigmod.h" -static char *usage = (char*)"\ -Tcl 8.0 Options (available with -tcl)\n\ - -module name - Set name of module\n\ +#ifndef MACSWIG +#include "swigconfig.h" +#endif + +static const char *usage = (char*)"\ +Tcl 8 Options (available with -tcl)\n\ + -ldflags - Print runtime libraries to link with\n\ -prefix name - Set a prefix to be appended to all names\n\ -namespace - Build module into a Tcl 8 namespace. \n\ - -noobject - Omit code for object oriented interface.\n\n"; - -static String *mod_init = 0; -static String *cmd_info = 0; -static String *var_info = 0; -static String *methods = 0; -static String *attributes = 0; + -pkgversion - Set package version.\n\n"; +static String *cmd_tab = 0; /* Table of command names */ +static String *var_tab = 0; /* Table of global variables */ +static String *const_tab = 0; /* Constant table */ +static String *methods_tab = 0; /* Methods table */ +static String *attr_tab = 0; /* Attribute table */ static String *prefix = 0; static String *module = 0; -static int nspace = 0; -static int shadow = 1; -static String *init_name = 0; -static String *ns_name = 0; -static int have_constructor; -static int have_destructor; +static int nspace = 0; +static String *init_name = 0; +static String *ns_name = 0; +static int have_constructor; +static int have_destructor; +static String *destructor_action = 0; +static String *version = (String *) "0.0"; +static String *class_name = 0; -static String *class_name = 0; -static String *class_type = 0; -static String *real_classname = 0; -static Hash *class_methods = 0; -static Hash *class_attributes = 0; -static Hash *repeatcmd = 0; +static File *f_header = 0; +static File *f_wrappers = 0; +static File *f_init = 0; +static File *f_runtime = 0; +class TCL8 : public Language { +public: + + /* ------------------------------------------------------------ + * TCL8::main() + * ------------------------------------------------------------ */ + + virtual void main(int argc, char *argv[]) { -/* ----------------------------------------------------------------------------- - * TCL8::parse_args() - * ----------------------------------------------------------------------------- */ - -void -TCL8::parse_args(int argc, char *argv[]) { - int i; - Swig_swiglib_set("tcl"); - - for (i = 1; i < argc; i++) { + SWIG_library_directory("tcl"); + + for (int i = 1; i < argc; i++) { if (argv[i]) { - if (strcmp(argv[i],"-prefix") == 0) { - if (argv[i+1]) { - prefix = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else Swig_arg_error(); - } else if (strcmp(argv[i],"-namespace") == 0) { - nspace = 1; + if (strcmp(argv[i],"-prefix") == 0) { + if (argv[i+1]) { + prefix = NewString(argv[i+1]); Swig_mark_arg(i); - } else if (strcmp(argv[i],"-noobject") == 0) { - shadow = 0; + Swig_mark_arg(i+1); + i++; + } else Swig_arg_error(); + } else if (strcmp(argv[i],"-pkgversion") == 0) { + if (argv[i+1]) { + version = NewString(argv[i+1]); Swig_mark_arg(i); - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); + Swig_mark_arg(i+1); + i++; } + } else if (strcmp(argv[i],"-namespace") == 0) { + nspace = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_TCL_RUNTIME); + SWIG_exit (EXIT_SUCCESS); + } } + } + Preprocessor_define("SWIGTCL 1",0); + Preprocessor_define("SWIGTCL8 1", 0); + SWIG_typemap_lang("tcl8"); + SWIG_config_file("tcl8.swg"); + allow_overloading(); } - if ((nspace) && module) { - ns_name = Copy(module); - } else if (prefix) { - ns_name = Copy(prefix); + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + virtual int top(Node *n) { + + /* Initialize all of the output files */ + String *outfile = Getattr(n,"outfile"); + + f_runtime = NewFile(outfile,"w"); + if (!f_runtime) { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header",f_header); + Swig_register_filebyname("wrapper",f_wrappers); + Swig_register_filebyname("runtime",f_runtime); + Swig_register_filebyname("init",f_init); + + /* Initialize some variables for the object interface */ + + cmd_tab = NewString(""); + var_tab = NewString(""); + methods_tab = NewString(""); + const_tab = NewString(""); + + Swig_banner(f_runtime); + + /* Include a Tcl configuration file */ + if (NoInclude) { + Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); + } + + /* Set the module name, namespace, and prefix */ + + module = NewStringf("%(lower)s", Getattr(n,"name")); + init_name = NewStringf("%(title)s_Init",module); + + ns_name = prefix ? Copy(prefix) : Copy(module); + if (prefix) Append(prefix,"_"); + + /* Generate some macros used throughout code generation */ + + Printf(f_header,"#define SWIG_init %s\n", init_name); + Printf(f_header,"#define SWIG_name \"%s\"\n", module); + if (nspace) { + Printf(f_header,"#define SWIG_prefix \"%s::\"\n", ns_name); + Printf(f_header,"#define SWIG_namespace \"%s\"\n\n", ns_name); + } else { + Printf(f_header,"#define SWIG_prefix \"%s\"\n", prefix); + } + Printf(f_header,"#define SWIG_version \"%s\"\n", version); + + Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n"); + Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n"); + Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n"); + + Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); + + /* Start emitting code */ + Language::top(n); + + /* Done. Close up the module */ + Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n",NIL); + Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n",NIL); + Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL); + + Printv(f_wrappers, cmd_tab, var_tab, const_tab,NIL); + + /* Dump the pointer equivalency table */ + SwigType_emit_type_table(f_runtime, f_wrappers); + + Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n"); + + /* Close the init function and quit */ + Printf(f_init,"return TCL_OK;\n}\n"); + + /* Close all of the files */ + Printv(f_runtime, f_header, f_wrappers,NIL); + Wrapper_pretty_print(f_init,f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_runtime); + return SWIG_OK; } - if (prefix) - Append(prefix,"_"); + + /* ------------------------------------------------------------ + * functionWrapper() + * ------------------------------------------------------------ */ - Preprocessor_define((void *) "SWIGTCL 1",0); - Preprocessor_define((void *) "SWIGTCL8 1", 0); - Swig_set_config_file("tcl8.swg"); -} + virtual int functionWrapper(Node *n) { + String *name = Getattr(n,"name"); /* Like to get rid of this */ + String *iname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + ParmList *parms = Getattr(n,"parms"); + String *overname = 0; -/* ----------------------------------------------------------------------------- - * TCL8::initialize() - * ----------------------------------------------------------------------------- */ + Parm *p; + int i; + String *tm; + Wrapper *f; + String *incode, *cleanup, *outarg, *argstr, *args; + int num_arguments = 0; + int num_required = 0; + int varargs = 0; + + char source[64]; + + if (Getattr(n,"sym:overloaded")) { + overname = Getattr(n,"sym:overname"); + } else { + if (!addSymbol(iname,n)) return SWIG_ERROR; + } + + incode = NewString(""); + cleanup = NewString(""); + outarg = NewString(""); + argstr = NewString("\""); + args = NewString(""); + + f = NewWrapper(); + String *wname = Swig_name_wrapper(iname); + if (overname) { + Append(wname, overname); + } + Setattr(n,"wrap:name",wname); -void -TCL8::initialize(String *modname) { + Printv(f->def, + "static int\n ", wname, "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", + NIL); + + /* Print out variables for storing arguments. */ + emit_args(type,parms, f); + + /* Attach standard typemaps */ + emit_attach_parmmaps(parms,f); + Setattr(n,"wrap:parms",parms); - mod_init = NewString(""); - cmd_info = NewString(""); - var_info = NewString(""); - repeatcmd = NewHash(); - class_methods = NewHash(); - class_attributes = NewHash(); + /* Get number of require and total arguments */ + num_arguments = emit_num_arguments(parms); + num_required = emit_num_required(parms); + varargs = emit_isvarargs(parms); + + /* Unmarshal parameters */ + + for (i = 0, p = parms; i < num_arguments; i++) { + /* Skip ignored arguments */ + + while (checkAttribute(p,"tmap:in:numinputs","0")) { + p = Getattr(p,"tmap:in:next"); + } + + SwigType *pt = Getattr(p,"type"); + String *ln = Getattr(p,"lname"); + + /* Produce string representations of the source and target arguments */ + sprintf(source,"objv[%d]",i+1); + + if (i == num_required) Putc('|',argstr); + if ((tm = Getattr(p,"tmap:in"))) { + String *parse = Getattr(p,"tmap:in:parse"); + if (!parse) { + Replaceall(tm,"$target",ln); + Replaceall(tm,"$source",source); + Replaceall(tm,"$input",source); + Setattr(p,"emit:input",source); - Swig_banner(f_runtime); - - /* Include a Tcl configuration file */ - if (NoInclude) { - Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); - } - if (Swig_insert_file("common.swg",f_runtime) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate 'common.swg' in SWIG library.\n"); - Swig_exit (EXIT_FAILURE); - } - if (Swig_insert_file("swigtcl8.swg",f_runtime) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate 'swigtcl8.swg' in SWIG library.\n"); - Swig_exit (EXIT_FAILURE); - } - if (!module) module = NewString(modname); - - /* Fix capitalization for Tcl */ - char *c = Char(module); - while (c && *c) { - *c = (char) tolower(*c); - c++; - } - /* Now create an initialization function */ - init_name = NewStringf("%s_Init",module); - c = Char(init_name); - *c = toupper(*c); - - if (!ns_name) ns_name = Copy(module); - - /* If namespaces have been specified, set the prefix to the module name */ - if ((nspace) && (!prefix)) { - prefix = NewStringf("%s_",module); - } else { - prefix = NewString(""); - } - - Printf(f_header,"#define SWIG_init %s\n", init_name); - if (!module) module = NewString("swig"); - Printf(f_header,"#define SWIG_name \"%s\"\n", module); - if (nspace) { - Printf(f_header,"#define SWIG_prefix \"%s::\"\n", ns_name); - Printf(f_header,"#define SWIG_namespace \"%s\"\n\n", ns_name); - } else { - Printf(f_header,"#define SWIG_prefix \"%s\"\n", prefix); - Printf(f_header,"#define SWIG_namespace \"\"\n\n"); - } - Printf(f_header,"#ifdef __cplusplus\n"); - Printf(f_header,"extern \"C\" {\n"); - Printf(f_header,"#endif\n"); - Printf(f_header,"#ifdef MAC_TCL\n"); - Printf(f_header,"#pragma export on\n"); - Printf(f_header,"#endif\n"); - Printf(f_header,"SWIGEXPORT(int) %s(Tcl_Interp *);\n", init_name); - Printf(f_header,"#ifdef MAC_TCL\n"); - Printf(f_header,"#pragma export off\n"); - Printf(f_header,"#endif\n"); - Printf(f_header,"#ifdef __cplusplus\n"); - Printf(f_header,"}\n"); - Printf(f_header,"#endif\n"); - - Printf(f_init,"SWIGEXPORT(int) %s(Tcl_Interp *interp) {\n", init_name); - Printf(f_init,"int i;\n"); - Printf(f_init,"if (interp == 0) return TCL_ERROR;\n"); - - /* Check to see if we're adding support for Tcl8 nspaces */ - if (nspace) { - Printf(f_init,"Tcl_Eval(interp,\"namespace eval %s { }\");\n", ns_name); - } - - Printf(cmd_info, "\nstatic swig_command_info swig_commands[] = {\n"); - Printf(var_info, "\nstatic swig_var_info swig_variables[] = {\n"); - Printv(f_init, - "for (i = 0; swig_types_initial[i]; i++) {\n", - "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", - "}\n", 0); -} - -/* ----------------------------------------------------------------------------- - * TCL8::close() - * ----------------------------------------------------------------------------- */ - -void -TCL8::close(void) { - - Printv(cmd_info, tab4, "{0, 0, 0}\n", "};\n",0); - Printv(var_info, tab4, "{0,0,0,0}\n", "};\n",0); - - Printf(f_wrappers,"%s", cmd_info); - Printf(f_wrappers,"%s", var_info); - - Printf(f_init,"for (i = 0; swig_commands[i].name; i++) {\n"); - Printf(f_init,"Tcl_CreateObjCommand(interp, (char *) swig_commands[i].name, swig_commands[i].wrapper, swig_commands[i].clientdata, NULL);\n"); - Printf(f_init,"}\n"); - - Printf(f_init,"for (i = 0; swig_variables[i].name; i++) {\n"); - Printf(f_init,"Tcl_SetVar(interp, (char *) swig_variables[i].name, \"\", TCL_GLOBAL_ONLY);\n"); - Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_READS | TCL_GLOBAL_ONLY, swig_variables[i].get, (ClientData) swig_variables[i].addr);\n"); - Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, swig_variables[i].set, (ClientData) swig_variables[i].addr);\n"); - Printf(f_init,"}\n"); - - /* Dump the pointer equivalency table */ - SwigType_emit_type_table(f_runtime, f_wrappers); - - /* Close the init function and quit */ - Printf(f_init,"return TCL_OK;\n"); - Printf(f_init,"}\n"); -} - -/* ----------------------------------------------------------------------------- - * TCL8::create_command() - * ----------------------------------------------------------------------------- */ - -void -TCL8::create_command(String *cname, String *iname) { - - String *wname = Swig_name_wrapper(cname); - Printv(cmd_info, tab4, "{ SWIG_prefix \"", iname, "\", ", wname, ", NULL},\n", 0); - - /* Add interpreter name to repeatcmd hash table. This hash is used in C++ code - generation to try and find repeated wrapper functions. */ - - Setattr(repeatcmd,iname,wname); -} - -/* ----------------------------------------------------------------------------- - * TCL8::create_function() - * ----------------------------------------------------------------------------- */ - -void -TCL8::function(DOH *node) { - char *name, *iname; - SwigType *d; - ParmList *l; - Parm *p; - int pcount,i,j; - char *tm; - Wrapper *f; - String *incode, *cleanup, *outarg, *argstr, *args; - int numopt= 0; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - d = Getattr(node,"type"); - l = Getattr(node,"parms"); - - incode = NewString(""); - cleanup = NewString(""); - outarg = NewString(""); - argstr = NewString("\""); - args = NewString(""); - - f = NewWrapper(); - Printv(f, - "static int\n ", Swig_name_wrapper(iname), "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {\n", - 0); - - /* Print out variables for storing arguments. */ - pcount = emit_args(node, f); - numopt = check_numopt(l); - - /* Extract parameters. */ - i = 0; - j = 0; - p = l; - while (p != 0) { - char source[64]; - char target[64]; - char argnum[64]; - SwigType *pt = Gettype(p); - String *pn = Getname(p); - - /* Produce string representations of the source and target arguments */ - sprintf(source,"objv[%d]",j+1); - sprintf(target,"%s", Char(Getlname(p))); - sprintf(argnum,"%d",j+1); - - /* See if this argument is being ignored */ - if (!Getignore(p)) { - if (j == (pcount-numopt)) Putc('|',argstr); - if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) { - Putc('o',argstr); - Printf(args,",0"); - Printf(incode,"%s\n", tm); - Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY); - Replace(incode,"$arg",source, DOH_REPLACE_ANY); - } else { - switch(SwigType_type(pt)) { - case T_INT: - case T_UINT: - Putc('i', argstr); - Printf(args,",&%s",target); - break; - - case T_BOOL: - Putc('i',argstr); - { - char tb[32]; - sprintf(tb,"tempb%d",i); - Wrapper_add_localv(f,tb,"int",tb,0); - Printf(args,",&%s",tb); - Printv(incode, target, " = (bool) ", tb, ";\n", 0); + if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) { + Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); + } else { + Replaceall(tm,"$disown","0"); } - break; - case T_SHORT: - case T_USHORT: - Putc('h',argstr); - Printf(args,",&%s",target); - break; - - case T_LONG: - case T_ULONG: - Putc('l',argstr); - Printf(args,",&%s",target); - break; - - case T_SCHAR: - case T_UCHAR: - Putc('b',argstr); - Printf(args,",&%s", target); - break; - - case T_FLOAT: - Putc('f',argstr); - Printf(args,",&%s", target); - break; - - case T_DOUBLE: - Putc('d',argstr); - Printf(args,",&%s", target); - break; - - case T_CHAR : - Putc('c',argstr); - Printf(args,",&%s",target); - break; - - case T_VOID : - break; - - case T_USER: - SwigType_add_pointer(pt); - SwigType_remember(pt); - Putc('p',argstr); - Printv(args, ",&", target, ", SWIGTYPE", SwigType_manglestr(pt), 0); - SwigType_del_pointer(pt); - break; - - case T_STRING: - Putc('s',argstr); - Printf(args,",&%s",target); - break; - - case T_POINTER: case T_ARRAY: case T_REFERENCE: - { - SwigType *lt; + Putc('o',argstr); + Printf(args,",0"); + if (i >= num_required) { + Printf(incode, "if (objc > %d) {\n", i+1); + } + Printf(incode,"%s\n", tm); + if (i >= num_required) { + Printf(incode, "}\n"); + } + } else { + Printf(argstr,"%s",parse); + Printf(args,",&%s",ln); + if (Strcmp(parse,"p") == 0) { + SwigType *lt = SwigType_ltype(pt); SwigType_remember(pt); - Putc('p',argstr); - lt = Swig_clocal_type(pt); if (Cmp(lt,"p.void") == 0) { - Printv(args, ",&", target, ", 0", 0); + Printf(args,",0"); } else { - Printv(args, ",&", target, ", SWIGTYPE", SwigType_manglestr(pt), 0); + Printf(args,",SWIGTYPE%s", SwigType_manglestr(pt)); } Delete(lt); - break; } - default : - Printf(stderr,"%s:%d: Unable to use type %s as a function argument.\n", - Getfile(node), Getline(node), SwigType_str(pt,0)); - break; } + p = Getattr(p,"tmap:in:next"); + continue; + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument.\n", SwigType_str(pt,0)); } - j++; + p = nextSibling(p); } - /* Check to see if there was any sort of a constaint typemap */ - if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) { - Printf(incode,"%s\n", tm); - Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY); - Replace(incode,"$arg",source, DOH_REPLACE_ANY); + + if (!varargs) { + Putc(':',argstr); + } else { + Putc(';',argstr); + /* If variable length arguments we need to emit the in typemap here */ + if (p && (tm = Getattr(p,"tmap:in"))) { + sprintf(source,"objv[%d]", i+1); + Printf(incode,"if (objc > %d) {\n", i); + Replaceall(tm,"$input",source); + Printv(incode,tm,"\n", NIL); + Printf(incode,"}\n"); + } } - /* Check if there was any cleanup code (save it for later) */ - if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,(char*)"tcl_result",0))) { - Printf(cleanup,"%s\n", tm); - Replace(cleanup,"$argnum",argnum, DOH_REPLACE_ANY); - Replace(cleanup,"$arg",source,DOH_REPLACE_ANY); + + Printf(argstr,"%s\"",usage_string(Char(iname),type,parms)); + + Printv(f->code, + "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", + NIL); + + Printv(f->code,incode,NIL); + + /* Insert constraint checking code */ + for (p = parms; p;) { + if ((tm = Getattr(p,"tmap:check"))) { + Replaceall(tm,"$target",Getattr(p,"lname")); + Printv(f->code,tm,"\n",NIL); + p = Getattr(p,"tmap:check:next"); + } else { + p = nextSibling(p); + } } - /* Look for output arguments */ - if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"tcl_result",0))) { - Printf(outarg,"%s\n", tm); - Replace(outarg,"$argnum",argnum, DOH_REPLACE_ANY); - Replace(outarg,"$arg",source, DOH_REPLACE_ANY); + + /* Insert cleanup code */ + for (i = 0, p = parms; p; i++) { + if ((tm = Getattr(p,"tmap:freearg"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Printv(cleanup,tm,"\n",NIL); + p = Getattr(p,"tmap:freearg:next"); + } else { + p = nextSibling(p); + } } - i++; - p = Getnext(p); + + /* Insert argument output code */ + for (i=0,p = parms; p;i++) { + if ((tm = Getattr(p,"tmap:argout"))) { + Replaceall(tm,"$source",Getattr(p,"lname")); + Replaceall(tm,"$target","(Tcl_GetObjResult(interp))"); + Replaceall(tm,"$result","(Tcl_GetObjResult(interp))"); + Replaceall(tm,"$arg",Getattr(p,"emit:input")); + Replaceall(tm,"$input",Getattr(p,"emit:input")); + Printv(outarg,tm,"\n",NIL); + p = Getattr(p,"tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + + /* Now write code to make the function call */ + emit_action(n,f); + + /* Need to redo all of this code (eventually) */ + + /* Return value if necessary */ + if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { + Replaceall(tm,"$source", "result"); + Replaceall(tm,"$target", "Tcl_GetObjResult(interp)"); + Replaceall(tm,"$result", "Tcl_GetObjResult(interp)"); + Printf(f->code,"%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s in function %s.\n", SwigType_str(type,0), name); + } + + /* Dump output argument code */ + Printv(f->code,outarg,NIL); + + /* Dump the argument cleanup code */ + Printv(f->code,cleanup,NIL); + + /* Look for any remaining cleanup */ + if (Getattr(n,"feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n", tm); + } + } + + if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) { + Replaceall(tm,"$source","result"); + Printf(f->code,"%s\n", tm); + } + Printv(f->code, "return TCL_OK;\n", NIL); + Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL); + Printv(f->code,"}\n", NIL); + + /* Substitute the cleanup code */ + Replaceall(f->code,"$cleanup",cleanup); + Replaceall(f->code,"$symname", iname); + + /* Dump out the function */ + Wrapper_print(f,f_wrappers); + + if (!Getattr(n,"sym:overloaded")) { + /* Register the function with Tcl */ + Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL); + } else { + if (!Getattr(n,"sym:nextSibling")) { + /* Emit overloading dispatch function */ + + int maxargs; + String *dispatch = Swig_overload_dispatch(n,"return %s(clientData, interp, objc, objv);",&maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *df = NewWrapper(); + String *dname = Swig_name_wrapper(iname); + + Printv(df->def, + "static int\n", dname, + "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", + NIL); + Printf(df->code,"Tcl_Obj *CONST *argv = objv+1;\n"); + Printf(df->code,"int argc = objc-1;\n"); + Printv(df->code,dispatch,"\n",NIL); + Printf(df->code,"Tcl_SetResult(interp,(char *) \"No matching function for overloaded '%s'\", TCL_STATIC);\n", iname); + Printf(df->code,"return TCL_ERROR;\n"); + Printv(df->code,"}\n",NIL); + Wrapper_print(df,f_wrappers); + Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL); + DelWrapper(df); + Delete(dispatch); + Delete(dname); + } + } + + Delete(incode); + Delete(cleanup); + Delete(outarg); + Delete(argstr); + Delete(args); + DelWrapper(f); + return SWIG_OK; } - Printf(argstr,":%s\"",usage_string(iname,d,l)); - Printv(f, - "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) return TCL_ERROR;\n", - 0); + /* ------------------------------------------------------------ + * variableWrapper() + * ------------------------------------------------------------ */ - Printv(f,incode,0); + virtual int variableWrapper(Node *n) { - /* Now write code to make the function call */ - emit_func_call(node,f); + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *t = Getattr(n,"type"); - /* Return value if necessary */ - if ((tm = Swig_typemap_lookup((char*)"out",d,name,(char*)"result",(char*)"tcl_result",0))) { - Printf(f,"%s\n", tm); - } else { - switch(SwigType_type(d)) { - case T_BOOL: - case T_INT: - case T_SHORT: - case T_LONG : - case T_SCHAR: - case T_UINT: - case T_USHORT: - case T_ULONG: - case T_UCHAR: - Printv(f, "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) result));\n",0); - break; + String *setname = 0; + String *getname = 0; + Wrapper *setf = 0, *getf = 0; + int readonly = 0; + String *tm; - /* Is a single character. We return it as a string */ - case T_CHAR : - Printv(f, "Tcl_SetObjResult(interp,Tcl_NewStringObj(&result,1));\n",0); - break; + if (!addSymbol(iname,n)) return SWIG_ERROR; - case T_DOUBLE : - case T_FLOAT : - Printv(f, "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));\n",0); - break; + /* Create a function for getting a variable */ + getf = NewWrapper(); + getname = Swig_name_wrapper(Swig_name_get(iname)); + Printv(getf->def,"static char *",getname,"(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",NIL); + Wrapper_add_local(getf,"value", "Tcl_Obj *value = 0"); - case T_USER : - - /* Okay. We're returning malloced memory at this point. - Probably dangerous, but safe programming is for wimps. */ - SwigType_add_pointer(d); - SwigType_remember(d); - Printv(f, "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) result,SWIGTYPE", - SwigType_manglestr(d), "));\n", 0); - - SwigType_del_pointer(d); - break; - - case T_STRING: - Printv(f, "Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1));\n",0); - break; - case T_POINTER: case T_REFERENCE: case T_ARRAY: - SwigType_remember(d); - Printv(f, "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) result,SWIGTYPE", - SwigType_manglestr(d), "));\n", - 0); - break; - - case T_VOID: - break; - - default : - Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n", - Getfile(node), Getline(node), SwigType_str(d,0), name); - break; + if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { + Replaceall(tm,"$source", name); + Replaceall(tm,"$target","value"); + Replaceall(tm,"$result", "value"); + Printf(getf->code, "%s\n",tm); + Printf(getf->code, "if (value) {\n"); + Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n"); + Printf(getf->code, "Tcl_DecrRefCount(value);\n"); + Printf(getf->code, "}\n"); + Printf(getf->code, "return NULL;\n"); + Printf(getf->code,"}\n"); + Wrapper_print(getf,f_wrappers); + } else { + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, + "Can't link to variable of type %s\n", SwigType_str(t,0)); + DelWrapper(getf); + return SWIG_NOWRAP; } - } + DelWrapper(getf); - /* Dump output argument code */ - Printv(f,outarg,0); + /* Try to create a function setting a variable */ + if (!Getattr(n,"feature:immutable")) { + setf = NewWrapper(); + setname = Swig_name_wrapper(Swig_name_set(iname)); + Printv(setf->def,"static char *",setname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",NIL); + Wrapper_add_local(setf,"value", "Tcl_Obj *value = 0"); + Wrapper_add_local(setf,"name1o", "Tcl_Obj *name1o = 0"); - /* Dump the argument cleanup code */ - Printv(f,cleanup,0); - - /* Look for any remaining cleanup */ - if (NewObject) { - if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) { - Printf(f,"%s\n", tm); - } - } - - if ((tm = Swig_typemap_lookup((char*)"ret",d,name,(char*)"result",(char*)"",0))) { - Printf(f,"%s\n", tm); - } - Printv(f, "return TCL_OK;\n}\n", 0); - - /* Substitute the cleanup code */ - Replace(f,"$cleanup",cleanup,DOH_REPLACE_ANY); - Replace(f,"$name", iname, DOH_REPLACE_ANY); - - /* Dump out the function */ - Printf(f_wrappers,"%s",f); - - /* Register the function with Tcl */ - Printv(cmd_info, tab4, "{ SWIG_prefix \"", iname, "\", ", Swig_name_wrapper(iname), ", NULL},\n", 0); - - Delete(incode); - Delete(cleanup); - Delete(outarg); - Delete(argstr); - Delete(args); - Delete(f); -} - -/* ----------------------------------------------------------------------------- - * TCL8::variable() - * ----------------------------------------------------------------------------- */ - -static Hash *setf = 0; -static Hash *getf = 0; - -void -TCL8::variable(DOH *node) { - char *name, *iname; - SwigType *t; - - String *setname; - String *getname; - - int isarray = 0; - int readonly = 0; - int setable = 1; - int tc; - - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - t = Getattr(node,"type"); - - if (!setf) setf = NewHash(); - if (!getf) getf = NewHash(); - - /* See if there were any typemaps */ - if (Swig_typemap_search((char *)"varin",t,name) || (Swig_typemap_search((char*)"varout",t,name))) { - Printf(stderr,"%s:%d. Warning. varin/varout typemap methods not supported.", - Getfile(node), Getline(node)); - } - - if (ReadOnly) readonly = 1; - isarray = SwigType_isarray(t); - tc = SwigType_type(t); - setname = Getattr(setf,t); - getname = Getattr(getf,t); - - /* Dump a collection of set/get functions suitable for variable tracing */ - if (!getname) { - Wrapper *get, *set; - - setname = NewStringf("swig_%s_set", Swig_string_mangle(t)); - getname = NewStringf("swig_%s_get", Swig_string_mangle(t)); - get = NewWrapper(); - set = NewWrapper(); - Printv(set, "static char *", setname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {\n",0); - Printv(get, "static char *", getname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {\n",0); - - SwigType *lt = Swig_clocal_type(t); - if ((tc != T_USER) && (!isarray)) - SwigType_add_pointer(lt); - Wrapper_add_localv(get,"addr",SwigType_lstr(lt,"addr"),0); - Wrapper_add_localv(set,"addr",SwigType_lstr(lt,"addr"),0); - Printv(set, "addr = (", SwigType_lstr(lt,0), ") clientData;\n", 0); - Printv(get, "addr = (", SwigType_lstr(lt,0), ") clientData;\n", 0); - if ((tc != T_USER) && (!isarray)) - SwigType_del_pointer(lt); - Delete(lt); - Wrapper_add_local(set, "value", "char *value"); - Wrapper_add_local(get, "value", "Tcl_Obj *value"); - - Printv(set, "value = Tcl_GetVar2(interp, name1, name2, flags);\n", - "if (!value) return NULL;\n", 0); - - switch(tc) { - case T_INT: - case T_SHORT: - case T_USHORT: - case T_LONG: - case T_UCHAR: - case T_SCHAR: - case T_BOOL: - Printv(set, "*(addr) = (", SwigType_str(t,0), ") atol(value);\n", 0); - Wrapper_add_local(get,"value","Tcl_Obj *value"); - Printv(get, - "value = Tcl_NewIntObj((int) *addr);\n", - "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n", - "Tcl_DecrRefCount(value);\n", - 0); - break; - - case T_UINT: - case T_ULONG: - Printv(set, "*(addr) = (", SwigType_str(t,0), ") strtoul(value,0,0);\n",0); - Wrapper_add_local(get,"value","Tcl_Obj *value"); - Printv(get, - "value = Tcl_NewIntObj((int) *addr);\n", - "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n", - "Tcl_DecrRefCount(value);\n", - 0); - break; - - case T_FLOAT: - case T_DOUBLE: - Printv(set, "*(addr) = (", SwigType_str(t,0), ") atof(value);\n",0); - Wrapper_add_local(get,"value","Tcl_Obj *value"); - Printv(get, - "value = Tcl_NewDoubleObj((double) *addr);\n", - "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n", - "Tcl_DecrRefCount(value);\n", - 0); - break; - - case T_CHAR: - Printv(set, "*(addr) = *value;\n",0); - Wrapper_add_local(get,"temp", "char temp[2]"); - Printv(get, "temp[0] = *addr; temp[1] = 0;\n", - "Tcl_SetVar2(interp,name1,name2,temp,flags);\n", - 0); - break; - - case T_USER: - /* User defined type. We return it as a pointer */ - SwigType_add_pointer(t); - SwigType_remember(t); - Printv(set, "{\n", - "void *ptr;\n", - "if (SWIG_ConvertPtrFromString(interp,value,&ptr,SWIGTYPE", SwigType_manglestr(t), ") != TCL_OK) {\n", - "return \"Type Error\";\n", - "}\n", - "*(addr) = *((", SwigType_lstr(t,0), ") ptr);\n", - "}\n", - 0); - - SwigType_del_pointer(t); - Wrapper_add_local(get,"value", "Tcl_Obj *value"); - SwigType_add_pointer(t); - SwigType_remember(t); - Printv(get, "value = SWIG_NewPointerObj(addr, SWIGTYPE", SwigType_manglestr(t), ");\n", - "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n", - "Tcl_DecrRefCount(value);\n",0); - SwigType_del_pointer(t); - - break; - - case T_STRING: - Printv(set, "if (*addr) free(*addr);\n", - "*addr = (char *) malloc(strlen(value)+1);\n", - "strcpy(*addr,value);\n", - 0); - Printv(get, "Tcl_SetVar2(interp,name1,name2,*addr, flags);\n",0); - break; - - case T_ARRAY: - { - SwigType *aop; - SwigType *ta = Copy(t); - aop = SwigType_pop(ta); - /* Printf(stdout,"'%s' '%s'\n", ta, aop);*/ - setable = 0; + if ((tm = Swig_typemap_lookup_new("varin", n, name, 0))) { + Replaceall(tm,"$source","value"); + Replaceall(tm,"$target",name); + Replaceall(tm,"$input", "value"); + Printf(setf->code,"name1o = Tcl_NewStringObj(name1,-1);\n"); + Printf(setf->code,"value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n"); + Printf(setf->code,"Tcl_DecrRefCount(name1o);\n"); + Printf(setf->code,"if (!value) return NULL;\n"); + Printf(setf->code,"%s\n", tm); + Printf(setf->code,"return NULL;\n"); + Printf(setf->code,"}\n"); + if (setf) Wrapper_print(setf,f_wrappers); + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF,input_file, line_number, + "Variable %s will be read-only without a varin typemap.\n", name); readonly = 1; - if (SwigType_type(ta) == T_CHAR) { - String *dim = SwigType_array_getdim(aop,0); - if (dim && Len(dim)) { - Printf(set, "strncpy(addr,value,%s);\n", dim); - setable = 1; - readonly = ReadOnly; - } - Printv(get, "Tcl_SetVar2(interp,name1,name2,addr, flags);\n",0); - } else { - Printf(stderr,"%s:%d: Array variable '%s' will be read-only.\n", Getfile(node), Getline(node), name); - Wrapper_add_local(get,"value","Tcl_Obj *value"); - SwigType_remember(t); - Printv(get, - "value = SWIG_NewPointerObj(addr, SWIGTYPE", SwigType_manglestr(t), ");\n", - "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n", - "Tcl_DecrRefCount(value);\n", - 0); - } - Delete(ta); - Delete(aop); } - break; + DelWrapper(setf); + } - case T_POINTER: case T_REFERENCE: - SwigType_remember(t); - Printv(set, "{\n", - "void *ptr;\n", - "if (SWIG_ConvertPtrFromString(interp,value,&ptr,SWIGTYPE", SwigType_manglestr(t), ") != TCL_OK) {\n", - "return \"Type Error\";\n", - "}\n", - "*(addr) = (", SwigType_lstr(t,0), ") ptr;\n", - "}\n", - 0); - - Wrapper_add_local(get,"value","Tcl_Obj *value"); - Printv(get, - "value = SWIG_NewPointerObj(*addr, SWIGTYPE", SwigType_manglestr(t), ");\n", - "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n", - "Tcl_DecrRefCount(value);\n", - 0); - - break; - case T_VOID: - break; - - default: - Printf(stderr,"TCL8::link_variable. Unknown type %s!\n", SwigType_str(t,0)); - break; + Printv(var_tab, tab4,"{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getname, ",", NIL); + if (readonly || Getattr(n,"feature:immutable")) { + static int readonlywrap = 0; + if (!readonlywrap) { + Wrapper *ro = NewWrapper(); + Printf(ro->def, "static const char *swig_readonly(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {"); + Printv(ro->code, "return (char*) \"Variable is read-only\";\n", "}\n", NIL); + Wrapper_print(ro,f_wrappers); + readonlywrap = 1; + DelWrapper(ro); + } + Printf(var_tab, "(swig_variable_func) swig_readonly},\n"); + } else { + Printv(var_tab, "(swig_variable_func) ", setname, "},\n",NIL); } - Printv(set, "return NULL;\n", "}\n",0); - Printv(get, "return NULL;\n", "}\n",0); - Printf(f_wrappers,"%s",get); - Setattr(getf,Copy(t),getname); - if (setable) { - Printf(f_wrappers,"%s",set); - Setattr(setf,Copy(t),setname); + Delete(setname); + Delete(getname); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + String *name = Getattr(n,"name"); + String *iname = Getattr(n,"sym:name"); + SwigType *type = Getattr(n,"type"); + String *value = Getattr(n,"value"); + String *tm; + + if (!addSymbol(iname,n)) return SWIG_ERROR; + + /* Special hook for member pointer */ + if (SwigType_type(type) == T_MPOINTER) { + String *wname = Swig_name_wrapper(iname); + Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type,wname), value); + value = Char(wname); } - Delete(get); - Delete(set); - } - Printv(var_info, tab4,"{ SWIG_prefix \"", iname, "\", (void *) ", isarray ? "" : "&", name, ",", getname, ",", 0); - - if (readonly) { - static int readonlywrap = 0; - if (!readonlywrap) { - Wrapper *ro = NewWrapper(); - Printf(ro, "static char *swig_readonly(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {\n"); - Printv(ro, "return \"Variable is read-only\";\n", "}\n", 0); - Printf(f_wrappers,"%s",ro); - readonlywrap = 1; - Delete(ro); + if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) { + Replaceall(tm,"$source",value); + Replaceall(tm,"$target",name); + Replaceall(tm,"$value",value); + Printf(const_tab,"%s,\n", tm); + } else if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { + Replaceall(tm,"$source", value); + Replaceall(tm,"$target", name); + Replaceall(tm,"$value",value); + Printf(f_init, "%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, + input_file, line_number, "Unsupported constant value.\n"); + return SWIG_NOWRAP; } - Printf(var_info, "swig_readonly},\n"); - } else { - Printv(var_info, setname, "},\n",0); + return SWIG_OK; } -} -/* ----------------------------------------------------------------------------- - * TCL8::constant() - * ----------------------------------------------------------------------------- */ + /* ------------------------------------------------------------ + * nativeWrapper() + * ------------------------------------------------------------ */ -void -TCL8::constant(DOH *node) { - char *name; - SwigType *type; - char *value; - int OldStatus = ReadOnly; - SwigType *t; - char var_name[256]; - char *tm; - String *rvalue; - ReadOnly = 1; - DOH *nnode; + virtual int nativeWrapper(Node *n) { + String *name = Getattr(n,"sym:name"); + String *funcname = Getattr(n,"wrap:name"); + if (!addSymbol(funcname,n)) return SWIG_ERROR; - name = GetChar(node,"name"); - type = Getattr(node,"type"); - value = GetChar(node,"value"); - nnode = Copy(node); - - /* Make a static variable */ - sprintf(var_name,"_wrap_const_%s",name); - - if (SwigType_type(type) == T_STRING) { - rvalue = NewStringf("\"%s\"",value); - } else if (SwigType_type(type) == T_CHAR) { - rvalue = NewStringf("\'%s\'",value); - } else { - rvalue = NewString(value); + Printf(f_init,"\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname); + return SWIG_OK; } - if ((tm = Swig_typemap_lookup((char*)"const",type,name,Char(rvalue),name,0))) { - Printf(f_init,"%s\n",tm); - } else { - /* Create variable and assign it a value */ - switch(SwigType_type(type)) { - case T_BOOL: case T_INT: case T_DOUBLE: - Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value); - Setattr(nnode,"name",var_name); - variable(nnode); - break; - case T_SHORT: - case T_LONG: - case T_SCHAR: - Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value); - Printf(f_header,"static char *%s_char;\n", var_name); - if (CPlusPlus) - Printf(f_init,"\t %s_char = new char[32];\n",var_name); - else - Printf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name); + /* ------------------------------------------------------------ + * classHandler() + * ------------------------------------------------------------ */ - Printf(f_init,"\t sprintf(%s_char,\"%%ld\", (long) %s);\n", var_name, var_name); - sprintf(var_name,"%s_char",var_name); - t = NewString("char"); - SwigType_add_pointer(t); - Setattr(nnode,"name",var_name); - Setattr(nnode,"type",t); - variable(nnode); - Delete(t); - break; + virtual int classHandler(Node *n) { + + String *mangled_classname = 0; + String *real_classname = 0; - case T_UINT: - case T_USHORT: - case T_ULONG: - case T_UCHAR: - Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value); - Printf(f_header,"static char *%s_char;\n", var_name); - if (CPlusPlus) - Printf(f_init,"\t %s_char = new char[32];\n",var_name); - else - Printf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name); + have_constructor = 0; + have_destructor = 0; + destructor_action = 0; - Printf(f_init,"\t sprintf(%s_char,\"%%lu\", (unsigned long) %s);\n", var_name, var_name); - sprintf(var_name,"%s_char",var_name); - t = NewSwigType(T_CHAR); - SwigType_add_pointer(t); - Setattr(nnode,"name",var_name); - Setattr(nnode,"type",t); - variable(nnode); - Delete(t); - break; + class_name = Getattr(n,"sym:name"); + if (!addSymbol(class_name,n)) return SWIG_ERROR; - case T_FLOAT: - Printf(f_header,"static %s %s = (%s) (%s);\n", SwigType_lstr(type,0), var_name, SwigType_lstr(type,0), value); - Setattr(nnode,"name",var_name); - variable(nnode); - break; + real_classname = Getattr(n,"name"); + mangled_classname = Swig_name_mangle(real_classname); - case T_CHAR: - SwigType_add_pointer(type); - Printf(f_header,"static %s %s = \"%s\";\n", SwigType_lstr(type,0), var_name, value); - Setattr(nnode,"name",var_name); - Setattr(nnode,"type",type); - variable(nnode); - SwigType_del_pointer(type); - break; + attr_tab = NewString(""); + Printf(attr_tab, "static swig_attribute swig_"); + Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL); + + methods_tab = NewStringf(""); + Printf(methods_tab,"static swig_method swig_"); + Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL); - case T_STRING: - Printf(f_header,"static %s %s = \"%s\";\n", SwigType_lstr(type,0), var_name, value); - Setattr(nnode,"name",var_name); - variable(nnode); - break; + /* Generate normal wrappers */ + Language::classHandler(n); - case T_POINTER: case T_ARRAY: case T_REFERENCE: - Printf(f_header,"static %s = %s;\n", SwigType_lstr(type,var_name), value); - Printf(f_header,"static char *%s_char;\n", var_name); - if (CPlusPlus) - Printf(f_init,"\t %s_char = new char[%d];\n",var_name,(int) Len(SwigType_manglestr(type))+ 20); - else - Printf(f_init,"\t %s_char = (char *) malloc(%d);\n",var_name, (int) Len(SwigType_manglestr(type))+ 20); + SwigType *t = Copy(Getattr(n,"name")); + SwigType_add_pointer(t); + + // Catch all: eg. a class with only static functions and/or variables will not have 'remembered' + // SwigType_remember(t); + String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname); + SwigType_remember_clientdata(t,wrap_class); - t = NewSwigType(T_CHAR); - SwigType_add_pointer(t); - SwigType_remember(type); - Printf(f_init,"\t SWIG_MakePtr(%s_char, (void *) %s, SWIGTYPE%s);\n", - var_name, var_name, SwigType_manglestr(type)); - sprintf(var_name,"%s_char",var_name); - Setattr(nnode,"type",t); - Setattr(nnode,"name",var_name); - variable(nnode); - Delete(t); - break; + // t = Copy(Getattr(n,"classtype")); + // SwigType_add_pointer(t); - default: - Printf(stderr,"%s:%d. Unsupported constant value.\n", Getfile(node), Getline(node)); - break; + String *rt = Copy(Getattr(n,"classtype")); + SwigType_add_pointer(rt); + + // Register the class structure with the type checker + /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */ + if (have_destructor) { + Printv(f_wrappers, "static void swig_delete_", class_name, "(void *obj) {\n", NIL); + if (destructor_action) { + Printv(f_wrappers, SwigType_str(rt,"arg1"), " = (", SwigType_str(rt,0), ") obj;\n", NIL); + Printv(f_wrappers, destructor_action, NIL); + } else { + if (CPlusPlus) { + Printv(f_wrappers," delete (", SwigType_str(rt,0), ") obj;\n",NIL); + } else { + Printv(f_wrappers," free((char *) obj);\n",NIL); + } + } + Printf(f_wrappers,"}\n"); + } + + Printf(methods_tab, " {0,0}\n};\n"); + Printv(f_wrappers,methods_tab,NIL); + + Printf(attr_tab, " {0,0,0}\n};\n"); + Printv(f_wrappers,attr_tab,NIL); + + /* Handle inheritance */ + + String *base_class = NewString(""); + List *baselist = Getattr(n,"bases"); + if (baselist && Len(baselist)) { + Node *base = Firstitem(baselist); + while (base) { + String *bname = Getattr(base, "name"); + if ((!bname) || Getattr(base,"feature:ignore") || (!Getattr(base,"module"))) { + base = Nextitem(baselist); + continue; + } + String *bmangle = Swig_name_mangle(bname); + Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); + Printf(base_class,"&_wrap_class_%s",bmangle); + base = Nextitem(baselist); + Putc(',',base_class); + Delete(bmangle); + } } - } - Delete(rvalue); - Delete(nnode); - ReadOnly = OldStatus; -} -/* ----------------------------------------------------------------------------- - * TCL8::usage_string() - * ----------------------------------------------------------------------------- */ + Printv(f_wrappers,"static swig_class *swig_",mangled_classname,"_bases[] = {", base_class,"0};\n", NIL); + Delete(base_class); -char * -TCL8::usage_string(char *iname, SwigType *, ParmList *l) { - static String *temp = 0; - Parm *p; - int i, numopt,pcount; - - if (!temp) temp = NewString(""); - Clear(temp); - if (nspace) { - Printf(temp,"%s::%s", ns_name,iname); - } else { - Printf(temp,"%s ", iname); + Printv(f_wrappers, "swig_class _wrap_class_", mangled_classname, " = { \"", class_name, + "\", &SWIGTYPE", SwigType_manglestr(t), ",",NIL); + + if (have_constructor) { + Printf(f_wrappers,"%s", Swig_name_wrapper(Swig_name_construct(class_name))); + } else { + Printf(f_wrappers,"0"); + } + if (have_destructor) { + Printv(f_wrappers, ", swig_delete_", class_name,NIL); + } else { + Printf(f_wrappers,",0"); + } + Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname,"_bases };\n", NIL); + Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL); + Delete(t); + Delete(mangled_classname); + return SWIG_OK; } - /* Now go through and print parameters */ - i = 0; - pcount = ParmList_len(l); - numopt = check_numopt(l); - for (p = l; p; p = Getnext(p)) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - /* Only print an argument if not ignored */ - if (!Swig_typemap_search((char*)"ignore",pt,pn)) { - if (i >= (pcount-numopt)) - Putc('?',temp); - /* If parameter has been named, use that. Otherwise, just print a type */ - if (SwigType_type(pt) != T_VOID) { + /* ------------------------------------------------------------ + * memberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int memberfunctionHandler(Node *n) { + String *name = Getattr(n,"name"); + String *iname = GetChar(n,"sym:name"); + + String *realname, *rname; + + Language::memberfunctionHandler(n); + + realname = iname ? iname : name; + rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); + if (!Getattr(n,"sym:nextSibling")) { + Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL); + } + Delete(rname); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * membervariableHandler() + * ------------------------------------------------------------ */ + + virtual int membervariableHandler(Node *n) { + String *symname = Getattr(n,"sym:name"); + String *rname; + + Language::membervariableHandler(n); + Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL); + rname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name,symname))); + Printv(attr_tab, rname, ", ", NIL); + Delete(rname); + if (!Getattr(n,"feature:immutable")) { + rname = Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name,symname))); + Printv(attr_tab, rname, "},\n",NIL); + Delete(rname); + } else { + Printf(attr_tab, "0 },\n"); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constructorHandler() + * ------------------------------------------------------------ */ + + virtual int constructorHandler(Node *n) { + Language::constructorHandler(n); + have_constructor = 1; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorHandler() + * ------------------------------------------------------------ */ + + virtual int destructorHandler(Node *n) { + Language::destructorHandler(n); + have_destructor = 1; + destructor_action = Getattr(n,"wrap:action"); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * validIdentifier() + * ------------------------------------------------------------ */ + + virtual int validIdentifier(String *s) { + if (Strchr(s,' ')) return 0; + return 1; + } + + /* ------------------------------------------------------------ + * usage_string() + * ------------------------------------------------------------ */ + + char * + usage_string(char *iname, SwigType *, ParmList *l) { + static String *temp = 0; + Parm *p; + int i, numopt,pcount; + + if (!temp) temp = NewString(""); + Clear(temp); + if (nspace) { + Printf(temp,"%s::%s", ns_name,iname); + } else { + Printf(temp,"%s ", iname); + } + /* Now go through and print parameters */ + i = 0; + pcount = ParmList_len(l); + numopt = 0; /*check_numopt(l); */ + for (p = l; p; p = nextSibling(p)) { + + SwigType *pt = Getattr(p,"type"); + String *pn = Getattr(p,"name"); + /* Only print an argument if not ignored */ + if (!checkAttribute(p,"tmap:in:numinputs","0")) { + if (i >= (pcount-numopt)) + Putc('?',temp); if (Len(pn) > 0) { Printf(temp, "%s",pn); } else { Printf(temp,"%s", SwigType_str(pt,0)); } + if (i >= (pcount-numopt)) Putc('?',temp); + Putc(' ',temp); + i++; } - if (i >= (pcount-numopt)) Putc('?',temp); - Putc(' ',temp); - i++; } + return Char(temp); } - return Char(temp); +}; + +/* ---------------------------------------------------------------------- + * swig_tcl() - Instantiate module + * ---------------------------------------------------------------------- */ + +extern "C" Language * +swig_tcl(void) { + return new TCL8(); } -/* ----------------------------------------------------------------------------- - * TCL8::nativefunction(); - * ----------------------------------------------------------------------------- */ -void -TCL8::nativefunction(DOH *node) { - char *name; - char *funcname; - name = GetChar(node,"scriptname"); - funcname = GetChar(node,"name"); - if ((Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,p.p.Tcl_Obj).int", node) == 0) || - (Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,a().p.Tcl_Obj).int", node) == 0)) { - Printf(f_init,"\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname); - } - - if ((Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,p.p.char).int", node) == 0) || - (Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,a().p.char).int", node) == 0)) { - Printf(f_init,"\t Tcl_CreateCommand(interp, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname); - } - -} - -/* ----------------------------------------------------------------------------- - * C++ Handling - * ----------------------------------------------------------------------------- */ - -void -TCL8::cpp_open_class(DOH *node) { - this->Language::cpp_open_class(node); - - char *classname = GetChar(node,"name"); - char *rename = GetChar(node,"scriptname"); - char *ctype = GetChar(node,"classtype"); - int strip = GetInt(node,"strip"); - - if (shadow) { - static int included_object = 0; - if (!included_object) { - if (Swig_insert_file("object.swg",f_header) == -1) { - Printf(stderr,"SWIG : Fatal error. Unable to locate 'object.swg' in SWIG library.\n"); - Swig_exit (EXIT_FAILURE); - } - included_object = 1; - } - - attributes = NewString(""); - /* Printf(attributes, "static swig_attribute swig_"); - Printv(attributes, classname, "_attributes[] = {\n", 0); */ - - methods = NewString(""); - /* Printf(methods,"static swig_method swig_"); - Printv(methods, classname, "_methods[] = {\n", 0); */ - - have_constructor = 0; - have_destructor = 0; - - Delete(class_name); - Delete(class_type); - Delete(real_classname); - - class_name = rename ? NewString(rename) : NewString(classname); - class_type = strip ? NewString("") : NewStringf("%s ",ctype); - real_classname = NewString(classname); - } -} - -void -TCL8::cpp_close_class() { - SwigType *t; - String *code = NewString(""); - - this->Language::cpp_close_class(); - if (shadow) { - t = NewStringf("%s%s", class_type, real_classname); - SwigType_add_pointer(t); - - if (have_destructor) { - Printv(code, "static void swig_delete_", class_name, "(void *obj) {\n", 0); - if (CPlusPlus) { - Printv(code," delete (", SwigType_str(t,0), ") obj;\n",0); - } else { - Printv(code," free((char *) obj);\n",0); - } - Printf(code,"}\n"); - } - - Printf(code,"static swig_method swig_"); - Printv(code, real_classname, "_methods[] = {\n", 0); - Printv(code,methods,0); - Printf(code, " {0,0}\n};\n"); - Setattr(class_methods,real_classname,methods); - - Printf(code, "static swig_attribute swig_"); - Printv(code, real_classname, "_attributes[] = {\n", 0); - Printv(code,attributes,0); - Printf(code, " {0,0,0}\n};\n"); - Setattr(class_attributes,real_classname,attributes); - - Printv(code, "static swig_class _wrap_class_", class_name, " = { \"", class_name, - "\", &SWIGTYPE", SwigType_manglestr(t), ",",0); - - if (have_constructor) { - Printf(code, "%s", Swig_name_wrapper(Swig_name_construct(class_name))); - } else { - Printf(code,"0"); - } - if (have_destructor) { - Printv(code, ", swig_delete_", class_name,0); - } else { - Printf(code,",0"); - } - Printv(code, ", swig_", real_classname, "_methods, swig_", real_classname, "_attributes };\n", 0); - Printf(f_wrappers,"%s",code); - - Printv(cmd_info, tab4, "{ SWIG_prefix \"", class_name, "\", SwigObjectCmd, &_wrap_class_", class_name, "},\n", 0); - } - Delete(code); -} - -void TCL8::cpp_memberfunction(DOH *node) { - char *name, *iname; - char *realname; - char temp[1024]; - String *rname; - - this->Language::cpp_memberfunction(node); - if (shadow) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - realname = iname ? iname : name; - /* Add stubs for this member to our class handler function */ - - strcpy(temp, Char(Swig_name_member(class_name,realname))); - rname = Getattr(repeatcmd,temp); - if (!rname) rname = Swig_name_wrapper(temp); - - Printv(methods, tab4, "{\"", realname, "\", ", rname, "}, \n", 0); - } -} - -void TCL8::cpp_variable(DOH *node) { - char *name, *iname; - char *realname; - char temp[1024]; - String *rname; - - this->Language::cpp_variable(node); - - if (shadow) { - name = GetChar(node,"name"); - iname = GetChar(node,"scriptname"); - realname = iname ? iname : name; - Printv(attributes, tab4, "{ \"-", realname, "\",", 0); - - /* Try to figure out if there is a wrapper for this function */ - strcpy(temp, Char(Swig_name_get(Swig_name_member(class_name,realname)))); - rname = Getattr(repeatcmd,temp); - if (!rname) rname = Swig_name_wrapper(temp); - Printv(attributes, rname, ", ", 0); - - if (!ReadOnly) { - strcpy(temp, Char(Swig_name_set(Swig_name_member(class_name,realname)))); - rname = Getattr(repeatcmd,temp); - if (!rname) rname = Swig_name_wrapper(temp); - Printv(attributes, rname, "},\n",0); - } else { - Printf(attributes, "0 },\n"); - } - } -} - -void -TCL8::cpp_constructor(DOH *node) { - this->Language::cpp_constructor(node); - have_constructor = 1; -} - -void -TCL8::cpp_destructor(DOH *node) { - this->Language::cpp_destructor(node); - have_destructor = 1; -} - -void -TCL8::cpp_inherit(List *bases) { - String *b; - Printf(stdout,"bases = %s\n", bases); - for (b = Firstitem(bases); b; b = Nextitem(bases)) { - Printf(stdout,"base: %s\n", b); - String *s = Getattr(class_methods,b); - if (s) { - Append(methods,s); - } - s = Getattr(class_attributes,b); - if (s) { - Append(attributes,s); - } - } -} diff --git a/Source/Modules1.1/tcl8.h b/Source/Modules1.1/tcl8.h deleted file mode 100644 index 4bafbab6e..000000000 --- a/Source/Modules1.1/tcl8.h +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - *******************************************************************************/ - -/************************************************************************** - * class TCL8 - * - * A TCL implementation for Tcl 8.0. Basically the same as the other - * Tcl module, but with different code generation. - **************************************************************************/ - -class TCL8 : public Language { -private: - char *usage_string(char *, SwigType *, ParmList *); - -public : - virtual void parse_args(int, char *argv[]); - virtual void initialize(String *); - virtual void function(DOH *node); - virtual void variable(DOH *node); - virtual void constant(DOH *node); - virtual void close(void); - virtual void nativefunction(DOH *); - virtual void create_command(String *, String *); - - // Stubs for processing C++ classes in Tcl - - virtual void cpp_open_class(DOH *node); - virtual void cpp_close_class(); - virtual void cpp_memberfunction(DOH *); - virtual void cpp_variable(DOH *); - virtual void cpp_constructor(DOH *); - virtual void cpp_destructor(DOH *); - virtual void cpp_inherit(List *bases); - -}; - - - - - - diff --git a/Source/Modules1.1/typepass.cxx b/Source/Modules1.1/typepass.cxx new file mode 100644 index 000000000..3e4f74338 --- /dev/null +++ b/Source/Modules1.1/typepass.cxx @@ -0,0 +1,966 @@ +/* ----------------------------------------------------------------------------- + * typepass.cxx + * + * This module builds all of the internal type information by collecting + * typedef declarations as well as registering classes, structures, and unions. + * This information is needed to correctly handle shadow classes and other + * advanced features. This phase of compilation is also used to perform + * type-expansion. All types are fully qualified with namespace prefixes + * and other information needed for compilation. + * + * This module also handles the %varargs directive by looking for + * "feature:varargs" and substituting ... with an alternative set of + * arguments. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1998-2002. The University of Chicago + * Copyright (C) 1995-1998. The University of Utah and The Regents of the + * University of California. + * + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_typepass_cxx[] = "$Header$"; + +#include "swigmod.h" + +struct normal_node { + Symtab *symtab; + Hash *typescope; + List *normallist; + normal_node *next; +}; + +static normal_node *patch_list = 0; + +class TypePass : public Dispatcher { + Node *inclass; + Node *module; + int importmode; + String *nsname; + Hash *classhash; + List *normalize; + + /* Normalize a type. Replaces type with fully qualified version */ + + void normalize_type(SwigType *ty) { + SwigType *qty; + /*qty = Swig_symbol_type_qualify(ty,0);*/ + /* if (SwigType_istemplate(ty)) { + qty = Swig_symbol_type_qualify(ty,0); + Clear(ty); + Append(ty,qty); + } + */ + + if (CPlusPlus) { + Replaceall(ty,"struct ",""); + Replaceall(ty,"union ",""); + Replaceall(ty,"class ",""); + } + + qty = SwigType_typedef_qualified(ty); + /* Printf(stdout,"%s --> %s\n", ty, qty);*/ + Clear(ty); + Append(ty,qty); + Delete(qty); + } + + /* Normalize a parameter list */ + + void normalize_parms(ParmList *p) { + while (p) { + SwigType *ty = Getattr(p,"type"); + normalize_type(ty); + String *value = Getattr(p,"value"); + if (value) { + Node *n = Swig_symbol_clookup(value,0); + if (n) { + String *q = Swig_symbol_qualified(n); + if (q && Len(q)) { + String *vb = Swig_scopename_last(value); + Clear(value); + Printf(value,"%s::%s", SwigType_namestr(q), vb); + Delete(q); + } + } + } + if (value && SwigType_istemplate(value)) { + String *nv = SwigType_namestr(value); + Setattr(p,"value",nv); + } + p = nextSibling(p); + } + } + + void normalize_later(ParmList *p) { + while (p) { + SwigType *ty = Getattr(p,"type"); + Append(normalize,ty); + p = nextSibling(p); + } + } + + /* Walk through entries in normalize list and patch them up */ + void normalize_list() { + Hash *currentsym = Swig_symbol_current(); + + normal_node *nn = patch_list; + normal_node *np; + while (nn) { + Swig_symbol_setscope(nn->symtab); + SwigType_set_scope(nn->typescope); + SwigType *t; + for (t = Firstitem(nn->normallist); t; t = Nextitem(nn->normallist)) { + normalize_type(t); + } + Delete(nn->normallist); + np = nn->next; + delete(nn); + nn = np; + } + Swig_symbol_setscope(currentsym); + } + + /* generate C++ inheritance type-relationships */ + void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) { + + if (first == cls) return; /* The Marcelo check */ + if (!cls) cls = first; + + List *ilist = Getattr(cls,"bases"); + if (!ilist) { + List *nlist = Getattr(cls,"baselist"); + if (nlist) { + int len = Len(nlist); + int i; + for (i = 0; i < len; i++) { + Node *bcls = 0; + int clsforward = 0; + String *bname = Getitem(nlist,i); + String *sname = bname; + String *tname = 0; + + /* Try to locate the base class. We look in the symbol table and we chase + typedef declarations to get to the base class if necessary */ + Symtab *st = Getattr(cls,"sym:symtab"); + + if (SwigType_istemplate(bname)) { + tname = SwigType_typedef_resolve_all(bname); + sname = tname; + } + while (1) { + String *qsname = SwigType_typedef_qualified(sname); + bcls = Swig_symbol_clookup(qsname,st); + Delete(qsname); + if (bcls) { + if (Strcmp(nodeType(bcls),"class") != 0) { + /* Not a class. The symbol could be a typedef. */ + if (checkAttribute(bcls,"storage","typedef")) { + SwigType *decl = Getattr(bcls,"decl"); + if (!decl || !(Len(decl))) { + sname = Getattr(bcls,"type"); + st = Getattr(bcls,"sym:symtab"); + if (SwigType_istemplate(sname)) { + if (tname) Delete(tname); + tname = SwigType_typedef_resolve_all(sname); + sname = tname; + } + continue; + } + } + if (Strcmp(nodeType(bcls),"classforward") != 0) { + Swig_error(Getfile(bname),Getline(bname),"'%s' is not a class. \n",bname); + } else { + Swig_warning(WARN_TYPE_INCOMPLETE,Getfile(bname),Getline(bname),"Base class '%s' is incomplete.\n", bname); + clsforward = 1; + } + bcls = 0; + } else { + if (Getattr(bcls,"typepass:visit")) { + if (!ilist) ilist = NewList(); + Append(ilist,bcls); + } else { + Swig_error(Getfile(bcls),Getline(bcls),"class '%s' must be defined before it is used as a base class.\n", bname); + } + } + } + break; + } + + if (tname) Delete(tname); + if (!bcls) { + if (!clsforward) { + if (!Getmeta(bname,"already_warned")) { + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname),Getline(bname),"Nothing known about class '%s'. Ignored.\n", SwigType_namestr(bname)); + if (Strchr(bname,'<')) { + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname)); + } + Setmeta(bname,"already_warned","1"); + } + } + SwigType_inherit(clsname,bname, cast); + } + } + } + if (ilist) { + Setattr(cls,"bases",ilist); + } + } + if (!ilist) return; + int len = Len(ilist); + int i; + for (i = 0; i < len; i++) { + Node *n = Getitem(ilist,i); + String *bname = Getattr(n,"name"); + Node *bclass = n; /* Getattr(n,"class"); */ + Hash *scopes = Getattr(bclass,"typescope"); + SwigType_inherit(clsname,bname, cast); + if (!importmode) { + String *btype = Copy(bname); + SwigType_add_pointer(btype); + SwigType_remember(btype); + Delete(btype); + } + if (scopes) { + SwigType_inherit_scope(scopes); + } + /* Set up inheritance in the symbol table */ + Symtab *s = Swig_symbol_current(); + Symtab *st = Getattr(cls,"symtab"); + Swig_symbol_setscope(st); + Swig_symbol_inherit(Getattr(bclass,"symtab")); + Swig_symbol_setscope(s); + + /* Recursively hit base classes */ + String *newcast = NewStringf("(%s *)%s", SwigType_namestr(Getattr(bclass,"name")), cast); + cplus_inherit_types(first,bclass,clsname, newcast); + Delete(newcast); + } + } + + /* Clean overloaded list. Removes templates, friends, ignored, and errors */ + + void clean_overloaded(Node *n) { + Node *nn = Getattr(n,"sym:overloaded"); + Node *first = 0; + int cnt = 0; + while (nn) { + if ((Strcmp(nodeType(nn),"template") == 0) || + (Getattr(nn,"feature:ignore")) || + (Getattr(nn,"error")) || + ((Strcmp(nodeType(nn),"using") == 0) && !firstChild(nn)) || + (checkAttribute(nn,"storage","friend"))) { + /* Remove from overloaded list */ + Node *ps = Getattr(nn,"sym:previousSibling"); + Node *ns = Getattr(nn,"sym:nextSibling"); + if (ps) { + Setattr(ps,"sym:nextSibling",ns); + } + if (ns) { + Setattr(ns,"sym:previousSibling",ps); + } + Delattr(nn,"sym:previousSibling"); + Delattr(nn,"sym:nextSibling"); + Delattr(nn,"sym:overloaded"); + nn = ns; + continue; + } else if ((Strcmp(nodeType(nn),"using") == 0)) { + /* A possibly dangerous parse tree hack. We're going to + cut the parse tree node out and stick in the resolved + using declarations */ + + Node *ps = Getattr(nn,"sym:previousSibling"); + Node *ns = Getattr(nn,"sym:nextSibling"); + Node *un = firstChild(nn); + Node *pn = un; + + if (!first) { + first = un; + } + while (pn) { + Node *ppn = Getattr(pn,"sym:nextSibling"); + Setattr(pn,"sym:overloaded",first); + Setattr(pn,"sym:overname", NewStringf("%s_%d", Getattr(nn,"sym:overname"), cnt++)); + if (ppn) pn = ppn; + else break; + } + if (ps) { + Setattr(ps,"sym:nextSibling",un); + Setattr(un,"sym:previousSibling",ps); + } + if (ns) { + Setattr(ns,"sym:previousSibling", pn); + Setattr(pn,"sym:nextSibling",ns); + } + if (!first) { + first = un; + Setattr(nn,"sym:overloaded",first); + } + } else { + if (!first) first = nn; + Setattr(nn,"sym:overloaded",first); + } + nn = Getattr(nn,"sym:nextSibling"); + } + if (!first || (first && !Getattr(first,"sym:nextSibling"))) { + Delattr(n,"sym:overloaded"); + } + } + +public: + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + importmode = 0; + module = Getattr(n,"module"); + inclass = 0; + normalize = 0; + nsname = 0; + classhash = Getattr(n,"classes"); + emit_children(n); + normalize_list(); + SwigType_set_scope(0); + return SWIG_OK; + } + + + /* ------------------------------------------------------------ + * moduleDirective() + * ------------------------------------------------------------ */ + + virtual int moduleDirective(Node *n) { + if (!module) { + module = n; + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * importDirective() + * ------------------------------------------------------------ */ + + virtual int importDirective(Node *n) { + String *oldmodule = module; + int oldimport = importmode; + importmode = 1; + module = 0; + emit_children(n); + importmode = oldimport; + module = oldmodule; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * includeDirective() + * externDirective() + * extendDirective() + * ------------------------------------------------------------ */ + + virtual int includeDirective(Node *n) { return emit_children(n); } + virtual int externDeclaration(Node *n) { return emit_children(n); } + virtual int extendDirective(Node *n) { return emit_children(n); } + + /* ------------------------------------------------------------ + * classDeclaration() + * ------------------------------------------------------------ */ + + virtual int classDeclaration(Node *n) { + String *name = Getattr(n,"name"); + String *tdname = Getattr(n,"tdname"); + String *unnamed = Getattr(n,"unnamed"); + String *storage = Getattr(n,"storage"); + String *kind = Getattr(n,"kind"); + Node *oldinclass = inclass; + List *olist = normalize; + Symtab *symtab; + String *nname = 0; + String *fname = 0; + String *scopename = 0; + + normalize = NewList(); + + if (name) { + + if (SwigType_istemplate(name)) { + // We need to fully resolve the name to make templates work correctly */ + Node *cn; + fname = SwigType_typedef_resolve_all(name); + if (Strcmp(fname,name) != 0) { + cn = Swig_symbol_clookup_local(fname,0); + if ((!cn) || (Strcmp(nodeType(cn),"template") == 0)) { + Swig_symbol_cadd(fname,n); + SwigType_typedef_class(fname); + scopename = Copy(fname); + } else { + Swig_warning(WARN_TYPE_REDEFINED,Getfile(n),Getline(n),"Template '%s' was already wrapped as '%s' at %s:%d.\n", + SwigType_namestr(name), SwigType_namestr(Getattr(cn,"name")), Getfile(cn), Getline(cn)); + scopename = 0; + } + } else { + Swig_symbol_cadd(fname,n); + SwigType_typedef_class(fname); + scopename = Copy(fname); + } + } else { + if ((CPlusPlus) || (unnamed)) { + SwigType_typedef_class(name); + } else { + SwigType_typedef_class(NewStringf("%s %s", kind, name)); + } + scopename = Copy(name); + } + } else { + scopename = 0; + } + + Setattr(n,"typepass:visit","1"); + + /* Need to set up a typedef if unnamed */ + if (unnamed && tdname && (Cmp(storage,"typedef") == 0)) { + SwigType_typedef(unnamed,tdname); + } + + if (nsname) { + nname = NewStringf("%s::%s", nsname, name); + } + SwigType_new_scope(scopename); + SwigType_attach_symtab(Getattr(n,"symtab")); + + /* Inherit type definitions into the class */ + if (name) { + cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name)); + } + + inclass = n; + symtab = Swig_symbol_setscope(Getattr(n,"symtab")); + emit_children(n); + Swig_symbol_setscope(symtab); + + Hash *ts = SwigType_pop_scope(); + Setattr(n,"typescope",ts); + Setattr(n,"module",module); + + /* Normalize deferred types */ + { + normal_node *nn = new normal_node(); + nn->normallist = normalize; + nn->symtab = Getattr(n,"symtab"); + nn->next = patch_list; + nn->typescope = Getattr(n,"typescope"); + patch_list = nn; + } + + normalize = olist; + + inclass = oldinclass; + + /* If in a namespace, patch the class name */ + if (nname) { + Setattr(n,"name",nname); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * namespaceDeclaration() + * ------------------------------------------------------------ */ + + virtual int templateDeclaration(Node *n) { + String *name = Getattr(n,"name"); + String *ttype = Getattr(n,"templatetype"); + if (Strcmp(ttype,"class") == 0) { + String *rname = SwigType_typedef_resolve_all(name); + SwigType_typedef_class(rname); + Delete(rname); + } else if (Strcmp(ttype,"classforward") == 0) { + String *rname = SwigType_typedef_resolve_all(name); + SwigType_typedef_class(rname); + Delete(rname); + /* SwigType_typedef_class(name);*/ + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * classforwardDeclaration() + * ------------------------------------------------------------ */ + + virtual int classforwardDeclaration(Node *n) { + + /* Temporary hack. Can't do inside a class because it breaks + C nested structure wrapping */ + + if ((!inclass) || (CPlusPlus)) { + String *name = Getattr(n,"name"); + String *nname; + SwigType_typedef_class(name); + if (nsname) { + nname = NewStringf("%s::%s", nsname, name); + Setattr(n,"name",nname); + } + + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * namespaceDeclaration() + * ------------------------------------------------------------ */ + + virtual int namespaceDeclaration(Node *n) { + Symtab *symtab; + String *name = Getattr(n,"name"); + String *alias = Getattr(n,"alias"); + List *olist = normalize; + normalize = NewList(); + if (alias) { + Typetab *ts = Getattr(n,"typescope"); + if (!ts) { + Node *ns; + /* Create a empty scope for the alias */ + ns = Getattr(n,"namespace"); + if (ns) { + SwigType_scope_alias(name, Getattr(ns,"typescope")); + } + ts = Getattr(ns,"typescope"); + Setattr(n,"typescope",ts); + } + /* Namespace alias */ + return SWIG_OK; + } else { + if (name) { + Node *nn = Swig_symbol_clookup(name,n); + Hash *ts = Getattr(nn,"typescope"); + if (!ts) { + SwigType_new_scope(name); + SwigType_attach_symtab(Getattr(n,"symtab")); + } else { + SwigType_set_scope(ts); + } + } + String *oldnsname = nsname; + nsname = Swig_symbol_qualified(Getattr(n,"symtab")); + symtab = Swig_symbol_setscope(Getattr(n,"symtab")); + emit_children(n); + Swig_symbol_setscope(symtab); + + if (name) { + Hash *ts = SwigType_pop_scope(); + Setattr(n,"typescope",ts); + } + + /* Normalize deferred types */ + { + normal_node *nn = new normal_node(); + nn->normallist = normalize; + nn->symtab = Getattr(n,"symtab"); + nn->next = patch_list; + nn->typescope = Getattr(n,"typescope"); + patch_list = nn; + } + normalize = olist; + + Delete(nsname); + nsname = oldnsname; + return SWIG_OK; + } + } + + /* ------------------------------------------------------------ + * cDeclaration() + * ------------------------------------------------------------ */ + + virtual int cDeclaration(Node *n) { + + if (NoExcept) { + Delattr(n,"throws"); + } + + /* Search for var args */ + if (Getattr(n,"feature:varargs")) { + ParmList *v = Getattr(n,"feature:varargs"); + Parm *p = Getattr(n,"parms"); + Parm *pp = 0; + while (p) { + SwigType *t = Getattr(p,"type"); + if (Strcmp(t,"v(...)") == 0) { + if (pp) { + set_nextSibling(pp,Copy(v)); + } else { + Setattr(n,"parms", Copy(v)); + } + break; + } + pp = p; + p = nextSibling(p); + } + } + + /* Normalize types. */ + SwigType *ty = Getattr(n,"type"); + normalize_type(ty); + SwigType *decl = Getattr(n,"decl"); + if (decl) { + normalize_type(decl); + } + normalize_parms(Getattr(n,"parms")); + normalize_parms(Getattr(n,"throws")); + + if (checkAttribute(n,"storage","typedef")) { + String *name = Getattr(n,"name"); + ty = Getattr(n,"type"); + decl = Getattr(n,"decl"); + SwigType *t = Copy(ty); + { + /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */ + if (Swig_scopename_check(t)) { + String *base, *prefix, *qprefix; + base = Swig_scopename_last(t); + prefix = Swig_scopename_prefix(t); + qprefix = SwigType_typedef_qualified(prefix); + Delete(t); + t = NewStringf("%s::%s", qprefix,base); + Delete(base); + Delete(prefix); + Delete(qprefix); + } + } + SwigType_push(t,decl); + if (CPlusPlus) { + Replaceall(t,"struct ",""); + Replaceall(t,"union ",""); + Replaceall(t,"class ",""); + } + SwigType_typedef(t,name); + } + /* If namespaces are active. We need to patch the name with a namespace prefix */ + if (nsname && !inclass) { + String *name = Getattr(n,"name"); + if (name) { + String *nname = NewStringf("%s::%s", nsname, name); + Setattr(n,"name", nname); + Delete(nname); + } + } + clean_overloaded(n); + return SWIG_OK; + } + + + /* ------------------------------------------------------------ + * constructorDeclaration() + * ------------------------------------------------------------ */ + + virtual int constructorDeclaration(Node *n) { + if (NoExcept) { + Delattr(n,"throws"); + } + + /* Search for var args */ + if (Getattr(n,"feature:varargs")) { + ParmList *v = Getattr(n,"feature:varargs"); + Parm *p = Getattr(n,"parms"); + Parm *pp = 0; + while (p) { + SwigType *t = Getattr(p,"type"); + if (Strcmp(t,"v(...)") == 0) { + if (pp) { + set_nextSibling(pp,Copy(v)); + } else { + Setattr(n,"parms", Copy(v)); + } + break; + } + pp = p; + p = nextSibling(p); + } + } + normalize_parms(Getattr(n,"parms")); + normalize_parms(Getattr(n,"throws")); + + /* If in a namespace, patch the class name */ + if (nsname) { + String *nname = NewStringf("%s::%s", nsname, Getattr(n,"name")); + Setattr(n,"name",nname); + } + clean_overloaded(n); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorDeclaration() + * ------------------------------------------------------------ */ + + virtual int destructorDeclaration(Node *n) { + /* If in a namespace, patch the class name */ + if (nsname) { + String *nname = NewStringf("%s::%s", nsname, Getattr(n,"name")); + Setattr(n,"name",nname); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constantDirective() + * ------------------------------------------------------------ */ + + virtual int constantDirective(Node *n) { + SwigType *ty = Getattr(n,"type"); + if (ty) { + Setattr(n,"type",SwigType_typedef_qualified(ty)); + } + return SWIG_OK; + } + + + /* ------------------------------------------------------------ + * enumDeclaration() + * ------------------------------------------------------------ */ + + virtual int enumDeclaration(Node *n) { + String *name = Getattr(n,"name"); + if (name) { + SwigType *t = NewStringf("enum %s", name); + SwigType_typedef(t,name); + Delete(t); + } + emit_children(n); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * enumvalueDeclaration() + * ------------------------------------------------------------ */ + + virtual int enumvalueDeclaration(Node *n) { + String *name = Getattr(n,"name"); + String *value = Getattr(n,"value"); + if (!value) value = name; + if (Strcmp(value,name) == 0) { + String *new_value; + if ((nsname) || (inclass)) { + new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); + } else { + new_value = NewString(value); + } + Setattr(n,"value",new_value); + Delete(new_value); + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * usingDeclaration() + * ------------------------------------------------------------ */ + + virtual int usingDeclaration(Node *n) { + if (Getattr(n,"namespace")) { + /* using namespace id */ + + /* For a namespace import. We set up inheritance in the type system */ + Node *ns = Getattr(n,"node"); + if (ns) { + Typetab *ts = Getattr(ns,"typescope"); + if (ts) { + SwigType_using_scope(ts); + } + } + return SWIG_OK; + } else { + Node *ns; + /* using id */ + + if (Getattr(n,"sym:symtab")) { + ns = Swig_symbol_clookup(Getattr(n,"uname"), Getattr(n,"sym:symtab")); + } else { + ns = 0; + } + if (!ns) { + if (!Getattr(n,"access") || ((Strcmp(Getattr(n,"access"),"public") == 0))) { + Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n,"uname"))); + } + } else { + + /* Only a single symbol is being used. There are only a few symbols that + we actually care about. These are typedef, class declarations, and enum */ + + String *ntype = nodeType(ns); + if (Strcmp(ntype,"cdecl") == 0) { + if (checkAttribute(ns,"storage","typedef")) { + /* A typedef declaration */ + String *uname = Getattr(n,"uname"); + SwigType_typedef_using(uname); + } else { + /* A normal C declaration. */ + if ((inclass) && (!Getattr(n,"feature:ignore")) && (Getattr(n,"sym:name"))) { + Node *c = ns; + Node *unodes = 0, *last_unodes = 0; + int ccount = 0; + String *symname = Getattr(n,"sym:name"); + while (c) { + if (Strcmp(nodeType(c),"cdecl") == 0) { + if (!(checkAttribute(c,"storage","static") + || checkAttribute(c,"storage","typedef") + || checkAttribute(c,"storage","friend") + || (Getattr(c,"feature:extend") && !Getattr(c,"code")) + || Getattr(c,"feature:ignore"))) { + + String *csymname = Getattr(c,"sym:name"); + if (!csymname || (Strcmp(csymname,symname) == 0)) { + /* Check for existence in overload list already */ + { + String *decl = Getattr(c,"decl"); + Node *over = Getattr(n,"sym:overloaded"); + int match = 0; + while (over) { + String *odecl = Getattr(over,"decl"); + if (Cmp(decl, odecl) == 0) { + match = 1; + break; + } + over = Getattr(over,"sym:nextSibling"); + } + if (match) { + c = Getattr(c,"csym:nextSibling"); + continue; + } + } + Node *nn = copyNode(c); + if (!Getattr(nn,"sym:name")) Setattr(nn,"sym:name", symname); + + if (!Getattr(nn,"feature:ignore")) { + Setattr(nn,"parms",CopyParmList(Getattr(c,"parms"))); + ccount++; + if (!last_unodes) { + last_unodes = nn; + unodes = nn; + } else { + Setattr(nn,"previousSibling",last_unodes); + Setattr(last_unodes,"nextSibling", nn); + Setattr(nn,"sym:previousSibling", last_unodes); + Setattr(last_unodes,"sym:nextSibling", nn); + Setattr(nn,"sym:overloaded", unodes); + Setattr(unodes,"sym:overloaded", unodes); + last_unodes = nn; + } + } else { + Delete(nn); + } + } + } + } + c = Getattr(c,"csym:nextSibling"); + } + if (unodes) { + set_firstChild(n,unodes); + if (ccount > 1) { + if (!Getattr(n,"sym:overloaded")) { + Setattr(n,"sym:overloaded",n); + Setattr(n,"sym:overname","_SWIG_0"); + } + } + } + } + } + } else if ((Strcmp(ntype,"class") == 0) || ((Strcmp(ntype,"classforward") == 0))) { + /* We install the using class name as kind of a typedef back to the original class */ + String *uname = Getattr(n,"uname"); + /* Import into current type scope */ + SwigType_typedef_using(uname); + } else if (Strcmp(ntype,"enum") == 0) { + SwigType_typedef_using(Getattr(n,"uname")); + } + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * typemapDirective() + * ------------------------------------------------------------ */ + + virtual int typemapDirective(Node *n) { + if (inclass || nsname) { + Node *items = firstChild(n); + while (items) { + Parm *pattern = Getattr(items,"pattern"); + Parm *parms = Getattr(items,"parms"); + normalize_later(pattern); + normalize_later(parms); + items = nextSibling(items); + } + } + return SWIG_OK; + } + + + /* ------------------------------------------------------------ + * typemapcopyDirective() + * ------------------------------------------------------------ */ + + virtual int typemapcopyDirective(Node *n) { + if (inclass || nsname) { + Node *items = firstChild(n); + ParmList *pattern = Getattr(n,"pattern"); + normalize_later(pattern); + while (items) { + ParmList *npattern = Getattr(items,"pattern"); + normalize_later(npattern); + items = nextSibling(items); + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * applyDirective() + * ------------------------------------------------------------ */ + + virtual int applyDirective(Node *n) { + if (inclass || nsname) { + ParmList *pattern = Getattr(n,"pattern"); + normalize_later(pattern); + Node *items = firstChild(n); + while (items) { + Parm *apattern = Getattr(items,"pattern"); + normalize_later(apattern); + items = nextSibling(items); + } + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * clearDirective() + * ------------------------------------------------------------ */ + + virtual int clearDirective(Node *n) { + if (inclass || nsname) { + Node *p; + for (p = firstChild(n); p; p = nextSibling(p)) { + ParmList *pattern = Getattr(p,"pattern"); + normalize_later(pattern); + } + } + return SWIG_OK; + } +}; + +void Swig_process_types(Node *n) { + if (!n) return; + TypePass *t = new TypePass; + t->top(n); + delete t; +} + + + + + + + diff --git a/Source/Modules1.1/xml.cxx b/Source/Modules1.1/xml.cxx index e3891b1c6..261f3e348 100644 --- a/Source/Modules1.1/xml.cxx +++ b/Source/Modules1.1/xml.cxx @@ -1,304 +1,318 @@ -/* ----------------------------------------------------------------------------- - * xml.cxx +/* ----------------------------------------------------------------------------- + * Xml.cxx * - * Generate XML representation + * A web-base parse tree Xml using SWILL. This is an optional + * feature that's normally disabled. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) * - * Author(s) : SWIG core: David Beazley (beazley@cs.uchicago.edu) - * XML module: Klaus Wiederaenders (kwconsulting@compuserve.com) - * Copyright (C) 1999-2001. The University of Chicago - * See the file LICENSE for information on usage and redistribution. + * Copyright (C) 2002. The University of Chicago + * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -/* DB: I had to take some features related to package naming out of this to - get the new type system to work. These need to be put back in at some - point. */ - -static char cvsroot[] = "$Header$"; - -#include -#include "swig11.h" -#include "xml.h" -#include "dohobj.h" - -static char *usage = (char*)"\ +char cvsroot_xml_cxx[] = "$Header$"; +static const char *usage = "\ XML Options (available with -xml)\n\ - -o filename - Output file\n\ - -dtd filename - Stylsheet file\n\n"; + -xml output.xml - Use output.xml as output file (extension .xml mandatory)\n\ + -xmllang lang - Typedef language.\n\n"; + +#include "swigmod.h" + +//static Node *view_top = 0; +static File *out = 0; + +class XML +: public Language +{ + + + +public: + + int indent_level; + long id; + XML() + : indent_level( 0 ) + , id( 0 ) + { + } + + virtual ~XML() + { + } + + virtual void main(int argc, char *argv[]) + { + SWIG_typemap_lang("xml"); + for( int iX = 0; iX < argc; iX++ ) + { + if( strcmp( argv[iX], "-xml" ) == 0 ) + { + char * extension = argv[iX+1]+strlen(argv[iX+1])-4; + if( strcmp( extension, ".xml" ) ) + continue; + iX++; + Swig_mark_arg (iX); + String * outfile = NewString( argv[iX] ); + out = NewFile(outfile,"w"); + if (!out) + { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + continue; + } + if( strcmp( argv[iX], "-xmllang" ) == 0 ) + { + Swig_mark_arg (iX); + iX++; + SWIG_typemap_lang(argv[iX]); + Swig_mark_arg (iX); + continue; + } + if( strcmp( argv[iX], "-help" ) == 0 ) + { + fputs( usage, stderr ); + } + } + } + + /* Top of the parse tree */ + + virtual int top(Node *n) + { + if( out == 0 ) + { + String *outfile = Getattr(n,"outfile"); + Replaceall(outfile,"_wrap.cxx", ".xml"); + out = NewFile(outfile,"w"); + if (!out) + { + Printf(stderr,"*** Can't open '%s'\n", outfile); + SWIG_exit(EXIT_FAILURE); + } + } + Printf( out, " \n" ); + Xml_print_tree(n); + return SWIG_OK; + } + + + + void print_indent(int l) + { + int i; + for (i = 0; i < indent_level; i++) + { + Printf(out, " "); + } + if (l) + { + Printf(out, " "); + } + } + + void Xml_print_tree(DOH *obj) + { + while (obj) + { + Xml_print_node(obj); + obj = nextSibling(obj); + } + } + + void Xml_print_attributes(Node * obj) + { + String *k; + indent_level += 4; + print_indent(0); + Printf( out, "\n", ++id, obj ); + indent_level += 4; + + k = Firstkey(obj); + while (k) + { + if ((Cmp(k,"nodeType") == 0) + || (Cmp(k,"firstChild") == 0) + || (Cmp(k,"lastChild") == 0) + || (Cmp(k,"parentNode") == 0) + || (Cmp(k,"nextSibling") == 0) + || (Cmp(k,"previousSibling") == 0) + || (*(Char(k)) == '$')) + { + /* Do nothing */ + } + else if (Cmp(k,"module") == 0) + { + Xml_print_module( Getattr(obj,k) ); + } + else if (Cmp(k,"baselist") == 0) + { + Xml_print_baselist( Getattr(obj,k) ); + } + else if (Cmp(k,"typescope") == 0) + { + Xml_print_typescope( Getattr(obj,k) ); + } + else if (Cmp(k,"typetab") == 0) + { + Xml_print_typetab( Getattr(obj,k) ); + } + else if (Cmp(k,"kwargs") == 0) + { + Xml_print_kwargs( Getattr(obj,k) ); + } + else if (Cmp(k,"parms") == 0 || Cmp(k, "pattern") == 0 ) + { + Xml_print_parmlist( Getattr(obj,k) ); + } + else + { + DOH *o; + print_indent(0); + if (DohIsString(Getattr(obj,k))) + { + o = Str(Getattr(obj,k)); + Replaceall( k, ":", "_" ); + Replaceall( o, "<", "<" ); + Replaceall( o, "&", "&" ); + Replaceall( o, "\"", """ ); + Replaceall( o, "\\", "\\\\" ); + Printf(out,"\n", k, o, ++id, o ); + Delete(o); + } + else + { + o = Getattr(obj,k); + Replaceall( k, ":", "_" ); + Printf(out,"\n", k, o, ++id, o ); + } + } + k = Nextkey(obj); + } + indent_level -= 4; + print_indent(0); + Printf( out, "\n" ); + indent_level -= 4; + } + + void Xml_print_node(Node *obj) + { + Node *cobj; + + print_indent(0); + Printf(out,"<%s id=\"%ld\" addr=\"%x\" >\n", nodeType(obj), ++id, obj); + Xml_print_attributes( obj ); + cobj = firstChild(obj); + if (cobj) + { + indent_level += 4; + Printf(out,"\n"); + Xml_print_tree(cobj); + indent_level -= 4; + } + else + { + print_indent(1); + Printf(out,"\n"); + } + print_indent(0); + Printf(out,"\n", nodeType(obj)); + } + + + void Xml_print_parmlist(ParmList *p) + { + + print_indent(0); + Printf( out, "\n", ++id, p ); + indent_level += 4; + while(p) + { + print_indent(0); + Printf( out, "\n", ++id ); + Xml_print_attributes( p ); + print_indent(0); + Printf( out, "\n" ); + p = nextSibling(p); + } + indent_level -= 4; + print_indent(0); + Printf( out, "\n" ); + } + + void Xml_print_baselist(List *p) + { + + print_indent(0); + Printf( out, "\n", ++id, p ); + indent_level += 4; + String *s; + for (s = Firstitem(p); s; s = Nextitem(p)) + { + print_indent(0); + Printf( out, "\n", s, ++id, s ); + } + indent_level -= 4; + print_indent(0); + Printf( out, "\n" ); + } + + void Xml_print_module(Node *p) + { + + print_indent(0); + Printf( out, "\n", Getattr( p, "name"), ++id, p ); + } + + void Xml_print_kwargs(Hash *p) + { + Xml_print_hash( p, "kwargs" ); + } + + void Xml_print_typescope(Hash *p) + { + + Xml_print_hash( p, "typescope" ); + } + + void Xml_print_typetab(Hash *p) + { + + Xml_print_hash( p, "typetab" ); + } + + + void Xml_print_hash(Hash *p, const char * markup) + { + + print_indent(0); + Printf( out, "<%s id=\"%ld\" addr=\"%x\" >\n", markup, ++id, p ); + Xml_print_attributes( p ); + indent_level += 4; + Node * n = Firstitem( p ); + while(n) + { + print_indent(0); + Printf( out, "<%ssitem id=\"%ld\" addr=\"%x\" >\n", markup, ++id, n ); + Xml_print_attributes( n ); + Printf( out, "\n", markup ); + print_indent(0); + Printf( out, " />\n" ); + n = Nextkey(p); + } + indent_level -= 4; + print_indent(0); + Printf( out, "\n", markup ); + } + +}; + -static String *dtdfile = 0; -static String *xmlfile = 0; -static int indent = 0; -static const int indentsize = 2; -static const char * indentchar = " "; -FILE *f_xml = 0; extern "C" { - -static String * emit_indent( int indent ) -{ - String *out; - out = NewString(""); - for(int iX = 0; iX < indent; iX ++ ) - Append( out, indentchar ); - return Swig_temp_result(out); -} - -void xml(DOH *node) -{ - if (ObjGetMark(node)) - { - Printf( f_xml, "%s\n", - emit_indent( indent ), node); - return; - } - indent += indentsize; - ObjSetMark(node, 1); - while (node) - { - DohBase * base = (DohBase *) node; - if( !base ) - return; - switch( base->type ) - { - case 1: - Replace( node, "<", "<", DOH_REPLACE_ANY ); - Replace( node, "&", "&", DOH_REPLACE_ANY ); - Printf( f_xml, "%s", node ); - break; - case 2: - { - indent += indentsize; - DOH *item; - - item = Firstitem(node); - while (item) - { - DohBase * itembase = (DohBase *) item; - if( itembase && itembase->type == DOHTYPE_STRING ) - { - Printf( f_xml, - "%s\n", - emit_indent( indent ), Char( item ), item ); - } - else - { - Printf( f_xml, "%s\n", - emit_indent( indent ), item ); - xml( item ); - Printf( f_xml, "%s\n", - emit_indent( indent ) ); - - } - item = Nextitem(node); - } - indent -= indentsize; - break; - } - case 3: - { - String * none = NewString("swigxml:none"); - DOH * tag = Getattr( node, "tag" ); - if( !tag ) - { - /* - ObjSetMark(node, 0); - Printf( f_xml, "------- %s\n", Char( Str( node ))); - ObjSetMark(node, 1); - */ - tag = none; - } - DOH * name = Getattr( node, "name" ); - char * ttt = Char( tag ); - - if( tag && ::strchr( Char(tag), ':' ) == 0 ) - Insert( tag, 0, "swigxml:" ); - // check for simple node - int length = Len( node ); - if( Getattr( node, "tag" ) ) - --length; - if( Getattr( node, "prev" ) ) - --length; - if( Getattr( node, "next" ) ) - --length; - if( Getattr( node, "parent" ) ) - --length; - if( Getattr( node, "last" ) ) - --length; - if( length == 1 && name ) - { // Yes, it's simple - if( Len( name) ) - Printf( f_xml, "%s<%s name=\"%s\" ident=\"ID%0X\" />\n", - emit_indent( indent ), Char( tag ), Char( name ), - node ); - else - Printf( f_xml, "%s<%s ident=\"ID%0X\" />\n", - emit_indent( indent ), Char( tag ), node ); - Delete( none ); - break; - } - if( Len( name) ) - Printf( f_xml, "%s<%s name=\"%s\" ident=\"ID%0X\">\n", - emit_indent( indent ), Char( tag ), Char( name ), node ); - else - Printf( f_xml, "%s<%s ident=\"ID%0X\">\n", - emit_indent( indent ), Char( tag ), node ); - indent += indentsize; - - DOH * key = Firstkey(node); - while (key) - { - char * kkkk = Char( key ); - DOH * attr = Getattr( node, key ); - char * aaaa = Char( Getattr( node, key ) ); - DohBase * attrbase = (DohBase *) attr; - if( ::strcmp( Char( key ), "tag") - && ::strcmp( Char( key ), "code") - && ::strcmp( Char( key ), "name") - && attrbase && attrbase->type == DOHTYPE_STRING) - { - Replace( attr, "\"", """, DOH_REPLACE_ANY ); - Printf( f_xml, - "%s\n", - emit_indent( indent ), Char( key ), Char( attr ), - attr ); - } - else - { - if( ::strcmp( Char( key ), "prev" ) - && ::strcmp( Char( key ), "next" ) - && ::strcmp( Char( key ), "parent" ) - && ::strcmp( Char( key ), "tag" ) - && ::strcmp( Char( key ), "name" ) - && ::strcmp( Char( key ), "last" ) ) - { - Printf( f_xml, "%s\n", - emit_indent( indent ), Char( key ), key ); - xml( attr ); - Printf( f_xml, "%s\n", - emit_indent( indent ), Char( key ) ); - } - - } - key = Nextkey(node); - } - indent -= indentsize; - Printf( f_xml, "%s\n", emit_indent( indent ), Char( tag ) ); - Delete( none ); - break; - } - case 4: - Printf( f_xml, "%s ", "DOHTYPE_VOID" ); - break; - case 5: - Printf( f_xml, "%s ", "DOHTYPE_FILE" ); - break; - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - Printf( f_xml, "%d ", base->type ); - ; - } - ObjSetMark(node, 0); - node = Swig_next(node); - } - indent -= indentsize; - -} - -int xml_init(int argc, char *argv[]) -{ - int i; - int help = 0; - - // Get options - for (i = 1; i < argc; i++) - { - if (argv[i]) - { - if(strcmp(argv[i],"-xml") == 0) - { - if (argv[i+1]) - { - xmlfile = NewString(argv[i+1]); - // don't do this: Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } - else - { - Swig_arg_error(); - } - continue; - } - if(strcmp(argv[i],"-dtd") == 0) - { - if (argv[i+1]) - { - dtdfile = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } - else - { - Swig_arg_error(); - } - continue; - } - if (strcmp(argv[i],"-help") == 0) - { - fputs(usage,stderr); - Swig_mark_arg(i); - help = 1; - } - } - } - - if (help) return 0; - Preprocessor_define((void *) "SWIGXML 1", 0); - if( ! Swig_swiglib_get() ) - Swig_swiglib_set("xml"); - - return 0; -} - -DOH *xml_run(DOH *node) -{ - time_t now; - time( &now ); - char buffer[32]; - ::strcpy( buffer, ctime(&now)); - buffer[24] = '\0'; - char * filename = Char(xmlfile); - if ((f_xml = fopen( filename,"w")) == 0) { - fprintf(stderr,"Unable to open %s\n", filename); - Swig_exit(1); - } - Printf( f_xml, "\n", buffer ); - - if( dtdfile ) - { - Printf( f_xml, "\n", dtdfile); - } - - Printf( f_xml, "\n" ); - xml(node); - Printf( f_xml, "\n" ); - - fclose(f_xml); - return node; -} - + Language * swig_xml( void ) + { + return new XML(); + } } diff --git a/Source/Modules1.1/xml.dtd b/Source/Modules1.1/xml.dtd deleted file mode 100644 index 68e40e33e..000000000 --- a/Source/Modules1.1/xml.dtd +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/Modules1.1/xml.h b/Source/Modules1.1/xml.h deleted file mode 100644 index 79532957c..000000000 --- a/Source/Modules1.1/xml.h +++ /dev/null @@ -1,18 +0,0 @@ -/**************************************************************************** - * Simplified Wrapper and Interface Generator (SWIG) - * - * Author : David Beazley - * - * Department of Computer Science - * University of Chicago - * 1100 E 58th Street - * Chicago, IL 60637 - * beazley@cs.uchicago.edu - * - * Please read the file LICENSE for the copyright and terms by which SWIG - * can be used and distributed. - ****************************************************************************/ - -extern "C" DOH *xml_run(DOH *node); -extern "C" int xml_init(int argc, char *argv[]); - diff --git a/Source/Preprocessor/Makefile.in b/Source/Preprocessor/Makefile.in index 24320f5e9..ac1bed800 100644 --- a/Source/Preprocessor/Makefile.in +++ b/Source/Preprocessor/Makefile.in @@ -6,7 +6,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ SRCS = expr.c cpp.c -OBJS = expr.o cpp.o +OBJS = expr.@OBJEXT@ cpp.@OBJEXT@ prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -15,11 +15,11 @@ CC = @CC@ AR = @AR@ RANLIB = @RANLIB@ CFLAGS = @CFLAGS@ -INCLUDE = -I$(srcdir)/. -I$(srcdir)/../Swig -I$(srcdir)/../DOH/Include +INCLUDES = -I$(srcdir)/. -I$(srcdir)/../Swig -I$(srcdir)/../DOH/Include -I$(srcdir)/../Include TARGET = libcpp.a -.c.o: - $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $< +.c.@OBJEXT@: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $*.@OBJEXT@ $< all: $(TARGET) @@ -28,4 +28,4 @@ $(TARGET): $(OBJS) $(RANLIB) $(TARGET) clean: - rm -f *.o *~ core *.so *.a *_wrap.* + rm -f *.@OBJEXT@ *~ core *.so *.a *_wrap.* diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c index f0f11b67c..9fa55a0e6 100644 --- a/Source/Preprocessor/cpp.c +++ b/Source/Preprocessor/cpp.c @@ -15,49 +15,36 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_cpp_c[] = "$Header$"; #include "preprocessor.h" #include -static DOHHash *cpp = 0; /* C preprocessor data */ +static Hash *cpp = 0; /* C preprocessor data */ static int include_all = 0; /* Follow all includes */ +static int ignore_missing = 0; +static int import_all = 0; /* Follow all includes, but as %import statements */ static int single_include = 1; /* Only include each file once */ -static int silent_errors = 0; -static DOHHash *included_files = 0; - -/* Handle an error */ - -static void cpp_error(DOHString *file, int line, char *fmt, ...) { - va_list ap; - if (silent_errors) return; - va_start(ap,fmt); - if (line > 0) { - Printf(stderr,"%s:%d ", file, line); - } else { - Printf(stderr,"%s:EOF ",file); - } - vPrintf(stderr,fmt,ap); - va_end(ap); -} +static Hash *included_files = 0; +static List *dependencies = 0; /* Test a character to see if it starts an identifier */ static int -isidentifier(char c) { +isidentifier(int c) { if ((isalpha(c)) || (c == '_') || (c == '$')) return 1; else return 0; } /* Test a character to see if it valid in an identifier (after the first letter) */ static int -isidchar(char c) { +isidchar(int c) { if ((isalnum(c)) || (c == '_') || (c == '$')) return 1; else return 0; } /* Skip whitespace */ static void -skip_whitespace(DOH *s, DOH *out) { +skip_whitespace(File *s, File *out) { int c; while ((c = Getc(s)) != EOF) { if (!isspace(c)) { @@ -69,7 +56,7 @@ skip_whitespace(DOH *s, DOH *out) { /* Skip to a specified character taking line breaks into account */ static int -skip_tochar(DOHFile *s, int ch, DOHFile *out) { +skip_tochar(File *s, int ch, File *out) { int c; while ((c = Getc(s)) != EOF) { if (out) Putc(c,out); @@ -89,8 +76,8 @@ copy_location(DOH *s1, DOH *s2) { Setline(s2,Getline(s1)); } -static DOHString *cpp_include(DOHString_or_char *fn) { - DOHString *s; +static String *cpp_include(String_or_char *fn) { + String *s; if (single_include) { if (Getattr(included_files,fn)) return 0; Setattr(included_files,fn,fn); @@ -98,18 +85,31 @@ static DOHString *cpp_include(DOHString_or_char *fn) { s = Swig_include(fn); if (!s) { Seek(fn,0,SEEK_SET); - cpp_error(Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn); + if (ignore_missing) { + Swig_warning(WARN_PP_MISSING_FILE,Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn); + } else { + Swig_error(Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn); + } } else { Seek(s,0,SEEK_SET); + if (!dependencies) { + dependencies = NewList(); + } + Append(dependencies, Copy(Swig_last_file())); } return s; } +List *Preprocessor_depend(void) { + return dependencies; +} + /* ----------------------------------------------------------------------------- * void Preprocessor_cpp_init() - Initialize the preprocessor * ----------------------------------------------------------------------------- */ void Preprocessor_init() { - DOHHash *s; + extern void Preprocessor_expr_init(void); + Hash *s; cpp = NewHash(); s = NewHash(); Setattr(cpp,"symbols",s); @@ -123,6 +123,15 @@ void Preprocessor_include_all(int a) { include_all = a; } +void Preprocessor_import_all(int a) { + import_all = a; +} + +void Preprocessor_ignore_missing(int a) { + ignore_missing = a; +} + + /* ----------------------------------------------------------------------------- * Preprocessor_define() * @@ -130,30 +139,30 @@ void Preprocessor_include_all(int a) { * SWIG macro semantics. * ----------------------------------------------------------------------------- */ -DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) +Hash *Preprocessor_define(const String_or_char *_str, int swigmacro) { - DOHString *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0; - DOHHash *macro = 0, *symbols = 0, *m1; - DOHList *arglist = 0; + String *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0; + Hash *macro = 0, *symbols = 0, *m1; + List *arglist = 0; int c, line; + int varargs = 0; + String_or_char *str = (String_or_char *) _str; assert(cpp); assert(str); /* First make sure that string is actually a string */ if (DohCheck(str)) { - s = Copy(str); + s = NewString(str); copy_location(str,s); str = s; } else { str = NewString((char *) str); - Seek(str,0,SEEK_SET); } + Seek(str,0,SEEK_SET); line = Getline(str); file = Getfile(str); - /* Printf(stdout,"%s:%d '%s'\n", file,line,str); */ - /* Skip over any leading whitespace */ skip_whitespace(str,0); @@ -169,7 +178,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) else Putc(c,argstr); } if (c != ')') { - cpp_error(Getfile(str),Getline(str), "Missing \')\' in macro parameters\n"); + Swig_error(Getfile(str),Getline(str), "Missing \')\' in macro parameters\n"); goto macro_error; } break; @@ -178,7 +187,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) } else if (isspace(c)) { break; } else { - cpp_error(Getfile(str),Getline(str),"Illegal character in macro name\n"); + Swig_error(Getfile(str),Getline(str),"Illegal character in macro name\n"); goto macro_error; } } @@ -197,18 +206,38 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) argname = NewString(""); while ((c = Getc(argstr)) != EOF) { if (c == ',') { - Append(arglist,argname); + /* Check for varargs */ + if (Strstr(argname,".")) { + if (Strcmp(argname,"...") != 0) { + Swig_error(Getfile(str),Getline(str),"Illegal macro argument name '%s'\n", argname); + } else { + Append(arglist,"__VA_ARGS__"); + varargs = 1; + } + } else { + Append(arglist,argname); + } Delete(argname); argname = NewString(""); - } else if (isidchar(c)) { + } else if (isidchar(c) || (c == '.')) { Putc(c,argname); - } else if (!isspace(c)) { - cpp_error(Getfile(str),Getline(str),"Illegal character in macro name\n"); + } else if (!(isspace(c) || (c == '\\'))) { + Swig_error(Getfile(str),Getline(str),"Illegal character in macro argument name\n"); goto macro_error; } } if (Len(argname)) { - Append(arglist,argname); + /* Check for varargs */ + if (Strstr(argname,".")) { + if (Strcmp(argname,"...") != 0) { + Swig_error(Getfile(str),Getline(str),"Illegal macro argument name '%s'\n", argname); + } else { + Append(arglist,"__VA_ARGS__"); + varargs = 1; + } + } else { + Append(arglist,argname); + } Delete(argname); } } @@ -216,16 +245,70 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) if (!swigmacro) { Replace(macrovalue,"\\\n"," ", DOH_REPLACE_NOQUOTE); } + + /* Look for special # substitutions. We only consider # that appears + outside of quotes and comments */ + + { + int state = 0; + char *cc = Char(macrovalue); + while (*cc) { + switch(state) { + case 0: + if (*cc == '#') *cc = '\001'; + else if (*cc == '/') state = 10; + else if (*cc == '\'') state = 20; + else if (*cc == '\"') state = 30; + break; + case 10: + if (*cc == '*') state = 11; + else if (*cc == '/') state = 15; + else { + state = 0; + cc--; + } + break; + case 11: + if (*cc == '*') state = 12; + break; + case 12: + if (*cc == '/') state = 0; + else if (*cc != '*') state = 11; + break; + case 15: + if (*cc == '\n') state = 0; + break; + case 20: + if (*cc == '\'') state = 0; + if (*cc == '\\') state = 21; + break; + case 21: + state = 20; + break; + case 30: + if (*cc == '\"') state = 0; + if (*cc == '\\') state = 31; + break; + case 31: + state = 30; + break; + default: + break; + } + cc++; + } + } + /* Get rid of whitespace surrounding # */ - Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE); + /* Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE); */ while(strstr(Char(macrovalue),"\001 ")) { - Replace(macrovalue,"\001 ","\001", DOH_REPLACE_NOQUOTE); + Replace(macrovalue,"\001 ","\001", DOH_REPLACE_ANY); } while(strstr(Char(macrovalue)," \001")) { - Replace(macrovalue," \001","\001", DOH_REPLACE_NOQUOTE); + Replace(macrovalue," \001","\001", DOH_REPLACE_ANY); } /* Replace '##' with a special token */ - Replace(macrovalue,"\001\001","\002", DOH_REPLACE_NOQUOTE); + Replace(macrovalue,"\001\001","\002", DOH_REPLACE_ANY); /* Go create the macro */ macro = NewHash(); @@ -234,6 +317,9 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) if (arglist) { Setattr(macro,"args",arglist); Delete(arglist); + if (varargs) { + Setattr(macro,"varargs","1"); + } } Setattr(macro,"value",macrovalue); Delete(macrovalue); @@ -245,7 +331,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) symbols = Getattr(cpp,"symbols"); if ((m1 = Getattr(symbols,macroname))) { if (Cmp(Getattr(m1,"value"),macrovalue)) - cpp_error(Getfile(str),Getline(str),"Macro '%s' redefined. Previous definition in \'%s\', Line %d\n", macroname, Getfile(m1), Getline(m1)); + Swig_error(Getfile(str),Getline(str),"Macro '%s' redefined. Previous definition in \'%s\', Line %d\n", macroname, Getfile(m1), Getline(m1)); } Setattr(symbols,macroname,macro); Delete(str); @@ -263,9 +349,9 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) * * Undefines a macro. * ----------------------------------------------------------------------------- */ -void Preprocessor_undef(DOHString_or_char *str) +void Preprocessor_undef(String_or_char *str) { - DOH *symbols; + Hash *symbols; assert(cpp); symbols = Getattr(cpp,"symbols"); Delattr(symbols,str); @@ -277,11 +363,11 @@ void Preprocessor_undef(DOHString_or_char *str) * Isolates macro arguments and returns them in a list. For each argument, * leading and trailing whitespace is stripped (ala K&R, pg. 230). * ----------------------------------------------------------------------------- */ -static DOHList * -find_args(DOHString *s) +static List * +find_args(String *s) { - DOHList *args; - DOHString *str; + List *args; + String *str; int c, level; long pos; @@ -344,7 +430,7 @@ find_args(DOHString *s) c = Getc(s); } unterm: - cpp_error(Getfile(args),Getline(args),"Unterminated macro call.\n"); + Swig_error(Getfile(args),Getline(args),"Unterminated macro call.\n"); return args; } @@ -355,9 +441,9 @@ find_args(DOHString *s) * or bare. * ----------------------------------------------------------------------------- */ -static DOHString * -get_filename(DOHString *str) { - DOHString *fn; +static String * +get_filename(String *str) { + String *fn; int c; skip_whitespace(str,0); @@ -377,6 +463,31 @@ get_filename(DOHString *str) { return fn; } +static String * +get_options(String *str) { + + int c; + skip_whitespace(str,0); + c = Getc(str); + if (c == '(') { + String *opt; + int level = 1; + opt = NewString("("); + while (((c = Getc(str)) != EOF)) { + Putc(c,opt); + if (c == ')') { + level--; + if (!level) return opt; + } + if (c == '(') level++; + } + Delete(opt); + return 0; + } else { + Ungetc(c,str); + return 0; + } +} /* ----------------------------------------------------------------------------- * expand_macro() * @@ -386,12 +497,13 @@ get_filename(DOHString *str) { DOH *expanded_value = 0; -static DOHString * -expand_macro(DOHString_or_char *name, DOHList *args) +static String * +expand_macro(String_or_char *name, List *args) { DOH *symbols, *ns, *macro, *margs, *mvalue, *temp, *tempa, *e; DOH *Preprocessor_replace(DOH *); int i, l; + int isvarargs = 0; symbols = Getattr(cpp,"symbols"); if (!symbols) return 0; @@ -420,14 +532,37 @@ expand_macro(DOHString_or_char *name, DOHList *args) assert(mvalue); margs = Getattr(macro,"args"); + if (Getattr(macro,"varargs")) { + isvarargs = 1; + /* Variable length argument macro. We need to collect all of the extra arguments into a single argument */ + if (Len(args) >= (Len(margs)-1)) { + int i; + int vi, na; + String *vararg = NewString(""); + vi = Len(margs)-1; + na = Len(args); + for (i = vi; i < na; i++) { + Append(vararg,Getitem(args,i)); + if ((i+1) < na) { + Append(vararg,","); + } + } + /* Remove arguments */ + for (i = vi; i < na; i++) { + Delitem(args,vi); + } + Append(args,vararg); + Delete(vararg); + } + } /* If there are arguments, see if they match what we were given */ if ((margs) && (Len(margs) != Len(args))) { - if (Len(margs) > 1) - cpp_error(Getfile(args),Getline(args),"Macro '%s' expects %d arguments\n", name, Len(margs)); - else if (Len(margs) == 1) - cpp_error(Getfile(args),Getline(args),"Macro '%s' expects 1 argument\n", name); + if (Len(margs) > (1+isvarargs)) + Swig_error(Getfile(args),Getline(args),"Macro '%s' expects %d arguments\n", name, Len(margs)-isvarargs); + else if (Len(margs) == (1+isvarargs)) + Swig_error(Getfile(args),Getline(args),"Macro '%s' expects 1 argument\n", name); else - cpp_error(Getfile(args),Getline(args),"Macro '%s' expects no arguments\n", name); + Swig_error(Getfile(args),Getline(args),"Macro '%s' expects no arguments\n", name); return 0; } @@ -480,27 +615,49 @@ expand_macro(DOHString_or_char *name, DOHList *args) } Replace(ns,temp,rep, DOH_REPLACE_ANY); } + if (isvarargs) { + if ((Strcmp(aname,"__VA_ARGS__") == 0) && (Len(arg) == 0)) { + /* Zero length __VA_ARGS__ macro argument. We search for commas that might appear before and nuke them */ + char *a, *s, *t; + s = Char(ns); + a = strstr(s,"__VA_ARGS__"); + while (a) { + t = a-1; + if (*t == '\002') { + t--; + while (t >= s) { + if (isspace((int) *t)) t--; + else if (*t == ',') { + *t = ' '; + } else break; + } + } + a = strstr(a+11,"__VA_ARGS__"); + } + } + } Replace(ns, aname, arg, DOH_REPLACE_ID); } } Replace(ns,"\002","",DOH_REPLACE_ANY); /* Get rid of concatenation tokens */ Replace(ns,"\001","#",DOH_REPLACE_ANY); /* Put # back (non-standard C) */ - /* Expand this macro even further */ e = Preprocessor_replace(ns); Delete(ns); Delattr(macro,"*expanded*"); if (Getattr(macro,"swigmacro")) { - DOHString *g; - DOHString *f = NewString(""); - Printf(f,"%%macro %s, \"%s\", %d {\n", name, Getfile(macro), Getline(macro)); + String *g; + String *f = NewString(""); Seek(e,0,SEEK_SET); copy_location(macro,e); g = Preprocessor_parse(e); - Printf(f,"%s\n", g); - Printf(f,"}\n"); + + /* Drop the macro in place, but with a marker around it */ + Printf(f,"/*@%s,%d,%s@*/%s/*@@*/", Getfile(macro), Getline(macro), name, g); + + /* Printf(f," }\n"); */ Delete(g); Delete(e); e = f; @@ -510,6 +667,24 @@ expand_macro(DOHString_or_char *name, DOHList *args) return e; } +/* ----------------------------------------------------------------------------- + * evaluate_args() + * + * Evaluate the arguments of a macro + * ----------------------------------------------------------------------------- */ + +List *evaluate_args(List *x) { + String *a; + String *Preprocessor_replace(String *); + + List *nl = NewList(); + + for (a = Firstitem(x); a; a = Nextitem(x)) { + Append(nl,Preprocessor_replace(a)); + } + return nl; +} + /* ----------------------------------------------------------------------------- * DOH *Preprocessor_replace(DOH *s) * @@ -575,6 +750,7 @@ Preprocessor_replace(DOH *s) DOH *arg = 0; args = NewList(); arg = NewString(""); + if (isidchar(c)) Putc(c,arg); while ((c = Getc(s)) != EOF) { if (!isidchar(c)) { Seek(s,-1,SEEK_CUR); @@ -585,8 +761,8 @@ Preprocessor_replace(DOH *s) Append(args,arg); Delete(arg); } - if (!args) { - cpp_error(Getfile(id),Getline(id),"No arguments given to defined()\n"); + if ((!args) || (!Len(args))) { + Swig_error(Getfile(id),Getline(id),"No arguments given to defined()\n"); state = 0; break; } @@ -608,7 +784,10 @@ Preprocessor_replace(DOH *s) break; } if (Cmp(id,"__FILE__") == 0) { - Printf(ns,"\"%s\"",Getfile(s)); + String *fn = Copy(Getfile(s)); + Replaceall(fn,"\\","\\\\"); + Printf(ns,"\"%s\"",fn); + Delete(fn); state = 0; break; } @@ -623,6 +802,12 @@ Preprocessor_replace(DOH *s) } else { args = 0; } + if (args) { + List *nargs = evaluate_args(args); + Delete(args); + args = nargs; + } + e = expand_macro(id,args); if (e) { Printf(ns,"%s",e); @@ -668,13 +853,13 @@ Preprocessor_replace(DOH *s) if (state == 1) { /* See if this is the special "defined" macro */ if (Cmp(id,"defined") == 0) { - cpp_error(Getfile(id),Getline(id),"No arguments given to defined()\n"); + Swig_error(Getfile(id),Getline(id),"No arguments given to defined()\n"); } else if ((m = Getattr(symbols,id))) { DOH *e; /* Yes. There is a macro here */ /* See if the macro expects arguments */ if (Getattr(m,"args")) { - cpp_error(Getfile(id),Getline(id),"Macro arguments expected.\n"); + Swig_error(Getfile(id),Getline(id),"Macro arguments expected.\n"); } e = expand_macro(id,0); Printf(ns,"%s",e); @@ -698,52 +883,24 @@ Preprocessor_replace(DOH *s) static int check_id(DOH *s) { - int c, state = 0; - int hasvalue = 0; - Seek(s,0,SEEK_SET); - while ((c = Getc(s)) != EOF) { - switch(state) { + static SwigScanner *scan = 0; + int c; - case 0: - if (isdigit(c)) { - hasvalue =1; - state = 1; - } - else if (isidentifier(c)) return 1; - else if (c == '\"') { - skip_tochar(s,'\"',0); - hasvalue = 1; - } else if (c == '\'') { - skip_tochar(s,'\'',0); - hasvalue = 1; - } else if (c == '/') state = 3; - break; - case 1: - if (isspace(c)) state = 0; - hasvalue = 1; - break; - case 3: - if (c == '*') state = 10; - else if (c == '/') state = 20; - else { - Ungetc(c,s); - state = 0; - } - break; - case 10: - if (c == '*') state = 11; - break; - case 11: - if (c == '/') state = 0; - else if (c != '*') state = 10; - break; - case 20: - if (c == '\n') state = 0; - break; - } + Seek(s,0,SEEK_SET); + + if (!scan) { + scan = NewSwigScanner(); + } + + SwigScanner_clear(scan); + s = Copy(s); + Seek(s,SEEK_SET,0); + SwigScanner_push(scan,s); + while ((c = SwigScanner_token(scan))) { + if ((c == SWIG_TOKEN_ID) || (c == SWIG_TOKEN_LBRACE) || (c == SWIG_TOKEN_RBRACE)) return 1; } - if (!hasvalue) return 1; return 0; + } /* addline(). Utility function for adding lines to a chunk */ @@ -775,7 +932,7 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) { } /* ----------------------------------------------------------------------------- - * DOH *Preprocessor_parse(DOH *s) + * Preprocessor_parse() * * Parses the string s. Returns a new string containing the preprocessed version. * @@ -787,12 +944,13 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) { * included inline (with all preprocessor directives included). * ----------------------------------------------------------------------------- */ -DOH * -Preprocessor_parse(DOH *s) +String * +Preprocessor_parse(String *s) { - DOH *ns; /* New string containing the preprocessed text */ - DOH *chunk, *symbols, *sval, *decl; - DOH *id = 0, *value = 0, *comment = 0; + String *ns; /* New string containing the preprocessed text */ + String *chunk, *sval, *decl; + Hash *symbols; + String *id = 0, *value = 0, *comment = 0; int i, state, val, e, c; int start_line = 0; int allow = 1; @@ -802,6 +960,9 @@ Preprocessor_parse(DOH *s) int cpp_lines = 0; int cond_lines[256]; + /* Blow away all carriage returns */ + Replace(s,"\015","",DOH_REPLACE_ANY); + ns = NewString(""); /* Return result */ decl = NewString(""); @@ -842,12 +1003,12 @@ Preprocessor_parse(DOH *s) else if (c == '\"') { start_line = Getline(s); if (skip_tochar(s,'\"',chunk) < 0) { - cpp_error(Getfile(s),-1,"Unterminated string constant starting at line %d\n",start_line); + Swig_error(Getfile(s),-1,"Unterminated string constant starting at line %d\n",start_line); } } else if (c == '\'') { start_line = Getline(s); if (skip_tochar(s,'\'',chunk) < 0) { - cpp_error(Getfile(s),-1,"Unterminated character constant starting at line %d\n",start_line); + Swig_error(Getfile(s),-1,"Unterminated character constant starting at line %d\n",start_line); } } else if (c == '/') state = 30; /* Comment */ @@ -896,8 +1057,13 @@ Preprocessor_parse(DOH *s) if (c == '\n') { Ungetc(c,s); state = 50; + } else { + state = 42; + if (!isspace(c)) { + Ungetc(c,s); + } } - else state = 42; + copy_location(s,value); break; } @@ -922,6 +1088,12 @@ Preprocessor_parse(DOH *s) state = 50; } else if (c == '/') { state = 45; + } else if (c == '\"') { + Putc(c,value); + skip_tochar(s,'\"',value); + } else if (c == '\'') { + Putc(c,value); + skip_tochar(s,'\'',value); } else { Putc(c,value); if (c == '\\') state = 44; @@ -982,9 +1154,9 @@ Preprocessor_parse(DOH *s) if ((m) && !(Getattr(m,"args"))) { v = Copy(Getattr(m,"value")); if (Len(v)) { - silent_errors = 1; + Swig_error_silent(1); v1 = Preprocessor_replace(v); - silent_errors = 0; + Swig_error_silent(0); /* Printf(stdout,"checking '%s'\n", v1); */ if (!check_id(v1)) { if (Len(comment) == 0) @@ -1021,20 +1193,20 @@ Preprocessor_parse(DOH *s) } } else if (Cmp(id,"else") == 0) { if (level <= 0) { - cpp_error(Getfile(s),Getline(id),"Misplaced #else.\n"); + Swig_error(Getfile(s),Getline(id),"Misplaced #else.\n"); } else { cond_lines[level-1] = Getline(id); if (allow) { allow = 0; mask = 0; } else if (level == start_level) { - allow = 1; + allow = 1*mask; } } } else if (Cmp(id,"endif") == 0) { level--; if (level < 0) { - cpp_error(Getfile(id),Getline(id),"Extraneous #endif ignored.\n"); + Swig_error(Getfile(id),Getline(id),"Extraneous #endif.\n"); level = 0; } else { if (level < start_level) { @@ -1053,7 +1225,7 @@ Preprocessor_parse(DOH *s) val = Preprocessor_expr(sval,&e); if (e) { Seek(value,0,SEEK_SET); - /* cpp_error(Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); */ + Swig_warning(WARN_PP_EVALUATION,Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); allow = 0; } else { if (val == 0) @@ -1063,7 +1235,7 @@ Preprocessor_parse(DOH *s) } } else if (Cmp(id,"elif") == 0) { if (level == 0) { - cpp_error(Getfile(s),Getline(id),"Misplaced #elif.\n"); + Swig_error(Getfile(s),Getline(id),"Misplaced #elif.\n"); } else { cond_lines[level-1] = Getline(id); if (allow) { @@ -1075,7 +1247,7 @@ Preprocessor_parse(DOH *s) val = Preprocessor_expr(sval,&e); if (e) { Seek(value,0,SEEK_SET); - /* cpp_error(Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); */ + Swig_warning(WARN_PP_EVALUATION,Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); allow = 0; } else { if (val) @@ -1087,24 +1259,36 @@ Preprocessor_parse(DOH *s) } } else if (Cmp(id,"line") == 0) { } else if (Cmp(id,"include") == 0) { - if ((include_all) && (allow)) { + if (((include_all) || (import_all)) && (allow)) { DOH *s1, *s2, *fn; Seek(value,0,SEEK_SET); fn = get_filename(value); s1 = cpp_include(fn); if (s1) { - Printf(ns,"%%file(\"include\") \"%s\" {\n", Swig_last_file()); + if (include_all) + Printf(ns,"%%includefile \"%s\" [\n", Swig_last_file()); + else if (import_all) + Printf(ns,"%%importfile \"%s\" [\n", Swig_last_file()); s2 = Preprocessor_parse(s1); addline(ns,s2,allow); - Printf(ns,"\n}\n"); + Printf(ns,"\n]\n"); Delete(s2); } Delete(s1); Delete(fn); } } else if (Cmp(id,"pragma") == 0) { + if (Strncmp(value,"SWIG ",5) == 0) { + char *c = Char(value)+5; + while (*c && (isspace((int)*c))) c++; + if (*c) { + if (Strncmp(c,"nowarn=",7) == 0) { + Swig_warnfilter(c+7,1); + } + } + } } else if (Cmp(id,"level") == 0) { - cpp_error(Getfile(s),Getline(id),"cpp debug: level = %d, startlevel = %d\n", level, start_level); + Swig_error(Getfile(s),Getline(id),"cpp debug: level = %d, startlevel = %d\n", level, start_level); } for (i = 0; i < cpp_lines; i++) Putc('\n',ns); @@ -1124,8 +1308,9 @@ Preprocessor_parse(DOH *s) } /* %#cpp - an embedded C preprocessor directive (we strip off the %) */ else if (c == '#') { + add_chunk(ns,chunk,allow); Putc(c,chunk); - state = 0; + state = 107; } else if (isidentifier(c)) { Clear(decl); Putc('%',decl); @@ -1155,6 +1340,22 @@ Preprocessor_parse(DOH *s) state = 105; } break; + + case 107: + Putc(c,chunk); + if (c == '\n') { + addline(ns,chunk,allow); + Clear(chunk); + state = 0; + } else if (c == '\\') { + state = 108; + } + break; + + case 108: + Putc(c,chunk); + state = 107; + break; case 110: if (!isidchar(c)) { @@ -1163,22 +1364,31 @@ Preprocessor_parse(DOH *s) if ((Cmp(decl,"%include") == 0) || (Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) { /* Got some kind of file inclusion directive */ if (allow) { - DOH *s1, *s2, *fn; + DOH *s1, *s2, *fn, *opt; + + if (Cmp(decl,"%extern") == 0) { + Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s),Getline(s),"%%extern is deprecated. Use %%import instead.\n"); + Clear(decl); + Printf(decl,"%%import"); + } + opt = get_options(s); fn = get_filename(s); s1 = cpp_include(fn); if (s1) { add_chunk(ns,chunk,allow); copy_location(s,chunk); - Printf(ns,"%%file(\"%s\") \"%s\" {\n", Char(decl)+1, Swig_last_file()); + Printf(ns,"%sfile%s \"%s\" [\n", decl, opt, Swig_last_file()); if ((Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) { Preprocessor_define("WRAPEXTERN 1", 0); + Preprocessor_define("SWIGIMPORT 1", 0); } s2 = Preprocessor_parse(s1); if ((Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) { + Preprocessor_undef("SWIGIMPORT"); Preprocessor_undef("WRAPEXTERN"); } addline(ns,s2,allow); - Printf(ns,"\n}\n"); + Printf(ns,"\n]\n"); Delete(s2); Delete(s1); } @@ -1209,15 +1419,17 @@ Preprocessor_parse(DOH *s) Putc(c,value); if (c == '%') { int i = 0; - char *d = "enddef\n"; - for (i = 0; i < 7; i++) { + char *d = "enddef"; + for (i = 0; i < 6; i++) { c = Getc(s); Putc(c,value); if (c != d[i]) break; } - if (i == 7) { + c = Getc(s); + Ungetc(c,s); + if ((i == 6) && (isspace(c))) { /* Got the macro */ - for (i = 0; i < 8; i++) { + for (i = 0; i < 7; i++) { Delitem(value,DOH_END); } if (allow) { @@ -1237,18 +1449,18 @@ Preprocessor_parse(DOH *s) } } while (level > 0) { - cpp_error(Getfile(s),-1,"Missing #endif for conditional starting on line %d\n", cond_lines[level-1]); + Swig_error(Getfile(s),-1,"Missing #endif for conditional starting on line %d\n", cond_lines[level-1]); level--; } if (state == 150) { Seek(value,0,SEEK_SET); - cpp_error(Getfile(s),-1,"Missing %%enddef for macro starting on line %d\n",Getline(value)); + Swig_error(Getfile(s),-1,"Missing %%enddef for macro starting on line %d\n",Getline(value)); } if ((state >= 105) && (state < 107)) { - cpp_error(Getfile(s),-1,"Unterminated %%{ ... %%} block starting on line %d\n", start_line); + Swig_error(Getfile(s),-1,"Unterminated %%{ ... %%} block starting on line %d\n", start_line); } if ((state >= 30) && (state < 40)) { - cpp_error(Getfile(s),-1,"Unterminated comment starting on line %d\n", start_line); + Swig_error(Getfile(s),-1,"Unterminated comment starting on line %d\n", start_line); } add_chunk(ns,chunk,allow); copy_location(s,chunk); diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c index 13ca42d96..39a54149c 100644 --- a/Source/Preprocessor/expr.c +++ b/Source/Preprocessor/expr.c @@ -10,7 +10,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_expr_c[] = "$Header$"; #include "preprocessor.h" @@ -19,6 +19,7 @@ static SwigScanner *scan = 0; typedef struct { int op; long value; + String *svalue; } exprval; #define EXPR_TOP 1 @@ -66,95 +67,122 @@ static void reduce_op() { sp = 0; return; } - switch(stack[sp-1].value) { - case SWIG_TOKEN_STAR: - stack[sp-2].value = stack[sp-2].value * stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_EQUALTO: - stack[sp-2].value = stack[sp-2].value == stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_NOTEQUAL: - stack[sp-2].value = stack[sp-2].value != stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_PLUS: - stack[sp-2].value = stack[sp-2].value + stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_MINUS: - stack[sp-2].value = stack[sp-2].value - stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_AND: - stack[sp-2].value = stack[sp-2].value & stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LAND: - stack[sp-2].value = stack[sp-2].value && stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_OR: - stack[sp-2].value = stack[sp-2].value | stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LOR: - stack[sp-2].value = stack[sp-2].value || stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_XOR: - stack[sp-2].value = stack[sp-2].value ^ stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LESSTHAN: - stack[sp-2].value = stack[sp-2].value < stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_GREATERTHAN: - stack[sp-2].value = stack[sp-2].value > stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LTEQUAL: - stack[sp-2].value = stack[sp-2].value <= stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_GTEQUAL: - stack[sp-2].value = stack[sp-2].value >= stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_NOT: - stack[sp-1].value = ~stack[sp].value; - sp--; - break; - case SWIG_TOKEN_LNOT: - stack[sp-1].value = !stack[sp].value; - sp--; - break; - case EXPR_UMINUS: - stack[sp-1].value = -stack[sp].value; - sp--; - break; - case SWIG_TOKEN_SLASH: - stack[sp-2].value = stack[sp-2].value / stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_PERCENT: - stack[sp-2].value = stack[sp-2].value % stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LSHIFT: - stack[sp-2].value = stack[sp-2].value << stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_RSHIFT: - stack[sp-2].value = stack[sp-2].value >> stack[sp].value; - sp -= 2; - break; - default: - errmsg = "Syntax error"; - sp = 0; - break; + if (stack[sp-2].svalue || stack[sp].svalue) { + /* A string expression */ + if (!(stack[sp-2].svalue && stack[sp].svalue)) { + errmsg = "Can't mix strings and integers in expression"; + sp = 0; + return; + } + switch(stack[sp-1].value) { + case SWIG_TOKEN_EQUALTO: + stack[sp-2].value = (Strcmp(stack[sp-2].svalue,stack[sp].svalue) == 0); + Delete(stack[sp-2].svalue); + Delete(stack[sp].svalue); + sp -= 2; + break; + case SWIG_TOKEN_NOTEQUAL: + stack[sp-2].value = (Strcmp(stack[sp-2].svalue,stack[sp].svalue) != 0); + Delete(stack[sp-2].svalue); + Delete(stack[sp].svalue); + sp -= 2; + break; + default: + errmsg = "Syntax error"; + sp = 0; + break; + } + } else { + switch(stack[sp-1].value) { + case SWIG_TOKEN_STAR: + stack[sp-2].value = stack[sp-2].value * stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_EQUALTO: + stack[sp-2].value = stack[sp-2].value == stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_NOTEQUAL: + stack[sp-2].value = stack[sp-2].value != stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_PLUS: + stack[sp-2].value = stack[sp-2].value + stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_MINUS: + stack[sp-2].value = stack[sp-2].value - stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_AND: + stack[sp-2].value = stack[sp-2].value & stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_LAND: + stack[sp-2].value = stack[sp-2].value && stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_OR: + stack[sp-2].value = stack[sp-2].value | stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_LOR: + stack[sp-2].value = stack[sp-2].value || stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_XOR: + stack[sp-2].value = stack[sp-2].value ^ stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_LESSTHAN: + stack[sp-2].value = stack[sp-2].value < stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_GREATERTHAN: + stack[sp-2].value = stack[sp-2].value > stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_LTEQUAL: + stack[sp-2].value = stack[sp-2].value <= stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_GTEQUAL: + stack[sp-2].value = stack[sp-2].value >= stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_NOT: + stack[sp-1].value = ~stack[sp].value; + sp--; + break; + case SWIG_TOKEN_LNOT: + stack[sp-1].value = !stack[sp].value; + sp--; + break; + case EXPR_UMINUS: + stack[sp-1].value = -stack[sp].value; + sp--; + break; + case SWIG_TOKEN_SLASH: + stack[sp-2].value = stack[sp-2].value / stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_PERCENT: + stack[sp-2].value = stack[sp-2].value % stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_LSHIFT: + stack[sp-2].value = stack[sp-2].value << stack[sp].value; + sp -= 2; + break; + case SWIG_TOKEN_RSHIFT: + stack[sp-2].value = stack[sp-2].value >> stack[sp].value; + sp -= 2; + break; + default: + errmsg = "Syntax error"; + sp = 0; + break; + } } stack[sp].op = EXPR_VALUE; } @@ -187,6 +215,7 @@ Preprocessor_expr(DOH *s, int *error) { assert(scan); Seek(s,0,SEEK_SET); + /* Printf(stdout,"evaluating : '%s'\n", s); */ *error = 0; SwigScanner_clear(scan); SwigScanner_push(scan,s); @@ -208,7 +237,10 @@ Preprocessor_expr(DOH *s, int *error) { } if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) { /* A number. Reduce EXPR_TOP to an EXPR_VALUE */ - stack[sp].value = (long) atol(Char(SwigScanner_text(scan))); + char *c = Char(SwigScanner_text(scan)); + stack[sp].value = (long) strtol(c,0,0); + stack[sp].svalue = 0; + /* stack[sp].value = (long) atol(Char(SwigScanner_text(scan))); */ stack[sp].op = EXPR_VALUE; } else if (token == SWIG_TOKEN_PLUS) { } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_LNOT) || (token==SWIG_TOKEN_NOT)) { @@ -216,12 +248,21 @@ Preprocessor_expr(DOH *s, int *error) { stack[sp].value = token; stack[sp++].op = EXPR_OP; stack[sp].op = EXPR_TOP; + stack[sp].svalue = 0; } else if ((token == SWIG_TOKEN_LPAREN)) { stack[sp++].op = EXPR_GROUP; stack[sp].op = EXPR_TOP; stack[sp].value = 0; - } else if (token == SWIG_TOKEN_ENDLINE) { } - else goto syntax_error; + stack[sp].svalue = 0; + } else if (token == SWIG_TOKEN_ENDLINE) { + } else if ((token == SWIG_TOKEN_STRING)) { + stack[sp].svalue = NewString(SwigScanner_text(scan)); + stack[sp].op = EXPR_VALUE; + } else if ((token == SWIG_TOKEN_ID)) { + stack[sp].value = 0; + stack[sp].svalue = 0; + stack[sp].op = EXPR_VALUE; + } else goto syntax_error; break; case EXPR_VALUE: /* A value is on the stack. We may reduce or evaluate depending on what the next token is */ @@ -302,6 +343,7 @@ Preprocessor_expr(DOH *s, int *error) { break; } break; + default: fprintf(stderr,"Internal error in expression evaluator.\n"); abort(); diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h index a32501164..eb4f8feda 100644 --- a/Source/Preprocessor/preprocessor.h +++ b/Source/Preprocessor/preprocessor.h @@ -15,19 +15,21 @@ #define _PREPROCESSOR_H #include "swig.h" +#include "swigwarn.h" #ifdef __cplusplus extern "C" { #endif - -extern void Preprocessor_expr_init(void); -extern int Preprocessor_expr(DOHString *s, int *error); -extern char *Preprocessor_expr_error(void); -extern DOH *Preprocessor_define(DOHString_or_char *str, int swigmacro); -extern void Preprocessor_undef(DOHString_or_char *name); -extern void Preprocessor_init(); -extern DOH *Preprocessor_parse(DOH *s); -extern void Preprocessor_include_all(int); +extern int Preprocessor_expr(String *s, int *error); +extern char *Preprocessor_expr_error(void); +extern Hash *Preprocessor_define(const String_or_char *str, int swigmacro); +extern void Preprocessor_undef(String_or_char *name); +extern void Preprocessor_init(); +extern String *Preprocessor_parse(String *s); +extern void Preprocessor_include_all(int); +extern void Preprocessor_import_all(int); +extern void Preprocessor_ignore_missing(int); +extern List *Preprocessor_depend(void); #ifdef __cplusplus } diff --git a/Source/README b/Source/README new file mode 100644 index 000000000..db46fd03d --- /dev/null +++ b/Source/README @@ -0,0 +1,32 @@ +SWIG Source directory + +This directory currently contains a mix of legacy SWIG1.1 code and +recent development work. As a result, it's still a little messy. +Here is a rough breakdown of the directories: + + Source/DOH - A core set of basic datatypes including + strings, lists, hashes, and files. Used + extensively by the rest of SWIG. + + Source/Swig - Swig core. Type-system, utility functions. + + Source/Preprocessor - SWIG C Preprocessor + + Source/CParse - SWIG C Parser (still messy) + + Source/Modules1.1 - Old SWIG1.1 derived language modules. + Remaining legacy code. + + +The following directories may be in CVS, but are largely deprecated: + + Source/Modules - Some experimental module work. New + modules may be added here eventually. + + Source/LParse - Experimental parser. Officially dead + as CParse is more capable. + + Source/SWIG1.1 - Old SWIG1.1 core. Completely empty now. + + + diff --git a/Source/Swig/Makefile.in b/Source/Swig/Makefile.in index 9503e0ab2..1186c6887 100644 --- a/Source/Swig/Makefile.in +++ b/Source/Swig/Makefile.in @@ -5,10 +5,10 @@ srcdir = @srcdir@ VPATH = @srcdir@ -SRCS = map.c wrapfunc.c naming.c tree.c stype.c scanner.c include.c getopt.c misc.c \ - parms.c cwrap.c typemap.c module.c main.c -OBJS = map.o wrapfunc.o naming.o tree.o stype.o scanner.o include.o getopt.o misc.o \ - parms.o cwrap.o typemap.o module.o main.o +SRCS = wrapfunc.c naming.c tree.c stype.c typesys.c scanner.c include.c getopt.c misc.c \ + parms.c cwrap.c typemap.c warn.c symbol.c error.c fragment.c +OBJS = wrapfunc.@OBJEXT@ naming.@OBJEXT@ tree.@OBJEXT@ stype.@OBJEXT@ typesys.@OBJEXT@ scanner.@OBJEXT@ include.@OBJEXT@ getopt.@OBJEXT@ misc.@OBJEXT@ \ + parms.@OBJEXT@ cwrap.@OBJEXT@ typemap.@OBJEXT@ warn.@OBJEXT@ symbol.@OBJEXT@ error.@OBJEXT@ fragment.@OBJEXT@ prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -17,11 +17,11 @@ CC = @CC@ AR = @AR@ RANLIB = @RANLIB@ CFLAGS = @CFLAGS@ -INCLUDE = -I$(srcdir)/. -I$(srcdir)/../DOH/Include -I$(srcdir)/../Include +INCLUDES = -I$(srcdir)/. -I$(srcdir)/../DOH/Include -I$(srcdir)/../Include TARGET = libswig.a -.c.o: - $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $< +.c.@OBJEXT@: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $*.@OBJEXT@ $< all: $(TARGET) @@ -30,4 +30,4 @@ $(TARGET): $(OBJS) $(RANLIB) $(TARGET) clean: - rm -f *.o *~ core *.so *.a *_wrap.* + rm -f *.@OBJEXT@ *~ core *.so *.a *_wrap.* diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index a5fd6d9ba..5abcab2ab 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -13,10 +13,18 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_cwrap_c[] = "$Header$"; #include "swig.h" +static Parm *nonvoid_parms(Parm *p) { + if (p) { + SwigType *t = Getattr(p,"type"); + if (SwigType_type(t) == T_VOID) return 0; + } + return p; +} + /* ----------------------------------------------------------------------------- * Swig_parm_name() * @@ -25,11 +33,11 @@ static char cvsroot[] = "$Header$"; String * Swig_cparm_name(Parm *p, int i) { - String *name = NewStringf("arg%d",i); + String *name = NewStringf("arg%d",i+1); if (p) { - Setlname(p,name); + Setattr(p,"lname",name); } - return Swig_temp_result(name); + return name; } /* ----------------------------------------------------------------------------- @@ -41,99 +49,67 @@ Swig_cparm_name(Parm *p, int i) { String * Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value) { - String *decl = 0; + String *decl; - /* *((char *) decl) = 'x';*/ decl = NewString(""); + switch(SwigType_type(t)) { - case T_USER: - SwigType_add_pointer(t); - if (value) - Printf(decl,"%s = (%s) &%s", SwigType_lstr(t,name), SwigType_lstr(t,0), value); - else - Printf(decl,"%s", SwigType_lstr(t,name)); - SwigType_del_pointer(t); - break; case T_REFERENCE: - if (value) - Printf(decl,"%s = (%s) &%s", SwigType_lstr(t,name), SwigType_lstr(t,0), value); - else - Printf(decl,"%s", SwigType_lstr(t,name)); + if (value) { + Printf(decl,"%s = (%s) &%s_defvalue", SwigType_lstr(t,name), SwigType_lstr(t,0), name); + } else { + Printf(decl,"%s = 0", SwigType_lstr(t,name)); + } break; case T_VOID: break; + case T_VARARGS: + Printf(decl,"void *%s = 0", name); + break; + default: - if (value) - Printf(decl,"%s = %s", SwigType_lstr(t,name), value); - else + if (value) { + Printf(decl,"%s = (%s) %s", SwigType_lstr(t,name), SwigType_lstr(t,0), SwigType_lcaststr(t,value)); + } else { Printf(decl,"%s", SwigType_lstr(t,name)); + } } - return Swig_temp_result(decl); + return decl; } /* ----------------------------------------------------------------------------- - * Swig_clocal_type() + * Swig_wrapped_var_convert() * - * Creates a string that declares a C local variable type. Converts references - * and user defined types to pointers. + * Converts a member variable for use in the get and set wrapper methods. + * This function only converts user defined types to pointers. * ----------------------------------------------------------------------------- */ -SwigType * -Swig_clocal_type(SwigType *t) { +String * +Swig_wrapped_var_type(SwigType *t) { SwigType *ty; - switch(SwigType_type(t)) { - case T_USER: - SwigType_add_pointer(t); - ty = SwigType_ltype(t); - SwigType_del_pointer(t); - break; - default: - ty = SwigType_ltype(t); - break; + ty = Copy(t); + + if (SwigType_isclass(t)) { + SwigType_add_pointer(ty); } return ty; } -/* ----------------------------------------------------------------------------- - * Swig_clocal_deref() - * - * Creates a string that can be used to deref a local variable wrapped with - * the Swig_clocal() function. - * ----------------------------------------------------------------------------- */ - String * -Swig_clocal_deref(SwigType *t, String_or_char *name) { - switch(SwigType_type(t)) { - case T_USER: - return Swig_temp_result(NewStringf("*%s",name)); - break; - case T_VOID: - return Swig_temp_result(NewString("")); - break; - default: +Swig_wrapped_var_deref(SwigType *t, String_or_char *name) { + if (SwigType_isclass(t)) { + return NewStringf("*%s",name); + } else { return SwigType_rcaststr(t,name); - break; } } -/* ----------------------------------------------------------------------------- - * Swig_clocal_assign() - * - * Assigns a value to a local - * ----------------------------------------------------------------------------- */ - String * -Swig_clocal_assign(SwigType *t, String_or_char *name) { - switch(SwigType_type(t)) { - case T_VOID: - return Swig_temp_result(NewString("")); - break; - case T_USER: - return Swig_temp_result(NewStringf("&%s", name)); - break; - default: +Swig_wrapped_var_assign(SwigType *t, String_or_char *name) { + if (SwigType_isclass(t)) { + return NewStringf("&%s",name); + } else { return SwigType_lcaststr(t,name); - break; } } @@ -151,17 +127,41 @@ int Swig_cargs(Wrapper *w, ParmList *p) { String *pname; String *local; String *lname; + SwigType *altty; + String *type; + int tycode; i = 0; while (p != 0) { lname = Swig_cparm_name(p,i); - pt = Gettype(p); - pname = Getname(p); - pvalue = Getvalue(p); - local = Swig_clocal(pt,lname,pvalue); - Wrapper_add_localv(w,lname,local,0); - i++; - p = Getnext(p); + pt = Getattr(p,"type"); + if ((SwigType_type(pt) != T_VOID)) { + pname = Getattr(p,"name"); + pvalue = Getattr(p,"value"); + altty = Getattr(p,"alttype"); + type = Getattr(p,"type"); + tycode = SwigType_type(type); + if (tycode == T_REFERENCE) { + if (pvalue) { + String *defname, *defvalue; + defname = NewStringf("%s_defvalue", lname); + defvalue = NewStringf("%s = %s", SwigType_str(type,defname), pvalue); + Wrapper_add_localv(w,defname, defvalue, NIL); + Delete(defname); + Delete(defvalue); + } + } else if (!pvalue && (tycode == T_POINTER)) { + pvalue = (String *) "0"; + } + if (!altty) { + local = Swig_clocal(pt,lname,pvalue); + } else { + local = Swig_clocal(altty,lname, pvalue); + } + Wrapper_add_localv(w,lname,local,NIL); + i++; + } + p = nextSibling(p); } return(i); } @@ -173,27 +173,21 @@ int Swig_cargs(Wrapper *w, ParmList *p) { * function call. * ----------------------------------------------------------------------------- */ -void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl) { +String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl) { String *fcall; fcall = NewString(""); - - if (SwigType_type(t) != T_VOID) - Wrapper_add_localv(w,name, Swig_clocal(t,name,0), 0); - switch(SwigType_type(t)) { case T_VOID: break; - case T_USER: - SwigType_add_pointer(t); - Printf(fcall,"%s = (%s) malloc(sizeof(", name, SwigType_lstr(t,0)); - SwigType_del_pointer(t); - Printf(fcall, "%s));\n", SwigType_str(t,0)); - Printf(fcall, "*(%s) = ", name); - break; case T_REFERENCE: + Printf(fcall,"{\n"); Printf(fcall,"%s = ", SwigType_str(t,"_result_ref")); break; + case T_USER: + Printf(fcall,"%s = ", name); + break; + default: /* Normal return value */ Printf(fcall,"%s = (%s)", name, SwigType_lstr(t,0)); @@ -201,7 +195,7 @@ void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char } /* Now print out function call */ - Printv(fcall,decl,0); + Printv(fcall,decl,NIL); /* A sick hack */ { @@ -213,75 +207,9 @@ void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char if (SwigType_type(t) == T_REFERENCE) { Printf(fcall,"%s = (%s) &_result_ref;\n", name, SwigType_lstr(t,0)); + Printf(fcall,"}\n"); } - - if (Replace(w,"$function",fcall, DOH_REPLACE_ANY) == 0) { - Printv(w, fcall, 0); - } - Delete(fcall); -} - -/* ----------------------------------------------------------------------------- - * Swig_cppresult() - * - * This function generates the C++ code needed to set the result. This uses - * the C++ default copy constructor for user defined objects. - * ----------------------------------------------------------------------------- */ - -void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl) { - String *fcall; - - fcall = NewString(""); - if (SwigType_type(t) != T_VOID) - Wrapper_add_localv(w,name, Swig_clocal(t,name,0), 0); - - switch(SwigType_type(t)) { - case T_VOID: - break; - case T_USER: - { - SwigType *temp = Copy(t); - while (SwigType_isconst(temp)) { - SwigType_pop(temp); - } - Printf(fcall, "%s = new %s(", name, SwigType_str(temp,0)); - Delete(temp); - } - break; - case T_REFERENCE: - Printf(fcall, "%s = ", SwigType_str(t,"_result_ref")); - break; - default: - Printf(fcall,"%s = (%s)", name, SwigType_lstr(t,0)); - break; - } - - /* Now print out function call */ - Printv(fcall, decl, 0); - - switch(SwigType_type(t)) { - case T_USER: - Printf(fcall,");\n"); - break; - case T_REFERENCE: - Printf(fcall,";\n"); - Printf(fcall, "%s = (%s) &_result_ref;\n", name, SwigType_lstr(t,0)); - break; - default: - /* A sick hack */ - { - char *c = Char(decl) + Len(decl) - 1; - if (!((*c == ';') || (*c == '}'))) - Printf(fcall, ";"); - } - Printf(fcall,"\n"); - break; - } - - if (Replace(w,"$function",fcall, DOH_REPLACE_ANY) == 0) { - Printv(w, fcall, 0); - } - Delete(fcall); + return fcall; } /* ----------------------------------------------------------------------------- @@ -296,25 +224,31 @@ void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_cha String * Swig_cfunction_call(String_or_char *name, ParmList *parms) { - DOH *func; + String *func; int i = 0; + int comma = 0; Parm *p = parms; SwigType *pt; + String *nname; func = NewString(""); - Printf(func,"%s(", name); + nname = SwigType_namestr(name); + Printf(func,"%s(", nname); while (p) { String *pname; - pt = Gettype(p); - pname = Swig_cparm_name(p,i); - Printf(func,"%s", Swig_clocal_deref(pt, pname)); - i++; - p = Getnext(p); - if (p) - Printf(func,","); + pt = Getattr(p,"type"); + + if ((SwigType_type(pt) != T_VOID)) { + if (comma) Printf(func,","); + pname = Swig_cparm_name(p,i); + Printf(func,"%s", SwigType_rcaststr(pt, pname)); + comma = 1; + i++; + } + p = nextSibling(p); } Printf(func,")"); - return Swig_temp_result(func); + return func; } /* ----------------------------------------------------------------------------- @@ -324,32 +258,58 @@ Swig_cfunction_call(String_or_char *name, ParmList *parms) { * * arg0->name(arg1, arg2, arg3, ..., argn) * + * self is an argument that defines how to handle the first argument. Normally, + * it should be set to "this->". With C++ proxy classes enabled, it could be + * set to "(*this)->" or some similar sequence. * ----------------------------------------------------------------------------- */ String * -Swig_cmethod_call(String_or_char *name, ParmList *parms) { - DOH *func; +Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self) { + String *func, *nname; int i = 0; Parm *p = parms; SwigType *pt; + int comma = 0; + + if (!self) self = (char *) "(this)->"; func = NewString(""); - if (!p) return Swig_temp_result(func); - Printf(func,"%s->%s(", Swig_cparm_name(p,0), name); + nname = SwigType_namestr(name); + if (!p) return func; + Append(func,self); + pt = Getattr(p,"type"); + + /* If the method is invoked through a dereferenced pointer, we don't add any casts + (needed for smart pointers). Otherwise, we cast to the appropriate type */ + + if (Strstr(func,"*this")) { + Replaceall(func,"this", Swig_cparm_name(p,0)); + } else { + Replaceall(func,"this", SwigType_rcaststr(pt, Swig_cparm_name(p,0))); + } + + if (SwigType_istemplate(name)) { + Printf(func,"template %s(", nname); + } else { + Printf(func,"%s(", nname); + } i++; - p = Getnext(p); + p = nextSibling(p); while (p) { String *pname; - pt = Gettype(p); - pname = Swig_cparm_name(p,i); - Printf(func,"%s", Swig_clocal_deref(pt, pname)); - i++; - p = Getnext(p); - if (p) - Printf(func,","); + pt = Getattr(p,"type"); + if ((SwigType_type(pt) != T_VOID)) { + if (comma) Printf(func,","); + pname = Swig_cparm_name(p,i); + Printf(func,"%s", SwigType_rcaststr(pt, pname)); + comma = 1; + i++; + } + p = nextSibling(p); } Printf(func,")"); - return Swig_temp_result(func); + Delete(nname); + return func; } /* ----------------------------------------------------------------------------- @@ -366,7 +326,7 @@ Swig_cconstructor_call(String_or_char *name) { func = NewString(""); Printf(func,"(%s *) calloc(1, sizeof(%s))", name, name); - return Swig_temp_result(func); + return func; } @@ -382,24 +342,30 @@ Swig_cconstructor_call(String_or_char *name) { String * Swig_cppconstructor_call(String_or_char *name, ParmList *parms) { - DOH *func; + String *func; + String *nname; int i = 0; + int comma = 0; Parm *p = parms; SwigType *pt; + nname = SwigType_namestr(name); func = NewString(""); - Printf(func,"new %s(", name); + Printf(func,"new %s(", nname); while (p) { String *pname; - pt = Gettype(p); - pname = Swig_cparm_name(p,i); - Printf(func,"%s", Swig_clocal_deref(pt, pname)); - i++; - p = Getnext(p); - if (p) - Printf(func,","); + pt = Getattr(p,"type"); + if ((SwigType_type(pt) != T_VOID)) { + if (comma) Printf(func,","); + pname = Swig_cparm_name(p,i); + Printf(func,"%s", SwigType_rcaststr(pt, pname)); + comma = 1; + i++; + } + p = nextSibling(p); } Printf(func,")"); - return Swig_temp_result(func); + Delete(nname); + return func; } @@ -413,12 +379,10 @@ Swig_cppconstructor_call(String_or_char *name, ParmList *parms) { String * Swig_cdestructor_call() { - DOH *func; - + String *func; func = NewString(""); - Printf(func,"free((char *) %s)", Swig_cparm_name(0,0)); - return Swig_temp_result(func); + return func; } @@ -432,11 +396,11 @@ Swig_cdestructor_call() { String * Swig_cppdestructor_call() { - DOH *func; + String *func; func = NewString(""); Printf(func,"delete %s", Swig_cparm_name(0,0)); - return Swig_temp_result(func); + return func; } /* ----------------------------------------------------------------------------- @@ -449,22 +413,17 @@ Swig_cppdestructor_call() { * ----------------------------------------------------------------------------- */ String * -Swig_cmemberset_call(String_or_char *name, SwigType *type) { - DOH *func; +Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self) { + String *func; func = NewString(""); - - /* - if (SwigType_type(type) == T_USER) { - Printf(func,"%s %s->%s; ", Swig_clocal_assign(type,""), Swig_cparm_name(0,0), name); - } else { - Printf(func,"%s ", Swig_clocal_assign(type,"")); + if (!self) self = NewString("(this)->"); + else self = NewString(self); + Replaceall(self,"this",Swig_cparm_name(0,0)); + if (SwigType_type(type) != T_ARRAY) { + Printf(func,"if (%s) %s%s = %s",Swig_cparm_name(0,0), self,name, Swig_wrapped_var_deref(type, Swig_cparm_name(0,1))); } - */ - /* Printf(func,"(%s->%s = ", Swig_cparm_name(0,0), name); - Printf(func,"%s)", Swig_clocal_deref(type, (pname = Swig_cparm_name(0,1)))); - */ - Printf(func,"%s->%s = %s",Swig_cparm_name(0,0),name, Swig_clocal_deref(type, Swig_cparm_name(0,1))); - return Swig_temp_result(func); + Delete(self); + return(func); } @@ -478,499 +437,358 @@ Swig_cmemberset_call(String_or_char *name, SwigType *type) { * ----------------------------------------------------------------------------- */ String * -Swig_cmemberget_call(String_or_char *name, SwigType *t) { - DOH *func; - +Swig_cmemberget_call(String_or_char *name, SwigType *t, String_or_char *self) { + String *func; + if (!self) self = NewString("(this)->"); + else self = NewString(self); + Replaceall(self,"this",Swig_cparm_name(0,0)); func = NewString(""); - Printf(func,"%s (%s->%s)", Swig_clocal_assign(t,""),Swig_cparm_name(0,0), name); - return Swig_temp_result(func); -} - - -static void fix_parm_names(ParmList *p) { - int i = 0; - while (p) { - if (!Getname(p)) { - char temp[64]; - sprintf(temp,"arg%d",i); - Setname(p,temp); - } - i++; - p = Getnext(p); - } + Printf(func,"%s (%s%s)", Swig_wrapped_var_assign(t,""),self, name); + Delete(self); + return func; } /* ----------------------------------------------------------------------------- - * Swig_cfunction_wrapper() + * Swig_MethodToFunction(Node *n) * - * This function creates a C wrapper around a C++ method. Returns a Wrapper - * object containing the code, parameters, and so forth. + * Converts a C++ method node to a function accessor function. * ----------------------------------------------------------------------------- */ -Wrapper * -Swig_cfunction_wrapper(String_or_char *funcname, - SwigType *rtype, - ParmList *parms, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; - - w = NewWrapper(); - - /* Set the name of the function */ - Setname(w,funcname); - - l = CopyParmList(parms); - fix_parm_names(l); - Printf(w,"%s %s(%s) {\n", SwigType_str(rtype,0), funcname, ParmList_str(l)); - if (code) { - Printv(w, code, "\n", 0); - } - - Printf(w,"}\n"); - Setattr(w,"type",rtype); - Setattr(w,"parms",l); - Delete(l); - return w; -} - -/* ----------------------------------------------------------------------------- - * Swig_cmethod_wrapper() - * - * This function creates a C wrapper around a C++ method. Returns a Wrapper - * object containing the code, parameters, and so forth. - * ----------------------------------------------------------------------------- */ - -Wrapper * -Swig_cmethod_wrapper(String_or_char *classname, - String_or_char *methodname, - SwigType *rtype, - ParmList *parms, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; +int +Swig_MethodToFunction(Node *n, String *classname, int flags) { + String *name, *qualifier; + ParmList *parms; + SwigType *type; Parm *p; - SwigType *t; + String *self = 0; - w = NewWrapper(); - - /* Set the name of the function */ - Setname(w,Swig_name_member(classname, methodname)); - - l = CopyParmList(parms); - t = NewString(classname); - SwigType_add_pointer(t); - p = NewParm(t,"self"); - Setnext(p,l); - Delete(t); - - l = p; - fix_parm_names(l); - - Printf(w,"%s %s(%s) {\n", SwigType_str(rtype,0), Swig_name_member(classname, methodname), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - if (SwigType_type(rtype) != T_VOID) { - Printf(w,"return "); - } - - Printf(w,"self->%s(", methodname); - p = Getnext(l); - while (p) { - Printf(w,"%s", Getname(p)); - p = Getnext(p); - if (p) - Printf(w,","); - } - Printf(w,");\n"); - Printf(w,"}\n"); - } else { - Printv(w, code, "\n", 0); - Printf(w,"}\n"); + /* If smart pointer, change self derefencing */ + if (flags & CWRAP_SMART_POINTER) { + self = NewString("(*this)->"); } - Setattr(w,"type",rtype); - Setattr(w,"parms",l); - Delete(l); - return w; + /* If node is a member template expansion, we don't allow added code */ + + if (Getattr(n,"templatetype")) flags &= ~(CWRAP_EXTEND); + + name = Getattr(n,"name"); + qualifier = Getattr(n,"qualifier"); + parms = CopyParmList(nonvoid_parms(Getattr(n,"parms"))); + + type = NewString(classname); + if (qualifier) { + SwigType_push(type,qualifier); + } + SwigType_add_pointer(type); + p = NewParm(type,"self"); + Setattr(p,"hidden","1"); + set_nextSibling(p,parms); + Delete(type); + + /* Generate action code for the access */ + if (!(flags & CWRAP_EXTEND)) { + Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cmethod_call(name,p,self))); + } else { + String *code; + String *mangled; + String *membername = Swig_name_member(classname, name); + mangled = Swig_name_mangle(membername); + + code = Getattr(n,"code"); + type = Getattr(n,"type"); + + /* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix + to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined + in C. */ + + if (Getattr(n,"sym:overloaded") && code) { + Append(mangled,Getattr(n,"sym:overname")); + } + + Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cfunction_call(mangled,p))); + + /* See if there is any code that we need to emit */ + if (code) { + String *body; + String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(p)); + body = SwigType_str(type,tmp); + Delete(tmp); + Printv(body,code,"\n",NIL); + Setattr(n,"wrap:code",body); + } + Delete(membername); + Delete(mangled); + } + Setattr(n,"parms",p); + Delete(p); + Delete(self); + return SWIG_OK; } - /* ----------------------------------------------------------------------------- - * Swig_cconstructor_wrapper() + * Swig_ConstructorToFunction() * * This function creates a C wrapper for a C constructor function. * ----------------------------------------------------------------------------- */ -Wrapper * -Swig_cconstructor_wrapper(String_or_char *classname, - ParmList *parms, - String_or_char *code) +int +Swig_ConstructorToFunction(Node *n, String *classname, int cplus, int flags) { - Wrapper *w; - ParmList *l; - SwigType *t; + ParmList *parms; + SwigType *type; + String *membername; + String *mangled; + membername = Swig_name_construct(classname); + mangled = Swig_name_mangle(membername); - w = NewWrapper(); + parms = CopyParmList(nonvoid_parms(Getattr(n,"parms"))); + type = NewString(classname); + SwigType_add_pointer(type); - /* Set the name of the function */ - Setname(w,Swig_name_construct(classname)); - - l = CopyParmList(parms); - t = NewString(classname); - SwigType_add_pointer(t); - - /* Patch up the argument names */ - fix_parm_names(l); - - Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_construct(classname), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"return (%s) calloc(1,sizeof(%s));\n", SwigType_str(t,0), classname); - } else { - Printv(w, code, "\n", 0); - } - Printf(w,"}\n"); - Setattr(w,"type",t); - Setattr(w,"parms",l); - Delete(l); - Delete(t); - return w; -} - -/* ----------------------------------------------------------------------------- - * Swig_cppconstructor_wrapper() - * - * This function creates a C wrapper for a C++ constructor function. - * ----------------------------------------------------------------------------- */ - -Wrapper * -Swig_cppconstructor_wrapper(String_or_char *classname, - ParmList *parms, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; - SwigType *t; - Parm *p; - - w = NewWrapper(); - - /* Set the name of the function */ - Setname(w,Swig_name_construct(classname)); - - l = CopyParmList(parms); - t = NewString(classname); - SwigType_add_pointer(t); - - /* Patch up the argument names */ - fix_parm_names(l); - - Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_construct(classname), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"return new %s", SwigType_str(t,0)); - p = l; - if (p) { - Printf(w,"("); - while (p) { - Printf(w,"%s", Getname(p)); - p = Getnext(p); - if (p) - Printf(w,","); - } - Printf(w,")"); + if (flags & CWRAP_EXTEND) { + String *code = Getattr(n,"code"); + if (code) { + String *wrap; + String *s = NewStringf("%s(%s)", mangled, ParmList_str(parms)); + wrap = SwigType_str(type,s); + Delete(s); + Printv(wrap,code,"\n",NIL); + Setattr(n,"wrap:code",wrap); + Delete(wrap); } - Printf(w,";\n"); + Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(mangled,parms))); } else { - Printv(w, code, "\n", 0); + if (cplus) { + Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cppconstructor_call(classname,parms))); + } else { + Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cconstructor_call(classname))); + } } - Printf(w,"}\n"); - Setattr(w,"type",t); - Setattr(w,"parms",l); - Delete(l); - Delete(t); - return w; + Setattr(n,"type",type); + Setattr(n,"parms", parms); + Delete(type); + Delete(parms); + Delete(mangled); + Delete(membername); + return SWIG_OK; } - /* ----------------------------------------------------------------------------- - * Swig_cdestructor_wrapper() + * Swig_DestructorToFunction() * - * This function creates a C wrapper for a C destructor. + * This function creates a C wrapper for a destructor function. * ----------------------------------------------------------------------------- */ -Wrapper * -Swig_cdestructor_wrapper(String_or_char *classname, - String_or_char *code) +int +Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) { - Wrapper *w; - ParmList *l; - SwigType *t; + SwigType *type; Parm *p; - w = NewWrapper(); + type = NewString(classname); + SwigType_add_pointer(type); + p = NewParm(type,"self"); + Delete(type); + type = NewString("void"); - /* Set the name of the function */ - Setname(w, Swig_name_destroy(classname)); + if (flags & CWRAP_EXTEND) { + String *membername, *mangled, *code; + membername = Swig_name_destroy(classname); + mangled = Swig_name_mangle(membername); + code = Getattr(n,"code"); + if (code) { + String *s = NewStringf("void %s(%s)", mangled, ParmList_str(p)); + Printv(s,code,"\n",NIL); + Setattr(n,"wrap:code",s); + Delete(s); + } + Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,p))); + Delete(membername); + Delete(mangled); + } else { + if (cplus) { + Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cppdestructor_call())); + } else { + Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cdestructor_call())); + } + } + Setattr(n,"type",type); + Setattr(n,"parms", p); + Delete(type); + Delete(p); + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Swig_MembersetToFunction() + * + * This function creates a C wrapper for setting a structure member. + * ----------------------------------------------------------------------------- */ + +int +Swig_MembersetToFunction(Node *n, String *classname, int flags) { + String *name; + ParmList *parms; + Parm *p; + SwigType *t; + SwigType *ty; + SwigType *type; + String *membername; + String *mangled; + String *self= 0; + + if (flags & CWRAP_SMART_POINTER) { + self = NewString("(*this)->"); + } + + name = Getattr(n,"name"); + type = Getattr(n,"type"); + + membername = Swig_name_member(classname, Swig_name_set(name)); + mangled = Swig_name_mangle(membername); t = NewString(classname); SwigType_add_pointer(t); - p = NewParm(t,"self"); - l = p; + parms = NewParm(t,"self"); Delete(t); - t = NewString("void"); + ty = Swig_wrapped_var_type(type); + p = NewParm(ty,name); + set_nextSibling(parms,p); - Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_destroy(classname), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"free((char *) self);\n"); - } else { - Printv(w, code, "\n", 0); + /* If the type is a pointer or reference. We mark it with a special wrap:disown attribute */ + if (SwigType_check_decl(type,"p.")) { + Setattr(p,"wrap:disown","1"); } - Printf(w,"}\n"); - Setattr(w,"type",t); - Setattr(w,"parms",l); - Delete(l); - Delete(t); - return w; + Delete(p); + + if (flags & CWRAP_EXTEND) { + String *code = Getattr(n,"code"); + if (code) { + String *s = NewStringf("void %s(%s)", mangled, ParmList_str(parms)); + Printv(s,code,"\n",NIL); + Setattr(n,"wrap:code",s); + Delete(s); + } + Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,parms))); + } else { + Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cmemberset_call(name,type,self))); + } + Setattr(n,"type","void"); + Setattr(n,"parms", parms); + Delete(parms); + Delete(ty); + Delete(membername); + Delete(mangled); + Delete(self); + return SWIG_OK; } - /* ----------------------------------------------------------------------------- - * Swig_cppdestructor_wrapper() + * Swig_MembergetToFunction() * - * This function creates a C wrapper for a C++ destructor. + * This function creates a C wrapper for setting a structure member. * ----------------------------------------------------------------------------- */ -Wrapper * -Swig_cppdestructor_wrapper(String_or_char *classname, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; +int +Swig_MembergetToFunction(Node *n, String *classname, int flags) { + String *name; + ParmList *parms; SwigType *t; - Parm *p; + SwigType *ty; + SwigType *type; + String *membername; + String *mangled; + String *self = 0; - w = NewWrapper(); + if (flags & CWRAP_SMART_POINTER) { + self = NewString("(*this)->"); + } - /* Set the name of the function */ - Setname(w, Swig_name_destroy(classname)); + name = Getattr(n,"name"); + type = Getattr(n,"type"); + + membername = Swig_name_member(classname, Swig_name_get(name)); + mangled = Swig_name_mangle(membername); t = NewString(classname); SwigType_add_pointer(t); - p = NewParm(t,"self"); - - l = p; + parms = NewParm(t,"self"); Delete(t); - t = NewString("void"); - - Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_destroy(classname), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"delete self;\n"); + ty = Swig_wrapped_var_type(type); + if (flags & CWRAP_EXTEND) { + String *code = Getattr(n,"code"); + if (code) { + String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(parms)); + String *s = SwigType_str(ty,tmp); + Delete(tmp); + Printv(s,code,"\n",NIL); + Setattr(n,"wrap:code",s); + Delete(s); + } + Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cfunction_call(mangled,parms))); } else { - Printv(w, code, "\n", 0); + Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cmemberget_call(name,type,self))); } - Printf(w,"}\n"); - Setattr(w,"type",t); - Setattr(w,"parms",l); - Delete(l); - Delete(t); - return w; + Setattr(n,"type",ty); + Setattr(n,"parms", parms); + Delete(parms); + Delete(ty); + Delete(membername); + Delete(mangled); + return SWIG_OK; } /* ----------------------------------------------------------------------------- - * Swig_cmemberset_wrapper() - * - * This function creates a C wrapper for setting a C++ structure member. - * ----------------------------------------------------------------------------- */ - -Wrapper * -Swig_cmemberset_wrapper(String_or_char *classname, - String_or_char *membername, - SwigType *type, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; - Parm *p; - SwigType *t; - SwigType *lt; - - w = NewWrapper(); - - /* Set the name of the function */ - Setname(w, Swig_name_member(classname, Swig_name_set(membername))); - - t = NewString(classname); - SwigType_add_pointer(t); - p = NewParm(t,"self"); - l = p; - Delete(t); - - lt = Swig_clocal_type(type); - p = NewParm(lt,"value"); - Setnext(l,p); - - Printf(w,"void %s(%s) {\n", Getname(w), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"self->%s = %s;\n", membername, Swig_clocal_deref(lt,"value")); - Printf(w,"return %s self->%s;\n", Swig_clocal_assign(lt,""), membername); - } else { - Printv(w, code, "\n", 0); - } - Printf(w,"}\n"); - /* Wrapper_Settype(w,lt); */ - Setattr(w,"type","void"); - Setattr(w,"parms", l); - Delete(l); - Delete(lt); - return w; -} - - -/* ----------------------------------------------------------------------------- - * Swig_cmemberget_wrapper() - * - * This function creates a C wrapper for getting a structure member - * ----------------------------------------------------------------------------- */ - -Wrapper * -Swig_cmemberget_wrapper(String_or_char *classname, - String_or_char *membername, - SwigType *type, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; - Parm *p; - SwigType *t; - SwigType *lt; - - w = NewWrapper(); - - /* Set the name of the function */ - Setname(w,Swig_name_member(classname, Swig_name_get(membername))); - - t = NewString(classname); - SwigType_add_pointer(t); - p = NewParm(t,"self"); - l = p; - Delete(t); - - lt = Swig_clocal_type(type); - Printf(w,"%s %s(%s) {\n", SwigType_str(lt,0), Getname(w), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"return %s self->%s;", Swig_clocal_assign(lt,""), membername); - } else { - Printv(w, code, "\n", 0); - } - Printf(w,"}\n"); - Setattr(w,"type",lt); - Setattr(w,"parms",l); - Delete(l); - Delete(lt); - return w; -} - -/* ----------------------------------------------------------------------------- - * Swig_cvarset_wrapper() + * Swig_VarsetToFunction() * * This function creates a C wrapper for setting a global variable. * ----------------------------------------------------------------------------- */ -Wrapper * -Swig_cvarset_wrapper(String_or_char *varname, - SwigType *type, - String_or_char *code) -{ - Wrapper *w; - ParmList *l; - Parm *p; - SwigType *lt; +int +Swig_VarsetToFunction(Node *n) { + String *name,*nname; + ParmList *parms; + SwigType *type, *ty; - w = NewWrapper(); + name = Getattr(n,"name"); + type = Getattr(n,"type"); - /* Set the name of the function */ - Setname(w,Swig_name_set(varname)); + nname = SwigType_namestr(name); - lt = Swig_clocal_type(type); - p = NewParm(lt,"value"); - l = p; + ty = Swig_wrapped_var_type(type); + parms = NewParm(ty,"value"); + Delete(ty); - Printf(w,"%s %s(%s) {\n", SwigType_str(lt,0), Getname(w), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"%s = %s;\n", varname, Swig_clocal_deref(lt,"value")); - Printf(w,"return %s;\n", Swig_clocal_assign(lt,varname)); - } else { - Printv(w, code, "\n", 0); - Replace(w,"$target",varname, DOH_REPLACE_ANY); - Replace(w,"$source","value", DOH_REPLACE_ANY); - Replace(w,"$ltype", SwigType_str(lt,""), DOH_REPLACE_ANY); - Replace(w,"$rtype", SwigType_str(type,""), DOH_REPLACE_ANY); - } - Printf(w,"}\n"); - Setattr(w,"type",lt); - Setattr(w,"parms",l); - Delete(l); - Delete(lt); - return w; + Setattr(n,"wrap:action", NewStringf("%s = %s;\n", nname, Swig_wrapped_var_deref(type,Swig_cparm_name(0,0)))); + Setattr(n,"type","void"); + Setattr(n,"parms",parms); + Delete(parms); + Delete(nname); + return SWIG_OK; } /* ----------------------------------------------------------------------------- - * Swig_cvarget_wrapper() + * Swig_VargetToFunction() * - * This function creates a C wrapper for getting a structure member + * This function creates a C wrapper for getting a global variable. * ----------------------------------------------------------------------------- */ -Wrapper * -Swig_cvarget_wrapper(String_or_char *varname, - SwigType *type, - String_or_char *code) -{ - Wrapper *w; - ParmList *l = 0; - SwigType *lt; +int +Swig_VargetToFunction(Node *n) { + String *name, *nname; + SwigType *type, *ty; - w = NewWrapper(); + name = Getattr(n,"name"); + type = Getattr(n,"type"); - /* Set the name of the function */ - Setname(w,Swig_name_get(varname)); + nname = SwigType_namestr(name); + ty = Swig_wrapped_var_type(type); - lt = Swig_clocal_type(type); - - Printf(w,"%s %s(%s) {\n", SwigType_str(lt,0), Getname(w), ParmList_str(l)); - - if (!code) { - /* No code supplied. Write a function manually */ - Printf(w,"return %s;", Swig_clocal_assign(type,varname)); - } else { - Printv(w, code, "\n", 0); - } - Printf(w,"}\n"); - Setattr(w,"type",lt); - Setattr(w,"parms",l); - Delete(l); - Delete(lt); - return w; + Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_wrapped_var_assign(type,nname))); + Setattr(n,"type",ty); + Delattr(n,"parms"); + Delete(nname); + Delete(ty); + return SWIG_OK; } - - - - - diff --git a/Source/Swig/error.c b/Source/Swig/error.c new file mode 100644 index 000000000..a728510eb --- /dev/null +++ b/Source/Swig/error.c @@ -0,0 +1,198 @@ +/* ----------------------------------------------------------------------------- + * error.c + * + * Error handling functions. These are used to issue warnings and + * error messages. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +#include "swig.h" +#include +#include + +char cvsroot_error_c[] = "$Header$"; + +/* ----------------------------------------------------------------------------- + * Commentary on the warning filter. + * + * The warning filter is a string of numbers prefaced by (-) or (+) to + * indicate whether or not a warning message is displayed. For example: + * + * "-304-201-140+210+201" + * + * The filter string is scanned left to right and the first occurrence + * of a warning number is used to determine printing behavior. + * + * The same number may appear more than once in the string. For example, in the + * above string, "201" appears twice. This simply means that warning 201 + * was disabled after it was previously enabled. This may only be temporary + * setting--the first number may be removed later in which case the warning + * is reenabled. + * ----------------------------------------------------------------------------- */ + +static int silence = 0; /* Silent operation */ +static String *filter = 0; /* Warning filter */ +static int warnall = 0; +static int nwarning = 0; + +/* ----------------------------------------------------------------------------- + * Swig_warning() + * + * Issue a warning message + * ----------------------------------------------------------------------------- */ + +void +Swig_warning(int wnum, const String_or_char *filename, int line, const char *fmt, ...) { + String *out; + char *msg; + int wrn = 1; + va_list ap; + if (silence) return; + + va_start(ap,fmt); + + out = NewString(""); + vPrintf(out,fmt,ap); + { + char temp[64], *t; + t = temp; + msg = Char(out); + while (isdigit(*msg)) { + *(t++) = *(msg++); + } + if (t != temp) { + msg++; + wnum = atoi(temp); + } + } + + /* Check in the warning filter */ + if (filter) { + char temp[32]; + char *c; + sprintf(temp,"%d",wnum); + c = Strstr(filter,temp); + if (c) { + if (*(c-1) == '-') wrn = 0; /* Warning disabled */ + if (*(c-1) == '+') wrn = 1; /* Warning enabled */ + } + } + if (warnall || wrn) { + if (wnum) { + Printf(stderr,"%s:%d: Warning(%d): ", filename, line, wnum); + } else { + Printf(stderr,"%s:%d: Warning: ", filename, line, wnum); + } + Printf(stderr,"%s",msg); + nwarning++; + } + Delete(out); + va_end(ap); +} + +/* ----------------------------------------------------------------------------- + * Swig_error() + * + * Issue an error message + * ----------------------------------------------------------------------------- */ + +static int nerrors = 0; + +void +Swig_error(const String_or_char *filename, int line, const char *fmt, ...) { + va_list ap; + + if (silence) return; + + va_start(ap,fmt); + if (line > 0) { + Printf(stderr,"%s:%d: ", filename, line); + } else { + Printf(stderr,"%s:EOF: ", filename); + } + vPrintf(stderr,fmt,ap); + va_end(ap); + nerrors++; +} + +/* ----------------------------------------------------------------------------- + * Swig_error_count() + * + * Returns number of errors received. + * ----------------------------------------------------------------------------- */ + +int +Swig_error_count(void) { + return nerrors; +} + +/* ----------------------------------------------------------------------------- + * Swig_error_silent() + * + * Set silent flag + * ----------------------------------------------------------------------------- */ + +void +Swig_error_silent(int s) { + silence = s; +} + + +/* ----------------------------------------------------------------------------- + * Swig_warnfilter() + * + * Takes a comma separate list of warning numbers and puts in the filter. + * ----------------------------------------------------------------------------- */ + +void +Swig_warnfilter(const String_or_char *wlist, int add) { + char *c; + String *s; + + if (!filter) filter = NewString(""); + s = NewString(wlist); + c = Char(s); + c = strtok(c,", "); + while (c) { + if (isdigit(*c) || (*c == '+') || (*c == '-')) { + if (add) { + Insert(filter,0,c); + if (isdigit(*c)) { + Insert(filter,0,"-"); + } + } else { + char temp[32]; + if (isdigit(*c)) { + sprintf(temp,"-%s",c); + } else { + strcpy(temp,c); + } + Replace(filter,temp,"", DOH_REPLACE_FIRST); + } + } + c = strtok(NULL,", "); + } + Delete(s); +} + +void +Swig_warnall(void) { + warnall = 1; +} + + +/* ----------------------------------------------------------------------------- + * Swig_warn_count() + * + * Return the number of warnings + * ----------------------------------------------------------------------------- */ + +int +Swig_warn_count(void) { + return nwarning; +} + diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c new file mode 100644 index 000000000..b039759a3 --- /dev/null +++ b/Source/Swig/fragment.c @@ -0,0 +1,64 @@ +/* ----------------------------------------------------------------------------- + * fragment.c + * + * This file manages named code fragments. Code fragments are typically + * used to hold helper-code that may or may not be included in the wrapper + * file (depending on what features are actually used in the interface). + * + * By using fragments, it's possible to greatly reduce the amount of + * wrapper code and to generate cleaner wrapper files. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_fragment_c[] = "$Header$"; + +#include "swig.h" + +static Hash *fragments = 0; + +/* ----------------------------------------------------------------------------- + * Swig_fragment_register() + * + * Add a fragment. + * ----------------------------------------------------------------------------- */ + +void +Swig_fragment_register(String *name, String *section, String *code) { + String *ccode; + if (!fragments) { + fragments = NewHash(); + } + ccode = Copy(code); + Setmeta(ccode,"section",Copy(section)); + Setattr(fragments,Copy(name),ccode); +} + +/* ----------------------------------------------------------------------------- + * Swig_fragment_emit() + * + * Emit a fragment + * ----------------------------------------------------------------------------- */ + +void +Swig_fragment_emit(String *name) { + String *code; + if (!fragments) return; + + code = Getattr(fragments,name); + if (code) { + String *section = Getmeta(code,"section"); + if (section) { + File *f = Swig_filebyname(section); + if (!f) { + Swig_error(Getfile(code),Getline(code),"Bad section '%s' for code fragment '%s'\n", section,name); + } else { + Printf(f,"%s\n",code); + } + } + Delattr(fragments,name); + } +} diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c index 7c71bee8b..77f53cf9b 100644 --- a/Source/Swig/getopt.c +++ b/Source/Swig/getopt.c @@ -18,7 +18,7 @@ * Should have cleaner error handling in general. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_getopt_c[] = "$Header$"; #include "swig.h" diff --git a/Source/Swig/include.c b/Source/Swig/include.c index 9d0bc24cd..288bd662d 100644 --- a/Source/Swig/include.c +++ b/Source/Swig/include.c @@ -11,7 +11,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_include_c[] = "$Header$"; #include "swig.h" @@ -19,7 +19,6 @@ static char cvsroot[] = "$Header$"; static List *directories = 0; /* List of include directories */ static String *lastpath = 0; /* Last file that was included */ -static int bytes_read = 0; /* Bytes read */ static String *swiglib = 0; /* Location of SWIG library */ static String *lang_config = 0; /* Language configuration file */ @@ -178,7 +177,6 @@ Swig_read_file(FILE *f) { * Opens a file and returns it as a string. * ----------------------------------------------------------------------------- */ -static int readbytes = 0; String * Swig_include(const String_or_char *name) { FILE *f; @@ -187,20 +185,13 @@ Swig_include(const String_or_char *name) { f = Swig_open(name); if (!f) return 0; str = Swig_read_file(f); - bytes_read = bytes_read + Len(str); fclose(f); Seek(str,0,SEEK_SET); Setfile(str,lastpath); Setline(str,1); - readbytes += Len(str); return str; } -int -Swig_bytes_read() { - return readbytes; -} - /* ----------------------------------------------------------------------------- * Swig_insert_file() * @@ -249,4 +240,82 @@ Swig_filebyname(const String_or_char *filename) { return Getattr(named_files,filename); } +/* ----------------------------------------------------------------------------- + * Swig_file_suffix() + * + * Returns the suffix of a file + * ----------------------------------------------------------------------------- */ +char * +Swig_file_suffix(const String_or_char *filename) { + char *d; + char *c = Char(filename); + if (strlen(c)) { + d = c + Len(filename) - 1; + while (d != c) { + if (*d == '.') return d; + d--; + } + return c+Len(filename); + } + return c; +} + +/* ----------------------------------------------------------------------------- + * Swig_file_basename() + * + * Returns the filename with no suffix attached. + * ----------------------------------------------------------------------------- */ + +char * +Swig_file_basename(const String_or_char *filename) +{ + static char tmp[1024]; + char *c; + strcpy(tmp,Char(filename)); + c = Swig_file_suffix(tmp); + *c = 0; + return tmp; +} + +/* ----------------------------------------------------------------------------- + * Swig_file_filename() + * + * Return the file with any leading path stripped off + * ----------------------------------------------------------------------------- */ +char * +Swig_file_filename(const String_or_char *filename) +{ + static char tmp[1024]; + const char *delim = SWIG_FILE_DELIMETER; + char *c; + + strcpy(tmp,Char(filename)); + if ((c=strrchr(tmp,*delim))) return c+1; + else return tmp; +} + +/* ----------------------------------------------------------------------------- + * Swig_file_dirname() + * + * Return the name of the directory associated with a file + * ----------------------------------------------------------------------------- */ +char * +Swig_file_dirname(const String_or_char *filename) +{ + static char tmp[1024]; + const char *delim = SWIG_FILE_DELIMETER; + char *c; + strcpy(tmp,Char(filename)); + if (!strstr(tmp,delim)) { + return ""; + } + c = tmp + strlen(tmp) -1; + while (*c != *delim) c--; + *(++c) = 0; + return tmp; +} + + + + diff --git a/Source/Swig/main.c b/Source/Swig/main.c deleted file mode 100644 index 623d1a442..000000000 --- a/Source/Swig/main.c +++ /dev/null @@ -1,103 +0,0 @@ -/* ----------------------------------------------------------------------------- - * main.c - * - * SWIG main program. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1999-2000. The University of Chicago - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -#include "swigconfig.h" -#include "swigver.h" -#include "swig.h" - -static char *usage = (char*)"\ -\nGeneral Options\n\ - -version - Print SWIG version number\n\ - -help - This output.\n\n"; - -/* ----------------------------------------------------------------------------- - * Swig_main() - * - * Entry point to SWIG. This should only be called after all of the available - * modules have been registered (presumably by the real main function). - * ----------------------------------------------------------------------------- */ - -int Swig_main(int argc, char **argv, char **modules) { - int i; - int help = 0; - int freeze = 0; - Hash *top = 0; - - /* Initialize the SWIG core */ - Swig_init(); - Swig_init_args(argc,argv); - - /* Look for command line options */ - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i],"-freeze") == 0) { - freeze= 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-version") == 0) { - fprintf(stderr,"\nSWIG Version %s %s\n", - SWIG_VERSION, SWIG_SPIN); - fprintf(stderr,"Copyright (c) 1995-1998, University of Utah and the Regents of the University of California\n"); - fprintf(stderr,"Copyright (c) 1998-2000, University of Chicago\n"); - Swig_exit (EXIT_SUCCESS); - } else if (strcmp(argv[i],"-help") == 0) { - Printf(stderr,"%s",usage); - Swig_mark_arg(i); - help = 1; - } else { - if (!Swig_check_marked(i)) { - Module *m; - m = Swig_load_module(argv[i]+1); - if (m) { - Swig_mark_arg(i); - Swig_init_module(m, argc, argv); - } - } - } - } - } - - /* Load the default modules (always enabled) */ - if (modules) { - int i = 0; - while (modules[i]) { - Module *m; - m = Swig_load_module(modules[i]); - if (m) { - Swig_init_module(m,argc,argv); - } else { - Printf(stderr,"Swig: default module '%s' not found!\n", modules[i]); - } - i++; - } - } - - if (help) Swig_exit(EXIT_SUCCESS); - /* Check the arguments */ - Swig_check_options(); - - /* Get the input file name and create a starting node */ - top = NewHash(); - Settag(top,"swig:initial"); - Setname(top,argv[argc-1]); - - /* Run the modules */ - Swig_run_modules(top); - - while(freeze); - return 0; -} - -void Swig_exit(int n) { - exit(n); -} - - - diff --git a/Source/Swig/map.c b/Source/Swig/map.c deleted file mode 100644 index f1384ba8a..000000000 --- a/Source/Swig/map.c +++ /dev/null @@ -1,352 +0,0 @@ -/* ----------------------------------------------------------------------------- - * map.c - * - * This file provides support for defining %map rules that match lists of - * parameters to objects defining code generation rules. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1999-2000. The University of Chicago - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -static char cvsroot[] = "$Header$"; - -#include "swig.h" - -/* ----------------------------------------------------------------------------- - * Synopsis - * - * One of the problems in creating wrappers is that of defining rules for - * managing various datatypes and function parameters. In SWIG1.1, - * this sort of customization was managed using a mechanism known as - * "typemaps". This module generalizes the idea even further and provides - * generic set of functions that can be used to define and match rules - * that are associated with lists of datatypes. - * - * The functions in this file are intended to be rather generic. They are only - * responsible for the storage and matching of rules. Other parts of the - * code can use these to implement typemaps, argmaps, or anything else. - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * Swig_map_add_parmrule() - * - * Adds a new mapping rule for a list of parameters. The parms input to this - * function should be a properly constructed parameter list with associated - * attributes (type and name). The 'obj' attribute can be any DOH object. - * - * The structure of how data might be stored is as follows: - * - * ruleset (hash) - * -------------- - * parm1 ---------> rule (hash) - * ------------- - * parm2 -----------> rule (hash) - * *obj* --> obj ------------ - * parm3 - * *obj* -->obj - * - * For multiple arguments, we end up building a large tree of hash tables. - * The object will be stored in the *obj* attribute of the last hash table. - * ----------------------------------------------------------------------------- */ - -void -Swig_map_add_parmrule(Hash *ruleset, Hash *parms, DOH *obj) -{ - Hash *p, *n; - - /* Walk down the parms list and create a series of hash tables */ - p = parms; - n = ruleset; - - while (p) { - String *ty, *name, *key; - Hash *nn; - ty = Getattr(p,"type"); - name = Getattr(p,"name"); - - /* Create a hash table key */ - - key = NewStringf("*map:%s-%s",name,ty); - - /* See if there is already a entry with this type in the table */ - nn = Getattr(n,key); - if (!nn) { - /* No. Go ahead and create it */ - nn = NewHash(); - Setattr(n,key,nn); - } - Delete(key); - n = nn; - p = Swig_next(p); - } - - /* No more parameters. At this point, n points to the very last hash table in our search. - We'll stick our object there */ - - Setattr(n,"*obj*",obj); -} - -/* ----------------------------------------------------------------------------- - * Swig_map_add_typerule() - * - * Adds a rule for a single type and name. - * ----------------------------------------------------------------------------- */ - -void -Swig_map_add_typerule(Hash *ruleset, DOH *type, String_or_char *name, DOH *obj) { - Hash *p; - - p = NewHash(); - Setattr(p,"type",type); - if (name) - Setattr(p,"name", name); - - Swig_map_add_parmrule(ruleset,p,obj); - Delete(p); -} - -typedef struct MatchObject { - Hash *ruleset; /* Hash table of rules */ - Hash *p; /* Parameter on which checking starts */ - int depth; /* Depth of the match */ - struct MatchObject *next; /* Next match object */ -} MatchObject; - - -static MatchObject *matchstack = 0; - -/* ----------------------------------------------------------------------------- - * Swig_map_match_parms() - * - * Perform a longest map match for a list of parameters and a set of mapping rules. - * Returns the corresponding rule object and the number of parameters that were - * matched. - * - * Note: If the ruleset has a 'parent' attribute, this function will walk its - * way up and try to find a match. This can be used to implement scoped - * mappings. - * ----------------------------------------------------------------------------- */ - -DOH * -Swig_map_match_parms(Hash *ruleset, Hash *parms, int *nmatch) -{ - MatchObject *mo; - - DOH *bestobj = 0; - int bestdepth = -1; - - *nmatch = 0; - - mo = (MatchObject *) malloc(sizeof(MatchObject)); - mo->ruleset = ruleset; - mo->depth = 0; - mo->p = parms; - mo->next = 0; - - matchstack = mo; - - /* Loop over all candidates until we find the best one */ - - while (matchstack) { - Hash *rs; - Hash *p; - int depth = 0; - DOH *obj; - String *key; - String *ty; - String *name; - String *nm; - int matched = 0; - - mo = matchstack; - /* See if there is a match at this level */ - rs = mo->ruleset; - obj = Getattr(rs,"*obj*"); - if (obj) { - if (mo->depth > bestdepth) { - bestdepth = mo->depth; - bestobj = obj; - } - } - p = mo->p; - - /* No more parameters. Oh well */ - if (!p) { - matchstack = mo->next; - free(mo); - continue; - } - - /* Generate some keys for checking the next parameter */ - - depth = mo->depth; - name = Getattr(p,"name"); - ty = Getattr(p,"type"); - - - if (!SwigType_isarray(ty)) { - key = NewStringf("*map:-%s",ty); - /* See if there is a generic name match for this type */ - nm = Getattr(rs,key); - if (nm) { - /* Yes! Add to our stack. Just reuse mo for this */ - mo->ruleset = nm; - mo->p = Swig_next(p); - mo->depth++; - mo = 0; - matched++; - } - - /* See if there is a specific name match for this type */ - Clear(key); - Printf(key,"*map:%s-%s",name,ty); - nm = Getattr(rs,key); - if (nm) { - if (!mo) { - mo = (MatchObject *) malloc(sizeof(MatchObject)); - mo->next = matchstack; - matchstack = mo; - } - mo->ruleset = nm; - mo->p = Swig_next(p); - mo->depth = depth+1; - matched++; - } - Delete(key); - } else { - /* The next parameter is an array. This is pretty nasty because we have to do a bunch of checks - related to array indices */ - - int ndim; - int i, j, n; - int ncheck; - String *ntype; - - key = NewString(""); - - /* Drop the mo record. This is too complicated */ - matchstack = mo->next; - free(mo); - mo = 0; - - /* Get the number of array dimensions */ - ndim = SwigType_array_ndim(ty); - - /* First, we test all of the generic-unnamed parameters */ - ncheck = 1 << ndim; - - j = ncheck-1; - for (i = 0; i < ncheck; i++, j--) { - int k = j; - ntype = Copy(ty); - for (n = 0; n < ndim; n++, k = k >> 1) { - if (k & 1) { - SwigType_array_setdim(ntype,n,""); - } - } - Clear(key); - Printf(key,"*map:-%s",ntype); - Printf(stdout,"matcharray : %s\n", key); - nm = Getattr(rs,key); - if (nm) { - mo = (MatchObject *) malloc(sizeof(MatchObject)); - mo->ruleset = nm; - mo->p = Swig_next(p); - mo->depth = depth+1; - mo->next = matchstack; - matchstack = mo; - matched++; - mo = 0; - } - Delete(ntype); - } - - /* Next check all of the named parameters */ - ncheck = 1 << ndim; - - j = ncheck-1; - for (i = 0; i < ncheck; i++, j--) { - int k = j; - ntype = Copy(ty); - for (n = 0; n < ndim; n++, k = k >> 1) { - if (k & 1) { - SwigType_array_setdim(ntype,n,""); - } - } - Clear(key); - Printf(key,"*map:%s-%s",name,ntype); - Printf(stdout,"matcharray : %s\n", key); - nm = Getattr(rs,key); - if (nm) { - mo = (MatchObject *) malloc(sizeof(MatchObject)); - mo->ruleset = nm; - mo->p = Swig_next(p); - mo->depth = depth+1; - mo->next = matchstack; - matchstack = mo; - matched++; - mo = 0; - } - Delete(ntype); - } - Delete(key); - } - if ((!matched) && mo) { - matchstack = mo->next; - free(mo); - } - } - if (bestobj) { - *nmatch = bestdepth; - } else { - /* If there is no match at all. I guess we can check for a default type */ - DOH *rs; - String *key; - String *dty = SwigType_default(Getattr(parms,"type")); - key = NewStringf("*map:-%s",dty); - - rs = Getattr(ruleset,key); - if (rs) { - bestobj = Getattr(rs,"*obj*"); - if (bestobj) *nmatch = 1; - } - Delete(key); - Delete(dty); - } - if (!bestobj) { - DOH *prules = Getattr(ruleset,"parent"); - if (prules) { - bestobj = Swig_map_match_parms(prules,parms,nmatch); - } - } - return bestobj; -} - -/* ----------------------------------------------------------------------------- - * Swig_map_match_type() - * - * Match a rule for a single type - * ----------------------------------------------------------------------------- */ - -DOH * -Swig_map_match_type(Hash *ruleset, DOH *type, String_or_char *name) { - Hash *p; - DOH *obj; - int nmatch; - - p = NewHash(); - Setattr(p,"type",type); - if (name) - Setattr(p,"name",name); - - obj = Swig_map_match_parms(ruleset,p,&nmatch); - Delete(p); - return obj; -} - - - - - diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index 7899e4e37..e1217d513 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -9,7 +9,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_misc_c[] = "$Header$"; #include "swig.h" #include "swigver.h" @@ -42,72 +42,16 @@ Swig_banner(File *f) { Printf(f, "/* ----------------------------------------------------------------------------\n\ * This file was automatically generated by SWIG (http://www.swig.org).\n\ - * Version %s %s\n\ + * Version %s\n\ * \n\ * This file is not intended to be easily readable and contains a number of \n\ * coding conventions designed to improve portability and efficiency. Do not make\n\ * changes to this file unless you know what you are doing--modify the SWIG \n\ * interface file instead. \n\ - * ----------------------------------------------------------------------------- */\n\n", SWIG_VERSION, SWIG_SPIN); + * ----------------------------------------------------------------------------- */\n\n", SWIG_VERSION); } -/* ----------------------------------------------------------------------------- - * Swig_section() - * - * Print a comment denoting a section of wrapper code - * ----------------------------------------------------------------------------- */ - -void Swig_section(File *f, const String_or_char *name) { - Printf(f,"/* -----------------------------------------------------------------------------\n"); - Printf(f," * %s\n", name); - Printf(f," * ----------------------------------------------------------------------------- */\n"); -} - -/* ----------------------------------------------------------------------------- - * Swig_temp_result() - * - * This function is used to return a "temporary" result--a result that is only - * guaranteed to exist for a short period of time. Typically this is used by - * functions that return strings and other intermediate results that are - * used in print statements. - * - * Note: this is really a bit of a kludge to make it easier to work with - * temporary variables (so that the caller doesn't have to worry about - * memory management). In theory, it is possible to break this if an - * operation produces so many temporaries that it overflows the internal - * array before they are used. However, in practice, this would only - * occur for very deep levels of recursion or functions taking lots of - * parameters---neither of which occur very often in SWIG (if at all). - * Also, a user can prevent destruction of a temporary object by increasing - * it's reference count using DohIncref(). - * - * It is an error to place two identical results onto this list. It is also - * an error for a caller to free anything returned by this function. - * - * Note: SWIG1.1 did something similar to this in a less-organized manner. - * ----------------------------------------------------------------------------- */ - -#define MAX_RESULT 512 - -static DOH *results[MAX_RESULT]; -static int results_index = 0; -static int results_init = 0; - -DOH *Swig_temp_result(DOH *x) { - int i; - if (!results_init) { - for (i = 0; i < MAX_RESULT; i++) results[i] = 0; - results_init = 1; - } - /* Printf(stdout,"results_index = %d, %x, '%s'\n", results_index, x, x); */ - if (results[results_index]) Delete(results[results_index]); - results[results_index] = x; - results_index = (results_index + 1) % MAX_RESULT; - return x; -} - - /* ----------------------------------------------------------------------------- * Swig_string_escape() * @@ -142,7 +86,108 @@ String *Swig_string_escape(String *s) { } return ns; } - + + +/* ----------------------------------------------------------------------------- + * Swig_string_upper() + * + * Takes a string object and convets it to all caps. + * ----------------------------------------------------------------------------- */ + +String *Swig_string_upper(String *s) { + String *ns; + int c; + ns = NewString(""); + + while ((c = Getc(s)) != EOF) { + Putc(toupper(c),ns); + } + return ns; +} + +/* ----------------------------------------------------------------------------- + * Swig_string_lower() + * + * Takes a string object and convets it to all lower. + * ----------------------------------------------------------------------------- */ + +String *Swig_string_lower(String *s) { + String *ns; + int c; + ns = NewString(""); + + while ((c = Getc(s)) != EOF) { + Putc(tolower(c),ns); + } + return ns; +} + + +/* ----------------------------------------------------------------------------- + * Swig_string_title() + * + * Takes a string object and convets it to all lower. + * ----------------------------------------------------------------------------- */ + +String *Swig_string_title(String *s) { + String *ns; + int first = 1; + int c; + ns = NewString(""); + + while ((c = Getc(s)) != EOF) { + Putc(first ? toupper(c) : tolower(c),ns); + first = 0; + } + return ns; +} + +/* ----------------------------------------------------------------------------- + * Swig_string_typecode() + * + * Takes a string with possible type-escapes in it and replaces them with + * real C datatypes. + * ----------------------------------------------------------------------------- */ + +String *Swig_string_typecode(String *s) { + String *ns; + int c; + String *tc; + ns = NewString(""); + while ((c = Getc(s)) != EOF) { + if (c == '`') { + tc = NewString(""); + while ((c = Getc(s)) != EOF) { + if (c == '`') break; + Putc(c,tc); + } + Printf(ns,"%s",SwigType_str(tc,0)); + } else { + Putc(c,ns); + if (c == '\'') { + while ((c = Getc(s)) != EOF) { + Putc(c,ns); + if (c == '\'') break; + if (c == '\\') { + c = Getc(s); + Putc(c,ns); + } + } + } else if (c == '\"') { + while ((c = Getc(s)) != EOF) { + Putc(c,ns); + if (c == '\"') break; + if (c == '\\') { + c = Getc(s); + Putc(c,ns); + } + } + } + } + } + return ns; +} + /* ----------------------------------------------------------------------------- * Swig_string_mangle() * @@ -160,28 +205,188 @@ String *Swig_string_mangle(String *s) { } /* ----------------------------------------------------------------------------- - * Swig_proto_cmp() + * Swig_scopename_prefix() * - * Compares a function prototype against an expected type-string. - * For example, Swig_proto_cmp("f(p.void,p.Tcl_Interp,int,p.p.char).int", node) + * Take a qualified name like "A::B::C" and return the scope name. + * In this case, "A::B". Returns NULL if there is no base. * ----------------------------------------------------------------------------- */ -int -Swig_proto_cmp(const String_or_char *pat, DOH *node) { - SwigType *ty; - SwigType *ct; - ParmList *p; - int r; +String * +Swig_scopename_prefix(String *s) { + char tmp[1024]; + char *c, *cc; + if (!Strstr(s,"::")) return 0; + strcpy(tmp,Char(s)); + c = tmp; + cc = c; + while (*c) { + if (strncmp(c,"::",2) == 0) { + cc = c; + c += 2; + } else { + if (*c == '<') { + int level = 1; + c++; + while (*c && level) { + if (*c == '<') level++; + if (*c == '>') level--; + c++; + } + } else { + c++; + } + } + } - ty = Gettype(node); - p = Getparms(node); - if (!ty || !p) return -1; - ct = Copy(ty); - SwigType_add_function(ct,p); - SwigType_strip_qualifiers(ct); - r = Cmp(pat,ct); - Delete(ct); - return r; + *cc = 0; + if (cc != tmp) { + return NewString(tmp); + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * Swig_scopename_last() + * + * Take a qualified name like "A::B::C" and returns the last. In this + * case, "C". + * ----------------------------------------------------------------------------- */ + +String * +Swig_scopename_last(String *s) { + char tmp[1024]; + char *c, *cc; + if (!Strstr(s,"::")) return NewString(s); + strcpy(tmp,Char(s)); + c = tmp; + cc = c; + + while (*c) { + if (strncmp(c,"::",2) == 0) { + cc = c; + c += 2; + } else { + if (*c == '<') { + int level = 1; + c++; + while (*c && level) { + if (*c == '<') level++; + if (*c == '>') level--; + c++; + } + } else { + c++; + } + } + } + return NewString(cc+2); +} + +/* ----------------------------------------------------------------------------- + * Swig_scopename_first() + * + * Take a qualified name like "A::B::C" and returns the first scope name. + * In this case, "A". Returns NULL if there is no base. + * ----------------------------------------------------------------------------- */ + +String * +Swig_scopename_first(String *s) { + char tmp[1024]; + char *c; + if (!Strstr(s,"::")) return 0; + strcpy(tmp,Char(s)); + c = tmp; + while (*c) { + if (strncmp(c,"::",2) == 0) { + break; + } else { + if (*c == '<') { + int level = 1; + c++; + while (*c && level) { + if (*c == '<') level++; + if (*c == '>') level--; + c++; + } + } else { + c++; + } + } + } + if (*c && (c != tmp)) { + *c = 0; + return NewString(tmp); + } else { + return 0; + } +} + + +/* ----------------------------------------------------------------------------- + * Swig_scopename_suffix() + * + * Take a qualified name like "A::B::C" and returns the suffix. + * In this case, "B::C". Returns NULL if there is no suffix. + * ----------------------------------------------------------------------------- */ + +String * +Swig_scopename_suffix(String *s) { + char tmp[1024]; + char *c; + if (!Strstr(s,"::")) return 0; + strcpy(tmp,Char(s)); + c = tmp; + while (*c) { + if (strncmp(c,"::",2) == 0) { + break; + } else { + if (*c == '<') { + int level = 1; + c++; + while (*c && level) { + if (*c == '<') level++; + if (*c == '>') level--; + c++; + } + } else { + c++; + } + } + } + if (*c && (c != tmp)) { + return NewString(c+2); + } else { + return 0; + } +} +/* ----------------------------------------------------------------------------- + * Swig_scopename_check() + * + * Checks to see if a name is qualified with a scope name + * ----------------------------------------------------------------------------- */ + +int Swig_scopename_check(String *s) { + char *c = Char(s); + if (!Strstr(s,"::")) return 0; + while (*c) { + if (strncmp(c,"::",2) == 0) { + return 1; + } else { + if (*c == '<') { + int level = 1; + c++; + while (*c && level) { + if (*c == '<') level++; + if (*c == '>') level--; + c++; + } + } else { + c++; + } + } + } + return 0; } @@ -193,7 +398,20 @@ Swig_proto_cmp(const String_or_char *pat, DOH *node) { void Swig_init() { + /* Set some useful string encoding methods */ DohEncoding("escape", Swig_string_escape); + DohEncoding("upper", Swig_string_upper); + DohEncoding("lower", Swig_string_lower); + DohEncoding("title", Swig_string_title); + DohEncoding("typecode",Swig_string_typecode); + + /* Initialize typemaps */ Swig_typemap_init(); + /* Initialize symbol table */ + Swig_symbol_init(); + + /* Initialize type system */ + SwigType_typesystem_init(); + } diff --git a/Source/Swig/module.c b/Source/Swig/module.c deleted file mode 100644 index 3c5916858..000000000 --- a/Source/Swig/module.c +++ /dev/null @@ -1,210 +0,0 @@ -/* ----------------------------------------------------------------------------- - * module.c - * - * This file implements the SWIG module system. Modules are simply - * pieces of code that manipulate tree objects. Each module is defined - * by 4 quantities: - * - * - Module name (used to select the module on the command line) - * - init function (called with the SWIG command line options). - * - start function (called to launch the module) - * - start tag (starting tag expected by the module) - * - * Currently modules must be statically linked with SWIG. However, it - * is anticipated that the module system may eventually support - * dynamic loading. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1999-2000. The University of Chicago - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" - -#ifdef DYNAMIC_MODULES -#include -#endif - -static char cvsroot[] = "$Header$"; - -struct Module { - String *modname; - int (*initfunc)(int argc, char **argv); - DOH *(*startfunc)(DOH *); - String *starttag; - struct Module *next; -}; - -static Module *Modules = 0; -static Hash *LoadedModules = 0; - -/* ----------------------------------------------------------------------------- - * Swig_register_module() - * - * Register a new module with the system - * ----------------------------------------------------------------------------- */ - -void -Swig_register_module(const String_or_char *modname, const String_or_char *starttag, - int (*initfunc)(int argc, char **argv), - DOH *(*startfunc)(DOH *)) -{ - Module *m; - m = (Module *) malloc(sizeof(Module)); - m->modname = NewString(modname); - m->starttag = NewString(starttag); - m->initfunc = initfunc; - m->startfunc = startfunc; - m->next = Modules; - Modules = m; -} - -/* ----------------------------------------------------------------------------- - * Swig_load_module() - * - * Load a module. Returns the module object. - * ----------------------------------------------------------------------------- */ - -Module * -Swig_load_module(const String_or_char *modname) { - Module *m; - static int dlcheck = 0; - m = Modules; - - while (m) { - if (Cmp(m->modname, modname) == 0) { - /* Create a new entry in the loaded modules table */ - List *ml; - if (!LoadedModules) LoadedModules = NewHash(); - ml = Getattr(LoadedModules,m->starttag); - if (!ml) { - ml = NewList(); - Setattr(LoadedModules,m->starttag,ml); - } - Append(ml,NewVoid(m,0)); - return m; - } - m = m->next; - } - /* Module is not a built-in module. See if we can dynamically load it */ - -#ifdef DYNAMIC_MODULES - if (dlcheck) return 0; - { - DOH *filename; - void *handle; - void (*init)(void) = 0; - char initfunc[256]; - FILE *f; - filename = NewStringf("./swig%s.so", modname); - f = Swig_open(filename); - if (!f) return 0; - fclose(f); - - Clear(filename); - Append(filename,Swig_last_file()); - - sprintf(initfunc,"%smodule",Char(modname)); - handle = dlopen(Char(filename), RTLD_NOW | RTLD_GLOBAL); - if (!handle) { - Printf(stdout,"%s\n", dlerror()); - return 0; - } - - init = (void (*)(void)) dlsym(handle,initfunc); - if (!init) { - Printf(stdout,"Dynamic module %s doesn't define %s()\n", initfunc); - return 0; - } - (*init)(); /* Register function */ - dlcheck = 1; - m = Swig_load_module(modname); - dlcheck = 0; - return m; - } -#else - return 0; -#endif -} - -/* ----------------------------------------------------------------------------- - * Swig_init_module() - * - * Initialize a module - * ----------------------------------------------------------------------------- */ - -int Swig_init_module(Module *m, int argc, char **argv) { - return (*m->initfunc)(argc,argv); -} - -/* ----------------------------------------------------------------------------- - * Swig_start_module() - * - * Start a module - * ----------------------------------------------------------------------------- */ - -DOH * -Swig_start_module(Module *m, DOH *obj) { - return (*m->startfunc)(obj); -} - -/* ----------------------------------------------------------------------------- - * Swig_run_modules() - * - * Given a tree node. This function tries to run it through all of the loaded - * modules. This works by looking at the "tag" attribute of the node and - * searching for a loaded module that can handle that tag. If no module can be - * found, processing stops and an error is generated. - * - * If more than one module can work on a given tag, those modules will be - * executed one after the other. Caveat: if one of those modules outputs - * a different type of tree, processing immediately stops. - * ----------------------------------------------------------------------------- */ - -DOH *Swig_run_modules(DOH *node) { - String *tag; - List *ml; - DOH *newnode; - String *newtag; - int i; - - tag = Getattr(node,"tag"); - if (!tag) { - Printf(stderr,"Whoa. No tag attribute on node passed to Swig_module_run.\n"); - exit(EXIT_FAILURE); - } - /* Get the set of modules that can respond to this node */ - while (node) { - if (!LoadedModules) { - Printf(stderr,"No modules loaded.\n"); - return 0; - } - ml = Getattr(LoadedModules,tag); - if ((!ml) || (Len(ml) == 0)) { - Printf(stderr,"Internal error. No module defined for handling '%s'\n", tag); - return 0; - } - newnode = 0; - newtag = 0; - for (i = 0; i < Len(ml); i++) { - Module *m; - m = (Module *) Data(Getitem(ml,i)); - assert(m); - newnode = (*m->startfunc)(node); - if (!newnode) return node; /* Done */ - newtag = Getattr(newnode,"tag"); - if (!newtag) { - Printf(stderr,"Fatal error. Module '%s' returns untagged object.\n", m->modname); - exit(EXIT_FAILURE); - } - if (Cmp(newtag,tag)) break; /* Tag is different. Oh well */ - } - if (Cmp(newtag,tag) == 0) break; /* Hmmm. The tag is the same but we already did everything */ - node = newnode; - tag = newtag; - } - return 0; -} - - diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 5b82276c3..2aa92db58 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -9,7 +9,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_naming_c[] = "$Header$"; #include "swig.h" #include @@ -25,11 +25,99 @@ static Hash *naming_hash = 0; * ----------------------------------------------------------------------------- */ void -Swig_name_register(String_or_char *method, String_or_char *format) { +Swig_name_register(const String_or_char *method, const String_or_char *format) { if (!naming_hash) naming_hash = NewHash(); Setattr(naming_hash,method,format); } +void +Swig_name_unregister(const String_or_char *method) { + if (naming_hash) { + Delattr(naming_hash,method); + } +} + +static int name_mangle(String *r) { + char *c; + int special; + special = 0; + Replaceall(r,"::","_"); + c = Char(r); + while (*c) { + if (!isalnum(*c) && (*c != '_')) { + special = 1; + switch(*c) { + case '+': + *c = 'a'; + break; + case '-': + *c = 's'; + break; + case '*': + *c = 'm'; + break; + case '/': + *c = 'd'; + break; + case '<': + *c = 'l'; + break; + case '>': + *c = 'g'; + break; + case '=': + *c = 'e'; + break; + case ',': + *c = 'c'; + break; + case '(': + *c = 'p'; + break; + case ')': + *c = 'P'; + break; + case '[': + *c = 'b'; + break; + case ']': + *c = 'B'; + break; + case '^': + *c = 'x'; + break; + case '&': + *c = 'A'; + break; + case '|': + *c = 'o'; + break; + case '~': + *c = 'n'; + break; + case '!': + *c = 'N'; + break; + case '%': + *c = 'M'; + break; + case '.': + *c = 'f'; + break; + case '?': + *c = 'q'; + break; + default: + *c = '_'; + break; + } + } + c++; + } + if (special) Append(r,"___"); + return special; +} + /* ----------------------------------------------------------------------------- * Swig_name_mangle() * @@ -37,16 +125,10 @@ Swig_name_register(String_or_char *method, String_or_char *format) { * ----------------------------------------------------------------------------- */ String * -Swig_name_mangle(String_or_char *s) { - String *r = NewString(""); - char *c; - Append(r,s); - c = Char(r); - while (*c) { - if (!isalnum(*c)) *c = '_'; - c++; - } - return Swig_temp_result(r); +Swig_name_mangle(const String_or_char *s) { + String *r = NewString(s); + name_mangle(r); + return r; } /* ----------------------------------------------------------------------------- @@ -56,7 +138,7 @@ Swig_name_mangle(String_or_char *s) { * ----------------------------------------------------------------------------- */ String * -Swig_name_wrapper(String_or_char *fname) { +Swig_name_wrapper(const String_or_char *fname) { String *r; String *f; @@ -69,8 +151,8 @@ Swig_name_wrapper(String_or_char *fname) { Append(r,f); } Replace(r,"%f",fname, DOH_REPLACE_ANY); - Replace(r,":","_", DOH_REPLACE_ANY); - return Swig_temp_result(r); + name_mangle(r); + return r; } @@ -81,11 +163,13 @@ Swig_name_wrapper(String_or_char *fname) { * ----------------------------------------------------------------------------- */ String * -Swig_name_member(String_or_char *classname, String_or_char *mname) { +Swig_name_member(const String_or_char *classname, const String_or_char *mname) { String *r; String *f; - char *cname, *c; + String *rclassname; + char *cname; + rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"member"); @@ -94,12 +178,17 @@ Swig_name_member(String_or_char *classname, String_or_char *mname) { } else { Append(r,f); } - cname = Char(classname); - c = strchr(cname, ' '); - if (c) cname = c+1; + cname = Char(rclassname); + if ((strncmp(cname,"struct ", 7) == 0) || + ((strncmp(cname,"class ", 6) == 0)) || + ((strncmp(cname,"union ", 6) == 0))) { + cname = strchr(cname, ' ')+1; + } Replace(r,"%c",cname, DOH_REPLACE_ANY); Replace(r,"%m",mname, DOH_REPLACE_ANY); - return Swig_temp_result(r); + /* name_mangle(r);*/ + Delete(rclassname); + return r; } /* ----------------------------------------------------------------------------- @@ -109,7 +198,7 @@ Swig_name_member(String_or_char *classname, String_or_char *mname) { * ----------------------------------------------------------------------------- */ String * -Swig_name_get(String_or_char *vname) { +Swig_name_get(const String_or_char *vname) { String *r; String *f; @@ -122,7 +211,8 @@ Swig_name_get(String_or_char *vname) { Append(r,f); } Replace(r,"%v",vname, DOH_REPLACE_ANY); - return Swig_temp_result(r); + Replace(r,"::","_", DOH_REPLACE_ANY); + return r; } /* ----------------------------------------------------------------------------- @@ -132,7 +222,7 @@ Swig_name_get(String_or_char *vname) { * ----------------------------------------------------------------------------- */ String * -Swig_name_set(String_or_char *vname) { +Swig_name_set(const String_or_char *vname) { String *r; String *f; @@ -145,7 +235,8 @@ Swig_name_set(String_or_char *vname) { Append(r,f); } Replace(r,"%v",vname, DOH_REPLACE_ANY); - return Swig_temp_result(r); + Replace(r,"::","_", DOH_REPLACE_ANY); + return r; } /* ----------------------------------------------------------------------------- @@ -155,10 +246,13 @@ Swig_name_set(String_or_char *vname) { * ----------------------------------------------------------------------------- */ String * -Swig_name_construct(String_or_char *classname) { +Swig_name_construct(const String_or_char *classname) { String *r; String *f; - char *cname, *c; + String *rclassname; + char *cname; + + rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"construct"); @@ -168,14 +262,52 @@ Swig_name_construct(String_or_char *classname) { Append(r,f); } - cname = Char(classname); - c = strchr(cname, ' '); - if (c) cname = c+1; + cname = Char(rclassname); + if ((strncmp(cname,"struct ", 7) == 0) || + ((strncmp(cname,"class ", 6) == 0)) || + ((strncmp(cname,"union ", 6) == 0))) { + cname = strchr(cname, ' ')+1; + } + Replace(r,"%c",cname, DOH_REPLACE_ANY); + Delete(rclassname); + return r; +} + + +/* ----------------------------------------------------------------------------- + * Swig_name_copyconstructor() + * + * Returns the name of the accessor function used to copy an object. + * ----------------------------------------------------------------------------- */ + +String * +Swig_name_copyconstructor(const String_or_char *classname) { + String *r; + String *f; + String *rclassname; + char *cname; + + rclassname = SwigType_namestr(classname); + r = NewString(""); + if (!naming_hash) naming_hash = NewHash(); + f = Getattr(naming_hash,"construct"); + if (!f) { + Append(r,"copy_%c"); + } else { + Append(r,f); + } + + cname = Char(rclassname); + if ((strncmp(cname,"struct ", 7) == 0) || + ((strncmp(cname,"class ", 6) == 0)) || + ((strncmp(cname,"union ", 6) == 0))) { + cname = strchr(cname, ' ')+1; + } Replace(r,"%c",cname, DOH_REPLACE_ANY); - return Swig_temp_result(r); + Delete(rclassname); + return r; } - /* ----------------------------------------------------------------------------- * Swig_name_destroy() @@ -183,10 +315,12 @@ Swig_name_construct(String_or_char *classname) { * Returns the name of the accessor function used to destroy an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_destroy(String_or_char *classname) { +String *Swig_name_destroy(const String_or_char *classname) { String *r; String *f; - char *cname, *c; + String *rclassname; + char *cname; + rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"destroy"); @@ -196,14 +330,297 @@ String *Swig_name_destroy(String_or_char *classname) { Append(r,f); } - cname = Char(classname); - c = strchr(cname, ' '); - if (c) cname = c+1; - + cname = Char(rclassname); + if ((strncmp(cname,"struct ", 7) == 0) || + ((strncmp(cname,"class ", 6) == 0)) || + ((strncmp(cname,"union ", 6) == 0))) { + cname = strchr(cname, ' ')+1; + } Replace(r,"%c",cname, DOH_REPLACE_ANY); - return Swig_temp_result(r); + Delete(rclassname); + return r; +} + +/* ----------------------------------------------------------------------------- + * Swig_name_object_set() + * + * Sets an object associated with a name and optional declarators. + * ----------------------------------------------------------------------------- */ + +void +Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) { + DOH *n; + + /* Printf(stdout,"name: '%s', '%s'\n", name, decl);*/ + n = Getattr(namehash,name); + if (!n) { + n = NewHash(); + Setattr(namehash,name,n); + } + /* Add an object based on the declarator value */ + if (!decl) { + Setattr(n,NewString("*"),object); + } else { + Setattr(n,Copy(decl),object); + } +} + +/* ----------------------------------------------------------------------------- + * Swig_name_object_get() + * + * Return an object associated with an optional class prefix, name, and + * declarator. This function operates according to name matching rules + * described for the %rename directive in the SWIG manual. + * ----------------------------------------------------------------------------- */ + +static DOH *get_object(Hash *n, String *decl) { + DOH *rn = 0; + if (!n) return 0; + if (decl) { + rn = Getattr(n,decl); + } else { + rn = Getattr(n,"*"); + } + return rn; +} + +DOH * +Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) { + String *tname; + DOH *rn = 0; + Hash *n; + char *ncdecl = 0; + + if (!namehash) return 0; + + /* DB: This removed to more tightly control feature/name matching */ + /* if ((decl) && (SwigType_isqualifier(decl))) { + ncdecl = strchr(Char(decl),'.'); + ncdecl++; + } + */ + + /* Perform a class-based lookup (if class prefix supplied) */ + if (prefix) { + if (Len(prefix)) { + tname = NewStringf("%s::%s",prefix,name); + n = Getattr(namehash,tname); + rn = get_object(n,decl); + if ((!rn) && ncdecl) rn = get_object(n,ncdecl); + if (!rn) rn = get_object(n,0); + Delete(tname); + } + /* A wildcard-based class lookup */ + if (!rn) { + tname = NewStringf("*::%s",name); + n = Getattr(namehash,tname); + rn = get_object(n,decl); + if ((!rn) && ncdecl) rn = get_object(n,ncdecl); + if (!rn) rn = get_object(n,0); + Delete(tname); + } + } else { + /* Lookup in the global namespace only */ + tname = NewStringf("::%s",name); + n = Getattr(namehash,tname); + rn = get_object(n,decl); + if ((!rn) && ncdecl) rn = get_object(n,ncdecl); + if (!rn) rn = get_object(n,0); + Delete(tname); + } + /* Catch-all */ + if (!rn) { + n = Getattr(namehash,name); + rn = get_object(n,decl); + if ((!rn) && ncdecl) rn = get_object(n,ncdecl); + if (!rn) rn = get_object(n,0); + } + return rn; +} + +/* ----------------------------------------------------------------------------- + * Swig_name_object_inherit() + * + * Implements name-based inheritance scheme. + * ----------------------------------------------------------------------------- */ + +void +Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { + String *key; + String *bprefix; + String *dprefix; + char *cbprefix; + int plen; + + if (!namehash) return; + + bprefix = NewStringf("%s::",base); + dprefix = NewStringf("%s::",derived); + cbprefix = Char(bprefix); + plen = strlen(cbprefix); + for (key = Firstkey(namehash); key; key = Nextkey(namehash)) { + char *k = Char(key); + if (strncmp(k,cbprefix,plen) == 0) { + Hash *n, *newh; + String *nkey, *okey; + + nkey = NewStringf("%s%s",dprefix,k+plen); + n = Getattr(namehash,key); + newh = Getattr(namehash,nkey); + if (!newh) { + newh = NewHash(); + Setattr(namehash,nkey,newh); + } + for (okey = Firstkey(n); okey; okey = Nextkey(n)) { + String *ovalue = Getattr(n,okey); + if (!Getattr(newh,okey)) { + Setattr(newh,okey,Copy(ovalue)); + } + } + } + } +} + +/* ----------------------------------------------------------------------------- + * Swig_features_get() + * + * Given a node, this function merges features. + * ----------------------------------------------------------------------------- */ + +static void merge_features(Hash *features, Node *n) { + String *key; + if (!features) return; + for (key = Firstkey(features); key; key = Nextkey(features)) { + if (Getattr(n,key)) { + continue; + } + Setattr(n,key,Copy(Getattr(features,key))); + } +} + +void +Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) { + String *tname; + DOH *rn = 0; + Hash *n; + char *ncdecl = 0; + + if (!features) return; + + if ((decl) && (SwigType_isqualifier(decl))) { + ncdecl = strchr(Char(decl),'.'); + ncdecl++; + } + + if (name) { + /* Perform a class-based lookup (if class prefix supplied) */ + if (prefix) { + if (Len(prefix)) { + tname = NewStringf("%s::%s",prefix,name); + n = Getattr(features,tname); + rn = get_object(n,decl); + merge_features(rn,node); + if (ncdecl) { + rn = get_object(n,ncdecl); + merge_features(rn,node); + } + rn = get_object(n,0); + merge_features(rn,node); + Delete(tname); + } + /* A wildcard-based class lookup */ + tname = NewStringf("*::%s",name); + n = Getattr(features,tname); + rn = get_object(n,decl); + merge_features(rn,node); + if (ncdecl) { + rn = get_object(n,ncdecl); + merge_features(rn,node); + } + rn = get_object(n,0); + merge_features(rn,node); + Delete(tname); + + /* A class-generic feature */ + if (Len(prefix)) { + tname = NewStringf("%s::",prefix); + n = Getattr(features,tname); + rn = get_object(n,0); + merge_features(rn,node); + Delete(tname); + } + + } else { + /* Lookup in the global namespace only */ + tname = NewStringf("::%s",name); + n = Getattr(features,tname); + rn = get_object(n,decl); + merge_features(rn,node); + if (ncdecl) { + rn = get_object(n,ncdecl); + merge_features(rn,node); + } + rn = get_object(n,0); + merge_features(rn,node); + Delete(tname); + } + /* Catch-all */ + n = Getattr(features,name); + rn = get_object(n,decl); + merge_features(rn,node); + if (ncdecl) { + rn = get_object(n,ncdecl); + merge_features(rn,node); + } + rn = get_object(n,0); + merge_features(rn,node); + } + /* Global features */ + n = Getattr(features,""); + rn = get_object(n,0); + merge_features(rn,node); + +} + + +/* ----------------------------------------------------------------------------- + * Swig_feature_set() + * + * Sets a feature name and value. + * ----------------------------------------------------------------------------- */ + +void +Swig_feature_set(Hash *features, String *name, SwigType *decl, String *featurename, DOH *value) { + Hash *n; + Hash *fhash; + /* Printf(stdout,"feature: %s %s %s %s\n", name, decl, featurename, value);*/ + + n = Getattr(features,name); + if (!n) { + n = NewHash(); + Setattr(features,name,n); + } + if (!decl) { + fhash = Getattr(n,"*"); + if (!fhash) { + fhash = NewHash(); + Setattr(n,"*",fhash); + } + } else { + fhash = Getattr(n,decl); + if (!fhash) { + fhash = NewHash(); + Setattr(n,Copy(decl),fhash); + } + } + if (value) { + Setattr(fhash,featurename,value); + } else { + Delattr(fhash,featurename); + } } + diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c index db6de504e..2dd8d5fbc 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -14,7 +14,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_parms_c[] = "$Header$"; #include "swig.h" @@ -42,27 +42,36 @@ Parm *NewParm(SwigType *type, String_or_char *n) { Parm *CopyParm(Parm *p) { SwigType *t; - char *name; - char *lname; - char *value; - int ignore; + String *name; + String *lname; + String *value; + String *ignore; + String *alttype; Parm *np = NewHash(); t = Getattr(p,"type"); - name = GetChar(p,"name"); - lname = GetChar(p,"lname"); - value = GetChar(p,"value"); - ignore = GetInt(p,"ignore"); + name = Getattr(p,"name"); + lname = Getattr(p,"lname"); + value = Getattr(p,"value"); + ignore = Getattr(p,"ignore"); + alttype = Getattr(p,"alttype"); - Setattr(np,"type",Copy(t)); + if (t) + Setattr(np,"type",Copy(t)); if (name) - Setattr(np,"name",name); + Setattr(np,"name",Copy(name)); if (lname) - Setattr(np,"lname", lname); + Setattr(np,"lname", Copy(lname)); if (value) - Setattr(np,"value", value); + Setattr(np,"value", Copy(value)); if (ignore) - SetInt(np,"ignore", ignore); + Setattr(np,"ignore", Copy(ignore)); + if (alttype) + Setattr(np,"alttype", Copy(alttype)); + + Setfile(np,Getfile(p)); + Setline(np,Getline(p)); + return np; } @@ -81,12 +90,12 @@ CopyParmList(ParmList *p) { while (p) { np = CopyParm(p); if (pp) { - Setnext(pp,np); + set_nextSibling(pp,np); } else { fp = np; } pp = np; - p = Getnext(p); + p = nextSibling(p); } return fp; } @@ -98,12 +107,29 @@ CopyParmList(ParmList *p) { int ParmList_numarg(ParmList *p) { int n = 0; while (p) { - if (!Getignore(p)) n++; - p = Getnext(p); + if (!Getattr(p,"ignore")) n++; + p = nextSibling(p); } return n; } +/* ----------------------------------------------------------------------------- + * int ParmList_numrequired(). Return number of required arguments + * ----------------------------------------------------------------------------- */ + +int ParmList_numrequired(ParmList *p) { + int i = 0; + while (p) { + SwigType *t = Getattr(p,"type"); + String *value = Getattr(p,"value"); + if (value) return i; + if (!(SwigType_type(t) == T_VOID)) i++; + else break; + p = nextSibling(p); + } + return i; +} + /* ----------------------------------------------------------------------------- * int ParmList_len() * ----------------------------------------------------------------------------- */ @@ -112,7 +138,7 @@ int ParmList_len(ParmList *p) { int i = 0; while (p) { i++; - p = Getnext(p); + p = nextSibling(p); } return i; } @@ -129,13 +155,13 @@ String *ParmList_str(ParmList *p) { out = NewString(""); while(p) { - t = Gettype(p); - Printf(out,"%s", SwigType_str(t,Getname(p))); - p = Getnext(p); + t = Getattr(p,"type"); + Printf(out,"%s", SwigType_str(t,Getattr(p,"name"))); + p = nextSibling(p); if (p) Printf(out,","); } - return Swig_temp_result(out); + return out; } /* --------------------------------------------------------------------- @@ -150,13 +176,17 @@ String *ParmList_protostr(ParmList *p) { out = NewString(""); while(p) { - t = Gettype(p); + if (Getattr(p,"hidden")) { + p = nextSibling(p); + continue; + } + t = Getattr(p,"type"); Printf(out,"%s", SwigType_str(t,0)); - p = Getnext(p); + p = nextSibling(p); if (p) Printf(out,","); } - return Swig_temp_result(out); + return out; } diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index 680db572d..8fc2d0ac4 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -12,7 +12,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_scanner_c[] = "$Header$"; #include "swig.h" #include @@ -598,22 +598,46 @@ look(SwigScanner *s) { if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LONG; if ((c == 'u') || (c == 'U')) { return SWIG_TOKEN_ULONG; + } else if ((c == 'l') || (c == 'L')) { + state = 870; } else { retract(s,1); return SWIG_TOKEN_LONG; } + break; + + /* A long long integer */ + + case 870: + if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LONGLONG; + if ((c == 'u') || (c == 'U')) { + return SWIG_TOKEN_ULONGLONG; + } else { + retract(s,1); + return SWIG_TOKEN_LONGLONG; + } /* An unsigned number */ case 88: if ((c = nextchar(s)) == 0) return SWIG_TOKEN_UINT; if ((c == 'l') || (c == 'L')) { - return SWIG_TOKEN_ULONG; + state = 880; } else { - retract(s,1); - return SWIG_TOKEN_UINT; + retract(s,1); + return SWIG_TOKEN_UINT; } + break; + /* Possibly an unsigned long long or unsigned long */ + case 880: + if ((c = nextchar(s)) == 0) return SWIG_TOKEN_ULONG; + if ((c == 'l') || (c == 'L')) return SWIG_TOKEN_ULONGLONG; + else { + retract(s,1); + return SWIG_TOKEN_ULONG; + } + /* A character constant */ case 9: if ((c = nextchar(s)) == 0) { diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 64ff0ceab..40bac71c8 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -10,7 +10,7 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_stype_c[] = "$Header$"; #include "swig.h" #include @@ -38,12 +38,12 @@ static char cvsroot[] = "$Header$"; * * All type constructors are denoted by a trailing '.': * - * 'p.' = Pointer - * 'r.' = Reference - * 'a(n).' = Array of size n - * 'f(..,..).' = Function with arguments - * 'q(str).' = Qualifier (such as const or volatile) - * 't(...).' = Template specifier??? + * 'p.' = Pointer (*) + * 'r.' = Reference (&) + * 'a(n).' = Array of size n [n] + * 'f(..,..).' = Function with arguments (args) + * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) + * 'm(qual).' = Pointer to member (qual::*) * * The encoding follows the order that you might describe a type in words. * For example "p.a(200).int" is "A pointer to array of int's" and @@ -124,6 +124,18 @@ SwigType *NewSwigType(int t) { case T_UCHAR: return NewString("unsigned char"); break; + case T_STRING: { + SwigType *t = NewString("char"); + SwigType_add_pointer(t); + return t; + break; + } + case T_LONGLONG: + return NewString("long long"); + break; + case T_ULONGLONG: + return NewString("unsigned long long"); + break; case T_VOID: return NewString("void"); break; @@ -147,6 +159,10 @@ SwigType_add_pointer(SwigType *t) { void SwigType_del_pointer(SwigType *t) { char *c = Char(t); + if (strncmp(c,"q(",2) == 0) { + Delete(SwigType_pop(t)); + c = Char(t); + } if (strncmp(c,"p.",2)) { printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n"); abort(); @@ -154,6 +170,19 @@ SwigType_del_pointer(SwigType *t) { Replace(t,"p.","", DOH_REPLACE_ANY | DOH_REPLACE_FIRST); } +/* ----------------------------------------------------------------------------- + * SwigType_add_memberpointer() + * + * Add a pointer to a member to a type + * ----------------------------------------------------------------------------- */ + +void +SwigType_add_memberpointer(SwigType *t, String_or_char *name) { + String *temp = NewStringf("m(%s).", name); + Insert(t,0,temp); + Delete(temp); +} + /* ----------------------------------------------------------------------------- * SwigType_add_array() * @@ -167,6 +196,25 @@ SwigType_add_array(SwigType *t, String *size) { Insert(t,0,temp); } +/* ----------------------------------------------------------------------------- + * SwigType_pop_arrays() + * + * Pop all arrays off as a single item + * ----------------------------------------------------------------------------- */ + +SwigType * +SwigType_pop_arrays(SwigType *t) { + String *ta; + if (!SwigType_isarray(t)) return 0; + ta = NewString(""); + while (SwigType_isarray(t)) { + SwigType *td = SwigType_pop(t); + Append(ta,td); + Delete(td); + } + return ta; +} + /* ----------------------------------------------------------------------------- * SwigType_add_reference() * @@ -187,8 +235,57 @@ SwigType_add_reference(SwigType *t) { void SwigType_add_qualifier(SwigType *t, String *qual) { char temp[256]; - sprintf(temp,"q(%s).",Char(qual)); - Insert(t,0,temp); + if (!SwigType_isqualifier(t)) { + sprintf(temp,"q(%s).",Char(qual)); + Insert(t,0,temp); + } else { + /* Already has a qualifier on it. We are going to generate a + canonical qualifier string */ + String *qt; + char *c, *qc; + String *newq; + + qt = SwigType_pop(t); /* Rip off the old qualifier */ + /* See if the added qualifier is already there */ + if (strstr(Char(qt),Char(qual))) { + /* Already added this qualifier */ + SwigType_push(t,qt); + Delete(qt); + return; + } + /* We need to add the qualifier to the qualifier list */ + /* To do this, we keep the qualifiers in alphabetical order */ + newq = NewString("q("); + qc = Char(qual); + c = Char(qt)+2; + c = strtok(c," )."); + while (c) { + if (!strlen(c)) { + c = strtok(NULL," )."); + continue; + } + if (qc) { + if (strcmp(c,qc) < 0) { + Printf(newq,"%s",c); + } else { + Printf(newq,"%s %s", qc,c); + qc = 0; + } + } else { + Printf(newq,"%s",c); + } + c = strtok(NULL," )."); + if (c) Putc(' ',newq); + } + if (qc) { + Printf(newq," %s",qc); + } + Putc(')',newq); + Putc('.',newq); + SwigType_push(t,newq); + Delete(newq); + Delete(qt); + } } /* ----------------------------------------------------------------------------- @@ -201,20 +298,84 @@ SwigType_add_qualifier(SwigType *t, String *qual) { void SwigType_add_function(SwigType *t, ParmList *parms) { String *pstr; + Parm *p; Insert(t,0,")."); pstr = NewString("f("); - - while (parms) { - Printf(pstr,"%s",Gettype(parms)); - parms = Getnext(parms); - if (parms) - Putc(',',pstr); + p = parms; + for (p = parms; p; p = nextSibling(p)) { + if (p != parms) Putc(',',pstr); + Printf(pstr,"%s", Getattr(p,"type")); } Insert(t,0,pstr); Delete(pstr); } +SwigType * +SwigType_pop_function(SwigType *t) { + SwigType *f = 0; + SwigType *g = 0; + char *c = Char(t); + if (strncmp(c,"q(",2) == 0) { + f = SwigType_pop(t); + c = Char(t); + } + if (strncmp(c,"f(",2)) { + printf("Fatal error. SwigType_pop_function applied to non-function.\n"); + abort(); + } + g = SwigType_pop(t); + if (f) SwigType_push(g,f); + Delete(f); + return g; +} + +ParmList * +SwigType_function_parms(SwigType *t) { + List *l = SwigType_parmlist(t); + Hash *p, *pp = 0, *firstp = 0; + DOH *obj; + for (obj = Firstitem(l); obj; obj = Nextitem(l)) { + p = NewParm(obj,0); + if (!firstp) firstp = p; + if (pp) { + set_nextSibling(pp,p); + } + pp = p; + } + Delete(l); + return firstp; +} + +/* ----------------------------------------------------------------------------- + * SwigType_add_template() + * + * Adds a template to a type. This template is encoded in the SWIG type + * mechanism and produces a string like this: + * + * vector ----> "vector<(p.int)>" + * ----------------------------------------------------------------------------- */ + +void +SwigType_add_template(SwigType *t, ParmList *parms) { + Parm *p; + + Append(t,"<("); + p = parms; + for (p = parms; p; p = nextSibling(p)) { + String *v; + if (Getattr(p,"default")) continue; + if (p != parms) Append(t,","); + v = Getattr(p,"value"); + if (v) { + Append(t,v); + } else { + Append(t,Getattr(p,"type")); + } + } + Append(t,")>"); +} + /* ----------------------------------------------------------------------------- * static isolate_element() * @@ -228,8 +389,7 @@ isolate_element(char *c) { if (*c == '.') { Putc(*c,result); return result; - } - else if (*c == '(') { + } else if (*c == '(') { int nparen = 1; Putc(*c,result); c++; @@ -263,6 +423,7 @@ List *SwigType_split(SwigType *t) { int len; c = Char(t); + list = NewList(); while (*c) { item = isolate_element(c); @@ -312,6 +473,7 @@ void SwigType_push(SwigType *t, String *cons) { if (!cons) return; if (!Len(cons)) return; + if (Len(t)) { char *c = Char(cons); if (c[strlen(c)-1] != '.') @@ -326,7 +488,7 @@ void SwigType_push(SwigType *t, String *cons) * Splits a comma separated list of components into strings. * ----------------------------------------------------------------------------- */ -List *SwigType_parmlist(String *p) { +List *SwigType_parmlist(const String *p) { DOH *item; List *list; char *c; @@ -404,20 +566,37 @@ String *SwigType_parm(SwigType *t) { * SwigType_isfunction() * SwigType_isqualifier() * - * Testing functions for querying a datatype + * Testing functions for querying a raw datatype * ----------------------------------------------------------------------------- */ int SwigType_ispointer(SwigType *t) { char *c; + if (!t) return 0; c = Char(t); + if (strncmp(c,"q(",2) == 0) { + c = strchr(c,'.'); + if (!c) return 0; + c++; + } if (strncmp(c,"p.",2) == 0) { return 1; } return 0; } +int SwigType_ismemberpointer(SwigType *t) { + char *c; + if (!t) return 0; + c = Char(t); + if (strncmp(c,"m(",2) == 0) { + return 1; + } + return 0; +} + int SwigType_isreference(SwigType *t) { char *c; + if (!t) return 0; c = Char(t); if (strncmp(c,"r.",2) == 0) { return 1; @@ -427,6 +606,7 @@ int SwigType_isreference(SwigType *t) { int SwigType_isarray(SwigType *t) { char *c; + if (!t) return 0; c = Char(t); if (strncmp(c,"a(",2) == 0) { return 1; @@ -436,8 +616,16 @@ int SwigType_isarray(SwigType *t) { int SwigType_isfunction(SwigType *t) { char *c; - + if (!t) { + return 0; + } c = Char(t); + if (strncmp(c,"q(",2) == 0) { + /* Might be a 'const' function. Try to skip over the 'const' */ + c = strchr(c,'.'); + if (c) c++; + else return 0; + } if (strncmp(c,"f(",2) == 0) { return 1; } @@ -446,6 +634,7 @@ int SwigType_isfunction(SwigType *t) { int SwigType_isqualifier(SwigType *t) { char *c; + if (!t) return 0; c = Char(t); if (strncmp(c,"q(",2) == 0) { return 1; @@ -455,18 +644,76 @@ int SwigType_isqualifier(SwigType *t) { int SwigType_isconst(SwigType *t) { char *c; + if (!t) return 0; c = Char(t); - if (strncmp(c,"q(const)",8) == 0) { + if (strncmp(c,"q(",2) == 0) { + String *q = SwigType_parm(t); + if (strstr(Char(q),"const")) { + Delete(q); + return 1; + } + Delete(q); + } + /* Hmmm. Might be const through a typedef */ + if (SwigType_issimple(t)) { + int ret; + SwigType *td = SwigType_typedef_resolve(t); + if (td) { + ret = SwigType_isconst(td); + Delete(td); + return ret; + } + } + return 0; +} + +int SwigType_ismutable(SwigType *t) { + int r; + SwigType *qt = SwigType_typedef_resolve_all(t); + if (SwigType_isreference(qt)) { + Delete(SwigType_pop(qt)); + } + r = SwigType_isconst(qt); + Delete(qt); + return r ? 0 : 1; +} + +int SwigType_isenum(SwigType *t) { + char *c = Char(t); + if (!t) return 0; + if (strncmp(c,"enum ",5) == 0) { return 1; } return 0; } -int SwigType_isenum(SwigType *t) { +int SwigType_issimple(SwigType *t) { char *c = Char(t); - if (strncmp(c,"enum ",5) == 0) { - return 1; + if (!t) return 0; + while (*c) { + if (*c == '<') { + int nest = 1; + c++; + while (*c && nest) { + if (*c == '<') nest++; + if (*c == '>') nest--; + c++; + } + c--; + } + if (*c == '.') return 0; + c++; } + return 1; +} + +int SwigType_isvarargs(const SwigType *t) { + if (Strcmp(t,"v(...)") == 0) return 1; + return 0; +} + +int SwigType_istemplate(const SwigType *t) { + if (Strstr(t,"<(")) return 1; return 0; } @@ -481,20 +728,35 @@ SwigType *SwigType_base(SwigType *t) { c = Char(t); d = c + strlen(c); + + /* Check for a type constructor */ + if ((d > c) && (*(d-1) == '.')) d--; + while (d > c) { d--; - if (*d == '.') return Swig_temp_result(NewString(d+1)); + if (*d == '>') { + /* Skip over template--that's part of the base name */ + int ntemp = 1; + d--; + while ((d > c) && (ntemp > 0)) { + if (*d == '>') ntemp++; + if (*d == '<') ntemp--; + d--; + } + } + if (*d == ')') { + /* Skip over params */ + int nparen = 1; + d--; + while ((d > c) && (nparen > 0)) { + if (*d == ')') nparen++; + if (*d == '(') nparen--; + d--; + } + } + if (*d == '.') return NewString(d+1); } - return Swig_temp_result(NewString(c)); -} - -void SwigType_setbase(SwigType *t, String_or_char *n) { - SwigType *p; - p = SwigType_prefix(t); - Clear(t); - Append(t,p); - Append(t,n); - Delete(p); + return NewString(c); } /* ----------------------------------------------------------------------------- @@ -509,8 +771,32 @@ String *SwigType_prefix(SwigType *t) { c = Char(t); d = c + strlen(c); + + /* Check for a type constructor */ + if ((d > c) && (*(d-1) == '.')) d--; + while (d > c) { d--; + if (*d == '>') { + int nest = 1; + d--; + while ((d > c) && (nest)) { + if (*d == '>') nest++; + if (*d == '<') nest--; + d--; + } + } + if (*d == ')') { + /* Skip over params */ + int nparen = 1; + d--; + while ((d > c) && (nparen)) { + if (*d == ')') nparen++; + if (*d == '(') nparen--; + d--; + } + } + if (*d == '.') { char t = *(d+1); *(d+1) = 0; @@ -522,6 +808,125 @@ String *SwigType_prefix(SwigType *t) { return NewString(""); } + + +/* ----------------------------------------------------------------------------- + * SwigType_templateprefix() + * + * Returns the prefix before the first template definition. + * For example: + * + * Foo<(p.int)>::bar + * + * Results in "Foo" + * ----------------------------------------------------------------------------- */ + +String * +SwigType_templateprefix(SwigType *t) { + char *c; + String *r; + String *s = NewString(t); + c = Char(s); + while (*c) { + if (*c == '<') { + *c = 0; + r = NewString(Char(s)); + Delete(s); + return r; + } + c++; + } + return s; +} + +/* ----------------------------------------------------------------------------- + * SwigType_templatesuffix() + * + * Returns text after a template substitution. Used to handle scope names + * for example: + * + * Foo<(p.int)>::bar + * + * returns "::bar" + * ----------------------------------------------------------------------------- */ + +String * +SwigType_templatesuffix(const SwigType *t) { + char *c; + c = Char(t); + while (*c) { + if ((*c == '<') && (*(c+1) == '(')) { + int nest = 1; + c++; + while (*c && nest) { + if (*c == '<') nest++; + if (*c == '>') nest--; + c++; + } + return NewString(c); + } + c++; + } + return NewString(""); +} + +/* ----------------------------------------------------------------------------- + * SwigType_templateargs() + * + * Returns the template part + * ----------------------------------------------------------------------------- */ + +String * +SwigType_templateargs(SwigType *t) { + String *result = NewString(""); + char *c; + c = Char(t); + while (*c) { + if ((*c == '<') && (*(c+1) == '(')) { + int nest = 1; + Putc(*c,result); + c++; + while (*c && nest) { + Putc(*c,result); + if (*c == '<') nest++; + if (*c == '>') nest--; + c++; + } + return result; + } + c++; + } + Delete(result); + return 0; +} + +/* ----------------------------------------------------------------------------- + * SwigType_strip_qualifiers() + * + * Strip all qualifiers from a type and return a new type + * ----------------------------------------------------------------------------- */ + +static Hash *memoize_stripped = 0; + +SwigType * +SwigType_strip_qualifiers(SwigType *t) { + SwigType *r; + List *l; + SwigType *e; + if (!memoize_stripped) memoize_stripped = NewHash(); + r = Getattr(memoize_stripped,t); + if (r) return Copy(r); + + l = SwigType_split(t); + r = NewString(""); + for (e = Firstitem(l); e; e = Nextitem(l)) { + if (SwigType_isqualifier(e)) continue; + Append(r,e); + } + Setattr(memoize_stripped,Copy(t),Copy(r)); + return r; +} + /* ----------------------------------------------------------------------------- * SwigType_array_ndim() * @@ -553,7 +958,7 @@ String *SwigType_array_getdim(SwigType *t, int n) { c++; n--; } - if (n == 0) return Swig_temp_result(SwigType_parm(c)); + if (n == 0) return SwigType_parm(c); return 0; } @@ -591,6 +996,22 @@ void SwigType_array_setdim(SwigType *t, int n, String_or_char *rep) { Delete(result); } +/* ----------------------------------------------------------------------------- + * SwigType_array_type() + * + * Return the base type of an array + * ----------------------------------------------------------------------------- */ + +SwigType * +SwigType_array_type(SwigType *ty) { + SwigType *t; + t = Copy(ty); + while (SwigType_isarray(t)) { + Delete(SwigType_pop(t)); + } + return t; +} + /* ----------------------------------------------------------------------------- * SwigType_default() * @@ -598,11 +1019,12 @@ void SwigType_array_setdim(SwigType *t, int n, String_or_char *rep) { * down to its most primitive form--resolving all typedefs and removing operators. * * Rules: - * Pointers: p.SWIGPOINTER - * References: r.SWIGREFERENCE - * Arrays: a().SWIGARRAY + * Pointers: p.SWIGTYPE + * References: r.SWIGTYPE + * Arrays: a().SWIGTYPE * Types: SWIGTYPE - * + * MemberPointer: m(CLASS).SWIGTYPE + * Enums: enum SWIGENUM * ----------------------------------------------------------------------------- */ static Hash *default_cache = 0; @@ -621,12 +1043,24 @@ SwigType *SwigType_default(SwigType *t) { if (r != t) Delete(r); r = r1; } + if (SwigType_isqualifier(r)) { + if (r == t) r = Copy(t); + do { + Delete(SwigType_pop(r)); + } while (SwigType_isqualifier(r)); + } if (SwigType_ispointer(r)) { - def = NewString("p.SWIGPOINTER"); + def = NewString("p.SWIGTYPE"); } else if (SwigType_isreference(r)) { - def = NewString("r.SWIGREFERENCE"); + def = NewString("r.SWIGTYPE"); } else if (SwigType_isarray(r)) { - def = NewString("a().SWIGARRAY"); + def = NewString("a().SWIGTYPE"); + } else if (SwigType_ismemberpointer(r)) { + def = NewString("m(CLASS).SWIGTYPE"); + } else if (SwigType_isenum(r)) { + def = NewString("enum SWIGTYPE"); + } else if (SwigType_isvarargs(r)) { + def = NewString("v(...)"); } else { def = NewString("SWIGTYPE"); } @@ -636,7 +1070,56 @@ SwigType *SwigType_default(SwigType *t) { } /* ----------------------------------------------------------------------------- - * SwigType_str(DOH *s, DOH *id) + * SwigType_namestr() + * + * Returns a string of the base type. Takes care of template expansions + * ----------------------------------------------------------------------------- */ + +String * +SwigType_namestr(const SwigType *t) { + String *r; + String *suffix; + List *p; + char tmp[256]; + char *c, *d, *e; + int i, sz; + + if (!SwigType_istemplate(t)) return NewString(t); + + c = Strstr(t,"<("); + + d = Char(t); + e = tmp; + while (d != c) { + *(e++) = *(d++); + } + *e = 0; + r = NewString(tmp); + Putc('<',r); + + p = SwigType_parmlist(t); + sz = Len(p); + for (i = 0; i < sz; i++) { + Append(r,SwigType_str(Getitem(p,i),0)); + if ((i+1) < sz) Putc(',',r); + } + Putc(' ',r); + Putc('>',r); + suffix = SwigType_templatesuffix(t); + Append(r,suffix); + Delete(suffix); +#if 0 + if (SwigType_istemplate(r)) { + SwigType *rr = SwigType_namestr(r); + Delete(r); + return rr; + } +#endif + return r; +} + +/* ----------------------------------------------------------------------------- + * SwigType_str() * * Create a C string representation of a datatype. * ----------------------------------------------------------------------------- */ @@ -668,15 +1151,32 @@ SwigType_str(SwigType *s, const String_or_char *id) } else { nextelement = 0; } - if (SwigType_ispointer(element)) { + if (SwigType_isqualifier(element)) { + DOH *q = 0; + q = SwigType_parm(element); + Insert(result,0," "); + Insert(result,0,q); + Delete(q); + } else if (SwigType_ispointer(element)) { Insert(result,0,"*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } + } else if (SwigType_ismemberpointer(element)) { + String *q; + q = SwigType_parm(element); + Insert(result,0,"::*"); + Insert(result,0,q); + if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + Insert(result,0,"("); + Append(result,")"); + } + Delete(q); } - else if (SwigType_isreference(element)) Insert(result,0,"&"); - else if (SwigType_isarray(element)) { + else if (SwigType_isreference(element)) { + Insert(result,0,"&"); + } else if (SwigType_isarray(element)) { DOH *size; Append(result,"["); size = SwigType_parm(element); @@ -696,20 +1196,83 @@ SwigType_str(SwigType *s, const String_or_char *id) } Append(result,")"); Delete(parms); - } else if (SwigType_isqualifier(element)) { - DOH *q = 0; - q = SwigType_parm(element); - Insert(result,0," "); - Insert(result,0,q); - Delete(q); } else { - Insert(result,0," "); - Insert(result,0,element); + if (Strcmp(element,"v(...)") == 0) { + Insert(result,0,"..."); + } else { + String *bs = SwigType_namestr(element); + Insert(result,0," "); + Insert(result,0,bs); + Delete(bs); + } } element = nextelement; } Delete(elements); - return Swig_temp_result(result); + Chop(result); + return result; +} + +/* ----------------------------------------------------------------------------- + * SwigType_ltype(SwigType *ty) + * + * Create a locally assignable type + * ----------------------------------------------------------------------------- */ + +SwigType * +SwigType_ltype(SwigType *s) { + String *result; + String *element; + SwigType *td, *tc = 0; + List *elements; + int nelements, i; + int firstarray = 1; + + result = NewString(""); + tc = Copy(s); + /* Nuke all leading qualifiers */ + while (SwigType_isqualifier(tc)) { + Delete(SwigType_pop(tc)); + } + if (SwigType_issimple(tc)) { + /* Resolve any typedef definitions */ + td = SwigType_typedef_resolve(tc); + if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isenum(td) || SwigType_isreference(td))) { + /* We need to use the typedef type */ + Delete(tc); + tc = td; + } else if (td) { + Delete(td); + } + } + elements = SwigType_split(tc); + nelements = Len(elements); + /* Now, walk the type list and start emitting */ + for (i = 0; i < nelements; i++) { + element = Getitem(elements,i); + if (SwigType_isqualifier(element)) { + /* Do nothing. Ignore */ + } else if (SwigType_ispointer(element)) { + Append(result,element); + firstarray = 0; + } else if (SwigType_ismemberpointer(element)) { + Append(result,element); + firstarray = 0; + } else if (SwigType_isreference(element)) { + Append(result,"p."); + firstarray = 0; + } else if (SwigType_isarray(element) && firstarray) { + Append(result,"p."); + firstarray = 0; + } else if (SwigType_isenum(element)) { + Append(result,"int"); + } else { + Append(result,element); + } + } + Delete(elements); + Delete(tc); + return result; } /* ----------------------------------------------------------------------------- @@ -731,164 +1294,11 @@ String * SwigType_lstr(SwigType *s, const String_or_char *id) { String *result; - String *element = 0, *nextelement; - List *elements; - int nelements, i; - int firstarray = 1; - SwigType *td, *rs, *tc = 0; - if (id) { - result = NewString(Char(id)); - } else { - result = NewString(""); - } - if (SwigType_isconst(s)) { - tc = Copy(s); - Delete(SwigType_pop(tc)); - rs = tc; - } else { - rs = s; - } - td = SwigType_typedef_resolve(rs); - if ((td) && (SwigType_isconst(td) || SwigType_isarray(td))) { - elements = SwigType_split(td); - } else if (td && SwigType_isenum(td)) { - elements = SwigType_split("int"); - } else { - elements = SwigType_split(rs); - } - if (td) Delete(td); - nelements = Len(elements); + SwigType *tc; - if (nelements > 0) { - element = Getitem(elements,0); - } - /* Now, walk the type list and start emitting */ - for (i = 0; i < nelements; i++) { - if (i < (nelements - 1)) { - nextelement = Getitem(elements,i+1); - } else { - nextelement = 0; - } - if (SwigType_ispointer(element)) { - Insert(result,0,"*"); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { - Insert(result,0,"("); - Append(result,")"); - } - firstarray = 0; - } else if (SwigType_isreference(element)) { - Insert(result,0,"*"); - } else if (SwigType_isarray(element)) { - if (firstarray) { - Insert(result,0,"*"); - while (nextelement && (SwigType_isarray(nextelement))) { - i++; - nextelement = Getitem(elements,i+1); - } - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { - Insert(result,0,"("); - Append(result,")"); - } - firstarray = 0; - } else { - DOH *size; - Append(result,"["); - size = SwigType_parm(element); - Append(result,size); - Append(result,"]"); - Delete(size); - } - } else if (SwigType_isfunction(element)) { - DOH *parms, *p; - int j, plen; - Append(result,"("); - parms = SwigType_parmlist(element); - plen = Len(parms); - for (j = 0; j < plen; j++) { - p = SwigType_str(Getitem(parms,j),0); - Append(result,p); - if (j < (plen-1)) Append(result,","); - } - Append(result,")"); - Delete(parms); - } else if (SwigType_isqualifier(element)) { - } else { - Insert(result,0," "); - Insert(result,0,element); - } - element = nextelement; - } - Delete(elements); - if (tc) Delete(tc); - return Swig_temp_result(result); -} - - -/* ----------------------------------------------------------------------------- - * SwigType_ltype(SwigType *ty) - * - * Returns a type object corresponding to the string created by lstr - * ----------------------------------------------------------------------------- */ - -SwigType * -SwigType_ltype(SwigType *s) { - String *result; - String *element, *nextelement; - SwigType *td, *rs, *tc = 0; - List *elements; - int nelements, i; - int firstarray = 1; - - result = NewString(""); - - if (SwigType_isconst(s)) { - tc = Copy(s); - Delete(SwigType_pop(tc)); - rs = tc; - } else { - rs = s; - } - - td = SwigType_typedef_resolve(rs); - if ((td) && (SwigType_isconst(td) || SwigType_isarray(td))) { - elements = SwigType_split(td); - } else if (td && SwigType_isenum(td)) { - elements = SwigType_split("int"); - } else { - elements = SwigType_split(rs); - } - if (td) Delete(td); - nelements = Len(elements); - /* Now, walk the type list and start emitting */ - for (i = 0; i < nelements; i++) { - element = Getitem(elements,i); - if (SwigType_ispointer(element)) { - Append(result,element); - firstarray = 0; - } else if (SwigType_isreference(element)) { - Append(result,"p."); - } else if (SwigType_isarray(element)) { - if (firstarray) { - Append(result,"p."); - while (i < (nelements - 1)) { - element = Getitem(elements,i+1); - if (!SwigType_isarray(element)) break; - i++; - } - firstarray = 0; - } else { - Append(result,element); - } - } else if (SwigType_isfunction(element)) { - Append(result,element); - } else if (SwigType_isqualifier(element)) { - } else { - Append(result,element); - } - element = nextelement; - } - Delete(elements); - if (tc) Delete(tc); + tc = SwigType_ltype(s); + result = SwigType_str(tc,id); + Delete(tc); return result; } @@ -907,6 +1317,7 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { int nelements, i; int clear = 1; int firstarray = 1; + int isreference = 0; result = NewString(""); @@ -918,18 +1329,21 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { rs = s; } - td = SwigType_typedef_resolve(rs); - if ((td) && (SwigType_isconst(td) || SwigType_isarray(td))) { - elements = SwigType_split(td); - } else if (td && SwigType_isenum(td)) { - elements = SwigType_split(rs); - clear = 0; + if (SwigType_issimple(rs)) { + td = SwigType_typedef_resolve(rs); + if ((td) && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) { + elements = SwigType_split(td); + } else if (td && SwigType_isenum(td)) { + elements = SwigType_split(rs); + clear = 0; + } else { + elements = SwigType_split(rs); + } + if (td) Delete(td); } else { elements = SwigType_split(rs); } - if (td) Delete(td); nelements = Len(elements); - if (nelements > 0) { element = Getitem(elements,0); } @@ -940,15 +1354,34 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { } else { nextelement = 0; } - if (SwigType_ispointer(element)) { + if (SwigType_isqualifier(element)) { + DOH *q = 0; + q = SwigType_parm(element); + Insert(result,0," "); + Insert(result,0,q); + Delete(q); + clear = 0; + } else if (SwigType_ispointer(element)) { Insert(result,0,"*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } firstarray = 0; + } else if (SwigType_ismemberpointer(element)) { + String *q; + Insert(result,0,"::*"); + q = SwigType_parm(element); + Insert(result,0,q); + Delete(q); + if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + Insert(result,0,"("); + Append(result,")"); + } + firstarray = 0; } else if (SwigType_isreference(element)) { Insert(result,0,"&"); + isreference = 1; } else if (SwigType_isarray(element)) { DOH *size; if (firstarray) { @@ -975,16 +1408,16 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { } Append(result,")"); Delete(parms); - } else if (SwigType_isqualifier(element)) { - DOH *q = 0; - q = SwigType_parm(element); - Insert(result,0," "); - Insert(result,0,q); - Delete(q); + } else if (SwigType_isenum(element)) { + String *bs = SwigType_namestr(element); + Insert(result,0,bs); + Delete(bs); clear = 0; } else { + String *bs = SwigType_namestr(element); Insert(result,0," "); - Insert(result,0,element); + Insert(result,0,bs); + Delete(bs); } element = nextelement; } @@ -995,14 +1428,14 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { cast = NewStringf("(%s)",result); } if (name) { - if (SwigType_isreference(s)) { + if (isreference) { Append(cast,"*"); } Append(cast,name); } Delete(result); Delete(tc); - return Swig_temp_result(cast); + return cast; } @@ -1020,36 +1453,66 @@ String *SwigType_lcaststr(SwigType *s, const String_or_char *name) { if (SwigType_isarray(s)) { Printf(result,"(%s)%s", SwigType_lstr(s,0),name); } else if (SwigType_isreference(s)) { - Printf(result,"(%s)", SwigType_lstr(s,0)); + Printf(result,"(%s)", SwigType_str(s,0)); if (name) - Printf(result,"&%s", name); + Printf(result,"%s", name); } else if (SwigType_isqualifier(s)) { Printf(result,"(%s)%s", SwigType_lstr(s,0),name); } else { if (name) Append(result,name); } - return Swig_temp_result(result); + return result; } String *SwigType_manglestr_default(SwigType *s) { char *c; - String *result; + String *result,*base; + SwigType *lt; + SwigType *ss = 0; + + if (SwigType_istemplate(s)) { + ss = SwigType_typedef_resolve_all(s); + s = ss; + } + lt = SwigType_ltype(s); + result = SwigType_prefix(lt); + base = SwigType_base(lt); - if (SwigType_istypedef(s)) - result = Copy(s); - else - result = SwigType_ltype(s); - Replace(result,"struct ","", DOH_REPLACE_ANY); - Replace(result,"class ","", DOH_REPLACE_ANY); - Replace(result,"union ","", DOH_REPLACE_ANY); c = Char(result); while (*c) { - if (!isalnum(*c)) *c = '_'; + if (!isalnum((int)*c)) *c = '_'; c++; } + if (SwigType_istemplate(base)) { + String *b = SwigType_namestr(base); + Delete(base); + base = b; + } + + Replace(base,"struct ","", DOH_REPLACE_ANY); /* This might be problematic */ + Replace(base,"class ","", DOH_REPLACE_ANY); + Replace(base,"union ","", DOH_REPLACE_ANY); + + c = Char(base); + while (*c) { + if (*c == '<') *c = 'T'; + else if (*c == '>') *c = 't'; + else if (*c == '*') *c = 'p'; + else if (*c == '[') *c = 'a'; + else if (*c == ']') *c = 'A'; + else if (*c == '&') *c = 'R'; + else if (*c == '(') *c = 'f'; + else if (*c == ')') *c = 'F'; + else if (!isalnum((int)*c)) *c = '_'; + c++; + } + Append(result,base); Insert(result,0,"_"); - return Swig_temp_result(result); + Delete(lt); + Delete(base); + if (ss) Delete(ss); + return result; } String *SwigType_manglestr(SwigType *s) { @@ -1057,622 +1520,89 @@ String *SwigType_manglestr(SwigType *s) { } /* ----------------------------------------------------------------------------- - * SwigType_strip_qualifiers() + * SwigType_typename_replace() * - * Rips all qualifiers out of a type. + * Replaces a typename in a type with something else. Needed for templates. * ----------------------------------------------------------------------------- */ -void SwigType_strip_qualifiers(SwigType *ty) { - /* Sick hack alert */ - Replace(ty,"q(const).","", DOH_REPLACE_ANY); - Replace(ty,"q(volatile).", "", DOH_REPLACE_ANY); -} +void +SwigType_typename_replace(SwigType *t, String *pat, String *rep) { + String *nt; + int i; + List *elem; -/* ----------------------------------------------------------------------------- - * Scope handling - * - * These functions are used to manipulate typedefs and scopes. - * ----------------------------------------------------------------------------- */ + if (!Strstr(t,pat)) return; -#define MAX_SCOPE 8 - -static Hash *type_scopes = 0; /* Hash table of scope names */ -static Hash *scopes[MAX_SCOPE]; /* List representing the current scope */ -static String *scopenames[MAX_SCOPE]; /* Names of the various scopes */ -static int scope_level = 0; - -static void init_scopes() { - if (type_scopes) return; - type_scopes = NewHash(); - scopes[scope_level] = NewHash(); - scopenames[scope_level] = NewString("::"); - Setattr(type_scopes,"::",scopes[scope_level]); -} - -/* ----------------------------------------------------------------------------- - * SwigType_typedef() - * - * Defines a new typedef. Returns -1 if the type name is already defined. - * ----------------------------------------------------------------------------- */ - -int SwigType_typedef(SwigType *type, String_or_char *name) { - int i; - String *qname; - init_scopes(); - if (Getattr(scopes[scope_level],name)) return -1; - if (Cmp(type,name) == 0) { - return 0; + if (Strcmp(t,pat) == 0) { + Replace(t,pat,rep,DOH_REPLACE_ANY); + return; } - i = scope_level; - qname = NewString(name); - while (i >= 0) { - String *sname; - /* Printf(stdout,"Adding typedef [%d] : '%s' -> '%s'\n", i, qname, type); */ - Setattr(scopes[i],qname,type); - if (i > 0) { - sname = scopenames[i]; - if (sname) { - qname = NewStringf("%s::%s",sname,qname); - } - } - i--; - } - - /* Setattr(scopes[scope_level],name,type); */ - /* Need to modify this to include all scopes */ - - if (default_cache) - Delattr(default_cache,type); - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_new_scope() - * - * Creates a new scope - * ----------------------------------------------------------------------------- */ - -void SwigType_new_scope() { - init_scopes(); - scope_level++; - scopes[scope_level] = NewHash(); - scopenames[scope_level] = NewString(""); -} - -/* ----------------------------------------------------------------------------- - * SwigType_reset_scopes() - * - * Reset the scope system - * ----------------------------------------------------------------------------- */ - -void SwigType_reset_scopes() { - Delete(type_scopes); - type_scopes = 0; - init_scopes(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_set_scope_name() - * - * Set the name of the current scope. Note: this will create an entry in the - * type_scopes hash. - * ----------------------------------------------------------------------------- */ - -void SwigType_set_scope_name(String_or_char *name) { - String *key; - int i; - init_scopes(); - scopenames[scope_level] = NewString(Char(name)); - key = NewString(""); - for (i = 1; i <= scope_level; i++) { - Append(key,scopenames[scope_level]); - if (i < scope_level) Append(key,"::"); - } - Setattr(type_scopes,key,scopes[scope_level]); -} - -/* ----------------------------------------------------------------------------- - * SwigType_merge_scope() - * - * Merges the contents of one scope into the current scope. - * ----------------------------------------------------------------------------- */ - -void SwigType_merge_scope(Hash *scope, String *prefix) { - String *name; - String *key; - String *type; - - init_scopes(); - key = Firstkey(scope); - while (key) { - type = Getattr(scope,key); - if (prefix) { - name = NewStringf("%s::%s",prefix,key); - } else { - name = NewString(key); - } - SwigType_typedef(type,name); - key = Nextkey(scope); - } -} - -/* ----------------------------------------------------------------------------- - * SwigType_pop_scope() - * - * Pop off the last scope. Returns the hash table for the scope that was popped off. - * ----------------------------------------------------------------------------- */ - -Hash *SwigType_pop_scope() { - Hash *s; - String *prefix; - init_scopes(); - if (scope_level == 0) return 0; - prefix = scopenames[scope_level]; - s = scopes[scope_level--]; - if (Len(s)) return s; - Delete(s); - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_resolve() - * - * Resolves a typedef and returns a new type string. Returns 0 if there is no - * typedef mapping. - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_typedef_resolve(SwigType *t) { - String *base; - String *type; - String *r; - int level; - - init_scopes(); - base = SwigType_base(t); - level = scope_level; - while (level >= 0) { - /* See if we know about this type */ - type = Getattr(scopes[level],base); - if (type) break; - level--; - } - if (level < 0) { - return 0; - } - r = SwigType_prefix(t); - Append(r,type); - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_resolve_all() - * - * Fully resolve a type down to its most basic datatype - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_typedef_resolve_all(SwigType *t) { - SwigType *n; - SwigType *r = Copy(t); - - while ((n = SwigType_typedef_resolve(r))) { - Delete(r); - r = n; - } - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_istypedef() - * - * Checks a typename to see if it is a typedef. - * ----------------------------------------------------------------------------- */ - -int SwigType_istypedef(SwigType *t) { - String *base, *type; - int level; - - init_scopes(); - base = SwigType_base(t); - level = scope_level; - while (level >= 0) { - /* See if we know about this type */ - type = Getattr(scopes[level],base); - if (type) { - return 1; - } - level--; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_cmp() - * - * Compares two type-strings using all available typedef information. Returns 0 - * if equal, 1 if not. - * ----------------------------------------------------------------------------- */ - -int SwigType_cmp(SwigType *tpat, SwigType *type) { - String *r, *s; - char *p, *t; - - p = Char(tpat); - t = Char(type); - - if (strcmp(p,t) == 0) return 0; - - r = SwigType_typedef_resolve(type); - while (r) { - t = Char(r); - if (strcmp(p,t) == 0) { - Delete(r); - return 0; - } - s = SwigType_typedef_resolve(r); - Delete(r); - r = s; - } - return 1; -} - -/* ----------------------------------------------------------------------------- - * SwigType_type() - * - * Returns an integer code describing the datatype. This is only used for - * compatibility with SWIG1.1 language modules and is likely to go away once - * everything is based on typemaps. - * ----------------------------------------------------------------------------- */ - -int SwigType_type(SwigType *t) -{ - char *c; - /* Check for the obvious stuff */ - c = Char(t); - - if (strncmp(c,"p.",2) == 0) { - if (SwigType_type(c+2) == T_CHAR) return T_STRING; - else return T_POINTER; - } - if (strncmp(c,"a(",2) == 0) return T_ARRAY; - if (strncmp(c,"r.",2) == 0) return T_REFERENCE; - - if (strncmp(c,"q(",2) == 0) { - while(*c && (*c != '.')) c++; - if (*c) return SwigType_type(c+1); - return T_ERROR; - } - if (strncmp(c,"f(",2) == 0) return T_FUNCTION; - - /* Look for basic types */ - if (strcmp(c,"int") == 0) return T_INT; - if (strcmp(c,"long") == 0) return T_LONG; - if (strcmp(c,"short") == 0) return T_SHORT; - if (strcmp(c,"unsigned") == 0) return T_UINT; - if (strcmp(c,"unsigned short") == 0) return T_USHORT; - if (strcmp(c,"unsigned long") == 0) return T_ULONG; - if (strcmp(c,"unsigned int") == 0) return T_UINT; - if (strcmp(c,"char") == 0) return T_CHAR; - if (strcmp(c,"signed char") == 0) return T_SCHAR; - if (strcmp(c,"unsigned char") == 0) return T_UCHAR; - if (strcmp(c,"float") == 0) return T_FLOAT; - if (strcmp(c,"double") == 0) return T_DOUBLE; - if (strcmp(c,"void") == 0) return T_VOID; - if (strcmp(c,"bool") == 0) return T_BOOL; - if (strncmp(c,"enum ",5) == 0) return T_INT; - /* Hmmm. Unknown type */ - if (SwigType_istypedef(t)) { - int r; - SwigType *nt = SwigType_typedef_resolve(t); - r = SwigType_type(nt); - Delete(nt); - return r; - } - return T_USER; -} - -/* ----------------------------------------------------------------------------- - * SwigType_remember() - * - * This function "remembers" a datatype that was used during wrapper code generation - * so that a type-checking table can be generated later on. It is up to the language - * modules to actually call this function--it is not done automatically. - * - * Type tracking is managed through two separate hash tables. The hash 'r_mangled' - * is mapping between mangled type names (used in the target language) and - * fully-resolved C datatypes used in the source input. The second hash 'r_resolved' - * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled - * names in the scripting languages. For example, consider the following set of - * typedef declarations: - * - * typedef double Real; - * typedef double Float; - * typedef double Point[3]; - * - * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and - * 'Point' were used in an interface file and "remembered" using this function. - * The hash tables would look like this: - * - * r_mangled { - * _p_double : [ p.double, a(3).double ] - * _p_Real : [ p.double ] - * _p_Float : [ p.double ] - * _Point : [ a(3).double ] - * - * r_resolved { - * p.double : [ _p_double, _p_Real, _p_Float ] - * a(3).double : [ _p_double, _Point ] - * } - * - * Together these two hash tables can be used to determine type-equivalency between - * mangled typenames. To do this, we view the two hash tables as a large graph and - * compute the transitive closure. - * ----------------------------------------------------------------------------- */ - -static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */ -static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */ -static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */ - -void SwigType_remember(SwigType *t) { - String *mt; - SwigType *lt; - Hash *h; - SwigType *fr; - - if (!r_mangled) { - r_mangled = NewHash(); - r_resolved = NewHash(); - r_ltype = NewHash(); - } - - mt = SwigType_manglestr(t); /* Create mangled string */ - if (SwigType_istypedef(t)) - lt = Copy(t); - else - lt = SwigType_ltype(t); - Setattr(r_ltype, mt, lt); - fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */ - h = Getattr(r_mangled,mt); - if (!h) { - h = NewHash(); - Setattr(r_mangled,mt,h); - Delete(h); - } - Setattr(h,fr,mt); - - h = Getattr(r_resolved, fr); - if (!h) { - h = NewHash(); - Setattr(r_resolved,fr,h); - Delete(h); - } - Setattr(h,mt,fr); -} - -/* ----------------------------------------------------------------------------- - * SwigType_equivalent_mangle() - * - * Return a list of all of the mangled typenames that are equivalent to another - * mangled name. This works as follows: For each fully qualified C datatype - * in the r_mangled hash entry, we collect all of the mangled names from the - * r_resolved hash and combine them together in a list (removing duplicate entries). - * ----------------------------------------------------------------------------- */ - -List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) { - List *l; - Hash *h; - Hash *ch; - Hash *mh; - - if (found) { - h = found; - } else { - h = NewHash(); - } - if (checked) { - ch = checked; - } else { - ch = NewHash(); - } - if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */ - Setattr(h,ms,"1"); - Setattr(ch, ms, "1"); - mh = Getattr(r_mangled,ms); - if (mh) { - String *key; - key = Firstkey(mh); - while (key) { - Hash *rh; - if (Getattr(ch,key)) { - key = Nextkey(mh); - continue; - } - Setattr(ch,key,"1"); - rh = Getattr(r_resolved,key); - if (rh) { - String *rkey; - rkey = Firstkey(rh); - while (rkey) { - Setattr(h,rkey,"1"); - SwigType_equivalent_mangle(rkey,ch,h); - rkey = Nextkey(rh); + nt = NewString(""); + elem = SwigType_split(t); + for (i = 0; i < Len(elem); i++) { + String *e = Getitem(elem,i); + if (SwigType_issimple(e)) { + if (Strcmp(e,pat) == 0) { + /* Replaces a type of the form 'pat' with 'rep' */ + Replace(e,pat,rep,DOH_REPLACE_ANY); + } else if (SwigType_istemplate(e)) { + /* Replaces a type of the form 'pat' with 'rep' */ + if (Strncmp(e,pat,Len(pat)) == 0) { + String *repbase = SwigType_templateprefix(rep); + Replace(e,pat,repbase,DOH_REPLACE_ID | DOH_REPLACE_FIRST); + Delete(repbase); + } + { + List *tparms = SwigType_parmlist(e); + int j; + String *nt = SwigType_templateprefix(e); + Printf(nt,"<("); + for (j = 0; j < Len(tparms); j++) { + SwigType_typename_replace(Getitem(tparms,j), pat, rep); + Printf(nt,"%s",Getitem(tparms,j)); + if (j < (Len(tparms)-1)) Printf(nt,","); + } + Printf(nt,")>%s", SwigType_templatesuffix(e)); + Clear(e); + Append(e,nt); + Delete(nt); } } - key = Nextkey(mh); - } - } - check_exit: - if (!found) { - l = Hash_keys(h); - Delete(h); - Delete(ch); - return l; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * SwigType_inherit() - * - * Record information about inheritance. We keep a hash table that keeps - * a mapping between base classes and all of the classes that are derived - * from them. - * - * subclass is a hash that maps base-classes to all of the classes derived from them. - * ----------------------------------------------------------------------------- */ - -static Hash *subclass = 0; -static Hash *conversions = 0; - -void -SwigType_inherit(String *derived, String *base) { - Hash *h; - if (!subclass) subclass = NewHash(); - - h = Getattr(subclass,base); - if (!h) { - h = NewHash(); - Setattr(subclass,base,h); - } - Setattr(h,derived,"1"); -} - -/* ----------------------------------------------------------------------------- - * SwigType_inherit_equiv() - * - * Modify the type table to handle C++ inheritance - * ----------------------------------------------------------------------------- */ - -void SwigType_inherit_equiv(File *out) { - String *rkey, *bkey, *ckey; - String *prefix, *base; - - Hash *sub; - Hash *rh; - - if (!conversions) conversions = NewHash(); - if (!subclass) subclass = NewHash(); - - rkey = Firstkey(r_resolved); - while (rkey) { - /* rkey is actually a fully qualified type */ - - base = SwigType_base(rkey); - sub = Getattr(subclass,base); - if (!sub) { - rkey = Nextkey(r_resolved); - continue; - } - - rh = Getattr(r_resolved, rkey); - - /* Hmmm. We actually got a base-class match. We're going to try and patch things up */ - bkey = Firstkey(sub); - while (bkey) { - prefix= SwigType_prefix(rkey); - Append(prefix,bkey); - Setattr(rh,SwigType_manglestr(prefix),prefix); - - ckey = NewStringf("%s+%s",SwigType_manglestr(prefix), SwigType_manglestr(rkey)); - if (!Getattr(conversions,ckey)) { - Printf(out,"static void *%sTo%s(void *x) {\n", SwigType_manglestr(prefix), SwigType_manglestr(rkey)); - Printf(out," return (void *)((%s) ((%s) x));\n", SwigType_lstr(rkey,0), SwigType_lstr(prefix,0)); - Printf(out,"}\n"); - SetInt(conversions,ckey,1); + } else if (SwigType_isfunction(e)) { + int j; + List *fparms = SwigType_parmlist(e); + Clear(e); + Printf(e,"f("); + for (j = 0; j < Len(fparms); j++) { + SwigType_typename_replace(Getitem(fparms,j), pat, rep); + Printf(e,"%s",Getitem(fparms,j)); + if (j < (Len(fparms)-1)) Printf(e,","); } - Delete(ckey); - Delete(prefix); - bkey = Nextkey(sub); + Printf(e,")."); } - rkey = Nextkey(r_resolved); + Append(nt,e); } + Clear(t); + Append(t,nt); } /* ----------------------------------------------------------------------------- - * SwigType_type_table() + * SwigType_check_decl() * - * Generate the type-table for the type-checker. + * Checks type declarators for a match * ----------------------------------------------------------------------------- */ -void -SwigType_emit_type_table(File *f_forward, File *f_table) { - DOH *key; - String *types, *table; - int i = 0; - - if (!r_mangled) { - r_mangled = NewHash(); - r_resolved = NewHash(); - } - - Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n"); - - SwigType_inherit_equiv(f_table); - -#ifdef DEBUG - Printf(stdout,"---r_mangled---\n"); - Printf(stdout,"%s\n", r_mangled); - - Printf(stdout,"---r_resolved---\n"); - Printf(stdout,"%s\n", r_resolved); - - Printf(stdout,"---r_ltype---\n"); - Printf(stdout,"%s\n", r_ltype); - - Printf(stdout,"---subclass---\n"); - Printf(stdout,"%s\n", subclass); - - Printf(stdout,"---scopes[0]---\n"); - Printf(stdout,"%s\n", scopes[0]); - -#endif - table = NewString(""); - types = NewString(""); - Printf(table,"static swig_type_info *swig_types_initial[] = {\n"); - key = Firstkey(r_mangled); - Printf(f_forward,"\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n"); - while (key) { - List *el; - String *en; - Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", key, i); - Printv(types,"static swig_type_info _swigt_", key, "[] = {", 0); - Printv(types,"{\"", key, "\", 0, \"", SwigType_str(Getattr(r_ltype,key),0),"\"},", 0); - el = SwigType_equivalent_mangle(key,0,0); - for (en = Firstitem(el); en; en = Nextitem(el)) { - String *ckey; - ckey = NewStringf("%s+%s", en, key); - if (Getattr(conversions,ckey)) { - Printf(types,"{\"%s\", %sTo%s},", en, en, key); - } else { - Printf(types,"{\"%s\"},", en); - } - Delete(ckey); - } - Delete(el); - Printf(types,"{0}};\n"); - Printv(table, "_swigt_", key, ", \n", 0); - key = Nextkey(r_mangled); - i++; - } - - Printf(table, "0\n};\n"); - Printf(f_forward,"static swig_type_info *swig_types[%d];\n", i+1); - Printf(f_forward,"\n/* -------- TYPES TABLE (END) -------- */\n\n"); - Printf(f_table,"%s\n", types); - Printf(f_table,"%s\n", table); - Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n"); - Delete(types); - Delete(table); +int +SwigType_check_decl(SwigType *ty, const SwigType *decl) { + SwigType *t,*t1,*t2; + int r; + t = SwigType_typedef_resolve_all(ty); + t1 = SwigType_strip_qualifiers(t); + t2 = SwigType_prefix(t1); + r = Cmp(t2,decl); + Delete(t); + Delete(t1); + Delete(t2); + if (r == 0) return 1; + return 0; } - - - - - - - - - - - - diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 3012d2cc4..604c62a9d 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -22,6 +22,12 @@ #include "doh.h" +/* Status codes */ + +#define SWIG_OK 1 +#define SWIG_ERROR 0 +#define SWIG_NOWRAP 0 + /* Short names for common data types */ typedef DOH String; @@ -32,30 +38,46 @@ typedef DOH File; typedef DOH Parm; typedef DOH ParmList; typedef DOH Node; +typedef DOH Symtab; +typedef DOH Typetab; +typedef DOH SwigType; /* --- Legacy DataType interface. These type codes are provided solely - for backwards compatibility with older modules --- */ + for backwards compatibility with older modules --- */ -#define T_INT 1 -#define T_SHORT 2 -#define T_LONG 3 -#define T_UINT 4 +/* --- The ordering of type values is used to determine type-promotion + in the parser. Do not change */ + +/* Numeric types */ + +#define T_BOOL 1 +#define T_SCHAR 2 +#define T_UCHAR 3 +#define T_SHORT 4 #define T_USHORT 5 -#define T_ULONG 6 -#define T_UCHAR 7 -#define T_SCHAR 8 -#define T_BOOL 9 -#define T_DOUBLE 10 -#define T_FLOAT 11 -#define T_CHAR 12 -#define T_USER 13 -#define T_VOID 14 -#define T_ENUM 15 -#define T_STRING 20 -#define T_POINTER 21 -#define T_REFERENCE 22 -#define T_ARRAY 23 -#define T_FUNCTION 24 +#define T_ENUM 6 +#define T_INT 7 +#define T_UINT 8 +#define T_LONG 9 +#define T_ULONG 10 +#define T_LONGLONG 11 +#define T_ULONGLONG 12 +#define T_FLOAT 20 +#define T_DOUBLE 21 +#define T_NUMERIC 22 + +/* non-numeric */ + +#define T_CHAR 30 +#define T_USER 31 +#define T_VOID 32 +#define T_STRING 33 +#define T_POINTER 34 +#define T_REFERENCE 35 +#define T_ARRAY 36 +#define T_FUNCTION 37 +#define T_MPOINTER 38 +#define T_VARARGS 39 #define T_SYMBOL 98 #define T_ERROR 99 @@ -68,20 +90,21 @@ extern FILE *Swig_open(const String_or_char *name); extern String *Swig_read_file(FILE *f); extern String *Swig_include(const String_or_char *name); extern int Swig_insert_file(const String_or_char *name, File *outfile); -extern int Swig_bytes_read(); -extern void Swig_register_filebyname(const String_or_char *name, File *outfile); -extern File *Swig_filebyname(const String_or_char *name); -extern void Swig_swiglib_set(const String_or_char *name); +extern void Swig_set_config_file(const String_or_char *filename); +extern String *Swig_get_config_file(void); +extern void Swig_swiglib_set(const String_or_char *); extern String *Swig_swiglib_get(); -extern void Swig_set_config_file(const String_or_char *name); -extern String *Swig_get_config_file(); - -#define OUTFILE(x) Swig_filebyname(x) +extern void Swig_register_filebyname(const String_or_char *filename, File *outfile); +extern File *Swig_filebyname(const String_or_char *filename); +extern char *Swig_file_suffix(const String_or_char *filename); +extern char *Swig_file_basename(const String_or_char *filename); +extern char *Swig_file_filename(const String_or_char *filename); +extern char *Swig_file_dirname(const String_or_char *filename); #ifdef MACSWIG -#define SWIG_FILE_DELIMETER ":" +# define SWIG_FILE_DELIMETER ":" #else -#define SWIG_FILE_DELIMETER "/" +# define SWIG_FILE_DELIMETER "/" #endif /* --- Command line parsing --- */ @@ -159,23 +182,29 @@ extern void SwigScanner_idstart(SwigScanner *, char *idchar); #define SWIG_TOKEN_DOLLAR 46 #define SWIG_TOKEN_CODEBLOCK 47 #define SWIG_TOKEN_RSTRING 48 +#define SWIG_TOKEN_LONGLONG 49 +#define SWIG_TOKEN_ULONGLONG 50 #define SWIG_TOKEN_ILLEGAL 98 #define SWIG_TOKEN_LAST 99 /* --- Functions for manipulating the string-based type encoding --- */ -typedef DOH SwigType; extern SwigType *NewSwigType(int typecode); extern void SwigType_add_pointer(SwigType *t); +extern void SwigType_add_memberpointer(SwigType *t, String_or_char *qual); extern void SwigType_del_pointer(SwigType *t); extern void SwigType_add_array(SwigType *t, String_or_char *size); +extern SwigType *SwigType_pop_arrays(SwigType *t); extern void SwigType_add_reference(SwigType *t); extern void SwigType_add_qualifier(SwigType *t, String_or_char *qual); extern void SwigType_add_function(SwigType *t, ParmList *parms); +extern void SwigType_add_template(SwigType *t, ParmList *parms); +extern SwigType *SwigType_pop_function(SwigType *t); +extern ParmList *SwigType_function_parms(SwigType *t); extern List *SwigType_split(SwigType *t); extern String *SwigType_pop(SwigType *t); extern void SwigType_push(SwigType *t, SwigType *s); -extern List *SwigType_parmlist(SwigType *p); +extern List *SwigType_parmlist(const SwigType *p); extern String *SwigType_parm(String *p); extern String *SwigType_str(SwigType *s, const String_or_char *id); extern String *SwigType_lstr(SwigType *s, const String_or_char *id); @@ -184,35 +213,84 @@ extern String *SwigType_lcaststr(SwigType *s, const String_or_char *id); extern String *SwigType_manglestr(SwigType *t); extern SwigType *SwigType_ltype(SwigType *t); extern int SwigType_ispointer(SwigType *t); +extern int SwigType_ismemberpointer(SwigType *t); extern int SwigType_isreference(SwigType *t); extern int SwigType_isarray(SwigType *t); extern int SwigType_isfunction(SwigType *t); extern int SwigType_isqualifier(SwigType *t); extern int SwigType_isconst(SwigType *t); - +extern int SwigType_issimple(SwigType *t); +extern int SwigType_ismutable(SwigType *t); +extern int SwigType_isvarargs(const SwigType *t); +extern int SwigType_istemplate(const SwigType *t); +extern int SwigType_isenum(SwigType *t); +extern int SwigType_check_decl(SwigType *t, const String_or_char *decl); +extern SwigType *SwigType_strip_qualifiers(SwigType *t); extern String *SwigType_base(SwigType *t); +extern String *SwigType_namestr(const SwigType *t); +extern String *SwigType_templateprefix(SwigType *t); +extern String *SwigType_templatesuffix(const SwigType *t); +extern String *SwigType_templateargs(SwigType *t); extern String *SwigType_prefix(SwigType *t); -extern void SwigType_setbase(SwigType *t, String_or_char *name); - -extern int SwigType_typedef(SwigType *type, String_or_char *name); -extern void SwigType_inherit(String *subclass, String *baseclass); -extern void SwigType_new_scope(); -extern void SwigType_reset_scopes(); -extern void SwigType_set_scope_name(String_or_char *name); -extern void SwigType_merge_scope(Hash *scope, String *prefix); -extern Hash *SwigType_pop_scope(); -extern SwigType *SwigType_typedef_resolve(SwigType *t); -extern SwigType *SwigType_typedef_resolve_all(SwigType *t); -extern int SwigType_istypedef(SwigType *t); -extern int SwigType_cmp(String_or_char *pat, SwigType *t); extern int SwigType_array_ndim(SwigType *t); extern String *SwigType_array_getdim(SwigType *t, int n); extern void SwigType_array_setdim(SwigType *t, int n, String_or_char *rep); +extern SwigType *SwigType_array_type(SwigType *t); extern String *SwigType_default(SwigType *t); -extern int SwigType_type(SwigType *t); +extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep); + +/* --- Type-system managment --- */ +extern void SwigType_typesystem_init(); +extern int SwigType_typedef(SwigType *type, String_or_char *name); +extern int SwigType_typedef_class(String_or_char *name); +extern int SwigType_typedef_using(String_or_char *qname); +extern void SwigType_inherit(String *subclass, String *baseclass, String *cast); +extern int SwigType_issubtype(SwigType *subtype, SwigType *basetype); +extern void SwigType_scope_alias(String *aliasname, Typetab *t); +extern void SwigType_using_scope(Typetab *t); +extern void SwigType_new_scope(String_or_char *name); +extern void SwigType_reset_scopes(); +extern void SwigType_set_scope_name(String_or_char *name); +extern void SwigType_inherit_scope(Typetab *scope); +extern Typetab *SwigType_pop_scope(); +extern Typetab *SwigType_set_scope(Typetab *h); +extern void SwigType_print_scope(Typetab *t); +extern SwigType *SwigType_typedef_resolve(SwigType *t); +extern SwigType *SwigType_typedef_resolve_all(SwigType *t); +extern SwigType *SwigType_typedef_qualified(SwigType *t); +extern int SwigType_istypedef(SwigType *t); +extern int SwigType_isclass(SwigType *t); +extern void SwigType_attach_symtab(Symtab *syms); extern void SwigType_remember(SwigType *t); +extern void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata); +extern void (*SwigType_remember_trace(void (*tf)(SwigType *, String *, String *)))(SwigType *, String *, String *); extern void SwigType_emit_type_table(File *f_headers, File *f_table); -extern void SwigType_strip_qualifiers(SwigType *t); +extern int SwigType_type(SwigType *t); + +/* --- Symbol table module --- */ + +extern void Swig_symbol_init(); +extern void Swig_symbol_setscopename(const String_or_char *name); +extern String *Swig_symbol_getscopename(); +extern String *Swig_symbol_qualifiedscopename(Symtab *symtab); +extern Symtab *Swig_symbol_newscope(); +extern Symtab *Swig_symbol_setscope(Symtab *); +extern Symtab *Swig_symbol_getscope(const String_or_char *symname); +extern Symtab *Swig_symbol_current(); +extern Symtab *Swig_symbol_popscope(); +extern Node *Swig_symbol_add(String_or_char *symname, Node *node); +extern void Swig_symbol_cadd(String_or_char *symname, Node *node); +extern Node *Swig_symbol_clookup(String_or_char *symname, Symtab *tab); +extern Symtab *Swig_symbol_cscope(String_or_char *symname, Symtab *tab); +extern Node *Swig_symbol_clookup_local(String_or_char *symname, Symtab *tab); +extern String *Swig_symbol_qualified(Node *node); +extern Node *Swig_symbol_isoverloaded(Node *node); +extern void Swig_symbol_remove(Node *node); +extern void Swig_symbol_alias(String_or_char *aliasname, Symtab *tab); +extern void Swig_symbol_inherit(Symtab *tab); +extern SwigType *Swig_symbol_type_qualify(SwigType *ty, Symtab *tab); +extern String *Swig_symbol_string_qualify(String *s, Symtab *tab); +extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab); /* --- Parameters and Parameter Lists --- */ @@ -221,58 +299,63 @@ extern void SwigType_strip_qualifiers(SwigType *t); extern Parm *NewParm(SwigType *type, String_or_char *n); extern Parm *CopyParm(Parm *p); - - - extern ParmList *CopyParmList(ParmList *); extern int ParmList_len(ParmList *); extern int ParmList_numarg(ParmList *); +extern int ParmList_numrequired(ParmList *); extern String *ParmList_str(ParmList *); extern String *ParmList_protostr(ParmList *); /* --- Parse tree support --- */ -typedef struct { - const char *name; - int (*action)(DOH *obj, void *clientdata); -} SwigRule; +/* DOM-like node access */ +#define nodeType(x) Getattr(x,"nodeType") +#define parentNode(x) Getattr(x,"parentNode") +#define previousSibling(x) Getattr(x,"previousSibling") +#define nextSibling(x) Getattr(x,"nextSibling") +#define firstChild(x) Getattr(x,"firstChild") +#define lastChild(x) Getattr(x,"lastChild") +extern int checkAttribute(Node *obj, const String_or_char *name, const String_or_char *value); -#define SWIG_OK 1 -#define SWIG_NORULE 0 -#define SWIG_ERROR -1 +/* Macros to set up the DOM tree (mostly used by the parser) */ -extern void Swig_add_rule(const String_or_char *, int (*action)(DOH *, void *)); -extern void Swig_add_rules(SwigRule ruleset[]); -extern void Swig_clear_rules(); -extern int Swig_tag_check(DOH *obj, const String_or_char *tagname); -extern int Swig_emit(DOH *obj, void *clientdata); -extern int Swig_emit_all(DOH *obj, void *clientdata); -extern void Swig_set_callback(DOH *obj, void (*cb)(void *clientdata), void *clientdata); -extern void (*Swig_set_trace(DOH *obj, void (*cb)(DOH *, DOH *), DOH *arg))(DOH *, DOH *); -extern void Swig_remove_trace(DOH *obj); -extern void Swig_node_cut(DOH *obj); -extern void Swig_node_insert(DOH *node, DOH *newnode); -extern void Swig_node_temporary(DOH *node); -extern void Swig_node_ignore(DOH *node); -extern void Swig_node_append_child(DOH *node, DOH *cld); -extern int Swig_count_nodes(DOH *node); +#define set_nodeType(x,v) Setattr(x,"nodeType",v) +#define set_parentNode(x,v) Setattr(x,"parentNode",v) +#define set_previousSibling(x,v) Setattr(x,"previousSibling",v) +#define set_nextSibling(x,v) Setattr(x,"nextSibling",v) +#define set_firstChild(x,v) Setattr(x,"firstChild",v) +#define set_lastChild(x,v) Setattr(x,"lastChild",v) -extern DOH *Swig_next(DOH *obj); -extern DOH *Swig_prev(DOH *obj); +extern void appendChild(Node *node, Node *child); +extern void deleteNode(Node *node); +extern Node *copyNode(Node *node); + +extern void Swig_tag_nodes(Node *node, const String_or_char *attrname, DOH *value); + +extern int Swig_require(Node **node, ...); +extern int Swig_save(Node **node,...); +extern void Swig_restore(Node **node); /* Debugging of parse trees */ extern void Swig_debug_emit(int); -extern void Swig_dump_tags(DOH *obj, DOH *root); -extern void Swig_dump_tree(DOH *obj); -extern void Swig_dump_rules(); +extern void Swig_print_tags(File *obj, Node *root); +extern void Swig_print_tree(Node *obj); +extern void Swig_print_node(Node *obj); /* -- Wrapper function Object */ -typedef DOH Wrapper; +typedef struct { + Hash *localh; + String *def; + String *locals; + String *code; +} Wrapper; extern Wrapper *NewWrapper(); +extern void DelWrapper(Wrapper *w); extern void Wrapper_pretty_print(String *str, File *f); +extern void Wrapper_print(Wrapper *w, File *f); extern int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl); extern int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...); extern int Wrapper_check_local(Wrapper *w, const String_or_char *name); @@ -281,160 +364,115 @@ extern char *Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) /* --- Naming functions --- */ -extern void Swig_name_register(String_or_char *method, String_or_char *format); -extern String *Swig_name_mangle(String_or_char *s); -extern String *Swig_name_wrapper(String_or_char *fname); -extern String *Swig_name_member(String_or_char *classname, String_or_char *mname); -extern String *Swig_name_get(String_or_char *vname); -extern String *Swig_name_set(String_or_char *vname); -extern String *Swig_name_construct(String_or_char *classname); -extern String *Swig_name_destroy(String_or_char *classname); +extern void Swig_name_register(const String_or_char *method, const String_or_char *format); +extern void Swig_name_unregister(const String_or_char *method); +extern String *Swig_name_mangle(const String_or_char *s); +extern String *Swig_name_wrapper(const String_or_char *fname); +extern String *Swig_name_member(const String_or_char *classname, const String_or_char *mname); +extern String *Swig_name_get(const String_or_char *vname); +extern String *Swig_name_set(const String_or_char *vname); +extern String *Swig_name_construct(const String_or_char *classname); +extern String *Swig_name_copyconstructor(const String_or_char *classname); +extern String *Swig_name_destroy(const String_or_char *classname); -/* --- Mapping interface --- */ +/* --- parameterized rename functions --- */ -extern void Swig_map_add(Hash *ruleset, Hash *parms, DOH *obj); -extern DOH *Swig_map_match(Hash *ruleset, Hash *parms, int *nmatch); +extern void Swig_name_object_set(Hash *namehash, String_or_char *name, SwigType *decl, DOH *object); +extern DOH *Swig_name_object_get(Hash *namehash, String_or_char *prefix, String_or_char *name, SwigType *decl); +extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived); +extern void Swig_features_get(Hash *features, String_or_char *prefix, String_or_char *name, SwigType *decl, Node *n); +extern void Swig_feature_set(Hash *features, String_or_char *name, SwigType *decl, String_or_char *fname, String *value); /* --- Misc --- */ extern char *Swig_copy_string(const char *c); extern void Swig_banner(File *f); -extern void Swig_section(File *f, const String_or_char *s); -extern DOH *Swig_temp_result(DOH *x); extern String *Swig_string_escape(String *s); extern String *Swig_string_mangle(String *s); -extern void Swig_init(); +extern String *Swig_scopename_prefix(String *s); +extern String *Swig_scopename_last(String *s); +extern String *Swig_scopename_first(String *s); +extern String *Swig_scopename_suffix(String *s); +extern int Swig_scopename_check(String *s); -extern int Swig_proto_cmp(const String_or_char *pat, DOH *node); +extern void Swig_init(); +extern void Swig_warn(const char *filename, int line, const char *msg); + + +#define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg) + +extern void Swig_warning(int num, const String_or_char *filename, int line, const char *fmt, ...); +extern void Swig_error(const String_or_char *filename, int line, const char *fmt, ...); +extern int Swig_error_count(void); +extern void Swig_error_silent(int s); +extern void Swig_warnfilter(const String_or_char *wlist, int val); +extern void Swig_warnall(void); +extern int Swig_warn_count(void); /* --- C Wrappers --- */ -extern String *Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value); -extern SwigType *Swig_clocal_type(SwigType *t); -extern String *Swig_clocal_deref(SwigType *t, String_or_char *name); -extern String *Swig_clocal_assign(SwigType *t, String_or_char *name); extern String *Swig_cparm_name(Parm *p, int i); +extern String *Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value); +extern String *Swig_wrapped_var_type(SwigType *t); +extern String *Swig_wrapped_var_deref(SwigType *t, String_or_char *name); +extern String *Swig_wrapped_var_assign(SwigType *t, String_or_char *name); extern int Swig_cargs(Wrapper *w, ParmList *l); -extern void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl); -extern void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl); +extern String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl); + extern String *Swig_cfunction_call(String_or_char *name, ParmList *parms); -extern String *Swig_cmethod_call(String_or_char *name, ParmList *parms); +extern String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self); extern String *Swig_cconstructor_call(String_or_char *name); extern String *Swig_cppconstructor_call(String_or_char *name, ParmList *parms); extern String *Swig_cdestructor_call(); extern String *Swig_cppdestructor_call(); -extern String *Swig_cmemberset_call(String_or_char *name, SwigType *t); -extern String *Swig_cmemberget_call(String_or_char *name, SwigType *t); +extern String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self); +extern String *Swig_cmemberget_call(String_or_char *name, SwigType *t, String_or_char *self); -extern Wrapper *Swig_cfunction_wrapper(String_or_char *funcname, - SwigType *rtype, - ParmList *parms, - String_or_char *code); +/* --- Transformations --- */ -extern Wrapper *Swig_cmethod_wrapper(String_or_char *classname, - String_or_char *methodname, - SwigType *rtype, - ParmList *parms, - String_or_char *code); +extern int Swig_MethodToFunction(Node *n, String *classname, int flags); +extern int Swig_ConstructorToFunction(Node *n, String *classname, int cplus, int flags); +extern int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags); +extern int Swig_MembersetToFunction(Node *n, String *classname, int flags); +extern int Swig_MembergetToFunction(Node *n, String *classname, int flags); +extern int Swig_VargetToFunction(Node *n); +extern int Swig_VarsetToFunction(Node *n); -extern Wrapper *Swig_cdestructor_wrapper(String_or_char *classname, - String_or_char *code); +#define CWRAP_EXTEND 0x01 +#define CWRAP_SMART_POINTER 0x02 -extern Wrapper *Swig_cppdestructor_wrapper(String_or_char *classname, - String_or_char *code); +/* --- Legacy Typemap API (somewhat simplified, ha!) --- */ -extern Wrapper *Swig_cconstructor_wrapper(String_or_char *classname, - ParmList *parms, - String_or_char *code); +extern void Swig_typemap_init(); +extern void Swig_typemap_register(const String_or_char *op, ParmList *pattern, String_or_char *code, ParmList *locals, ParmList *kwargs); +extern int Swig_typemap_copy(const String_or_char *op, ParmList *srcpattern, ParmList *pattern); +extern void Swig_typemap_clear(const String_or_char *op, ParmList *pattern); +extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat); +extern void Swig_typemap_clear_apply(ParmList *pattern); +extern void Swig_typemap_debug(); -extern Wrapper *Swig_cppconstructor_wrapper(String_or_char *classname, - ParmList *parms, - String_or_char *code); +extern Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *pname, SwigType **matchtype); +extern Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch); +extern String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *lname, + String_or_char *source, String_or_char *target, Wrapper *f); +extern String *Swig_typemap_lookup_new(const String_or_char *op, Node *n, const String_or_char *lname, Wrapper *f); -extern Wrapper *Swig_cmemberset_wrapper(String_or_char *classname, - String_or_char *membername, - SwigType *type, - String_or_char *code); - -extern Wrapper *Swig_cmemberget_wrapper(String_or_char *classname, - String_or_char *membername, - SwigType *type, - String_or_char *code); - -extern Wrapper *Swig_cvarset_wrapper(String_or_char *varname, - SwigType *type, - String_or_char *code); - -extern Wrapper *Swig_cvarget_wrapper(String_or_char *varname, - SwigType *type, - String_or_char *code); - - -/* --- Module loader and handler --- */ - -typedef struct Module Module; -extern void Swig_register_module(const String_or_char *modname, const String_or_char *starttag, - int (*initfunc)(int, char **), - DOH *(*startfunc)(DOH *)); - -extern Module *Swig_load_module(const String_or_char *modname); -extern int Swig_init_module(Module *m, int argc, char **argv); -extern DOH *Swig_start_module(Module *m, DOH *obj); -extern DOH *Swig_run_modules(DOH *node); - -/* --- Legacy Typemap API (somewhat simplified) --- */ - -extern void Swig_typemap_init(); -extern void Swig_typemap_register(const String_or_char *op, SwigType *type, String_or_char *name, String_or_char *code, ParmList *locals); -extern void Swig_typemap_copy(const String_or_char *op, SwigType *stype, String_or_char *sname, - SwigType *ttype, String_or_char *tname); -extern void Swig_typemap_clear(const String_or_char *op, SwigType *type, String_or_char *name); -extern void Swig_typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname); -extern void Swig_typemap_clear_apply(SwigType *type, String_or_char *pname); -extern void Swig_typemap_debug(); -extern Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *pname); -extern char *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *source, String_or_char *target, Wrapper *f); -extern void Swig_typemap_new_scope(Hash *); +extern String *Swig_typemap_lookup_multi(const String_or_char *op, ParmList *parms, String_or_char *source, Wrapper *f, int *nmatch); +extern void Swig_typemap_new_scope(); extern Hash *Swig_typemap_pop_scope(); -/* --- Legacy %except directive API --- */ -extern void Swig_except_register(String_or_char *code); -extern char *Swig_except_lookup(); -extern void Swig_except_clear(); +extern void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f); -/* --- Attribute access macros --- */ - -#define Gettype(x) Getattr(x,"type") -#define Getname(x) Getattr(x,"name") -#define Getvalue(x) Getattr(x,"value") -#define Getlname(x) Getattr(x,"lname") -#define Getignore(x) GetInt(x,"ignore") -#define Getparms(x) Getattr(x,"parms") -#define Gettag(x) Getattr(x,"tag") -#define Getparent(x) Getattr(x,"parent") - -#define Settype(x,v) Setattr(x,"type",v) -#define Setname(x,v) Setattr(x,"name",v) -#define Setlname(x,v) Setattr(x,"lname",v) -#define Setvalue(x,v) Setattr(x,"value", v) -#define Setignore(x,v) SetInt(x,"ignore",v) -#define Settag(x,v) Setattr(x,"tag",v) -#define Setparms(x,v) Setattr(x,"parms", v) -#define Setparent(x,p) Setattr(x,"parent",p) - -#define Getnext(x) Getattr(x,"next") -#define Setnext(x,n) Setattr(x,"next",n) -#define Getprev(x) Getattr(x,"prev") -#define Setprev(x,n) Setattr(x,"prev",n) - -#define Getchild(x) Getattr(x,"child") -#define Setchild(x,c) Setattr(x,"child",c) - -extern int Swig_main(int argc, char **argv, char **modules); -extern void Swig_exit(int n); +/* --- Code fragment support --- */ +extern void Swig_fragment_register(String *name, String *section, String *code); +extern void Swig_fragment_emit(String *name); + #endif + + + diff --git a/Source/Swig/swig.i b/Source/Swig/swig.i index d90df029b..33d174ddf 100644 --- a/Source/Swig/swig.i +++ b/Source/Swig/swig.i @@ -717,11 +717,7 @@ extern FILE *Swig_open(DOH *name); extern DOH *Swig_read_file(FILE *file); extern DOH *Swig_include(DOH *name); -#ifdef MACSWIG -#define SWIG_FILE_DELIMETER ":" -#else #define SWIG_FILE_DELIMETER "/" -#endif %section "Command Line Parsing" diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c new file mode 100644 index 000000000..31a6016c3 --- /dev/null +++ b/Source/Swig/symbol.c @@ -0,0 +1,1124 @@ +/* ----------------------------------------------------------------------------- + * symbol.c + * + * This file implements the SWIG symbol table. See details below. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_symbol_c[] = "$Header$"; + +#include "swig.h" +#include "swigwarn.h" +#include + +/* ----------------------------------------------------------------------------- + * Synopsis + * + * This module provides symbol table management for all of SWIG. In previous + * releases, the management of symbols was rather haphazard. This module tries + * to correct that. + * + * All symbols are associated with simple identifiers. For example, here are some + * declarations that generate symbol table entries: + * + * decl symbol + * -------------- ------------ + * void foo(int); foo + * int x; x + * typedef int *blah; blah + * + * Associated with each symbol is a Hash table that can contain any set of + * attributes that make sense for that object. For example: + * + * typedef int *blah; ----> "name" : 'blah' + * "type" : 'int' + * "decl" : 'p.' + * "storage" : 'typedef' + * + * In some cases, the symbol table needs to manage overloaded entries. For instance, + * overloaded functions. In this case, a linked list is built. The "sym:nextSibling" + * attribute is reserved to hold a link to the next entry. For example: + * + * int foo(int); --> "name" : "foo" "name" : "foo" + * int foo(int,double); "type" : "int" "type" : "int" + * "decl" : "f(int)." "decl" : "f(int,double)." + * ... ... + * "sym:nextSibling" : --------> "sym:nextSibling": --------> ... + * + * When more than one symbol has the same name, the symbol declarator is + * used to detect duplicates. For example, in the above case, foo(int) and + * foo(int,double) are different because their "decl" attribute is different. + * However, if a third declaration "foo(int)" was made, it would generate a + * conflict (due to having a declarator that matches a previous entry). + * + * Structures and classes: + * + * C/C++ symbol tables are normally managed in a few different spaces. The + * most visible namespace is reserved for functions, variables, typedef, enum values + * and such. In C, a separate tag-space is reserved for 'struct name', 'class name', + * and 'union name' declarations. In SWIG, a single namespace is used for everything + * this means that certain incompatibilities will arise with some C programs. For instance: + * + * struct Foo { + * ... + * } + * + * int Foo(); // Error. Name clash. Works in C though + * + * Due to the unified namespace for structures, special handling is performed for + * the following: + * + * typedef struct Foo { + * + * } Foo; + * + * In this case, the symbol table contains an entry for the structure itself. The + * typedef is left out of the symbol table. + * + * Target language vs C: + * + * The symbol tables are normally managed *in the namespace of the target language*. + * This means that name-collisions can be resolved using %rename and related + * directives. A quirk of this is that sometimes the symbol tables need to + * be used for C type resolution as well. To handle this, each symbol table + * also has a C-symbol table lurking behind the scenes. This is used to locate + * symbols in the C namespace. However, this symbol table is not used for error + * reporting nor is it used for anything else during code generation. + * + * Symbol table structure: + * + * Symbol tables themselves are a special kind of node that is organized just like + * a normal parse tree node. Symbol tables are organized in a tree that can be + * traversed using the SWIG-DOM API. The following attributes names are reserved. + * + * name -- Name of the scope defined by the symbol table (if any) + * This name is the C-scope name and is not affected by + * %renaming operations + * symtab -- Hash table mapping identifiers to nodes. + * csymtab -- Hash table mapping C identifiers to nodes. + * + * Reserved attributes on symbol objects: + * + * When a symbol is placed in the symbol table, the following attributes + * are set: + * + * sym:name -- Symbol name + * sym:nextSibling -- Next symbol (if overloaded) + * sym:previousSibling -- Previous symbol (if overloaded) + * sym:symtab -- Symbol table object holding the symbol + * sym:overloaded -- Set to the first symbol if overloaded + * + * These names are modeled after XML namespaces. In particular, every attribute + * pertaining to symbol table management is prefaced by the "sym:" prefix. + * ----------------------------------------------------------------------------- */ + +static Hash *current = 0; /* The current symbol table hash */ +static Hash *ccurrent = 0; /* The current c symbol table hash */ +static Hash *current_symtab = 0; /* Current symbol table node */ +static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */ +static Hash *global_scope = 0; /* Global scope */ + +/* ----------------------------------------------------------------------------- + * Swig_symbol_new() + * + * Create a new symbol table object + * ----------------------------------------------------------------------------- */ + +void +Swig_symbol_init() { + current = NewHash(); + current_symtab = NewHash(); + ccurrent = NewHash(); + set_nodeType(current_symtab,"symboltable"); + Setattr(current_symtab,"symtab",current); + Setattr(current_symtab,"csymtab", ccurrent); + + /* Set the global scope */ + symtabs = NewHash(); + Setattr(symtabs,"",current_symtab); + global_scope = current_symtab; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_setscopename() + * + * Set the C scopename of the current symbol table. + * ----------------------------------------------------------------------------- */ + +void +Swig_symbol_setscopename(const String_or_char *name) { + String *qname; + assert(!Getattr(current_symtab,"name")); + Setattr(current_symtab,"name",name); + + /* Set nested scope in parent */ + + qname = Swig_symbol_qualifiedscopename(current_symtab); + + /* Save a reference to this scope */ + Setattr(symtabs,qname,current_symtab); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_getscopename() + * + * Get the C scopename of the current symbol table + * ----------------------------------------------------------------------------- */ + +String * +Swig_symbol_getscopename() { + return Getattr(current_symtab,"name"); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_getscope() + * + * Given a fully qualified C scopename, this function returns a symbol table + * ----------------------------------------------------------------------------- */ + +Symtab * +Swig_symbol_getscope(const String_or_char *name) { + if (!symtabs) return 0; + if (Strcmp(name,"::") == 0) name = ""; + return Getattr(symtabs,name); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_qualifiedscopename() + * + * Get the fully qualified C scopename of a symbol table. Note, this only pertains + * to the C/C++ scope name. It is not affected by renaming. + * ----------------------------------------------------------------------------- */ + +String * +Swig_symbol_qualifiedscopename(Symtab *symtab) { + String *result = 0; + Hash *parent; + String *name; + if (!symtab) symtab = current_symtab; + parent = parentNode(symtab); + if (parent) { + result = Swig_symbol_qualifiedscopename(parent); + } + name = Getattr(symtab,"name"); + if (name) { + if (!result) { + result = NewString(""); + } + if (Len(result)) { + Printf(result,"::%s",name); + } else { + Printf(result,"%s",name); + } + } + return result; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_newscope() + * + * Create a new scope. Returns the newly created scope. + * ----------------------------------------------------------------------------- */ + +Symtab * +Swig_symbol_newscope() +{ + Hash *n; + Hash *hsyms, *h; + + hsyms = NewHash(); + h = NewHash(); + + set_nodeType(h,"symboltable"); + Setattr(h,"symtab",hsyms); + set_parentNode(h,current_symtab); + + n = lastChild(current_symtab); + if (!n) { + set_firstChild(current_symtab,h); + } else { + set_nextSibling(n,h); + } + set_lastChild(current_symtab,h); + current = hsyms; + ccurrent = NewHash(); + Setattr(h,"csymtab",ccurrent); + current_symtab = h; + return current_symtab; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_setscope() + * + * Set the current scope. Returns the previous current scope. + * ----------------------------------------------------------------------------- */ + +Symtab * +Swig_symbol_setscope(Symtab *sym) { + Symtab *ret = current_symtab; + current_symtab = sym; + current = Getattr(sym,"symtab"); + assert(current); + ccurrent = Getattr(sym,"csymtab"); + assert(ccurrent); + return ret; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_popscope() + * + * Pop out of the current scope. Returns the popped scope and sets the + * scope to the parent scope. + * ----------------------------------------------------------------------------- */ + +Symtab * +Swig_symbol_popscope() { + Hash *h = current_symtab; + current_symtab = parentNode(current_symtab); + assert(current_symtab); + current = Getattr(current_symtab,"symtab"); + assert(current); + ccurrent = Getattr(current_symtab,"csymtab"); + assert(ccurrent); + return h; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_current() + * + * Return the current symbol table. + * ----------------------------------------------------------------------------- */ + +Symtab * +Swig_symbol_current() { + return current_symtab; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_alias() + * + * Makes an alias for a symbol in the global symbol table. + * ----------------------------------------------------------------------------- */ + +void +Swig_symbol_alias(String_or_char *aliasname, Symtab *s) { + String *qname; + qname = Swig_symbol_qualifiedscopename(current_symtab); + if (qname) { + Printf(qname,"::%s", aliasname); + } else { + qname = NewString(aliasname); + } + if (!Getattr(symtabs,qname)) { + Setattr(symtabs,qname,s); + } +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_inherit() + * + * Inherit symbols from another scope. + * ----------------------------------------------------------------------------- */ + +void Swig_symbol_inherit(Symtab *s) { + int i; + List *inherit = Getattr(current_symtab,"inherit"); + if (!inherit) { + inherit = NewList(); + Setattr(current_symtab,"inherit", inherit); + } + assert(s != current_symtab); + for (i = 0; i < Len(inherit); i++) { + Node *n = Getitem(inherit,i); + if (n == s) return; /* Already inherited */ + } + Append(inherit,s); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_cadd() + * + * Adds a node to the C symbol table only. + * ----------------------------------------------------------------------------- */ + +void +Swig_symbol_cadd(String_or_char *name, Node *n) { + Node *append = 0; + + Node *cn; + /* There are a few options for weak symbols. A "weak" symbol + is any symbol that can be replaced by another symbol in the C symbol + table. An example would be a forward class declaration. A forward + class sits in the symbol table until a real class declaration comes along. + + Certain symbols are marked as "sym:typename". These are important + symbols related to the C++ type-system and take precedence in the C + symbol table. An example might be code like this: + + template T foo(T x); + int foo(int); + + In this case, the template is marked with "sym:typename" so that it + stays in the C symbol table (so that it can be expanded using %template). + */ + + if (!name) return; + cn = Getattr(ccurrent,name); + + if (cn && (Getattr(cn,"sym:typename"))) { + /* The node in the C symbol table is a typename. Do nothing */ + /* We might append the symbol at the end */ + append = n; + } else if (cn && (Getattr(cn,"sym:weak"))) { + /* The node in the symbol table is weak. Replace it */ + Setattr(ccurrent,name, n); + } else if (cn && (Getattr(n,"sym:weak"))) { + /* The node being added is weak. Don't worry about it */ + } else if (cn && (Getattr(n,"sym:typename"))) { + /* The node being added is a typename. We definitely add it */ + Setattr(ccurrent,name,n); + append = cn; + } else if (cn && (Strcmp(nodeType(cn),"templateparm") == 0)) { + Swig_error(Getfile(n),Getline(n),"Error. Declaration of '%s' shadows template parameter at %s:%d\n", + name,Getfile(cn),Getline(cn)); + return; + } else if (cn) { + append = n; + } else if (!cn) { + /* No conflict. Add the symbol */ + Setattr(ccurrent,name,n); + } + + /* Multiple entries in the C symbol table. We append to to the symbol table */ + if (append) { + Node *fn, *pn = 0; + cn = Getattr(ccurrent,name); + fn = cn; + while (fn) { + pn = fn; + if (fn == append) { + /* already added. Bail */ + return; + } + fn = Getattr(fn,"csym:nextSibling"); + } + if (pn) { + Setattr(pn,"csym:nextSibling",append); + } + } + + /* Special typedef handling. When a typedef node is added to the symbol table, we + might have to add a type alias. This would occur if the typedef mapped to another + scope in the system. For example: + + class Foo { + }; + + typedef Foo OtherFoo; + + In this case, OtherFoo becomes an alias for Foo. */ + + { + Node *td = n; + while (td && (Strcmp(nodeType(td),"cdecl") == 0) && (checkAttribute(td,"storage","typedef"))) { + SwigType *type; + Node *td1; + type = Copy(Getattr(td,"type")); + SwigType_push(type,Getattr(td,"decl")); + td1 = Swig_symbol_clookup(type,0); + Delete(type); + if (td1 == td) break; + td = td1; + if (td) { + Symtab *st = Getattr(td,"symtab"); + if (st) { + Swig_symbol_alias(Getattr(n,"name"),st); + break; + } + } + } + } +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_add() + * + * Adds a node to the symbol table. Returns the node itself if successfully + * added. Otherwise, it returns the symbol table entry of the conflicting node. + * + * Also places the symbol in a behind-the-scenes C symbol table. This is needed + * for namespace support, type resolution, and other issues. + * ----------------------------------------------------------------------------- */ + +Node * +Swig_symbol_add(String_or_char *symname, Node *n) { + Hash *c, *cn, *cl = 0; + SwigType *decl, *ndecl; + String *cstorage, *nstorage; + int nt = 0, ct = 0; + int pn = 0; + int u1 = 0, u2 = 0; + String *name; + + /* See if the node has a name. If so, we place in the C symbol table for this + scope. We don't worry about overloading here---the primary purpose of this + is to record information for type/name resolution for later. Conflicts + in C namespaces are errors, but these will be caught by the C++ compiler + when compiling the wrapper code */ + + + /* There are a few options for weak symbols. A "weak" symbol + is any symbol that can be replaced by another symbol in the C symbol + table. An example would be a forward class declaration. A forward + class sits in the symbol table until a real class declaration comes along. + + Certain symbols are marked as "sym:typename". These are important + symbols related to the C++ type-system and take precedence in the C + symbol table. An example might be code like this: + + template T foo(T x); + int foo(int); + + In this case, the template is marked with "sym:typename" so that it + stays in the C symbol table (so that it can be expanded using %template). + */ + + name = Getattr(n,"name"); + if (name) { + Swig_symbol_cadd(name,n); + } + + /* No symbol name defined. We return. */ + if (!symname) { + Setattr(n,"sym:symtab",current_symtab); + return n; + } + + /* If node is ignored. We don't proceed any further */ + if (Getattr(n,"feature:ignore")) return n; + + /* See if the symbol already exists in the table */ + c = Getattr(current,symname); + + /* Check for a weak symbol. A weak symbol is allowed to be in the + symbol table, but is silently overwritten by other symbols. An example + would be a forward class declaration. For instance: + + class Foo; + + In this case, "Foo" sits in the symbol table. However, the + definition of Foo would replace the entry if it appeared later. */ + + if (c && Getattr(c,"sym:weak")) { + c = 0; + } + if (c) { + /* There is a symbol table conflict. There are a few cases to consider here: + (1) A conflict between a class/enum and a typedef declaration is okay. + In this case, the symbol table entry is set to the class/enum declaration + itself, not the typedef. + + (2) A conflict between namespaces is okay--namespaces are open + + (3) Otherwise, overloading is only allowed for functions + */ + + /* Check for namespaces */ + if ((Strcmp(nodeType(n),nodeType(c)) == 0) && ((Strcmp(nodeType(n),"namespace") == 0))) { + Node *cl, *pcl = 0; + cl = c; + while (cl) { + pcl = cl; + cl = Getattr(cl,"sym:nextSibling"); + } + Setattr(pcl,"sym:nextSibling",n); + Setattr(n,"sym:symtab", current_symtab); + Setattr(n,"sym:name", symname); + Setattr(n,"sym:previousSibling", pcl); + return n; + } + if (Getattr(n,"allows_typedef")) nt = 1; + if (Getattr(c,"allows_typedef")) ct = 1; + if (nt || ct) { + Node *td, *other; + String *s; + /* At least one of the nodes allows typedef overloading. Make sure that + both don't--this would be a conflict */ + + if (nt && ct) return c; + + /* Figure out which node allows the typedef */ + if (nt) { + td = n; + other = c; + } else { + td = c; + other = n; + } + /* Make sure the other node is a typedef */ + s = Getattr(other,"storage"); + if (!s || (Strcmp(s,"typedef"))) return c; /* No. This is a conflict */ + + /* Hmmm. This appears to be okay. Make sure the symbol table refers to the allow_type node */ + + if (td != c) { + Setattr(current,symname, td); + Setattr(td,"sym:symtab", current_symtab); + Setattr(td,"sym:name", symname); + } + return n; + } + + decl = Getattr(c,"decl"); + ndecl = Getattr(n,"decl"); + + { + String *nt1, *nt2; + nt1 = nodeType(n); + if (Strcmp(nt1,"template") == 0) nt1 = Getattr(n,"templatetype"); + nt2 = nodeType(c); + if (Strcmp(nt2,"template") == 0) nt2 = Getattr(c,"templatetype"); + if (Strcmp(nt1,"using") == 0) u1 = 1; + if (Strcmp(nt2,"using") == 0) u2 = 1; + + if ((Strcmp(nt1,nt2) != 0) && !(u1 || u2)) return c; + } + if (!(u1 || u2)) { + if ((!SwigType_isfunction(decl)) || (!SwigType_isfunction(ndecl))) { + /* Symbol table conflict */ + return c; + } + } + + /* Hmmm. Declarator seems to indicate that this is a function */ + /* Look at storage class to see if compatible */ + cstorage = Getattr(c,"storage"); + nstorage = Getattr(n,"storage"); + + /* If either one is declared as typedef, forget it. We're hosed */ + if (Cmp(cstorage,"typedef") == 0) { + return c; + } + if (Cmp(nstorage,"typedef") == 0) { + return c; + } + /* Okay. Walk down the list of symbols and see if we get a declarator match */ + cn = c; + pn = 0; + while (cn) { + decl = Getattr(cn,"decl"); + if (!(u1 || u2)) { + if (Cmp(ndecl,decl) == 0) { + /* Declarator conflict */ + return cn; + } + } + cl = cn; + cn = Getattr(cn,"sym:nextSibling"); + pn++; + } + /* Well, we made it this far. Guess we can drop the symbol in place */ + Setattr(n,"sym:symtab",current_symtab); + Setattr(n,"sym:name",symname); + Setattr(n,"sym:overname", NewStringf("__SWIG_%d", pn)); + Setattr(cl,"sym:nextSibling",n); + Setattr(n,"sym:previousSibling",cl); + Setattr(cl,"sym:overloaded",c); + Setattr(n,"sym:overloaded",c); + return n; + } + + /* No conflict. Just add it */ + Setattr(n,"sym:symtab",current_symtab); + Setattr(n,"sym:name",symname); + Setattr(n,"sym:overname", NewStringf("__SWIG_%d", pn)); + Setattr(current,symname,n); + return n; +} + +/* ----------------------------------------------------------------------------- + * symbol_lookup_qualified() + * + * Internal function to handle fully qualified symbol table lookups. This + * works from the symbol table supplied in symtab and unwinds its way out + * towards the global scope. + * + * This function operates in the C namespace, not the target namespace. + * ----------------------------------------------------------------------------- */ + +static Node * +symbol_lookup(String_or_char *name, Symtab *symtab) { + Node *n; + List *inherit; + Hash *sym = Getattr(symtab,"csymtab"); + + if (Getmark(symtab)) return 0; + Setmark(symtab,1); + + n = Getattr(sym,name); + if (n) { + Setmark(symtab,0); + return n; + } + inherit = Getattr(symtab,"inherit"); + if (inherit) { + int i,len; + len = Len(inherit); + for (i = 0; i < len; i++) { + n = symbol_lookup(name, Getitem(inherit,i)); + if (n) { + Setmark(symtab,0); + return n; + } + } + } + Setmark(symtab,0); + return 0; +} + +static Node * +symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, int local) { + /* This is a little funky, we search by fully qualified names */ + + if (!symtab) return 0; + if (!prefix) { + Node *n; + String *bname; + String *prefix; + bname = Swig_scopename_last(name); + prefix = Swig_scopename_prefix(name); + n = symbol_lookup_qualified(bname,symtab,prefix,local); + Delete(bname); + Delete(prefix); + return n; + } else { + String *qname; + Symtab *st; + Node *n = 0; + /* Make qualified name of current scope */ + qname = Swig_symbol_qualifiedscopename(symtab); + if (qname && Len(qname)) { + if (Len(prefix)) { + Append(qname,"::"); + Append(qname,prefix); + } + } else { + qname = NewString(prefix); + } + st = Getattr(symtabs,qname); + /* Found a scope match */ + if (st) { + if (!name) return st; + n = symbol_lookup(name, st); + } + Delete(qname); + if (!n) { + if (!local) { + Node *pn = parentNode(symtab); + if (pn) n = symbol_lookup_qualified(name,pn, prefix, local); + } else { + n = 0; + } + } + return n; + } +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_clookup() + * + * Look up a symbol in the symbol table. This uses the C name, not scripting + * names. Note: If we come across a using a directive, we follow it to + * to get the real node. + * ----------------------------------------------------------------------------- */ + +Node * +Swig_symbol_clookup(String_or_char *name, Symtab *n) { + Hash *hsym; + Node *s = 0; + + if (!n) { + hsym = current_symtab; + } else { + if (Strcmp(nodeType(n),"symboltable")) { + n = Getattr(n,"sym:symtab"); + } + assert(n); + if (n) { + hsym = n; + } + } + + if (Swig_scopename_check(name)) { + if (Strncmp(name,"::",2) == 0) { + String *nname = NewString(Char(name)+2); + if (Swig_scopename_check(nname)) { + s = symbol_lookup_qualified(nname,global_scope,0,0); + } + } else { + String *prefix = Swig_scopename_prefix(name); + if (prefix) { + s = symbol_lookup_qualified(name,hsym,0,0); + Delete(prefix); + if (!s) { + return 0; + } + } + } + } + if (!s) { + while (hsym) { + s = symbol_lookup(name,hsym); + if (s) break; + hsym = parentNode(hsym); + if (!hsym) break; + } + } + if (!s) { + return 0; + } + /* Check if s is a 'using' node */ + while (s && Strcmp(nodeType(s),"using") == 0) { + Node *ss; + ss = Swig_symbol_clookup(Getattr(s,"uname"), Getattr(s,"sym:symtab")); + if (!ss) { + Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname")); + } + s = ss; + } + return s; +} + +Node * +Swig_symbol_clookup_local(String_or_char *name, Symtab *n) { + Hash *h, *hsym; + Node *s = 0; + + if (!n) { + hsym = current_symtab; + h = ccurrent; + } else { + if (Strcmp(nodeType(n),"symboltable")) { + n = Getattr(n,"sym:symtab"); + } + assert(n); + hsym = n; + h = Getattr(n,"csymtab"); + } + + if (Swig_scopename_check(name)) { + if (Strncmp(name,"::",2) == 0) { + s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0); + } else { + s = symbol_lookup_qualified(name,hsym,0,0); + } + } + if (!s) { + s = symbol_lookup(name,hsym); + } + if (!s) return 0; + /* Check if s is a 'using' node */ + while (s && Strcmp(nodeType(s),"using") == 0) { + Node *ss = Swig_symbol_clookup_local(Getattr(s,"uname"), Getattr(s,"sym:symtab")); + if (!ss) { + Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname")); + } + s = ss; + } + return s; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_cscope() + * + * Look up a scope name. + * ----------------------------------------------------------------------------- */ + +Symtab * +Swig_symbol_cscope(String_or_char *name, Symtab *symtab) { + if (Strncmp(name,"::",2) == 0) return symbol_lookup_qualified(0, global_scope, name, 0); + return symbol_lookup_qualified(0,symtab,name,0); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_remove() + * + * Remove a symbol + * ----------------------------------------------------------------------------- */ + +void +Swig_symbol_remove(Node *n) { + Symtab *symtab; + String *symname; + Node *symprev; + Node *symnext; + symtab = Getattr(n,"sym:symtab"); /* Get symbol table object */ + symtab = Getattr(symtab,"symtab"); /* Get actual hash table of symbols */ + symname = Getattr(n,"sym:name"); + symprev = Getattr(n,"sym:previousSibling"); + symnext = Getattr(n,"sym:nextSibling"); + + /* If previous symbol, just fix the links */ + if (symprev) { + if (symnext) { + Setattr(symprev,"sym:nextSibling",symnext); + } else { + Delattr(symprev,"sym:nextSibling"); + } + } else { + /* If no previous symbol, see if there is a next symbol */ + if (symnext) { + Setattr(symtab,symname,symnext); + } else { + Delattr(symtab,symname); + } + } + Delattr(n,"sym:symtab"); + Delattr(n,"sym:previousSibling"); + Delattr(n,"sym:nextSibling"); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_qualified() + * + * Return the qualified name of a symbol + * ----------------------------------------------------------------------------- */ + +String * +Swig_symbol_qualified(Node *n) { + Hash *symtab; + if (Strcmp(nodeType(n),"symboltable") == 0) { + symtab = n; + } else { + symtab = Getattr(n,"sym:symtab"); + } + if (!symtab) return NewString(""); + return Swig_symbol_qualifiedscopename(symtab); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_isoverloaded() + * + * Check if a symbol is overloaded. Returns the first symbol if so. + * ----------------------------------------------------------------------------- */ + +Node * +Swig_symbol_isoverloaded(Node *n) { + return Getattr(n,"sym:overloaded"); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_type_qualify() + * + * Create a fully qualified type name + * ----------------------------------------------------------------------------- */ + +SwigType * +Swig_symbol_type_qualify(SwigType *t, Symtab *st) { + List *elements; + String *result; + int i,len; + + result = NewString(""); + elements = SwigType_split(t); + + len = Len(elements); + for (i = 0; i < len; i++) { + String *e = Getitem(elements,i); + if (SwigType_issimple(e)) { + Node *n = Swig_symbol_clookup(e,st); + if (n) { + String *name = Getattr(n,"name"); + Clear(e); + Append(e,name); + if (!Swig_scopename_check(name)) { + String *qname = Swig_symbol_qualified(n); + if (Len(qname)) { + Insert(e,0,"::"); + Insert(e,0,qname); + } + Delete(qname); + } + } else if (SwigType_istemplate(e)) { + String *tprefix, *tsuffix; + SwigType *qprefix; + List *targs; + String *tparm; + tprefix = SwigType_templateprefix(e); + tsuffix = SwigType_templatesuffix(e); + qprefix = Swig_symbol_type_qualify(tprefix,st); + targs = SwigType_parmlist(e); + Printf(qprefix,"<("); + for (tparm = Firstitem(targs); tparm;) { + String *qparm = Swig_symbol_type_qualify(tparm,st); + /* Printf(stdout,"qparm = '%s', tparm = '%s'\n", qparm, tparm);*/ + while (1) { + /* It is possible for an integer to show up here. If so, we need to evaluate it */ + { + Node *nn = Swig_symbol_clookup(qparm,st); + if ((nn) && (Strcmp(nodeType(nn),"cdecl") == 0)) { + String *nv = Getattr(nn,"value"); + if (nv) { + Clear(qparm); + Append(qparm,nv); + } else { + break; + } + } else if ((nn) && (Strcmp(nodeType(nn),"enumitem") == 0)) { + String *qn = Swig_symbol_qualified(nn); + if (Len(qn)) { + Append(qn,"::"); + Append(qn,Getattr(nn,"name")); + Clear(qparm); + Append(qparm,qn); + } + Delete(qn); + break; + } else { + break; + } + } + } + Append(qprefix,qparm); + tparm = Nextitem(targs); + if (tparm) { + Putc(',',qprefix); + } + Delete(qparm); + } + Append(qprefix,")>"); + Append(qprefix,tsuffix); + Clear(e); + Append(e,qprefix); + Delete(tprefix); + Delete(tsuffix); + Delete(qprefix); + } + if (Strncmp(e,"::",2) == 0) { + Delitem(e,0); + Delitem(e,0); + } + Append(result,e); + } else if (SwigType_isfunction(e)) { + List *parms = SwigType_parmlist(e); + String *s = NewString("f("); + String *p; + p = Firstitem(parms); + while (p) { + Append(s,Swig_symbol_type_qualify(p,st)); + p = Nextitem(parms); + if (p) { + Append(s,","); + } + } + Append(s,")."); + Append(result,s); + Delete(s); + } else { + Append(result,e); + } + } + Delete(elements); + return result; +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_typedef_reduce() + * + * Chase a typedef through symbol tables looking for a match. + * ----------------------------------------------------------------------------- */ + +SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { + SwigType *prefix, *base; + Node *n; + + base = SwigType_base(ty); + prefix = SwigType_prefix(ty); + + n = Swig_symbol_clookup(base,tab); + if (!n) { + Delete(base); + Delete(prefix); + return Copy(ty); + } + if (Strcmp(nodeType(n),"using") == 0) { + String *uname = Getattr(n,"uname"); + if (uname) { + n = Swig_symbol_clookup(base,Getattr(n,"sym:symtab")); + if (!n) { + Delete(base); + Delete(prefix); + return Copy(ty); + } + } + } + if (Strcmp(nodeType(n),"cdecl") == 0) { + String *storage = Getattr(n,"storage"); + if (Strcmp(storage,"typedef") == 0) { + SwigType *decl; + SwigType *rt; + SwigType *nt = Copy(Getattr(n,"type")); + decl = Getattr(n,"decl"); + if (decl) { + SwigType_push(nt,decl); + } + SwigType_push(nt,prefix); + Delete(base); + Delete(prefix); + rt = Swig_symbol_typedef_reduce(nt, Getattr(n,"sym:symtab")); + Delete(nt); + return rt; + } + } + Delete(base); + Delete(prefix); + return Copy(ty); +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_string_qualify() + * + * This function takes a string and looks for identifiers. Identifiers are + * then qualified according to scope rules. This function is used in a number + * of settings including expression evaluation, scoping of conversion operators, + * and so forth. + * ----------------------------------------------------------------------------- */ + +String * +Swig_symbol_string_qualify(String *s, Symtab *st) { + char *c; + String *id, *r; + int have_id = 0; + + id = NewString(""); + r = NewString(""); + c = Char(s); + while (*c) { + if (isalpha(*c) || (*c == '_') || (*c == ':')) { + Putc(*c,id); + have_id = 1; + } else { + if (have_id) { + String *qid = Swig_symbol_type_qualify(id,st); + Append(r,qid); + Clear(id); + Delete(qid); + have_id = 0; + } + Putc(*c,r); + } + c++; + } + if (have_id) { + String *qid = Swig_symbol_type_qualify(id,st); + Append(r,qid); + Delete(qid); + } + Delete(id); + return r; +} + diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c index 81566d21e..7df80420c 100644 --- a/Source/Swig/tree.c +++ b/Source/Swig/tree.c @@ -11,40 +11,19 @@ * ----------------------------------------------------------------------------- */ #include "swig.h" +#include +#include -static char cvsroot[] = "$Header$"; - -/* Hash table mapping tag names to handler functions */ -static Hash *rules = 0; -static int debug_emit = 0; +char cvsroot_tree_c[] = "$Header$"; /* ----------------------------------------------------------------------------- - * Swig_next() - * Swig_prev() - * - * Return next/prev node in a parse tree - * ----------------------------------------------------------------------------- */ - -DOH *Swig_next(DOH *obj) { - return Getnext(obj); -} - -DOH *Swig_prev(DOH *obj) { - return Getprev(obj); -} - -void Swig_debug_emit(int n) { - debug_emit = n; -} - -/* ----------------------------------------------------------------------------- - * Swig_dump_tags() + * Swig_print_tags() * * Dump the tag structure of a parse tree to standard output * ----------------------------------------------------------------------------- */ void -Swig_dump_tags(DOH *obj, DOH *root) { +Swig_print_tags(DOH *obj, DOH *root) { DOH *croot, *newroot; DOH *cobj; @@ -52,22 +31,21 @@ Swig_dump_tags(DOH *obj, DOH *root) { else croot = root; while (obj) { - Printf(stdout,"%s . %s (%s:%d)\n", croot, Getattr(obj,"tag"), Getfile(obj), Getline(obj)); - cobj = Getattr(obj,"child"); + Printf(stdout,"%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj)); + cobj = firstChild(obj); if (cobj) { - newroot = NewStringf("%s . %s",croot,Getattr(obj,"tag")); - Swig_dump_tags(cobj,newroot); + newroot = NewStringf("%s . %s",croot,nodeType(obj)); + Swig_print_tags(cobj,newroot); Delete(newroot); } - obj = Swig_next(obj); + obj = nextSibling(obj); } if (!root) Delete(croot); } - /* ----------------------------------------------------------------------------- - * Swig_dump_tree() + * Swig_print_tree() * * Dump the tree structure of a parse tree to standard output * ----------------------------------------------------------------------------- */ @@ -85,429 +63,339 @@ static void print_indent(int l) { } } -void -Swig_dump_tree(DOH *obj) { - DOH *k; - DOH *cobj; - while (obj) { - print_indent(0); - Printf(stdout,"+++ %s ----------------------------------------\n", Getattr(obj,"tag")); - - k = Firstkey(obj); - while (k) { - if ((Cmp(k,"tag") == 0) || (Cmp(k,"child") == 0) || - (Cmp(k,"parent") == 0) || (Cmp(k,"next") == 0) || - (Cmp(k,"prev") == 0)) { - /* Do nothing */ - } else if (Cmp(k,"parms") == 0) { - print_indent(2); - Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k))); - } else { - DOH *o; - char *trunc = ""; - print_indent(2); +/* ----------------------------------------------------------------------------- + * Swig_dump_node(Node *n) + * ----------------------------------------------------------------------------- */ + +void +Swig_print_node(Node *obj) { + String *k; + Node *cobj; + + print_indent(0); + Printf(stdout,"+++ %s ----------------------------------------\n", nodeType(obj)); + k = Firstkey(obj); + while (k) { + if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) || + (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) || + (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) { + /* Do nothing */ + } else if (Cmp(k,"parms") == 0) { + print_indent(2); + Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k))); + } else { + DOH *o; + char *trunc = ""; + print_indent(2); + if (DohIsString(Getattr(obj,k))) { o = Str(Getattr(obj,k)); if (Len(o) > 40) { trunc = "..."; } Printf(stdout,"%-12s - \"%(escape)-0.40s%s\"\n", k, o, trunc); Delete(o); - } - k = Nextkey(obj); - } - cobj = Getattr(obj,"child"); - if (cobj) { - indent_level += 6; - Printf(stdout,"\n"); - Swig_dump_tree(cobj); - indent_level -= 6; - } else { - print_indent(1); - Printf(stdout,"\n"); - } - obj = Swig_next(obj); - } -} - - -/* ----------------------------------------------------------------------------- - * Swig_add_rule() - * - * Adds a new rule to the tree walking code. - * ----------------------------------------------------------------------------- */ - -void -Swig_add_rule(const String_or_char *name, int (*action)(DOH *node, void *clientdata)) -{ - if (!rules) rules = NewHash(); - if (action) - Setattr(rules,name,NewVoid((void *) action,0)); - else - Delattr(rules,name); - - if (debug_emit) { - Printf(stderr,"Swig_add_rule : '%s' -> %x\n", name, action); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_add_rules() - * - * Add a complete set of rules to the rule system - * ----------------------------------------------------------------------------- */ - -void -Swig_add_rules(SwigRule ruleset[]) { - int i = 0; - while (ruleset[i].name) { - Swig_add_rule(ruleset[i].name, ruleset[i].action); - i++; - } -} - -/* ----------------------------------------------------------------------------- - * Swig_clear_rules() - * - * Clears all of the existing rules - * ----------------------------------------------------------------------------- */ - -void -Swig_clear_rules() -{ - if (rules) Delete(rules); - rules = NewHash(); - if (debug_emit) { - Printf(stderr,"Swig_clear_rules :\n"); - } - -} - -/* ----------------------------------------------------------------------------- - * Swig_dump_rules() - * - * Print out debugging information for the rules - * ----------------------------------------------------------------------------- */ - -void -Swig_dump_rules() { - String *key; - Printf(stdout,"SWIG emit rules:::\n"); - if (!rules) { - Printf(stdout," No rules defined.\n"); - return; - } - key = Firstkey(rules); - while (key) { - Printf(stdout," '%-15s' -> %x\n", key, GetVoid(rules,key)); - key = Nextkey(rules); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_tag_check() - * - * Checks the tag name of an object taking into account namespace issues. - * For example, a check of "function" will match any object with a tag - * of the form "xxx:function" whereas a check of "c:function" will check - * for a more exact match. Returns 1 if a match is found, 0 otherwise - * ----------------------------------------------------------------------------- */ - -int -Swig_tag_check(DOH *obj, const String_or_char *tagname) { - String *tag; - char *tc; - char *tnc; - tag = Getattr(obj,"tag"); - assert(tag); - - tnc = Char(tag); - tc = Char(tagname); - - while (tnc) { - if (strcmp(tc,tnc) == 0) return 1; - tnc = strchr(tnc,':'); - if (tnc) tnc++; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_set_callback() - * - * Sets a parser callback function for a node. - * ----------------------------------------------------------------------------- */ -void -Swig_set_callback(DOH *obj, void (*cb)(void *clientdata), void *clientdata) { - SetVoid(obj,"-callback-",(void *)cb); - if (clientdata) - SetVoid(obj,"-callbackarg-", clientdata); -} - -/* ----------------------------------------------------------------------------- - * Swig_set_trace() - * - * Sets a tracing function on a parse tree node. Returns the old tracing - * function (if any). - * ----------------------------------------------------------------------------- */ - -void (*Swig_set_trace(DOH *obj, void (*cb)(DOH *, DOH *), DOH *arg))(DOH *, DOH *) { - void (*old)(DOH *,DOH *); - old = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-"); - SetVoid(obj,"-trace-", (void *) cb); - if (arg) - Setattr(obj,"-tracearg-", arg); - return old; -} - -/* ----------------------------------------------------------------------------- - * Swig_remove_trace() - * - * Removes the tracing function from a parse tree node - * ----------------------------------------------------------------------------- */ - -void -Swig_remove_trace(DOH *obj) { - Delattr(obj,"-trace-"); - Delattr(obj,"-tracearg-"); -} - - -/* ----------------------------------------------------------------------------- - * Swig_node_temporary() - * - * Sets a node as being temporary (deleted immediately after it is emitted) - * ----------------------------------------------------------------------------- */ - -void Swig_node_temporary(DOH *obj) { - SetInt(obj,"-temp-",1); -} - -/* ----------------------------------------------------------------------------- - * Swig_node_ignore() - * - * Causes a node to be ignored - * ----------------------------------------------------------------------------- */ - -void Swig_node_ignore(DOH *obj) { - SetInt(obj,"-ignore-",1); -} - -/* ----------------------------------------------------------------------------- - * int Swig_emit() - * - * This function calls the handler function (if any) for an object. - * ----------------------------------------------------------------------------- */ - -int -Swig_emit(DOH *obj, void *clientdata) { - DOH *tag; - DOH *actionobj; - char *tc; - int (*action)(DOH *obj, void *clientdata); - void (*callback)(void *clientdata); - void (*tracefunc)(DOH *obj, DOH *arg); - int ret; - - assert(obj); - - if (!rules) { - Printf(stderr,"No rules defined in Swig_emit()!\n"); - return SWIG_ERROR; - } - if (obj) { - if (Getattr(obj,"-ignore-")) return SWIG_OK; - tag = Getattr(obj,"tag"); - assert(tag); - tc = Char(tag); - while(tc) { - actionobj = Getattr(rules,tc); - if (actionobj) { - if (debug_emit) { - Printf(stderr,"Swig_emit : Matched tag '%s' -> rule '%s'\n", tag, tc); - } - /* Check for user tracing -- traces occur before any handlers are called */ - tracefunc = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-"); - if (tracefunc) { - DOH *tobj = Getattr(obj,"-tracearg-"); - (*tracefunc)(obj,tobj); - } - action = (int (*)(DOH *, void *)) Data(actionobj); - ret = (*action)(obj,clientdata); - /* Check for a parser callback */ - callback = (void (*)(void *clientdata)) GetVoid(obj,"-callback-"); - if (callback) { - void *cbarg; - cbarg = GetVoid(obj,"-callbackarg-"); - (*callback)(cbarg); - Delattr(obj,"-callback-"); - Delattr(obj,"-callbackarg-"); - } - return ret; } else { - tc = strchr(tc,':'); - if (tc) tc++; + Printf(stdout,"%-12s - 0x%x\n", k, Getattr(obj,k)); } } - actionobj = Getattr(rules,"*"); - if (actionobj) { - if (debug_emit) { - Printf(stderr,"Swig_emit : Matched tag '%s' -> rule '*'\n", tag); - } - /* Check for user tracing -- traces occur before any handlers are called */ - tracefunc = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-"); - if (tracefunc) { - DOH *tobj = Getattr(obj,"-tracearg-"); - (*tracefunc)(obj,tobj); - } - action = (int (*)(DOH *, void *)) Data(actionobj); - ret = (*action)(obj,clientdata); - /* Check for a parser callback */ - callback = (void (*)(void *clientdata)) GetVoid(obj,"-callback-"); - if (callback) { - void *cbarg; - cbarg = GetVoid(obj,"-callbackarg-"); - (*callback)(cbarg); - Delattr(obj,"-callback-"); - Delattr(obj,"-callbackarg-"); - } - return ret; - } - if (debug_emit) { - Printf(stderr,"Swig_emit : No rule defined for tag '%s'\n", tag); - } + k = Nextkey(obj); + } + cobj = firstChild(obj); + if (cobj) { + indent_level += 6; + Printf(stdout,"\n"); + Swig_print_tree(cobj); + indent_level -= 6; + } else { + print_indent(1); + Printf(stdout,"\n"); } - return SWIG_NORULE; } -/* ----------------------------------------------------------------------------- - * Swig_emit_all() - * - * Emit all of the nodes at this level. - * ----------------------------------------------------------------------------- */ - -int -Swig_emit_all(DOH *obj, void *clientdata) { - int ret; +void +Swig_print_tree(DOH *obj) { while (obj) { - ret = Swig_emit(obj,clientdata); - if (ret < 0) return ret; - obj = Swig_next(obj); + Swig_print_node(obj); + obj = nextSibling(obj); } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_node_cut() - * - * This function cuts an object out of a parse tree. To do this, the object - * MUST be properly initialized with "next", "prev", and "parent" attributes. - * ----------------------------------------------------------------------------- */ - -void Swig_node_cut(DOH *obj) { - DOH *parent; - DOH *next; - DOH *prev; - - parent = Getattr(obj,"parent"); - assert(parent); - next = Getattr(obj,"next"); - prev = Getattr(obj,"prev"); - - DohIncref(obj); /* Make sure object doesn't go away */ - Delattr(obj,"parent"); /* Disassociate from my parent */ - - if (!next && !prev) { - /* Well, this is a single child. Guess we'll just tell the parent that their child is gone */ - Delattr(parent,"child"); - return; - } - - /* If no next node, then this must be at the end of a list */ - if (!next) { - Delattr(prev,"next"); /* Break the 'next' link in the previous node */ - Delattr(obj,"prev"); /* Break my link back to the previous object */ - return; - } - - /* No previous node. This must be the beginning of a list */ - if (!prev) { - Delattr(next,"prev"); /* Break the 'prev' link of the next node */ - Setattr(parent,"child",next); /* Update parent to point at next node */ - Delattr(obj,"next"); /* Break my link to the next object */ - return; - } - - /* In the middle of a list someplace */ - Setattr(prev,"next",next); /* Update previous node to my next node */ - Setattr(next,"prev",prev); /* Update next node to my previous node */ - Delattr(obj,"next"); - Delattr(obj,"prev"); - return; } /* ----------------------------------------------------------------------------- - * Swig_node_insert() - * - * Inserts a node after a given node. The node to be inserted should be - * isolated (no parent, no siblings, etc...). - * ----------------------------------------------------------------------------- */ - -void -Swig_node_insert(DOH *node, DOH *newnode) { - DOH *next; - next = Getattr(node,"next"); - - if (next) { - Setattr(newnode,"next", next); - Setattr(next,"prev", newnode); - } - Setattr(node,"next",newnode); - Setattr(newnode,"prev", node); - Setattr(newnode,"parent", Getattr(node,"parent")); -} - -/* ----------------------------------------------------------------------------- - * Swig_node_append_child() + * appendChild() * * Appends a new child to a node * ----------------------------------------------------------------------------- */ void -Swig_node_append_child(DOH *node, DOH *chd) { - DOH *c; - DOH *pc; - c = Getattr(node,"child"); - if (!c) { - Setattr(node,"child",chd); - Setattr(chd,"parent",node); - return; +appendChild(Node *node, Node *chd) { + Node *lc; + + if (!chd) return; + + lc = lastChild(node); + if (!lc) { + set_firstChild(node,chd); + } else { + set_nextSibling(lc,chd); + set_previousSibling(chd,lc); } - while (c) { - pc = c; - c = Getnext(c); + while (chd) { + lc = chd; + set_parentNode(chd,node); + chd = nextSibling(chd); } - Setattr(pc,"next",chd); - Setattr(chd,"prev",pc); - Setattr(chd,"parent",node); + set_lastChild(node,lc); } /* ----------------------------------------------------------------------------- - * Swig_count_nodes() + * deleteNode() * - * Count number of nodes at this level + * Deletes a node. * ----------------------------------------------------------------------------- */ -int Swig_count_nodes(DOH *node) { - int n = 0; - while (node) { - n++; - node = Getnext(node); +void +deleteNode(Node *n) { + Node *parent; + Node *prev; + Node *next; + + parent = parentNode(n); + prev = previousSibling(n); + next = nextSibling(n); + if (prev) { + set_nextSibling(prev,next); + } else { + if (parent) { + set_firstChild(parent,next); + } + } + if (next) { + set_previousSibling(next,prev); + } else { + if (parent) { + set_lastChild(parent,prev); + } } - return n; } - +/* ----------------------------------------------------------------------------- + * copyNode() + * + * Copies a node, but only copies simple attributes (no lists, hashes). + * ----------------------------------------------------------------------------- */ + +Node * +copyNode(Node *n) { + String *key; + DOH *v; + Node *c = NewHash(); + for (key = Firstkey(n); key; key = Nextkey(n)) { + v = Getattr(n,key); + if (DohIsString(v)) { + Setattr(c,key,Copy(v)); + } + } + Setfile(c,Getfile(n)); + Setline(c,Getline(n)); + return c; +} + +/* ----------------------------------------------------------------------------- + * Swig_tag_nodes() + * + * Tags a collection of nodes with an attribute. Used by the parser to mark + * subtypes with extra information. + * ----------------------------------------------------------------------------- */ + +void +Swig_tag_nodes(Node *n, const String_or_char *attrname, DOH *value) { + while (n) { + Setattr(n,attrname,value); + Swig_tag_nodes(firstChild(n),attrname, value); + n = nextSibling(n); + } +} + +int +checkAttribute(Node *n, const String_or_char *name, const String_or_char *value) { + String *v; + v = Getattr(n,name); + if (!v) return 0; + if (Cmp(v,value) == 0) return 1; + return 0; +} + +/* ----------------------------------------------------------------------------- + * Swig_require() + * ----------------------------------------------------------------------------- */ + +#define MAX_SWIG_STACK 256 +static Hash *attr_stack[MAX_SWIG_STACK]; +static Node **nodeptr_stack[MAX_SWIG_STACK]; +static Node *node_stack[MAX_SWIG_STACK]; +static int stackp = 0; +static int stack_direction = 0; + +static void set_direction(int n, int *x) { + if (n == 1) { + set_direction(0,&n); + } else { + if (&n < x) { + stack_direction = -1; /* Stack grows down */ + } else { + stack_direction = 1; /* Stack grows up */ + } + } +} + +int +Swig_require(Node **nptr, ...) { + va_list ap; + char *name; + DOH *obj; + DOH *frame = 0; + Node *n = *nptr; + va_start(ap, nptr); + name = va_arg(ap, char *); + while (name) { + int newref = 0; + int opt = 0; + if (*name == '*') { + newref = 1; + name++; + } else if (*name == '?') { + newref = 1; + opt = 1; + name++; + } + obj = Getattr(n,name); + if (!opt && !obj) { + Printf(stderr,"%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", + Getfile(n), Getline(n), name, nodeType(n)); + assert(obj); + } + if (!obj) obj = DohNone; + if (newref) { + if (!attr_stack[stackp]) { + attr_stack[stackp]= NewHash(); + } + frame = attr_stack[stackp]; + if (Setattr(frame,name,obj)) { + Printf(stderr,"Swig_require('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name); + } + } + name = va_arg(ap, char *); + } + va_end(ap); + if (frame) { + /* This is a sanity check to make sure no one is saving data, but not restoring it */ + if (stackp > 0) { + int e = 0; + if (!stack_direction) set_direction(1,0); + + if (stack_direction < 0) { + if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1; + } else { + if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1; + } + if (e) { + Printf(stderr, +"Swig_require('%s'): Fatal memory management error. If you are seeing this\n\ +message. It means that the target language module is not managing its memory\n\ +correctly. A handler for '%s' probably forgot to call Swig_restore().\n\ +Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1])); + assert(0); + } + } + nodeptr_stack[stackp] = nptr; + node_stack[stackp] = n; + stackp++; + } + return 1; +} +int +Swig_save(Node **nptr, ...) { + va_list ap; + char *name; + DOH *obj; + DOH *frame; + Node *n = *nptr; + if ((stackp > 0) && (nodeptr_stack[stackp-1] == nptr)) { + frame = attr_stack[stackp-1]; + } else { + if (stackp > 0) { + int e = 0; + if (!stack_direction) set_direction(1,0); + if (stack_direction < 0) { + if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1; + } else { + if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1; + } + if (e) { + Printf(stderr, +"Swig_save('%s'): Fatal memory management error. If you are seeing this\n\ +message. It means that the target language module is not managing its memory\n\ +correctly. A handler for '%s' probably forgot to call Swig_restore().\n\ +Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1])); + assert(0); + } + } + attr_stack[stackp] = NewHash(); + nodeptr_stack[stackp] = nptr; + node_stack[stackp] = n; + frame = attr_stack[stackp]; + stackp++; + } + va_start(ap, nptr); + name = va_arg(ap, char *); + while (name) { + if (*name == '*') { + name++; + } else if (*name == '?') { + name++; + } + obj = Getattr(n,name); + if (!obj) { + obj = DohNone; + } + if (Setattr(frame,name,obj)) { + Printf(stderr,"Swig_save('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name); + } + name = va_arg(ap, char *); + } + va_end(ap); + return 1; +} + +void +Swig_restore(Node **nptr) { + String *key; + Hash *frame; + Node *n = *nptr; + assert(stackp > 0); + if (!(nptr==nodeptr_stack[stackp-1])) { + Printf(stderr, +"Swig_restore('%s'): Fatal memory management error. If you are seeing this\n\ +message. It means that the target language module is not managing its memory\n\ +correctly. A handler for '%s' probably forgot to call Swig_restore().\n\ +Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1])); + assert(0); + } + stackp--; + frame = attr_stack[stackp]; + nodeptr_stack[stackp] = 0; + node_stack[stackp] = 0; + for (key = Firstkey(frame); key; key = Nextkey(frame)) { + DOH *obj = Getattr(frame,key); + if (obj != DohNone) { + Setattr(n,key,obj); + } else { + Delattr(n,key); + } + Delattr(frame,key); + } +} diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 3d68dd4fd..fbb5dddbd 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -9,10 +9,33 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_typemap_c[] = "$Header$"; #include "swig.h" +/* ----------------------------------------------------------------------------- + * Typemaps are stored in a collection of nested hash tables. Something like + * this: + * + * [ type ] + * +-------- [ name ] + * +-------- [ name ] + * + * Each hash table [ type ] or [ name ] then contains references to the + * different typemap methods. These are referenced by names such as + * "tmap:in", "tmap:out", "tmap:argout", and so forth. + * + * The object corresponding to a specific method has the following + * attributes: + * + * "type" - Typemap type + * "pname" - Parameter name + * "code" - Typemap code + * "typemap" - Descriptive text describing the actual map + * "locals" - Local variables (if any) + * + * ----------------------------------------------------------------------------- */ + #define MAX_SCOPE 32 static Hash *typemaps[MAX_SCOPE]; @@ -33,10 +56,15 @@ void Swig_typemap_init() { tm_scope = 0; } -static char *parm_key(String_or_char *pname) { - static char temp[512] = "-"; - strcpy(temp+1,Char(pname)); - return temp; +static String *tmop_name(const String_or_char *op) { + static Hash *names = 0; + String *s; + if (!names) names = NewHash(); + s = Getattr(names,op); + if (s) return s; + s = NewStringf("tmap:%s",op); + Setattr(names,op,s); + return s; } /* ----------------------------------------------------------------------------- @@ -45,14 +73,9 @@ static char *parm_key(String_or_char *pname) { * Create a new typemap scope * ----------------------------------------------------------------------------- */ -void Swig_typemap_new_scope(Hash *oldscope) { +void Swig_typemap_new_scope() { tm_scope++; - if (!oldscope) { - typemaps[tm_scope] = NewHash(); - } else { - typemaps[tm_scope] = oldscope; - DohIncref(oldscope); - } + typemaps[tm_scope] = NewHash(); } /* ----------------------------------------------------------------------------- @@ -64,12 +87,7 @@ void Swig_typemap_new_scope(Hash *oldscope) { Hash * Swig_typemap_pop_scope() { if (tm_scope > 0) { - if (Len(typemaps[tm_scope])) { - return typemaps[tm_scope--]; - } else { - Delete(typemaps[tm_scope--]); - return 0; - } + return typemaps[tm_scope--]; } return 0; } @@ -77,56 +95,96 @@ Swig_typemap_pop_scope() { /* ----------------------------------------------------------------------------- * Swig_typemap_register() * - * Add a new typemap + * Add a new multi-valued typemap * ----------------------------------------------------------------------------- */ void -Swig_typemap_register(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *code, ParmList *locals) { - char *key; +Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_char *code, ParmList *locals, ParmList *kwargs) { Hash *tm; Hash *tm1; Hash *tm2; + Parm *np; + String *tmop; + SwigType *type; + String *pname; + + if (!parms) return; + tmop = tmop_name(op); + + /* Register the first type in the parameter list */ + + type = Getattr(parms,"type"); + pname = Getattr(parms,"name"); /* See if this type has been seen before */ tm = Getattr(typemaps[tm_scope],type); if (!tm) { tm = NewHash(); - Setattr(typemaps[tm_scope],Char(type),tm); + Setattr(typemaps[tm_scope],Copy(type),tm); Delete(tm); } - if ((pname) && Len(pname)) { + if (pname) { /* See if parameter has been seen before */ - key = parm_key(pname); - tm1 = Getattr(tm,key); + tm1 = Getattr(tm,pname); if (!tm1) { tm1 = NewHash(); - Setattr(tm,key,tm1); + Setattr(tm,NewString(pname),tm1); Delete(tm1); } tm = tm1; } - tm2 = Getattr(tm,op); - if (tm2) { - SwigType *tm_type; - String *tm_pname; - tm_type = Getattr(tm2,"type"); - tm_pname = Getattr(tm2,"pname"); - if (Cmp(tm_type,type) || Cmp(tm_pname,pname)) { - tm2 = 0; - } - } + + /* Now see if this typemap op has been seen before */ + tm2 = Getattr(tm,tmop); if (!tm2) { tm2 = NewHash(); - Setattr(tm,op,tm2); + Setattr(tm,tmop,tm2); Delete(tm2); } - Setattr(tm2,"code",NewString(code)); - Setattr(tm2,"type",NewString(type)); - Setattr(tm2,"typemap",NewStringf("typemap(%s) %s", op, SwigType_str(type,pname))); - if (pname) { - Setattr(tm2,"pname", NewString(pname)); + + /* For a multi-valued typemap, the typemap code and information + is really only stored in the last argument. However, to + make this work, we perform a really neat trick using + the typemap operator name. + + For example, consider this typemap + + %typemap(in) (int foo, int *bar, char *blah[]) { + ... + } + + To store it, we look at typemaps for the following: + + operator type-name + ---------------------------------------------- + "in" int foo + "in-int+foo:" int *bar + "in-int+foo:-p.int+bar: char *blah[] + + Notice how the operator expands to encode information about + previous arguments. + + */ + + np = nextSibling(parms); + if (np) { + /* Make an entirely new operator key */ + String *newop = NewStringf("%s-%s+%s:",op,type,pname); + /* Now reregister on the remaining arguments */ + Swig_typemap_register(newop,np,code,locals,kwargs); + + /* Setattr(tm2,newop,newop); */ + Delete(newop); + } else { + Setattr(tm2,"code",NewString(code)); + Setattr(tm2,"type",Copy(type)); + Setattr(tm2,"typemap",NewStringf("typemap(%s) %s", op, SwigType_str(type,pname))); + if (pname) { + Setattr(tm2,"pname", NewString(pname)); + } + Setattr(tm2,"locals", CopyParmList(locals)); + Setattr(tm2,"kwargs", CopyParmList(kwargs)); } - Setattr(tm2,"locals", CopyParmList(locals)); } /* ----------------------------------------------------------------------------- @@ -145,7 +203,7 @@ Swig_typemap_get(SwigType *type, String_or_char *name, int scope) { return 0; } if ((name) && Len(name)) { - tm1 = Getattr(tm, parm_key(name)); + tm1 = Getattr(tm, name); return tm1; } return tm; @@ -157,107 +215,263 @@ Swig_typemap_get(SwigType *type, String_or_char *name, int scope) { * Copy a typemap * ----------------------------------------------------------------------------- */ -void -Swig_typemap_copy(const String_or_char *op, SwigType *stype, String_or_char *sname, - SwigType *ttype, String_or_char *tname) { - - Hash *tm=0, *tm1; +int +Swig_typemap_copy(const String_or_char *op, ParmList *srcparms, ParmList *parms) { + Hash *tm = 0; + String *tmop; + Parm *p; + String *pname; + SwigType *ptype; int ts = tm_scope; + String *tmops, *newop; + if (ParmList_len(parms) != ParmList_len(srcparms)) return -1; + + tmop = tmop_name(op); while (ts >= 0) { - tm = Swig_typemap_get(stype,sname,ts); - if (tm) break; - tm = Swig_typemap_get(stype,0,ts); - if (tm) break; + p = srcparms; + tmops = NewString(tmop); + while (p) { + ptype = Getattr(p,"type"); + pname = Getattr(p,"name"); + + /* Lookup the type */ + tm = Swig_typemap_get(ptype,pname,ts); + if (!tm) break; + + tm = Getattr(tm,tmops); + if (!tm) break; + + /* Got a match. Look for next typemap */ + newop = NewStringf("%s-%s+%s:",tmops,ptype,pname); + Delete(tmops); + tmops = newop; + p = nextSibling(p); + } + Delete(tmops); + + if (!p && tm) { + + /* Got some kind of match */ + Swig_typemap_register(op,parms, Getattr(tm,"code"), Getattr(tm,"locals"),Getattr(tm,"kwargs")); + return 0; + } ts--; } - if (!tm) return; - tm1 = Getattr(tm,op); - if (!tm1) return; - Swig_typemap_register(op,ttype,tname, Getattr(tm1,"code"), Getattr(tm1,"locals")); + /* Not found */ + return -1; + } /* ----------------------------------------------------------------------------- * Swig_typemap_clear() * - * Delete a typemap + * Delete a multi-valued typemap * ----------------------------------------------------------------------------- */ void -Swig_typemap_clear(const String_or_char *op, SwigType *type, String_or_char *name) { - Hash *tm; +Swig_typemap_clear(const String_or_char *op, ParmList *parms) { + SwigType *type; + String *name; + Parm *p; + String *newop; + Hash *tm = 0; - tm = Swig_typemap_get(type,name,tm_scope); - if (tm) - Delattr(tm,op); + /* This might not work */ + newop = NewString(op); + p = parms; + while (p) { + type = Getattr(p,"type"); + name = Getattr(p,"name"); + tm = Swig_typemap_get(type,name,tm_scope); + if (!tm) return; + p = nextSibling(p); + if (p) + Printf(newop,"-%s+%s:", type,name); + } + if (tm) { + tm = Getattr(tm, tmop_name(newop)); + if (tm) { + Delattr(tm,"code"); + Delattr(tm,"locals"); + Delattr(tm,"kwargs"); + } + } + Delete(newop); } /* ----------------------------------------------------------------------------- * Swig_typemap_apply() * - * %apply directive. This function is nothing more than a glorified typemap - * copy. Note: this is *very* different than SWIG1.1 although the end result - * is very "similar." + * Multi-argument %apply directive. This is pretty horrible so I sure hope + * it works. * ----------------------------------------------------------------------------- */ -static void merge_attributes(Hash *target, Hash *source) { - String *key; - for (key = Firstkey(source); key; key = Nextkey(source)) { - /* if (Getattr(target,key)) continue; */ - Setattr(target,key,Getattr(source,key)); +static +int count_args(String *s) { + /* Count up number of arguments */ + int na = 0; + char *c = Char(s); + while (*c) { + if (*c == '+') na++; + c++; } + return na; } -void -Swig_typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname) { - Hash *tm, *tm1, *am; - int ts = tm_scope; - char *key; +int +Swig_typemap_apply(ParmList *src, ParmList *dest) { + String *ssig, *dsig; + Parm *p, *np, *lastp, *dp, *lastdp = 0; + int narg = 0; + int ts = tm_scope; + SwigType *type = 0, *name; + Hash *tm, *sm; + int match = 0; - tm = Swig_typemap_get(type,pname,tm_scope); - if (!tm) { - tm = Getattr(typemaps[tm_scope],type); - if (!tm) { - tm = NewHash(); - Setattr(typemaps[tm_scope], Char(type), tm); - Delete(tm); - } - if ((pname) && Len(pname)) { - key = parm_key(pname); - tm1 = NewHash(); - Setattr(tm,key,tm1); - Delete(tm1); - tm = tm1; + /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */ + + /* Create type signature of source */ + ssig = NewString(""); + dsig = NewString(""); + p = src; + dp = dest; + lastp = 0; + while (p) { + lastp = p; + lastdp = dp; + np = nextSibling(p); + if (np) { + Printf(ssig,"-%s+%s:", Getattr(p,"type"), Getattr(p,"name")); + Printf(dsig,"-%s+%s:", Getattr(dp,"type"), Getattr(dp,"name")); + narg++; } + p = np; + dp = nextSibling(dp); } - /* tm contains the typemap table into which we are going to be copying */ + + /* make sure a typemap node exists for the last destination node */ + tm = Getattr(typemaps[tm_scope],Getattr(lastdp,"type")); + if (!tm) { + tm = NewHash(); + Setattr(typemaps[tm_scope],Getattr(lastdp,"type"),tm); + Delete(tm); + } + name = Getattr(lastdp,"name"); + if (name) { + Hash *tm1 = Getattr(tm,name); + if (!tm1) { + tm1 = NewHash(); + Setattr(tm,NewString(name),tm1); + Delete(tm1); + } + tm = tm1; + } + + /* This is a little nasty. We need to go searching for all possible typemaps in the + source and apply them to the target */ + + type = Getattr(lastp,"type"); + name = Getattr(lastp,"name"); + while (ts >= 0) { - am = Swig_typemap_get(tm_type, tmname,ts); - if (am) { - merge_attributes(tm,am); + + /* See if there is a matching typemap in this scope */ + sm = Swig_typemap_get(type,name,ts); + + if (sm) { + /* Got a typemap. Need to only merge attributes for methods that match our signature */ + String *key; + + match = 1; + for (key = Firstkey(sm); key; key = Nextkey(sm)) { + /* Check for a signature match with the source signature */ + if ((count_args(key) == narg) && (Strstr(key,ssig))) { + String *oldm; + /* A typemap we have to copy */ + String *nkey = Copy(key); + Replace(nkey,ssig,dsig,DOH_REPLACE_ANY); + + /* Make sure the typemap doesn't already exist in the target map */ + + oldm = Getattr(tm,nkey); + if (!oldm || (!Getattr(tm,"code"))) { + String *code; + ParmList *locals; + ParmList *kwargs; + Hash *sm1 = Getattr(sm,key); + + code = Getattr(sm1,"code"); + locals = Getattr(sm1,"locals"); + kwargs = Getattr(sm1,"kwargs"); + if (code) { + Replace(nkey,dsig,"", DOH_REPLACE_ANY); + Replace(nkey,"tmap:","", DOH_REPLACE_ANY); + Swig_typemap_register(nkey,dest,code,locals,kwargs); + } + } + Delete(nkey); + } + } } ts--; } + return match; } /* ----------------------------------------------------------------------------- * Swig_typemap_clear_apply() * - * %clear directive. Clears all typemaps for a type. + * %clear directive. Clears all typemaps for a type (in the current scope only). * ----------------------------------------------------------------------------- */ +/* Multi-argument %clear directive */ void -Swig_typemap_clear_apply(SwigType *type, String_or_char *name) { - Hash *tm; - - tm = Getattr(typemaps[tm_scope],type); - if (!tm) return; - if ((name) && (Len(name))) { - Delattr(tm,parm_key(name)); - } else { - Delattr(typemaps[tm_scope],type); - } -} +Swig_typemap_clear_apply(Parm *parms) { + String *tsig; + Parm *p, *np, *lastp; + int narg = 0; + Hash *tm; + String *name; + /* Create a type signature of the parameters */ + tsig = NewString(""); + p = parms; + lastp = 0; + while (p) { + lastp = p; + np = nextSibling(p); + if (np) { + Printf(tsig,"-%s+%s:", Getattr(p,"type"), Getattr(p,"name")); + narg++; + } + p = np; + } + tm = Getattr(typemaps[tm_scope],Getattr(lastp,"type")); + if (!tm) { + Delete(tsig); + return; + } + name = Getattr(lastp,"name"); + if (name) { + tm = Getattr(tm,name); + } + if (tm) { + /* Clear typemaps that match our signature */ + String *key, *key2; + for (key = Firstkey(tm); key; key = Nextkey(tm)) { + if (Strncmp(key,"tmap:",5) == 0) { + int na = count_args(key); + if ((na == narg) && Strstr(key,tsig)) { + Hash *h = Getattr(tm,key); + for (key2 = Firstkey(h); key2; key2 = Nextkey(h)) { + Delattr(h,key2); + } + } + } + } + } + Delete(tsig); +} /* Internal function to strip array dimensions. */ static SwigType *strip_arrays(SwigType *type) { @@ -272,25 +486,30 @@ static SwigType *strip_arrays(SwigType *type) { return t; } + /* ----------------------------------------------------------------------------- - * Swig_typemap_search_op() + * Swig_typemap_search() * - * Search for a typemap match. + * Search for a typemap match. Tries to find the most specific typemap + * that includes a 'code' attribute. * ----------------------------------------------------------------------------- */ Hash * -Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *name) { +Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *name, SwigType **matchtype) { Hash *result = 0, *tm, *tm1, *tma; + Hash *backup = 0; SwigType *noarrays = 0; SwigType *primitive = 0; SwigType *ctype = 0; int ts; int isarray; - char *cname = 0; + String *cname = 0; + SwigType *unstripped = 0; + String *tmop = tmop_name(op); - if ((name) && Len(name)) cname = parm_key(name); - isarray = SwigType_isarray(type); + if ((name) && Len(name)) cname = name; ts = tm_scope; + while (ts >= 0) { ctype = type; while (ctype) { @@ -299,61 +518,455 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na if (tm && cname) { tm1 = Getattr(tm,cname); if (tm1) { - result = Getattr(tm1,op); /* See if there is a type-name match */ - if (result) goto ret_result; + result = Getattr(tm1,tmop); /* See if there is a type-name match */ + if (result && Getattr(result,"code")) goto ret_result; + if (result) backup = result; } } if (tm) { - result = Getattr(tm,op); /* See if there is simply a type match */ - if (result) goto ret_result; + result = Getattr(tm,tmop); /* See if there is simply a type match */ + if (result && Getattr(result,"code")) goto ret_result; + if (result) backup = result; } - + isarray = SwigType_isarray(ctype); if (isarray) { - /* If working with arrays, strip away all of the dimensions and replace with ANY. + /* If working with arrays, strip away all of the dimensions and replace with "ANY". See if that generates a match */ if (!noarrays) noarrays = strip_arrays(ctype); tma = Getattr(typemaps[ts],noarrays); if (tma && cname) { tm1 = Getattr(tma,cname); if (tm1) { - result = Getattr(tm1,op); /* type-name match */ - if (result) goto ret_result; + result = Getattr(tm1,tmop); /* type-name match */ + if (result && Getattr(result,"code")) goto ret_result; + if (result) backup = result; } } if (tma) { - result = Getattr(tma,op); /* type match */ + result = Getattr(tma,tmop); /* type match */ + if (result && Getattr(result,"code")) goto ret_result; + if (result) backup = result; + } + Delete(noarrays); + noarrays = 0; + } + + /* No match so far. If the type is unstripped, we'll strip its + qualifiers and check. Otherwise, we'll try to resolve a typedef */ + + if (!unstripped) { + unstripped = ctype; + ctype = SwigType_strip_qualifiers(ctype); + if (Strcmp(ctype,unstripped) != 0) continue; /* Types are different */ + Delete(ctype); + ctype = unstripped; + unstripped = 0; + } + { + String *octype; + if (unstripped) { + if (unstripped != type) { + Delete(ctype); + } + ctype = unstripped; + unstripped = 0; + } + octype = ctype; + ctype = SwigType_typedef_resolve(ctype); + if (octype != type) Delete(octype); + } + } +#ifdef NEW + /* No match seems to be found at all. Try a SWIGTYPE substitution */ + if (!primitive) { + SwigType *base = SwigType_base(type); + primitive = SwigType_prefix(type); + if (Strstr(base,"enum ")) { + Append(primitive,"enum SWIGTYPE"); + } else { + Append(primitive,"SWIGTYPE"); + } + tm = Getattr(typemaps[ts],primitive); + if (tm && cname) { + tm1 = Getattr(tm, cname); + if (tm1) { + result = Getattr(tm1,tmop); if (result) goto ret_result; } } - - /* No match so far. If this type had a typedef declaration, maybe there are - some typemaps for that */ - { - SwigType *nt = SwigType_typedef_resolve(ctype); - if (ctype != type) Delete(ctype); - ctype = nt; + if (tm) { + result = Getattr(tm,tmop); + if (result) goto ret_result; } + Delete(primitive); + primitive = 0; } - +#endif + /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */ if (!primitive) primitive = SwigType_default(type); tm = Getattr(typemaps[ts],primitive); - if (tm) { - result = Getattr(tm,op); + if (tm && cname) { + tm1 = Getattr(tm,cname); + if (tm1) { + result = Getattr(tm1,tmop); /* See if there is a type-name match */ + if (result) goto ret_result; + } + } + if (tm) { /* See if there is simply a type match */ + result = Getattr(tm,tmop); if (result) goto ret_result; } if (ctype != type) Delete(ctype); ts--; /* Hmmm. Nothing found in this scope. Guess we'll go try another scope */ } - + result = backup; + ret_result: if (noarrays) Delete(noarrays); if (primitive) Delete(primitive); + if ((unstripped) && (unstripped != type)) Delete(unstripped); + if (matchtype) { + *matchtype = Copy(ctype); + } if (type != ctype) Delete(ctype); return result; } +/* ----------------------------------------------------------------------------- + * Swig_typemap_search_multi() + * + * Search for a multi-valued typemap. + * ----------------------------------------------------------------------------- */ + +Hash * +Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch) { + SwigType *type; + SwigType *mtype = 0; + String *name; + String *newop; + Hash *tm, *tm1; + + if (!parms) { + *nmatch = 0; + return 0; + } + type = Getattr(parms,"type"); + name = Getattr(parms,"name"); + + /* Try to find a match on the first type */ + tm = Swig_typemap_search(op, type, name, &mtype); + if (tm) { + if (mtype && SwigType_isarray(mtype)) { + Setattr(parms,"tmap:match", mtype); + } + Delete(mtype); + newop = NewStringf("%s-%s+%s:", op, type,name); + tm1 = Swig_typemap_search_multi(newop, nextSibling(parms), nmatch); + if (tm1) tm = tm1; + if (Getattr(tm,"code")) { + *(nmatch) = *nmatch + 1; + } else { + tm = 0; + } + Delete(newop); + } + return tm; +} + + +/* ----------------------------------------------------------------------------- + * typemap_replace_vars() + * + * Replaces typemap variables on a string. index is the $n variable. + * type and pname are the type and parameter name. + * ----------------------------------------------------------------------------- */ + +static +void replace_local_types(ParmList *p, String *name, String *rep) { + SwigType *t; + while (p) { + t = Getattr(p,"type"); + Replace(t,name,rep,DOH_REPLACE_ANY); + p = nextSibling(p); + } +} + +static +void typemap_replace_vars(String *s, ParmList *locals, SwigType *type, String *pname, String *lname, int index) +{ + char var[512]; + char *varname; + SwigType *ftype; + + ftype = SwigType_typedef_resolve_all(type); + + if (!pname) pname = lname; + { + Parm *p; + int rep = 0; + p = locals; + while (p) { + if (Strchr(Getattr(p,"type"),'$')) rep = 1; + p = nextSibling(p); + } + if (!rep) locals = 0; + } + + sprintf(var,"$%d_",index); + varname = &var[strlen(var)]; + + /* If the original datatype was an array. We're going to go through and substitute + it's array dimensions */ + + if (SwigType_isarray(type)) { + String *size; + int ndim = SwigType_array_ndim(type); + int i; + size = NewString(""); + for (i = 0; i < ndim; i++) { + String *dim = SwigType_array_getdim(type,i); + if (index == 1) { + char t[32]; + sprintf(t,"$dim%d",i); + Replace(s,t,dim,DOH_REPLACE_ANY); + replace_local_types(locals,t,dim); + } + sprintf(varname,"dim%d",i); + Replace(s,var,dim,DOH_REPLACE_ANY); + replace_local_types(locals,var,dim); + if (Len(size)) Putc('*',size); + Append(size,dim); + Delete(dim); + } + sprintf(varname,"size"); + Replace(s,var,size,DOH_REPLACE_ANY); + replace_local_types(locals,var,size); + Delete(size); + } + + /* Parameter name substitution */ + if (index == 1) { + Replace(s,"$parmname",pname, DOH_REPLACE_ANY); + } + strcpy(varname,"name"); + Replace(s,var,pname,DOH_REPLACE_ANY); + + /* Type-related stuff */ + { + SwigType *star_type, *amp_type, *base_type; + SwigType *ltype, *star_ltype, *amp_ltype; + String *mangle, *star_mangle, *amp_mangle, *base_mangle; + String *descriptor, *star_descriptor, *amp_descriptor; + String *ts; + char *sc; + + sc = Char(s); + + if (strstr(sc,"type")) { + /* Given type : $type */ + ts = SwigType_str(type,0); + if (index == 1) { + Replace(s, "$type", ts, DOH_REPLACE_ANY); + replace_local_types(locals,"$type",type); + } + strcpy(varname,"type"); + Replace(s,var,ts,DOH_REPLACE_ANY); + replace_local_types(locals,var,type); + Delete(ts); + sc = Char(s); + } + if (strstr(sc,"ltype")) { + /* Local type: $ltype */ + ltype = SwigType_ltype(type); + ts = SwigType_str(ltype,0); + if (index == 1) { + Replace(s, "$ltype", ts, DOH_REPLACE_ANY); + replace_local_types(locals,"$ltype",ltype); + } + strcpy(varname,"ltype"); + Replace(s,var,ts,DOH_REPLACE_ANY); + replace_local_types(locals,var,ltype); + Delete(ts); + Delete(ltype); + sc = Char(s); + } + if (strstr(sc,"mangle") || strstr(sc,"descriptor")) { + /* Mangled type */ + + mangle = SwigType_manglestr(type); + if (index == 1) + Replace(s, "$mangle", mangle, DOH_REPLACE_ANY); + strcpy(varname,"mangle"); + Replace(s,var,mangle,DOH_REPLACE_ANY); + + descriptor = NewStringf("SWIGTYPE%s", mangle); + + if (index == 1) + if (Replace(s, "$descriptor", descriptor, DOH_REPLACE_ANY)) + SwigType_remember(type); + + strcpy(varname,"descriptor"); + if (Replace(s,var,descriptor,DOH_REPLACE_ANY)) + SwigType_remember(type); + + Delete(descriptor); + Delete(mangle); + } + + /* One pointer level removed */ + /* This creates variables of the form + $*n_type + $*n_ltype + */ + + if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype))) { + if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type))) { + star_type = Copy(ftype); + } else { + star_type = Copy(type); + } + if (!SwigType_isreference(star_type)) { + if (SwigType_isarray(star_type)) { + Delete(SwigType_pop(star_type)); + } else { + SwigType_del_pointer(star_type); + } + ts = SwigType_str(star_type,0); + if (index == 1) { + Replace(s, "$*type", ts, DOH_REPLACE_ANY); + replace_local_types(locals,"$*type",star_type); + } + sprintf(varname,"$*%d_type",index); + Replace(s,varname,ts,DOH_REPLACE_ANY); + replace_local_types(locals,varname,star_type); + Delete(ts); + } else { + Delete(SwigType_pop(star_type));; + } + star_ltype = SwigType_ltype(star_type); + ts = SwigType_str(star_ltype,0); + if (index == 1) { + Replace(s, "$*ltype", ts, DOH_REPLACE_ANY); + replace_local_types(locals,"$*ltype",star_ltype); + } + sprintf(varname,"$*%d_ltype",index); + Replace(s,varname,ts,DOH_REPLACE_ANY); + replace_local_types(locals,varname,star_ltype); + Delete(ts); + Delete(star_ltype); + + star_mangle = SwigType_manglestr(star_type); + if (index == 1) + Replace(s, "$*mangle", star_mangle, DOH_REPLACE_ANY); + + sprintf(varname,"$*%d_mangle",index); + Replace(s,varname,star_mangle,DOH_REPLACE_ANY); + + star_descriptor = NewStringf("SWIGTYPE%s", star_mangle); + if (index == 1) + if (Replace(s, "$*descriptor", + star_descriptor, DOH_REPLACE_ANY)) + SwigType_remember(star_type); + sprintf(varname,"$*%d_descriptor",index); + if (Replace(s,varname,star_descriptor,DOH_REPLACE_ANY)) + SwigType_remember(star_type); + + Delete(star_descriptor); + Delete(star_mangle); + Delete(star_type); + } + else { + /* TODO: Signal error if one of the $* substitutions is + requested */ + } + /* One pointer level added */ + amp_type = Copy(type); + SwigType_add_pointer(amp_type); + ts = SwigType_str(amp_type,0); + if (index == 1) { + Replace(s, "$&type", ts, DOH_REPLACE_ANY); + replace_local_types(locals,"$&type",amp_type); + } + sprintf(varname,"$&%d_type",index); + Replace(s,varname,ts,DOH_REPLACE_ANY); + replace_local_types(locals,varname,amp_type); + Delete(ts); + + amp_ltype = SwigType_ltype(type); + SwigType_add_pointer(amp_ltype); + ts = SwigType_str(amp_ltype,0); + + if (index == 1) { + Replace(s, "$<ype", ts, DOH_REPLACE_ANY); + replace_local_types(locals, "$<ype", amp_ltype); + } + sprintf(varname,"$&%d_ltype",index); + Replace(s,varname,ts,DOH_REPLACE_ANY); + replace_local_types(locals,varname,amp_ltype); + Delete(ts); + Delete(amp_ltype); + + amp_mangle = SwigType_manglestr(amp_type); + if (index == 1) + Replace(s, "$&mangle", amp_mangle, DOH_REPLACE_ANY); + sprintf(varname,"$&%d_mangle",index); + Replace(s,varname,amp_mangle,DOH_REPLACE_ANY); + + amp_descriptor = NewStringf("SWIGTYPE%s", amp_mangle); + if (index == 1) + if (Replace(s, "$&descriptor", + amp_descriptor, DOH_REPLACE_ANY)) + SwigType_remember(amp_type); + sprintf(varname,"$&%d_descriptor",index); + if (Replace(s,varname,amp_descriptor,DOH_REPLACE_ANY)) + SwigType_remember(amp_type); + + Delete(amp_descriptor); + Delete(amp_mangle); + Delete(amp_type); + + /* Base type */ + if (SwigType_isarray(type)) { + SwigType *bt = Copy(type); + Delete(SwigType_pop_arrays(bt)); + base_type = SwigType_str(bt,0); + Delete(bt); + } else { + base_type = SwigType_base(type); + } + + if (index == 1) { + Replace(s,"$basetype", base_type, DOH_REPLACE_ANY); + replace_local_types(locals,"$basetype", base_type); + } + strcpy(varname,"basetype"); + Replace(s,var,base_type,DOH_REPLACE_ANY); + replace_local_types(locals,var,base_type); + + base_mangle = SwigType_manglestr(base_type); + if (index == 1) + Replace(s,"$basemangle", base_mangle, DOH_REPLACE_ANY); + strcpy(varname,"basemangle"); + Replace(s,var,base_mangle,DOH_REPLACE_ANY); + Delete(base_mangle); + Delete(base_type); + } + + /* Replace any $n. with (&n)-> */ + { + char temp[64]; + sprintf(var,"$%d.",index); + sprintf(temp,"(&$%d)->", index); + Replace(s,var,temp,DOH_REPLACE_ANY); + } + + /* Replace the bare $n variable */ + sprintf(var,"$%d",index); + Replace(s,var,lname,DOH_REPLACE_ANY); + Delete(ftype); +} /* ------------------------------------------------------------------------ * static typemap_locals() @@ -362,42 +975,50 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na * creates the local variables. * ------------------------------------------------------------------------ */ -static void typemap_locals(SwigType *t, String_or_char *pname, DOHString *s, ParmList *l, Wrapper *f) { +static void typemap_locals(DOHString *s, ParmList *l, Wrapper *f, int argnum) { Parm *p; char *new_name; - + p = l; while (p) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); + SwigType *pt = Getattr(p,"type"); + String *pn = Getattr(p,"name"); + String *value = Getattr(p,"value"); if (pn) { if (Len(pn) > 0) { - DOHString *str; - SwigType *tt; + String *str; + int isglobal = 0; str = NewString(""); + + if (Strncmp(pn,"_global_",8) == 0) { + isglobal = 1; + } + /* If the user gave us $type as the name of the local variable, we'll use the passed datatype instead */ - if (Cmp(SwigType_base(pt),"$type")==0 || Cmp(SwigType_base(pt),"$basetype")==0) { - tt = t; + if ((argnum >= 0) && (!isglobal)) { + Printf(str,"%s%d",pn,argnum); } else { - tt = pt; + Printf(str,"%s",pn); } - Printf(str,"%s",pn); - /* Substitute parameter names */ - Replace(str,"$arg",pname, DOH_REPLACE_ANY); - if (Cmp(SwigType_base(pt),"$basetype")==0) { - /* use $basetype */ - new_name = Wrapper_new_localv(f,str,SwigType_base(tt),str,0); - } else { - new_name = Wrapper_new_localv(f,str, SwigType_str(tt,str), 0); + if (isglobal && Wrapper_check_local(f,str)) { + p = nextSibling(p); + continue; + } + if (value) { + new_name = Wrapper_new_localv(f,str, SwigType_str(pt,str), "=", value, NIL); + } else { + new_name = Wrapper_new_localv(f,str, SwigType_str(pt,str), NIL); + } + if (!isglobal) { + /* Substitute */ + Replace(s,pn,new_name,DOH_REPLACE_ID); } - /* Substitute */ - Replace(s,pn,new_name,DOH_REPLACE_ID); } } - p = Getnext(p); + p = nextSibling(p); } } @@ -407,43 +1028,39 @@ static void typemap_locals(SwigType *t, String_or_char *pname, DOHString *s, Par * Perform a typemap lookup (ala SWIG1.1) * ----------------------------------------------------------------------------- */ -char *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *source, +String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, + String_or_char *lname, String_or_char *source, String_or_char *target, Wrapper *f) { Hash *tm; - String *s; + String *s = 0; + SwigType *mtype = 0; ParmList *locals; - - tm = Swig_typemap_search(op,type,pname); + tm = Swig_typemap_search(op,type,pname,&mtype); if (!tm) return 0; s = Getattr(tm,"code"); if (!s) return 0; + + /* Blocked */ + if (Cmp(s,"pass") == 0) return 0; + s = Copy(s); /* Make a local copy of the typemap code */ locals = Getattr(tm,"locals"); + if (locals) locals = CopyParmList(locals); + + /* This is wrong. It replaces locals in place. Need to fix this */ + if (mtype && SwigType_isarray(mtype)) { + typemap_replace_vars(s,locals,mtype,pname,lname,1); + } else { + typemap_replace_vars(s,locals,type,pname,lname,1); + } - /* Replace array dimensions */ if (locals && f) { - typemap_locals(type,pname,s,locals,f); + typemap_locals(s,locals,f,-1); } - - /* If the original datatype was an array. We're going to go through and substitute - it's array dimensions */ - - if (SwigType_isarray(type)) { - char temp[10]; - int ndim = SwigType_array_ndim(type); - int i; - for (i = 0; i < ndim; i++) { - DOHString *dim = SwigType_array_getdim(type,i); - sprintf(temp,"$dim%d",i); - if (f) - Replace(Getattr(f,"locals"),temp,dim, DOH_REPLACE_ANY); - Replace(s,temp,dim,DOH_REPLACE_ANY); - } - } - + /* Now perform character replacements */ Replace(s,"$source",source,DOH_REPLACE_ANY); Replace(s,"$target",target,DOH_REPLACE_ANY); @@ -451,20 +1068,256 @@ char *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_ch String *tmname = Getattr(tm,"typemap"); if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY); } - Replace(s,"$type",SwigType_str(type,0),DOH_REPLACE_ANY); - { - SwigType *ltype = Swig_clocal_type(type); - Replace(s,"$ltype",SwigType_str(ltype,0), DOH_REPLACE_ANY); - Delete(ltype); - } Replace(s,"$parmname",pname, DOH_REPLACE_ANY); + /* Replace(s,"$name",pname,DOH_REPLACE_ANY); */ + Delete(locals); + Delete(mtype); + return s; +} - /* Print base type (without any pointers) */ - Replace(s,"$basetype",SwigType_base(type), DOH_REPLACE_ANY); - Replace(s,"$basemangle",SwigType_manglestr(SwigType_base(type)), DOH_REPLACE_ANY); - Replace(s,"$mangle",SwigType_manglestr(type), DOH_REPLACE_ANY); - Swig_temp_result(s); - return Char(s); +/* ----------------------------------------------------------------------------- + * Swig_typemap_lookup_new() + * + * Attach one or more typemaps to a node + * ----------------------------------------------------------------------------- */ + +String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f) +{ + SwigType *type; + SwigType *mtype = 0; + String *pname; + Hash *tm; + String *s = 0; + ParmList *locals; + ParmList *kw; + char temp[256]; + String *symname; + String *cname = 0; + String *clname = 0; + + type = Getattr(node,"type"); + if (!type) return 0; + + pname = Getattr(node,"name"); + tm = Swig_typemap_search(op,type,pname,&mtype); + if (!tm) return 0; + + s = Getattr(tm,"code"); + if (!s) return 0; + + /* Empty typemap. No match */ + if (Cmp(s,"pass") == 0) return 0; + + s = Copy(s); /* Make a local copy of the typemap code */ + + locals = Getattr(tm,"locals"); + if (locals) locals = CopyParmList(locals); + + if (pname) { + if (SwigType_istemplate(pname)) { + cname = SwigType_namestr(pname); + pname = cname; + } + } + if (SwigType_istemplate((char*)lname)) { + clname = SwigType_namestr((char *)lname); + lname = clname; + } + if (mtype && SwigType_isarray(mtype)) { + typemap_replace_vars(s,locals,mtype,pname,(char *) lname,1); + } else { + typemap_replace_vars(s,locals,type,pname,(char *) lname,1); + } + if (locals && f) { + typemap_locals(s,locals,f,-1); + } + { + String *tmname = Getattr(tm,"typemap"); + if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY); + } + Replace(s,"$name",pname,DOH_REPLACE_ANY); + + symname = Getattr(node,"sym:name"); + if (symname) { + Replace(s,"$symname",symname, DOH_REPLACE_ANY); + } + + Setattr(node,tmop_name(op),s); + if (locals) { + sprintf(temp,"%s:locals", Char(op)); + Setattr(node,tmop_name(temp), locals); + Delete(locals); + } + + if (checkAttribute(tm,"type","SWIGTYPE")) { + sprintf(temp,"%s:SWIGTYPE", Char(op)); + Setattr(node,tmop_name(temp),"1"); + } + + /* Attach kwargs */ + kw = Getattr(tm,"kwargs"); + while (kw) { + sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name"))); + Setattr(node,tmop_name(temp), Copy(Getattr(kw,"value"))); + kw = nextSibling(kw); + } + + /* Look for warnings */ + { + String *w; + sprintf(temp,"%s:warning", Char(op)); + w = Getattr(node,tmop_name(temp)); + if (w) { + Swig_warning(0,Getfile(node),Getline(node),"%s\n", w); + } + } + + /* Look for code fragments */ + { + String *f; + sprintf(temp,"%s:fragment", Char(op)); + f = Getattr(node,tmop_name(temp)); + if (f) { + char *c, *tok; + String *t = Copy(f); + c = Char(t); + tok = strtok(c,","); + while (tok) { + Swig_fragment_emit(tok); + tok = strtok(NULL,","); + } + Delete(t); + } + } + + if (cname) Delete(cname); + if (clname) Delete(clname); + if (mtype) Delete(mtype); + return s; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_attach_parms() + * + * Given a parmeter list, this function attaches all of the typemaps for a + * given typemap type + * ----------------------------------------------------------------------------- */ + +void +Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f) { + Parm *p, *firstp; + Hash *tm; + int nmatch = 0; + int i; + String *s; + ParmList *locals; + int argnum = 0; + char temp[256]; + Parm *kw; + + p = parms; + while (p) { + argnum++; + nmatch = 0; + tm = Swig_typemap_search_multi(op,p,&nmatch); + if (!tm) { + p = nextSibling(p); + continue; + } + s = Getattr(tm,"code"); + if (!s) { + p = nextSibling(p); + continue; + } + + /* Empty typemap. No match */ + if (Cmp(s,"pass") == 0) { + p = nextSibling(p); + continue; + } + + s = Copy(s); + locals = Getattr(tm,"locals"); + if (locals) locals = CopyParmList(locals); + firstp = p; + for (i = 0; i < nmatch; i++) { + SwigType *type; + String *pname; + String *lname; + SwigType *mtype; + + type = Getattr(p,"type"); + pname = Getattr(p,"name"); + lname = Getattr(p,"lname"); + mtype = Getattr(p,"tmap:match"); + + if (mtype) { + typemap_replace_vars(s,locals, mtype,pname,lname,i+1); + Delattr(p,"tmap:match"); + } else { + typemap_replace_vars(s,locals, type,pname,lname,i+1); + } + if (checkAttribute(tm,"type","SWIGTYPE")) { + sprintf(temp,"%s:SWIGTYPE", Char(op)); + Setattr(p,tmop_name(temp),"1"); + } + p = nextSibling(p); + } + + if (locals && f) { + typemap_locals(s,locals,f,argnum); + } + + /* Replace the argument number */ + sprintf(temp,"%d",argnum); + Replace(s,"$argnum",temp, DOH_REPLACE_ANY); + + /* Attach attributes to object */ + Setattr(firstp,tmop_name(op),s); /* Code object */ + + if (locals) { + sprintf(temp,"%s:locals", Char(op)); + Setattr(firstp,tmop_name(temp), locals); + Delete(locals); + } + + /* Attach a link to the next parameter. Needed for multimaps */ + sprintf(temp,"%s:next",Char(op)); + Setattr(firstp,tmop_name(temp),p); + + /* Attach kwargs */ + kw = Getattr(tm,"kwargs"); + while (kw) { + sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name"))); + Setattr(firstp,tmop_name(temp), Copy(Getattr(kw,"value"))); + kw = nextSibling(kw); + } + { + String *w; + sprintf(temp,"%s:warning", Char(op)); + w = Getattr(firstp,tmop_name(temp)); + if (w) { + Swig_warning(0,Getfile(firstp), Getline(firstp), "%s\n", w); + } + } + /* Look for code fragments */ + { + String *f; + sprintf(temp,"%s:fragment", Char(op)); + f = Getattr(firstp,tmop_name(temp)); + if (f) { + char *c, *tok; + String *t = Copy(f); + c = Char(t); + tok = strtok(c,","); + while (tok) { + Swig_fragment_emit(tok); + tok = strtok(NULL,","); + } + Delete(t); + } + } + } } /* ----------------------------------------------------------------------------- @@ -483,37 +1336,4 @@ void Swig_typemap_debug() { } Printf(stdout,"-----------------------------------------------------------------------------\n"); } - -/* ----------------------------------------------------------------------------- - * %except directive support. - * - * These functions technically don't really have anything to do with typemaps - * except that they have the same scoping rules. Therefore, it's easy enough to - * just use the hash table structure of the typemap code. - * ----------------------------------------------------------------------------- */ - -void Swig_except_register(String_or_char *code) { - String *s = NewString(code); - Setattr(typemaps[tm_scope],"*except*",s); - Delete(s); -} - -char *Swig_except_lookup() { - String *s; - int ts = tm_scope; - while (ts >= 0) { - s = Getattr(typemaps[tm_scope],"*except*"); - if (s) { - s = Copy(s); - Swig_temp_result(s); - return Char(s); - } - ts--; - } - return 0; -} - -void Swig_except_clear() { - Delattr(typemaps[tm_scope],"*except*"); -} diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c new file mode 100644 index 000000000..65df2f882 --- /dev/null +++ b/Source/Swig/typesys.c @@ -0,0 +1,1609 @@ +/* ----------------------------------------------------------------------------- + * typesys.c + * + * SWIG type system management. These functions are used to manage + * the C++ type system including typenames, typedef, type scopes, + * inheritance, and namespaces. Generation of support code for the + * run-time type checker is also handled here. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_typesys_c[] = "$Header$"; + +#include "swig.h" + +/* ----------------------------------------------------------------------------- + * Synopsis + * + * The purpose of this module is to manage type names and scoping issues related + * to the C++ type system. The primary use is tracking typenames through typedef + * and inheritance. + * + * New typenames are introduced by typedef, class, and enum declarations. + * Each type is declared in a scope. This is either the global scope, a + * class, or a namespace. For example: + * + * typedef int A; // Typename A, in global scope + * namespace Foo { + * typedef int A; // Typename A, in scope Foo:: + * } + * class Bar { // Typename Bar, in global scope + * typedef int A; // Typename A, in scope Bar:: + * } + * + * To manage scopes, the type system is constructed as a tree of hash tables. Each + * hash table contains the following attributes: + * + * "name" - Scope name + * "qname" - Fully qualified typename + * "typetab" - Type table containing typenames and typedef information + * "symtab" - Hash table of symbols defined in a scope + * "inherit" - List of inherited scopes + * "parent" - Parent scope + * + * Typedef information is stored in the "typetab" hash table. For example, + * if you have these declarations: + * + * typedef int A; + * typedef A B; + * typedef B *C; + * + * typetab is built as follows: + * + * "A" : "int" + * "B" : "A" + * "C" : "p.B" + * + * To resolve a type back to its root type, one repeatedly expands on the type base. + * For example: + * + * C *[40] ---> a(40).p.C (string type representation, see stype.c) + * ---> a(40).p.p.B (C --> p.B) + * ---> a(40).p.p.A (B --> A) + * ---> a(40).p.p.int (A --> int) + * + * For inheritance, SWIG tries to resolve types back to the base class. For instance, if + * you have this: + * + * class Foo { + * public: + * typedef int Integer; + * }; + * + * class Bar : public Foo { + * void blah(Integer x); + * } + * + * The argument type of Bar::blah will be set to Foo::Integer. + * + * The scope-inheritance mechanism is used to manage C++ namespace aliases. + * For example, if you have this: + * + * namespace Foo { + * typedef int Integer; + * } + * + * namespace F = Foo; + * + * In this case, "F::" is defined as a scope that "inherits" from Foo. Internally, + * "F::" will merely be an empty scope that refers to Foo. SWIG will never + * place new type information into a namespace alias---attempts to do so + * will generate a warning message (in the parser) and will place information into + * Foo instead. + * + *----------------------------------------------------------------------------- */ + +static Typetab *current_scope = 0; /* Current type scope */ +static Hash *current_typetab = 0; /* Current type table */ +static Hash *current_symtab = 0; /* Current symbol table */ +static Typetab *global_scope = 0; /* The global scope */ +static Hash *scopes = 0; /* Hash table containing fully qualified scopes */ + +/* Performance optimization */ +static Hash *typedef_resolve_cache = 0; +static Hash *typedef_all_cache = 0; +static Hash *typedef_qualified_cache = 0; + +static void flush_cache() { + typedef_resolve_cache = 0; + typedef_all_cache = 0; + typedef_qualified_cache = 0; +} + +/* Initialize the scoping system */ + +void SwigType_typesystem_init() { + if (global_scope) Delete(global_scope); + if (scopes) Delete(scopes); + + current_scope = NewHash(); + global_scope = current_scope; + + Setattr(current_scope,"name",""); /* No name for global scope */ + current_typetab = NewHash(); + Setattr(current_scope,"typetab", current_typetab); + + current_symtab = 0; + scopes = NewHash(); + Setattr(scopes,"",current_scope); +} + +/* ----------------------------------------------------------------------------- + * SwigType_typedef() + * + * Defines a new typedef in the current scope. Returns -1 if the type name is + * already defined. + * ----------------------------------------------------------------------------- */ + +int SwigType_typedef(SwigType *type, String_or_char *name) { + Typetab *SwigType_find_scope(Typetab *, String *s); + if (Getattr(current_typetab, name)) return -1; /* Already defined */ + if (Strcmp(type,name) == 0) { /* Can't typedef a name to itself */ + return 0; + } + + /* Check if 'type' is already a scope. If so, we create an alias in the type + system for it. This is needed to make strange nested scoping problems work + correctly. */ + { + Typetab *t = SwigType_find_scope(current_scope,type); + if (t) { + SwigType_new_scope(name); + SwigType_inherit_scope(t); + SwigType_pop_scope(); + } + } + Setattr(current_typetab,name,type); + flush_cache(); + return 0; +} + + +/* ----------------------------------------------------------------------------- + * SwigType_typedef_class() + * + * Defines a class in the current scope. + * ----------------------------------------------------------------------------- */ + +int SwigType_typedef_class(String_or_char *name) { + String *cname; + /* Printf(stdout,"class : '%s'\n", name); */ + if (Getattr(current_typetab, name)) return -1; /* Already defined */ + cname = NewString(name); + Setmeta(cname,"class","1"); + Setattr(current_typetab,cname,cname); + flush_cache(); + return 0; +} + +/* ----------------------------------------------------------------------------- + * SwigType_scope_name() + * + * Returns the qualified scope name of a type table + * ----------------------------------------------------------------------------- */ + +String * +SwigType_scope_name(Typetab *ttab) { + String *qname = NewString(Getattr(ttab,"name")); + ttab = Getattr(ttab,"parent"); + while (ttab) { + String *pname = Getattr(ttab,"name"); + if (Len(pname)) { + Insert(qname,0,"::"); + Insert(qname,0,pname); + } + ttab = Getattr(ttab,"parent"); + } + return qname; +} +/* ----------------------------------------------------------------------------- + * SwigType_new_scope() + * + * Creates a new scope + * ----------------------------------------------------------------------------- */ + +void SwigType_new_scope(String_or_char *name) { + Typetab *s; + Hash *ttab; + String *qname; + + if (!name) { + name = ""; + } + s = NewHash(); + Setattr(s,"name", name); + Setattr(s,"parent", current_scope); + ttab = NewHash(); + Setattr(s,"typetab", ttab); + + /* Build fully qualified name and */ + qname = SwigType_scope_name(s); + Setattr(scopes,qname,s); + Setattr(s,"qname",qname); + Delete(qname); + + current_scope = s; + current_typetab = ttab; + current_symtab = 0; + flush_cache(); +} + +/* ----------------------------------------------------------------------------- + * SwigType_inherit_scope() + * + * Makes the current scope inherit from another scope. This is used for both + * C++ class inheritance, namespaces, and namespace aliases. + * ----------------------------------------------------------------------------- */ + +void +SwigType_inherit_scope(Typetab *scope) { + List *inherits; + int i, len; + inherits = Getattr(current_scope,"inherit"); + if (!inherits) { + inherits = NewList(); + Setattr(current_scope,"inherit", inherits); + } + assert(scope != current_scope); + + len = Len(inherits); + for (i = 0; i < len; i++) { + Node *n = Getitem(inherits,i); + if (n == scope) return; + } + Append(inherits,scope); +} + +/* ----------------------------------------------------------------------------- + * SwigType_scope_alias() + * + * Creates a scope-alias. + * ----------------------------------------------------------------------------- */ + +void +SwigType_scope_alias(String *aliasname, Typetab *ttab) { + String *q; + /* Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab);*/ + q = SwigType_scope_name(current_scope); + if (Len(q)) { + Append(q,"::"); + } + Append(q,aliasname); + Setattr(scopes,q,ttab); + flush_cache(); +} + +/* ----------------------------------------------------------------------------- + * SwigType_using_scope() + * + * Import another scope into this scope. + * ----------------------------------------------------------------------------- */ + +void +SwigType_using_scope(Typetab *scope) { + SwigType_inherit_scope(scope); + { + List *ulist; + int i, len; + ulist = Getattr(current_scope,"using"); + if (!ulist) { + ulist = NewList(); + Setattr(current_scope,"using", ulist); + } + assert(scope != current_scope); + len = Len(ulist); + for (i = 0; i < len; i++) { + Typetab *n = Getitem(ulist,i); + if (n == scope) return; + } + Append(ulist,scope); + } + flush_cache(); +} + +/* ----------------------------------------------------------------------------- + * SwigType_pop_scope() + * + * Pop off the last scope and perform a merge operation. Returns the hash + * table for the scope that was popped off. + * ----------------------------------------------------------------------------- */ + +Typetab *SwigType_pop_scope() { + Typetab *s, *s1; + s = Getattr(current_scope,"parent"); + if (!s) { + current_scope = 0; + current_typetab = 0; + current_symtab = 0; + return 0; + } + s1 = current_scope; + current_scope = s; + current_typetab = Getattr(s,"typetab"); + current_symtab = Getattr(s,"symtab"); + flush_cache(); + return s1; +} + +/* ----------------------------------------------------------------------------- + * SwigType_set_scope() + * + * Set the scope. Returns the old scope. + * ----------------------------------------------------------------------------- */ + +Typetab * +SwigType_set_scope(Typetab *t) { + Typetab *old = current_scope; + if (!t) t = global_scope; + current_scope = t; + current_typetab = Getattr(t,"typetab"); + current_symtab = Getattr(t,"symtab"); + flush_cache(); + return old; +} + +/* ----------------------------------------------------------------------------- + * SwigType_attach_symtab() + * + * Attaches a symbol table to a type scope + * ----------------------------------------------------------------------------- */ + +void +SwigType_attach_symtab(Symtab *sym) { + Setattr(current_scope,"symtab",sym); + current_symtab = sym; +} + +/* ----------------------------------------------------------------------------- + * SwigType_print_scope() + * + * Debugging function for printing out current scope + * ----------------------------------------------------------------------------- */ + +void SwigType_print_scope(Typetab *t) { + String *key; + Hash *ttab; + String *tkey; + + for (tkey = Firstkey(scopes); tkey; tkey = Nextkey(scopes)) { + t = Getattr(scopes,tkey); + ttab = Getattr(t,"typetab"); + + Printf(stdout,"Type scope '%s' (%x)\n", tkey, t); + { + List *inherit = Getattr(t,"inherit"); + if (inherit) { + Typetab *it; + for (it = Firstitem(inherit); it; it = Nextitem(inherit)) { + Printf(stdout," Inherits from '%s' (%x)\n", Getattr(it,"qname"), it); + } + } + } + Printf(stdout,"-------------------------------------------------------------\n"); + for (key = Firstkey(ttab); key; key = Nextkey(ttab)) { + Printf(stdout,"%40s -> %s\n", key, Getattr(ttab,key)); + } + } +} + +Typetab * +SwigType_find_scope(Typetab *s, String *nameprefix) { + Typetab *ss; + String *nnameprefix = 0; + static int check_parent = 1; + + /* Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */ + + if (SwigType_istemplate(nameprefix)) { + nnameprefix = SwigType_typedef_resolve_all(nameprefix); + nameprefix = nnameprefix; + } + + ss = s; + while (ss) { + String *full; + String *qname = Getattr(ss,"qname"); + if (qname) { + full = NewStringf("%s::%s", qname, nameprefix); + } else { + full = NewString(nameprefix); + } + if (Getattr(scopes,full)) { + s = Getattr(scopes,full); + } else { + s = 0; + } + Delete(full); + if (s) { + if (nnameprefix) Delete(nnameprefix); + return s; + } + if (!s) { + /* Check inheritance */ + List *inherit; + inherit = Getattr(ss,"using"); + if (inherit) { + Typetab *ttab; + int i, len; + len = Len(inherit); + for (i = 0; i < len; i++) { + int oldcp = check_parent; + ttab = Getitem(inherit,i); + check_parent = 0; + s = SwigType_find_scope(ttab,nameprefix); + check_parent = oldcp; + if (s) { + if (nnameprefix) Delete(nnameprefix); + return s; + } + } + } + } + if (!check_parent) break; + ss = Getattr(ss,"parent"); + } + if (nnameprefix) Delete(nnameprefix); + return 0; +} + +/* ----------------------------------------------------------------------------- + * SwigType_typedef_resolve() + * + * Resolves a typedef and returns a new type string. Returns 0 if there is no + * typedef mapping. base is a name without qualification. + * ----------------------------------------------------------------------------- */ + +static Typetab *resolved_scope = 0; + +/* Internal function */ +static SwigType * +typedef_resolve(Typetab *s, String *base) { + Hash *ttab; + SwigType *type; + List *inherit; + + if (!s) return 0; + /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */ + + if (Getmark(s)) return 0; + Setmark(s,1); + + ttab = Getattr(s,"typetab"); + type = Getattr(ttab,base); + if (type) { + resolved_scope = s; + Setmark(s,0); + return type; + } + /* Hmmm. Not found in my scope. It could be in an inherited scope */ + inherit = Getattr(s,"inherit"); + if (inherit) { + int i,len; + len = Len(inherit); + for (i = 0; i < len; i++) { + type = typedef_resolve(Getitem(inherit,i), base); + if (type) { + Setmark(s,0); + return type; + } + } + } + type = typedef_resolve(Getattr(s,"parent"), base); + Setmark(s,0); + return type; +} + +SwigType *SwigType_typedef_resolve(SwigType *t) { + String *base; + String *type = 0; + String *r = 0; + Typetab *s; + Hash *ttab; + String *namebase = 0; + String *nameprefix = 0; + int newtype = 0; + + resolved_scope = 0; + + if (!typedef_resolve_cache) { + typedef_resolve_cache = NewHash(); + } + /* + r = Getattr(typedef_resolve_cache,t); + if (r) { + if (r != DohNone) { + resolved_scope = Getmeta(r,"scope"); + return Copy(r); + } else { + return 0; + } + } +*/ + + base = SwigType_base(t); + + /* Printf(stdout,"base = '%s'\n", base); */ + + if (SwigType_issimple(base)) { + s = current_scope; + ttab = current_typetab; + if (Strncmp(base,"::",2) == 0) { + s = global_scope; + ttab = Getattr(s,"typetab"); + Delitem(base,0); + Delitem(base,0); + } + /* Do a quick check in the local scope */ + type = Getattr(ttab,base); + if (type) { + resolved_scope = s; + } + if (!type) { + /* Didn't find in this scope. We need to do a little more searching */ + if (Swig_scopename_check(base)) { + /* A qualified name. */ + nameprefix = Swig_scopename_prefix(base); + /* Printf(stdout,"nameprefix = '%s'\n", nameprefix);*/ + if (nameprefix) { + /* Name had a prefix on it. See if we can locate the proper scope for it */ + s = SwigType_find_scope(s,nameprefix); + /* Couldn't locate a scope for the type. */ + if (!s) { + Delete(base); + Delete(nameprefix); + r = 0; + goto return_result; + } + /* Try to locate the name starting in the scope */ + namebase = Swig_scopename_last(base); + /* Printf(stdout,"namebase = '%s'\n", namebase); */ + type = typedef_resolve(s,namebase); + /* Printf(stdout,"%s type = '%s'\n", Getattr(s,"name"), type); */ + if ((type) && (!Swig_scopename_check(type))) { + Typetab *rtab = resolved_scope; + String *qname = Getattr(resolved_scope,"qname"); + /* If qualified *and* the typename is defined from the resolved scope, we qualify */ + if ((qname) && typedef_resolve(resolved_scope,type)) { + type = Copy(type); + Insert(type,0,"::"); + Insert(type,0,qname); + newtype = 1; + } + resolved_scope = rtab; + } + } else { + /* Name is unqualified. */ + type = typedef_resolve(s,base); + } + } else { + /* Name is unqualified. */ + type = typedef_resolve(s,base); + } + } + + if (type && (Strcmp(base,type) == 0)) { + Delete(base); + r = 0; + goto return_result; + } + + /* If the type is a template, and no typedef was found, we need to check the + template arguments one by one to see if they can be resolved. */ + + if (!type && SwigType_istemplate(base)) { + List *tparms; + String *suffix; + int i,sz; + int rep = 0; + type = SwigType_templateprefix(base); + suffix = SwigType_templatesuffix(base); + Append(type,"<("); + tparms = SwigType_parmlist(base); + sz = Len(tparms); + for (i = 0; i < sz; i++) { + SwigType *tpr; + SwigType *tp = Getitem(tparms, i); + if (!rep) { + tpr = SwigType_typedef_resolve(tp); + } else { + tpr = 0; + } + if (tpr) { + Append(type,tpr); + rep = 1; + } else { + Append(type,tp); + } + if ((i+1) < sz) Append(type,","); + } + Append(type,")>"); + Append(type,suffix); + Delete(suffix); + Delete(tparms); + if (!rep) { + Delete(type); + type = 0; + } + } + if (namebase) Delete(namebase); + if (nameprefix) Delete(nameprefix); + } else { + if (SwigType_isfunction(base)) { + List *parms; + int i,sz; + int rep = 0; + type = NewString("f("); + parms = SwigType_parmlist(base); + sz = Len(parms); + for (i = 0; i < sz; i++) { + SwigType *tpr; + SwigType *tp = Getitem(parms, i); + if (!rep) { + tpr = SwigType_typedef_resolve(tp); + } else { + tpr = 0; + } + if (tpr) { + Append(type,tpr); + rep = 1; + } else { + Append(type,tp); + } + if ((i+1) < sz) Append(type,","); + } + Append(type,")."); + Delete(parms); + if (!rep) { + Delete(type); + type = 0; + } + } else if (SwigType_ismemberpointer(base)) { + String *rt; + String *mtype = SwigType_parm(base); + rt = SwigType_typedef_resolve(mtype); + if (rt) { + type = NewStringf("m(%s).", rt); + Delete(rt); + } + Delete(mtype); + } else { + type = 0; + } + } + r = SwigType_prefix(t); + if (!type) { + if (r && Len(r)) { + if ((Strstr(r,"f(") || (Strstr(r,"m(")))) { + SwigType *rt = SwigType_typedef_resolve(r); + if (rt) { + Delete(r); + Append(rt,base); + Delete(base); + r = rt; + goto return_result; + } + } + } + Delete(r); + Delete(base); + r = 0; + goto return_result; + } + Delete(base); + Append(r,type); + if (newtype) { + Delete(type); + } + + return_result: + if (!r) { + Setattr(typedef_resolve_cache,NewString(t),DohNone); + } else { + Setattr(typedef_resolve_cache,NewString(t),r); + Setmeta(r,"scope",resolved_scope); + r = Copy(r); + } + return r; +} + + +/* ----------------------------------------------------------------------------- + * SwigType_typedef_resolve_all() + * + * Fully resolve a type down to its most basic datatype + * ----------------------------------------------------------------------------- */ + +SwigType *SwigType_typedef_resolve_all(SwigType *t) { + SwigType *n; + SwigType *r; + + if (!typedef_all_cache) { + typedef_all_cache = NewHash(); + } + r = Getattr(typedef_all_cache,t); + if (r) { + return Copy(r); + } + r = NewString(t); + while ((n = SwigType_typedef_resolve(r))) { + Delete(r); + r = n; + } + { + SwigType *rr = Copy(r); + Setattr(typedef_all_cache,NewString(t),rr); + } + return r; +} + + +/* ----------------------------------------------------------------------------- + * SwigType_typedef_qualified() + * + * Given a type declaration, this function tries to fully qualify it according to + * typedef scope rules. + * ----------------------------------------------------------------------------- */ + +SwigType *SwigType_typedef_qualified(SwigType *t) +{ + List *elements; + String *result; + int i,len; + + if (!typedef_qualified_cache) typedef_qualified_cache = NewHash(); + result = Getattr(typedef_qualified_cache,t); + if (result) { + String *rc = Copy(result); + return rc; + } + result = NewString(""); + elements = SwigType_split(t); + len = Len(elements); + for (i = 0; i < len; i++) { + String *e = Getitem(elements,i); + if (SwigType_issimple(e)) { + if (!SwigType_istemplate(e)) { + String *isenum = 0; + if (SwigType_isenum(e)) { + isenum = e; + e = NewString(Char(e)+5); + } + resolved_scope = 0; + if (typedef_resolve(current_scope,e)) { + /* resolved_scope contains the scope that actually resolved the symbol */ + String *qname = Getattr(resolved_scope,"qname"); + if (qname) { + Insert(e,0,"::"); + Insert(e,0,qname); + if (isenum) { + Clear(isenum); + Printf(isenum, "enum %s", e); + Delete(e); + } + } + } else { + + if (Swig_scopename_check(e)) { + String *tqname; + String *qlast; + String *qname = Swig_scopename_prefix(e); + if (qname) { + qlast = Swig_scopename_last(e); + tqname = SwigType_typedef_qualified(qname); + Clear(e); + Printf(e,"%s::%s", tqname, qlast); + Delete(qname); + Delete(qlast); + Delete(tqname); + } + /* Automatic template instantiation might go here??? */ + + } + } + if (isenum) e = isenum; + + } else { + /* Template. We need to qualify template parameters as well as the template itself */ + String *tprefix, *qprefix; + String *tsuffix; + Parm *p; + List *parms = SwigType_parmlist(e); + tprefix = SwigType_templateprefix(e); + tsuffix = SwigType_templatesuffix(e); + qprefix = SwigType_typedef_qualified(tprefix); + Printf(qprefix,"<("); + p = Firstitem(parms); + while (p) { + String *qt = SwigType_typedef_qualified(p); + if ((Strcmp(qt,p) == 0)) { /* && (!Swig_scopename_check(qt))) { */ + /* No change in value. It is entirely possible that the parameter is an integer value. + If there is a symbol table associated with this scope, we're going to check for this */ + + if (current_symtab) { + Node *lastnode = 0; + String *value = Copy(p); + while (1) { + Node *n = Swig_symbol_clookup(value,current_symtab); + if (n == lastnode) break; + lastnode = n; + if (n) { + if (Strcmp(nodeType(n),"enumitem") == 0) { + /* An enum item. Generate a fully qualified name */ + String *qn = Swig_symbol_qualified(n); + if (Len(qn)) { + Append(qn,"::"); + Append(qn,Getattr(n,"name")); + Delete(value); + value = qn; + continue; + } else { + break; + } + } else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) { + Delete(value); + value = Copy(Getattr(n,"value")); + continue; + } + } + break; + } + Append(qprefix,value); + } else { + Append(qprefix,p); + } + } else { + Append(qprefix,qt); + } + Delete(qt); + p= Nextitem(parms); + if (p) { + Append(qprefix,","); + } + } + Append(qprefix,")>"); + Append(qprefix,tsuffix); + Delete(tsuffix); + Clear(e); + Append(e,qprefix); + Delete(tprefix); + Delete(qprefix); + } + if (Strncmp(e,"::",2) == 0) { + Delitem(e,0); + Delitem(e,0); + } + Append(result,e); + } else if (SwigType_isfunction(e)) { + List *parms = SwigType_parmlist(e); + String *s = NewString("f("); + String *p; + p = Firstitem(parms); + while (p) { + Append(s,SwigType_typedef_qualified(p)); + p = Nextitem(parms); + if (p) { + Append(s,","); + } + } + Append(s,")."); + Append(result,s); + Delete(s); + } else if (SwigType_isarray(e)) { + String *ndim; + String *dim = SwigType_parm(e); + ndim = Swig_symbol_string_qualify(dim,0); + Printf(result,"a(%s).",ndim); + Delete(dim); + Delete(ndim); + } else { + Append(result,e); + } + } + Delete(elements); + Setattr(typedef_qualified_cache,NewString(t),NewString(result)); + return result; +} + +/* ----------------------------------------------------------------------------- + * SwigType_istypedef() + * + * Checks a typename to see if it is a typedef. + * ----------------------------------------------------------------------------- */ + +int SwigType_istypedef(SwigType *t) { + String *type; + + type = SwigType_typedef_resolve(t); + if (type) { + Delete(type); + return 1; + } else { + return 0; + } +} + + +/* ----------------------------------------------------------------------------- + * SwigType_typedef_using() + * + * Processes a 'using' declaration to import types from one scope into another. + * Name is a qualified name like A::B. + * ----------------------------------------------------------------------------- */ + +int SwigType_typedef_using(String_or_char *name) { + String *base; + String *td; + String *prefix; + Typetab *s; + Typetab *tt = 0; + + String *defined_name = 0; + + /* Printf(stdout,"using %s\n", name);*/ + + if (!Swig_scopename_check(name)) return -1; /* Not properly qualified */ + base = Swig_scopename_last(name); + + /* See if the base is already defined in this scope */ + if (Getattr(current_typetab,base)) { + Delete(base); + return -1; + } + + /* See if the using name is a scope */ + /* tt = SwigType_find_scope(current_scope,name); + Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */ + + /* We set up a typedef B --> A::B */ + Setattr(current_typetab,base,name); + + /* Find the scope name where the symbol is defined */ + td = SwigType_typedef_resolve(name); + /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */ + if (resolved_scope) { + defined_name = Getattr(resolved_scope,"qname"); + if (defined_name) { + defined_name = Copy(defined_name); + Append(defined_name,"::"); + Append(defined_name,base); + } + } + if (td) Delete(td); + + /* Printf(stdout,"defined_name = '%s'\n", defined_name);*/ + tt = SwigType_find_scope(current_scope,defined_name); + + /* Figure out the scope the using directive refers to */ + { + prefix = Swig_scopename_prefix(name); + s = SwigType_find_scope(current_scope,prefix); + if (s) { + Hash *ttab = Getattr(s,"typetab"); + if (!Getattr(ttab,base) && defined_name) { + Setattr(ttab,base, defined_name); + } + } + } + + if (tt) { + /* Using directive had it's own scope. We need to do create a new scope for it */ + SwigType_new_scope(base); + SwigType_inherit_scope(tt); + SwigType_pop_scope(); + } + + if (defined_name) Delete(defined_name); + Delete(prefix); + Delete(base); + return 0; +} + +/* ----------------------------------------------------------------------------- + * SwigType_isclass() + * + * Determines if a type defines a class or not. A class is defined by + * its type-table entry maps to itself. Note: a pointer to a class is not + * a class. + * ----------------------------------------------------------------------------- */ + +int +SwigType_isclass(SwigType *t) { + SwigType *qty, *qtys; + int isclass = 0; + + qty = SwigType_typedef_resolve_all(t); + qtys = SwigType_strip_qualifiers(qty); + if (SwigType_issimple(qtys)) { + String *td = SwigType_typedef_resolve(qtys); + if (td) { + Delete(td); + } + if (resolved_scope) { + isclass = 1; + } + /* Hmmm. Not a class. If a template, it might be uninstantiated */ + if (SwigType_istemplate(qtys)) { + String *tp = SwigType_templateprefix(qtys); + isclass = SwigType_isclass(tp); + Delete(tp); + } + } + Delete(qty); + Delete(qtys); + return isclass; +} + +/* ----------------------------------------------------------------------------- + * SwigType_type() + * + * Returns an integer code describing the datatype. This is only used for + * compatibility with SWIG1.1 language modules and is likely to go away once + * everything is based on typemaps. + * ----------------------------------------------------------------------------- */ + +int SwigType_type(SwigType *t) +{ + char *c; + /* Check for the obvious stuff */ + c = Char(t); + + if (strncmp(c,"p.",2) == 0) { + if (SwigType_type(c+2) == T_CHAR) return T_STRING; + else return T_POINTER; + } + if (strncmp(c,"a(",2) == 0) return T_ARRAY; + if (strncmp(c,"r.",2) == 0) return T_REFERENCE; + if (strncmp(c,"m(",2) == 0) return T_MPOINTER; + if (strncmp(c,"q(",2) == 0) { + while(*c && (*c != '.')) c++; + if (*c) return SwigType_type(c+1); + return T_ERROR; + } + if (strncmp(c,"f(",2) == 0) return T_FUNCTION; + + /* Look for basic types */ + if (strcmp(c,"int") == 0) return T_INT; + if (strcmp(c,"long") == 0) return T_LONG; + if (strcmp(c,"short") == 0) return T_SHORT; + if (strcmp(c,"unsigned") == 0) return T_UINT; + if (strcmp(c,"unsigned short") == 0) return T_USHORT; + if (strcmp(c,"unsigned long") == 0) return T_ULONG; + if (strcmp(c,"unsigned int") == 0) return T_UINT; + if (strcmp(c,"char") == 0) return T_CHAR; + if (strcmp(c,"signed char") == 0) return T_SCHAR; + if (strcmp(c,"unsigned char") == 0) return T_UCHAR; + if (strcmp(c,"float") == 0) return T_FLOAT; + if (strcmp(c,"double") == 0) return T_DOUBLE; + if (strcmp(c,"void") == 0) return T_VOID; + if (strcmp(c,"bool") == 0) return T_BOOL; + if (strcmp(c,"long long") == 0) return T_LONGLONG; + if (strcmp(c,"unsigned long long") == 0) return T_ULONGLONG; + if (strncmp(c,"enum ",5) == 0) return T_INT; + + if (strcmp(c,"v(...)") == 0) return T_VARARGS; + /* Hmmm. Unknown type */ + if (SwigType_istypedef(t)) { + int r; + SwigType *nt = SwigType_typedef_resolve(t); + r = SwigType_type(nt); + Delete(nt); + return r; + } + return T_USER; +} + +/****************************************************************************** + *** * * * WARNING * * * *** + *** *** + *** Don't even think about modifying anything below this line unless you *** + *** are completely on top of *EVERY* subtle aspect of the C++ type system *** + *** and you are prepared to suffer endless hours of agony trying to *** + *** debug the SWIG run-time type checker after you break it. *** + ******************************************************************************/ + +/* ----------------------------------------------------------------------------- + * SwigType_remember() + * + * This function "remembers" a datatype that was used during wrapper code generation + * so that a type-checking table can be generated later on. It is up to the language + * modules to actually call this function--it is not done automatically. + * + * Type tracking is managed through two separate hash tables. The hash 'r_mangled' + * is mapping between mangled type names (used in the target language) and + * fully-resolved C datatypes used in the source input. The second hash 'r_resolved' + * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled + * names in the scripting languages. For example, consider the following set of + * typedef declarations: + * + * typedef double Real; + * typedef double Float; + * typedef double Point[3]; + * + * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and + * 'Point' were used in an interface file and "remembered" using this function. + * The hash tables would look like this: + * + * r_mangled { + * _p_double : [ p.double, a(3).double ] + * _p_Real : [ p.double ] + * _p_Float : [ p.double ] + * _Point : [ a(3).double ] + * + * r_resolved { + * p.double : [ _p_double, _p_Real, _p_Float ] + * a(3).double : [ _p_double, _Point ] + * } + * + * Together these two hash tables can be used to determine type-equivalency between + * mangled typenames. To do this, we view the two hash tables as a large graph and + * compute the transitive closure. + * ----------------------------------------------------------------------------- */ + +static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */ +static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */ +static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */ +static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */ +static Hash *r_remembered = 0; /* Hash of types we remembered already */ + +static void (*r_tracefunc)(SwigType *t, String *mangled, String *clientdata) = 0; + +void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata) { + String *mt; + SwigType *lt; + Hash *h; + SwigType *fr; + SwigType *qr; + + if (!r_mangled) { + r_mangled = NewHash(); + r_resolved = NewHash(); + r_ltype = NewHash(); + r_clientdata = NewHash(); + r_remembered = NewHash(); + } + + { + String *last; + last = Getattr(r_remembered,t); + if (last && (Cmp(last,clientdata) == 0)) return; + } + + Setattr(r_remembered, Copy(t), clientdata ? NewString(clientdata) : (void *) ""); + + mt = SwigType_manglestr(t); /* Create mangled string */ + + if (r_tracefunc) { + (*r_tracefunc)(t,mt, (String *) clientdata); + } + + if (SwigType_istypedef(t)) + lt = Copy(t); + else + lt = SwigType_ltype(t); + Setattr(r_ltype, mt, lt); + fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */ + qr = SwigType_typedef_qualified(fr); + Delete(fr); + + /* Added to deal with possible table bug */ + fr = SwigType_strip_qualifiers(qr); + Delete(qr); + + /*Printf(stdout,"t = '%s'\n", t); + Printf(stdout,"fr= '%s'\n\n", fr); */ + + if (Strstr(t,"<") && !(Strstr(t,"<("))) { + Printf(stdout,"Bad template type passed to SwigType_remember: %s\n", t); + assert(0); + } + + h = Getattr(r_mangled,mt); + if (!h) { + h = NewHash(); + Setattr(r_mangled,mt,h); + Delete(h); + } + Setattr(h,fr,mt); + + h = Getattr(r_resolved, fr); + if (!h) { + h = NewHash(); + Setattr(r_resolved,fr,h); + Delete(h); + } + Setattr(h,mt,fr); + + if (clientdata) { + String *cd = Getattr(r_clientdata,fr); + if (cd) { + if (Strcmp(clientdata,cd) != 0) { + Printf(stderr,"*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr,0)); + Printf(stderr,"*** '%s' != '%s'\n", clientdata, cd); + assert(0); + } + } else { + Setattr(r_clientdata, fr, NewString(clientdata)); + } + } +} + +void +SwigType_remember(SwigType *ty) { + SwigType_remember_clientdata(ty,0); +} + +void (*SwigType_remember_trace(void (*tf)(SwigType *, String *, String *)))(SwigType *, String *, String *) { + void (*o)(SwigType *, String *, String *) = r_tracefunc; + r_tracefunc = tf; + return o; +} + +/* ----------------------------------------------------------------------------- + * SwigType_equivalent_mangle() + * + * Return a list of all of the mangled typenames that are equivalent to another + * mangled name. This works as follows: For each fully qualified C datatype + * in the r_mangled hash entry, we collect all of the mangled names from the + * r_resolved hash and combine them together in a list (removing duplicate entries). + * ----------------------------------------------------------------------------- */ + +List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) { + List *l; + Hash *h; + Hash *ch; + Hash *mh; + + if (found) { + h = found; + } else { + h = NewHash(); + } + if (checked) { + ch = checked; + } else { + ch = NewHash(); + } + if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */ + Setattr(h,ms,"1"); + Setattr(ch, ms, "1"); + mh = Getattr(r_mangled,ms); + if (mh) { + String *key; + key = Firstkey(mh); + while (key) { + Hash *rh; + if (Getattr(ch,key)) { + key = Nextkey(mh); + continue; + } + Setattr(ch,key,"1"); + rh = Getattr(r_resolved,key); + if (rh) { + String *rkey; + rkey = Firstkey(rh); + while (rkey) { + Setattr(h,rkey,"1"); + SwigType_equivalent_mangle(rkey,ch,h); + rkey = Nextkey(rh); + } + } + key = Nextkey(mh); + } + } + check_exit: + if (!found) { + l = Keys(h); + Delete(h); + Delete(ch); + return l; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * SwigType_clientdata_collect() + * + * Returns the clientdata field for a mangled type-string. + * ----------------------------------------------------------------------------- */ + +static +String *SwigType_clientdata_collect(String *ms, Hash *checked) { + Hash *ch; + Hash *mh; + String *clientdata = 0; + + if (checked) { + ch = checked; + } else { + ch = NewHash(); + } + if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */ + Setattr(ch, ms, "1"); + mh = Getattr(r_mangled,ms); + if (mh) { + String *key; + key = Firstkey(mh); + while (key) { + Hash *rh; + Setattr(ch,key,"1"); + clientdata = Getattr(r_clientdata,key); + if (clientdata) goto check_exit; + rh = Getattr(r_resolved,key); + if (rh) { + String *rkey; + rkey = Firstkey(rh); + while (rkey) { + clientdata = SwigType_clientdata_collect(rkey,ch); + if (clientdata) goto check_exit; + rkey = Nextkey(rh); + } + } + key = Nextkey(mh); + } + } + check_exit: + if (!checked) { + Delete(ch); + } + return clientdata; +} + + + + +/* ----------------------------------------------------------------------------- + * SwigType_inherit() + * + * Record information about inheritance. We keep a hash table that keeps + * a mapping between base classes and all of the classes that are derived + * from them. + * + * subclass is a hash that maps base-classes to all of the classes derived from them. + * ----------------------------------------------------------------------------- */ + +static Hash *subclass = 0; +static Hash *conversions = 0; + +void +SwigType_inherit(String *derived, String *base, String *cast) { + Hash *h; + if (!subclass) subclass = NewHash(); + + /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */ + + if (SwigType_istemplate(derived)) { + derived = SwigType_typedef_qualified(SwigType_typedef_resolve_all(derived)); + } + if (SwigType_istemplate(base)) { + base = SwigType_typedef_qualified(SwigType_typedef_resolve_all(base)); + } + + /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast);*/ + + h = Getattr(subclass,base); + if (!h) { + h = NewHash(); + Setattr(subclass,base,h); + } + if (!Getattr(h,derived)) { + Setattr(h,derived, cast ? cast : (void *) ""); + } + +} + +/* ----------------------------------------------------------------------------- + * SwigType_issubtype() + * + * Determines if a t1 is a subtype of t2 + * ----------------------------------------------------------------------------- */ + +int +SwigType_issubtype(SwigType *t1, SwigType *t2) { + SwigType *ft1, *ft2; + String *b1, *b2; + Hash *h; + int r = 0; + + if (!subclass) return 0; + + ft1 = SwigType_typedef_resolve_all(t1); + ft2 = SwigType_typedef_resolve_all(t2); + b1 = SwigType_base(ft1); + b2 = SwigType_base(ft2); + + h = Getattr(subclass,b2); + if (h) { + if (Getattr(h,b1)) { + r = 1; + } + } + Delete(ft1); + Delete(ft2); + Delete(b1); + Delete(b2); + /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */ + return r; +} + +/* ----------------------------------------------------------------------------- + * SwigType_inherit_equiv() + * + * Modify the type table to handle C++ inheritance + * ----------------------------------------------------------------------------- */ + +void SwigType_inherit_equiv(File *out) { + String *rkey, *bkey, *ckey; + String *prefix, *base; + Hash *sub; + Hash *rh; + List *rlist; + + if (!conversions) conversions = NewHash(); + if (!subclass) subclass = NewHash(); + + rkey = Firstkey(r_resolved); + while (rkey) { + /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */ + base = SwigType_base(rkey); + /* Check to see whether the base is recorded in the subclass table */ + sub = Getattr(subclass,base); + Delete(base); + if (!sub) { + rkey = Nextkey(r_resolved); + continue; + } + + /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */ + + rh = Getattr(r_resolved, rkey); + rlist = NewList(); + for (ckey = Firstkey(rh); ckey; ckey = Nextkey(rh)) { + Append(rlist,ckey); + } + /* Printf(stdout,"rkey = '%s'\n", rkey); + Printf(stdout,"rh = %x '%s'\n", rh,rh); */ + + bkey = Firstkey(sub); + while (bkey) { + prefix= SwigType_prefix(rkey); + Append(prefix,bkey); + /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */ + Setattr(rh,SwigType_manglestr(prefix),prefix); + ckey = NewStringf("%s+%s",SwigType_manglestr(prefix), SwigType_manglestr(rkey)); + if (!Getattr(conversions,ckey)) { + String *convname = NewStringf("%sTo%s", SwigType_manglestr(prefix), SwigType_manglestr(rkey)); + Printf(out,"static void *%s(void *x) {\n", convname); + Printf(out," return (void *)((%s) %s ((%s) x));\n", SwigType_lstr(rkey,0), Getattr(sub,bkey), SwigType_lstr(prefix,0)); + Printf(out,"}\n"); + Setattr(conversions,ckey,convname); + Delete(ckey); + + /* This inserts conversions for typedefs */ + { + Hash *r = Getattr(r_resolved, prefix); + if (r) { + String *rrkey = Firstkey(r); + while (rrkey) { + String *rlkey; + String *rkeymangle; + + /* Make sure this name equivalence is not due to inheritance */ + if (Cmp(prefix, Getattr(r,rrkey)) == 0) { + rkeymangle = SwigType_manglestr(rkey); + ckey = NewStringf("%s+%s", rrkey, rkeymangle); + if (!Getattr(conversions, ckey)) { + Setattr(conversions, ckey, convname); + } + Delete(ckey); + for (rlkey = Firstitem(rlist); rlkey; rlkey = Nextitem(rlist)) { + ckey = NewStringf("%s+%s", rrkey, rlkey); + Setattr(conversions, ckey, convname); + Delete(ckey); + } + Delete(rkeymangle); + /* This is needed to pick up other alternative names for the same type. + Needed to make templates work */ + Setattr(rh,rrkey,Getattr(r,rrkey)); + } + rrkey = Nextkey(r); + } + } + } + Delete(convname); + } + Delete(prefix); + bkey = Nextkey(sub); + } + rkey = Nextkey(r_resolved); + } +} + +/* ----------------------------------------------------------------------------- + * SwigType_type_table() + * + * Generate the type-table for the type-checker. + * ----------------------------------------------------------------------------- */ + +void +SwigType_emit_type_table(File *f_forward, File *f_table) { + DOH *key; + String *types, *table; + int i = 0; + + if (!r_mangled) { + r_mangled = NewHash(); + r_resolved = NewHash(); + } + + Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n"); + + SwigType_inherit_equiv(f_table); + + /* #define DEBUG 1 */ +#ifdef DEBUG + Printf(stdout,"---r_mangled---\n"); + Printf(stdout,"%s\n", r_mangled); + + Printf(stdout,"---r_resolved---\n"); + Printf(stdout,"%s\n", r_resolved); + + Printf(stdout,"---r_ltype---\n"); + Printf(stdout,"%s\n", r_ltype); + + Printf(stdout,"---subclass---\n"); + Printf(stdout,"%s\n", subclass); + + Printf(stdout,"---conversions---\n"); + Printf(stdout,"%s\n", conversions); + +#endif + table = NewString(""); + types = NewString(""); + Printf(table,"static swig_type_info *swig_types_initial[] = {\n"); + key = Firstkey(r_mangled); + Printf(f_forward,"\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n"); + while (key) { + List *el; + String *en; + String *cd; + + Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", key, i); + Printv(types,"static swig_type_info _swigt_", key, "[] = {", NIL); + + cd = SwigType_clientdata_collect(key,0); + if (!cd) cd = "0"; + Printv(types,"{\"", key, "\", 0, \"", SwigType_str(Getattr(r_ltype,key),0),"\", ", cd, "},", NIL); + el = SwigType_equivalent_mangle(key,0,0); + for (en = Firstitem(el); en; en = Nextitem(el)) { + String *ckey; + String *conv; + ckey = NewStringf("%s+%s", en, key); + conv = Getattr(conversions,ckey); + if (conv) { + Printf(types,"{\"%s\", %s},", en, conv); + } else { + Printf(types,"{\"%s\"},", en); + } + Delete(ckey); + } + Delete(el); + Printf(types,"{0}};\n"); + Printv(table, "_swigt_", key, ", \n", NIL); + key = Nextkey(r_mangled); + i++; + } + + Printf(table, "0\n};\n"); + Printf(f_forward,"static swig_type_info *swig_types[%d];\n", i+1); + Printf(f_forward,"\n/* -------- TYPES TABLE (END) -------- */\n\n"); + Printf(f_table,"%s\n", types); + Printf(f_table,"%s\n", table); + Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n"); + Delete(types); + Delete(table); +} diff --git a/Source/Swig/warn.c b/Source/Swig/warn.c new file mode 100644 index 000000000..805f0a4dd --- /dev/null +++ b/Source/Swig/warn.c @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------------- + * warn.c + * + * SWIG warning framework. This was added to warn developers about + * deprecated APIs and other features. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2001. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_warn_c[] = "$Header$"; + +#include "swig.h" + +static Hash *warnings = 0; + +/* ----------------------------------------------------------------------------- + * Swig_warn() + * + * Issue a warning + * ----------------------------------------------------------------------------- */ + +void +Swig_warn(const char *filename, int line, const char *msg) { + String *key; + if (!warnings) { + warnings = NewHash(); + } + key = NewStringf("%s:%d", filename,line); + if (!Getattr(warnings,key)) { + Printf(stderr,"swig-dev warning:%s:%d:%s\n", filename, line, msg); + Setattr(warnings,key,key); + } + Delete(key); +} + + + + + diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c index f716fba39..182e3f2af 100644 --- a/Source/Swig/wrapfunc.c +++ b/Source/Swig/wrapfunc.c @@ -14,30 +14,41 @@ * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ -static char cvsroot[] = "$Header$"; +char cvsroot_wrapfunc_c[] = "$Header$"; #include "swig.h" #include -#include "dohobj.h" +/* ----------------------------------------------------------------------------- + * NewWrapper() + * + * Create a new wrapper function object. + * ----------------------------------------------------------------------------- */ -typedef struct { - Hash *attr; /* Attributes */ - Hash *localh; /* Hash of local variable names */ - String *code; /* Code string */ -} WrapObj; +Wrapper * +NewWrapper() { + Wrapper *w; + w = (Wrapper *) malloc(sizeof(Wrapper)); + w->localh = NewHash(); + w->locals = NewString(""); + w->code = NewString(""); + w->def = NewString(""); + return w; +} /* ----------------------------------------------------------------------------- * DelWrapper() + * + * Delete a wrapper function object. * ----------------------------------------------------------------------------- */ -static void -DelWrapper(DOH *wo) { - WrapObj *w = (WrapObj *) ObjData(wo); +void +DelWrapper(Wrapper *w) { Delete(w->localh); + Delete(w->locals); Delete(w->code); - Delete(w->attr); - DohFree(w); + Delete(w->def); + free(w); } /* ----------------------------------------------------------------------------- @@ -108,6 +119,35 @@ Wrapper_pretty_print(String *str, File *f) { Printf(f,"%s",ts); Clear(ts); empty = 1; + } else if (c == '/') { + Putc(c,ts); + c = Getc(str); + if (c != EOF) { + Putc(c,ts); + if (c == '/') { /* C++ comment */ + while ((c = Getc(str)) != EOF) { + if (c == '\n') { + Ungetc(c,str); + break; + } + Putc(c,ts); + } + } else if (c == '*') { /* C comment */ + int endstar = 0; + while ((c = Getc(str)) != EOF) { + if (endstar && c == '/') { /* end of C comment */ + Putc(c,ts); + break; + } + endstar = (c == '*'); + Putc(c,ts); + if (c == '\n') { /* multi-line C comment. Could be improved slightly. */ + for (i = 0; i < level; i++) + Putc(' ',ts); + } + } + } + } } else { if (!empty || !isspace(c)) { Putc(c,ts); @@ -122,39 +162,20 @@ Wrapper_pretty_print(String *str, File *f) { /* ----------------------------------------------------------------------------- - * Wrapper_str() + * Wrapper_print() * - * Create a string representation of the wrapper function. + * Print out a wrapper function. Does pretty printing as well. * ----------------------------------------------------------------------------- */ -static String * -Wrapper_str(DOH *wo) { - String *s, *s1; - WrapObj *w = (WrapObj *) ObjData(wo); - s = NewString(w->code); - s1 = NewString(""); +void +Wrapper_print(Wrapper *w, File *f) { + String *str; - /* Replace the first '{' with a brace followed by local variable definitions */ - Replace(s,"{", Getattr(w->attr,"locals"), DOH_REPLACE_FIRST); - Wrapper_pretty_print(s,s1); - Delete(s); - return s1; -} - -/* ----------------------------------------------------------------------------- - * Wrapper_dump() - * - * Serialize on out - * ----------------------------------------------------------------------------- */ - -static int -Wrapper_dump(DOH *wo, DOH *out) { - String *s; - int len; - s = Wrapper_str(wo); - len = Dump(s,out); - Delete(s); - return len; + str = NewString(""); + Printf(str,"%s\n", w->def); + Printf(str,"%s\n", w->locals); + Printf(str,"%s\n", w->code); + Wrapper_pretty_print(str,f); } /* ----------------------------------------------------------------------------- @@ -165,14 +186,13 @@ Wrapper_dump(DOH *wo, DOH *out) { * ----------------------------------------------------------------------------- */ int -Wrapper_add_local(Wrapper *wo, const String_or_char *name, const String_or_char *decl) { - WrapObj *w = (WrapObj *) ObjData(wo); +Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) { /* See if the local has already been declared */ if (Getattr(w->localh,name)) { return -1; } Setattr(w->localh,name,decl); - Printf(Getattr(w->attr,"locals"),"%s;\n", decl); + Printf(w->locals,"%s;\n", decl); return 0; } @@ -185,24 +205,23 @@ Wrapper_add_local(Wrapper *wo, const String_or_char *name, const String_or_char * ----------------------------------------------------------------------------- */ int -Wrapper_add_localv(Wrapper *wo, const String_or_char *name, ...) { +Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) { va_list ap; int ret; String *decl; DOH *obj; - WrapObj *w = (WrapObj *) ObjData(wo); decl = NewString(""); va_start(ap,name); obj = va_arg(ap,void *); while (obj) { - Printv(decl,obj,0); + Printv(decl,obj,NIL); Putc(' ', decl); obj = va_arg(ap, void *); } va_end(ap); - ret = Wrapper_add_local(wo,name,decl); + ret = Wrapper_add_local(w,name,decl); Delete(decl); return ret; } @@ -214,8 +233,7 @@ Wrapper_add_localv(Wrapper *wo, const String_or_char *name, ...) { * ----------------------------------------------------------------------------- */ int -Wrapper_check_local(Wrapper *wo, const String_or_char *name) { - WrapObj *w = (WrapObj *) ObjData(wo); +Wrapper_check_local(Wrapper *w, const String_or_char *name) { if (Getattr(w->localh,name)) { return 1; } @@ -230,22 +248,22 @@ Wrapper_check_local(Wrapper *wo, const String_or_char *name) { * ----------------------------------------------------------------------------- */ char * -Wrapper_new_local(Wrapper *wo, const String_or_char *name, const String_or_char *decl) { +Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) { int i; - char *ret; String *nname = NewString(name); String *ndecl = NewString(decl); - WrapObj *w = (WrapObj *) ObjData(wo); + char *ret; + i = 0; - while (Wrapper_check_local(wo,nname)) { + while (Wrapper_check_local(w,nname)) { Clear(nname); Printf(nname,"%s%d",name,i); i++; } Replace(ndecl, name, nname, DOH_REPLACE_ID); Setattr(w->localh,nname,ndecl); - Printf(Getattr(w->attr,"locals"),"%s;\n", ndecl); + Printf(w->locals,"%s;\n", ndecl); ret = Char(nname); Delete(nname); Delete(ndecl); @@ -262,205 +280,29 @@ Wrapper_new_local(Wrapper *wo, const String_or_char *name, const String_or_char * ----------------------------------------------------------------------------- */ char * -Wrapper_new_localv(Wrapper *wo, const String_or_char *name, ...) { +Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) { va_list ap; char *ret; String *decl; DOH *obj; - WrapObj *w = (WrapObj *) ObjData(wo); decl = NewString(""); va_start(ap,name); obj = va_arg(ap,void *); while (obj) { - Printv(decl,obj,0); + Printv(decl,obj,NIL); Putc(' ',decl); obj = va_arg(ap, void *); } va_end(ap); - ret = Wrapper_new_local(wo,name,decl); + ret = Wrapper_new_local(w,name,decl); Delete(decl); return ret; } -/* ----------------------------------------------------------------------------- - * Wrapper_Getattr() - * ----------------------------------------------------------------------------- */ - -static DOH * -Wrapper_getattr(Wrapper *wo, DOH *k) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Getattr(w->attr,k); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_Delattr() - * ----------------------------------------------------------------------------- */ - -static int -Wrapper_delattr(Wrapper *wo, DOH *k) { - WrapObj *w = (WrapObj *) ObjData(wo); - Delattr(w->attr,k); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Wrapper_Setattr() - * ----------------------------------------------------------------------------- */ - -static int -Wrapper_setattr(Wrapper *wo, DOH *k, DOH *obj) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Setattr(w->attr,k,obj); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_firstkey() - * ----------------------------------------------------------------------------- */ - -static DOH * -Wrapper_firstkey(Wrapper *wo) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Firstkey(w->attr); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_firstkey() - * ----------------------------------------------------------------------------- */ - -static DOH * -Wrapper_nextkey(Wrapper *wo) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Nextkey(w->attr); -} - -/* File methods. These simply operate on the code string */ - -static int -Wrapper_read(Wrapper *wo, void *buffer, int nbytes) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Read(w->code,buffer,nbytes); -} - -static int -Wrapper_write(Wrapper *wo, void *buffer, int nbytes) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Write(w->code,buffer,nbytes); -} - -static int -Wrapper_putc(Wrapper *wo, int ch) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Putc(ch, w->code); -} - -static int -Wrapper_getc(Wrapper *wo) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Getc(w->code); -} - -static int -Wrapper_ungetc(Wrapper *wo, int ch) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Ungetc(ch, w->code); -} - -static int -Wrapper_seek(Wrapper *wo, long offset, int whence) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Seek(w->code, offset, whence); -} - -static long -Wrapper_tell(Wrapper *wo) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Tell(w->code); -} - -/* String method */ - -static int Wrapper_replace(DOH *wo, DOH *tok, DOH *rep, int flags) { - WrapObj *w = (WrapObj *) ObjData(wo); - return Replace(w->code, tok, rep, flags); -} - -/* ----------------------------------------------------------------------------- - * type information - * ----------------------------------------------------------------------------- */ - -static DohHashMethods WrapperHashMethods = { - Wrapper_getattr, - Wrapper_setattr, - Wrapper_delattr, - Wrapper_firstkey, - Wrapper_nextkey, -}; - -static DohFileMethods WrapperFileMethods = { - Wrapper_read, - Wrapper_write, - Wrapper_putc, - Wrapper_getc, - Wrapper_ungetc, - Wrapper_seek, - Wrapper_tell, - 0, /* close */ -}; - -static DohStringMethods WrapperStringMethods = { - Wrapper_replace, - 0, -}; - -static DohObjInfo WrapperType = { - "Wrapper", /* objname */ - DelWrapper, /* doh_del */ - 0, /* doh_copy */ - 0, /* doh_clear */ - Wrapper_str, /* doh_str */ - 0, /* doh_data */ - 0, /* doh_dump */ - 0, /* doh_len */ - 0, /* doh_hash */ - 0, /* doh_cmp */ - 0, /* doh_setfile */ - 0, /* doh_getfile */ - 0, /* doh_setline */ - 0, /* doh_getline */ - &WrapperHashMethods, /* doh_mapping */ - 0, /* doh_sequence */ - &WrapperFileMethods, /* doh_file */ - &WrapperStringMethods, /* doh_string */ - 0, /* doh_positional */ - 0, -}; - -/* ----------------------------------------------------------------------------- - * NewWrapper() - * - * Create a new wrapper function object. - * ----------------------------------------------------------------------------- */ - -#define DOHTYPE_WRAPPER 0xa - -Wrapper * -NewWrapper() { - WrapObj *w; - static int init = 0; - if (!init) { - DohRegisterType(DOHTYPE_WRAPPER, &WrapperType); - init = 1; - } - w = (WrapObj *) DohMalloc(sizeof(WrapObj)); - w->localh = NewHash(); - w->code = NewString(""); - w->attr= NewHash(); - Setattr(w->attr,"locals","{\n"); - Setattr(w->attr,"wrapcode", w->code); - return DohObjMalloc(DOHTYPE_WRAPPER, w); -} + + diff --git a/Tools/.cvsignore b/Tools/.cvsignore new file mode 100644 index 000000000..d2f6a9257 --- /dev/null +++ b/Tools/.cvsignore @@ -0,0 +1,6 @@ +config.log +config.status +configure +libtool +autom4te.cache +install-sh diff --git a/Tools/WAD/CHANGES b/Tools/WAD/CHANGES index 455c1ca6b..186d15e7b 100644 --- a/Tools/WAD/CHANGES +++ b/Tools/WAD/CHANGES @@ -1,3 +1,7 @@ +WAD 0.3 - June 2, 2002 + + - Added to the SWIG distribution. + WAD 0.2 - June 24, 2001 - Minor changes. Added the wadtrace file diff --git a/Tools/WAD/Papers/README b/Tools/WAD/Papers/README index 8cac04da5..8eb7b81d1 100644 --- a/Tools/WAD/Papers/README +++ b/Tools/WAD/Papers/README @@ -1,8 +1,5 @@ -This directory contains papers and information about WAD. +Papers about WAD can be obtained at: + + http://systems.cs.uchicago.edu/wad -python.html - WAD paper from Python9. -usenix2001.tex - USENIX 2001 Technical conference submission. - This paper was accepted, but the text has not yet - been updated to final copy. -WADTalk.pdf - Slides from the WAD Talk at Python9. diff --git a/Tools/WAD/Papers/WADTalk.pdf b/Tools/WAD/Papers/WADTalk.pdf deleted file mode 100644 index 8ca120d93aa3707215d28c5d30ff73b54dd45f38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 385395 zcmeFae~hJBde^sP(Mk-olLy zTeqrfyXxL@)vf7nW3-D2M9Duf7$P7NfkXluh$feBtl^ zPrv%#U3sa~A5`sXvGc7fU;c7+W$Uej`D}7>@ME*xsss3L)#;D;`?czBH5`tsLAzgl zL)EI@c+lG(@bhNX?{~-ic&DPND_eIc>h?y%>dIHXQeBzNchz?F$^Q4~WVUxj7{;bzNU$560pL@609gokw zyM4aBerNlFaX{j=v2{9w1}@8!$-&|5gt@x1^**yybq3=rTW`+y7EDy1iF}V4cyF;- z0@A#}+b6S+JSRg<&zrB`{c>-zw>y}$d)=L#(e7k-x-;(VO}2Nox5ss$%Cl>H zgW0`ux}2OWJxA>;U--h!cW-%~nJ{%-SnAH><5{(JW3rqaF80CT_GEu{%8YIYehn_^ z3>q(PyOB!Qpat!r#Nma`yUcy4a<)w`TMG<$Xp!awBTvba^tH99?EW=PyW&`{?%Xn#sBNyyZ)Wu@Ed;Pce+=<`q%#OFMj8@{>6>%xBsR0e*7Q) zAAkMc_y4ZrfB%cWtFzeuUw3|G|CL|*@vr~*&;9MQ-@5gqKlF1yaP=Gi^1J`}pZNNp zyZ@`Zzwftw>A(FWThqV#KmL~ozxvyL>F@n?Z{y$n8~Z=|zyIEU@%6X<+2O&z{=5Ig zfA*LD`Op98@t@i~{DtMe`S5T3oqzIo9{%Nj^cVicul?Wu=x;vw%isC$|NQHJ{$~#V z$v^zzS33v)_OJcSpZ(b{{=~2Kf8}rfnU{X&uf2Z%m;bBJbl!P*@Q;7t=kEX7|1kd> zKlS#1^TiK7^9TRzpZeU-U;o=b{pbFJ|LEO6|Bt`?H-7rcd;i78-XHqtxBS{mLKz?ce+G`po}!zq;~2w|`;Q{=xS5k6I)C9Jl}C zPqhBf=dS;zTYu$q*MG;ATVMFixBkrM{`6-)d*e5L_On0q+0VZGeQ$pC-}=}7;9vRh zCwD&geV_en|MZ*R_t(GqeRsa~egDe*Gk@Xlee*L9{+G|Z{F{Dq@)KYEr{Dj_KL4Gc z|LQk>;>v5k?LYm^-}=)({jBx7 zkALd-|Bm1PpZuSH;5YrP-|)H5edjZu{mch{|3CbPlKwO;Ne{$?i8ZV|@>6uoIffCN zm|IR}bJ)3uWCVB5P8Vk&NORKFrvqwv}bqg#iwCL8YF1Q7IZ{6yF z6j}$Qwr=(LjaKq+l-dC8!Ebf7b@S2kjrWbRT6p9A4#m>UQM`hUS}xdxbh&F(!r9K! z(x#`<-#6#T%fWoV+WO#Netmv=P##>_dTnw#^Ltx&4vuE0*WOzkP39|FJE)nuDl*q+ zDw+ZZru^T@{!7Ms|MVr4HUFQfd@_4!@1@u7ykx3WclKUtSKFKDzH9z(yBciwH~Z~A zQ_|lYS9gvm*Zs_sl*x~89Pem;EZZtH`M(PqDOeWSbCYrVcfGox0u(do8c z*|;{2U)!jLH#a)%&F$8F<63uf+(LuQC(DDyd}DjF+nQ{2XyLHB{djplJ*sYOTmvyIQ@q(dp32V!rR<>b0mmn@sQf!PWdaE%#{UP^cVi^fx=Ly=d`d zelWReG~b?_Oz&62cyFT(I#suAsNJF2?LmKY*y0z&ANFWqCq^)fmM1^vwr7w1##g7O z8$-sw>2}T%HV5i`Itg4Co3mZlJ=^%kogZWtn4Fk}9&^CIHr?Y7V0n6dXbF*zOz%;9 zB+|DN(XVe@8;Kgy}(Hm}dd3iA21Wrw~5wtRUgJ|e__4ZZazY+jYcz-;}-wbpVT>gAm}vJJeV&R)$M5ZaccH{G`5&m zrV6am$JENn!a=(8dg5MwCTg~BKAO&s#f_&McfQ4xpcZ0EI%8gwQtS0bo82BJvezAL z;!qTVLR(sqVDL-Q@cKlw>$N^Q*sb2)tjrFtd7%9k%rcA8$Hwd$ygBOij2bhOFr)9( zWNLAC%z!K;BZzUWkN9l#nEE3%+d{{=6OpjB=Yr~nfurLyS?c$v2QvseXiZ__*33P3 zVXWaOI_7Wgy3NRHBxsTzQqM#(&lT1ZtNB0{Y}>#;STdS?G2X1fk}|_Qc)Up)pc<}8kh^V^ zK*%ZfVNFiAhnqckVK}5KaYRwPZabz?t+sCeo@;Mk7i-!9|i)9uAyVGynWG{`?b*CnCMPG0he-yu;j%` zymw{m`sq|2@Cd_jg=N(7*JcO%_cN@TD!talTwl>5Y5%n94!a#Kz>ULe;oe@;f(w&5 zuEyPNwLJ{?S4h4yIbuciq+z^?9X*&{pYLO)GDOwrVN=zYK z)Y`$Nk?Ymo+t}Nc@v4Yu zm`%QyG8IBLlY2X_UOPKD)XGn8K*LY(v~eP|{>5i3u6`S3h#%(m(0yv}dUd=wK0Cxh zo*|}qUTLlL1b?-IzuMWxk8O{d?FzZ%TN=%~tv^C3qtwq@~C(sZ*M3ET(FjK3GP4;ys}t`P?$X}52N_Wso!t2I&f$B?(${de8Vr^ z`BID;r#K637}U>tA6Fy8Ze^ZM&6G{m%I4C`@!5WadMcUvm};*{C{@5B;Q z!{(QkGvBU0Y+XP0@@&*1UZ~ecETu(mLOv|MCaewQc;lvPx$g4$ta`ILV%DsCSsYe}smgqxHMAbH*!N#8rF#RfUfZZZ zt)zPjB3z9X>y01y0sYv{a9PQz4Y<0?JMoOQ^tf(@mlQWyvhbnN$^1!Dx6Z~I-+Pw# zLF@Ry%l_O!0xazV*7iLG0K9G`e6r9Al&+2>^gPDFnauO+$0v*Bf-u*CH35sSCjS=J zx`@>8m_xQ()0wo|Nu?Gvas>uV0fc-TYE7o;L5RjhTr?05K2?t<#q-+P@@lm^gNMXD zXRK27cV96%v?@^@vDPEAR#M%kVy zj;vRh5Lm3kBs1Vq>-w@<-ro?VXXyzOp>o!-nrWnc#9yt539S)K&{Gz?{FhZR&luam zl6c&p^+z@c{dCe}38^a07aKjX(POQZ$E@o05LQJ3ljgo?g(^q+WBYp%D{c6DdHdr9 z`g<#0?Q{5hEYLA55$=6bNO(w{SQ&gg->%qO>v&d}n{klWq zpNjZg==u7Ph ztWIWLw@xRAGH0htTfPrBa$s4_I7E53RaI;O&Z^I!9*1>QpP#>49kNr+su~3}uYPxJ z0=kMbf-0|7)z0DM{)a7`0XxCZ+h*5o?i@yU_uV#bShP4fS!*!5dperi(c&cL#9mO0 z&TZ~37P(Ejd3sAjx5OLgN30jC>Xb?Ou+>ZCY}Seid>S=-Zk!hU_R-3~cNb7{zCy}8 zas?3Jyv4~Yey_T7e|9pH5t}cnk2p*)*<8S zuJ+YOF-tE*`+q!*-`MuctNl(FlYgo4KV6OA|Mk%Lcmto$-Xf00St@Ea<+h<>FeIV24AINKGr=l70 zSP$eP{4etMdmXwxw`P16vb{c=q2s~!D%qcotqs6+mar$<9}Fz_bmnLGm1nFu6H4Gy0c&AVy?I0o$RVOGX9HLO5ZBQ;0Uc8qv<@6_ z;#|qWkELJfc~pWh1YQmgI9H=1Ae`?|h)G9+9Pr>U1x;9yK`73CbW)_Ej0=hwMV1pe z!7DjZV(;Ps%&|GRy{n)&xv=Pq=P?1y+rJc zYGL%kkloJq1@5{u&V z5!)^i{VtK16&EQlil4=zCGyRFc1-H+4FYmHX$F&Vdg#=VM*?C{As!KGgk!6BzW!Fg zZ?WN$D{+bj*28&tp{!RpFB$Dxj3h);Hdf&MkwUR@C>4rT08nR(w4o$0cu@n$2Y+(# zdZmnzCGC96ElfF-2@?~BR?I%)##^_}&v;M!Qs>;khO41aro;uMCW=lhq4J9=?O`Z( z?MN<|=AiBQIWDKFKFK7XKdV%|Wf>T>c6><8v#l_v!ltr1kAq%E6NTivfJc)D8*nyC z3kos$1iw|_<7qmh$j+UZ!QpU4+6hxjv~~K-$Djfz=b&IN7kciN&Ca3TsQRnofwcpK7E-B=FHj z-$rA4R(rSF(!pD0EZV$TX2dUG5zO8NEK=CIn-r>@Q4Wp4AsivIe%Qu9oi5Mz_MRyI zeXWpm;O>*K#szxv%|oK)HZc1W_S!Uki7){qHMx|8X+!4BDzTwPKMmVc9EEJp*(GLf zv>w_RpmC8;omfklzCAnAw7|+8ZGyH{faTwxTe)I^nRjUlwkC}1_EW^WKgMXD6K`DT zY+uscy={frX>ouTwAB7~9K_V>mQ}0c9!97S6cCgo)vp9bL%{Ok{zWKt0(XQBenpN-ap}o-*1Gx{< z*zAG&+~=@$Rr@J4yVfvU!1J-LgKpo#b}_eHXDm zv|3v0eZ1J82bC6^d41RE^ie#Q3%pNvfj2~;KBfJhV&ck4{IcIO*yNj&yx~*FTeQC} zC+LmWU#sqH@Zp4AGzDE^izO81gQOx$_-yF!E&Sg$XG%9m+nf%>AoJhUhfb3xXZJ4t zgH&y|wZFUb;YRgP(R{b)$R1y%fRDCZMcnGMx=^2J2o< zW~Z|yJ>?$McJ#m6gW8VgrH2?%kCUd&5p^4V?e4N|R`*3WtRK@*(jcPE#!%8A;&}|^ zV$${Mj&|F#@wCwq6gj^4;DF7sy0g^LxlzUQi|N+SUCd_v?H%H2j3v=}a=^*1x^>S- zG?iv$S~qzyp$2v1J-*d5{w$=$J1PF?DbJJr^v2iuYS?VNx7*|^d;AJ-Hkyyd3r96@ zZ?e&-Zgke^&DJr#H$9o0-me>uMq$!o`oe z<2DBo>GAgCn;%7+lf!#A!06qbZ_TF54-S_1e<+^M9zP@|aoWI*kb$`O9B%!1UgKsg zRw&>$G3LX2`p~rtY6+u-$h6xV%^=!- zBJN^`L)4-bI{*tlL^1AuqMFk^kvAUht6C?~yn$F^J8%6HSWEp^nigEj`SMlHk#`4! zc+S4~gNLcV2M<*q&zG-)!0v1>74a*cM+=lK9?oYc!ZV)7%+?f4MAxX9V?L~C>ddE+ zj-WTB>rJE^qUooRZaf%27wHOTMw3B0bms)t{8*$Lk9+MjWO@$Lb#_O5H4YSwn~E#+ zi|3~23jN}_sd%BBH@UAfPGSOsUdVH}+8={(v%&N6T%yq`&rL?X(JJB6j6Q|uAY3P@ zgF-k^ctJe3raRWSuR*$6MsfeqD}$MhP(!(;$Y(>l#WZyowb&(TxA9(5dY$vyEnYC^ zcSoacgTdCdtkwY1ZrmmC3AJ0&5bL;gF4k^qbZRJvP|Hcr4QoNpDvh&gkA~y+juDjs zh(Tfo?y=ZBe2i8*ogMC>5u$*(g;G`@p&K}RV_n7@$yiQb8DF4K>ltFl0NOmi`PuHY zr|?!WKRZdsou8nrR-eQCa6;s}Ge6rg>~pwXJV7tS{BWw|xy{dBZ@UlCp2Pg?^|(r6 z-TWk)H(2~R%ulb!zP6dc8sNJzKiR|R4QKsl>(C3$P+_=kxEjx|61si#AY1i`<0ivo z8HPMtb9iF77pa7GFOiVvcc&7%!^ClYsis<8JwYWrmE%GYT)a}?v|IZTx1iX|@oB~A zcQL=h=Zy8uF>FW)`yU>$K0E3$3nG? z`R1b;@%-6qkC(F>x|}5t{7^wsPh6R@L?r6mUdoZ_PTJGmJTFhPHciB%5zs$O{et?q zKd9$68KJJMB{7L^cW2LQl7jEOn>d=R1#UiKQiNnQDIP1RLc`n3^jwd7Bb$poeO{S4 zG%?f~!>_ScP4OD>OmR*W^)8y?JOY`~y}j;$4>oN{(+C~}lks7}(y@r0vxI4)>S&vD z;9*Deg0#kBYxzJg1~PjX33jAnx|K1zIHj);P+bu!NSEJI@0z^xWWx!k&a%FDbYX6OR60IWo><8Frl*5^6H ze17QXyy8RObR+F(-_Y^sr7W#B)Q9mu?c1Y%GjSD{>mD3Rb$2b68t>0PP?<+XkvX-d`Iq4 zb-UXUFHG_?J^X|kK-Q?K0ak{wri9D9#EjI)7vUcu3JPTm_>QJew0FqHZ;z|aA`;n4 z@)JWC4hDQRhu42+n&T>8KR%p&G?N|+3(Bn%Ch*bGW4H{{kkxNIZfdsLa;!-Q+#R)x z{m9xmMptFATpQh1(kDy}(O#Hti2qQBX^K?83>O;77*%ab@~GBL3Hmu+ST`kEsv4$b zXOxj$8x@D*Q?E}%`$?vx*K6Wio05$0IYv4;ju+NV$w~cq)Zf*5Iv6Q=HBT@l&qlm( z)00d|uiqTOa4^|(%(L(j{PU)XtCI-#LWHb^B;aVr&<-Zbus^Xw0&IhO>}!S7z`=b7c0rr(A9OXcKLE8@xY2_ z`s_K+>Tgx2H-s$t^jW8mB6eP;+)P`Xp9_p!Lv$~oLfmMPCKV!N20KTDBnoRpn4cx5 zSpMQ^gACVFL){^V1+pkVx86zCj!Q0@E>(jlqgB4yo`y@cBFRm=&z)Rmv{-FCgCzF% zKOsrNh(~8lM>i~8JP%XOJ#t~iO_i5>S!Ov|^@NiS~`RoYo!xjT<-Nvi#j&tLv8y-jNB3$&j*OAGp zT{v8YDA4-ML-#~O(s;};boFK3~!|0q6!F)hZ$HI3;>bhaHmQJhIKqH=Xip zoweCaRzJ_?nqRVfa5Fj*=V@ZwDf}Da-CyxN20J@k7PR64zCSzp=wMpN1SZiOE7Ubi z5;4-c|L~o~@?h^VJ;w84`w8^PnmyJAL{U~t&B zyM8lpR9Nd}*7RAzx3~3aJA?Opd@Y_Y7U@iZSua93QKCT3E8R94Ts~-`W^ELACVMOm zXzk?i9#_W3JG=KD%oLZ789bPCm0emqPhTN$cQFIiHf1v1jx{cY;}-Q-C`Fsc>{K7K7e?f7XE$Lp ztv>%1PB?u&rbVwrL;Coa{03h{tvu##6%0$M?9LaQ*p{J-;T(d4ij&qt@(s!`dk88Wu=% zEDv!RC|GkeDT9?aWqcN4)b1)MZ>-}nUMk;Rb08IcAqM3fv8&?&ZSQ1+*F?5nHbCv@ zeDOfU?#4b=NZp`TOWeXbaPZ~!V|n<|!|ddq-F<%n&k+h-wjRq$yK(x=OxLGpttz@-iXJEQ7sC^6hUwe(!9a+(EB# zCmgT-Xok&#Q}>SJ1#n!YWIR5Si?~9`c>WbM(bH)pbbUv{$(f?7nNgeW&!AT3y~%jT z+UW_%zO}FhPy8mweFfVxd|69`|>UungEoCPeR!Y zk%*g6ZitqN8;@5+D~!@b>;MNueXf@dKIpGFz{A=;b%?TCci(<|@9jzU96-n$T-?aO zUj-?mJuA=YC`EpcCfQeo)4JOiyK&g6EE*iMYMTUlkuIWOts}aK=d-=iQE+r|h&mS@ z!upT{qw%JWjhZYMp7Un)f@7F3)^lp7}1P*e}m~HxI{Op838!^Q|Dy z<(Y4;=H#IC%2~*!-<-Vd3(wzPp7~C${^gl(T>G>LzdZAuRw^vLUi5bcYr&Z{?z=qm zo!8oHbV^~db9(Ob%y;>G=km-qH|^+DcIWcUx57yAkz2$;F3)^lp7}24+H(l+^33<; zneQil!P>n%^Nq7X1lA`|FVB28kC${W&wT5U%;lMH4w+q^`DSl<(!MzIZi-$Ya$^J{7>Y#dwjP$x`c%;-_J~ za&(be?r;>I&(FA1$5$ffcVD|xXS@UzvgRmsSo$Ll&BSa00nGY(6(8&@K4C?|+6nPC$4W^X*a%Y>SYpewXtjZ(}Q~#-E16p z4~tCoh0rT4>Rd`1f8Wi*NFOtU3Tk7-p?Zh<=Hdn6v)kNeQe`9Flj0<-W*SOrf;40!q&>+TvKUd#D?01_tDX*aj zcJ921PR3+?+O~yLH|~7&TXU_j{F&$ZONV`_t80~O?sVty+I5fqXoV4zA)I)rKC01$ z!%4ie{538auDjJ`!{@IV_65VPw0g^M+%H^zIaE&sALIBejdAmv<#xb~T;zEz2Txr| zn5OSU`R1m>&G4v3r842q5ikiE3=W3Xp+S_YiihI_lSx2ufJzU%0-`b-wMpI-Z+HE& z68Nu%OyH(Zad25>WkbJff@<7)c8PZTCaCE`P#YDCee*S z5=qv-H@Rf1@hbW{UX3>s4aoeIVdLdyNcO^;HW=!pNv=a#B=rlvPK-7*1<4L23&36b zZlH}x03_E&0vWwP531W9iy9qLTtfdtTR@Ep*b|^~p-S#|8WjTMTo*zzi2{wYKu8s^ zXh6=OAQ{;K0Lc&}P>mTia?FT?>x~N*o#-sh2dTC@FfJ_L=@G(Zgx1((lg=F<2Y4fcZVOQNJ5eRv*0I7xGA7)0J2sVO4 z+!{PwzpeI~?Soab>u0>%d{Zs)0rlyUkHwF!@Jk=AbsAZMpa1JR-DbM_b)9Y&^^+I) zb)9<=l3)HZ$vL0n>pE!K*LdEmoX-w+kKc6`l~0~A(*sP%`!}jnpp~|QHaozaW zN!Lh|ENS?sRmh0DlS1n# z{bI&lc(w7xlbcW|KU8XA!w^Of z&i3~MCIi&&B9)!aSMerKW_RQ-VOjnJjg99YS8qGJ6=uq~wX7b@xwmA{ zddOT<6RzPQho15U)4%41$xx~|L1!t=obwOr0hLwECPg7*q8)j6Q?L8YZjx8G+wk-9UL8##tToPH6sxlgH+x> z=j!6G5|ybJ=QtH{qCDr_Dtre0zl$8EWUxp=lyX^AN((BgudxM#i|?a94p*Gx-6a`D zH4fwjD#I84eY%0Q?!zmHi4s`;=vn5?paMD3p+eME4l`J4jc1)MPFcrRvHPhtp6&6! z2G@2;78Ik$Hd(grGwo{sVYLhWmCJRvdb8RG9a1il5b=Kcbu!BtPZJy3OI+{%kE;7? zWWF1b6(m?x2tHHf%cS)3q+AzAN{U-%n7-0ZwvMWUz3Q>Di$b6?QgEyMBUGJBs|lGz zM6(filhrM=5NdGF6>w(gk!n6Yn`c+aPf@sQda>l#Q(jM9FZaF@f*%}7K$glU$t6k3 zB{_nCq=h`0g}$Wo-LvTo+zM>{IeM!8?Bea|?iYD&A6tK(OH5e3my+AfuLCTS$)9f>}b?{u3)dpk2{#uG`I2ImaiZarF8M@?y5&En7Dc%FxlNQF8`BSKIMp_>+$rxj|NM%pkpgRM8UB)NdW>KXX6E z8c=z0!em6FWY^`IR&oyV7s4Qx;wKgz@JZ+dURXNgU}}==gev&a)M2zcjfW^~B~yGF zg*4O^EAwO;+0L|!#7cI3ts&&Gc_UkWXb4zZ`Z!V>M#fgMUXn6VdTqOf-dRkiXQUY3 zQzk@7Nh*X6YPH8~ISVFn#)_1#Bz=^G%9nHQQgH`7 z&Q+0~=#)4!0H)hT$LZ;bQf`mzZ;=+EOA`*1;`z`D3S}=M_mo)o zY<>)j$vcSpi}?%AvU$!3RY8Ygq5~scp@j7)Gfehmjm;w-Hi-dnBgm0FFYAJSj0^(? z8=)YQy*hS^)zC4tnRE;(NRy5sA15w_hCXa@DO3DN8E3IRFH(4vt}4u3ZC7AFIGWx^ zIajEaBaj>)Mh|zG4IUUr^miDHhd4iQi0q~8$3tlvw-UA28c9BnG|~;6QX8^VWnacs z-IKR=Ty({Gsp`uBv20wkLtL^QLn1n3CckkwIXHR+qb+aq0p_tsa75;DO3wA&1zLQG z*xP-$=t>)VwPj)Zys1l-MPhBytu=)%xp|R`ZuL@dL+?H7N}Er0(X9clExHL@vVyuy zWBTb{X|pX&-5$zKWmUoIM;fOGlatkO;~LQ84J9W3>h#otyNRTBTW8bzev0BBx2BVQ z1B=bsu78{*ce;ojYt3u?YgZ|aX>WjtdgUrJJZgs~35omQI=Wpx!s~8@UAAYesf$A9 z6DiB=2c$tfCjI+$GD=}LoKW1Wd7`73B+T|ui$+1XEGV3z%!d~67a7e@xZ0Kv7R!Bm z8iSO^I{7(o?#?E!aG|$dEmB*v0PnXR;}SmJ=qjBy3MR_P^ma%p4cA+q$&*mFbd;wO zDOaps!d`0jmV^;79ct+jlOzL5+IWnl(|Bv8iCvDCaNbG6-f3YY)ed!TDqFQEb-GH3 z?`k=yq_oKim7g8gMtdml&m1}!Xb7x+$x@4zgRP{y2Y6mmvRa{!`Rg?DjZ)=|cQyGK zyc%vc`EE=77$hlDQ$;6Q$LDWVUIlldpV}inD&DXA%}Le?8qk*7=5|Em3!$}owmluR zxXLat$TQ=OJQz#pE=5!7MDS#Q?4JP|rbhd|Nli#HlzU@LhUoY*`7^Fw=$>sZ!Kt zS_slKL(sq}PTMoIBG?&{RgN#t$O_!`3bFwkiTZuK1;_tgjrV~WS*$w+vWI2RQ^3N| zxFyVc#BbDh9v3h=vjG#{XwpGZ!GMEI1VI1`6%`X{QdL_Y%~_~nQ?W0;sQ0P*@U*5h zPdPBS)t~^M&|p-eSZ1Am-@OJ~0cZr7(sMxbaH<+?6vw;i* z8f=QGtJuM#Ji)0o?2KNwNU1)qIlW2i#rsS%;5cn#Q4HOoNg{%4i)7xA)!Vez!APW` z6gXrndgo@~BpiXQCdylO8oC%9t(S;cV2frSbE0Whj7fv*Ndt(70`e)B6%Mqt6b?nl z!k}!GWquaV!0ka9xLwG1Hu^O&nIEzLEhlqz7Pr}7Og1J^;$#4jt z%55g<_rr_`PG-YareG5`s0L-AfXun+cN$dKvNC4xY1ae-WUvi5&dnA2!dX&1OhX7@ z4ZANLkC2|rR=sDfXPFiw*=Uo`E^~^FdYWsM+vrPaCQd4FXrk~LipmXtLTWGiwtG=4 z>+n8mWo|~Rb$#KxV4MPKa@UzO!9|58rmi(CZ%f-}1q_IU2+^2=8cx!V^s788cne$u zOyf@GAf&YmYlk_g;m|c9-6DFpS#A{>uqazGWWY*8lWSeeT$@GhzKHw<4tiPziKSAv zR#7z^DoijOA&#}m6Nknitr5F@j-dn_T8tX76{_Iiq%07aNVOK4Sj7QaQP;IYk=Lz- zqOUs-L(qU(;fk*_vgnrpV{EXb3~50mrP%pbVhz3LT^3LrlWBH(y> zEW=L4{O8|p#Fi&&y3Jq%&fsX8OBdh>E7fR7cCZkSIWiPD$Tc#xtW`AEOlMjE3!=dqw2K2@ z1Pamwyb51Qn?p zEQW{E8(NKJmK-8T){bV-k&K$SF2sG54o|Y8Hrv&32+c@mdQrdT`w@H}Y!GT>l#B$_ zmspH^rZSt99y5USXo;5IE^rJ`6RGkn%D`rt0%Q6hbhc)_5NpBaVZr8;0@E0UMg>8R zR|AT$4TUjih^leaa4a5yW6-JF01zZ-Tz8AyGfkx@z|@wz!p_MKVv%E>n1ldn6A}T! zwJJ_NwPSnV!N`J_%FQ}D+?HN1uoY{c zKtgfL0PM|3{rlYlrnayl;5;yi)ONTe*d6mzKeUnjLX%#wa2py$)ejd1*sLyC#Kab+ z_KO>8nbP~PONaK&zk6Tx=gc0fo9JdvjN*SXnXKPe;rX+zX2&Ci1uo?8Rs>ndQt@ zSui?ig{P%}3qvy!Pz6qnnNuV!p>W=pWu4PKe#0Ucoe=^<=PUbYkhHATsA^dy%> zT_D8L)4(A*A@Zdqd=!;Mv+{gb;A9-bAW4&Grm1d&j)s?44d}_^8kP*3iF+t2)o$oD zp`1KtsXgOW;9z;mZLi2zX9_ulRs*>!$Rk9pNuf3BSmeU0$3TEhgaRi+E4!oWZF#{- zllyn*FgEk>JRGN_7T@AQWQ;{B%wW8Sd{BsxnHI^;WL^P;^B}z$t*12@UQ_m$5hbu^ zB4VV)xM@+gDvn1MM-2t*P7|hOpC2Hkj}il~ z8qQtAQe7Qg&M++1fTe%6w6~q=TLBC7T=XNlub@gG&Vo`QmB0jLpr&zKLYqMmP}25B zXx>;+mXJ$7Y(@j-B(7rUT7581$eloYU44W>10z=sg&|iNU?$X2p0`j=TJ4))VOcUL zizTeH8&g2{BJ&6nDv~4e^g=r*n3jyGO>Yh3#iDc-&9ueq!L_^{Tn!gOwHzPm0g4}P=NSbnnr!&s#2r^G;o$; zP*hW6a+W+QU}j%%$TS8p!IlA1dj*b|B3jCv&>O^1f$3K7 z2PJ^b!h&J1uG}Z13%mkGc#P^c@#>ypz=WNnZ0g+_M@WKhAr{po@FN^blchi!nkF1NRgi}2UeFZ=uTg3Pz%n`Ik zSC}KDS5%H7F-Hm(?!cjn(OOnZc8EghX;xS+d2Crpa@ZpZMF_2lLxX~a8uyY=oaLaCyxj>PtjNTZbO2;e<=zigJg~G*;MNmZ2y~OOq@`Dz`Mqki`2m zOusTa(SGPQnI$)O&S_kAD)-jJi)9?lN6Qiz=3C-tyN0+WAY@MfY$-AqNrNp_Sl(3V zH_9!?fEFb<&To71CCLk&1s7YgvKo+96duVn@4=~>m!f8XH4imRZ|Xg5?r^SNwg^oZ zS_>=0gcQldglUwlJ59EprbWdH^D#7LK}G?=HLif--U7;Xmii2xA=3mV3SXIG@VYQn zaLaGY_Nd&2^2+(0ocbQ1TCQO$8fk#gFL+MUAZYUNZdmuIe%1(G_(W8K^yc0M>|uB1 zPSGE<2PFkAv&QhS1^RU)F^X*kOC((OOm9c*Q9)4Gwm+iA>~hzeMXV)-EIPr2>DI7_ z+C?4Fn8(p25TK^AZ_q`PQO2o7)$?jXJ7}g~12ze}XhEjR{*Hdr3=~eyI($Te^w1QF z5^Ek=G6Y7z&_&9Q(; ze#}yklUWr9MPk0F$|QD$w~YMJF7SatHpn6%pozlmKtloii}I_&?&~e z2YXvoEHTI(B+^J^;=x?f;p#}KEm#d_!IH?!!W)(@)Y~bHM_z9us}-mzl0;_v$zNe`NfdOUnjVvCe)nWFNYS_Hf!_*2} zLVmQ3wv(Aa8^+7PE-Y}cK&@+eQvoFpEP}{_8J`-nl5fCX2?`E66_p-bEEO+IDG$u# ze}GJB?*fm@$R)Q#TVQ56#Uf}(J5~kGVg!j)oW#hMSTOB~LrZm!UJW({PYtdM-qTxH zeP8Q0-@<|@>kGZc_Y8IlP$eB`hLYw(NT0Rr_#2&;zW|*3n<>1_wmzAX5sPm`Trob9 zY2AF3PD-jSWY&jil#d7c(jk432uV50c(-+fbLot(#ix)uFiN%D@^Cw<-{s&PC;L=M zpY8QHWT~2*!qdGp%&`;@f1rzbyVg$y40Q;Y)K}1Xu#GND&Sm#Obt0t+bGz+HYBdr|pJ2GJqoscCoRSi1o z9@v&DVF#G73+!u{q1NxZ6T!C7qMGOeocfZ6XrPk8glUuJ@Y0t|D~Q&Z26O;$Ui=r@ zCa+Fj3TjgGWO+c$JvKKC=~Hn{3nQw~pQ|%7?#=2fW-7rJmppSgGdzywnw>@8rExl= zw19cqW8r)bb4Vr8)oL%MC175+u2FsCl3+x4<%v}aXH?Phx+}@0qC~te2KG|5ZXfK# zh0XR|A2SsFNBvx`$-vs6I}@W?kCuCz3NmIBm*s1jdjK!fUQjh*VsmT zst<|GzqvlJB~5UX`vqGvlXM79l4!}x_y(b9KaHmei&!C;nHYfS?GR#fj|gc)kWr}# z9jMl@xr^CV@0um!NZ2jFENGe3dG!RhGMQP<`nc#GNn*}^DlU|WiArLYdrDGPgJwMS zWJXUyrnWq*A=2lXPQ}fx^g41R^|g*SjiZ^06sTBmj9S$jL~t~+`Cwhf^tPx_(=6aD z!@{*Gv!#BLu>xnAW)@=oexZzIs*6f25sr}t3J-D zSwV*s;h8?pYY0982)MdGmb;{rWC4WhC76ls<0XU#t!0y5POI>Uo%YB1$P_&QT!bmY z357(0qdQ>Os)plKZv*zqw0@tU2clBL1WAxP^=GG4L6rc5s>EDG)q*at(aY$wDoDeL z;Suj~c^-ZZ2fETdG>7W2rGhQpd!i+v#*!h_Vw3O)I~Kjq=037nzVYVdK_B#)Nr+Q|s=%kMkbP4K_%H zrYM9X!zq-UMyDx`!RoIB6IoVoux{{6f>9L|o5fUY0Ty=!l?xbs!I@%oQ;nsT)I||m zV6jpSD=N|u3P*(`LqSv>tW))dOo=;?*_iz}2ikzGy#)vNM4+;-ps~h z7uezWQeEe?8FzkLo9O~`=QW%Zh{;zY&!U*QZNLte)`KNNC^0FtAh4@BgRDVEB9l_B znar%vr4Y(2z=>);PhkxPX@HZErq(ornH}I-y_&fN0fDK-UBOK?9NY#hMP0ZNSkq91 zl;%X4uqd*Uao$ssgrgbSWyo+6?@Bif8GS=>2`t>xrPRuqDGIeW)V8lVHPj>@m&V(G zpj?AivI3J5EpTw7RPqqR5ltCufuS8D%3Z?|)gCgi0Qc z0RigvX^06e=m3I;z?i_WZ}nKh{*|HHI@WZFkX8e>ZLP_wV+B%IiRw%SYK@Dr(%4}x zdadUuB4!QPB9c^N*m!_M80ka?!k@%0_7Q5e8xBR$$~9=OI(@KKtMuTeTIJW=6+&IZ zC@EOv95aU*PO&SEdMoV^`IFIB}_Hch2}p5g#xo%ir~pVf*#_Z=v+b&>=h;f{?Zil zCrk?L2>k_z1p>Ax71+vf7@@qPECpL`LzmW|mo9Z}gvrdETMJEH_YQ1f$k>FY7xsZI zg54ZU*o}JdVOMJ6*yc!UBt!4XETjy3CT@?3uzw@)38r4wFnC=7F|T_E?2kit1;m&K z3_EaeJ8sX|peGRsIa6sc_sZK=jVn*op7jrx)aLf!KRgBPPuLiv@ZrP(ycF{;dmv?; z!Z9@%Y9j)f{kZ&+X#=LYK3f3MT!v}h^H{^d2I+lFMW|4jBfW2x383Hhyw!FF=>ZT- zZE|uz8<^LM0RyzXD_aJRStdszs32nq`P7!!Otv#<;H9C!KpO0@xiZCxMvjQdQU}t^ zg5EA5BvW;m&0}VJM4$~QeGzz<-6edio*}HQzU?P5U1VNu!BHyi!8Ia3OFWZAFl`l3 zQYhF9FRF+5=oV{BosO96?R;vI$Tl3ya#>9yGolxp(xyRAG69I{6?s$Gy3dYO^o$$E zX!{E3i)1}~JW%WtT`{8w*38wgIHpg`#)^$=kxfHwVEJ`mIH+I4NP+5?^6E3~P`JAZ z#!^tx^juw&&}`k5K+(FKWw%WF_9|m(z+v#~S={fgJ)7oq|D_FBC%` zkKMc|I-9N;rdKf#_0zP4Q(D8YgmDWpGs|u+Nsaa^5^SLpSC}%1LzsHVWWbA`zBV)s zns$BmJ7diHOpvO{&k|oE8-2E6WA-o$41&OB%m+*lh_GlNWfr4PbvmN&_0J(Edok3|4X< zsuQ*0my2HTAkiYxHaf_CrERA4^-t}vqrlvJ963SV(X@@Sx(dLwm0nas)EBX&f;D9{ zpENk^1zJs5(}pKsRCIy^FNHvu8?e_*YGa-`(sDbLVTOx_kLtArC~#KznrYNrP&km4 zeMuGztg&E;V%9M-PVV}d)=eLXFw_uK9ZmP1oR~292L6&T6rEPXN$&lDcFmhxrqdRl}hWVG|Ww?a`Rld4kh& zPlwcnI)74g$p#hJo1x;C7%D%^d}+5=N5iB?n5~d|U^8QZji<^z>pEMip;Il;V|DKL z3+#hEDi3_Hm};JB6)Ciz9&ZO|EL0i_RJ(jpJHdLb?u(V4)NkpVm7Qsk`vOj{N8j+8 z6fX5cy(_E%=u=T31BjY$z_GAS@{!I3OI(67a&2gh0msOJ#j!Q)?N7;%DXnwKAfLrY zhnOvHX|Y@26#LMDDz)wa3=v)!U%2CzNjwC~tQF9fx{uls59xrlg$FJVI5Y|aH2>;6 zHnZ0!>SNi|VJ#Y$aM>6%;CS6za}uvK5-YF)$Eq}II{Ati4)h(`DriYnF+T?RD2HIM z8kEymtQg?1K|X$g32JuBb%I@@l-+WvOwk>c>ao_Kg+Urt!h{|+*#*0~0*69Q zu7HlTYZk)CC_wNs2iQF&sDAUZOo8gASdET{(i3*WoL@lA0I!JRxOu58ylxvJ75j%Q z7M%-D7A$+=SU3%$>3gcRkMCxnWHj%!ucO+~B*efmDK3 z@zW4dtgPjxK&jA9;vgM@FWXpCphSj>!G(3 zh{`pXsf@Y<>7lfqtMkL1C0Lpy;zhyn1uSM0$xvXzbC#5Y0!FF2C#{B=0Z6K_haE>9 zV^`25=2Y5%W=cp#un3a_Iy$=!2M#%$CAu}h&|0vHP$$Y6E&{?W!Z5j>b%`U>JtPhk zFkAdKfMOe9lV8g~#j1?9Zr3em(?h;F@+^teQ)@Vb-BIC+vFiy63Y-6t@K zuGb_D*mGKord4Q(GfOubmlS`}iEcPhf!?IXTp&dfz2Rm-m=YK+ipjiClp+)e-%SLk zc5-NR22^0OPCBj5$fXo5E)6(_N;$m_B%+}e6Kor(&TLntkWFa8u;xH6wYZ`Ii_jTY zcq2%~ScDEjXoi+j1P>XCL`n<)K+zaC$NYoW0C7vO^_r}bu{-A~HjS9Vm@5Jmhu0+# zcp4!SUYs;w8@XD(FmGsu6&SKK;7~SMT#+r6W?=@jgk@O|B_at7o+cVBMnHFjgeaH{ z8%DqkiQvxL2H7fDJmK`?8H#31=kL-LJ>%VAtkC@ zv_K6b6GRa(m)07IMscx*Y=?*0#TvU|$8mbn#%NZV*}%q`=XOsUZy{FoKb7f+m}(l~5L3pV6*$!v8x#>yj2L7GKF6C5kPom*F+K_*u>``DS2-vQ zIMxGDnol+Qg+$IYSS7pdp-pW6@ens zIEwo~J*fJR1r1>v|AxKbm=)yX~mJ! z{+JmIeFu8l&I&Nae#M>iK7i0kQWBij4!L@=n$cV>YHDv?)SlXa+N)oeq2l=Y+Ntvq zr_Ki`;sI*O33!yW#wi!pj-C4~Ib>D}oP3u23CGS!EUL|}#`*NF@6YATIj7CzB3FI4 zgtC#=fV2#)hC{0W8+V&-vIAp?}CdMX{u~11)KjBinE8J_F`(?*;?bdu+f>!q!d9Sl_*ybr)`Ox z^h@9paIjqimlPF3<}!AE;sqK9$5A@z;JAgeLAZcR`=BRu>h@Fp##rH~QtpG}j&3B* zMgMS1csZV$kuhVqtS-``M3WA`J2sh1>QuvoYeaZPE&&@ftZV{o&sm!aQ zN-TI8I6xB+NCc%c2+9x1DSyIXM?nMjL^bL=dM7xVGnoaZ&g?}9nZV7~qxKGX9wSO} z2@FpU2ylhe153(*%?*GOa>c)*Ib*#7Qy{n?@4=M%X|N4gq{yu&LY2-FAz|-CSn7sR z4eDoYQqK!YnNJ58z0rtyN`TiSaA+oY<{)ev8c-y$H0v~^hir1@Lc8tt%dCuS-*QjD zVS!T5z;L+g$86$$#q47FMBdU@>N_`|iZhtr#Xv&QK(r3VvkHGaQ^yh~SeU zscv9)P7EnE5fWzykedZ7&tm3R)vQNY-VEBarj#ZR7Fd%$ONkkKRrKa7Nz)W6(@xXAFh%-~{Ne~D%w5wpE_hKO^*!~)zUS_65E|oGRf;B^>a$1;| z#@uGzm)a1NFv%3Uj-(#wD?I|N~-PA2{t1Z*vB}c9FY~CmI9UQ z^*kuliAu|uAwLoDnkF7@gJeyTnlB2KT>_PHED)hW82K3iM*qN`gczIGVtu^tL{w3; zkK1Q0qo#RY7kf5K=*}Bb^}y1Ji84^&)NyLN^c5cLdgC>m%Hv!T?G+EZMm!I);Z7&y zV2YSv!-?udK4`wKL2?XBs!e5GBqq%*7d{J;c)Njy^C&YLMVoYqdKA;a%DSHtSIz4| zFU;c$4zZ}F+Wg`|aw%X-a%p-O8y3P6rV@`gkptDX!be#gz(50TzAnAw4>(H}1MZHA zOqM!%(#Dk*A6m{KL{0~Cx3!iDk!NpQ=zM7_xWvvms^at)5KS6-YgK3#p|{pEyIS!B-LdgFbX z7}Uk8lCuALfb02n)a>^zy^d2;XoA~qekvKr2V`g*w661&Y#+6L4OKy2tWLM}igG1x z$M5as{pw9+UnS=Wfi9AooXnllg-kO&rwt)rh_exra6^x(8_Mt^^)G0?M`{<|p3SGT ztJPb|>ak6}6D6#n>T6MTHgP(e9_c>P%cLWLqm=?qh+s`f60#R9p3Dy>qy+)Zw%B!Phomr=sGV3T=6>GbcS*J&z zt`oU+NXQtub(D=Z64ex8!s%Sit;4PrIw~2>NUdY4rwl9*9kblJ{(9vEA<-IqlfJEX zr1~18M;UO57jx1Z4=Umi=#tbXT%#;mPBQX^N-NW?TkxnFAVk|{bG6Je*(r}n#m3aQ zR_X>-6V>?JL1QS1^z+8 z9zT92g|Py!S2yRAokNmKnO5rKWPg=t&&NK`H_c@X=$l}{noaMv?wm}fvz^KG0W*B$ zk&xmSvpIzcND6m&SRGDImmhAt;*qV)?A=yX-6D5T_4zNKE`x^;=3n{z)#~tIKC3!c z$J*528C`fB@8$2F!qlfCxU$;rN+jQ6;T@#=$z{BD1^LAoSy z^c;t}`r>r<(d2M*`o)B9?p>l5jN4+()vnn&u{k((jMLt1HtV{*;m%k%-Frx$u6w7m zB5$X&!@XBsgWiSFX+cT2%&RXRKUTIs;e@yrR0il+sj)R;zuYeU#z=`#sFg;KjQDE% z5t!`-X1o0{aA$k6y{8{-{*Bm#9*zckR}*4`y}=%V)a}5?{d%^(7|dm)T-9?r&WJT9 zY3r=LwKKyE%pPyKD!KQ*HJdI^x8QaEyE8joZbgHxFwHy??YTn+$7q%wPE^WTtNOjU z*Lrfqd-;toO0+B!la0O38C{H&Q2F+CsR_3lA(3YY3r3r3%fwuZ9Jm4XS)ZJ*A|Zu8Wppx zzy;mi>KpR*P8P=(mNfk&^-^&Abxw-t0j@i3+nD1^r;QlEr|GoezkQFLHWUPIRl31O z4suGIhfhE*x7QB#tJ?=tq|Q45&q|6&a_j7&#WHG?(}4(TK1IE*IAVt5pJ$d%^H^l)BSlP1$cqCRQ`Rgj@bAUQR(HK2eeP3 z?s$;%cz)R0-zD*Vhd_X{bdE@g+i5+z8mT!6K5Rhy&9W}Mh|(W71wB#3Jm>ss&|0w& zjrE4~%BXcUQngk$en2scUh4;lL8$na@~0}=A&o2DBk$NbNQZ!gJNhkUs@6EA1a!1= zEfx9U;y6l=;PH~6T-uhLvQ;zHc*-k&B-M*B;C#+!rXZQcS)I9y7srK){D&GLids{K z=y0NpZ&@3+cG(?=EBH|zr(Y*zl_hN4T0jsK>!77vtExg2s8o_w(zCpU!a`-@gaM5E873-^dFx4MZ z#YTTc&ns47w)y(0xtd7Xezj(ZUyLes$K3LnXC=$z8$ssQV@2ptRRj_g;cCsClU{aB ziRk@TQ7u$EN!!zdRB&*(W{K#lw$ab6y)LrQt?I3Vqk{<0oUTm8N*^CXZZGPEmC>y; zS=4IxfM7smQpP~^5>s8Y4(fH9YmMh!2Vv~j*Fia5{0j_TyO)o%4k841VelIECc-C- z9VCQX<98j%-nzwgS41)OTnn4$4{E!^_4UzU(7s$Bq2xc+^-=eGzCKzBYOm|vyDgNT z)gC*?_4*@)L5dbv4yoP~TxKh`wpUwsTb)f3qAPj)!BW~x`i)&lUFf+UF3&qz$`VgZ z`(j<5BCDZ%Qly+6h02N~MeYs{c5Kg^QPJ~usG~EcPqRa@wbJTtR&Sz(Jpi0EyJxmS zb)Y|Eu5=Tekh>7`yDgH>Upu`&Il;Wk+o*o$hpl&C`@#2#eqCEsdy54Q{n_Dc(}kxv z`9YsFM)cqI7{ywTvvut-2G}%-*K$1tT(M^C20Y6_Ee^ewKDK_>H#i72@WPKA?298D z<0-}ka%CrfbEXJ^{2IX+>P$+;(UbLl|0zj&h+r~<_UT4H#oT!zHajIuJ5Q&0@xq7mKWD~^ALAK zD9!fW{^6T**4@%jJagkyfYuV{L$wz37wfY)9-_ z95L1jF(d~_G@DN#Z1s_Zf|ZV6IZUmZU;D+Ye<7q<7mIhTEI?T-eey7|*s1s}iHjC) zt!logj)fKrN(&LHxzaWaj-sAwwKZy;ZgjT2&}&swq9V(Q7F=c_m&v(~)~s&*A`-*X z7{A2JXh2PczYbWtMpO-H6H!~ILHQ50u`N+x6He?C`{*My7j=#$!H=V2b2#zD&3FOW zYaK5iGnr3WTRgYl9>%vUX>#bQx_)@NcqR0;tvZKrBC4nW$l+``L$hnwNaR{h*m2o4 zHWxbEay*Me``pfU9HwZT6iJTim8}=)Y_FVRd5%qo=W(`Qh=biY!m{<&Y`)K7jLw)_ zTrW2uK4k~H_dRy7JABy2(XM=I#O6O7ffQb_P1CZr`r2f^i%+>3lZ|~ za*8K5VxP<9mRp!b{RgGM+1B;80P&NL$+s`&^?M1+?ok6+RHB<-O`G$gir=aaMj`*GCvakX=>j7UwYsAlfAX5P4{ z@bhe$d~D%rbsA?N%5L?Nt>x2LDrj^6Zu=YBCa$WNt2dwzryBe+5jxZ~jzVH39ho8X zPjsZ}$0yqMcHO1m{J)p0+bT&mu5nbN*-+ig;f#|Icq48ox8c7pSMQu1?aWT14hu#{rUN3-y5X{#)_>J5PRJXHEQmJqF&p`6KSP`5M#muIJ(6e%CR-eZws@@Ycj) z%l08#P+___6IVYO`}gm-;`JLpR5$Z-_1@&6$mb$Xzjzv&Z3HGh->|v4*X z({%0>k9=DviFLP=!mk|LCn$jGYt5PAXrLTXbuE_19NS9!Z21sGnxL1fAD$p=)xrqw z>8y-)BaZM+PS9X164~^Og>lhCYZwgqG)OV-BSdNLW`u_{>4lz*&Z>TVPez9>R?fU~ zKrWuVNKae4MX-tM}i033qpT|?AaT>ogCi<2j5QR3ugHAIQEuSNz`C4-P!O-{o6PzZm&F_ zZF$`hfPU+AO4w0B$F5J3Xrq}Ob^;8<4z%;H*i85d#JvPax>}2U9}#35TA_={Mz?k3 zmAZn2Jm3fqQT^7Ecu<6mKP4W1&jBT(L%WK@A?d7L@ah&0O7$I-Dn3qBP&lVYIOfHn z)h%m>KEE8Xj#Od_PlF#Z_!hw+{m}Ob!q3MTxCcmaKo#%rr()3GC32`|xJ7~Ed0x|< zJ>&zex2!D^7Cg&fLgV_5cQ-r{1lo4lzLw*vKx9gwwnBsktN9izzEHYw=ipfpe8o!h z3AePuOs6-##!&{v4j<;z94w9aD6hq$N;v>^d`c@mh~lRZLVtQi>_2H#`%PFMcuoK!v?>tkU}JEiaVFp-3?P!BqEaai4A$FHN!Dyc7Iu2UUU zFLC=O8-~hk#U`7-x#W0|uThBa9w}#C7{wi~VBrg3GzQP_L7v}$<-VI9?t>0)*@bQRHy3>r)!0qF%QtC@&C}zwWGr7SG2E1=g9BD+nCkeKm@+2_J$F}&F5QE4%H+nk+I-BLVB)24 z317()gv-h9{F{nU+y#vn_4#amwQfout9Q5&AihS{h0^-+Gp=*c9jb&AI{LUe+S6Cw z9j+n*9X0Q(lseo%6d#GRc*61I!=LnVFR<{|#bN$@*;1ji6Y5f1^RiUd}RT&GnHW&ke zOh*BcBzofx1Cv}A1tPAxWkRnaEX=9y<}#>{_H`pxd}Xhz$mv!0ySN`D4=sWKfHd#M zv~%^1zf2dXix(24ds_@fuMmJArBv5?aWe$k(WB!cE_$G!7#$#3)L`6Z=DY=T3(>eD z3WX;m2G9%$#6&^exXje&;Rw{w)941Gn(m?se&CjOlZ`{>8eI)CeSn0#VJ_Y0;eG(Y zwF!#kzIh@lH)deK3^1NVV|5GJQYSED{u!4^`RItcw2x>ZByabFviG&*FNe)%F$4}l3obATUXt=wugssh z=NYrIv2m$gXGfYN^CShpnGt*30kQqXYNqk~vjGI8;(ZZNhsV=3dAt}Ak-m01) z(|5q;6`U=ynZZ+@qK^D4b;IJFQZ@`zDTHylkO8;T={=N6;K~^gI5ub69pEa6Xdxf8 z1CKLl9Vvb_%N-DOpHguN_T3=LNfnxe>#-R~mtDUYJC|S3dY3uyoD4`1LGN9VNc9V> zDN-@dyYv#|P(BIL&8I6_2DFCw>OQqlRKNnQe)YER|L8K6p2KtrYL}E9!W6ARWpS64 zT=bEyom07_QI}d;o(4!WS6*P9jhA?c3oz6jRb`~Pt)l@7O8l$R00W7*Fi*E__+1@& zSFw4KwsdWw?$*F$MY-*zVAGoujZi{YZ^VdW)_dWH>U9%L`Q@#41k-H;7Rmyx_6BfA zfF^;iYh+kZF-U?W!4t$I5-u>V%L`0JHI9uD8L%nfEHLIa!$}^Kk&fa^64blJRgxjf6d2s;N7!0V42bLs2>#Z_w8&^xD!OoTMs&+^1s&Blbn|>N z3%nZB5rXTj>LoL(FE7C&gl(Z1s(X?kZvtrq?11UE zAz>bd1TqUCtx8_4a3yg<4tWmbl88wmt2OZ<)p1OsdY=#%sv-?cdQX}pjXQ(E4bV^8 z8=V>4BUMFph7p1gw;y)sFp)8Cqyo`kWynrL(szLwGpzTOgD3>aC}+bZs$fY=EPYo-T04YxLZBai?ztL&}G2!;Y94sT?hSDK6@ zQJS1claX#*7HFH4?l2G70>{)w^(5?RO`yD-(k)EAN1|MC;Hnd*o}KWBbm6)wp3=Z7 z1(!#f@)XrD{(%H8yOhd!lVHo7HeDq|xPE3WC6SU0;(dF<1%pQeHqn&ZM`ES)XVNa2 zb}4sIq->xV*;HfM(FfGnY8dkuup5*14UngL+Z%nj6+mevu z6F1%prvkF-5}5R*ZU#3u_)L&qEpW^}GAr_Dl}M1F>S1kSZunr7;lt|gNlS^UC*Bla zC0~+7dQ?_gAA0Vx&Qon=E09h=B+N%zBcfXs%+L_HiAH#JWs+PyR*T$nV$#YH)Nga7 z!r$Pix=~enER9EQs5F-(&%N3>2??7AIj!mym_NcQRMGYTK#5?)iujN*z2RIo;4lY_ z-!CgShu9;;3RNLOOAp7KSU_Zmg14}-Vh+SCm_aAL1=E?uvWCq|Orz&1%JBPC7w0-) z=0R+ZU5>uY?+w^iL^%~q>pq6bGR64(K3b3;BrnmZ^=&i1vpnjPM8;9WMIIB+)0fKa zkn%b*BQS|45``MC#S;fc%A~A6`dm0v10k$-v1kcWiK$s72Zgezrv-pSUp-|IF-cv; zAi>yOB}~vWYAnwspfy2(y--vBmY5!?{2(c#2O0R$vP>reF;B3Svi-$uZ_ABH5(iIt zWY*V0&%AZbBo zP+RLmc*^VRW^_dEoRq zw!*rl^pzA>ffKa_Bf=bcQLk!Gs=4lMt@Tve=u9tb<>{B#amS;Dz8Z^hPhi2F>NOn{ z#4OmEGPJ6T%Osr&NV`PC71=TzX03k;hSr6V26@Ue6Pp+XfEH zl>5%&1Z;*$6D$o&#kxCYI0zHcmx~+S>GeFtx%!QJu1CJMTf5yJ^e%U6 zKkdVK!|(NOEkeoRl6+xI+D6lnm$Xfb&eACkT>Y|7%M-pt;(_l?oakM^-}P1%l2~1Hf_{jZrQT&cDZHiVCUtQEwMSV!{wIk<(6%6oG!O) z`%eKe<7n|@So%qwGjD+p3DGN2b zpRpsT3ha}m3S5As6ClkE#Q__&YQX2wp3ne2=QiGpo54Er47 zAa0gFfQpYNbq|F;L*%097xp(dl)fs}ZjVs%r$J;mPG7rlfZCs6MQ(u(*#_(M0%;J} zL_-*8P=8DlSnIQzp+A=PHJkeIcG$Y9FEV|nzdqOGz7T()>2Hs9DV#szoN=K(!;P!U z*g5!r*n8jRxQ^`1^SvYd9cuNe=#@lPp#YF=@9ebIR=XqGUPa4Zzi3S;KoF!bO#)m1 zY)PJ&nC~#3cz@6HoXnfI>Vi_Ysh%Dio@o)M^5)5t=U<*Y`H$rSZil%BtFGmQ!zP{#m5^nqme0%niyQW|3sUFVK>QpVLpRI2SkyBi!FzoWFDLa`c)5W4mOg zce-#%rz~1cXULYR#Jj@993bT;?}|1L)00t4;KSo!qb7WsH&ORI0R+IRMbY4)#qI| zhw56Z=`FfzGnUVJ$R2_j!hz>SfWPPU%`y+2N5N{?aHN_UO}Z)Ak~nm@SH=jTJzFO> zLT~H{sE%}9iz+mu>K(UDw$JO?O*Vk+4J+Ec`;2pvwH>7mD|vM$_kj&}i|91zY%>q9 zVi$~FPP>xYu93cL>0wio_|!Khg>8Vf-$lEz9yT?x@2_ndY5^y(b|szUtu)~zg;c8!b*sw9{OF{hnqJv^~?nJ;pPn; zZ+N(QgQ?5I%^Pg;ayQYA-XNp&aPx-m zDDX+tcG?h z1hNA3aPx+jw@6NF!J?n+=MVg@wuRXJKHR+VaPx+8^5dlf1|M$Tc({3kT*t%B8(gB3 zMc}!Sa02k*<_+I?`%~S#@vx1n?L_MP!5+48J#6E8*v8d1K0R#XB68DasE2J_58JpN z?xynXKhB^%+)bq^-NW5fxeyAK$gN)5boS?WH&x$Cp<5$4s<72&PHh(La9uttm~GG8 z{wwKfn{Gb#e(NJ{DP_NKRi4Uq!>+ctw#wWSYZGb6b&X*wSL2lT?**Eqpc`AO);o4! zeLXa$uYC+_YCD9pvs)#h+JO6;&!+zS&J`7hq8!4Qu9p-2pqMesaKj8mQ+bdJ9{V?z zv&FaOb2~2cgp+R2IO@zuW_x4lC%S=n+s>3gQ0I{A8ADZO63GrTS8o>ue?SCVSue&E*>`wriF(L%8A z9^LV?He*)pJV6jpo6&ozCwD_-U#K}C_eG~OIJ9`mJhWw{Qe!jh9jsz>*pyf8ead~S z%1&3R%LH1-_rSW;`6cBeaaNt_j8Cua&Dw7O3%TKroL{}=eZbXw5>gGKJ=!K@b@je{ zE5Otm#kzf!`{^+#w(WB@EBWb#@}2Usb!2Iy8;05@^Ts-tZ@6D`tlSDCbMu2@G%ecK zim40tQ_QW!O>++~#~a>R{qg%qkLAc_57P38zz4q^&#iojeWZ*9h)eW6{`^BcPV3I@ z-G_II0X*y+{i*N6d-|u|IjW;hz7J1V;q{YQ^@{74c{uj(+r#yKgB_Fqg#U5+jy;|W z4~9;UCqAiX9RKMNH)-eDO`V{7ajDZ?JV?8b{@%wNb=fsXLN;8SiU;er_h}#B5547x z(zerPb+Av(=13nj=r|k~`+57MAH6?W)7cci=8bG#17+twuYux@PS+evOVQmU7BTf? zqfQ3iA~PLyG!pI()Nfau0Nkus7dJP&V961q%{piGKFkxfoBl+t&Mo@E&VS}4q8^TX z`G`wlb%h~v)sv5UWkHWh>g?jX`sVEJ;x!LeZno=>>p@AA?!KO?uiMsBRb{Z@F;xyQ z^4{6a#jQDTwC1(>)mgoC&zq8JI&JFNNkMmdCe;1s+QhT^@kI_s-dwyj?@)%j+pivd zP}cDNaGfsnOT_G@{YT5>nIFPrX?6Xx_IN0CJ}a@^`uWn6H4i0={AXPL_~!bB`^w)s z-kHOUU4Fb7a`X)Dvzc`E>hJ%|^SbR^)2BT7=ua5Ku&)DUEDj#3-ip_g^?)+Zo{FH8 zwH`lxZQ^))t~Bq3pLR~U-ksw*_tUOu?fE(0ta!$&8C+zof9K@>cK!S7OR!wL`r5BU zM-Ohk;_=Ws0ERao=B>tBn9vmMdv|6V`&AR`+in-nxu1jp7-$*g$^GDW*(52tOWb8TLt|a<^>(5I?mU#B0kfd*i)%*Z69hAqV?9m z&Lai-zPE-K4oEPjVxO%Px`Ox7cR1zTrao5Rr=4Pa`-Zh!A0KR8-viAFPp67CF5i!b zTV>p`=AI3;zz_~0&>g7vaww$Ff~JYohL+>|WY~IpI4KACYU# z6Z6#msa`u!b?|`Bz*sZtfo?HF-LPvI!A95AcQ(iRM049B3LKLxwFfqNDxd0$y!kJ} z=%a>{*>ZO)bZ@wg(+3bq0;xf+ZLn3cJy-OSl(493-Eo2?QH_%LHu_Sg$i%~u8;s?n#>|6?NDYO`C-talGh#U&LcD(ONFeBms zr)Qjy4tml+qLsu%cvTmwBNESiYe->Cw zP*^BpOEJ_Z*uJl9 zRNpIOAom2rQXQ+I*e#Vf{cw<4j+yE?8dI(p?)cX9tJtZd3C^n@>InU(91D@+_l`=Y zk++?e7%63y&RQ%mT4o1h4I&1M#f}!KHL*0fiOpVml4?2RE^{22b*AZrPZvjrtTWDU z0c$`~>kYlcI;o?34y8zjZ&6i$Td>|YD#f-Cr0DW*aKhTG*N{r2F?sAHB8+@Q5V>kF9MhG#ylOhXTB3iaIDhxx+6U>v$+*&!1dcf<(V}^!gfhHjrY;lg44&+ zH&|?anpbY)cc)(1N=X{^KY&17>eW3&!WNp=vxV@NAre_=Fv+Na==oaDSlMu;3jUZ^ z8?74162;OQLuBPW2uGSVr`S>45jT#xH}!0sp1BNqM1-jI3}Vm&BO<}(hIU}0X@a9! zG^cW!vm`YjqtFw6U_KOF^;H?#qNaPaPko6gBVad<1gxhs#+X$z^2Dl&)>`GML09jKX?>yQq?UU(y&xx%j+b0w~es`rq^?kdZh^t$w_;dl6XPEtGJ=9!FGpW zAr`YXmUeD44rxKo+Njqzt<9zVTLxVln`2Vy1Jet=@*4bdxPbg>it(>v1sY;%2vX5o znWi;F3kdW~ubH}-$D74vx@rC4bxpNRycQ?RRbKwOJM2 zF4>7CMQkivVWz0DV$nJ<%?>cv1gSL-k}7vE8>@;+)e3PL4#n9R+cCJhU7BQ-#VpN$ z351JkxNcoii)K?~qTeOKiH;6iC+U}o4om5@J5etLiU~s9Kn%sG+Zf(BTJuK5^X7O3 zNnIk1r%hssvlX`(T^G0qpqTX0ae&l34 zGRcf@&RYqTjN4GSXOH8^3B!fE#$D?$wHcSydrj-a4Z*U7rX&LhS! zE$?WVmce2DniWPyhxNC&ecg+CuUFp`L02#8Ll$oDyy(Xgte0lq6!hZq<@c-e>nj$} zAnX}yoe;KRk#n~6%vv3B4ck&6TK~>h`2NS<3ZFk6*7y$BW`A{c{<@Y;UufA>tIjMi ze)h#bvlQ^kYpb_e(mN8%#7EZhn6J*)XKR_YzPNt%=qX<_oT3h1R((Uy+7fR^m;QgX z{^Bz=%F}hnYZkli%(0{OxzuU5{@v=W8FZv|KbXhj*cbK6U0?A0w=v~l;dAv_U-PWh zcsLWXbXBhAJZ*hFU8p5bsg0CJ6E;4O^td9|LUtGW(z}-udB~51kZ$Q^Ttzu=uHQ6` zs6bfe$(TNmGYY1(G8eI_Fz%0!=~9(3+|;8I_d$J-28 zmw%xPdoSO-t&c9=T+lgIgky-o1(r`*IeIRqLCC$nc)hy&hKEDh-T*INUp~J%lP<}h zc=ekvq;|c(wSWwZwNk0Ob;%~rJKWZf&HuKD%nIrnv%b1U(JoPMb%r~OKhAZ&k3VOq zo!$A#RP`B=;D!_lv5y|ACT?Ss$J&Pa-JR^Mt%z=Ryg;S}1hP@gEj}R~O_-DgHSatu zqS>87DgV=xpu&67stIvhGX8{4J$o8UXQAF#ez9=O5_X7g>)02IOW5%Y!y@mn^y{T? zb`ThkoKAU|d-}d5>ZR{n%^ES4gT8MyFJ`@hNcqQhTltg|9_2!Kh0`=)7N+Ul&DCr@ zzB)6mv*)K0@k`h0>+SNFLw5%zu+r^@Sz}XE?0p z684n({(Ua1t4nTAe{Q|Jyj$G+(JJ@NAM#?PaLEQR*^n_S^Y8rgMq6sdF2PJw1=9z? zGI)Vb9w-wJ8#c!7#xR1MzNfv0qI(hc_@KjEtg_FvZ1M-J~k>02(CA!$PRKO|lnF0A>YG zl|{x@dx=z)2*zbNMcE1s*p{{|y@(88lPOrAH&EIJ{G=8rb#=IS0&HxgA^P7i55GHo zior;G_%u|J+Y*uBH_@ZQ-NnD4X8Gis}=Lpdad-%5lW54ysQR_aDfT~Y$d;$(z9M^t9byO?qB1c(4k<+#WOmGG=gl-Ad zn(T(i+m=LiQBOo4hsK(YK=mPw%P3F{ClxnjUd2fz6;mFM)L?baong(|GN$vEVdads zaK$pO6ejg#lbu)6Sg|ro3|r+vRcxei8aas?U^5yqS{0j|N~~ROC3awQPHQp}YP74= zrNgC8{o~R$7Mk4_%4stwSF06&3%xA{q1f(8Q*;y`ZBWm`2w?ZD!(RSJ3*fSns*<>~ z+JMktCRggT)}o{l7Ln{#8pS_0q$AnAVDpyxa+%VI7&>cMy zDez2mDj}_Y*LuSS&RYSF@KfRgVNzhm47CO8o#s_ywBXcN`Wt*~e*+m#Qt~7XE6qL9 z>;M<)RI9)raKO@B_uHDR5yHWku1JkC0^4W89?+{;+R}&WY(|(Af5evI%!7VKWAz{$2@JtA0^g5dzkdutauQ6H2(}P7u^oPvKaRzHkti7H z9ZRAG>T^JQrmP$sYt6{~M?oM*Z=qH(3Im*VO|VJ9)S4_^>v3rEu}0hisU$FRr&y&p zl@yz~YN}LpAGH_W)Kt_2Z-{7T9hp&1xk%|f!EwO*V}?^VH{**3Yv`Hi6Q@SbiBod~ zt#{?uYW1;qFRT}VcqGMz;8+k63M6*{BD z35thOMeth;8#!%Z7CgcY0<)6Bk^eY@PV00B~wQZ8m z1UszLZss(H%22*jT%lsGfa#v{5Z}R6CRju9^}bG60j$a$)@~0SP_#n@8xbjLwQJss zefQ!8Swxu;<)<4S+A=``9IMv@FM{a_$i-)WjLV0poer3)uEudx5 zLUf|Sf+LN2(h(bi6tcsyAQVgnRcvXNJ;C1Ka*UsL&$Zowo~kuh*Al5zFu?}YWo>`Q z=$`S2&M;7`GgcB@F%Us%Gz>>AKEjG%n_zp6Eqg}kr1%!G$n}}67%7dxc3RmHM>!bQ zYb6lVo6q4 zPU-Prx-mW!FwJ&1AW&Xr)Pl*uV^r#*A_3_T1R2^>k+E*Dp$((Ya=#|0>4j4bCc*7V zs6gA6JZ7&PY#D4!i%6T(^4{8QpsIc>t!N%k3vz$JK~OzIGCv5~o*4O%E1GKM4_VPv zz@vk$I`HWTr~dvRhdm3>a%8g(D47P#W+k|FD&BYSjo7#cto^xvi|mlgQ8cj=4*39GEcb- zw%jt!_Bh$Q@uQA~vZ`0d1nWJ+b}W>&imVH@^-8Z(Y01^cLQgpjcmvg5U)dpcNrG1z zZ&@|CKKCNkX-4u7_$Ya}C%*SrRrb?)vFx&lxIfaPML(MPO&^NF-78GL>eOWnfV z%_Fhvnpb=DX|SfkT^u}mppyT4?wkG%E5lrZ(afUxqrdlVhokkks~1-6)82DfLo{cQcpAj{_|y;x^nibu$2QK?=lH^yu~? zEMvXraA)1{EZco?XuoUZ;`aL8%{eSw^dF6`X=A>Ow@*(5U*<~qTFra;T zaku*I>hTx9_7O(x)fuf}1e!*OO~nhJUtYaX?D)lvh5-D-tDCboE8E2*GT8C~TCA>3T~C-B zSCo3J6B{~bu{X#ahN+uRSHHZty13z@jMWVRzM|7_wQI`zrP!aey1U`+?78|NJ51UTzH0%UyzA-um$(jX4rEfl{{P<9AM9JqFDocg31c-P z^X0&&+N4GZ#|J7E1b-}1YZsj=;Ske?gL3^6;UIo(W_!uDIC5cB^4Dyv zl0Im2lgeAL)^-YgdVH!qA_SHP+nd%;zSG?0<>~oOfsghED4c6QKYQYzwY*;+Uc5Nh zhy9nMv(xjZd%v7-_P%+3dV287*G;jd&H0NLo3VAidG`FJ ze|h{l!-pq5BEDMt~*7MkeeoqBDm!>Q3 z$P|ts@hzZp$0{X5$T2S`1{=t1TG=vze5;l30IKPwp@7VwpXp?BYlE4&@?4DqY`_(j zZ|2JmGSv|p=Wut*OztMEfHd8jWZ_EGHF64U#8%bT6+miM248rY=>sZ_DTwAe6N;k7 zqLG1KJZLP{0xldSfvye+QfH6#XX_|z)UqP1NXNAlr|>jA$Hb;WuW$CMOcy4c*+S7; z0D{=wO)rQDkF$pKWkebvB}`$&yjF1_loFD*^xvu4*1bJ2{o}#)&JQgJsfyf3?R{#6 zURD-wg4y7}fjXwW>m3^z1ce4!rYVgh!_P1ChuBLsEu_77*t^z}f5s(w31Vrt6Dj#8 z5U$-2ZAQ2C?qpk3^VW4S`z@D5kt}Avo`woWxPXpm$wc|ri~3gEiEDqbwlrxaA*p^W z#LG+*$NtL2Sb|mpDCQW`z)v`!eJHCF=4q&o`OJ<~JbGKI(l!R@KVfwU8#VGS4dK?t ziYoMpsJewE?9h5J%LJ^`D(xj94vSzZoVC1Iii%HkwQXfvRx-4JkxuQSuG0H(55)s= zueXG5ojZpe_h7Hm`>+qi_h5%<1VuZT!w0MyhsA2mdMOxIRqL!fV|)0aS@~37nS0fk zei245bM8*F3Zabz2tW&2UKnPDN8*BJSg?BPt?yPRKz!7RIZ=8z9WikOwhnuw7V$7dt%r-ipo6wzlgB~zrK1xYfulXenDYHK zVu^2sT^k#YQS%}W&n_X@H$f~mLHC*QPuP-ijE?ejd)oZJ#Qu=d1D6Qk(NCJmsuQ97z^Mp z&4ZdH>9f(&z%Ik=jYw~>+nF^H0Md0WrBaAmMnAC~{D_=DSXst`++rN0=I}OfI-Jpb zvad_mCMUV3n9`4MZY+C7t-J{}Dt^L0rNYOkT=|=5%%p%r&E_XPm_gFuc~6+fdI`Tg zt>7rE9k0N$rWy-fJqV-1A;zwJAm;tG%T{|wUjBs-P_Q3qb~=M;t@^{^NJ;alSBsRo z^)xk8)K5Qk4mA@i0)ic4q(2&9kdp`1F(BCCe^7=hw%cDUw&7&x9R}uJ+x{rUUYE|$ z*^1eGOB?$Gb1!uWb}w!`VGBllH_jZj_K;VYaY&c8XH>g%3db<3Tbno1@FD7B4nyBd zwDccixsT|2MettKC{e4uKo=&4j^B$Li^HVu#f@UL+6%auKj2vI#jTrCik;*QXlBka zqVZOH0XOR!RxzqAv73D%??KI`l2&;EwXQL{pK5d)6~C7waxW=ez)akOJ>Sca3<39| z&ZQYHKEz!k>AkoacpXNIUx&=*ypV?P`*3S8zh96i6r=C=(S1VlrPW@bdz=8^(l57pymSJLGKRnDwJ=+JuDrnE+8Ik<*+J7 z*c|mCCys}z3y3H4KE$ge$Gws}o@y?j9X!$@UVI(n{(T%CsxBZN+~^@PAcN5+a3k)8p;G(G>5XEMMeDC(LJE>N2i97p_^_@83oQ?om&hKx<3eRT?ow#h z=pHIB;htRi0%|6@OVL?FJ=I;pJd8VssCNuzO95I#Jyc%6z2nS9^QjBCpRzMYf0FqlXIvd@CJhQwx|WZKK5!)nuU$NBV{tx7!Bo(dLHYrSZNO`)HJ9u|OB2MRTl6 zxG8SByF_+Q>)eNXn4>S@rnqbVp>8YqX(PfR-LpK)V)4C3qZp_u&_Ye(obEY?FsK}f z($Gz_-0exd6b8BQzz3mK_#g#IOH-sR#f&gjeCUI8k1WMQ=4i&uDh7EE3QRx|)@s+h zdhBo&4e72W#5}WfXve9l5U5G;5V1m_=0O$^kCkVtRk#PuTfjY~7MD;Db(c_MPt9N! zP!9>wCEP>hCESCZFW_dZT8av{)#st|67I=6EubFK&r4)ab(b&?K6L>#YP}Q{HmZlp zOSlPRmh8B?JSF>=s2=Jrp(c!J&g+nD#Xw6@VIzB}yntJgObxsXs2S2*!wX~&b(b)6 zwQZwo0rgNirfB3P6v*Vbz3YwsCqAS~_Z^V#yibb8E@E#UR(G=~2BP@D|McSWUUe(c@z>{N&7iRXYWzzPo@&am%YH7^xmA$1Rj@h>v#of2!T;bv31>7jhlJ>UB6fceW zz1X|4?!%1>Yu3KR5{lc1F`7ohos;AD;U1@-3*F*ac^I-FN3uN&V}5Iv@uG!&3wSvq z-E?<}W@4bjnQ6m3Bng(-!M2H}x(lck0=1y=kgi#tXQ_CYxE^vu@x;O)Sad5GY05cz zp?DI-Iabcb(x!agfK;W2P6)kmlw-vEP6+RVVpO|_PDoeqQ#_=vX6&qDsBQ)~#6X)? zd1A=Ot}2~!ZA+NhO5OaxOi-z;?JrG^hp3N-#NYz%vGNk`LH!nR4{6LL+(YFh+|6Vb z5DzKWCB&`f64t@U7Z4KzEro?8B_)CuJw$POa83)jr)2gL%|qQKvT?af7EukO^W7^h zv^-SiATm8Do2c5;P_R&!7^pS8MD|p7iE75THh>+XRt(fU$P((I@&azfF>T;oz)cXe zqWm*o({DMQ=F3-)T-r}Efat}HS*1q6GfHC-3K*PXxPVeY9j*E*U zf8nD9`huN9y5$m8(pE#q9U!sPQxu}6xWAR~KYuwP$v2xH6 zJ_wyR>W1}V4b)&mB9=kXeW6Pt&SRtyhBaet@M&W^aRuGU+GyV>uRUL?p)&=@q_%(! zFrstuSX%@x;e#(b?uoJNR9-Ogoe*l%YF?lZgf;JQ>}D>d03O#|XrSt8&u15^=nN>4 z?eL;fIF|BY)&RFN7+lsQBJksAhRQpP+ZXJBT&Du80)lCEfbj={U77VI7>Gntw}HYV zU(a_M-)Ot05<ZGxlr9dzGvgOE5&7gRY3 z_X&>2z+b^Im3yE0Wbs&$SylJrlu0AiZe-#V;wt23Omlv0B2#I*9u30f+knekIV_uC zI$BaMKFM^Y1O-|p1s9u@0*LmDiP}CqX^4hSgQjx_=x(?-5}C9wJ6Lt+lKe_n7Va03 zY|XD-Q;h}_X}S*`Ca4w_UQYxunpUzmKehV{YDJed4aGGbb}f9)=3=+4RsMitSV7u} z3{?BnWkIf6{%(L>mr11!Rl`20ytSsgW`U~QT=k9{j_d}oN_`zu*l~53b#8zys^W*d zMm{g6A)c#td=A41Z3LFNGVFLzl#Ij_okvM|JXSU&t5k&N9$nS$aN6?bD|ylG{p^<9HHAM=e_kC`sy1`%rSVOj=8>#Tl2&9$m`Q)zC1`xK$hQnUGF~pO zmrMo97;_o3;0#vYdjUw~Fb*SnK-T(IM+jA}hP{Q*pAP`2;gwpdmglH*b-s!%aPv~$9Y=U--sN>tKn+gy9hm5zWO)Sw>Ab^a5ec+8shEhTGJ>cquy~&UJ8-XV9oxs3 z7BRTOXXTUu2G%JHHSZl);8WivuR7+@VYc>2tMq)?jyh()?n)Im>O4zZ9ELmo6yGmq zmd@#-RclR$wO~3K3tm{oXmlG1=Eej?t0){_o5*_HA?5f@q^O5nJ% z;UaJ}8`6|6DwJp9bEDRoHJ}PYbsK7FWacMmq{kr*eh`B4%I;+XffLTiVXM>`Q4RhE zX@YOb&47_oSY_{P!xzjB8;Xsm{)V)CY7LfqDr1F{+UMs&h9w!v1eeqIIv9B6zd?-U zmvMVI!Igz%26zdQF~VA*C))~+&Ha#LnyZz3aU7q>ib{Igt060Dq$wT@2aYBksNq~q ztSLLW!U$4FTQ633Xz89PP-g>Ij~_hZ=aAjeW!h853vKb)gc zoV1hfHeqeB1o0m+nBfB~_6QXF<#zP9{1<}&hAB9c5C#ng9=f#L;~0afiUB?9w4-{= zIW+n=P0)qxrlgfuQ#F-6z+QwGDRDDU-KeZiG*ISBsTEWVkeM)InCSyU#BmWa5eADU zeyJDxbv?*xFbcnBm4nVPHH}#vT0aI-<<`;-DqGp=u)Z3TCb=rOxWE`W=?i#_HKGl` zqO}dgy5m({1&+D`M?|*1d3CGT0mArm49r3mLep0UR~G~KNC~?TD_N$29`qMjLY!dd zft2o%4(KIKc@e;1$J@g;!gdwnmuxtt0J?k)Baztb3Va#c2;%!BMcV__eYxvosLuTM zfnD!psvpWV+t4`9X;)d($}O-6$NR+)a|W|dg>*f$7~iHwy1v=NjRO^0SISTwa5q_Y zu%oSW%Uii=RjvuNo-$C+=wP@;LKoTqQ4w$fiq;8EG$wwScE$(^y~E5H-5k|aUAtIa znx1GoN3a!KgO_LR`aB-FjS2&7PU*dND$;Xs3vf>YF!l~SlZ68|7I%YorbKn^#3d4u z$+a>@)gm)J6K@IG;i{Y&tI(BvyIG=fuAaEgN}#XpClo$dvjkgSnSyN@lFe}k_UbfP zEKW1bX_WL(Z%(;W6{5gBS0qxkg2QV#AyIk&+9C^SAuyjwb|sq*m+U%RvTfW)6(p=d zQ)D1r7-)_-TqCxwATOk>ZBmyN~p&Q)Eg4XkjnI3vczQL9I{3{ zzEu{xS{f>64N$2VL2^iGC9T3X~rjyx)&F3UqU^P7&zX7Z8OqUceaM@LtP#5 zHLou<%9xWDMX}C5@SGI5iZM&o> z_gQkyt!@fqAMZ0>GR)eC?l2v3snv7VQa)&y#u# ztVB+tNA$zisP8?#)V#9QN0F>JGK4J;&pm?baTZhF_T(8WfooJ(r!Oi}A0mtUlG^ zMKM#WkB9pkTB*Nx7H(W#?4_nV#kh$qiR!iV9bv7X)?kk107jsu888^WGZ~a!>fvXx zk1Q|$coqU659+_|nWwUhTdk_7ms4nnnP<*GH-h%hTCwBPTu0wdm^)nMSRc()CO15`+$O@Xz!^-+N})*Sgi$-gzH7lQ)Z!*czbS`9jAotoQ65A5=xIehMkQev*ZPd+gGS9!=U zINcxUshKP@!}f(KEF+L+iGMCF`igxX^d|h!C-zPFQ$F^0s?VswY=LM^40ey4SHLD2 z(3-pof%)&^S!tIh-NWXoHx!eBQ_NY^pp*?RX$YpqNeSynLo>_@DVTvKFul6qDlc7V z)tjy~^uX4o4j1zUqXk`9M@lt|StZN^{H=UwPxYI!wDueM4C9Om>Wy_vSqj4?+eS{4 z4aVH~;V<@Otx}Wc(s0jk!w-4p-hf}_P1ol2Eo*s&NqrB5JZ;a^|{NG2N!c#J#C{LI; zG~7z%4^oKZYIt==7JaEKCm|D|GOD9RVl0k`3m7NrSXGa>(La@0yt+V1-?n_8u8QkP zHWe}$!0y6BP%7B7D&cjOVFn`?!Hz2G?k?3w!hB!oDz(_ahFv*gD4SZ#oH%Q1YHg2l z;B?YHu{zn3i*uehu!P!)I&o>_TIbS)AQM%yCw-l22VbT))RIB?&N3Im6O8CU2aE~}j!flj1yV*%r$fTz38``v zkpP)v^+KsbVe-a)BL)Pl@TbG!uKGcD_+Gx1V#IF=F#(mp!0M<&Y!Xig zSOy)85;7)>l$LZLdu!#;^jgBEjCeR?1IiL6ID36Gb+tcYY?0QHl~vsWTE-F;RAoe1 z?UssWzPv$$MJ3B;X$x2^n&9`^M(vY{aIg;@frLfCp-i_R(Rf=g>gBa=bs)^-ahj|# zzR9V8Cr+U(J-xy5B?6i;&-vUQb%4v0`*RS^C=A6j3V#5@yuSPcn*oQ3uoBsr+Oc+C z^m#C^rnf7dnKk;2j`OoeP`-ZsI`=H=@62qMZn!_u_4WNVqksDT?FARepS`-^=J+qp zZn(T&uQ~eC_`iJon|{On34`MNrKOYHEYC;Rce;uD*%L7Q!^Mlsv%kImj$7$<0saYw ze+uckmj1Jw>$i&~x+9)@_(hUi>9qYh-EgnY?%ic7re6bNXH%4yj;XfC~q#_=tT{#``fL*=fw-IRey8#R@bTLqc^L^ zy@HF+f0`TcbGIP$;^Xr~&?>LA=t}wLe*8mkZ0N50?fUWaJl~=BZf;jE9}$2(<;@V6 z-K3hI{>d-AZ9?xz1HGEg7@Aqf4$*0Z zeDo8MsyiVy*1nGpPfhYc zw)*{nq_~BN6k@y)fwZ8|q$fOTLX#2%YF z(&m!hLSx;$KKS!w?qT&tt^S35Mk`r*8>f;clyThw%_0Ge?gAhOUgAfFkY&K&4CLyB(3mUC+E3Np5NOh*o%ws0M zxK!E5OGox=TSX3+jr2(QQyiyuhBEtUcj{x8#LMfqd0>vUAuYwQZuE(gE90Wi6QXG? z`n9;&8dHv@4#k)uNDn_YK zs}fTOd4f-$jx~JAznZ!G=7wQj-)c<@qu-b?_@T9{wrr(GAL+oYA7`w$H8fd=?c`PI zDeF&}y946WwEX00*$85ffX*wZ6s8~_n3azO)+Q8{@@ET(8hi5ey zkhQZx8H3Wrx|d$C6KH$I4b%c&6p&>s>i@*gYP7hz9<{81l@KnE67jszk=~&rf5D>~ z{+YL<#$WZkAn(D}n;M@S<2!f)Nw0~zAc496Bs%{-DBc9a+qPW%2aTrQb}~B44Vj|~ zb+F$BXE_e12elPS9R^BcKLk5I>BtLNmXbYq_O;|16G(|+4L?f3NG^0eR4r>lP;r;)e(l;Wtj{PZyDa{l9|$#L{PA61`M zt6%8F;d+FaH|vyzxx8}bV3QZ6^-i9~hP!X-*MM)F?bxheymKz%DG&ag-QHfGUpl+M z1E+ofxvIP%0m8`i?d9D!tE3+`Yn~>DA4*y9_am)N)gyYWi>%MyI3uE9RY7Wh{1*?* zW(`HT%>1)UYM3Ye4~3DBKW~po+#JoPnbyQ4W|3=HpS6%k$Il; z{f}RE&h)oD`zx5jnlb?Ev~+QSYP>UJ}vdeVh~m zqPdnH((X8-eSfRo_r`Rqkd z@Ac?ay}<4k#sEyBUr+`a?nqEz6rg zI=G6mp%bJ*Da>EeUVVv5s|0;q)iG3oKGSog6H8WhogpC=tZi#Xl$Ek0j@v{_vr9*C zFIVaq^f9yS{!+QMvA34C_mH>7Sei)VZgrs5yFX_z-4$Hld+(SUi*{#Moyz%4+d{O^ zH<2ekc_(83Li^f4HDTa;^0tCmAA~)#`o>5NdMXV36V3-L_F{e`e?b6kQvCmk99`S$>FXUyF)%Sh4ww}UlE!>A3YItYc zloA|Ettk`wMk{s2iYP|wYK~qEsP(l5s`QnY(q#kAkD`Kog}q84z9mnWN=brG1Y?YKfhHjr7OJj8=PBN%1eD!*vU~g>PvHMFth>j!%U z>N5((t@#)A@Z`{9*-SH%S$+EeZzEP0;b7PgtwInZrvmW6LPtphOSB8Qsz+DYN++VV zkJ-8hjDwKwq?6RE~m6 zq7k?Ccn>$7-D?_FK;mNML$dlLsIJK=$IT9Z?zyvd)!0+_+{ur+!yT^eqWWGYtX(&d ze02JZzvYSjw+9`@Tr2Dmms!BeBc21cz6%cM-U7O;zLh!ZQ|r#qiglZ2=BOLos9^0f z!<)V5A<^hT%1yMkWXt&?OVJHjwGpj^IFJU1_KF41YUgBB>+;km;bFw)2amepHJ=GC zGJPRM=cO(%30XGSS#4|U5!Zc4`5dEzuY+MIx3^k%S+I3CCpi4?pIiGvUeROaSAzw6 zh~@^SsW$<9JS!}lYMNyua*@_)DcOhpk>=En89w!+5vDE5vIXzS0b5Sx6io9uZz9-+ zC73R6HFK~;PYDy*AmX83mmy-}N0=%kOHI8WeJIy~ZPoSUOS&VA2X~~vmS?-U0WR9o zcC}TN_i=Z)%GtG|j#)nYRJUGcPq*mIw`E-;Pt5WeWm2#C7aeZ+sv|xqE`t(G!;IMD@}U8lMX)zGtKz2I8SEp@utWM2^-)XvxGH zqmNOuNk68B{k_s^`hVV;W#@auX?ie#7hR-kAC#NX)p2NnG@(0>Ji?S-YhGbp;1O#3|8atiM|?;#W&$-E-8m%vhqP!V(=r+3UxQ za2+%mJEEJ0WRrBnJ<)whDmP!^1PA)WsQCx-=5qugzFgN(H^|Djc?1+TwO#oRF%@B` ztHmZFli5fyRtBBUi$(*OG{7zJ0ec*8cl(f@@VM<`NvNt$pJ-fX2r{>4^&5pA2s?!t zkve}I7KuNeqh*M2JOg%kGu1V=8Gg~X*S-h8d#cYn7vda-lp2bCgqq^F_xp%|%jXkV9;$&d zp{c!(99ipgEC!LQdX1(-Pe#fq*4M2gFd7w6%$&+2Tf!(ury)*!ntvcc&FVWzrLW6g zhuV$r=Cea>;mZgKJ@M!C23BbMYi!uZFNLoLI##p9N>>LVipvoZDA3a$QCy~4ia#3# z6k|bk#SH8LmS^jFJF6ZNePFNJNS9?>6Neo6Bzagj0qf(^ld-bV%^CpRJ^^sFy0nO4 z-aldNsrij;r!j-WF@%_?NTYN^jz>-a!mXo%tyf7aZs4hW0&}b?w#z-zW#>`_Z9!Fa z%B^=B@Ra|vy$-PH7HpHPt!(UFX#J}1dwa|1dvhs9t4+J*en5Nmv07lN(j;=v($dkH26*U`MwCbkE^AW9dTpT_(L-3Lr26^Z+GAalMhGFx z*3<^dI6x=Ap(&V|rZewyQ%B;U58J8C@uto<%0Dulc7UkuTGrgUaCgHcQ}U;InnKle z7IWgi&k75)VgX4SJSU+kmcB*91Xf#kPd7yi6z`+XeO78JwV{m9TM~4iaQfkp!ZE8F zOYGCU+h$-%STxWk9!(rus!Vw3UfNS`=KVqysI71UhNE`EmJBCc^*Euf$y?Bs*e{&0 z1lnQ0S$)XE)uK2wChempt_&E)3y!x2h8=?A{ec}Lw6puO`b{YmWI-fExXT7gC!9*? zBcFOiSNh-}c&aRPO9YMt{1AqDeG^EY!g|U-GR_T$9c|3b^R%pHb$J6UT_lcBB*2RR zQhGGEK@tfpcP>QdDXq9ov59HQC?X=@*hnNq2xM)ujQ~h|F__BgD|u$U+(!&7EvFn8 zF0vG;h{yu>h%V2KCfGJBx2=;ssyt&!nA8b_Lwm)W{n}W3I#qq_b%QE#mMvQBt~`VH zz>9D=B-?I>=;1=#Mwu^-$&0u;_;j+o&zr4afExX4IZvm>t-%eyPmilOJs&GK^4y+> zR&~~+ry8^csPme00K@O_N>dVGJ0CuusvF_h0{HgY2i<$B&-x~8eNy(YAGRHg$UJy< z;_Ij05BtCVsMq0++*2m&{n+o1K9bCVvArF+&+3;Cxg%GtblU!$cI2wF`#W;EUUKtr zCi$n{k-PhMxFgqF%vhvj)2H@)u6Gd3L-rj!y=K1yO%k$M0yG?Jib(9?+d)wEJ zS)e7 z++P0cBh7lbjnLJ;dK7GTI?hb=vc7z)Q_`yP>8hVVna7(ARCW*YpkPgc9{`i9ZM9*J-Hgg-!>fZH2kA z!+#Fvh97^<-r>DKc0=On8HYQM=^6<<0@?0GJ-)2J=77@8o!sja&R6Nw)cVcY<&}Pr zoBiVZum52N{^s4)*FV4d{&T|9zx!_bNr`?J?y>p!0jpIzw3bAH&iiuK`VT%q&-IDGz>R&vfyUq63$`T8#1=@}dK>+5fC z&fb1~`}XWj`@H?#`Qy*NzIc0cd3EMW zmWI`CEh36+stG3dr(#ht0n*8#uGjAc2bEW|)pGSoi?#xT$yfw>`9Lq1nUGqSA7E#= z1w(@R?1ZpjVJrKsCu{^epDtLWmE%x9NK;PiAB5xFXBU_ES|Bejk|g1)=A2L#Z27qy zMgYsnP>x{2H^|ZTfDKe{H0z5L*mVuu%Xx@Nv?6orvVcymdl08ntTWhc*V=((mbR2P z73DM36YOFxYb@je_vmi@j1TQ>=!#a1s&4BgpOLsIw)MO*hUN`-4E22%)L37c*xqKX z#0{)3?T)R$yMjB$#@Zslia{b<3_@4xwPMj&F!Ru`Oggw@*{xJ7pc4I&k~&jLCx>a{tmnrI7`PvfWgz-F zSELH_V-@1l!?6rDg0YmBV8dhGXk9-AU4;wV#0I5-Z%Yl zEF)(&NCrF{%ixff=65=!!9;I5nT7?Cjd(bgA=WVC6lEzWjq|qcsQ29VnmLNuvSUp zU62m4U@!+~Iv$Q?JRHk-IF|8nEJLSAlw^K5mQfGNuz>fzH&6Zp9?Lk@?u~x*;m01! zIMr^D*+uE(tv~oh>29Ud_9KpEupy@sZO zn>S~7muz&>8vYYjHddeTKQ>RXRLE5}E8;jU+`q|w0vkl4y>+Ys$T=Lif?0-t6awLKgh~YQS>-U=vNK-a_h+Sk6!=%sOU7aIZc5@(Ry>Rzzy?T3g z!$A*3b=%H-xRe*@*qz4fc0MM;rRk(mxHMf=e0luw`rXAX8$<5rq3>`vTYf;I<{y0x8yyXL3}(NlU{#qJ0BxXaxa*PpEG$O{KpbW#0@?xm+Q zI>Pet9L;OEuMgCZc4s|4ID0U=+Uo)gw%+Wk{iK1My|D(`%7jl=c7l0fW%@_|m6ct_ z%6LQ3Kb4iOE^pb1bIn_UIxd9g))^unADXjvFq|#dCuu9*?0D0UGn^;KjmsPUGTFa+ z$+jO(C23zK|9SJ4y`e86b>IE}$*VabNNc*z{|}V0FJzWR9<^gie}Ao46pz;5K03ub zIkbGV{{17}lc+OA>>onb$Mp^(N06+GepFFkZ`P7L?B2j-e+8AjzOMiCdlDljF!(lQ1>$f$JHk=pZZmHJkcP`SwDz+w~`D!G! z>AUcTIq;B;a(b^44xT?EuwK8r%hze->V8c>Vh_lIrgxRumdbo~{rWXp$`FC(-tge= zD|rWe3*f@r6X-E8Jm5pP-@~sNI{9wKCyA-^5_8Kda3hdUi^LXW9 zaUe&y2tWTRQ}l=Lu4b4RG~~GDAmOX__*xlxe+?n1w%-3pO+CZGUUQx8<0ySm!Y(+Y z^=qA+eVg;;-(o<0nCXv!eA(XSkZM2yPjt9%&(b%X<%)gUkP~Y`ciz3Swa8NHkHN0u zV%ZCLc7VoAE>!ZvIA)#$(J8~Ae=P?_$dQeOXhfb&k?UpT(0dtJS1|)4JUDvIZFYZ5 zjIYpS9^<#?kv`zjYrO41+mDFx3DDW|n7IDFc%LnrsPqSn{f8HudhE|7txq3@zvFZBfDp7MkgMk ze`}`&n;A5pYDS>V&dhiwfM@sYq&)30lDI^BwrBP2>Nf93KTAZvRYdQYPJ?XCoCx(f zg0SXMCWcZ*f8)9vo4W1;FhPex%|C895G(RZsQwar63ktlzkc_Eqvx-$&pnB|)dB5I z&Ttd#+lSwM|CWe&_WMh-2CivR;yJ?A-WRUPTtVusLBd~V-cYFA=Id5XlO0cUG?KnE z2i`nqk}+?$KUdu+h%!Hmnnh->%MhF6zH#oF@du=IRM>Ki;jW zqJFD!Tu)&U2sl1H(bHlYXy3lB5a2ejX3U7Y#QXyI6D^Nqc;C8v7&cn&*f{1wFrtaKELOiktc6mN%}5%2ph9(l_t!R+o2e zrlZ43>@sQpYfpr4+0scge0<`ImpJVpE#b5Y7m4L$3zI_j=m^Fgao$0bL{8S|qA?%G z;J}(rzHqL@_X2IX$cmZNF+sMEXKa}h=`ag$z9;RV;~Ts)o`XBQsjT*ZeTYa|3D5%? zJD^(Q_3dDzHG#gfQ^f2c2lnSmr&7G-)D8ZV{w)xmvqCD*sT?}a27zM&*L*)?jB?f6 zkv4H^ zHZ_mgMMOOirfbI}mthJBkQtH!jHDt`!3c!nS#=XQ`vru0{{<4bmK%{%gEYQ$gV`xR z4=~a)MlR_>Y{v{C-uhNIpQ}gFt-Q}L>4I(uqlbj9t`1njFW9%jieF(Ua+BVATgR3u zq!q_2Y|z5~brkkkx6+w5U5Kym5t>K^OlcrSG0DE}&f21sA{;n})%5VUDC@BA+EU}C z)VKkP8!fG^PD>i=ASRU0qoo{LOHT}HF04{tVg{v5kxg4&R4-WPzfL+V%b6?$o|-Ss zL?$?V;NC2E#bzs+F#`u3GKx%qMcf4Yh@xbi`g+#~YB?4L71aM>Et)Y;cH@HwaLaON zK*@Z2WIo2)o5j?na9d{UIwd)=eJ&Q6XsF8jKKF-pSqgf)d8;Q*e`0fB{}MUh?(#JJ8r~X9UWWKm2+S?$SZ8hp=4s5!N5x* ztN-`x^}CBlxI1pH`NhTU`D(TL@=hsWk3Jj`MkRMo{hs%4xt@WZq1g_tpBz$D6Mn{a?>-cYpoluaC9^)`5ZKG8pjqK?&{{G5H)t{aZ2=Q zMyJYr8aRAA;;r%OHx{u+@kV{n8RVaRUL?B#tv@vsQv>Ss*+Hj`;_7E_$NKpGQw`F* zs=$Ar5H~YW-^;em1|rD5zx|nT(B-904s2uK;Qz4OE`FNHJv};2-Wei#^DUld`u51^ zb%44An@WcbY_`49HkD@Rr|NxaKw-nq8BPzXrTN84(!``L?#yoKQ#T4yV!T!l%cX2z zt(&f;8vZ>6s_H}Byh*5c#O$rEUz;8w8vqKKDUFK#f9tJQy6J^AX9k@hLVrlmPtaX>%JER1{sH<`A3$Wcmp;u=wGZUyN0iymjB z#fSvgt)u>4JxMv({k_jRyR&SEMgtY3IBHD-yD=i4yA)#J|6Z}FPcia}lgRiE(>b7y8S3lAr;Ct(Xj7!=HAP(!#)9*MHP7!lB0LMV3 zO220{!!tjUT%G|lN565Rg~_>AQS76X^3UZU+RVzRr~61b_XzcYb^oZ}q36!R@K)a= zd)o6%MK)PgSA?5OuL6QO{8R(XAM$qpI8co zMzP{R>ptkND~f5I@dr$BSdpEybSR`{ajGLP8f`V=jJ0s%-c?LLuk3k8??aesB!{PHS7o&&1JJiO?7gO zgsvb?SO_fd1)RW>Knypx$q`xV6BeSfkW7aH5{C+|s1fVe=g{n8$FviOuBh=k0Hmo0 z8n)48{F(A%Z*o!{_C3nO_t@2}zNh9BdUL0PB61+DgQ1)rnGvRto&dwzsiWcuVBJrCCmUuG!xAHPm=P+89wh|&&WWUM1vZuSR@ailyR$dVE0|4^b9Vsw~!}x zt?xa6Y*7;UM zCOIEJ09o(}>r^Mrp#c^H_GmNXb?T3v_^OfYL}=J4RrE3YJ02h#aY) z!SeH1WYmX0q}WfMNWcKnL;i`L#x|$|N) zS&IUBz~cQD(7cjp^mPZz_XWmWVr!{AX`GQw3YoSh1q>~~<%UDM9E*8YeM2W}pmC~Q zIvV{aTP;SRqZw0St78M}i-c!3D>#VTN5SYDVC+L%4QFtL7R|xI1lrN-3}GESa&x`D zbz?wpw<&^hXyG@T9JDQ$PaO|S7uh~UouVB+#{-DF%PGWXV zc!L?1U77DP%Nfk~1v9Z0{oT$wY}*k&v9G;w0w_(JV2h=D9FZqggB?{}mt{$~)tc7~ z2Dn1f;5gj;h6$E4pZkU|%P8sGa`h zh}9RNO^qZ$F_FYDp|6{Qpx^en)kWE&i7E~VHc@S$!@69*IJ(s;sfg~uQHSmLR4z(O zUIjLBw%T+q#+J(Jc;GaK(#J7Y<4^S5Nux~OF@B-EN{7=kSwPA=981S?X=U_y;F&

      YmbYmN{r?{s!|po4~(6sG#7zR^k@JVanOh&tXtL??M zqv8C^R?oF?Nu3t&oL~dS;q7=3FZu)fcVvAcLcM;1Zc;KQbvkn^IULx1`PvXm$BoLjL^dJl6nRlFaN^)PE0+>*(ukHc49chkoee4kB&z6D;H;S4?_|l*?8oaqH$4x`B42TY#k<7PpGk&8AIylaY3s zrU_KL(L^=XVcU6!Y1)*yHaIPihMbqeLv=OAffS(%B}_buGP@$(%xJx)+}AV~kS^jQ z93r$X%V!iWsU^k_BZ3?HgvYuMSto_z-C$ zl~!!9ykDyh7khI;50eXhngcGrggk`Q`6lw&b!96NtJFPI5*$;Is$fHpE&9)x(@(pEA&LWm5JsRL`#TsHzMpqA4JV zZJH`GU34g48q(GQK)pU3*wPYgUm^1q*MQ^b%Dg+A)#m>F_SnOB$0t}+H~d?&$nv5^ z%$9XkTP$ivp9av~(EbKdhi7sh1&ak8q?%ytO10Vj;IE5AdfQEvJqoIrP*vWc!}xx| zZ7T~YUBe|H`EU!Y1l-|L0Ksw(O+osAQ3@njA%rEq4%ae_T5m{S_Z#5^&e zcvrzy-x2h?CHZD)(rXyDq`L$#P3Ix>=Xrq@7U zE^>mR-W3%zZ`-1V=8b{n4z1e$E1pW4AREFV*;94Rh$HOaJ&JRvSfyyKy47$(-av?v z5k-lclNKx`hve!~!7X!wk;qH7L7*AU2+PRYprNO6(Jm<^x~ld%jP`URmNe|2V&em7 z7jR5CX`Pqwupa5Gb$o!W!&{buXns&5`=bH2yE@+X>`I_ z*t@jR3%CaBjCM^fGhZX;GhZCsk;T}8e{XRxdy`qfZs%5h?H#G_9>KnK_M&P}CX0i5 zf?dv$=@{yw=QO1>q7nnLj~P~qv*$uolaI8J(h_UvTBsx zF~fr4J5q$;&17s1GhCn$#sfm~ob=o;03(oh^dpdeN}crR*MVfoVjr zDdAs8*m3frszbRx_ZA~Hl>rzy9R*HtKuFS{MWg8`T~Nn0-&8;8pau!RG!Bd!OfW-Z zeV%d#zoB-5@s2w#d1_06u8=j-@aQwrnazmQ)-%9aPc_h~dh__eVsd93*FtIh?2N4d zr}LfhN{sG8ncxVG@lM4}#DL<|2#YnSNW@5a!Qo`ZXI-U$p{6Tb2R(WPYS|ZA1K$F6 zN`#uMM~$Q~Y7RmuSJ6kLp&KxxrkB%q>;mj{^)WGgqS{1}d`$}ooR-m}U0cJOU>7nX zz;WnG-GFon#;7jAymIU#BG_X^0@rozm0yxA zSU}g{Hrk^L8p1G+7$mT|HNj?wR4>gtW(7(|62hXlk!;1Vz-b&>~H;~>;s>4NE`yL)Z#;&6Www1Kz;EBzkkt6*_J393ZZk^K^Ei|BY9Z+8v zBly=gQ{$N)YxT#Ck0i}ROJg&j+iGIK&)Gzqn6#HeZ8fptHYH}Qu3Kyq9M0lqB_@{T zJle|*+eAC;jmEOMcwrP#pEsQ&G%PsSaR8LcHN$5LWxq#Sc$g0d4t7feV<(Ds;~j`U z%Bt*-cf=c!YIzqztTO+28zo+%k?}^vYo(#_Rudd=MzmM;?d&>OzK|(L3}S*ac$e=~ z@Mu<)Zv`%;a~@;@EoDV3QPJoiJ6t9O?0{TN0T~Q>wHhos){G^9p#f0Rn&1pYnl_n6 z)JB@y`&2_$?=#A$ku4*MG*Ta%UX)pwJM&OWfsNN43@bIdb~)A1+vQk8^8|b3?(Q)I zx%N!E;Tq?=Z>>0>dtzXSBu$={3v}u~S|-!%Zk=K|J(BS0R)d#Ra!+4Nc^QsNm+61= z!=?6Qwwt2MX1$u*72T^HAxRe2{e4+r9}mi6VNd!W0|qREjDf@X7;rg&>{bGO{KEvs zeQ44W4TyU|;&IF6Zh&JnaYiUeq#jSz!8kV53tdoKaeU0D2*gdN3#9cDEsbCbU6fz zPHQdz(FGEmv%9^xyKTGhlv0JkM@+yN3GkzFOh;tp;zvn`&`ZGyZztF?=W`7}sG+@R zfvA;5OtK5jrm%dlqfxePmrThZ2sIzY1*2^SBNU}a4b~{$TPhDa$K9K1bhuYatD|a* zL|30x3|j^|W-Q5IGf*ZTjXXQ758>$O5p$&qPlnn?M}6!`?W0!VIeiq58&Bm|8&8vG z5u2jAV`b2>u@i-qjBxkJOk-i-7#Q@SpyCE_Y^Pwpk4$Iv)8RvmctW<0iklEby(8`8 zFum1ZmRjQ`BRGYmCK!<4kK{x~m@{HU4cZAelo(C9HJ|)tQwz`iHKUDBqd?zdWi?V~ zYcD@XQHo#SEAkvk4fsR;)PCTJzG&%0e}@w(gC9bUw6bh&Xf;912rrJsrE)7jg3n{$ zBsq&vx#i&QU~$$#h>GKn4_GmxYpQ0|^7J{Xi?K=d$|Pl}0?UI} z-lyoj2!{T-Lu_YJn73P<;(F1BY$x53?crPn8?^t*bR$$^LDZp7V-R>_X)V<$#S#umWJ<*io&A&=wSklnJ-~R+vCpYz#6HsK|tz zC9-=rY=h>w>U(}5T1TEp@N?>T&1mn7Lk!NO(c9|!*fpVpQEm@jphnP3^N?$`r#Ip_ zy>aBAwvoCxVWpi_hB%afNrP;XAOX*0C2&uoLqjPaL3`%--T&`&R|@SRkZ?XZf*ql! z%}nzb4RS;~mc#&C5|v|6hR8~x`H<-4AA2;-pXjEVwRAMUqVwdoEF6K*HNeKR!@)?W zGf>_11XgB5$s5tC^q{&nfgUNvF{wP4_^6O!Q-CZ? zUPLKvI!Z)KO zGqdH&L$BNo+;iK_ud^qLS&$q$&PED`U(`((6j={|0ZOM-s8I&kc(jp~uXI2`_N`qT z^x%j9*(xZQuPL?p=xa1ohc#?2t+sN(scy%p^1|+U=Rc7^r(XK*Ypxt4 zLW4LsNE6fC5EY>e8_q|EffLMU5`ew`Mge^U!f{+!7-11QQ)|nDj+xI{Ol`)^htxnp zbg(=PGZ}#`I>}()v;pRG{A4t?zzS1Us;^m)wj-?ew;GO3mf}e^pKFLs(;c?Q;Z1dY zsOKirEnu465+J!3nlk`-4y;aExwl9zTE%D5D%K4hh=~bwO6wM-q&RtGiua9;C^_zk zzIg0-L=k?7g{LwhKJV2jsAUp0?+l%qOJ^rICZ`!M%z(UzB-BEE43^G_SA0b)paTY^ z>m?M-d|*@hUX{sFe~*A*s5B)!b24p(HXQzFu4%H6fx6`?5@SV7O& zk4Xx)$OY?j;1t`!1=`^sMCHKpkP@$5rTV`lFoYT9+KNwC8lX0#Upek%7;#{hw?4Xuv)`HC?|+W z_d8hnA-3odF%OhmZRuwyDwitlkvS2imbId(j9j(ju<18ioUR}Z8DA{9{%%EO*ljNe zIji6{0B0c zlq>L{d#a9_Hq8|F7?-uyt)t)(Db)~K$xfz%ZxxLGx&8!K?_n;6<($A^S?-hI=$}NB z>fT44J@_hiv{IKz33jeWKA?+A;YbCAav24BB$QdAr?p9)>N+JM81w#d9;@k`L@WQS zX-v=Z34|#F>L&Lw3cZCGCIQe^LTEQK~`FgZwJAoe;g2x+pR{L0(E1 z7p7kRyqliY=!A)IdPq5VPmpgsugAUYorr5Bo^r^b+#k#3pC}6vJ+|T&Un~lSFN%sdaccgB;2DDIszV47 zGgc2mGfhoIIX$F_+VF5tN>Vuw!`5(1zPCuE#r))*+RcM_zsH`LuY&R}X{ zM%FBnOI7o+QwzdOFZ6L4Ieu9xru3ARgy7i?H(1fH2*CtI7lFGpu8%q$cA+N+Dl{rw zyjmhCjk^I>H#*EH3ueHmTLxjlRuP?bNbM^2RBQU2+vy~rj*V%Q)U#7|T!d@Xgm6Ih zy0+xk=2mebmd>c)+BLmVG;%@)ZwNmo&{+(jvZO$a28ltj*-YmKx*{x6ol!LCmasb9 z`f0I1Xk&vHdjy9|z1Y!}s>2-##0op1(~_0B5^)0J@Y zBqq@Q0}2EGfI(@`>Lf$C5W7*eX4(O*$;~_NiFm3S_u)`a1{h}qol1Mhkvfgt=$31e z;nR&o7>N>9HJAo6Le-3n_toC(!v1bj*!K*Ij_5ej-M@5A*SzPUhdg(|wYPVAPvVrj z=&>d427eKd3$(o+{?+>S^3B`VzP+8RISH`VFE8~F#VI$zt43YZ#WvK#8?kj~RexFL zN56WbOGD>3Vl#gFmk)U(wp!`5{Tpt?*7@}5DVsmwr5kl>@1+}r#w~4n4u^~BFV5cl zB`Ib7KcWUdn)B-RFYxF5fAn{Cij`@}M!Sjo63BEa24O9&365>-1O|fpYbNouecUn4^-g2*Sx)Pl^0it z{<$`m5o!H;^~Lvh-*Ba@ep-E|7dv#xu%N4#7u>?TSzlb8Uwpj!b?#Tc=8ivq`nUP? zC%x_Z6g~b^-gd2N5F?7&->gs9J*_{#yyAlA-(1|jd+ldte)zST{z{H6Pu7*mzr48P zF5u7dSOi-0?)>iE%>|0_mbYszuI}`5$J?7nguOhE^NOcZbiMuEbg$HkrzCXp8Lzrk zHm$7+>naF5SFJ1afo3@QK!=dgzj0kzcXbh9C|14~0WH7>ly;%MRd~8cvOlroC0X(v zIkeOnXy#q#i=ov&?)smlG&;FVp^l>V{b)4q0xyR$Jj5152^Cm6|oK`w3I= zc1zj(q`;>5p@}K%gdgjVbZg^B>VYpMoS5*@<9AQmC7ABXh~Y+w#AL#u7ArTIv-tq^f9dX>QQcF{x9vj->&~=b#wNu-$(de%KSvhe`?#KD(;Y) zFv6!VGdD7!`UVDa_Sq-PD8*Nk5@mw_^Ju&X2ymIeYsx!mxM{qIC5>Df%1TXF8MO z*Fxc>`CVJ+bRSVa`Hl)M+;Y?du`fy7<>$YPpXn0U zGJJUsRD6;bab)c#;DhoUe6S$#x@!Bt_slTJbvRI4Krokhwm?eae&TEWzf#^DZR*lq zf5aY&Oje9=U-DMgM;{~G^YiTsr1~*8isHp_7}5m_qy?n}AM0vO6@K-o%YJ6; zW#{NO?rzK7no2@3fg^NfZ4Mi(^snX~5qRS4z>Fg*XKWE{*QLAyLqT9X0yA%fEKq^D zN;9`$T(R$TG)=LN<%7&|ct8z1z)3$4=HOYA#}01MM$$A>i#_Ck&{RoxVN0G4QZp-~ zD|6Ci-0FEvK9iIrhd?8$-r3?1zlOxn2BXGefDqd2CWlAdpDEd_a?m+RktBTBE>8-r zy=!6=j5C*Egr(9l8MG%mb-n|1tW)SxW{ud+Y=RJ2V5VJl(pX@oFIniV3#sYrthVW! z{StgANM*xPqhL>$7{MSni%lwZQjKLwF|vSUk^$sEvT{Hp{Hj$CI;$@|(kRgr`A={r z!Z1_H5X~doTRbV)+v6&oDrBCtPntZz)tG1VIkT$ImC?}JK{Qo6P-F)UCfDrNy)?+@ z6P(sL3$BqaxnY%i@;<=MMQQ$;WCT0mU?(80=<{O(nXo5)pu&Q)C=49wae!RB2gW*7 z*(=Z;Otyhym9bS^-$Iw|u^C|N7R%OB8@6-DUbR`+VA+6jmttY7ECb_XOG{B4P)p(i z7RO5Gvl2qfQE44>4<(f(@tTMzi?G>~I_IF*BnA#T$x_|QHT)AGYeC&Y%R|4>rI^Q{T7rsCF@_i!ImNV5djXKbdqlabP>UX7a!= zsys20L%$KfG7lE=1jf-?8_iOE>rh{YlwOqe;wekl;~lcxr0<;suRH4|xa`%@+F;Bb zj_Q_GG6#w70%M-7FA>oEKuJhNFeS+@6DOj0<~&X`11 z?lrb}CdRhrJh;$#V9}2=jd{)L$61dArUUx~z7K<17(2+8I$~<|*y%29%FKEyzK!p+ z2hT2i>BG^8!dm&&1fWmNXq5_pjfzR<6ul`|MqZluh-tC+LnAk*8i+nOQ3<>$Q1+5GFw7X<%*X zY*88a^i>!MG-*uL-wMp+kwY!v^XLIO4i>nniW)$Ne7R`=ZP^iw zi>u41fGi9Z#=M1Hi3*Dj1@Rygvd2pH78GF^dWa4TbXW^&mjbhcpsC)NXpozrLOtM> zn1%HMVLJOlLmp_YllzGuX3Rh6k&|#X~nt?FWlCcb|apaN6TOWeJqP3ySkt^H6 z;;cNrcguOYm$i9*$6Kc=t>Fx2c+(EdB0c1WMPkjde5{P;XW2QsGm`9Ek*GFEp&U;h zvoS+GZ}ZZQ!xi%MvwWXV#*@}mGimCQP1!NmSlu%Vu@a6?`6;Z5dr4H5N{qb_%kD8l*SC*fBG%mO)0h zf`WFVtOafn3ht?p5Mhy+^R&u|n!-w9)nA!j{A6z#)gnYG4ae zwtM*eqa7wgo=ibcuRzDDmWBt3Cek8l)1ofpOJHf0_;eIF_ef!qYW10x9p-NwIhdkp z$b*)NNa;IFp=2YTzeOSiz-rVzN2!x)9V_JIg$!!eXlyuS*bx`9YrfBh>74MX8MHML z1cg23i=t^o#S)|97}&IXMJtimb}Fh9-fJL*qy>`>o7p)5n*p9OqwrCq0ENvB<-y=T zfPKiuArrr}}e*jLS!#4{KDI#j}ALaXUl~^b@pH3T+@OnG(hL z9nqLjKo~>*oSKsXS_0h(WftBWWRwQGv}Rz73J)YC&FtD`rT>NP1x*BQY58j(mtlU< z3Lu;E+5u?F7aeE=b|6Hi7cF=oyHp@LV|I(S!a{cF{D>~$pgac!=t^gOkgaJ?g)|L` z_TQ#GF9Jy-VPeK|bLjC5sYj0t)^u}h06u{oO49Ob_?<@)!JTP$fghij#YHR*m7DH1UeAQL}QK!UnAoBpQd;VGu$~ zuLtm=g5V>LsF0Mq_pFECzfg5{;iMr}dU4r9(GI05zu|`UX|iE-s`?Ga)jX#|4R>}o z#l7Y;Os{1&NRhNAQ1l*AT$7k`W-CH4n61Vgl@+rUrMWYX3#+qH+)E{_O`xbYO7 zc`He`nh)fO2dD`SstmZ@q8WwgXz&(xVW=oR8Gbt~QR?{9SX^|d`#kX-b zd&SiU3@gdUe-lXAsw2yik5+k_@oBm&t|HO4wvc?(oVTtLAWDg~zN@)Lc2Fx ziA8jK#ppU{1%&A}vGgs2Hgbauq}3#C#r1fad-@U3iVRXEpyh)#J|W4>pH36i$e6EX2~K+)6c$u}f35*FmzhT)ane zbP&=@*Z=NO6ho18v#D^2lBZuV~l@4Z-yZh(>g{ zaHPxEq<;lnFoC~~i{Ux4Z)G*^d-_0&CfzH<8t5h9M55G`Hc}=OsR-ZL?M#I?4GV&u zk!!divQ;hX>IrFc2Dhc;BGs1QDea?r2(Q4p(z~X0I>_cdR;OEnMF)6h{>DC)zcd7Y zi|R{(Nsd_)T7osQUAB;-C7yA7daZ*HmkGrG(w9!SGi+?3Gd)}eoO!`&>hhk)XaEc zru&tC8U567Y-ouk{p`fnY)RN?3`O42TtFW1lpLQyGn@7xAFP^C#Kb^_x zr+IXp=9zs5?Y_qF$5D5IqP+tjtU>N{Mj-8%kqO2PT9Qt%NIHF=i>GJgjli(>K=*9S z7L&ZBUrt`rFXIfHQ8dO9Xz^P4VGrzERtJ~LA)lyj9||U%Z;GzF^?8wsg!c zUZQYgDJb)j^PS|iOz^TGn5 zS5XA@WWfuTLD=U8W)HLl6FN`8w+>4zky=sxm7||#Pfffd^ORh^n>{5E$ z>~FeTNDHHPP_FGbbzP<*V1)G5#Ua%V<5!BqYqC{$>x_jw#S#Wxi_g4s)VgBO8ctEI ziRwINMYOmQP8eW`F31wBbC=w8J$3N3yhTD*aw?TghfdveDI9SdGp93Er;2d*%aq`l z0}}!tQ+nxn2V0isZS9uAv>7M5AvY^4lHy7v10b27Tb;x`wo^Nw z5i?}jbe*7uO=UoqSK0tPD>zAKm7EN;5~G9BgY<&geOP)hV$*AA;Y{WCV6>amK+V4a zRkVm|)k86PL=}-7R*cDNjF)h87>TAma21v@(y&BgX}KZ~Tw;@PmW4Tg3KRi0cnMj% z>QY3}f%E3O(2OIslF%n_JAZXOsxL{o@f4(av->RGOYWia)B}%m+6wR!Ct20|tWfa|73a=-ZN(T!*|h*k znu>B9JCF(^Nrs*!3CTYO4t1mgavt)0&O(3eF`~~ zgSF2oPD5wWDI+A))aS;28~_VnC_<@xVozZo>OwkTiod}sDog{zE|qjZmpm>>H|?g1 zE^BN3Dy>gbxne!6Cwi5JiW2S%hBtgUUAhSe^hP^iBOCvV?(wI!9{BRA7 z(zsbQbQbGnN*V#>ic1t_i6JRF;}T@imU9`h)sS{x1B0%s28FSgwQ0uP(9(mkn#@Y> zHO}1mYF!CrUZE6)8FLWJUiDBmRx5T*sdfjy+*3B~Q5eM?=Vfh)FLrK865}x)94X1c zWGNv{Rl+a7THUgrEt!WKE~(gKlNOuy=!GQ>O=zs_F|4X`%{ZFI$<#1T3;@Ns;CSd* zk@D&OY-Ra$(sDrd@ubO$BjbUzZ98}ALp`8=LW=e`booRgNx1B`=n>GAB^YS(EVBW# z3}>|2F}1^ync@WMA$mK#?DQ}{A6RU9mOviLDn6R0=u_B90{t#dTo3`O-7H0C?$XOA_i02UO=$7DbjKP-x(Qu?F^;taM@Y-_FHP0s%;o^SNVdsCMU-CA z;W|?I8XriM-v|O@IyxG|6gf>>aA5@LGpy7SQ>2y@gG?8m4W$cDE;MA5#dL(A+2K;4 zJM5sxFYXNbwkaDXQ{DrqP9%xZ!#<`9$LTynaQJZ0(R5&ak!4EqG{q=f1}(9nH9?48 zl^up3Njpp*4!hH!DG{;Z5+8{Yt#g*-ZPA)fQpH7Eab_z~59wkvy)}9@wxH;=V29O> zmyJnFW{HxJutZu0>G7EZz&Le4ChDO!`n-l@SJPL6RY|x;i@R2BBLUgdRYQjI9AUqx zgo$&(V8K=C)F6~zH{qacV7$#ya9JiaGC26%0b&DBo!-m8!6h!n2=jh7Q)N~Y zzgwyEez%g<7d-ugrZfw4-!{A&M2*;6Y;gNWMjL~NqBSl+d zmEQp^>l5bK6IcC)+G;+`r?_)8UEJFfZ*aR!qo!zOOl02hQdO9n;FENa@+TxUs*>5H zvooMIN6F5*xF;c1d&&l{@n~9L(IsywX)76$){F2WPPck*$4OxcsBI}}*GZOPFkGdbsBf7n@S@w4m)$^fcEYw3 z<}0ttWC=bwg&oMOB=#gcv7l9GM5IV;G$}5VDay=k&&ty3l|5@i3n2%aQ?JZdYBc$@ znLdx0@}Y*p1d;8q7~a{eU!xF*j9PWQeScJw{rZD!Qe*0)N>H4ZLDpE-|os zgNu@$+lPEj+9y=mMj5I)Vpt|~h}+=|WSD_|E=NfLQO|Z|*(H0rl7~HE4bP-8;IufC z`EvkL>MBNr9bgE1lsLUhNkWgASj$~6{9u=J9#TbKVAVSb2(_?^Cc$31%%uL?Z3z3;U zy(6;AgQR!N+7lApwr$3YrSAjVVa$LsaI)p@LFR-R1)v4K0r=z!vK_8BBX_caKLixX zC1}B8_QKh-lc;SpM^MX_kC{s0wW3w%xv5{I^OALR!CNZ{P`pkcW3_36HmZcj11<1O z{2OTS7s`=%)8j$B!u15(6n}#8K!?~skK{7YS_hyuRiDpEHMHCJLS4EF(2nd-Cbf8<7FI%&zrcScH)Y*`~m=m+)yST&4sxH*zA#8twy4a7TEaP-ODbutU-$P5+g=9~rtTOjI{h&pbZqj4A zA!R+8JMBJe2MseEoN^8-GXqjWOI|@YJz-o-k;jPA#GJ4eo)U>_*~_~843%jQ-`Mg< zc_Uett4$Q5hwDytB`2v)FfR2wiri$!3j4H{I?R|LCURcZ5@eVbyrGjx(+M5VjB8{x zosKVbYR4I7YR4NQIR*e403#sf(Xv_q2Tt4X zB%O?d_P_;>qMunl14YoW$Vr1@dbDmSnY9#XEAMcT^@}VadzPhr3@`Btf{@jwRf5)F zO?(5b*>%xSoOBYHlQPzP5QKw~z}A6|2obdOo7g`+Rcnw~p3769y zCf})}>{q%&(CT-FhY*wIEU99fZIWpY0%mAH{meu_5$!aq=C$>RVxwEUPKvXQOTKz;IGfqO ztkjMh%);s>_Q>!avZUZ{`?=|KeIUW67Y6w>wdb7jgQUZNe1U3dG;)PWq-zE3X<9f9&}1c}aTuUxD;YlxbbxynPe>eSvmVuD z;5j50YveRh63Iczg80CEYjLDoiz6*Lr8@*IITmd(rziG!kmqe}AHFil1W8mSC*RO& zIsqA+Y6elG%VMmiHQ?E^2%{i30e;3spl#)V1GZ27mXL!$159zr49JRhVi-o~*5G2l zox&DttjRnMP$hqrF=TeBXiM9kHYJjNS;Dl_F6d}z!JsqOP;%X*CElU|Xo0GfMvYN( zPFkoL9cxHg(VFMYWwWprmWH(*&|=0REYnRJA)G&tCb>HAkD_fUCy>jG*kFs3aO=gl zt$^JW&^fv-F_izqOL6RWS(%;fAzh9=&6GbNu1vCO zCok#1`M4}=YiNz;41D<%Hi0LL=kzz=6`$y^^~odgBlR-YWG3n46*Pqo-ZfQWewELz zW^0xVm@~8lq$aZoEh9mP;~svJ8Dw{}Lf>{v*n@C1d9vI-e2vXyU9Zok}Q=pPWDi_@x8;ko@#*@o1X3b%I`n?ol+8$`x z&S07v8V6+J7jnyi7wyK=>w;O~Wep9F#I)Q;e3UM_)f~H|1WjgS2a#w9mo|JFt+Z(o zrY!(xsO)r&$wx!W80;#u8|f-j2=Gdrv}j5hEfM?f})5h58TuLB+G1uch_ zeZ@6j&+q^<9PXymdNRMmSdf8M%ImgLz}c3=*z;Jo3{yxx?d*v7>_+Ko9I_^am8yLm zJ}d(R@hp#8~(EGFxukGPOdn&6WnT~6%pq~ zvZ&+qtQhZ<$fWFUxA}6E0g1Gnck-R-*)P!UXY?C%%&D?tZm+}?+=MLzqc)?FI^+z8 zUuY-Q%Pi|BE{sP^_Pkw2OOeU>8s12^@JCv5vM+3C{M@L-?vE;Jqt{ZI-Csk?O^_Z* zZlE{ZtD$2CFAl5B$(ve0+pvmMA7-XQQLLIh746>JWd=mpofZT%v}O&J*<(DsHAjV1G?1FzR#P6) zY1+o%WE=yQa&@;rN$N3tY6lEbB35`7k>VO?kM#&U9ELKx?Jn#->-LgDK}l*D{Sf1Y zly%@6)v$SY+mk7ZNn$Ar3UfOk!xr)McKBCWBVqP<=CfFLpN~7YPL+*K;?7F#_+u27 zFG+{YFAp^Hj4hra6@sTj<{PWcpu)EYZ293+L62M$XlXFfA?b8=Sw3AMzGy`42d-sX zwv}WhJ#ey`P8VH~vq&1Rg9tWV9Ha~&o5~l0Xs*zw$z&9yVJv)XmUh&+1+5{JJ~kT* z1ykzcC9P*9=5VybPx7?co2&px22muCA(b(38Ye{2F6B{6BV2@7)x5(Hq@%FV2q}W5 zgx`UVNl+>z;d`L16D#~sfetXErF5StEH)%y@TdWm2$noI+IEB(@aQh5_XJ6Sq%GJ? zlPuK>?;u)rGE>KK>=v)ixTWY5bSIk+J1~)b$TwxOgJ}pUfTSD4vBl#b+Eq-{)BP2x z=z^(gTDnOhwFX)SoU^5Yj@e4~LkIfMRKBK@-Y~^bMpQ;A1ZxeDrHurMSg1|zC~36r zxn8(L&>8^_P_m-v5}_d=Sq@yj0nL>_6-M(V`}EE zgAP+PDkYuPmH90>kixVa+NwK6o^5%Of_{kcf+S-|Ie(o zfd~elmgHgi0664-jBi4ATpE)){!B?7XQs6DWcboE+0X9s!_FdQVvmH|oWO<2J>mzh zyu!G}N1kn-fe)YsCmD|^b4HP<$*>jxnl&e^xn0|XnMxOhhdYSOMZzRS%9MsDc7l!J zRh?)_?~NoIctuCrO&;^foirR}&JJeH*?YhI6Pkfu+LZ>WDW!-DBS}lgCF2k(rt%?j z00qV|x^5pCE*5lvosApx2;T-e@GV7~z6!MF9*LzxdO+vP71=3N_siAZl2hhM~rHoslK{s@)9i z2HL}x&To)4l5JrCZH{W!ovKPcQk9^k`kc39w^H?xf|@VWpf4H`BM$~>6cozTX0zeT z*BX%XzAjVe-Cd>5d%Q}v(<9wZ(sulc(BSrV__~YaZs6bHYc7HcI|kA*FB5>0)L^qy zsqA(-tj;qt)QSiGvw9;_wI1eK%-P-T@Z}n5u4o@naCW>~5yK#u0cqHa#_~a)WF{ZT zNoGOI_>D}v%%6RA^(l&cer?6{6qt&-njy3LhKrtC<`NqoFQqA76Tb* zn3+*82|;p6*=~?@*nbIKN-*L!*{wtj1Y%Rl1;tHkIAwJP{DG{-h5z;!OqKh--N>cUN{gHOMSu?A4f9#rAPeTAbvKr6| z<(UgIwV2YzazG6xsL_2u8l+fQsx8`LOp{Mu4V*g+C>ff8m2}vlaF?WUIP?u#mSP{s zbkp*IS==tLNOj9YH@pRf<_S%zP%^Y*DVe6R)Dc3f$lbD=s&3n@)kwG7t8v`Ww4TiF zC8ekvqd}2E*6pEbPC!Xu$!Majy9HAHh@k|hMro!vkjPf;1Btvrq6Ej1_gy^SAg$7# zj*wQ>sjB28RS8x#|3GDFBy~U&`aEC8!Y4oLw0Ig|Uj&9H`l4kbwK&Xy_^8#bl zo-mb-+d7iB^nUmVnsit+hI)g6crU`U!hm(q20`S4Nq`pb$xJ>rldz9;fn@e2^JiZ{ ztN!$d@tvX)RdSa`GLm%o!{H~{LH5t+15*4ZRzVs@lYlbN>}|S3$Wm66KseChmn`e_ zi6G@o5@#zpV7SPT9Y_u1l+8fL@B*#c(hCf9HSUNkpbzP?BPjxe(JCO`9c!#W{Z40= za+z3#{9uaRsUTaY2^|S?vo6q-VKxO)=#+jDw0(JSmMTyCv3*6KkSKknX9O)zlrjMw zVC*OMMOb&6-(FznHA2Ie;En4`@ju%_jww)|PS{j8TK-fJ}%( zZt1sZ3o?yAxlK65SmVG?w9U6$5{*F{oxwAQDiku3UD4qgvwZr3qCL(%*-5pjC-y1H zS-PBoj+V)0IxEO*FH8t=?HT`H?%A!^QYlw{h(ttD@+1pYr7zW84MQ4B(c=} z02$WjG@BmUi@a($og*@v_V9&UDJ{{8i{yZhVy#jBs;ubXfF^fR0bI$iLOfBL7z&mKPc;q`v; z@QaHVdk|k--0rXM7b|?U@O1Gde)w{Kck|}a(6!NUUVKm2^PSZy}q?BVBYFwVYxiQl&id_~89pCJ$K$LRNS{Jrzv zkMQ@I{w4mX(eZBm{3B1PgmnRr5%U_?MnzQBNWVK%Y;^YAgF8+QD zMt^&MdU`zWCw(TmQ89^yC5fSl%eZ_4EBL zOYg5Q_a85Qhd)vA&GicW7cBFzUq|X8AH0xjMm=V);C3yuH4<_*iWI z{^IuX+r?RwJb_t^eN=k!zg_MA2W9^6mv<)^ zm&;F7#T&D76-{4W1gkfn?4K$3o0ETi@;{*h7)7W6=I}r!!KZjQYIzlJ8{&t+2YD~Q z+~2i~HM)%l+c{32!+<35c+kw~LF#-J7fXi*HUCaZ#*rrOW-| zRvax}-&|eayI-_Gnbzvj;sO32Oko=Z;JCn{M@&U!R_qr!Sw2O}xA!ON#RC-l^+(HB z7gyK(;mJRIwEW_Sr@tSOU%t71`pfGdKEHao|LprA7k~ch>ecI)`?-|yZ@0+1zrB5W zee-OeHSo8V{^Ezv{&Mm1DgX0nlWor*FY&`V3p(Sc7cXD_uW$aezr6ngQyzYf;U7{! z_ceeP(8S}%SO{eoFOmJ}H*c<9-bYsjDVaY89Aw9VcCP$Szq`G7{q*kj#Vgi+iZuP4 zKTuLnpYC7ZLJQB6vx{$TLa!-$sC?;w&cKw1Ekm#)(qU@O>M^eww`U4Ip@YKeB^# zmq#|uoJj+)n{=*^HpMkZ9;(N-AhSpFtWL9F(wrhxYg!qM*2cBFwM@s0L+C~oKV%*> zndj=0YIolcNQr`*h}k*i$6NrzKu21HzLlt5&ybud7u`rkcTA#d?kfHn($Q7Xdj3qp zU1MY-j8aqDP>3(5r7)s^Qo#}%tSr*q9uVn2oTz;<#z1`tEIp7rFwZ`bdTN+z)JzuG^?;by9wO_-JA;MfP@_+yD z#mhH)q1{mbIo^Ae09pU8sl0)LVx12PpPg?T)+uETudhegusCQL9Go7)YKp=CdrS^1$6R0D^%}!gQpE}@EG6p{Yzkw{$5}bba{eH(3|C->2J@mrLkRp zDUS*tbMk<`=@xDW$6}V(3l=(GK7l_zQ#Ie5tWj6wPR*1|H;f=KzVSgS*eAxEY1|c2 zu(E-@1EzQgUqcK77Y4=bP$q^PCgDIS7bop>otgmc;`|bm;3u1tT{7LxYa23XU?V=X z1a4TJhH}%~LG_tl%`uSXS^6k`z&uFus^dYyTg!T~B1s6WM!$GaCOn9BqE9P1(OEr2 zLCHmWbWQ0^SBLUiV&N;`7>`@tXUANb$lAcsOzH!!&L_r{EF}yTR26|hEKM-wr^Voa zapxT^HR+oAPUj~Z92;5Tc-e-Caxm|u>BdauzuFTLP+=Dv?Bc@Z!J6X9MAD%UyN}2G z20J|(1;kxSDLbBxYiO{_$^@#+Uv$_KzfuZqV>E=LgCH&`5ics6l&h53c&95yn03=?*x40E6% zCuUbX%*!U39opF-)Ig<8vVC}#u2B+=g^Gs8K}YG}jpwMMvEUu&sA2-*zT(`J$8_|a zC-S1NAsbji=*hAx+Oow&BV+-X;|q&wD|7;PWfh0YK*I>Zsa1+8PN0oV0A^&BhKUSx z%$-0(J}7Vd0v+~+KPYGX1MM-L`zZ~nr8CmbuH)CFT^+e@NG)fP4sIY3s-?IE&6(Xm z!xBLXG12(>sfg&Qi4X(e5XM&m3v_H~DV9Ue+4adR(xEWGBaOA8K>#TwQg{~iKEqh8viYvI~098faxt-Qpv~ttj|`Zj|;$A@KngI0z1O zOXd*K+!~c9ofP8svr} zG!0OI3LJuI(o~UK-9q3JQxcC!cs2-}&Zj_fpaVofv;G2E_+9BKK^W5l>LD>2AYm5^ zp(2f@T(cn1B#r){$XjHJ+@{0!oZGG>veEN|f(ANsL&Ww{NRw?O87!AibC=>eCmW6~ zmQMsNf1EzkA}gP2n1k{SV?x1l$wbKVdM6FZPt2msBoMBQC;+f*3|tWaLCYiqK8p%)1sUdSEJl~) zbb;LLVOf75c?pClU!%zWpaxwkA_rkAN(k8~E(dYU34O16u)o9rm<8QULBv2?k6QVs ziG>%%ECvJEH)mO$=O41_5p5H6{+#U~Kd~6S3ds~rZMyLSOVAoCLQ;1G#uJb+(19ox zM8UKL71qPb$Bx$v!j9mY_?p9hwPKJe9;a)GYe#chl{|T{*Se=;V$6p6yYak*uRdYN~{mYN+lLRxlnn!_~Y`Q|K)eTL%_HE<4G0P z8X1Nn_MxIMYRHNDB4Sc3#z#yFf5kSiVyU*c{`UWk!dAf5cEkjFZ7#5cFE$nkHL>aR znBBs9!jkbOdxwbg49lRGSUl73_a|67$xK&Dy}rw(TIC2iJb&W?mk4%I-#u1~0Zdrf zzFXXXdvU+u3Ss;d1@PkfXtM~y-B>Omi>fiImRvL8zg#mx z9LU`lOhT87fBqNlOYD}v`yHenS<=EH|Lx7~38tNBn*;Yzj=FXYn9dYn6LVk86M~F) z+lerWrD9PPBya??EzG}jLXE|hC^{r&tQ18HyWEaK5M(w9dy}sLxn6|-VNF^!tY)Io ztk;Q2M#=O-V|Ky98Fs>Ad6j)>xHSXvh*~{~WHF?5h6h^j++h=Cd$XU2L;3I6tNNy(x@w@t?>3P+*zB7-vJQY)oxhD zCjoiJG6o1cc1<$3K%toXxgcyyt{fz$f=x2RsG+dd?_F^$-Va2y@2MLmBj^_E2|qij zx7vyHurf9jQ@;bQL9#j|;~yGHcK47*Vy)aeduQpMsc0K!KU7}4vM=C0+EO6p?4!1o zeOS5Q;G?||p41}sS*w;sw5L=k9c2%bqa^m)(5}y-nJiL9!p2`X|r6)}px*w5D-W>n) zyNFC5vDP$wy!5Cn8JnCKdBl?xbt>bXPmIL53>^HZ6C>Og*RhiKcw&UD6mRe8#K?O& zCBn{{u{a*652r-7%b)a=$m75NQzE;ZORn)(of299V(}$U4=gUO7nsCi=7&iv z|9iQQ>FX%)XaY#iHt@N0oJmovJ3jZ(4?=X_MO%ja3#XT2*8bb)2z?M-Uf*!G&do#k z=jF?*XO6C75{vUF%7)1=12Im15j$h@%ghK!t}k(7iQ(4G^~a0XNM3E0I5ZK3;}8tb zxBNMNxX1J!Q^qCF!(3cH%Xu1*@i+(02|ZqZ3|*|33`DTf0jcn}IPP?ZXnc*}Q~?{$S1ApXerACx`N@an z_XtHuzm7((ZbU_%_tYka;`56)FLem0wvxFHn3mwB0X+VI zSZ9fNXk6WnivUf93J#aQumY!qj*;hJbV`Dxxp_7tv+-W!y zftAz00xcv21S}ck8@U$0y$ie7dd<#}{M~CtmW$IEB%$CqK+DCTlF6RYJo z7*Uk@&PvDlkj~bn8;|YM4ff>D;>1$3vUq>{!!J0j4^Bzx6xe@R+}*sA74C7^?9GdB z?|)d}ocR9wj>pfiIE$DUT*?%h6H{L=_d-UjsJ>7ZIlhkEB~jXoXWBI z`5(T$x%hv6-c}Wgm}b3G+2%k0W%27bss)xnRbO2CcyC*q0179~&{Zt*P2(^gN3U4t zo#QYpQz_~i;xI1rzwbDVtrTzXDGqz@C->R$! zDkj_fV)6T%XIIaEU<`wg?`)PgxGr0Du~DS(Cfv`^XK8J5PSgQwN(ZWUz_8i;-GY4Oex#uYxzvf>pBFpjBJdvizn(PZ^U-L>EmV&1CIWedq% zH!e80k(-KC-MI*j_>#pz2K}lG-%Io=+uXpgHeG6Ya1Vn_)I|(s)oqN-J-Loi`FS5h z`D1qe2iyM9TN$IH*D4&=@}KH*#@D#$QMWV1B(7*s9u+xbSmG8C-U8#laU48G>LkYa zRHF{JuU^LKYeZ^moW73QJVnCf>yg4AoTcJs_-H5jM;TOWPtE0>w6o^+j=ELm;&MOT z9iEZVguRG^cQTsMas3DaGjN30_uV<^0}E2?ZKDrP;t)adaKp!o&T0i~P#w5hx8XT` zXc7-2Pz|Be$?kTDMoU|)?_(3d zZ^7aXJRU~D&K?f%>3j)k{6QM=4BjdNjp;pU9V;V^y-3pdhv_=e%(rH>-BGkpP?5&I z58tlU?h$Ej*%5rXVN><O_*kqU-fRYnB9rHzEjmSUzU3Y@Z2 zB7rQn*h>y>qC#x5>Kqws!$wsl!=PlW_6Bh9~yHq zHe91Q7eC}ZOvk2Dq8QWW1@A2m#)%yGx%I6>Dz~gDHfe7x6m9B4W_lVjayT+Fl_KstGI$2 zc5(`dgTy8)Q)6P{!lWY=CMy1;@D3krg5j|;wM9DAkTj0|Wqxk^@e58-Jv!dDHm)6w zDYa=0rMK9&j?#y$gC>NaE2=z6b-b9XzCf*!gY2N*m=sA-6u45|yag8~m(_zi39hPF zvMXbA&hB(77hAT(9H>I=!88GRFJXX&pOxM zt+Iw6mZ#FS;&Heoc&!a2(?_Nc1KF4Le4*~N}95Cb7`+sP_yuzcA z0I1&C(&aA~KmY3G6;{`NzWDS8i<(!L@p6Dxh9IzO3S8KFEu5`vwNLgH6<8gx#GpK4zh0Z%58;n1Q>dILJI^79mL(lAx^9|c+~-X z!WQl`H5Mjf>6{A{+H5#m;?i-fGI;j{<#T0%3li9MeRU(L@vJBu%kueEY_lMv+x3!1 zFa`sacz*DG*YCLfuB~qh?FVe}z+u*+c5XiXO-7+X6GF=MoZ#ijxBHAO$ZK=ZHDm;1 zjSwTUU*6o_?qk1=W~^Rgqzz|cM^PqT$HN6og*UY`JFHv8$lw-71X$h?o!KHj9P>+^ zqxL1`ln=c7#vv`H=!n8bF>Qa;Xs=jamCS!dXT#!J%F5_o}T38;7y|^%9#C3Q`yUw!m0f{JTesMT6L4X0Mom zqxX}fTS({S#T%ULAhP`9KUz%F(YxWJBA8+gqnCTojiqQfEuVag?!MYzT;J8b@F{5W z^xql>&3^2ukPt&{DDj+xQ1cHbJY~Z5K)&$e#YAl3c^MIBG1rKFmB_2_k{LFNuzTZ! z5kJ4U{pN}XJrEZ00642b(2PqDkGTiQ!xcYYyu5+qk*;9+JT8Gv9tbUJ!}g;72pA!N za&UZ)OAuu2@(o{2;X4V-ms*^Z=hb>3Cqrxco^pb#w+|gUp}A&IO_TK3m2BL@Qfwr_~jY) zOyjSpBB{x>eeeRYwOR4_jO##J%4Nm^IZv2a;4l_(ia_Qd6ND9BETB`YKI0EAkaLjT z;OQC+3n<}L-=%Mn^{=+hnNtY4iGRz@Ob+-ra_~Dmg2Zm`aP{HSFa8C_DmRZ!WXN`h z4etHz9p6IOStN7Ya=7aCS40*F^$)h?@FLB7k1W)RC-8XR>-{{a^N0W74_!0wBSwYXk{S^Z*jV z=;mcDz8bxQr3_Ax&NSQ-fQZiMGrnN5T7FBI6YOwTj^Ma}lfBE4uEx>w@-Fdi>LqtL zo3}kb^paRD?$1ud38vT?R@g!6i4*{d@MgV?0AszxsW^004lm{_i2LByuAEKi^9W}P zxoEwV`$I&6g;_fZo$5jifEnLTOU(S2;8iuk<#E~BrQn5-;h@%6`&VEC_Xfk$@_5JM zLKDUH@);(NcbaBC#`Ngp#s2;>q?KED+_>YrTH3Z-VG9&1MCb7KSk}SoJLpYr*f9-@ zQRiR>p+~GOaa#>*KCxy~g_Qws7#*wztzym5m3JyY3p>1{ffl9}^tS9UO*q5xFh1D^ zu3@P}bU*%;rp4(g)c*YDMkjp!ZE_w($I#*=2tp=CGa;wu(1}izuwWf8fh%WD?E8Fk zace{8@fyDbR0Wz!W|}~C%YP4se4BH0Qbq=8{?W{Yf6u$oJ04gW@i*6#n5YLE&*FRy zwvpdFf8O%XIy;u)JWew~0<_G#I%P*dkFugHr(`8S z0JWsJ!dnX}t!l%F4oWi_x0_M4?-Sg3fFb! znZm81V@ySIm#L_>%M@PlIwmPxq?>07s|&}NisUX+QEitgTnIbH6dt3UX9};_9%Cw! zyG%v3U8dmJjxfb7f?1|^*l{?*l#_c*x!NvMvCA zwFsrYULxwm(g-ISbWh8dcLICtt9`OM$Jz*kLj04v;itojrsF{dSD5d?+v(^igYXEh z9-Q%0wYw!=qGN>5Gf7|ZbfoI1KR~RAmnnEhFEzW4*D9=AEFxhu${BbC@nF`l1r{(} zT@RriRKNzX0fqW!imz~65F4C$b_C1gD&E}ujKtB5W+t_1d6*4NHmGT}LJ&q@e z+YKt7#C*@EJJrhj4kO?9=}s7U2{1#-)f%@uKg5&>sD8>TcbmRt=Sxv%8;1Cv7V_PVy;~6&WhcLETKEQ(V+42qn7lH=V zE1a4;%Q+u8;@Z@YjvRllg+Lsyzh9tTAHwH>hKwa+u`f^IBa#E&&>E`l(B5C%ta-K)s!0DKk%^>ZTuVI`hb;Vl(Lo!Dd23K=8B#WfCjGQ)Sn8YBWn zu0bM(eb1|_TI8l?a?9vTGK4!O+UvNxzX6vQ&$*gV>!GXQ1=+9+pg1e{O=3Ot@Jtq> zVr~|^OL*%DwG-avanyyeOw`Eu)TbBL)*v99Ab56njFJ23X zn0|IGAPsst@8?PZW_X7a!&(XGM>1Xsm@AwM0gBD0s}qd$`y54TkE3IY2;hjz07p1- zG(VBi770fq&14 zcZbsJ;GTKy;GTKy;huTz;9gWcgL_e|hkHY@zVy1dXO23!7gguVWiu>Xtb=<)u|7xL z)lyg8!M&*3tC}sSM6p1&DZCHG`W$taN?r9l?yaHBS(sx&AKjW_GaRj9KrUNLeDX@M zz?W6eqnoRqf|-kTFsv!o=ctEaS@rxpEUTVCRu-E_s;1ZxjygzHRnN}Dvg!#^WwCjr zYKk4FpQ9cgB}emk zc^*kQA>M0(%SO<@qVttN!c$8JoY2GIsP%N z&GdSIe1$Hvx$3#;k_@Fwm8BHpzFR|sc}k97BS6<+K_)|RP?j{DI)g5`QB^9%A3-7) zi(`|HI@49rprtc)g0x=W91Lin!DOZL!emy5;#=I5M<1&?(ve%OZL!>3tuwcu>?Jec zH5MLNSY5$(-@qvM{@hP7wnbEi?hlMalom8tU{hgmoDT3hqZT`vj>E@H_vKg9>}Yk2 zCWPlWkuB;A+Jtnd83a7;4-t+^^N zFmSEVnNO!SCJwNUp}fUMiBKdA19g!OwgU;aI3>qK!9)_mlr6qF0;;I?=ZD-6*0yg^5DT=Onc@X6e^5gEmZMl%g9tR@|rml8=v zV*&J}W9Z=E4)jyJhu;`_3a8Q#ayXDlx-U5-%P71P6JtP!^BSZbM$*vqeFh)7#loec zY+drH1E__MC2c1vA6yWLWH7+H>tlq*~)X0pM13KUUS=m5K&dhHRs>XtsQQbi# zKA}RE3u{6b#!N>K@!!a90aTw_fdo{xj8R1697R_R&R-0)<)g-Glkam6G7o!)6k)6N zHu@?Bqs0eGwJEKK2YlR^)&v7Zg}_k&Iqk>ZRC5W^MoQBPB5145uky(uhOUJleKsA# z$eM?cLx`c9u%cjbD6R@eO_0R{7P7+hoakg*!wicEMj<8GD{OJ}*a9wkBIO)Ul|r85 zw-z!<9cL2c<;5Eu1mNUH(aRcy{I;VP(y*bLtQPI)g&${SvZEK0;3=aQzPGO00Bamn zq}dc$rz0Y%iGb~e&zxf{X7qyZvueU2O|EhKfZfeGJQ7tFco9{5bqmtf2<7n;PAWiC zPbA4nk?^3Asv)+7PHTQbB-)C~vD$$@ zs%;z#F=xRkzort&rX4wD&v?Z+qyoD@S4^YlAsM{Sz$qXBOI-!6saes&-x50S6jG3> z6WpGVh8?}E@vgm!r%FMybw7c^WJ(TJ8=VI&ojH2Jt38^1W%%3BU=rL%db(y-hvF5z zG<5Vut(Bu^GIOgCMG=!O&>FZL4XvpkX^6R8Iceylq8GmAt4V~T z7tS=@L{X8MMp1O_ocB6wC4My!xnK-1oc)pQsc(q3Tf6} zB&>+T&cO~Zr_*$Y>LRKbXdGLuw(+hj2~A1X+A$ou0kVx=hz=0!&~4sb0+|v5(8$Ie zy%2~vBuk=+TlT_s&rngcI=HjP9BIcpP=GdZk1 zfSz;=op21rd-#nCSm;y+A{-8qg^vRz^duY6C5)RU#3B&W4x5py{V-;PKTtlKK(!NN^RQmi10OmwiMj$fvKIpx zEhX2AZ^%{nHaD2XITV3h>h9Lk^rIIBY;X?97ElZB)SX2l|q66c^& zkf;a}WksQMG*pEnVtI^3RK_?`5W<0h7C7WC1s8xI(1w&|n(UfR1%GA;U5c)n4t&Hj zALgEl4I*aW@%1qDM7l#rJn(|b$(zoSR#bbe^tdcd^sN_NU~G7ab$mj+z3Q@w2R(k| zRTsXD0%!J6v^(Pg&u^gc@SSoXU=nD!W~ zk6#;y7T*7T6t?o8{ys|cs$1SiS#Q_)mcWNM4u0bMDBHj5`zV;q1CIgo_%E-xG?!5J z58?*M`uNQgc+{DfecpESBpwpN6y4ZC;`oV1yULnaEZok7#70wEmSMgN(`}|_ZYVsNn?u#JM z;(d`gZLbgF@Zkh}42M@q@Dk4*AB*7gF!~4wbA#o2fiBPH; z3@0W~S@$J}Sw5SG9A>YoAkaR_r*F~*pP15P;?-V5A&30`m7blzJfe{&CRfe!qbC_% zfim5NQ61)22Q4)UnU`qJVz8DnTR}Y}!IjpA%`umQJm$qYl$}$1)5#8#QGZYE|A%hn z#Oo0Kn>X+JMn=?g^d8NB@aq}f%RUF4-M{lSqq&;(X^+ zYjHiN%aIO%Oe>A!JS=;RBQ2Lq3!5XXlA!PmM@UHgJm@Bn_rv8K*%3F>JT;h+ky59E zx7Lt)Olw?-@7mGy(5Od$=g_EM|B2KdN4-O%S@ry(QBHF{T;Abg;#96NQ|KLh=Pf59 z#{9weo?MMT?SQQru`ARb+Z0QX%8{$oF0Vaw%c|$m%~em)&BcUYU5+~FX6g0N%~f~M ztz(tMtpm6_lwJq-+(o5!r5Cl&c9fc)KP>OtZqvi^HjvI?`KDOk_Iiiq)Ar^M%e(67 zVfif9!9B~UgL~Fz5BIFk4(>(OGq@MUdbl?fJ0c?ldb3FEs^@Xf=kTX@6n)0NGY@Nu z&2aSL@(#aIVi|Ri$};NB!z}*JCF-ntf>c>-9;upQeXaH8VOjM&Qf1W>V9H|ic+?a- z!chm0vg&y}a@A8ja^v;1o}gP6n@6{%*b$DR(#hN=tDZ-j*Tu!VWYJ<@?g>P5e>} zJPbOG#Z!7yXf#J1Xf#JkoebfWUJn{w^}9l&+d2Y`uCN1*L-`p2B(FVabk+0FXz5Ln z&_eG4U~tp{Ky%auKyx$?fT_XA%4mXWDI+Az0k37G z)SiWP!7Mm>E12Qf;5?Wi;Ru)w#byj@gQIlEz|2*5z$~hs0kbI91GAx6pQA3Ax$1XZ zZ`-)7BVgtVJ76}HKf-I&KAlx%)$?HHs;6M)VjVCWiXGvo2WGDNUBS$49RV{}*a5Sl z{1IMzVCJgl!EEsH(Z&p_Mfo184aNGbby3Z%bx^1%L2* zla3XCc%?!oy?NtPw_+d|9@hrZ-t#Ic`JPup>p;A3wAMYZ53f`}h96$3`0z@F%pk5; z`JR`bBdU8|c-ts$mGNpGvttE{cW?4Njt{R?e0ZfI?iI$xt`DzN$U7loulqb7Ua1gr z3Kp^jXY4PC1dwZp#bDNC!q4n7$ z-nHUQjQS$MCB8B84L*g0)h~Q>k>3zT5-xz^zxq@(KV*$-6vscFgpV8L(mr0B!3|3V zy3NCYPHj)G&!^VX{P6I`26tNL-|>i)*>^lLNjJ#G?|AUG9_}8>T5%5$B=0ohPJ7(N z1g+bVd_e&>0YU1PQh-s8$FE(T)qzvc5bx;psS_d&P5F9{mc-Yo(q ztS7K?9n&AKpFWOv8g$Qaa|#LRilpvZ4y1~1PUFU;ULbl2>HFel(YU_?H;*T)*wBVo zXfa>pUpo1?#qk>5yd({d22v07kajb8zK!+x!4JL{$#ZO4<6>=iJc7mJ{g2H`dLMFQ z5rLVrGLXDiJBs6^BFr})@G2(stknTtWu zkb2aTyo8H>g|UPHNJm|`{){^~AYB)}(nA`zdS!LEVGhCZV|0pzHv^4Y$qVkoh*fkw zNV?s4KOkrfN%phSK~pFeL%gR2nW0!#x5eWXl}ugwl|?tc1pqs@n5DK-#9*4FORH}* zg_0935SHS;*%pe{op0VC26~X0cpD5R8N3y#o8h?8D}%<1VL&`&hrYtvT^vFnlEC1j zIt&1s8itNgYD47*ZHq7377x*LsQDd`4KAngw(~$srKF>I+~{U@KR8mu95K7t&v9O~ zULCwmORe;fsKwah86;mh6DokNzhi( zCz$RT*VOi8iv_i|)q-Nu>?f^=)wq|@C}iNY^ykjFRHUFsxY|w2e6}KShPvV zlJ)5wU>YS1fQSvjf-rmoTVk}tSZd3rS%jj%L-bY5>G4#$GPE-48|F+cbC69HkNVmc zSmBrf)OV!(xNoWtTRP}KOvX_iNEpsARR^tU0tOfR4iZ}Cv>>cHX^nmCdjOS&5CL=> zFmCYlH#Ed4NC+M@WHAIJ*j7?oe!qyX>Zv}pjJMEOHkDRnxb(;4fDxo>$_eOWxy_2O z@Cjf1&HfO|!2)J$VH==Fkx* z^1Y-%Jp(E2Z2>7XoLmkdt!f=0l4i|CIz*(Pc#cMsQJWEIj5S6#VhSXDO&MVv*$ESk z!c26a6p1xAAc?Xuad5pAFE+Gbk~H|JSxNAm0it` z>RSa5>?=_sgA0qIp~vweElVRgLY0P;d!a?DIuBP`Y*;==F`5S*#-H>!UgY4=xT}#> zbeJkI(!*BXa0^8Dz%)II7q^&1D|^O^Im$CW%wb;iLA;0wo?(EB-GGFwGG4^wvTZw0 z8&&2AQc4SvNsxx4NsHm;H9SHY6luyJWMC1BYLjkRio_{ zNcJK_6C+neE;J|(J-zWq`x(cJM#PMZjF&ZY++s$<$y3IQ#$M8rxq-Q%D?Wro*j&-5 zhIC9oJgW^iP;=ZcCXz9I3S(>NgLo0vL|kxXbYR3J4WRO8q{RxYhiI5x!3&}sLe*8$ z6jVma@~SBp``?Ne8#-(+{B=p476qNBQta*rauhH6?chRF(y;RcTTe6!nQeX*FE+G> zFlp*6mI=dn$|o?<##FZ37}wPH#_=N4VXFnjw&jW!Npo_Y@nS}`2gEo}48>&gibVW!$kfV5!0~df7U9i)j>D$T3 zJJe9H(<#x|DV5}iFw}Ym=H>1~4|aj2CDLQ}KbjpNM!`f0PHhLz3){m?n{#N8adLr= z6w`b)xG|1F%KHO}G_%CU6Qf5SFb+Cq2S6GO8sz6EOq3ki`7kA`LoBLf&}v(wpVfzy zkshD}M~;llA2g~XY@F_9>INjUqhLjmCZ`bW2k-vOFpiE;pE+%z6gXBeIf~M)P!x}h zSfiN6IVKfEEZFu`?YSo*cm1N!niYl}K-8KXP;{6KvOf@6$VMENtir~?u~3f@;u<{y zU+6dL!>~rej*d~~LE{gmYmS-g44?yihQiTbSC8gp74liMlE4lYqb8w{;0_i5GKHs} zv8d`Ast&$rztt{1`FzQyKdh$S7S{99!3nWn!<~s3V}@_6UnTwFTL2u<3iSB&HHHW+ zO(yZ-TL2J78Bo4*kA)3dv0uTjhpzGDF@*TxTL4%CqtrBYfRy4TXihEgGijh0hause zPrk#@hL`Id6|M73AHD^E`BfqOhi?IB zA)jl>L~Tu~xn`9l?2@FyoXLy+hzgq0AHD^kkRl)OPmxJ}A28{mGKP?`9zFMsC-3Rja z@bfizk53ak{CvAuA>xhS&yWXaah2yBfA9P^o?eDm;qPSO;b-69|K=-og*E@?D^$IU ztV|wp$(qe&eFxz598+xOy1T#KU%dL+M<^ffc&M%ycOR|r^}S8Wgm2;=eDy-XAdVoz z*s;@$#WXy60Rb``*Q@aq>Fo<0L`J8dT*mQbe171`cR0TMhZC%-E`Nz<+_%eL^CUA~ zb3a+Fm%li9fN(SZetiG!;l3U4^XYWd@N)6R5BJ~t zr^Tly55NbWO=pJd=lffh-d|ttKVJL}f1=`>>laE~{3^2UFD}2;4I6#`_;QEx++JT@d@MG9e{p;H?cyv-o?wG#xmcfyI$fdSbL_S3mYdz*^>+ZUWP{Ow zeHE<5<>~WyqhANnv7#zXesOz(^KFo9Jk^gk`S0J{Uh7o4EPL_fIlduK0J+1ry3WpF z@z~ytit&Mg%lOK`TfY#1CXtn22yo+2I2NpA3y+pBp)*qZJ(#$=zu`;yn8_{gPOv(s zj|BvM1nmYe0aswLmX8*u74X$1KH)Kb(qF93Kk46PHQ)4) z4AV#X{VCBttM#aV?1D)OZC{ho@vHtJRm{d_UiI(uiruS5tViDUSM@V;t#|!HuG1O@ zBZ$3j_j|1Wlu4ga7mf@w>O)74>fbGN_5aql{k0zu9~rTO;IRAdBYrFCkIO%vEdK4} z$)5lY7?JCBjYv9>1^zepF8uDZ~vxO^~rraVNdrdTO4&>$ZHXO zb8$Nn5zG67Efi4y#sB)e!JG_3&>_WVH~N0c;_m*<^XG!gw|~xnP5(%-{f%$?V~6Z) z=1uku4)+%H=~({31{xt>QHP;HFQgVGolelK8J+7HEZ3t^6_EyBGcOgVX4 zt)D@UYI{t1mw#H?Orer_rm)y?jHyVTR%@oB+AdSL!G_AGrSp-09YJW`O7RQoJlS@P zsYsqyYo>76f;B9(w(a9kxgwQxyw{k+m#ge!~2rrcHS&g*wZ}5 zl#_c*x!NvM7zam~+QR$KGPT8~{xL~Ka*ruj+hq#dP)C^Jv4dHrcyQwgQ%>$N~^s&*meC==?1%9Z0oT*1-nCbd#Go2d#Go2d#Go2d#LBi@y~&Ux?B(SvYbG%r*dDx z>dLT(dOaCVVen9fJv=nKJv_7wdw6JB^zbk$pTWZ@*TusuC%Ej%u#1Ogs)vVB`3xSq zTn`VkTxT|7Nd?Sy72CtZsC)(wgQ+eaW;wxSS5g79J*IkiSd&|S0nIqo0!xG*UHFR- zs|SB;_{n4N=gM)aY}SQDo3<>rmcOm#udmB%s7slX=#)U6!>IoH?&xvW4l zze$71ZV%*Kc@N}VIjraao;yCDj8tSKb4;sC)+GqFfi` zvfMn#nW^ri&y^!0n}ZR5O<{^{{s==4+p1hgQh3Aj2)1SA9c**uQ*3j&9=27vj!gwq zJ#5R$JJ^<$PoONzbr7t|br8%+BF@(EyN zxeiWMxsIWmsSZwMMGdgHx`2ic?vxgHu)R=;-SOr&)Oi zr(F3Ir(CXwQ&sM$`g%B(m3MH8i}a)5)Y}46;Hp(;?=18XtSXq7p+An$3r@504ubXA zokH3nyFF|(yS?Bvzva+bcr&~29Gqrr6R?}G+d;jmU>^07-45y{yB*Za$|tCopZ@nd+ckRX&e;U6oH@a3aGF9wxh;d0VpE!NX*?gNHqKrvQ1#ZVxHVu9GKIb+g+; z%4D~Lls$H*(0RyiZ-FnR+gadC>2~IN$!-Tjd+bg@^^n~jx~6nvWw0yVPN-{k-x})r zO5_w({kelKn8ww~UZ~5fMMtKCS$PLc^PXm4TN8h~To*EZpEI^HCL%Laz3E_9-kA@dB{u|_8>DWe^!Dp#KArWY5;_5M%DjViso@^lnW-MyxyMtqi*ns5U6z|iyOdOKO6SUt zpk3_I0&6kr@cFq|jUFAa8=qR^i%>XY+@3Vy=d~XlIbb(FwKh{hofN|wia(a6D`7s9 z5G#};24|9Su@j5*#lKGn<}1gz9D^%)3!aG_rJRFzCg`-}I3+3^J>mP-M~?NnM4mI{ z38eW~j(0dr3<>^q?;Otx$rJdVkTQ8*NbzRz4i^{?h2+2(9iBM zPL;mW;a41Hhj4gAj)$xuj1B%Lp*->txwk(4`~YX1@s)w|1#a3?qBu5&dQMMqHQpy| zH#o-4b9SG8@h^)n_b+e=Y`w(MRNS!l$=L^ITbw0*w8RlyOhK0yFJCTjApP>sIwQt& zs0azf!h2F3;+5ML-uur^Wpc44(o) zM1YIqz$a9+!CN4@z1+|k!hCB0%pgkgO98mO!4qD7CzJ`MQHL_;b#YwBBn|h5?0Nws zNSqlZt=wo6=lgjjKXQX7)uyMVkX=tyY#sp$R9Q>_Ne5@3bq^LjiFCcSzQ6k&b`Z9FC3z4ao$JOYqDu+K*Q>G#~gPsp6czx;fK&$F7>=w=Y>8 z*dsT5R)%scFOOmJZSa%0VVwS(unO z09psx<4E#|R1!~bQ_C9K>@y9#=(GYoi-wxQ57TO*s-jsJEQ+HiM;|SaV;62SEC`p< zS$EMGY)HrG2m!+SachEfXdOrFDFMuHG`RhW5@{g`M-wd!bO;zXM}qWNhkZwJ(^^um z>=x%j0*AKGW;qpo-)D>k02}=qMEs2LIl|o3usz)?Q zV_bOSfMSx%l#s>b7SSquz8ja-kydN2o)%7J+D1760HCIs z5q{C*_>V%ua-kBP2fYjCu*Ij0)GR(Fz2x-3emx z6_TWNznE9s)#`TVCp_1>u1PUU0ND{wts5YdA`U>}n%?=Xj2SH*KQ4>i*P#j$=j9g71=mtr&GZoShcfE(R zdb|N)V+WzB1ZE~0XpGOp7eg?t3zOWS(QVQ-(Ut~R!0+(v=0jbkr#Br3%5$2(!i#pA zxX9PBI)xXUDQE_}=Dt%*bduJz!UTN=^JDi;sT zui;McmMJteEyW~XQIs{fI498ZbPXMni{>~1r&5`Wd^O!C>tK~W#M#v~qLf<0%mpH> z*8nYv062?@iE?$MAx46s5F?~a?2L|Z;Tph8gajj;wh)IE@sL&wL^@;&nv8)i9m&O1 zZRX64g-XbaY#IFoBk|re`z*fn1YgJ?x-2(JiIQu-f;x~2SV$7lg*+@9^AN-*vU1aQ zwM=Jrdg>5~>gLdGnj#sHN*_xrk{dLeoZp7kq6-5NilB*F*6RMqWYGj^iz`+qFhVSR ziI*d!l)=G`5fz*8mr+@M^qrohV4?5 zkXjCL>z{12_E7*~`ytmFI;3H5>=Z^6Wl(hbXG3Ufu8ERi%mbwkHd4n?U@0)V36~sX z^b#7xA5>^?8sm!g5mJhA*U%AHI>e&60C|`U{yE5PUJkI=X z7DDq8S7-;MfUn+kMUX@g=4+G;J}^w3uGc8J=OvkL@L(x>6`ezVd>)I{A)F>KZty8x zwGO>e+f2qE!$YK?F%}0J&9OFALXl5uM{69hXiX|%XJ|ZF+t$Qq%6)WBi#BXs&_!7U zbFFA7^D%o6)<}3W72ty=Ls!RLV{Mqbv2%(MD0&S?a;uTS-a*LhZKwjmAU?r|T3Bs) z@P|1#>Y_nZ)BD z1#i$nwp#?p=oTCf;w?la9O9aFfy5uAW6r^F3?UC_0n8dZFc9??*eLs4Z>6d&-|f&m z05tO>T~b_c50V;5j{F@|Aj6sL-8#K zCoA;Z@w4Mmoo1b+BZh&aA^T@u@!>Rxs0YIi(*PWj^rp-jb76=kKTJfDBe!T+44FX) zE)-gaV{d4!kL~dF^RRhnNcrV@p?IhmvJLf-6jtwW%q5rwP38s~N0uP+g z2ihd7w6n0mqGL3p5A1oal5&VqtvM4~V=;$ai3ccAJ)X%Sxgsa5IGrR2YIchWg~zJa zsJF5Dz|1m;EkYd`KtqR$kj}9Jdp2W{pWaV0#4#DPw}ruk%G@4`g;@9{d$bRoMfM^? zUqBjALaC~!T92)lmr)tajcqxzo@(drau_Rk3sy@M zY@4$Z=>T0ZU0p+4L(d}_lCoq}8w45pMn{R?5VQp$iBJ))EoSM6hK=_{x2Rd)Xjq38 z*SwlY1bfQm%(N${EkTdQ3H!2XV~B;lg?S16cX)$2a_bt~F6=ry4LZON#)V}Kw2A|$FwzJ`A+U(&@|$nOH54O|#W3&$8#reWhLd7( zZ(^;m8K>5SK!jnr(j7mXB`@FzPBM$2d539>h6Dkfx`EwEgc*qe;pKD6A;^J8)IuzP zLx}Qkbt&cGG>Yi(gphFlIm)DtEv%(R75->OnH{7@VYpE6OdqScOF$}pc!L^!|s4RSRvFGyEN)+Gcj`_4~zq2Vq!L*3`C7&xVyF2 zmhl3lA5N^dAo;Fiy#@L1PgTZKk9cqrk3`}@OTJzi&p7_<;g|38sYGPClf7j1b!pQ-ih?jbv5(s}9uT%0bKE}w?Yrp*FhL0;^ z0OR%0XBfS2d7Bb|y~6X2f6e2R_(oG6ozoL`I6B9d9JhR&(yu>4pZf=RlWo0P{^ex7 zTZ*F>eCF{SXX`MV(b2laUrx9}gmOxF`9=>xp5qxyoU}a0)2Q&`naIv9_luV|clV1w z@|{#xwLbyKZrsFeTZ@fpfEJ$QrnQy(vH z(Hd6ucgr`gMFZz>u24^_E+{1Og>F4wUc^89#nrVkI`#5G)Jv7XE1#HNqnD}~Z+YUm zSUdnr%GuFbQulA1Cg->WMt}oua`1byX#Wz>?@%-;w`_hv~^StKhJ<)h;bOcrLCL<3HKAL?| zQwy|Vs0gm|DPg|Y2ov`qF(tJ4R4;0>*4e@s1l+O%I!y~l-TZv(980`_Rj4^->Hlx< zT$|)Nj`aLp5&RGR!HR82#HDX@;VO1b5~M^~lo$lP{2*>P1~Uzy&AEBHM|{U2=q zU_bAhS#@rG1^@|g*Ab+4F`eg}s#BGfx5~=QledSxYWvCV#l4OVNzux84T(+6-XYQV zT|Mim)>@iA?A_Zd3#W6Oy}c%u-0R-P!XZ&edmHD%X+OV* zmgH-_3rlf(6ie=PbVzst?ikVveY$T*^32>Zq`W;gr08{YNU+o$Lt3Jn_YFx2S$7O6 zZ;uTrdL11S%H@tBMOgQcmhvoiZ?Di&-X0rL^t!h(w3Me!!^Vh>PL&cB$h5@iqpeq; zFh$bveWkt8JA7X#=8%JX8{Z|dMg}_+VZFhQ%CZ>js4R=Yj>$3_i%Z93+1OwQ!mU5p zF)5dW9g}i7*byn0gB_D{+4n%oWi$TlWtP%xM9SrmMxrhw?9)jmp2$%;Is3S;pjF4rxsOMc+gDm(9lHUukwH|BlJO>>E_> zm4DIqQ2s@;QTbPzS+9*^$;mQfB4tee)#PCr{Cnjd*Cmn^M6%DuD$VwzD@)ytiM#B3 z%s`92hte&YjS98WY(G(zl7J%yTK4_MLM>l5F4VHaF`<_2M}%4#?1)gyzQ=@G_B{}4 z*$lF}V@bzMw=$#=p_YBWu~5q~jtjNya7?I`_WOCG40c4QW#1!0tLksxd3w4Yr?I!){Ev)n+5;f~+hX_ijH+-y_m3`yNQQY&Is{YO@jP7DE~_*-GCd z(yjE}7iOi|hzu*u#$;FyX}=6BeUHen(sy5mm1ZL{tTx+kn3W`s{W7fdJtD(O-{fM|L zgWWIg%3w#tUFo|o?n<)}aaWt|7k6by`^8=9dqmugE_Pr34e&Q22+Lqc_Mv64`vqYc z?1&&78|*+J_6IvA8FR2>He3#NL^77aj!4F_!45=af3Rb|yMoyesRL`MVAdYNfr=@E z9g&%1gB=Lb{$R(XX~8Vfu=~_T!R-EBZ4UOeyV_ESfEDOCK{IiDRCp@zb^O>NOYMyb zPa5Ch#LFQKWMvL%R7A#*#zbVP{x>2bV@PiAS8Wn1Zr4gZ4 zurwmnVo0wSYJ@EAbJb-o79gYdLY(FB@%3w!?TJ}9A)Uxk^P|IdxLaj90FVxDAMub}S{l-Eq zUp6k(vcoZm~_jrjY+p0+n98Vz6Vxa zEr4l$9NJ^0*`4eoAk4d+juH{h6g^|rhrCVus=L(K&fJ@&a8(^(qr~2i1gcUS^ z_{#{ZJ;f_a^~^Uz?D~7v9Mzun#_TBEhy;LWR%-zUj+*|vS z01xcWy~Qup;oH@|be3Pqp&hS%dGO;aU+%?F8t1t{LD($})!X|pR0>}@d8>n=QuuNY zhDznjeHdyb7dM43_2B=HRWBpcHZZDG=_XDp%U;Ff^|D5@1T_N{Oh(W9y@Hhqv`~s!+;;MdVA5-J+u16Db9A62 zo=@1RJ-Q#0jmZHr>t^!6?!KZb-=0<8>gY0czl(ZjnAS^YxP!JyTV?x8f3{Cy_pubAmb`l*PZ!Qm?wz~*X3#T9dNx* zDy4Cyrpy8r(Y#lAx-kwVl9f>xnkp2TqadZdToL+x{@p|!wr|p>P*yw7RSE)k!L3D^ zp;xN&YCo)G_atEzc;leGT@kt53SQ}|g?cX{BvBdoI7%sH@h}UKHRUwMfJx_aj#+`p zCr+|gMX0Qwx!`pg3Ep2bU;{eeZ=vjP6`9HWG$ET#RHP>RCQ4rSvu+`c+Chq@cAUWZGb`2-smP6p2Y`po%d_u|jVAXu(A18H|Av=dGT3Jh@9Ly)7{6 zK{dA>tF8OlJc>y+u+tBlw~@f7M6fzEm;mB!!LVI>CM5VJ91|t;3k;~BO$<+Yt@KwB z!+rJFz^dxJ_C zt)Mb7$ry0fp}M9s%28R4)099XpW6ecY-{43v zsEK!JAT)>E1-o9IdJpPp;KX^P$dkGg#K(OEg(hNx0;Hds>a6Y>Hj3^|tIRv!mS8BO zc$-j+daR=pr?f{aIEb0q(NHUxql>bu4U8Dm{Y-#XnURD8SxyfY=j3F=Ygwu}Eg(44 zzg3`y1Cqr6s?oDh@@jAce}Ivr;#zhL!NtmCHW+=Aund*zc51TVr3zZb=ypDC71V-5 zN;SPFoEgj#W-@$ZXaHi21Uw*dl~bXSwnj*Z3J@9i2`~ju7Cn`qvLLFq0&a#DwvlVb zeyQ=&z(GsMOs{TPO<=KC3p6`hYJfm)C+xLnr>~(^fol-<3I@Rq!mj0r79ku|ekdr-vO{1}qGgM!5yf(a?5P!*79p!@p)^s02%k+?vOl_4uPZRr zVLq#3xWch2Pzw!Ju_)~zW2FTfYl6crBB2Z+P>RAy@52!-Sc1IO+IEdblW&s%sY8*O z(2UgTqnT)EmliC9HFyd`L1<;EwTKK%_iaB2wytaBPXosyN0Esl+m@8Ws$x$-2*ggYlaie!R!qV`723r3MbsFQ}zM5(|r@({rlM{udpU(g8` ziw~fm)Bu+7g0p#Ff3>;Z`Rai)RS<=f$X740%WVK~Rq5qk%{dAg&9cPM(M;HsNl0f~ z!FfBg`PG-3yGD&FB6xk2XW`LS*xEeqBR*8r!d$KDuL8^4dcEh}*2~=3R#J4<8GCTE z=Hjsz(DQDMEnyPx%M%`5Y=SMpvl6UCO9yQNvvY>#cegr^d0Dn<-nDIPi(sq7Bu{vw z-RuB8V)VmRS&Xm+TWkx?DOsjhxYmEo`@rtZ4@Y6d+E=OnTHami zzc#Ryjz%sV)OxQukt|fI+nQ$9F|Ak-Y%HYlr2<3HLPc3E_nIhe!G2q*{#vWU+On>@ zCe`@_W3iY5{4R?*#zM6_Pym8kS#R)8sKt%~a) zN+A)~axKI6JFL2BX(m&FbX%@Mj^3GDga(Yaa#zF64MM5p3MPZZa8IWdml9Tw%jmQG zj?TnoHW3>TolyoNCbQPlxadR_W3vUg4M3IZxmFua^0GHf=%{ePE1gs>6fv96(m>0? zx#GiIBWqOgO5nPJm6Jrw#a z0WF@Rwa^^m+WI*vxkAzCW*t4sSa7I~)+`FS0_P%h%vd2Ac9aB4Jt#o;M5N0mLd;Qx3ob^fRrAg zrK)ggK=Ce+nJ=^uXa&2nZ9!wjw%~Yg+^^UlERJ^VdO9W?D_dDRS6%}#=O<-U!H|?w z<%VD$)U@oksBnxsQIOIoiMUFya%NP7n-)Vds;q6YNDCGRRSUKjVNC$!D&!e(qh{ayQGkUm5N2vJ@-EH>Ik)>5=l)B6b?-IIM@k=Pj<>{mqV8m zB_?^;`p(ykPk!n9YNuB>H@DZjd-oxD%8?Y;|C}Dl38uId%WIR#OIPeB-PG!UH{ZnK zVqv>?ambc>n79$^UG^6+^$MYgcvF!lUJN=&yA82j;G(Nn?9GB3VMBT2St__MggT}B z#4AybFz$nn6~(Tteeh0*XwmPXr|^jDT}`ny8D;`4cy*cq;*sWNdETYQ^lci`yE}bb zDd<(9F_@PhcYFjx>5QA3nzL74_iO>G%&OniL5U?7Ln#9jirOd}HkaE~y{G>|b+Ag~ z=q&gFjDz9mP7VV`Q|77GA`?kET8kS%O4uumRpc72=?{}ydp0`Ykyt`tG*ZQ5xoxXS zJ=$)h3ZXg%F8AF$Mu>x1@9+_XMko(VgC1|7H3F-Na@Sf_-M1UNyUq*LU2g!{{YVGH z@$D)01yhuoRUbTj^I~6zH2ZqeDfUICo-e)AVqbdCzt3V{nr^??*8-2)FU7tn6!l(< zeH~JqXn8byG<~|hhv`gtslQW53CF;6{pucO(DXl^ZmB$SG=1PgRJW%ue3hC=dgk=x zxxuRkC<#4%n`NV@0XO;P8I{42toNlXCa~We4K@$kK!^9GE*3iK<*%lEOmef`t#A0M zB*mz1PIeoLH=(E=O^`rTYNCr7qJXgCrnnahhMHa+VW0W~mxJ^lFWPrGHU+Q9|rHVoY#RpSe}SE}GpCCp>^j51xSE_M1Mi%(tOT%A&} zOV`eBRd!3iCRF*-UvRI&RNG0mnmoH%Z(rmy+kAMJJzYJ^ANmGol*zi`OPua#Lr3%Y z5+{YfSS6e}(+6~qp*wx>VeP+*26?xRF#}kV$GI+ElmDXyc=$Qz#a_(#pr{`*=2;Y5 z3olI#v+3p8RnXAOZucndS*Q2u{~hgkN|`Lbl$Fp+@5?sl8Xkbwrms}GtK7cH z_I%Ow>B;FmTvE&F_mdsVq+Zt;I?q9bnnA~LQT5GO*m$GRq`O8Fw)XU8KHcY;hTyUK zhXmi0vzvn=Sf|kYN0SYQhaL2_2z<`|`o|LZtoi;czl75-U50K&^)$-tP{1uHjT%d@ zRHMygx4mAU?j{!}r!PG5`Sfxqdb{`r(jTgihcOQOU80jZrW3c{TYmU?yOnCz*QJ;{B@x@@-u3}`;RWhvxwnxdjMrw^#X<#qZJD&=T+N;R&@^Yw1B zK}3t1VQgLY`a!0bCY<^7!^u->JkpCO2pUh>A-uQ(CGWs%8s!>QNl;zwt|ni-+Py#* z(q*}LaiUU=N7GjzW^)d5^|tbAJV3CCUQh=8z32$>KZdg^THhRHkGxS7%J@2MpzP0A zyUEEG(Rijm1r^(?TZ-b|zkgpsb$vlCTWfaJQhas~m8+7KY=fp7A!|7W>lVM(Sci4U zvs4D`0Ehy@=Y51|@2IM$=O-^dlIZKyG5hOuwQ|X{`p@<4_QiRiYVzy#(`)0TQ$OwK zc(QIcy14q=d8xkk>-F~f!`ked-yjJ2#Krn_GCwVE*xo*^kN<~9Kg>^ge%pCXkS9Ys zEN$X%cW7su;n3J}b^hzN*mhdfw=6nMCfznqfACwV^j0IVqbMauY*=eE_UQ10PP64k zRqaW;9~;nH=nPb7;@UWLW7DiKIXhBy*o_e=Sewf{`xaT-V-+{If0=#im{E2#I*Bc{o089fDlgY+i=7L>P`V2Ya zZa{D61;;=R;llQ9pRBYVhlAByc^e;6QEwHL3#l1e9D6j=YT%d`FlU7gR)FyZH837m z2&BOxo@wS>k=}r@CJ~m@teH5AQ?r;DH`SD76u#w9;!O~Pj~807-GBuajTo!ZTB}-` z)0qMuwA1Hl0Jaq6o)!z(4imZ4HE4w(#ltZv0&{X;6%Nt>32Lu(@~abR4Qw1!4mjvG zR)7!OWb0TUU^-!FtfvSMI7Soe+kmnBz!46_4<@X~6AtRB&ohhcF1iom<93oYgjq+H zRNKI&@j8!W0q_v7N|^ge$WS6n)I1Ni!D9pC6!qJJp?vDiz>}N6wPsOA$+F@XEM0>_ zbzNZk6mtV7%FQDUm`Ezog!F49RoHaUYHp8gt9!FY3x;C@$+pQZqoa zWD%R$6u!!)@g~?V=9X_}!;=F-M8Z(YUjWrzWVZr z&u9h*)?=(O5eXHIt%wU?%fx~RU?$NZDxyOw9*dSUQUSbJWib>JP20Ly4V*d)ZGwZqY{dUH!m)uvcuL?xd0r0)Ccz?hb3D2l zx~{F#^>}~$0XNUb{K0tYQHRHh?yC(T=~mbzQA>$$^^I@{PD_~*>rgo_*QqU@g!{mh zaMxs^69dC*II#sM;7}nk^9hU+lwUy`2JFds3hMWSITHrY5rwGpVRDWNvjc*{JX}?k zY^D^SIb-mEuqQ{W!S8?|(3(Rx&HWsK1g8N)zYXZ45x_thhw9uEf2gGoH!8&7aAnme z8D9e_PRd}sWHD>rz-Kg=VjUbHZ^%Qf1-k;ZGsbu$T&8!FNf%Iq5rcu%#FW_Ypbc?o zVI>|<1{5^QqhN#Ouz(F{#&JmSBQOuoI7NUhYh%GdvGF24W|8OvW*CBl;$w(eXJ73- zAr;Z4+YX$V(e!5=a^&EQoEFT+LFYPdYMcrTwS{8|?&bU;s9C459oVa-`!O;vWefB| zx0;&{TD^yoC@&8h(!c@_L1N87fsKbU5$%$N$0EmqUR%$57J8jU7tKLKGc~Jf4XzSt zOf5kN{?8O<;YHN8UCk?;Q!hN0Q?H=U)|pe-vxaZjouI6tCAa!AfclL~oIz;Yz4}8k$Z*DPUj#-3Q;m4PoC_5Q+#Q zmOLm@8JdN=8_-i~7&5>fM;2WQE@0Mtsqs|gL0}Q6Qm5pKzj(zELXZ?LN=Z^duV3@5 zm$v~G!_f3=(f|yRB)UNc1#>}kyu6MtXt08iU|Y6S&>e-~tvIP*5L}Azf?hy~yJDN5 zM}!4S6KJVmtP~)tUY0R?vNEuW?J$beLu`sFK^3@c27yKE+>f;d7V!ed(#Oaf0TueC z5nv4*0xkyBP+c9MIjce;Lwa+G%?D?!p)6wJqVLc<4Qwi;FN=gwbQbX(h=@MRn3HK5 zFnEe7vT%3GlD4eDZV8RSr>DRXI0Xb}ie2=i0O4u`#6V6X+ZTB}NRt*IiOv|QUJ?{v&0l}ZuTmcgG~%5iI~f|Cz@Vm7 zf=rlIWmm5}hQvKIhVWduua!OLg`p(Yy8Sk9R(3GWUu)80~H^)yYCEfpSM{cnT{ z8xMgV)%0<%$^gwp5=#n@M#!&KO1cFW$K!hVmy(Xm)eOrl0k+>}q z69`uZ_SLX}T7~j#bO~J=^}ep(F`sx9A71mqS9EET#ySOPZ8hSul7sd@uwG2xiq8!(0g;lQx)n)y^j z*YKJk7QE6Yicf?c{XojWX@PUn9?URFyP>7hDin*D^H?+n#I6_Ff(o;ETZW&nXtZR+ z)NcxeW^`qP1it+e_p<=f(91R+)(7E$A*(Cs5h=}%aWi@kHP~xb#bwUdk+{+uLbt{$^{HcYio)n3dvc{6qtY2AvKyg}VmXM4! zJ+y)$lL2{2%oiaCDCQ8V1X+0$LVX4~nBT=LQ1S(^0_3IttUpt7%oG6S#R|bvHv}nY zsy>xivi{9|P>Lz(-=OFaYN6=#o4+%jzSJs z5VF!lQfs6L7wn0stPawm19w2ZxM-X}mtZSQRF3p-F)=~|)lrLjc!h!+Vm(5ArEUjc zZUwN~tH{Yr(u&L$Y#x(emLGL7L{4Be*G_8Gs;3IR)ZIlcCPfvQ+JKgt0wuCN!%8K4 zXr@n4g}k8Tpf(X-%0)d3`=!h*Z}b-;gBBso6ulZOU1;!O5>zk^58IQ%jYVK)PRP14 ztq51VNw|#l1%^#qu$fq^lKoXUS1C40tZJZxRSeoo(DI^^K**YA|7P}TftFK(J(ogj z7Icz$wqAAHV@U~E9uM(YJ6j@3k!yOjEfsNzXBN~b(BxJ?No5hE$DJa(5@QPViU#qo zJ1>?_Xoreci39UePl@gHL^2CzFFm;lEK2y zo?n*D;R#!9?CE{I4y;Nw+33GFJ36ERc+xAua-g4gYs4{r{Ch@TMV1x|Y{cDmW5)Lz z255bpJVAePY9=_WE!#4HRx;M_t$XdZG2QkR^;W$z(E-X024z!MK*UUi(D{Hw_5?EF z&V>Ci%!rbn!7BlVgBx_j)9@Y=LWh1<7iqB0g2h3!k~k+b{tYrAgIvAg?~R2es}K+| zoSY3uplnzN8&FFE{y>L{|RB7PgzC{X)Yj{c%I?!nXdBFuNdu*ncdQwOddxq5}1aYGW;>t599xcpYYuNS1B_xnW5w zku%nULkB20=0x)l@k{&O)9hJd^(H}E>n|C5uy>e2EtsCT8KMD_080OgXc1m5=MxPW zC=J^zF|AREMm5H?#?)sDcujG}N29Tc{hpXuvbJu5$cfMuJPgetOoYzdl9*_O?r3d6 zs?|u+u{P0SC8@E|^ji99uoO@w9P+U0x_bp%WZ}I+i)?I&&UsamRlsesquUNyLZvOD zWdfP_$~2S4d3kID;R)7LJd(ZJsum9g(FIHK@(`_&$14sD3{#s%s@z*kA<JH^Kt=rR3$aC5f3MOCjHCmDRL$N4Tqs5W<{=45$Pq}pC6>AQ zW5Hp&9 zfsD2mm`h|D$`}gv{-9FNX79F-qiqbWbwQnZB{LP9xu8WMSmpm)f@$XlPUjf@F**oG zVg{XRNsuY3f+ga#nPDyF#G(l>UoP0$7)@+U5H2dvVp0O+Q5{8R&)$6|g{ige4Gjnq z2^ck!n^eJ&B<+FHe*)M{7(u ze;Ax_5ES3QxmxzEws2ln}EFerS;1Y8)hP3k|7aZYe-v2qqFDCj?pr zlbOonkesAKFtSGytOpsiMsi2%PFr=hCr|4b8C?^h-Z)QdCehx_(;^}K-REifJ#~0r zkvH;$*y6uV9)9)s^U1?+)<5hf|4O#l=U11z$?twQdH6Yp+)l6fn%@YarKYFf&;nW` zek%rYmA^6S5#+l5Pya+mpZ&1={S&1=xVPUwp*x~x%WXXZ3N;>%bh+Hm(>i*z`XxC`@0r19P+{C@4{-YN{>9=bqP|T);%+qhCoA8>;$+;6{$i4bL+nh~E z8CWYn;9&ZLUb&n`Hqvr>x!vS6F1P<|$CqV?)2y)hohyT}b8yH)w}b1+2R}dAZYSTK zoPFULvD}mY-VRTXVDsrUvG1GHb{M`oijR-0@#Q9R8ondTD?4xueTh(idE)zL|7BAM zYOP2AanGyNBtOuuRW91R#}CYen`< zN#}6tSxNYyOZ=Ft@MD(r4zGCR4wCyc`SiC+*FT>AR@pL|yC;6?6(^}=yK{yG513%* z<%PR^;AR^Q%JZJjgshD#+OegaPj@}O`)T=A#i?4-M?Teyn_(V$m<$q24-un#jPS$> zd&xXT+#%^Q>EgvNxqv5m@_S_>DNjniU*SGmJk`&*3MWDGW?|(5PEJT( z!8L_vres<QPxZm?O#>e|LI5fqc!7*2D3t1&l^!nuD142dhKfL!3WxG7z{)##9e+OXt5W`ya zC*l}^p~f+Sw+HwAFV#%2m+>s|unbyjysTu;7U&U%72f|i2uM=>_8wa##5tP^Nptp9 zkQbW#qtNsIeY|@y`GTxtC3CUygqUtFtsJe{Ls*=b%q}8Qrp0Cm^WgH?`bMqSm#6Cw zCx7B6e5*V%Kl(|S7w^^JIEJ8qPJ=@QQ`l^kV&qf}D~B#l$(w%BO&@!_-koeXYH`9B zo1VK8#4}e-XE(iW#!_WR%!t?Nhkjx%ito#-?T(zbkN^DSix97$%5WkTP-KA>u)VrK z_H4K73sM8oy(GY~*ia_Pg1-0ZZ-1Mb8f(6zsdY#bdiTxK_J(=9lm97Vnonn|N60bg z`q6~JY(i~daYf?cJIk#VOR-`wCLIlPMC-$wE&b~kR8>3Vkx zBa;^S-~l=3|N6}z$#ma`c66#pJBnSX#6US&z!*6s9pBFEds8fN40( z8I$kQrh#1ro=*48f3lW>`l_od!N;6fN+N922%6xHl z{UO=)UMbH=dGnKt^@Yt5CFR>dLU8(#FsXQkf)sv*QcdI6?%hsscpN-=%(Qe4Os?}K zNwBQJE7F{6mRYZreu^59pa2DGA12(v zbdx8~X|sJNs|0V&^ucp#JQyLhgSdg^qxR2o91Tipp^hp<=Y+FS@3mKDqb)=~y}GzY znLXW{Z+5T7WavV<%nLmHiY>rZShkXPFwlr_cyfCgb9!>kUU@>bgA?IFTo0BcyxwWz zf0a)7OM-zn3oXWKO49M4%yi1pZkIjyA;$L|EFMp)(uZ2W#I{9CqCDfa_`i$|9V2g6 z;vLAI;n17h@nQp8gisSin}yYMh2d+7Q*N7SWF%u$&q-tl&9TKm`XZ3n2*%8|%Jj~k zNNR65F`Uc9uS@+EX%03vE7kQFm$7fH$A(ho%gr`kzL=h$W6g&YfW?;H6Cibzbx)ZE z^i13gB97mXvSiVY>J{6qH%Qby+p55VS3K5RdlGf=!#fg~ruQ0Mf^#j%?c?+9RS?wn z_Bys-@)$@39x(iGq_!{=?%HF>eOHb6H+OJ`Q?RqgD7C5H=^mp~C+iIyobPv!(JG7e z@K5W@=a}x4%KpWvDHrDZ++!@UIDghX#sXietTJj($qbDxhL~>pr_IGiPLr$4H{4R# z%8OkgMTunQ{Q2tgzT>~p|GV3pOKL4qYZ0Z+c^Sr-M5MwQ@GWr61Y&ItU3O*SPxoYc zVhEB5Ses?Q+JtI7oS4tBF3#5{X;ooMVJTQT%55aoByaVr?vQ?(lV>QV|D3`%1e{e5 zk~So>JycmsXfZu)nTwPOLYzrLQ&K369t&)luy|#)OS-?TH4p}LW6E!*xO(#tKE6ZYTB4Pu00g=WMRdm1J_-dOu^ZAVa&3WD?I{w|gBb~})L zyHEx$ALA=%b9;MEp_;U)ZZ9!b*C$)ZbNh;_RiX%djy!dBdvl5c{BHVeb1tuztgW(X z^`y5~a`J->+>qL@u6I1;jcaag{S=!lc2{>z?rqnFc&OqT;8*M(Jw2^UZ+d6zlQVcy zuk|`@WyO%XiQ&(wa^JLVNr(mE zpFjGnBV?caTl~sh+HTDOfy^Pfnzn3PPIi+s8?ve>NA)u$Z-QiyqWZ8bv+O#`#MV76 zd-JlV#a*0DC0MlgxQ116;;vQW@64tn&*a~N*LT6VdkBQn%|Zmhv1~SFOc55W1z+Dh zV+-vo7`$AEMuL*qrONT^$#M*?$-*iG`JUf5Jz(2vt(xuwZYX|8DEjzbhfplCtL0u? zBHClYd8&GbX?}%0eL>W*_7vep?AX$6svyYt$5Mq(Q9^Ox4GpUJTxVCR*X83kIUJ5< z&=Z~FqE**Ob4d)=m?$$!TE%{h;|gDXuKI3v(Wp6QwVuUM6aBz*q61wM9q6x|Uip~l zi$czWNDCEn{4=FTQ&)o}L@)99)j$Op=9NEPFvYccU3G@6i zpF5W)D7cbMCxJF`Y6(rmW_muo05OiWSGOvvCm}>R%`B#d6GWIp9madDaIPA zupK+(XY7zK?-BFs&GGT{hjc*wDcVOt(#``ur(8|HfmY&~le4W4*!@0v(2&9sd&p!K zR)RoWZ~a|Zd;if|tBmm2(ONl1`?{JqxZ4LuYkcM@AtX|#vAvuZh^C~e%S(hrx=pm#`N?{74m$G-LQ=pTjcJgRA7Fr zV;Swt!eRDYdz|HzKm03Odvp1$*t)uObAg#dyp)}WW0uXxq1=zG<{A|~Tcv)bKRA#J z%ak3vMXo%8-rYqo4mo2AL71>3xQXKh9$-5+Q;e4^NuNoSlNPH5PG!P|=KP0(!_rmA z{0)2_E?o_{VNz44LuL|4I7}7h)gW3V zR)d%ij+rz%UGl()kFve$K$$rwio~{^;>q#+4zYTfeu?aO`1#Nro3qQ@b8b>CdwpLU z^X!`!FhK6E{_E|QEmqVyfA~2fUI)BXVvzf`6M;4T-*L=R-l{YJKN4J5-$6?&aH~){ zlIvSm^i8iAaBIV$Pdm(2qNjUI^JZ*SJxx@o3d`Y>Gyu`pSg=Cy5vL&U^nhl#(oeME z&{9HZ)AL*~N+IX3>u|y>uq;V!ln<#KMY8yJabj-~#!E&^3|3qeRA6H4bW*jHkdRc{ zYqU_q`?bFMJw^+AwSGJhm3ZI1(c<^iqlC9KTA-?T8-VO7_6(Id$yvV`DoEz{YN*VA zZbOBP7m^%mJdpP&mUaps(I(~V3=;YFo~jB;(n%4gqoq}bc;2Xzpcs=Ww-vE0a_-(gy^4b+`7g`4LSP1e zm&|?K-+FlRxeCB*=?zLzLLImeW7p4-gW_Iv?{a`SGF6rH!lQ2=1lO=WF)v}Ye0g=Y zdA2!?6F>#f+w1ZC>}eFKSE#>vK55o2P5J3=8Qwx3O-x7pZb7}!Z94eA{q#@on0V`X zLX9r_W0>VGbfJ$+fMM0t_h!bcB{()WX`J7`Aka>fTlNPXqunBfSZ4R&V5(xj2eSjg zmVbtc13FH^tEw_jflZ*AvhX&@F-qNU%$|HZ~+U`m!qkarpO;rIOeF(q3;C?)J;eu%mIOKACf zHYJIs`+0p{_%zy~zxia`v)FZfgxe1CvgPC`P~tnWDBg=7Y|r`4NikCp(um3(*?pXGC|cxW9akN5 z#=&WqqSX1ujl>X^50-F#59d_ZbquKM+j6>7j%Lt1a_YZR>vTAU#QTf2eLOymvcXsj*ddwr`;LHSNYO7Dlf8re^~lkTlMzRid>76c0x`ClLA#b z3CC{md8J~MG!Z<5M3!5Da`-^K35j7(EMq@{S@b;fAVtTmM%JLpiBb2g zf{w|uBN3F`ix=>R44AaHamp3qDZa1fdw>Iv8&0d(xR|fCrHlBsUEE6;4 zpe<^-vC( z+uONBtqQ6uwghrOlIM9O`t>aYpg^iv`W4|0U)@s)4@RWR@Bn+UBkV`{Y{N;8tf7Mt z6)#EuBE+WiEWt{q4|c8Y`eh?EhFDq>GPK7OjnZ%;-?c(HA?rx%-ZoOkq+rQYFt za42^U>Hp0g%B?f`vJ2oFVT)gO0qElQ>QG)v#r%vFE#?HqQJSVYltaXXn)&qVl0CZe zdCzaDk-!E(#`o)e$kiKDqB|+2q996~n0O5$m=k>~Kk0k2=c}Mpp0YLO#{{zO>UULr zvReYIZE7tXh{;TCw3hri8=ebmAZ)U=K2&*x4+z_BG2NWoPr{F|=1LodYoQus6UIp! zN4uJPwDNgr^99F!PM^0nVXJbjsafF&Uxnf6EKt3jq6#t8;`*_XEtiUtnmEHh&%`DN zbd&Z^GE;n~755IG{Y;m?k-`;pD-o}>xxd+S0K(*~Nmr+U^z z0bgpF3ro};^& zb}NU0^hk=*(JQT=V{zd<<&&R+);eR4pJAkw+|ztZF=*cjZ49?J-^z5HO<$CtecMTK zoUbSp9aSuP8z1uZB0Cr1ryy`c8`Geg7B4|z06j>vD8YtKl6t3u(SA?+B$ z@4+8zOF?ImB?&p2@no{!$FGXhSxsKvdo=yte7u;RD8ZI?cAaWRrw4G>dq~PnR8T1) zrG90U!NH)*`)q=rlTs(?r!lJ|BzClg)w}%oV=Yasr;$ds`)5j%RI>B+&NN9{v>@aG z|4v@`55qvv_$O0S+$+S!|Hq~0!A~dGegIvg(3GnaL;B*pRzgpc@vd#Wuaj-f<~^Qi zbsP^9V~rFi6t})&63>7K)vw3_tBY6a^Cds>R?Gnj%Voblbx6om%c})doM^$ptuD}O)bgwqF^~j z%WL zeqfEFv7IkEE|dEr-~3F++;j}z_>jhOmkYh{qzy`m!U;bS8>i zX+YQpMeiqNY6_SdaxnRqRPS;MZE{#njr6=452wW-SDPp;%UfZ!TuvOCrR)=kMsCx1 zMw6$v2rfiD#VaDbu#QkDXLz>9;sNDaHJ`yA3gIQY?~W6p`jd1TD(mW#s~zQ=un#WR zAK@iER2=vm2Pu=fxT4YrXK~ux!)7)Bl@mth+A~;?LN0Lom}>V|Rr(%>J6%jc@znsW z$AQ{I>ST|z$oLUO9s(;CgF<7b`Y2=(TebK$6{3ju(&#K_gDRP1Ht>Ps3zMc|8cmxl z(U~1d@lbrn{<5Y6DabwUydj6b&Nt9vbIH?1Q9Yj~$1oKsdj)!#-%0>jq#%fkB^Zkp z!cUN6TgPp*LQ$cD8=Ufc?9`8nxJ8Et!ls;VUt2j~LPM}Zf#z5`?++k5Ndb^t(qq@X z+xUe-(Cca0{v7Ta@YMvf6NuN}#^Vrs_uF{Crw;GmdK>R4_Ts{3E6Sw&a+vp?xA7}D z?PuM_6Rz6c#y2Li0(&H*9m4*F0?g$^M+$0Rf1|`8q)~rgkK0%d(WtmyeFHYsER6m- zeX-kJfAsKSq{nU_oNgc7l1r%gq!$E?D0}m0`uys_`t0`MOYB{}0CDhWxpHud0&?>^ zBG#u<0wV~&sYg03&-om0^SrME2-vy%m?0-U`9@J_{2vCf6fe_u+8IGKl+nRbRwAR7 zvBU6@^q3;pB`S$@r~Q>i!|QdCb|`uHl6w^bu$3Tpa`s9mZj@?fR0@x{aYzL=JSTKi zzaq17Jwa*mc>=60Jy1_N_E|A+?KBu}48KIQ`_#+f`WVHfYEp4zZ~`V|+03Avh%7Um zg~*<`NPl~T@|V-Fm)<{MsPTksT}8u?uOuTSgFD_?a=JGXc7#|PmT1Vyzucp=x#?ZU zj2Pru04fee%h4&us;9Wnw-m%eQ#@p*p!oqcl5U2wDuf% z{InN+gHYP;n^NcWqOr=h(7=D%kjMB};wYnLP8ecQqcg8WR-sF5e$9t;Sa<%!Axp;d zmsl(n_=Z~WM^O#@gNI*{b)?^v)3Pbop`X?fM#1t|C(p@6ZH7dcoZq#~5pd)baF~XK zej0Axiu&phsT=lqq4yG}qJTnBcWc z|0V~k73T@hKKNB!Sk9^a(jfo((?DN9f-HO*N%_zP;{^HNxc` z#pk>R*Z4Zk;Mz*XiaTu=#|tq)@7hYjvv=)4{L;BbYyqEH>0etB*xkQ&z*={&9ULEt zh4f!t%Y)-%K2FiSM&W$|1A5o^l2da|_vW?J>_+vqPCTy=%vP{2@*U{4rl4WBX%4VfA$s&#n5jJ72+EJzQ~Z zE>ovFmgA*jeLB|;=5rZAy=#1mc5sci^slXs`}{jUIC#|OU#`vja&3+bJL>m$cr0IU zcPx~4=RmDEmr8Q-nuOiLw#F?YxBM=L1NEjKX-6|hC;*iuQ8MU zwS$38vp6_J$o8K*oDcAPz`6~d1Equa9`k+MUVn!(G|k}J@o|4G59efD_MhX6u02^S zi)OGMhw$5=zazdi-0u(e9gOdo4?*^xL;Lo5l@Em-ANKf&Z*f1OzHk@!=;Xfc;W^4! z4xU>+>d*Ixk2np+GQ-v#v_0zU58g4H@6ntA_S??q+OQTHBCARz%Rczs@9>ap{=Sx_ z{lUX89{=@si<4((s}qXNJ$-t3c5-(5^l0|%gwO>cGzo%8htN@a?;YtXRhmc# z6_Ae7>o30dyLa9Dy?5O|&N^q$nVCIh?`Q94CQ?&fiR>o*O*}k2GNiJ+HXa^9Fzx{X zZs1C|GS6gjFMusV4S|PO^_t}3DIrc~)qJF*fO}tGU-R?xFD@?b?(U9^jCgu_T3cHy zC@8S7u%xA>QCR_Pah1eT3I?dht~My|r|#Bx26`-d*6tqmt}ZM>_XPN#vao1ddr7hg z2=WO^@JR@>aN&l-;`S6}X~!aPPmp^adJl<*$E=BzN9g#ZZ)Xg6&nhNGXw@q}F`9%j zQ&(Zm*d@lL^1l6ysS)f;lFEcGPwy!6u9}@PIEeu}ax+&|6D5EsPGQk~6bpwbLm_W5Anjg2 zkp)@@R}6zBOwA~lrhV}BBU>|FfBJm$S0^R;7xHM zJdy~{U(3EPAz+=+H1VSQP;OHNd=hm^*Psp4LQa^tp)1EaO0KcQCD{AWS(B=kce)R$ zWH3bXv+w#AE$p$rn+G=`y}lu+8T7z=|6OW! zH8}Lk(qXbz=3_W70;um!dsnDaHxi^>M+LZUEbOxL{rth96I5@cp_F%?MV4HnVEZEG zQnF0RtpI8hCDD{Oa$*5VcxLN=_bN6C%QU;796FQQ;_$j0u6bxznG)q84lbJpTo(G< z-VNLdsvcSKkB?IyrHhIL2*fb@s=-AO()FCVcaHoP5oKRIJFd+dCpNo}JLLB~`7qek zbtBE|ZH~HUw=WhbOba4%Obc8(3*hCL0-Gr>0*!hp$>y7#q>7*w=7obJwe)YxrzS*b zw?n+vrK~;ulTvc;JF4@CvcF$DI`h5s9^%Q7?7QqK>5k4WAMW2G+H(d(j`#XFz+UfK z-{qIL=2xUVj%_@bjKK!Uv>GM^Em?a$$~rbzWpdjbsS1LejJrZg^R85Td$juLI2V|G zx;BlODM|56>lgZc#JjQBr@^f75CL>!1gBms)nE|-Fv-d&8Ii{FARE~HF&K98y{D%s z4qOTXE&|+BLL`&{&f@h}Lqn{k&?ZJ~$I_VH|A(}7fY-ta4FFuP+jxU6& z<_o-DP_Jw+W5zpQI&8l#nmV6a*a_929AEy(*S5E5w&PS_-{uvth6&S%J9B+O^tIcz z_RA^$l94M(`xS?d5Rb3z?Rv9~b-28>TT4U6-1Y(gd#$L(h}(Y7O#OncDi{_QX#A%- zb)z1!k2MNV#Q`aGT9|RKHAkaCQ(np6JT5WByaf7?_rsS^zbj?HdC}Q4P~CL`8O~7a z?#g3Enk4HGqex#&4VXX90o_(Q^=ozhs@Ku%fM24M;XF$9swV%d-NcY6sUQQ}vv!8N zx<3r3*0d>gl%Bm^>&}}iD{^h}AZ`nFs_LT@js}NCFG2p5D8eb7mcY{b6kfqs!n#FIkXCsr@I$xQZ|&x;RVsy*p*Am4c)))g#7$>QI-U z7!&)%jcB_k1x*_}c{TYn;>t6V43*&`YN<+WW9%F3(ly``MnG9N%bkvoY;R%ii1#of0qcv*gDaDvIZ00oixy~t2|%qVF=F6*llZ;#!29z^8=s_goA8vpwmuu~sqW>U2PZfp>`#7MVvA35eApiK1q= zT#VZ2_Cu2Sdz+J4f=Yu8;MNH4ghyq|jRpCmr#Q9oIJL#ofXSy04XOtTkC+4$Hl&+$ zDb&q+{R5mWKQRjQON;1&CH7Va^=aF62|1@**hjak7yNx~pJd;$(Y{^=>z(D4eE-QA z`I~Qd>28S#7+vLmW5NO?7@6( zLOSzYmh16wh@HwSoJpPzzfdgU9=1;mVPORDa1XL4hAt8QdocT3jDw3KO64z^QhuU! z+|UM*Gk8KKu{YJ-$a?-6{{GhDU)G?&(TL8;u+>3;%1frI68`4N{~0I$=P3TsClTOh z{r*p>C%v+I_nIo@hTH-lZDth2{!8J%X{h5zSBqp&K%QeA^!yzdVJD(r_4q}|AMdWfbrZ-Debo%GT7h@7upq~}cf6I;Ok|7=Q zLe?3G$Uv%1;OZA}clTK1IzSFJS9DK2W7XVINmB4!jtu<3hU-tTOi4A28}1_a$V90jzz>`7+g5PD-PH zTN-aMnt-qrIi?b)+A>JE!-Afnp^}zT1XFQ@*V?k>wKU-z0DWVAtix}8I47Nj*4?a4 zNYYE(e+T<;)E~;5D{Q;k(Z>cUO%d8KuHgDIOx17!7&-Jy-|!UnpZf(d{(q~V3pU1l z9RjT>>u91qe$*Dex|y#FPH=o7JCvsjZuKo!NzJuO1Yjo>wjDESRnQ~lcOA?&*#qM= zdo$N{syHQew<6V{{<)9;B@#Y@esR(IN7`0Ki;xnB>VVOvCDt@XWm9>=r8LXCzX#4J zJLGmv%@idkV%$NOde1qT+3k8q)2!$Y`8K~!*$cYc^$Z+|YOrsq7U&Q7w%BWDQ4dth}Z;Dk^)&`ttb$2+-r%h5R{m`Pt1A;`enA z3I=lll24Zu$(wqf+9cK6J~tu3v36Kg^&x+^|Lh4@B820s3DsdliQvp z>7wzuRAKE_WXqr(O<2djur1tnj97Bunr#^smsCvP`#zOZ>9r{HS+-lwM+u4|kKugf zZAybqT2xXpvjcjH)(4z)LC$h}qGuXtFY|Pp<e9C7g7|Cofm6OpC zlhCR#pm}ceCOg1CPaUvWbk5548!e#7|y>0~;cpY+4N~ZVf$z)U%FSW|S zEgHDX+OTEE;K+)W#0DwJjha_#QlA_2N!B);`_z^m_}{>aG1MID-3z%PM3OORI~_@Y zBEPqP&f;LBv}ojirgcAnpS!kak=;m0>P#=BNNd<_jc?a`zgTCXIhBMO^0v4Tz&Fz_ zjDytS#PJEb;U;<^sKQo@0@NS>aj)rnohn*>-7TD<-$xc&@R=7+lcd0p2=Xy)K}G)* z%dt6_P2xY)r7U&{aOVT*j4--Rxurf(#Q3%g*8C+FfmL)HX{^tmpPaFvkcodps}%pL zQ%D(d(M|7R%#W~-vms_wIWXWinNfFFPC=}9oN72SAMuQJ0cYxwcEAOKMsj@P-I zAo9tRMx%_zy`1^?2Pd}4{2MdAGx}u4m8a6EYd(2%u@Pi$8Jca5ejJ7aEJtwXOVBVI z%CL?I;5|{TIrwXh<%euzxY0%Y_d_idkmksghj-umko`@x`n14s2?4IRYs1zgBWVOm zkx9HJx4#%d_%(OxVmHLGs27qB|0MR2euDs*wAFIL223h(S!DwbbKbS*aep$3nSA{P zbBNl9({%cu?@=<`keN^mLH*7q(XRq3u2)+TX>yTvMwOq^-Bdk$pr~+1{B@Ggf@~}Z z!u~V(cN{400MAO8WqqZ#HDIVXm#UP*jZEsJ=E3vyq=pJZU1793fxldUzGd<)ab8!m znqmXMi;(-nS5%@X7f&~%g?1a=Djs$ba}no`|HYKI`9DIxeLD zag6`ZPreLk_8x}(Vez>CC2V%H6=?8UqdwL8}=rtQ)gi zrydQ!UJiFS$SH-%ic}mdR}~J?E|Di z1!eVm++4KTaqJKay!{r_fh=6vwWw}%S?&5q)crHFC+q)fX8(Dzf>CsfE|%0b54+Pi zI5<*J%k{|3ARhXC(2gdM>sja^8#n?Us|UwApE0#g0TrU;_6 zYiVXYAWrDy2Y7XscnvETA=B^d%ehopPC9c1)800LMA;fisV45-LF~oQ>LqYc8W*p^ z3|K*}Og0=3HK%3LQ>gy$6U@Rg%T z7_6}dCzE%M9D2}I*eHy0hz@;#T6+Lhq^C7ahLqi2Pxl6tbCKM!D;asJ(N;8-_GRpc z9?yg$eByigLBVckL#!w&`Lxu6BI+?BRfawl)MX4RPt! zrFhDto}7moQY|#Jg&*pcwqwDbe6$mmU4j(2 zxe#>VLGBh$mQJw~i6W>KmUf3&lOBDv{h`z(Vw2c`hP5*}-=ATYe8$F-k{^*b4%pl_ z`IGSk0|LVX_F~|xn7-X?qMi(;y@iNi&d}J8f*5TAv|zcCnlw4S?s_xGwD&7liN+y* z;Bw?c%9Xr#)bB_EIn49FA;bp{>cGS$gr#gJ$*`xq$xe3><0|=X%F26)4MKf9W_jkicZlC;%MdrVw_jZ5Cw#&* zpWt1|KVT}|q+ReHFz+?VLHS-zm~#Y9urtrVva{Gvdq7WNiFo$qr+e+5_tjd!X^8ve06T@ zw@F(`?n@wLCi)1B@z`I&06ygIUC#9%0335uJckBMc=U0hQ4uClL;KS%kj%pfz<W z0lo`MrF7@oOoVCtFY4fY{#6>|ApA~;Q=lwm-o1#GfrD>}~l3upw%~JkcEq`gHJFCWot+ecedU;;x!M)b~|5I~1b_+vM6P z)ZDFl&F2gMt`5B_&txBp(5#SE{5H>OaQNwC^3^x7jkG>9L*Fn`W5u!1^F>F7 zkVGTR&r)=^YFXBErzHVPnk(zYk7~q{?#mAGO-0p%Vv2?F#nFF8hBN(AwzR$c6ypS zXsO=*+-i{=6&<6ln@9UD8?fvhoY@4W7|VY&gZh5c6=!vU1$?sPmHx!R`2|X`A8w-F z*7FxVU__qk#}}KDjm(S;DsaOPUs6)uxBX&w{$vHuXp>EgdyxGRsSy2oLb|NIyxC5; z>%ic43&T&HT4MhOCIISh1flCVTmV@S>r-7DjpW za%^ZPWS9%l;CsV}#i1&)SWRPx8$HR|`O<)z3x;SSga&MNdyE?Q3hF530O|E9K}A22 zh3hxa0UFrXqUVgL6^*cZ;mOj#nS_riF|GYqtOld_n_OKHM8moSU)MvKoX!t8mQ48N zyWglQIM$h%qw}}-3TuA?%aAh(32EtWI{-r=&UjO7Vzr1iEqxfw=h;sU+q!1}+Alx) z!@)g{Nk`wa~9h1+!1T`sjX>dEPpg3Aw7w!CUvpaIfy^%F=k}U15%a6BD zgzQP;XErXTy&;i$Tty|Pp4&%(y2s-p-dZlTz%mWF2C7YY2cbSTYTQIU z+?|}C$T5tsJ4OnyS;Gnjn?v&pl(ATpP~r0GX_Ph!9WPvm7`KouSAFE>5R%`Uf>n9s zrtr7pxZ)3hkcs1o^G9tL@0{H$6^669$zufG^1{ldoim25(C%b@!+(M2(IDnr_I3CDe~5;j`{(%E_&*181Qxh5p{fPKM=j#04nkwB>6c%=z9F27 zVlE=v4WJ`EM-PZCYYp_h7kq~^JG#?8nyrNn(o7d~kCf)MO)5UMC!pFCD*y$ee=OQ< zRCDEGT1@FGj5GW%tsle%iITYgKoH}w=?I%DRS%J+UXEuu7;g0JCH3T8^{3_+5oOY>t>_r zup4+s49T40PF;^(&>L{IR~hmq_W8kTUeFeh;uvnZ(Ef5_ERJ-{;e+j>sVSx_p{yyU zy-hIbA28s4LH0I#%em>n>*VS8eJ?H)QI+4s0zxMKTI8A+q4-zd^#58zOC|+7!Oz!G z@|dS)Zl^G5hp%)7`G1UN{xgk)9f1U$z4JD?Y1DWjafpq01CdM*VfJ~n(Cqm40_@%+ zZruK4a_{QardedGAV&|%TGfgPAr;i+%jL|`{|7aiw~_z= diff --git a/Tools/WAD/Papers/python.html b/Tools/WAD/Papers/python.html deleted file mode 100644 index 90282bcea..000000000 --- a/Tools/WAD/Papers/python.html +++ /dev/null @@ -1,860 +0,0 @@ - - -WAD: A Module for Converting Fatal Extension Errors into Python Exceptions - - -

      - -

      WAD: A Module for Converting Fatal Extension Errors into Python Exceptions

      -
      David M. Beazley
      -Department of Computer Science
      -University of Chicago
      -Chicago, IL 60637
      -beazley@cs.uchicago.edu
      -
      -
      - -

      Abstract

      - -One of the more popular uses of Python is as an extension language for -applications written in compiled languages such as C, C++, and -Fortran. Unfortunately, one of the biggest drawbacks of this approach -is the lack of a useful debugging and error handling facility for -identifying problems in extension code. In part, this limitation is -due to the fact that Python does not know anything about the internal -implementation of an extension module. A more difficult problem is -that compiled extensions sometimes fail with catastrophic errors such -as memory access violations, failed assertions, and floating point -exceptions. These types of errors fall outside the realm of normal -Python exception handling and are particularly difficult to identify -and debug. Although traditional debuggers can find the location of a -fatal error, they are unable to report the context in which such an -error has occurred with respect to a Python script. This paper describes -an experimental system that converts fatal extension errors -into Python exceptions. In particular, a dynamically -loadable module, WAD (Wrapped Application Debugger), has been developed which catches -fatal errors, unwinds the call stack, and generates Python exceptions -with debugging information. WAD requires no modifications to Python, -works with all extension modules, and introduces no performance -overhead. An initial implementation of the system is currently -available for Sun SPARC Solaris and i386-Linux. - - - -

      1. Introduction

      - -One of the primary reasons C, C++, and Fortran programmers are -attracted to Python is its ability to serve as an extension language -for compiled programs. Furthermore, tools such as SIP, CXX, Pyfort, FPIG, -and SWIG make it extremely easy for a programmer to ``wrap'' existing -software into an extension module [1,2,3,4,5]. Although this approach is -extremely attractive in terms of providing a highly usable and -flexible environment for users, extension modules suffer from -problems not normally associated with Python -scripts---especially when they don't work. - -

      -Normally, Python programming errors result in an exception like this: - -

      -% python foo.py
      -Traceback (innermost last):
      -  File "foo.py", line 11, in ?
      -    foo()
      -  File "foo.py", line 8, in foo
      -    bar()
      -  File "foo.py", line 5, in bar
      -    spam()
      -  File "foo.py", line 2, in spam
      -    doh()
      -NameError: doh
      -% 
      -
      - -Unfortunately for compiled extensions, the following situation sometimes occurs: - -
      -% python foo.py
      -Segmentation Fault (core dumped)
      -%
      -
      - -Needless to say, this isn't very informative--well, -other than indicating that something ``very bad'' happened. - -

      -In order to identify the source of a fatal error, a programmer can run a -debugger on the Python executable or on a core file like this: - -

      -% gdb /usr/local/bin/python
      -(gdb) run foo.py
      -Starting program: /usr/local/bin/python foo.py
      -
      -Program received signal SIGSEGV, Segmentation fault.
      -0xff060568 in doh () from /u0/beazley/Projects/WAD/Python/./libfoo.so
      -(gdb) where
      -#0  0xff060568 in doh () from /u0/beazley/Projects/WAD/Python/./libfoo.so
      -#1  0xff082f34 in _wrap_doh ()
      -   from /u0/beazley/Projects/WAD/Python/./dohmodule.so
      -#2  0x2777c in call_builtin (func=0x1984b8, arg=0x1a1ccc, kw=0x0)
      -    at ceval.c:2650
      -#3  0x27648 in PyEval_CallObjectWithKeywords (func=0x1984b8, arg=0x1a1ccc,
      -    kw=0x0) at ceval.c:2618
      -#4  0x25d18 in eval_code2 (co=0x19acf8, globals=0x0, locals=0x1c7844,
      -    args=0x1984b8, argcount=1625472, kws=0x0, kwcount=0, defs=0x0, defcount=0,
      -    owner=0x0) at ceval.c:1951
      -#5  0x25954 in eval_code2 (co=0x199620, globals=0x0, locals=0x1984b8,
      -    args=0x196654, argcount=1862720, kws=0x197788, kwcount=0, defs=0x0,
      -#6  0x25954 in eval_code2 (co=0x19ad38, globals=0x0, locals=0x196654,
      -    args=0x1962fc, argcount=1862800, kws=0x198e90, kwcount=0, defs=0x0,
      -    defcount=0, owner=0x0) at ceval.c:1850
      -#7  0x25954 in eval_code2 (co=0x1b6c60, globals=0x0, locals=0x1962fc,
      -    args=0x1a1eb4, argcount=1862920, kws=0x0, kwcount=0, defs=0x0, defcount=0,
      -    owner=0x0) at ceval.c:1850
      -#8  0x22da4 in PyEval_EvalCode (co=0x1b6c60, globals=0x1962c4, locals=0x1962c4)
      -    at ceval.c:319
      -#9  0x3adb4 in run_node (n=0x18abf8, filename=0x1b6c60 "", globals=0x1962c4,
      -    locals=0x1962c4) at pythonrun.c:886
      -#10 0x3ad64 in run_err_node (n=0x18abf8, filename=0x1b6c60 "",
      -    globals=0x1962c4, locals=0x1962c4) at pythonrun.c:874
      -#11 0x3ad38 in PyRun_FileEx (fp=0x18a5a8, filename=0xffbefd7a "foo.py",
      -    start=1616888, globals=0x1962c4, locals=0x1962c4, closeit=1)
      -    at pythonrun.c:866
      -#12 0x3a1d8 in PyRun_SimpleFileEx (fp=0x18a5a8, filename=0xffbefd7a "foo.py",
      -    closeit=1) at pythonrun.c:579
      -#13 0x39d84 in PyRun_AnyFileEx (fp=0x18a5a8, filename=0xffbefd7a "foo.py",
      -    closeit=1) at pythonrun.c:459
      -#14 0x1f498 in Py_Main (argc=2, argv=0xffbefc84) at main.c:289
      -#15 0x1eec0 in main (argc=2, argv=0xffbefc84) at python.c:10
      -
      - -Unfortunately, even though the debugger identifies the location where the fault occurred, it -mostly provides information about the internals of the -interpreter. The debugger certainly doesn't reveal anything about the Python -program that led to the error (i.e., it doesn't reveal the -same information that would be contained in a Python traceback). As a result, -the debugger is of limited use when it comes to debugging an application that -consists of both compiled and Python code. - -

      -Normally, extension developers try to avoid catastrophic errors by -adding error handling. If -an application is small or customized for use with Python, it can be -modified to raise Python exceptions. -Automated tools such as SWIG can also convert C++ -exceptions and C-related error handling mechanisms into Python -exceptions. However, no matter how much error checking is added, -there is always a chance that an extension will fail in an unexpected -manner. This is especially true for large applications that have been wrapped -into an extension module. In addition, certain types of errors such as floating -point exceptions (e.g., division by zero) are especially difficult to find -and eliminate. Finally, rigorous error checking may be omitted to improve -performance. - -

      -To address these problems, an experimental module known as WAD (Wrapped -Application Debugger) has been developed. -WAD is able to -convert fatal errors into Python exceptions that include information -from the call stack as well as debugging -information. By turning such errors into Python exceptions, fatal -errors now result in a traceback that crosses the boundary between -Python code and compiled extension code. This makes it much -easier to identify and correct extension-related programming errors. -WAD requires no modifications to Python and is compatible with all -extension modules. However, it is also highly platform specific -and currently only runs on Sun Sparc -Solaris and i386-Linux. The primary goal of this paper is to motivate the problem -and to describe one possible solution. In addition, many of the -implementation issues -associated with providing an integrated error reporting mechanism are described. - -

      2. An Example

      - -WAD can either be imported as a Python extension module or linked to an -extension module. To illustrate, consider the earlier example: - -
      -% python foo.py
      -Segmentation Fault (core dumped)
      -%
      -
      - -To identify the problem, a programmer can run Python interactively and import WAD as follows: - -
      -% python
      -Python 2.0 (#1, Oct 27 2000, 14:34:45) 
      -[GCC 2.95.2 19991024 (release)] on sunos5
      -Type "copyright", "credits" or "license" for more information.
      ->>> import libwadpy
      -WAD Enabled
      ->>> execfile("foo.py")
      -Traceback (most recent call last):
      -  File "", line 1, in ?
      -  File "foo.py", line 16, in ?
      -    foo()
      -  File "foo.py", line 13, in foo
      -    bar()
      -  File "foo.py", line 10, in bar
      -    spam()
      -  File "foo.py", line 7, in spam
      -    doh.doh(a,b,c)
      -SegFault: [ C stack trace ]
      -
      -#2   0x00027774 in call_builtin(func=0x1c74f0,arg=0x1a1ccc,kw=0x0)
      -#1   0xff022f7c in _wrap_doh(0x0,0x1a1ccc,0x160ef4,0x9c,0x56b44,0x1aa3d8)
      -#0   0xfe7e0568 in doh(a=0x3,b=0x4,c=0x0) in 'foo.c', line 28
      -
      -/u0/beazley/Projects/WAD/Python/foo.c, line 28
      -
      -    int doh(int a, int b, int *c) {
      - =>   *c = a + b;
      -      return *c;
      -    }
      -
      ->>>
      -
      - -In this case, we can -see that the program has tried to assign a value to a -NULL pointer (indicated by the value "c=0x0" in the last function call). Furthermore, we obtain a Python traceback that shows the -entire sequence of functions leading to the problem. Finally, since -control returned to the interpreter, it is possible to interactively -inspect various aspects of the application or to continue with the computation -(although this clearly depends on the severity of the error and the nature of the application). - -

      -In certain applications, it may be difficult to run Python -interactively or to modify the code to explicitly import a special -debugging module. In these cases, WAD can be attached to an extension module with the -linker. For example: - -

      -% ld -G $(OBJS) -o dohmodule.so -lwadpy
      -
      - -This requires no recompilation of any source code--only a relinking of the -extension module. When Python loads the relinked extension module, WAD is automatically -initialized before Python invokes the module initialization function. - -

      3. Design Considerations for Embedded Error Recovery

      - -The primary design goal of WAD is provide an error reporting mechanism -for extension modules that is a natural extension of normal Python -exception handling. There are two primary motivations for -handling fatal errors in this manner: first, in the context of Python -programming, it is simply unnatural to run a separate debugging -application to identify a problem in an extension module when no such -requirement exists for scripts. Thus, an embedded error reporting -mechanism is simply more convenient. Second, the target users -of an extension module may not know how to use a debugger or even have -a development environment installed on their machine. Therefore, -the ability to produce an informative traceback within the -confines of the Python interpreter can be of tremendous value to an -extension developer. This is because users who report a problem will -be able to include an informative traceback as opposed to simply -saying ``the code crashed.'' - -

      -A secondary design goal is to provide a system that is as non-invasive -as possible. The system should not require modifications to Python or -any extension modules and it should be easy to integrate -into the runtime environment of an application. In addition, it shouldn't -introduce any performance overhead. - -

      -Finally, since WAD co-exists with the Python interpreter (i.e., in the same -process), there are a number of technical issues that have to be -addressed. First, fatal errors can theoretically occur anywhere in -the interpreter as well as in extension modules. Therefore, WAD needs -to know about Python's internal organization if it is going to provide -a graceful recovery back to the interpreter. Second, in order to -implement this recovery scheme, the system has to perform direct -manipulation of the CPU context and call stack. Last, but not least, -since the recovery code lives in the same address space as the -interpreter and extension modules it should not depend on the process -stack and heap (since both could have been corrupted by the faulting -application). - -

      4. Catching Fatal Errors

      - -WAD catches catastrophic errors by installing a -reliable signal handler for SIGSEGV, SIGBUS, SIGABRT, SIGILL, and SIGFPE [9]. Unlike the -more familiar BSD-style signal interface (as provided by the Python -signal module), reliable signal handlers are installed using the sigaction() system call and have a few notable properties: - -
        -
      • The signal handler can be configured to run on its own dedicated stack. - -

        -

      • Handler functions can receive a structure containing the CPU context -including the CPU registers, program counter, and stack pointer. - -

        -

      • Changes to the CPU context take effect immediately after the signal handler returns. -
      - -Therefore, the high level implementation of WAD is relatively straightforward: when a fatal signal occurs, -a handler function runs on an isolated signal handling stack. -The CPU context is then used to unwind the call stack and to inspect the process state. Finally, -if possible, the CPU context is modified in a manner that allows the signal handler to -return to Python with a raised exception. - -

      5. A Detailed Description of the Recovery Mechanism

      - -In this section, a more detailed description of the error recovery -scheme is presented. The precise implementation details of this are -highly platform specific and involve a number of advanced topics including -the Unix process file system (/proc), the ELF object file format, and the -Stabs compiler debugging format [6,7,8]. The details of these topics are -beyond the scope of this paper. However, this section hopes to -give the reader a small taste of the steps involved in implementing the recovery mechanism. - -

      -The services of WAD are only invoked upon the reception of a fatal -signal. This triggers a signal handling function that results in a return to Python -as illustrated in the following figure: - -

      - -
      Control flow of the error recovery mechanism
      -
      - -

      -The steps required to implement this recovery are as follows: - -

        -
      1. The values of the program counter and stack pointer are obtained from the CPU - context structure passed to the WAD signal handler. - -

        -

      2. The virtual memory map of the process is inspected to identify all of -the shared libraries, dynamically loaded modules, and valid memory regions. -This information is obtained by reading from the Unix /proc filesystem. -The following table illustrates the nature of this data: - - -
        -Address     Size    Permissions        File
        -----------  -----   -----------------  ---------------------------------
        -00010000    1264K   read/exec         /usr/local/bin/python 
        -0015A000     184K   read/write/exec   /usr/local/bin/python 
        -00188000     296K   read/write/exec     [ heap ] 
        -FE7C0000      32K   read/exec         /u0/beazley/Projects/dohmodule.so 
        -FE7D6000       8K   read/write/exec   /u0/beazley/Projects/dohmodule.so 
        -...
        -FF100000     664K   read/exec         /usr/lib/libc.so.1 
        -FF1B6000      24K   read/write/exec   /usr/lib/libc.so.1 
        -FF1BC000       8K   read/write/exec   /usr/lib/libc.so.1 
        -FF2C0000     120K   read/exec         /usr/lib/libthread.so.1 
        -FF2EE000       8K   read/write/exec   /usr/lib/libthread.so.1 
        -FF2F0000      48K   read/write/exec   /usr/lib/libthread.so.1 
        -FF310000      40K   read/exec         /usr/lib/libsocket.so.1 
        -FF32A000       8K   read/write/exec   /usr/lib/libsocket.so.1 
        -FF330000      24K   read/exec         /usr/lib/libpthread.so.1 
        -FF346000       8K   read/write/exec   /usr/lib/libpthread.so.1 
        -FF350000       8K   read/write/exec    [ anon ] 
        -FF3B0000       8K   read/exec         /usr/lib/libdl.so.1 
        -FF3C0000     128K   read/exec         /usr/lib/ld.so.1 
        -FF3E0000       8K   read/write/exec   /usr/lib/ld.so.1 
        -FFBEA000      24K   read/write/exec    [ stack ] 
        -
        - -

        -

      3. The call stack is unwound to produce a traceback of the -calling sequence that led to the error. The unwinding process is just a simple -loop that is similar to the following: - -
        -long *pc = get_pc(context);
        -long *sp = get_sp(context);
        -while (sp) {
        -    /* Move to previous stack frame */
        -    pc = (long *) sp[15];      /* %i7 register on SPARC */
        -    sp = (long *) sp[14];      /* %i6 register on SPARC */
        -}
        -
        - -
      4. For each stack frame, symbol table and debugging information -is gathered and stored in a WAD exception frame object. -Obtaining this information is the most complicated part of WAD and involves -the following steps: first, the current program counter is mapped to an object file -using the virtual memory map obtained in step 2. Next, the object file is loaded -using mmap(). Once loaded, the ELF symbol table -is searched for an address match. The symbol table contains a collection of records -containing memory offsets, sizes, and names such as this: - -
        -Offset    Size    Name 
        ---------  ------  ---------
        -0x1280    324     wrap_foo
        -0x1600    128     foo
        -0x2408    192     bar
        -...
        -
        - -To find a match for a virtual memory address addr, WAD simply -searches for a symbol s such that base + -s.offset <= addr < base + -s.offset + s.size, where base is the base -virtual address of the object file in the virtual memory map. - -

        -Debugging information, if available, is scanned to identify a source -file, function name, and line number. This involves scanning object files for a -table of debugging information stored in a format -known as ``stabs.''. Stabs is a relatively simple, but highly extensible format that -is language independent and capable of encoding almost every aspect of the -original source code. For the purposes of WAD, only a small subset of this -data is actually used. - -

        -The following table shows a small fragment of relevant stabs data: -

        -type    desc   value        string                        description
        -------  -----  ---------    ---------------------------   -----------
        -0x64      0        0         /u0/beazley/Projects/foo/    Pathname
        -0x64      0        0        foo.c                         Filename
        -...                             
        -0x24      0        0        foo:F(0,3);(0,3)              Function
        -0xa0      4        68       n:p(0,3)                      Parameter
        -...                                                      
        -0x44      6        8                                      Line number
        -0x44      7        12                                     Line number
        -0x44      8        44                                     Line number
        -0x44      9        56                                     Line number
        -...                                                      
        -
        - -In the table, the type field indicates the type of debugging information. For -example, 0x64 specifies the source file, 0x24 is a function -definition, 0xa0 is a function parameter, and 0x44 is line number -information. Associated with each stab is a collection of parameters -and an optional string. The string usually contains symbol names and -other information. The desc and value fields are numbers -that usually contain byte offsets and line number data. -Therefore, to collect debugging information, WAD simply walks through the debugging -tables until it finds the function of interest. Once found, parameter and line -number specifiers are inspected to determine the location and values of the function -arguments as well the source line at which the error occurred. - -

        -

      5. After the complete traceback has been obtained, it is examined to see if -there are any ``safe'' return points to which control can be returned. -This is accomplished by maintaining an internal table of predefined symbolic return -points as shown in the following table: - -
        -Python symbol                     Return value
        ------------------------------     ------------------
        -call_builtin                      NULL
        -_PyImport_LoadDynamicModule       NULL
        -PyObject_Repr                     NULL
        -PyObject_Print                    -1
        -PyObject_CallFunction             NULL
        -PyObject_CallMethod               NULL
        -PyObject_CallObject               NULL
        -PyObject_Cmp                      -1
        -PyObject_Compare                  -1
        -PyObject_DelAttrString            -1
        -PyObject_DelItem                  -1
        -PyObject_GetAttrString            NULL
        -PyObject_GetItem                  NULL
        -PyObject_HasAttrString            -1
        -PyObject_Hash                     -1
        -PyObject_Length                   -1
        -PyObject_SetAttrString            -1
        -PyObject_SetItem                  -1
        -PyObject_Str                      NULL
        -PyObject_Type                     NULL
        -...
        -PyEval_EvalCode                   NULL
        -
        - -The symbols in this table correspond to functions within the Python interpreter that -might execute extension code and include the parts of the interpreter that invoke builtin functions -as well as the functions from the abstract object interface. -If any of these symbols appear on the call stack, -a handler function is invoked to raise a Python exception. -This handler function -is given a WAD-specific traceback object that contains a copy of the -call stack and CPU registers as well as any symbolic and debugging -information that was obtained. If none of the symbolic return points -are encountered, WAD invokes a default handler that simply prints the -full C stack trace and generates a core file. - -

        -

      6. If a return point is found, the CPU context is modified in a manner that allows the signal handler to return - with a suitable Python error. - This last step is the most tricky part of the recovery process, but the general - idea is that CPU context is modified in a way that makes Python think that - an extension function simply raised an exception and returned an error. Currently, this - is implemented by having the signal handler return to a small - handler function written in assembly language which arranges to return the - desired value back to the specified return point. - -

        - The most complicated part of modifying the CPU context is that of restoring - previously saved CPU registers. By manually unwinding the call stack, the - WAD exception handler effectively performs the same operation as a longjmp() call in C. - However, unlike longjmp(), no previously saved set of CPU registers are available from which to resume - execution in the Python interpreter. The solution to this problem depends entirely on the - underlying architecture. On the SPARC, register values are saved in register windows - which WAD manually unwinds to restore the proper state. On the Intel, the solution is much - more interesting. To restore the register values, WAD must manually inspect the - machine instructions of each function on the call stack in order to find out where the - registers might have been saved. This information is then used to restore the registers from their - saved locations before returning to the Python interpreter. - -

        -

      7. Python receives the exception and produces a traceback. -
      - -

      6. Initialization and Loading

      - -In the earlier example, it was shown that WAD could be both -loaded as an extension module or simply attached to an existing module -with the linker. This latter case is implemented by -wrapping the WAD initialization function inside the constructor of a -statically allocated C++ object like this: - -
      -
      -class WadInit {
      -public:
      -    WadInit() {
      -        wad_init();   /* Call the real initialization function */
      -    }
      -};
      -static WadInit wad_initializer;
      -
      - -When the dynamic loader brings WAD into memory, it automatically -executes the constructors of all statically allocated C++ objects. -Therefore, this initialization code executes immediately after -loading, but before Python actually calls the module initialization -function. As a result, when an extension module is linked with WAD, -the debugging capability is enabled before any other operations occur---this -allows WAD to respond to fatal errors that might occur during module -initialization. - -The rest of the initialization process consists of the following: -
        -
      • The WAD signal handler is installed. -
      • A collection of return symbols are registered with the signal handler (see the previous section). -
      • Four new Python exception objects SegFault, BusError, AbortError, -and IllegalInstruction are added -to the __builtin__ module. -
      - -Although the use of a C++ static constructor has the potential to -conflict with C++ extension code that also uses static constructors, -it is always possible to enable WAD prior to loading a C++ extension -(e.g., WAD could be loaded separately). - -

      7. Implementation Details

      - -Currently, WAD is written in ANSI C with a small amount of C++, -and a small amount of assembly code (to assist in the return to the interpreter). -The entire implementation contains approximately 2000 semicolons and most of the code -relates to the gathering of source code information (symbol tables, -debugging information, etc.). - -

      -Although there are libraries such as GNU bfd that can assist with the -reading of object files, none of these are used in the implementation [10]. -First, these libraries tend to be quite large -and are oriented more towards stand-alone tools such as debuggers, -linkers, and compilers. Second, due to usual nature of the runtime -environment and the restrictions on memory utilization (no heap, no -stack), the behavior of these libraries is somewhat unclear and -would require further study. -Finally, given the small size of the prototype implementation, it didn't seem necessary to rely on a -large general purpose library. - -

      8. Discussion

      - -The primary focus of this work is to provide a more useful error -reporting mechanism to extension developers. -However, this does not imply that -WAD is appropriate as a general purpose exception -handling mechanism. First, let's focus -on the recovery mechanism: - -
        -
      • When WAD unwinds the call stack, objects allocated on the stack -are lost. This may interact poorly with C++ extensions since the -unwinding process does not invoke C++ destructors. It may be possible to fix -this problem, but doing so would require coordination with the C++ runtime library. - -

        -

      • Similarly, if a procedure allocates objects on the heap, stack unwinding -may cause those objects to never be reclaimed. - -

        -

      • Closely related to heap management, stack unwinding may result in -open files, sockets, and other system resources. Furthermore, in a multithreaded -environment, deadlock may occur if a procedure is holding a lock when an error occurs. - -

        -

      • An application may fail by overwriting the process heap and corrupting -memory. Although WAD can produce internal diagnostics even when the heap has been -destroyed, Python may fail immediately upon return from the -WAD signal handler or shortly thereafter. - -

        -

      • If an application destroys the call stack (via buffer overflow), WAD will -be unable to complete a stack trace and will be unable to return to -Python. - -

        -

      • Memory management problems such as double-freeing of memory are particularly -difficult to identify. If an extension module corrupts the memory allocator -in some manner, this may cause Python to fail in a completely unexpected location. -WAD is usually able to produce a traceback in this situation, but -it may not correspond to the real source of the problem. - -
      - -In addition, there are a number of issues that pertain to WAD's interaction with the -Python interpreter: - -
        -
      • The recovery mechanism is entirely based on symbolic information stored -in the Python executable. Therefore, the return points are simply specified -as strings such as ``call_builtin'' as opposed to real memory addresses. -Because of this, WAD is compatible with essentially any version of Python (provided -it supports class-based exceptions). - -

        -

      • WAD is unable to manage multiple return values to same procedure. -For example, Python's eval_code2() procedure contains a huge -case statement for executing byte codes. Within this procedure, certain -function calls return NULL to indicate an error and others return -1. Since WAD -is unable to determine which value to return, this particular procedure does not make a very -good return point for error recovery. - -

        -

      • An alternative approach to the symbolic recovery scheme would be to -instrument Python with a collection of safe return points using setjmp()/longjmp(). -This approach is not used because it would require a significant number of changes to -the interpreter and it would introduce an unacceptable amount of performance overhead. - -

        -

      • WAD is generally safe to use with Python threads. However, if a -compiled extension function manually releases the Python interpreter -lock and subsequently faults, the return behavior is unspecified. In -the future, it may be possible to use the interpreter lock to provide coordination -between the interpreter and the error recovery mechanism. - -

        -

      • Compiled extension code may perform an eval operation in which Python code is executed -in the interpreter. This results in a situation where the complete call-stack of an -application crosses the boundary between Python and C several times. WAD can -still handle faults in this setting as long as an application is doing a reasonable amount of -error checking. For example, a fatal error that occurs inside an eval operation could -be caught by the extension code and propagated further up the call stack. - -

        -

      • In certain cases, Python may be configured to handle the SIGFPE signal for floating point -exceptions. The default Python handling of this error is to abort and dump core. However, -with WAD, a complete stack traceback will be obtained when a SIGFPE occurs. - -

        -

      • WAD is extremely inefficient. Due to restrictions on the heap and stack, -WAD relies heavily on mmap() and a variety of other file -operations as it handles errors. It also performs linear searches of symbol and -debugging tables. As a result, WAD's generation of a -Python exception is several orders of magnitude slower than an ordinary -exception. -
      - -Finally, there are a number of application specific issues to note: - -
        -
      • Aggressive compiler optimization techniques may prevent WAD from -accurately reporting locations within the original source code. -This is particularly problematic with numerical applications where -techniques such procedure inlining can make it impossible to obtain accurate -debugging information. Since these types of problems also arise in -full-featured debuggers, it is unlikely that they can be easily fixed in WAD (at least not -without a considerable amount of work). - -

        -

      • If an application implements its own exception handling, -it may provide Python with less information than what would obtained with WAD. -For example, a programmer might implement a function like this: - -
        -void *Malloc(int size) {
        -   void *ptr;
        -   ptr = malloc(size);
        -   if (!ptr) throw("Out of memory");
        -   return ptr;
        -}
        -
        - -In this case, the ``throw'' function may initiate an internal -exception handling mechanism that relies upon setjmp/longjmp or C++ exceptions. -When the error eventually makes it back to the interpreter, the user will get an ``out -of memory'' exception, but no additional information will be -provided. In contrast, if the programmer simply used an assert() statement, WAD would produce a full stack trace leading to -the error. -
      - - -Despite its various limitations, WAD is applicable to a wide range of -extension-related errors. Furthermore, most of the errors that are -likely to occur are of a more benign variety. For example, a -segmentation fault may simply be the result of an uninitialized -pointer (perhaps the user forgot to call an initialization procedure). -Likewise, bus errors, failed assertions, and floating point exceptions -rarely result in a situation where the WAD recovery mechanism would be -unable to produce a meaningful Python traceback. - -

      9. Related Work

      - -There is a huge body of literature concerning the implementation of -exception handling in various programming languages and environments. -A detailed discussion of this work is clearly not possible here, but -a general overview of various exception handling issues can be found in [11]. -In general, there are a few themes that seem to prevail. -First, -considerable attention has been given to exception handling mechanisms -in specific languages such as efficient exception handling for C++. -Second, a great deal of work has been given to the semantic aspects of -exception handling such as exception hierarchies, finalization, and -whether or not code is restartable after an exception has occurred. -Finally, a fair amount of exception work has been done in the context -of component frameworks and distributed systems. Most of this work -tends to concentrate on explicit exception handling mechanisms. Very little -work appears to have been done in the area of converting hardware generated errors -into exceptions. - -

      -With respect to debuggers, quite a lot of work has been done in -creating advanced debugging support for specific languages and -integrated development environments. However, very little of this work -has concentrated on the problem of extensible systems and -compiled-interpreted language integration. For instance, debuggers -for Python are currently unable to cross over into C extensions whereas C -debuggers aren't able to easily extract useful information from the -internals of the Python interpreter. - -

      -One system of possible interest is Rn which was developed in the -mid-1980s at Rice University [12]. This system, primarily -designed for working with large scientific applications written in -Fortran, provided an execution monitor that consisted of a special -debugging process with an embedded interpreter. When attached to -compiled Fortran code, this monitor could dynamically patch -the executable in a manner that allowed parts of the code to be executed in the -interpreter. This was used to provide a debugging environment in which -essentially any part of the compiled application could be modified at -run-time by simply compiling the modified code (Fortran) to an -interpreted form and inserting a breakpoint in the original executable -that transferred control to the interpreter. Although this -particular scheme is not directly related to the functionality -of WAD, it is one of the few systems in which -interpreted and compiled code have been tightly coupled within -a debugging framework. Several aspects of the interpreted/compiled -interface are closely related to way in which WAD operates. In addition, -various aspects of this work may be useful should WAD be extended with -new capabilities. - -

      10. Future Directions

      - -WAD is currently an experimental prototype. Although this paper has -described its use with Python, the core of the system is generic and -is easily extended to other programming environments. For example, when -linked to C/C++ code, WAD will automatically produce stack -traces for fatal errors. A module for generating Tcl exceptions has -also been developed. Plans are underway to provide support for other -extensible systems including Perl, Ruby, and Guile. - -

      -Finally, a number of extensions to the WAD approach may be possible. -For example, even though the current implementation only returns a -traceback string to the Python interpreter, the WAD signal handler -actually generates a full traceback of the C call stack including all -of the CPU registers and a copy of the stack data. Therefore, with a -little work, it may be possible to implement a diagnostic tool that -allows the state of the C stack to be inspected from the Python -interpreter after a crash has occurred. Similarly, it may be possible -to integrate the capabilities of WAD with those provided by the Python -debugger. - -

      11. Conclusions and Availability

      - -WAD provides a simple mechanism for converting fatal errors into -Python exceptions that provide useful information to extension -writers. In doing so, it solves one of the most frustrating aspects -of working with compiled Python extensions--that of identifying program errors. -Furthermore the system requires no code modifications to Python and introduces -no performance overhead. -Although the system is -necessarily platform specific, the system does not involve a -significant amount of code. As a result, it may be relatively -straightforward to port to other Unix systems. - -

      -As of this writing, WAD is still undergoing active development. However, -the software is available for experimentation and download at -at http://systems.cs.uchicago.edu/wad. - -

      References

      - -[1] D.M. Beazley, Using SWIG to Control, Prototype, and Debug C Programs with Python, -4th International Python Conference, Livermore, CA. (1996). - -

      -[2] P.F. Dubois, Climate Data Analysis Software, 8th International Python Conference, -Arlington, VA. (2000). - -

      -[3] P.F. Dubois, A Facility for Creating Python Extensions in C++, 7th International Python -Conference, Houston, TX. (1998). - -

      -[4] SIP. http://www.thekompany.com/projects/pykde/. - -

      -[5] FPIG. http://cens.ioc.ee/projects/f2py2e/. - -

      -[6] R. Faulkner and R. Gomes, The Process File System and Process Model in UNIX System V, USENIX Conference Proceedings, -January 1991. - -

      -[7] J.R. Levine, Linkers & Loaders. Morgan Kaufmann Publishers, 2000. - -

      -[8] Free Software Foundation, The "stabs" debugging format. GNU info document. - -

      -[9] W. Richard Stevens, UNIX Network Programming: Interprocess Communication, Volume 2. PTR -Prentice-Hall, 1998. - -

      -[10] S. Chamberlain. libbfd: The Binary File Descriptor Library. Cygnus Support, bfd version 3.0 edition, April 1991. - -

      -[11] M.L. Scott. Programming Languages Pragmatics. Morgan Kaufmann Publishers, 2000. - -

      -[12] A. Carle, D. Cooper, R. Hood, K. Kennedy, L. Torczon, S. Warren, A Practical Environment for Scientific Programming. -IEEE Computer, Vol 20, No. 11, (1987). p. 75-89. - - - - - - - - - - - - diff --git a/Tools/WAD/Papers/tcl.ps b/Tools/WAD/Papers/tcl.ps deleted file mode 100644 index ac2ee86f9..000000000 --- a/Tools/WAD/Papers/tcl.ps +++ /dev/null @@ -1,11006 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: /u0/beazley/Papers/2000/usenix2000/tcl.ps -%%Creator: XV Version 3.10a Rev: 12/29/94 - by John Bradley -%%BoundingBox: 37 188 574 604 -%%Pages: 1 -%%DocumentFonts: -%%EndComments -%%EndProlog - -%%Page: 1 1 - -% remember original state -/origstate save def - -% build a temporary dictionary -20 dict begin - -% define string to hold a scanline's worth of data -/pix 707 string def - -% define space for color conversions -/grays 707 string def % space for gray scale line -/npixls 0 def -/rgbindx 0 def - -% lower left corner -37 188 translate - -% size of image (on paper, in 1/72inch coords) -537.33600 416.44800 scale - -707 548 8 % dimensions of data -[707 0 0 -548 0 548] % mapping matrix -{currentfile pix readhexstring pop} -image - -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c039c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c039c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c039 -c0c0767676767676767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767676767676763939 -c0c0767676767676767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767676767676763939 -c0c0767676767676767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767676767676763939 -c0c0767676393939393939393939393939393939393939393939393939c0393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939c03939393939 -3939393939393939393939393939393939397676763939 -c0c076767639c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c076767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -ffffffff7676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767676767676ffffffffff767676767676767676767676767676767676767676 -7676767676ffff767676767676767676767676ffffffffffffffffffff76767676767676 -7676767676767676767676767676767676767676767676767676767676767676767676ff -ff7676767676767676767676767676767676767676767676767676ffffffffffffff7676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676ffffff767676ff767676ffff76767676767676767676767676767676 -7676767676ffff76767676767676767676767676767676ffff7676767676767676767676 -7676767676767676767676767676767676767676767676767676767676767676767676ff -ff7676767676767676767676767676767676767676767676767676ffff76767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676ffff7676767676767676ffff76767676767676767676767676767676 -7676767676ffff76767676767676767676767676767676ffff7676767676767676767676 -7676767676767676767676767676767676767676767676767676767676767676767676ff -ff7676767676767676767676767676767676767676767676767676ffff76767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c0767676c0c0c0c0c0c0c0c0c0c0c0c0c0c0c076767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676ffff76767676767676ffffffffff7676ffffffffff7676767676ffff -ffffff7676ffff76767676ffff76767676767676767676ffff76767676767676ffff76ff -ff7676ffffffffff7676767676ffffffffff76767676ffffffff7676767676767676ffff -ffffff767676ffffffffff76767676ffff76ffff76767676767676ffff76767676767676 -ffff76ffff7676ffff76ffff767676ffffffffff76767676ffff76ffff76767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c07676767676767676c0c0c0c076767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c0767676c0767676767676767676767676763976767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676ffffffff767676767676ffff76767676ff767676ffff767676ffff76 -7676767676ffff767676ff767676767676767676767676ffff76767676767676ffffff76 -767676ff767676ffff767676ffff76767676767676ffff7676ffff7676767676767676ff -ff76767676ffff767676ffff767676ffffff767676767676767676ffff76767676767676 -ffffff76767676ffffff76767676ffff767676ffff767676ffffff767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c07676767676767676c076763976767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c0767676c0767676767676767676767676763976767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676ffffffffff76767676ffff7676767676767676ffff7676ffff7676 -7676767676ffff7676ff76767676767676767676767676ffff76767676767676ffff7676 -76767676767676ffff7676ffff76767676767676ffff76767676ffff76767676767676ff -ff767676ffff7676767676ffff7676ffff76767676767676767676ffffffffffff767676 -ffff7676767676ffff76767676ffff7676767676ffff7676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c07676767676767676c076763976767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c0767676c0393939393939393939393939393976767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676767676ffffffff767676ffff7676767676767676ffff7676ffff7676 -7676767676ffff76ff7676767676767676767676767676ffff76767676767676ffff7676 -76767676767676ffff7676ffff76767676767676ffff76767676ffff76767676767676ff -ff767676ffff7676767676ffff7676ffff76767676767676767676ffff76767676767676 -ffff7676767676ffff76767676ffff7676767676ffff7676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c07676767676767676c039393976767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767676767676767676ffffff7676ffff7676767676ffffffffff7676ffff7676 -7676767676ffffffff7676767676767676767676767676ffff76767676767676ffff7676 -76767676ffffffffff7676ffff76767676767676ffffffffffffffff76767676767676ff -ff767676ffff7676767676ffff7676ffff76767676767676767676ffff76767676767676 -ffff7676767676ffff76767676ffff7676767676ffff7676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676767676767676ffff7676ffff767676ffffff7676ffff7676ffff7676 -7676767676ffff76ffff76767676767676767676767676ffff76767676767676ffff7676 -7676ffffff7676ffff7676ffff76767676767676ffff76767676767676767676767676ff -ff767676ffff7676767676ffff7676ffff76767676767676767676ffff76767676767676 -ffff7676767676ffff76767676ffff7676767676ffff7676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676767676767676ffff7676ffff767676ffff767676ffff7676ffff7676 -7676767676ffff7676ffff767676767676767676767676ffff76767676767676ffff7676 -7676ffff767676ffff7676ffff76767676767676ffff76767676767676767676767676ff -ff767676ffff7676767676ffff7676ffff76767676767676767676ffff76767676767676 -ffff7676767676ffff76767676ffff7676767676ffff7676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676ff76767676ffff767676ffff767676ffff767676ffff767676ffff76 -7676ff7676ffff767676ffffff76767676767676767676ffff76767676767676ffff7676 -7676ffff767676ffff767676ffff767676ff767676ffff76767676ff76767676767676ff -ff76767676ffff767676ffff767676ffff76767676767676767676ffff76767676767676 -ffff7676767676ffff7676767676ffff767676ffff767676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -7676767676767676ffffffffffff7676767676ffffff7676ffffffff76ffff767676ffff -ffffff7676ffff76767676ffffff767676767676767676ffff76767676767676ffff7676 -767676ffffffff76ffff767676ffffffffff7676767676ffffffffff76767676767676ff -ff7676767676ffffffffff76767676ffff76767676767676767676ffffffffffffff7676 -ffff7676767676ffff767676767676ffffffffff76767676ffff76767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c076 -7676767676767676767676763976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c0767676c039 -3939393939393939393939393976767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767639c07676763939 -c0c076767639c076767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -76767676767639c076767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767639c07676763939 -c03939393939c039393939393939393939393939393939393939393939c0393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -39393939393939c039393939393939393939393939393939393939393939c03939393939 -3939393939393939393939393939393939c03939393939 -c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c039 -c0c076767639d96b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6bd9d96b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6bd9c07676763939 -c0c076767639d96b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6bf8d9d96b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6bf8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3c36bc3c3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3f86bc3c3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3f86b6bc3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3f8f86b6bc3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3f8f8e16b6bc3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3f8f8e1e16b6bc3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e100e1e1e1e100e1000000e1e1e1e1e1e1000000e1e1 -e1e1e100e1e1e10000e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1 -e1e100000000000000e1e1e100000000e1e1e1e1e1e100000000e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e1e1e10000e1e1e100000000e1e1 -e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3f8f8e1e1e16b6bc3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e100e1e1e1e10000e1e1e100e1e1e1e100e1e1e100e1 -e1e1e100e10000e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e100e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e10000e100e1e1e1e1e1e1e100e1 -e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3f8f8e1e1e1e16b6bc3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e10000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3f8f8e1e1e1e1e16b6bc3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1 -e1e1e1e1e100e1e1e1e1e1e10000000000e1e1e100e1e1e1e1e1e1e1e1000000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e10000000000e1 -e1e100e1e1e1e1e1e1e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3f8f8e1e1e1e1e1e16b6bc3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e100000000000000e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3f8f8e1e1e1e1e1e1e16b6bc3c3f8f8d9c07676763939 -c0c076767639d96b6be1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -f8f8e1e1e1e1e1e1e1e16b6bc3c3f8f8d9c07676763939 -c0c076767639d96b6be1e100e1e1e1e1e100e1e100e1e1e1e100e1e1e1e100e1e1e100e1 -e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e10000e1e1e1e100e1e1e1e100e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1 -e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -f8f8e1e1e1e1e1e1e1e1e16b6bc3f8f8d9c07676763939 -c0c076767639d96b6be1e100e1e1e1e1e100e1e10000000000e1e1e1e1e1e1000000e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1 -e1e1e1e1e1e1000000e1e1e1000000e1e10000e1e1e100000000e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e100e1e1e1e1e1e1e1e1000000e1e100 -00e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f86b6b6b6b6b6b6b6b6b6b6b6bc3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -6b6b6b6b6b6b6b6b6b6b6b6b6b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3c3c3c3c3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8f8f8f8f8f8f8f8f8f8f8f8f86bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100000000e1e1e1e1e1000000e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1000000000000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e100e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e100e1e1e1e1e1e1e100000000e1 -e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e100000000e1e1e100e1e1e1e1e100 -e1e100000000000000e1e1e1e100000000e1e1e1e100e1e1e1e100e1e100e1e1e1e1e100 -e1e100000000000000e1e1e1e100000000e1e1e100e1e1e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e10000000000e1e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100000000000000e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100000000000000e1e100000000000000e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100 -e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e100000000000000e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e100e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e10000e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e10000000000e1 -e1e1e1e100e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100000000e1e1e1e1e100e1e1e100e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100000000000000e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100000000000000e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e100e1e1e1e1e100000000000000e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100000000000000e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be100000000000000e1e1e1e100000000000000e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e1e1e100e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e10000 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100 -e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e10000e1e100e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e100e1 -e1e1e100e1e1e10000e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1 -e1e1e1e100000000e1e1e1e10000000000e1e1e1e1e100e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100e1e1e1e1e1e1000000000000 -e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1000000e1e100 -e1e1e1e1e1e1000000e1e1e1e100000000e1e1e1e10000000000e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1000000e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1000000e1e1 -e1e1e1e1000000e100e1e1e1e100000000e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1 -e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1000000e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1 -e1e1e1e100e1e1e100e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e10000e1e1e100000000e1e1 -e1e100e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1 -e1e1e1e100000000e1e1e100000000000000e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e10000e1e1e100000000e1e1 -e1e100e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1 -e1e100e1e1000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e100e1 -e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100000000000000e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100000000000000e1e100000000000000e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e100e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e100e10000e100e1e1e1e1e1e1e100e1 -e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e1e1e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e100e10000e100e1e1e1e1e1e1e100e1 -e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e100e1e10000e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e100e10000e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e10000e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e10000e1e1e1e1e1e1e1e1e1e1e100e1 -e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e10000e1e1e1e1e1e1e1e1e1e1e100e1 -e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e10000e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e10000e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e100e1e1e1e1e1e1e1e10000000000e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000000000e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e100e1e1e1e1e1e1e1e10000000000e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e100e1e1e1e100e1e1e100e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be100000000000000e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000000000 -00e1e100e1e1e1e100e1e1e1e10000e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1 -e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1 -e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e10000e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1 -e1e100e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e100e1e100e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1 -e1e1e10000000000e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1000000e1e100 -00e10000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1000000e1e100 -00e1e1e100000000e1e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1000000e1e100 -00e10000000000e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e10000e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1000000000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1000000000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1000000000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100000000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1000000e1 -e1e1e1e1000000e1e1e1e1e10000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1000000e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100 -e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e100000000e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100000000e1e1e100000000000000 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1 -e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100000000000000e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100000000000000e1e1e100e1e1e1e100e1e100000000000000e1e1e100e10000e1e1 -e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e100000000000000e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100e100e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000000000 -e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e10000e1e100e1 -e1e100e1e1e1e1e100e1e1e100000000e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e100000000000000e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100000000000000e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e10000000000e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be100000000000000e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e10000e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100 -e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e100e1 -e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e10000e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e10000000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e1e1e10000e1e1 -e1e1e1e1000000e1e1e1e1e1000000e1e1e1e1e1e1e100000000e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1000000e1e10000e1e1e100000000e1e1e1e1e1e1e1000000 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e10000000000e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e10000000000e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e100e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e100000000e1e1e100e1000000e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100000000e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e10000000000e1 -e1e1e10000000000e1e1e1e1e100000000e1e1e1e100e1e1e10000e1e100000000000000 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100000000000000e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100000000000000e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e10000e1e1e100e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e10000e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e100000000e1e1e1e1e1e10000e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e10000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e10000e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e100000000000000e1e100000000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1e1e1e1000000e1e1e1 -e1e1e1000000e1e1e1e1e100000000000000e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be100000000000000e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e10000e1 -e1e1e1e1e1e10000e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e100e1e1e1e100e1 -e1e100e1e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e10000e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e100000000e1e1e10000000000e1e1 -e1e1e1000000e1e1e1e1e1e1e1000000e1e1e1e1e1e100000000e1e1e1e1e100000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e10000e1e10000000000e1 -e1e1e10000000000e1e1e1e1e100000000e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1000000 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1000000000000000000000000000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e10000e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e10000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e100e100e1e1e1 -e1e1e100000000e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e100e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1e1e100e1000000e1e1 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100000000e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100000000000000e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100000000000000e1e1e100e1e1e1e100e1e100000000000000e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e100e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e100e1e1e100e1e1e1e1e100e1e1e1e10000e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e100000000000000e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e10000000000e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be100000000000000e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e100e1e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1000000000000 -00e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e10000e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e100e1e100e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e100e1e1e1e1e100 -e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1000000e1e10000e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e10000000000e1e1 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1000000000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1000000000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100000000e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e10000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100000000e1e1e1e1e1e1e1e1e1e100e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e10000e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e100e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e1e1e1e1e1e100e1e1e100e1000000e1e1e1e1e1e100000000e1e1e1e100000000e1e1 -e1e100000000000000e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e10000e1e1e1e1000000e1e1 -e1e1e100000000e1e1e1e1e1e100000000e1e1e1e1e100000000e1e1e100000000000000 -e1e1e10000000000e1e1e1e1e1e1e1e100e1e1e100e1e100e1e100e1e1e1e100e100e1e1 -e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e10000e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e10000e100e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e100e100e100e1e1e1e100e100e1e1 -e1e1e100e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100000000000000e1e1e100e1e1e100e1 -e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e100e100e1e1e100e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e100000000000000e1e1e10000000000e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100000000000000e1e1e100e1e1e100e1 -e1e1e1e1e100e1e1e1e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e100000000000000e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1000000e1e1e1e1e1e1e1e100e1e1e1e1e100e100e100e100e1e1e100e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e10000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e100e1 -e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e100e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e1e100e1e1e100e1e1e100000000000000 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e10000e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e1e1e1e1e100e1e1e1e10000e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e100e1 -e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e100e1e1 -e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e1e1e1e1e10000e1e100e100e1e1e100e1e1e100e1 -e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100e1e100e1e1e10000e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1 -e1e1e100e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e1e1e1e1e1e1e1000000e1e100e1e1e1e1000000e1e1 -e1e1e100e1e1e1e1e1e1e10000000000e1e1e1e1e1e100000000e1e1e1e1000000e1e100 -00e100000000000000e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1e1e1000000 -e1e1e10000000000e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e100000000e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1000000e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1e1e1e1000000e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e100000000000000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100000000e1 -e1e100000000000000e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e100000000000000e1e1e1e1e1e1e1e1e1e1e100e1e1000000e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e100e1e10000e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000000000e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e10000e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1000000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1000000e1e10000e1e1e100000000e1 -e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1 -e1e1e10000000000e1e1e1e10000000000e1e1e1e1e100000000e1e1e1e100e1e1e10000 -e1e100000000000000e1e1e1e100e1e1e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e10000e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e10000e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e100000000000000e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1 -e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1e100000000000000e1e1e100e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1 -e1e1e1e1e1e10000e1e1e1e1e1e1e10000e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e100000000000000e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e10000e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e100 -00e1e10000000000e1e1e1e10000000000e1e1e1e1e100000000e1e1e1e100e1e1e1e1e1 -e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e10000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1000000e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e10000 -e1e1e1e100000000e1e1e100000000000000e1e100e1e1e1e1e100e1e1e100e1e1e10000 -e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e100e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e100e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e10000e100 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e10000e100 -e1e100e100e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e10000e1e1e1e1 -e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e100000000000000e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e10000e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e10000e1e100e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1000000e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1 -e1e1e1e100000000e1e1e1e1e1e1e1000000e1e1e1000000e1e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e100e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e10000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e10000000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e10000e1e1e1e100000000e1e1e100000000000000e1e100e1e1e1e1e100 -e1e1e100e1e1e10000e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1e1e100e1e1000000e1 -e1e1e1e100e100e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100000000e1 -e1e100000000000000e1e1e1e100e1e1e1e1e1e100e1e1000000e1e1e1e1e1e1e1e1e1e1 -e1e1e100e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e100e10000e100e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e1e100e10000e100e1e100e100e1e10000e1e1e1e1e1e1e1e1e1e1e100e100e1e10000 -e1e1e100e100e100e1e1e100000000000000e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e100e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e10000e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e1e10000e1e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000000000 -e1e1e1e1e100e1e1e1e1e1e1000000e1e1e1e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e100000000000000e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000000000e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e100000000000000 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e10000e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e10000 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e10000e1e100e100 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e10000e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e10000000000e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e100e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1000000e1e1e1000000e1e100 -e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1000000e1e10000e1e1e100000000e1 -e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e100e1e1e1e1e100 -e1e1e1e1000000e1e1e1e100e1e1e1e100e1e1e1e1e100000000e1e1e1e1e10000000000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1e1e1e1000000e1e1 -e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100000000e1e1 -e1e100000000000000e1e100e1e1000000e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e10000e100e1e1e100e1e1e100e1 -e1e10000e10000e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e100e1e10000e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1000000e1e1e1e1e1e100000000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1000000e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1000000e1e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1000000e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e10000e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1 -e1e1e1e100000000e1e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e1e1e1e1e100e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000000000e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000000000 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e10000e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1000000e1e100 -00e1e1e100000000e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e100e1e1e1e1e100 -e1e1e1e1000000e1e1e1e100e1e1e1e100e1e1e1e1e100000000e1e1e1e1e10000000000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1e1e1e1000000e1e1 -e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100000000e1e1 -e1e100000000000000e1e100e1e1000000e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e10000e100e1e1e100e1e1e100e1 -e1e10000e10000e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e100e1e10000e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1000000e1e1e1e1e1e100000000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1000000e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1000000e1e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1000000e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e100e1e1e1e1e100 -e1e1e1e1000000e1e1e1e100e1e1e1e100e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1000000e1e1e1e1e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e10000000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e10000e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e100e1e1e1e1e100 -e1e1e1e100000000e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1000000e1e1e1e1e1e1000000e1e1e1e1e1e10000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e100e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e100e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e100e1e1e1e1e100 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e10000e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e10000e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100000000000000e1e1e100e1e1e100e1 -e1e100000000000000e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e100e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e100e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e100e100 -e1e100e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e10000e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e100 -e1e10000000000e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100e1e1e1 -e1e1e1e100000000e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e10000000000e1e1e1e1e1e1000000e1e1e1e1e1e1000000e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e100e1e1e1e1e100 -e1e1e1e1000000e1e1e1e100e1e1e1e100e1e1e1e1e100000000e1e1e1e1e10000000000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1e1e1e1000000e1e1 -e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100000000e1e1 -e1e100000000000000e1e100e1e1000000e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e10000e100e1e1e100e1e1e100e1 -e1e10000e10000e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e100e1e10000e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1000000e1e1e1e1e1e100000000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1000000e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1000000e1e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1000000e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e100000000e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100000000e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e10000e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e100e1e1e1e1e100e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1 -e1e1e10000000000e1e1e100000000000000e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e100e1e1e1e1e100e1e1e1e1000000e1e1e1e100e1e1e1e100e1e1e1e1e100000000e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e100e1e100e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e100e1e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e100e1e1e1e1e100e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e10000e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100000000000000e1e1e100e1e1e100e1e1e100000000000000 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1000000e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1 -e1e100e100e100e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1000000e1e1e1e1e1e100000000000000 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e100e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100 -e1e100e100e100e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e100e100e1e1e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e100e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100 -e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e100e100e1e1e1e100e1e1e1e1e100e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e10000e1e100e100e1e100e1e1e1e100e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e100e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100 -e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1000000e1e100e1e10000000000e1e1 -e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1e1e1e1e1e1e1000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1 -e1e1e10000000000e1e1e1e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e10000000000e1 -e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e10000000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000000000e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e10000e1e1e1e1e100e1e1e10000 -e1e1e1e1000000e1e1e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e10000000000 -e1e100e1e1e1e1e100e1e1e100e1e1e10000e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e100e1e1e1e100e1e1e1e100e1e1e1e100 -e1e100e1e1e1e1e100e1e100000000000000e1e100000000000000e1e1e1e1000000e1e1 -e1e100e1e1000000e1e1e100e1e1e1e1e100e1e100e1e10000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e100e1e100e1e1e1e100e10000e100 -e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e100e1e1e1e1e100e1e1e100e10000e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e100e1 -e1e100e100e1e10000e1e100e1e1e1e1e100e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e100e1e1e10000e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e10000e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e100000000e1e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e10000e1e1e1e100e1e100e1e1e1e1e100e1e10000e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100000000000000e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100000000000000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1000000e1e1e1e1e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100000000000000e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e10000e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100 -e1e100e1e1e1e10000e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e1e1 -e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100e1e1e100e1e1e10000 -e1e10000e1e100e100e1e1e100e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100 -e1e10000e1e100e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e10000000000e1e1e1e1e100e1e1e1e1e1 -e1e1e1e1000000e1e1e1e1e1e100000000e1e1e1e1e100000000e1e1e1e1e1000000e100 -e1e1e1000000e1e100e1e1e100e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e100e1e1e1e1e100e1e1e10000000000e1 -e1e1e1000000e1e100e1e1e1e1e1e1000000e1e1e1e1e1e1000000e1e1e1e1000000e1e1 -e1e100e1e1e1e1e100e1e1e1e1000000e1e1e1e10000000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100000000e1e1e1e100e1e1000000e1e1e100e1e1e1e1e100 -e1e1e1e1000000e1e1e1e100e1e1e1e100e1e1e1e1e100000000e1e1e1e1e10000000000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e10000e1e1e1e1000000e1e1 -e1e100e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100000000e1e1 -e1e100000000000000e1e100e1e1000000e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e100e1e10000e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e100e1e1e100e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e100000000000000e1e1e100e10000e100e1e1e100e1e1e100e1 -e1e10000e10000e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e100e1e10000e1e1e1e1e1e100e1e1e1e100e100e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e10000e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e10000e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e1e100e1e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e10000e1e1e1e100e1e1e1e1e1e100e1e1e1e10000e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e1000000e1e1e1e1e1e100000000000000e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e100e100e100e100e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e100e100e1e1 -e1e100e1e1e1e1e100e1e100e1e1e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1e1e10000 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e100e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e100000000e1e1e1e1e1000000e100 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1000000e1e1 -e1e100e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e100e1e1 -e1e1e1e1e1e1000000e1e100e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e10000000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e100000000000000e1e100e1e1e1e100e1 -e1e1e100e1e1e1e100e1e100e1e1e1e1e100e1e100000000000000e1e100000000000000 -e1e1e1e1000000e1e1e1e100e1e1000000e1e1e100e1e1e1e1e100e1e100e1e10000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e100e1e10000e1e100e1e1e1e1e100e1e100e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1 -e1e1e100000000e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e100e1e10000e1e1e1e100e1e100e1e1e1e1e100e1e10000e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1000000e1e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1 -e1e1e100e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1 -e1e1e100e1e1e1e100e1e100e1e1e1e10000e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1 -e1e1e100e1e1e1e100e1e10000e1e100e100e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1 -e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e1e100e1e1e100e1e1e100e1e1e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e100e1e1e1e1e100 -e1e1e10000000000e1e1e1e1000000e1e100e1e1e1e1e1e1000000e1e1e1e1e1e1000000 -e1e1e1e1000000e1e1e1e100e1e1e1e1e100e1e1e1e1000000e1e1e1e10000000000e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e10000000000e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e100e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100000000e1e1e1e1e1000000e1e1 -e1e100e100e1e100e1e1e100e100e1e100e1e1e1e100000000e1e1e1e100e1e1000000e1 -e1e1e1e10000000000e1e1e1e1e1e1e1e1e1e1e100e1000000e1e1e1e1e1e1000000e1e1 -e1e100e1e1e1e1e100e1e100e1e1000000e1e1e1e1e10000000000e1e1e1e1e1e1e1e1e1 -e1e100000000000000e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e100e1e1e1e1e100e1e1e1e100000000e1e1e100e1e1000000e1e1e100000000000000 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e100e1 -e1e10000e10000e100e1e10000e10000e100e1e1e1e1e1e1e100e1e1e100e100e1e10000 -e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1e1e10000e1e1e100e1e1e1e100e1e1e100e1 -e1e100e1e1e1e1e100e1e100e100e1e10000e1e1e100e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e100e1e1e1e1e100e1e1e100e1e1e1e100e1e100e100e1e10000e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e100e1e100e1e100e1e1e1e1e1e1e100e1e1e10000e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e10000e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e1e100e1e1e100e1e1e100e1e1e1e1e100e1e10000e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e100e1e100e1e100e1e1e10000000000e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100000000000000 -e1e1e100e1e1e100e1e1e100000000000000e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e100e1e100e1e100e1e100e1e1e1e100e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e100e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100 -e1e100e1e100e1e100e1e100e1e100e1e100e1e100e1e1e1e100e1e1e100e1e1e1e1e100 -e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e100e1e1e1e1e100 -e1e100e1e1e1e10000e1e100e1e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1 -e1e1e1e100e100e1e1e1e100e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100e1e1e1e100e1e1e100e1e1e100e1 -e1e100e1e100e1e100e1e100e1e100e1e100e1e100e1e1e10000e1e1e100e1e1e1e1e100 -e1e1e100e1e1e10000e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100e1e1e1e100e1e1e100e1 -e1e10000e1e100e100e1e100e1e1e1e1e100e1e1e100e1e1e10000e1e1e1e1e1e1e1e1e1 -e1e1e1e1e100e1e1e1e1e1e100e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e100 -e1e1e1e1e100e1e1e1e1e1e100e1e1e1e100e1e100e1e1e1e1e100e1e1e1e1e100e1e1e1 -e1e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e1e1e1000000e1e1 -e1e100e1e100e1e100e1e100e1e100e1e100e1e1e1000000e1e10000e100e1e1e1e1e100 -e1e1e1e1000000e100e1e1e1e1e1e1e1e1e1e1e10000000000e1e1e1e1e1e1000000e1e1 -e1e1e1000000e1e100e1e100e1e1e1e1e100e1e1e1e1000000e100e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1000000e1e1e1e1000000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100000000e1 -e1e1e1e1e100e1e1e1e1e1e1e100000000e1e1e100e1e1e1e1e100e1e1e1e1e1e1000000 -e1e1e1e1e100e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8e1e1e1e1e1e1e1e1e1e1e16b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e10000e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f86b6b6b6b6b6b6b6b6b6b6b6b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -6b6b6b6b6b6b6b6b6b6b6b6b6b6bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3c3c3c3c3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bf8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -f8f8f8f8f8f8f8f8f8f8f8f8f86bf8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -f8f8e1e1e1e1e1e1e1e1e16b6bc3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3f8f8e1e1e1e1e1e1e1e16b6bc3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3f8f8e1e1e1e1e1e1e16b6bc3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3f8f8e1e1e1e1e1e16b6bc3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3f8f8e1e1e1e1e16b6bc3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3f8f8e1e1e1e16b6bc3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3f8f8e1e1e16b6bc3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3f8f8e1e16b6bc3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3f8f8e16b6bc3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3f86b6b6bc3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3f86b6bc3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3c36b6bc3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6be1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1f8f8d9d96b6bc3 -c3c3c3c3c3c36bc3c3c3c3c3c3c3f8f8d9c07676763939 -c0c076767639d96b6bf8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9d96b6bf8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9c07676763939 -c0c076767639d96bf8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9d96bf8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9c07676763939 -c0c076767639d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9828282828282828282828282828282828282828282828282828282828282828282 -82828282828282828282828282828282828282d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8d9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8 -f8f8f8f8f8f8f8f8f8f8f8f8f8f8f86bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1 -00e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e10000e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e100e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e100e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e1e1e100e1e1e100e1e1e100 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c03939393939e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e100e1e1e100e1e1e1e100e1e1e1e1 -00e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c03939393939 -c0c0c0c0c0c0e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1000000e1e1e1e1e100e1e1e1e1 -00e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c0c0c0c0c039 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f8e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e16b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f8f86b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9f86b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b -6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6bd9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d982ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffd9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9 -d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1 -e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c07676763939 -c0c076767639c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 -c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c07676763939 -c0c0767676767676767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767676767676763939 -c0c0767676767676767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767676767676763939 -c0c0767676767676767676767676767676767676767676767676767639c0767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767676767676767676 -767676767676767676767676767676767676767676767676767676767639c07676767676 -7676767676767676767676767676767676767676763939 -c0c0393939393939393939393939393939393939393939393939393939c0393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939c03939393939 -3939393939393939393939393939393939393939393939 -c03939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -393939393939393939393939393939393939393939393939393939393939393939393939 -3939393939393939393939393939393939393939393939 - -showpage - -% stop using temporary dictionary -end - -% restore original state -origstate restore - -%%Trailer diff --git a/Tools/WAD/Papers/usenix2001.tex b/Tools/WAD/Papers/usenix2001.tex deleted file mode 100644 index f81e42824..000000000 --- a/Tools/WAD/Papers/usenix2001.tex +++ /dev/null @@ -1,1347 +0,0 @@ -%template for producing IEEE-format articles using LaTeX. -%written by Matthew Ward, CS Department, Worcester Polytechnic Institute. -%use at your own risk. Complaints to /dev/null. -%make two column with no page numbering, default is 10 point -%\documentstyle{article} -\documentstyle[twocolumn,times]{article} -\pagestyle{empty} - -%set dimensions of columns, gap between columns, and space between paragraphs -%\setlength{\textheight}{8.75in} -\setlength{\textheight}{9.0in} -\setlength{\columnsep}{0.25in} -\setlength{\textwidth}{6.45in} -\setlength{\footheight}{0.0in} -\setlength{\topmargin}{0.0in} -\setlength{\headheight}{0.0in} -\setlength{\headsep}{0.0in} -\setlength{\oddsidemargin}{0in} -%\setlength{\oddsidemargin}{-.065in} -%\setlength{\oddsidemargin}{-.17in} -%\setlength{\parindent}{0pc} - -%I copied stuff out of art10.sty and modified them to conform to IEEE format - -\makeatletter -%as Latex considers descenders in its calculation of interline spacing, -%to get 12 point spacing for normalsize text, must set it to 10 points -\def\@normalsize{\@setsize\normalsize{12pt}\xpt\@xpt -\abovedisplayskip 10pt plus2pt minus5pt\belowdisplayskip \abovedisplayskip -\abovedisplayshortskip \z@ plus3pt\belowdisplayshortskip 6pt plus3pt -minus3pt\let\@listi\@listI} - -%need an 11 pt font size for subsection and abstract headings -\def\subsize{\@setsize\subsize{12pt}\xipt\@xipt} - -%make section titles bold and 12 point, 2 blank lines before, 1 after -\def\section{\@startsection {section}{1}{\z@}{24pt plus 2pt minus 2pt} -{12pt plus 2pt minus 2pt}{\large\bf}} - -%make subsection titles bold and 11 point, 1 blank line before, 1 after -\def\subsection{\@startsection {subsection}{2}{\z@}{12pt plus 2pt minus 2pt} -{12pt plus 2pt minus 2pt}{\subsize\bf}} -\makeatother - -\newcommand{\ignore}[1]{} -%\renewcommand{\thesubsection}{\arabic{subsection}.} - -\begin{document} - -%don't want date printed -\date{} - -%make title bold and 14 pt font (Latex default is non-bold, 16 pt) -\title{\Large \bf An Embedded Error Recovery and Debugging Mechanism for Scripting Language Extensions} - -%for single author (just remove % characters) -\author{{David M.\ Beazley} \\ -{\em Department of Computer Science} \\ -{\em University of Chicago }\\ -{\em Chicago, Illinois 60637 }\\ -{\em beazley@cs.uchicago.edu }} - -% My Department \\ -% My Institute \\ -% My City, ST, zip} - -%for two authors (this is what is printed) -%\author{\begin{tabular}[t]{c@{\extracolsep{8em}}c} -% Roscoe Giles & Pablo Tamayo \\ -% \\ -% Department of Electrical, Computer, & Thinking Machines Corp. \\ -% and Systems Engineering & Cambridge, MA~~02142. \\ -% and & \\ -% Center for Computational Science & \\ -% Boston University, Boston, MA~~02215. & -%\end{tabular}} - -\maketitle - -%I don't know why I have to reset thispagesyle, but otherwise get page numbers -\thispagestyle{empty} - - -\subsection*{Abstract} -{\em -In recent years, scripting languages such as Perl, Python, and Tcl -have become popular development tools for the creation of -sophisticated application software. One of the most useful features -of these languages is their ability to easily interact with compiled -languages such as C and C++. Although this mixed language approach -has many benefits, one of the greatest drawbacks is the complexity of -debugging that results from using interpreted and compiled code in the -same application. In part, this is due to the fact that scripting -language interpreters are unable to recover from catastrophic errors -in compiled extension code. Moreover, traditional C/C++ debuggers -do not provide a satisfactory degree of integration with interpreted -languages. This paper describes an experimental system in which fatal -extension errors such as segmentation faults, bus errors, and failed -assertions are handled as scripting language exceptions. This system, -which has been implemented as a general purpose shared library, -requires no modifications to the target scripting language, introduces -no performance penalty, and simplifies the debugging of mixed -interpreted-compiled application software. -} - -\section{Introduction} - -Slightly more than ten years have passed since John Ousterhout -introduced the Tcl scripting language at the 1990 USENIX technical -conference \cite{ousterhout}. Since then, scripting languages have -been gaining in popularity as evidenced by the wide-spread use of -systems such as Tcl, Perl, Python, Guile, PHP, and Ruby -\cite{ousterhout,perl,python,guile,php,ruby}. - -In part, the success of modern scripting languages is due to their -ability to be easily integrated with software written in compiled -languages such as C, C++, and Fortran. In addition, a wide variety of wrapper -generation tools can be used -to automatically produce bindings between existing code and a -variety of scripting language environments -\cite{swig,sip,pyfort,f2py,advperl,heidrich,vtk,gwrap,wrappy}. As a result, a large number of -programmers are now using scripting languages to control -complex C/C++ programs or as a tool for re-engineering legacy -software. This approach is attractive because it allows programmers -to benefit from the flexibility and rapid development of -scripting while retaining the best features of compiled code such as high -performance \cite{ouster1}. - -A critical aspect of scripting-compiled code integration is the way in -which it departs from traditional C/C++ development and shell -scripting. Rather than building stand-alone applications that run as -separate processes, extension programming encourages a style of -programming in which components are tightly integrated within -an interpreter that is responsible for high-level control. -Because of this, scripted software tends to rely heavily -upon shared libraries, dynamic loading, scripts, and -third-party extensions. In this sense, one might argue that the -benefits of scripting are achieved at the expense of creating a -more complicated development environment. - -A consequence of this complexity is an increased degree of difficulty -associated with debugging programs that utilize multiple languages, -dynamically loadable modules, and a sophisticated runtime environment. -To address this problem, this paper describes an experimental system -known as WAD (Wrapped Application Debugger) in which an embedded error -reporting and debugging mechanism is added to common scripting -languages. This system converts catastrophic signals such as -segmentation faults and failed assertions to exceptions that can be -handled by the scripting language interpreter. In doing so, it -provides more seamless integration between error handling in -scripting language interpreters and compiled extensions. - -\section{The Debugging Problem} - -Normally, a programming error in a scripted application -results in an exception that describes the problem and the context in -which it occurred. For example, an error in a Python script might -produce a traceback similar to the following: - -\begin{verbatim} -% python foo.py -Traceback (innermost last): - File "foo.py", line 11, in ? - foo() - File "foo.py", line 8, in foo - bar() - File "foo.py", line 5, in bar - spam() - File "foo.py", line 2, in spam - doh() -NameError: doh -\end{verbatim} - -In this case, a programmer might be able to apply a fix simply based -on information in the traceback. Alternatively, if the problem is -more complicated, a script-level debugger can be used to provide more -information. In contrast, a failure in compiled extension code might -produce the following result: - -\begin{verbatim} -% python foo.py -Segmentation Fault (core dumped) -\end{verbatim} - -In this case, the user has no idea of what has happened other than it -appears to be ``very bad.'' Furthermore, script-level debuggers are -unable to identify the problem since they also crash when the error -occurs (they run in the same process as the interpreter). This means -that the only way for a user to narrow the source of the problem -within a script is through trial-and-error techniques such as -inserting print statements, commenting out sections of scripts, or -having a deep intuition of the underlying implementation. Obviously, -none of these techniques are particularly elegant. - -An alternative approach is to run the application under the control of -a traditional debugger such as gdb \cite{gdb}. Although this provides -some information about the error, the debugger mostly provides -detailed information about the internal implementation of the -scripting language interpreter instead of the script-level code that -was running at the time of the error. Needless to say, this information -isn't very useful to most programmers. -A related problem is that -the structure of a scripted application tends to be much more complex -than a traditional stand-alone program. As a result, a user may not -have a good sense of how to actually attach an external debugger to their -script. In addition, execution may occur within a -complex run-time environment involving events, threads, and network -connections. Because of this, it can be difficult for the user to reproduce -and identify certain types of catastrophic errors if they depend on -timing or unusual event sequences. Finally, this approach -requires a programmer to have a C development environment installed on -their machine. Unfortunately, this may not hold in practice. -This is because scripting languages are often used to provide programmability to -applications where end-users write scripts, but do not write low-level C code. - -Even if a traditional debugger such as gdb were modified to provide -better integration with scripting languages, it is not clear that this -would be the most natural solution to the problem. For one, -having to run a separate debugging process to debug -extension code is unnatural when no such requirement exists for -scripts. Moreover, even if such a debugger existed, an -inexperienced user may not have the expertise or inclination to use -it. Finally, obscure fatal errors may occur long after an application -has been deployed. Unless the debugger is distributed along with the -application in some manner, it will be extraordinary difficult to -obtain useful diagnostics when such errors occur. - -\begin{figure*}[t] -{\small -\begin{verbatim} -% python foo.py -Traceback (most recent call last): - File "", line 1, in ? - File "foo.py", line 16, in ? - foo() - File "foo.py", line 13, in foo - bar() - File "foo.py", line 10, in bar - spam() - File "foo.py", line 7, in spam - doh.doh(a,b,c) - -SegFault: [ C stack trace ] - -#2 0x00027774 in call_builtin(func=0x1c74f0,arg=0x1a1ccc,kw=0x0) in 'ceval.c',line 2650 -#1 0xff083544 in _wrap_doh(self=0x0,args=0x1a1ccc) in 'foo_wrap.c',line 745 -#0 0xfe7e0568 in doh(a=3,b=4,c=0x0) in 'foo.c',line 28 - -/u0/beazley/Projects/WAD/Python/foo.c, line 28 - - int doh(int a, int b, int *c) { - => *c = a + b; - return *c; - } -\end{verbatim} -} -\caption{Cross language traceback generated by WAD for a segmentation fault in a Python extension} -\end{figure*} - -The current state of the art in extension debugging is to simply add -as much error checking as possible to extension modules. This is never -a bad thing to do, but in practice it's usually not enough to -eliminate every possible problem. For one, scripting languages are -sometimes used to control hundreds of thousands to millions of lines -of compiled code. In this case, it is improbable that a programmer will -foresee every conceivable error. In addition, scripting languages are -often used to put new user interfaces on legacy software. In this -case, scripting may introduce new modes of execution that cause a -formerly ``bug-free'' application to fail in an unexpected manner. -Finally, certain types of errors such as floating-point exceptions can -be particularly difficult to eliminate because they might be generated -algorithmically (e.g., as the result of instability in a numerical -method). Therefore, even if a programmer has worked hard to eliminate -crashes, there is usually a small probability that an application may -fail under unusual circumstances. - -\section{Embedded Error Reporting} - -Rather than modifying an existing debugger to support scripting -languages, an alternative approach is to add a more powerful error -handling and reporting mechanism to the scripting language -interpreter. We have implemented this approach in the form of an -experimental system known as WAD. WAD is packaged as dynamically -loadable shared library that can either be loaded as a scripting -language extension module or linked to existing extension modules as a -library. The core of the system is generic and requires no -modifications to the scripting interpreter or existing extension -modules. Furthermore, the system does not introduce a performance -penalty as it does not rely upon program instrumentation or tracing. - -WAD works by converting fatal signals such as SIGSEGV, -SIGBUS, SIGFPE, and SIGABRT into scripting language exceptions that contain -debugging information collected from the call-stack of compiled -extension code. By handling errors in this manner, the scripting -language interpreter is able to produce a cross-language stack trace that -contains information from both the script code and extension code as -shown for Python and Tcl/Tk in Figures 1 and 2. In this case, the user -is given a very clear idea of what has happened without having -to launch a separate debugger. - -The advantage to this approach is that it provides more seamless -integration between error handling in scripts and error handling in -extensions. In addition, it eliminates the most common debugging step -that a developer is likely to perform in the event of a fatal -error--running a separate debugger on a core file and typing 'where' -to get a stack trace. Finally, this allows end-users to provide -extension writers with useful debugging information since they can -supply a stack trace as opposed to a vague complaint that the program -``crashed.'' - -\begin{figure*}[t] -\begin{picture}(400,250)(0,0) -\put(50,-110){\special{psfile = tcl.ps hscale = 60 vscale = 60}} -\end{picture} -\caption{Dialog box with WAD generated traceback information for a failed assertion in a Tcl/Tk extension} -\end{figure*} - -\section{Scripting Language Internals} - -In order to provide embedded error recovery, it is critical to understand how -scripting language interpreters interface with extension code. Despite the wide variety -of scripting languages, essentially every implementation uses a similar -technique for accessing foreign code. - -Virtually all scripting languages provide an extension mechanism in the form of a foreign function -interface in which compiled procedures can be called from the scripting language -interpreter. This is accomplished by writing a collection of wrapper functions that conform -to a specified calling convention. The primary purpose of the wrappers are to -marshal arguments and return values between the two languages and to handle errors. -For example, in Tcl, every wrapper -function must conform to the following prototype: - -\begin{verbatim} -int -wrap_foo(ClientData clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[]) -{ - /* Convert arguments */ - ... - /* Call a function */ - - result = foo(args); - /* Set result */ - ... - if (success) { - return TCL_OK; - } else { - return TCL_ERROR; - } -} -\end{verbatim} - -Another common extension mechanism is an object/type interface that allows programmers to create new -kinds of fundamental types or attach special properties to objects in -the interpreter. For example, both Tcl and Python provide an API for creating new -``built-in'' objects that behave like numbers, strings, lists, etc. -In most cases, this involves setting up tables of function -pointers that define various properties of an object. For example, if -you wanted to add complex numbers to an interpreter, you might fill in a special -data structure with pointers to methods that implement various numerical operations like this: - -\begin{verbatim} -NumberMethods ComplexMethods { - complex_add, - complex_sub, - complex_mul, - complex_div, - ... -};\end{verbatim} - -\noindent -Once registered with the interpreter, the methods in this structure -would be invoked by various interpreter operators such as $+$, -$-$, $*$, and $/$. - -Most interpreters handle errors as a two-step process in which -detailed error information is first registered with the interpreter -and then a special error code is returned. For example, in Tcl, errors -are handled by setting error information in the interpreter and -returning a value of TCL\_ERROR. Similarly in Python, errors are -handled by calling a special function to raise an exception and returning NULL. In both cases, -this triggers the interpreter's error handler---possibly resulting in -a stack trace of the running script. In some cases, an interpreter -might handle errors using a form of the C {\tt longjmp} function. -For example, Perl provides a special function {\tt die} that jumps back -to the interpreter with a fatal error \cite{advperl}. - -The precise implementation details of these mechanisms aren't so -important for our discussion. The critical point is that scripting -languages always access extension code though a well-defined interface -that precisely defines how arguments are to be passed, values are to be -returned, and errors are to be handled. - -\section{Scripting Languages and Signals} - -Under normal circumstances, errors in extension code are handled -through the error-handling API provided by the scripting language -interpreter. For example, if an invalid function parameter is passed, -a program can simply set an error message and return to the -interpreter. Similarly, automatic wrapper generators such as SWIG can produce -code to convert C++ exceptions and other C-related error handling -schemes to scripting language errors \cite{swigexcept}. On the other -hand, segmentation faults, failed assertions, and similar problems -produce signals that cause the interpreter to abort execution. - -Most scripting languages provide limited support for Unix signal -handling \cite{stevens}. However, this support is not sufficiently advanced to -recover from fatal signals produced by extension code. -Unlike signals generated for asynchronous events such as I/O, -execution can {\em not} be resumed at the point of a fatal signal. -Therefore, even if such a signal could be caught and handled by a script, -there isn't much that it can do except to print a diagnostic -message and abort before the signal handler returns. In addition, -some interpreters block signal delivery while executing -extension code--opting to handle signals at a time when it is more convenient. -In this case, a signal such as SIGSEGV would simply cause the whole application -to freeze since there is no way for execution to continue to a point where -the signal could be delivered. Thus, scripting languages tend to -either ignore the problem or label it as a ``limitation.'' - -\section{Overview of WAD} - -WAD installs a signal handler for SIGSEGV, SIGBUS, SIGABRT, SIGILL, -and SIGFPE using the {\tt sigaction} function -\cite{stevens}. Furthermore, it uses a special option (SA\_SIGINFO) of -signal handling that passes process context information to the signal -handler when a signal occurs. Since none of these signals are normally used in the -implementation of the scripting interpreter or by user scripts, -this does not usually override any previous signal handling. -Afterwards, when one of these signals occurs, a two-phase recovery -process executes. First, information is collected about the execution -context including a full stack-trace, symbol table entries, and -debugging information. Then, the current stream of execution is -aborted and an error is returned to the interpreter. This process is -illustrated in Figure~3. - -The collection of context and debugging information involves the -following steps: - -\begin{itemize} -\item The program counter and stack pointer are obtained from -context information passed to the signal handler. - -\item The virtual memory map of the process is obtained from /proc -and used to associate virtual memory addresses with executable files, -shared libraries, and dynamically loaded extension modules \cite{proc}. - -\item The call stack is unwound to collect traceback information. -At each step of the stack traceback, symbol table and debugging -information is gathered and stored in a generic data structure for later use -in the recovery process. This data is obtained by memory-mapping -the object files associated with the process and extracting -symbol table and debugging information. -\end{itemize} - -Once debugging information has been collected, the signal handler -enters an error-recovery phase that -attempts to raise a scripting exception and return to a suitable location in the -interpreter. To do this, the following steps are performed: - -\begin{itemize} - -\item The stack trace is examined to see if there are any locations in the interpreter -to which control can be returned. - -\item If a suitable return location is found, the CPU context is modified in -a manner that makes the signal handler return to the interpreter -with an error. This return process is assisted by a small -trampoline function (partially written in assembly language) that arranges a proper -return to the interpreter after the signal handler returns. -\end{itemize} - -\noindent -Of the two phases, the first is the most straightforward to implement -because it involves standard Unix API functions and common file formats such -as ELF and stabs \cite{elf,stabs}. On the other hand, the recovery phase in -which control is returned to the interpreter is of greater interest. Therefore, -it is now described in greater detail. - -\begin{figure*}[t] -\begin{picture}(480,340)(5,60) - -\put(50,330){\framebox(200,70){}} -\put(60,388){\small \tt >>> {\bf foo()}} -\put(60,376){\small \tt Traceback (most recent call last):} -\put(70,364){\small \tt File "", line 1, in ?} -\put(60,352){\small \tt SegFault: [ C stack trace ]} -\put(60,340){\small \tt ...} - -\put(55,392){\line(-1,0){25}} -\put(30,392){\line(0,-1){80}} -\put(30,312){\line(1,0){95}} -\put(125,312){\vector(0,-1){10}} -\put(175,302){\line(0,1){10}} -\put(175,312){\line(1,0){95}} -\put(270,312){\line(0,1){65}} -\put(270,377){\vector(-1,0){30}} - -\put(50,285){\framebox(200,15)[c]{[Python internals]}} -\put(125,285){\vector(0,-1){10}} -\put(175,275){\vector(0,1){10}} -\put(50,260){\framebox(200,15)[c]{call\_builtin()}} -\put(125,260){\vector(0,-1){10}} -%\put(175,250){\vector(0,1){10}} -\put(50,235){\framebox(200,15)[c]{wrap\_foo()}} -\put(125,235){\vector(0,-1){10}} -\put(50,210){\framebox(200,15)[c]{foo()}} -\put(125,210){\vector(0,-1){10}} -\put(50,185){\framebox(200,15)[c]{doh()}} -\put(125,185){\vector(0,-1){20}} -\put(110,148){SIGSEGV} -\put(160,152){\vector(1,0){100}} -\put(260,70){\framebox(200,100){}} -\put(310,155){WAD signal handler} -\put(265,140){1. Unwind C stack} -\put(265,125){2. Gather symbols and debugging info} -\put(265,110){3. Find safe return location} -\put(265,95){4. Raise Python exception} -\put(265,80){5. Modify CPU context and return} - -\put(260,185){\framebox(200,15)[c]{return assist}} -\put(365,174){Return from signal} -\put(360,170){\vector(0,1){15}} -\put(360,200){\line(0,1){65}} - -%\put(360,70){\line(0,-1){10}} -%\put(360,60){\line(1,0){110}} -%\put(470,60){\line(0,1){130}} -%\put(470,190){\vector(-1,0){10}} - -\put(360,265){\vector(-1,0){105}} -\put(255,250){NULL} -\put(255,270){Return to interpreter} - -\end{picture} - -\caption{Control Flow of the Error Recovery Mechanism for Python} -\label{wad} -\end{figure*} - -\section{Returning to the Interpreter} - -To return to the interpreter, WAD maintains a table of symbolic names -that correspond to locations within the interpreter -responsible for invoking wrapper functions and object/type methods. -For example, Table 1 shows a partial list of return locations used in -the Python implementation. When an error occurs, the call stack is -scanned for the first occurrence of any symbol in this table. If a -match is found, control is returned to that location by emulating the -return of a wrapper function with the error code from the table. If no -match is found, the error handler simply prints a stack trace to -standard output and aborts. - -When a symbolic match is found, WAD invokes a special user-defined -handler function that is written for a specific scripting language. -The primary role of this handler is to take debugging information -gathered from the call stack and generate an appropriate scripting -language error. One peculiar problem of this step is that the -generation of an error may require the use of parameters passed to a -wrapper function. For example, in the Tcl wrapper shown earlier, one -of the arguments was an object of type ``{\tt Tcl\_Interp *}''. This -object contains information specific to the state of the interpreter -(and multiple interpreter objects may exist in a single application). -Unfortunately, no reference to the interpreter object is available in the -signal handler nor is a reference to interpreter guaranteed to exist in -the context of a function that generated the error. - -To work around this problem, WAD implements a feature -known as argument stealing. When examining the call-stack, the signal -handler has full access to all function arguments and local variables of each function -on the stack. -Therefore, if the handler knows that an error was generated while -calling a wrapper function (as determined by looking at the symbol names), -it can grab the interpreter object from the stack frame of the wrapper and -use it to set an appropriate error code before returning to the interpreter. -Currently, this is managed by allowing the signal handler to steal -arguments from the caller using positional information. -For example, to grab the {\tt Tcl\_Interp *} object from a Tcl wrapper function, -code similar to the following is written: - -\begin{verbatim} -Tcl_Interp *interp; -int err; - -interp = (Tcl_Interp *) - wad_steal_outarg( - stack, - "TclExecuteByteCode", - 1, - &err - ); - ... -if (!err) { - Tcl_SetResult(interp,errtype,...); - Tcl_AddErrorInfo(interp,errdetails); -} -\end{verbatim} - -In this case, the Tcl interpreter argument passed to a wrapper function -is stolen and used to generate an error. Also, the name {\tt TclExecuteByteCode} -refers to the calling function, not the wrapper function itself. -At this time, argument stealing is only applicable to simple types -such as integers and pointers. However, this appears to be adequate for generating -scripting language errors. - - -\begin{table}[t] -\begin{center} -\begin{tabular}{ll} -Python symbol & Error return value \\ \hline -call\_builtin & NULL \\ -PyObject\_Print & -1 \\ -PyObject\_CallFunction & NULL \\ -PyObject\_CallMethod & NULL \\ -PyObject\_CallObject & NULL \\ -PyObject\_Cmp & -1 \\ -PyObject\_DelAttrString & -1 \\ -PyObject\_DelItem & -1 \\ -PyObject\_GetAttrString & NULL \\ -\end{tabular} -\end{center} - -\label{returnpoints} -\caption{A partial list of symbolic return locations in the Python interpreter} -\end{table} - -\section{Register Management} - -A final issue concerning the return mechanism has to do with the -behavior of the non-local return to the interpreter. Roughly -speaking, this emulates the C {\tt longjmp} -library call. However, this is done without the use of a matching -{\tt setjmp} in the interpreter. - -The primary problem with aborting execution and returning to the -interpreter in this manner is that most compilers use a register -management technique known as callee-save \cite{prag}. In this case, -it is the responsibility of the called function to save the state of -the registers and to restore them before returning to the caller. By -making a non-local jump, registers may be left in an inconsistent -state due to the fact that they are not restored to their original -values. The {\tt longjmp} function in the C library avoids this -problem by relying upon {\tt setjmp} to save the registers. Unfortunately, -WAD does not have this luxury. As a result, a return from the signal -handler may produce a corrupted set of registers at the point of return -in the interpreter. - -The severity of this problem depends greatly on the architecture and -compiler. For example, on the SPARC, register windows effectively -solve the callee-save problem \cite{sparc}. In this case, each stack -frame has its own register window and the windows are flushed to the -stack whenever a signal occurs. Therefore, the recovery mechanism can -simply examine the stack and arrange to restore the registers to their -proper values when control is returned. Furthermore, certain -conventions of the SPARC ABI resolve several related issues. For -example, floating point registers are caller-saved and the contents of -the SPARC global registers are not guaranteed to be preserved across -procedure calls (in fact, they are not even saved by {\tt setjmp}). - -On other platforms, the problem of register management becomes -more interesting. In this case, a heuristic approach that examines -the machine code for each function on the call stack can be used to -determine where the registers might have been saved. This approach is -used by gdb and other debuggers when they allow users to inspect -register values within arbitrary stack frames \cite{gdb}. Even though -this sounds complicated to implement, the algorithm is greatly -simplified by the fact that compilers typically generate code to store -the callee-save registers immediately upon the entry to each function. -In addition, this code is highly regular and easy to examine. For -instance, on i386-Linux, the callee-save registers can be restored by -simply examining the first few bytes of the machine code for each -function on the call stack to figure out where values have been saved. -The following code shows a typical sequence of machine instructions -used to store callee-save registers on i386-Linux: - -\begin{verbatim} -foo: -55 pushl %ebp -89 e5 mov %esp, %ebp -83 a0 subl $0xa0,%esp -56 pushl %esi -57 pushl %edi -... -\end{verbatim} - -% -% Include an example -% - -% more interesting. One approach is to simply ignore the problem -% altogether and return to the interpreter with the registers in an -% essentially random state. Surprisingly, this approach actually seems to work (although a considerable degree of -% caution might be in order). -% This is because the return of an error code tends to trigger -% a cascade of procedure returns within the implementation of the interpreter. -% As a result, the values of the registers are simply discarded and -% overwritten with restored values as the interpreter unwinds itself and prepares to handle an -% exception. A better solution to this problem is to modify the recovery mechanism to discover and -% restore saved registers from the stack. Unfortunately, there is -% no standardized way to know exactly where the registers might have been saved. -% Therefore, a heuristic scheme that examines the machine code for each procedure would -% have to be used to try and identify stack locations. This approach is used by gdb -% and other debuggers when they allow users to inspect register values -% within arbitrary stack frames \cite{gdb}. However, this technique has -% not yet been implemented in WAD due to its obvious implementation difficulty and the -% fact that the WAD prototype has primarily been developed for the SPARC. - -As a fall-back, WAD could be configured to return control to a location -previously specified with {\tt setjmp}. Unfortunately, this either -requires modifications to the interpreter or its extension modules. -Although this kind of instrumentation could be facilitated by automatic -wrapper code generators, it is not a preferred solution and is not discussed further. - -\section{Initialization} - -To simplify the debugging of extension modules, it -is desirable to make the use of WAD as transparent as possible. -Currently, there are two ways in which the system is used. First, WAD -may be explicitly loaded as a scripting language extension module. -For instance, in Python, a user can include the statement {\tt import -libwadpy} in a script to load the debugger. Alternatively, WAD can be -enabled by linking it to an extension module as a shared -library. For instance: - -\begin{verbatim} -% ld -shared $(OBJS) -lwadpy -\end{verbatim} - -In this latter case, WAD initializes itself whenever the extension module is -loaded. The same shared library is used for both situations by making -sure two types of initialization techniques are used. First, an empty -initialization function is written to make WAD appear like a proper -scripting language extension module (although it adds no functions to -the interpreter). Second, the real initialization of the system is -placed into the initialization section of the WAD shared library -object file (the ``init'' section of ELF files). This code always executes -when a library is loaded by the dynamic loader is commonly used to -properly initialize C++ objects. Therefore, a fairly portable way -to force code into the initialization section is to encapsulate the -initialization in a C++ statically constructed object like this: - -\begin{verbatim} -class InitWad { - public: - InitWad() { wad_init(); } -}; -/* This forces InitWad() to execute - on loading. */ -static InitWad init; -\end{verbatim} - -The nice part about this technique is that it allows WAD to be enabled -simply by linking or loading; no special initialization code needs to -be added to an extension module to make it work. In addition, due to -the way in which the loader resolves and initializes libraries, the -initialization of WAD is guaranteed to execute before any of the code -in the extension module to which it has been linked. The primary -downside to this approach is that the WAD shared object file can not be -linked directly to an interpreter. This is because WAD sometimes needs to call the -interpreter to properly initialize its exception handling mechanism (for instance, in Python, -four new types of exceptions are added to the interpreter). Clearly this type of initialization -is impossible if WAD is linked directly to an interpreter as -its initialization process would execute before before the main program of the -interpreter started. However, -if you wanted to permanently add WAD to an interpreter, the problem is easily -corrected by first removing the C++ initializer from WAD and then replacing it with an explicit -initialization call someplace within the interpreter's startup function. - -\section{Exception Objects} - -Before WAD returns control to the interpreter, it collects all of the -stack-trace and debugging information it was able to obtain into a -special exception object. This object represents the state of the call -stack and includes things like symbolic names for each stack frame, -the names, types, and values of function parameters and stack -variables, as well as a complete copy of data on the stack. This -information is represented in a generic manner that hides -platform specific details related to the CPU, object file formats, -debugging tables, and so forth. - -Minimally, the exception data is used to print a stack trace as shown -in Figure 1. However, if the interpreter is successfully able to -regain control, the contents of the exception object can be -freely examined after an error has occurred. For example, a Python -script could catch a segmentation fault and print debugging information -like this: - -\begin{verbatim} -try: - # Some buggy code - ... -except SegFault,e: - print 'Whoa!' - # Get WAD exception object - t = e.args[0] - # Print location info - print t.__FILE__ - print t.__LINE__ - print t.__NAME__ - print t.__SOURCE__ - ... -\end{verbatim} - -Inspection of the exception object also makes it possible to write post mortem -script debuggers that merge the call stacks of the two languages and -provide cross language diagnostics. Figure 4 shows an -example of a simple mixed language debugging session using the WAD -post-mortem debugger (wpm) after an extension error has occurred in a -Python program. In the figure, the user is first presented with a -multi-language stack trace. The information in this trace is obtained -both from the WAD exception object and from the Python traceback -generated when the exception was raised. Next, we see the user walking -up the call stack using the 'u' command of the debugger. As this -proceeds, there is a seamless transition from C to Python where the -trace crosses between the two languages. An optional feature of the -debugger (not shown) allows the debugger to walk up the entire C -call-stack (in this case, the trace shows information about the -implementation of the Python interpreter). More advanced features of -the debugger allow the user to query values of function -parameters, local variables, and stack frames (although some of this -information may not be obtainable due to compiler optimizations and the -difficulties of accurately recovering register values). - -\begin{figure*}[t] -{\small -\begin{verbatim} -[ Error occurred ] ->>> from wpm import * -*** WAD Debugger *** -#5 [ Python ] in self.widget._report_exception() in ... -#4 [ Python ] in Button(self,text="Die", command=lambda x=self: ... -#3 [ Python ] in death_by_segmentation() in death.py, line 22 -#2 [ Python ] in debug.seg_crash() in death.py, line 5 -#1 0xfeee2780 in _wrap_seg_crash(self=0x0,args=0x18f114) in 'pydebug.c', line 512 -#0 0xfeee1320 in seg_crash() in 'debug.c', line 20 - - int *a = 0; - => *a = 3; - return 1; - ->>> u -#1 0xfeee2780 in _wrap_seg_crash(self=0x0,args=0x18f114) in 'pydebug.c', line 512 - - if(!PyArg_ParseTuple(args,":seg_crash")) return NULL; - => result = (int )seg_crash(); - resultobj = PyInt_FromLong((long)result); - ->>> u -#2 [ Python ] in debug.seg_crash() in death.py, line 5 - - def death_by_segmentation(): - => debug.seg_crash() - ->>> u -#3 [ Python ] in death_by_segmentation() in death.py, line 22 - - if ty == 1: - => death_by_segmentation() - elif ty == 2: ->>> \end{verbatim} -} -\caption{Cross-language debugging session in Python where a user is walking a mixed language call stack.} -\end{figure*} - -\section{Implementation Details} - -Currently, WAD is implemented in ANSI C and small amount of assembly -code to assist in the return to the interpreter. The current -implementation supports Python and Tcl extensions on SPARC Solaris and -i386-Linux. Each scripting language is currently supported by a -separate shared library such as {\tt libwadpy.so} and {\tt -libwadtcl.so}. In addition, a language neutral library {\tt -libwad.so} can be linked against non-scripted applications (in which case -a stack trace is simply printed to standard error when a problem occurs). -The entire implementation contains approximately 2000 -semicolons. Most of this code pertains to the gathering of debugging -information from object files. Only a small part of the code is -specific to a particular scripting language (170 semicolons for Python -and 50 semicolons for Tcl). - -Although there are libraries such as the GNU Binary File Descriptor -(BFD) library that can assist with the manipulation of object files, -these are not used in the implementation \cite{bfd}. These -libraries tend to be quite large and are oriented more towards -stand-alone tools such as debuggers, linkers, and loaders. In addition, -the behavior of these libraries with respect to memory management -would need to be carefully studied before they could be safely used in -an embedded environment. Finally, given the small size of the prototype -implementation, it didn't seem necessary to rely upon such a -heavyweight solution. - -A surprising feature of the implementation is that a significant -amount of the code is language independent. This is achieved by -placing all of the process introspection, data collection, and -platform specific code within a centralized core. To provide a -specific scripting language interface, a developer only needs to -supply two things; a table containing symbolic function names where -control can be returned (Table 1), and a handler function in the form -of a callback. As input, this handler receives an exception object as -described in an earlier section. From this, the handler can -raise a scripting language exception in whatever manner is most -appropriate. - -Significant portions of the core are also relatively straightforward -to port between different Unix systems. For instance, code to read -ELF object files and stabs debugging data is essentially identical for -Linux and Solaris. In addition, the high-level control logic is -unchanged between platforms. Platform specific differences primarily -arise in the obvious places such as the examination of CPU -registers, manipulation of the process context in the signal handler, -reading virtual memory maps from /proc, and so forth. Additional -changes would also need to be made on systems with different object -file formats such as COFF and DWARF2. To extent that it is possible, -these differences could be hidden by abstraction mechanisms (although -the initial implementation of WAD is weak in this regard and would -benefit from techniques used in more advanced debuggers such as gdb). -Despite these porting issues, the primary requirement for WAD is a fully -functional implementation of SVR4 signal handling that allows for -modifications of the process context. - -Due to the heavy dependence on Unix signal handling, process -introspection, and object file formats, it is unlikely that WAD could -be easily ported to non-Unix systems such as Windows. However, it may -be possible to provide a similar capability using advanced features of -Windows structured exception handling \cite{seh}. For instance, structured -exception handlers can be used to catch hardware faults, they can -receive process context information, and they can arrange to take -corrective action much like the signal implementation described here. - -\section{Modification of Interpreters?} - -A logical question to ask about the implementation of WAD is whether -or not it would make sense to modify existing interpreters to assist -in the recovery process. For instance, instrumenting Python or Tcl with setjmp -functions might simplify the implementation since it would eliminate -issues related to register restoration and finding a suitable return -location. - -Although it may be possible to make these changes, there are -several drawbacks to this approach. First, the number of required modifications may be -quite large. For instance, there are well over 50 entry points to -extension code within the implementation of Python. Second, an -extension module may perform callbacks and evaluation of script code. -This means that the call stack would cross back and forth -between languages and that these modifications would have to be made -in a way that allows arbitrary nesting of extension calls. Finally, -instrumenting the code in this manner may introduce a performance -impact--a clearly undesirable side effect considering the infrequent -occurrence of fatal extension errors. - -\section{Discussion} - -The primary goal of embedded error recovery is to provide an -alternative approach for debugging scripting language extensions. -Although this approach has many benefits, there are a number -drawbacks and issues that must be discussed. - -First, like the C {\tt longjmp} function, the error recovery mechanism -does not cleanly unwind the call stack. For C++, this means that -objects allocated on stack will not be finalized (destructors will not -be invoked) and that memory allocated on the heap may be -leaked. Similarly, this could result in open files, sockets, and other -system resources. In a multi-threaded environment, -deadlock may occur if a procedure holds a lock when an error occurs. - -In certain cases, the use of signals in WAD may interact adversely with scripting -language signal handling. Since scripting languages ordinarily do not catch signals such as -SIGSEGV, SIGBUS, and SIGABRT, the use of WAD is unlikely to conflict -with any existing signal handling. However, most scripting languages would not -prevent a user from disabling the WAD error recovery mechanism by -simply specifying a new handler for one or more of these signals. In addition, the use of -certain extensions such as the Perl sigtrap module would completely -disable WAD \cite{perl}. - -A more difficult signal handling problem arises when thread libraries -are used. These libraries tend to override default signal handling -behavior in a way that defines how signals are delivered to each -thread \cite{thread}. In general, asynchronous signals can be -delivered to any thread within a process. However, this does not -appear to be a problem for WAD since hardware exceptions are delivered -to a signal handler that runs within the same thread in which the -error occurred. Unfortunately, even in this case, personal experience has -shown that certain implementations of user thread libraries (particularly on older versions -of Linux) do not reliably pass -signal context information nor do they universally support advanced -signal operations such as {\tt sigaltstack}. Because of this, WAD may -be incompatible with a crippled implementation of user threads on -these platforms. - -A even more subtle problem with threads is that the recovery process -itself is not thread-safe (i.e., it is not possible to concurrently -handle fatal errors occurring in different threads). For most -scripting language extensions, this limitation does not apply due to -strict run-time restrictions that interpreters currently place on -thread support. For instance, even though Python supports threaded -programs, it places a global mutex-lock around the interpreter that -makes it impossible for more than one thread to concurrently execute -within the interpreter at once. A consequence of this restriction is -that extension functions are not interruptible by thread-switching -unless they explicitly release the interpreter lock. Currently, the -behavior of WAD is undefined if extension code releases the lock and -proceeds to generate a fault. In this case, the recovery process may -either cause an exception to be raised in an entirely different -thread or cause execution to violate the interpreter's mutual exclusion -constraint on the interpreter. - -In certain cases, errors may result in an unrecoverable crash. For -example, if an application overwrites the heap, it may destroy -critical data structures within the interpreter. Similarly, -destruction of the call stack (via buffer overflow) makes it -impossible for the recovery mechanism to create a stack-trace and -return to the interpreter. More subtle memory management problems -such as double-freeing of heap allocated memory can also cause a system -to fail in a manner that bears little resemblance to actual source -of the problem. Given that WAD lives in the same process as the -faulting application and that such errors may occur, a common -question to ask is to what extent does WAD complicate debugging when it -doesn't work. - -To handle potential problems in the implementation of WAD itself, -great care is taken to avoid the use of library functions and -functions that rely on heap allocation (malloc, free, etc.). For -instance, to provide dynamic memory allocation, WAD implements its own -memory allocator using mmap. In addition, signals are disabled -immediately upon entry to the WAD signal handler. Should a fatal -error occur inside WAD, the application will dump core and exit. Since -the resulting core file contains the stack trace of both WAD and the -faulting application, a traditional C debugger can be used to identify -the problem as before. The only difference is that a few additional -stack frames will appear on the traceback. - -An application may also fail after the WAD signal handler has completed -execution if memory or stack frames within the interpreter have been -corrupted in a way that prevents proper exception handling. In this case, the -application may fail in a manner that does not represent the original -programming error. It might also cause the WAD signal handler to be -immediately reinvoked with a different process state--causing it to -report information about a different type of failure. To address -these kinds of problems, WAD creates a tracefile {\tt -wadtrace} in the current working directory that contains information -about each error that it has handled. If no recovery was possible, a -programmer can look at this file to obtain all of the stack traces -that were generated. - -If an application is experiencing a very serious problem, WAD -does not prevent a standard debugger from being attached to the -process. This is because the debugger overrides the current signal -handling so that it can catch fatal errors. As a result, even if WAD -is loaded, fatal signals are simply redirected to the attached -debugger. Such an approach also allows for more complex debugging -tasks such as single-step execution, breakpoints, and -watchpoints--none of which are easily added to WAD itself. - -% -% Add comments about what WAD does in this case? -% - -Finally, there are a number of issues that pertain -to the interaction of the recovery mechanism with the interpreter. -For instance, the recovery scheme is unable to return to procedures -that might invoke wrapper functions with conflicting return codes. -This problem manifests itself when the interpreter's virtual -machine is built around a large {\tt switch} statement from which different -types of wrapper functions are called. For example, in Python, certain -internal procedures call a mix of functions where both NULL and -1 are -returned to indicate errors (depending on the function). In this case, there -is no way to specify a proper error return value because there will be -conflicting entries in the WAD return table (although you could compromise and -return the error value for the most common case). The recovery -process is also extremely inefficient due to its heavy reliance on -{\tt mmap}, file I/O, and linear search algorithms for finding symbols -and debugging information. Therefore, WAD would -unsuitable as a more general purpose extension related exception handler. - -Despite these limitations, embedded error recovery is still a useful -capability that can be applied to a wide variety of extension related -errors. This is because errors such as failed assertions, bus errors, -and floating point exceptions rarely result in a situation where the -recovery process would be unable to run or the interpreter would -crash. Furthermore, more serious errors such as segmentation faults -are more likely to caused by an uninitialized pointer than a blatant -destruction of the heap or stack. - -\section{Related Work} - -A huge body of literature is devoted to the topic of exception -handling in various languages and systems. Furthermore, the topic -remains one of active interest in the software community. For -instance, IEEE Transactions on Software Engineering recently devoted -two entire issues to current trends in exception handling -\cite{except1,except2}. Unfortunately, very little of this work seems -to be directly related to mixed compiled-interpreted exception -handling, recovery from fatal signals, and problems pertaining to -mixed-language debugging. - -Perhaps the most directly relevant work is that of advanced programming -environments for Common Lisp \cite{lisp}. Not only does CL have a foreign function interface, -debuggers such as gdb have previously been modified to walk the Lisp stack -\cite{ffi,wcl}. Furthermore, certain Lisp development environments have -previously provided a high degree of integration between compiled code and -the Lisp interpreter\cite{gabriel}. - -In certain cases, a scripting language module has been used to provide -partial information for fatal signals. For example, the Perl {\tt -sigtrap} module can be used to produce a Perl stack trace when a -problem occurs \cite{perl}. Unfortunately, this module does not -provide any information from the C stack. Similarly, advanced software development -environments such as Microsoft's Visual Studio can automatically launch a C/C++ -debugger when an error occurs. Unfortunately, this doesn't provide any information -about the script that was running. - -In the area of programming languages, a number of efforts have been made to -map signals to exceptions in the form of asynchronous exception handling -\cite{buhr,ml,haskell}. Unfortunately, this work tends to -concentrate on the problem of handling asynchronous signals related to I/O as opposed -to synchronously generated signals caused by software faults. - -With respect to debugging, little work appears to have been done in the area of -mixed compiled-interpreted debugging. Although modern debuggers -certainly try to provide advanced capabilities for debugging within a -single language, they tend to ignore the boundary between languages. -As previously mentioned, debuggers have occasionally been modified to -support other languages such as Common Lisp \cite{wcl}. However, little work appears -to have been done in the context of modern scripting languages. One system of possible interest -in the context of mixed compiled-interpreted debugging is the R$^{n}$ -system developed at Rice University in the mid-1980's \cite{carle}. This -system, primarily developed for scientific computing, allowed control -to transparently pass between compiled code and an interpreter. -Furthermore, the system allowed dynamic patching of an executable in -which compiled procedures could be replaced by an interpreted -replacement. Although this system does not directly pertain to the problem of -debugging of scripting language extensions, it is one of the few -examples of a system in which compiled and interpreted code have been -tightly integrated within a debugger. - -More recently, a couple of efforts have emerged to that seem to -address certain issues related to mixed-mode debugging of interpreted -and compiled code. PyDebug is a recently developed system that focuses -on problems related to the management of breakpoints in Python -extension code \cite{pydebug}. It may also be possible to perform -mixed-mode debugging of Java and native methods using features of the -Java Platform Debugger Architecture (JPDA) \cite{jpda}. Mixed-mode -debugging support for Java may also be supported in advanced debugging systems -such as ICAT \cite{icat}. -However, none of these systems appear to have taken the approach of -converting hardware faults into Java errors or exceptions. - -\section{Future Directions} - -As of this writing, WAD is only an experimental prototype. Because of -this, there are certainly a wide variety of incremental improvements -that could be made to support additional platforms and scripting -languages. In addition, there are a variety of improvements that could be made -to provide better integration with threads and C++. One could also -investigate heuristic schemes such as backward stack tracing that might be able -to recover partial debugging information from corrupted call stacks \cite{debug}. - -A more interesting extension of this work would be to see how the -exception handling approach of WAD could be incorporated with -the integrated development environments and script-level debugging -systems that have already been developed. For instance, it would be interesting -to see if a graphical debugging front-end such as DDD could be modified -to handle mixed-language stack traces within the context of a script-level debugger \cite{ddd}. - -It may also be possible to extend the approach taken by WAD to other -types of extensible systems. For instance, if one were developing a -new server module for the Apache web-server, it might be possible to redirect fatal -module errors back to the server in a way that produces a webpage with -a stack trace \cite{apache}. The exception handling approach may also have -applicability to situations where compiled code is used to build software -components that are used as part of a large distributed system. - -\section{Conclusions and Availability} - -This paper has presented a mechanism by which fatal errors such as -segmentation faults and failed assertions can be handled as scripting -language exceptions. This approach, which relies upon advanced -features of Unix signal handling, allows fatal signals to be caught -and transformed into errors from which interpreters can produce an -informative cross-language stack trace. In doing so, it provides more -seamless integration between scripting languages and compiled -extensions. Furthermore, this has the potential to greatly simplify the -frustrating task of debugging complicated mixed scripted-compiled -software. - -The prototype implementation of this system is available at : - -\begin{center} -{\tt http://systems.cs.uchicago.edu/wad}. -\end{center} - -\noindent -Currently, WAD supports Python and Tcl on SPARC Solaris and i386-Linux -systems. Work to support additional scripting languages and platforms -is ongoing. - -\section{Acknowledgments} - -Richard Gabriel and Harlan Sexton provided interesting insights -concerning debugging capabilities in Common Lisp. Stephen Hahn -provided useful information concerning the low-level details of signal -handling on Solaris. I would also like to thank the technical -reviewers and Rob Miller for their useful comments. - -\begin{thebibliography}{99} - - -\bibitem{ousterhout} J. K. Ousterhout, {\em Tcl: An Embeddable Command Language}, -Proceedings of the USENIX Association Winter Conference, 1990. p.133-146. - -\bibitem{perl} L. Wall, T. Christiansen, and R. Schwartz, {\em Programming Perl}, 2nd. Ed. -O'Reilly \& Associates, 1996. - -\bibitem{python} M. Lutz, {\em Programming Python}, O'Reilly \& Associates, 1996. - -\bibitem{guile} Thomas Lord, {\em An Anatomy of Guile, The Interface to -Tcl/Tk}, USENIX 3rd Annual Tcl/Tk Workshop 1995. - -\bibitem{php} T. Ratschiller and T. Gerken, {\em Web Application Development with PHP 4.0}, -New Riders, 2000. - -\bibitem{ruby} D. Thomas, A. Hunt, {\em Programming Ruby}, Addison-Wesley, 2001. - -\bibitem{swig} D.M. Beazley, {\em SWIG : An Easy to Use Tool for Integrating Scripting Languages with C and C++}, Proceedings of the 4th USENIX Tcl/Tk Workshop, p. 129-139, July 1996. - -\bibitem{sip} P. Thompson, {\em SIP},\\ -{\tt http://www.thekompany.com/ projects/pykde}. - -\bibitem{pyfort} P.~F.~Dubois, {\em Climate Data Analysis Software}, 8th International Python Conference, -Arlington, VA., 2000. - -\bibitem{f2py} P. Peterson, J. Martins, and J. Alonso, -{\em Fortran to Python Interface Generator with an application to Aerospace -Engineering}, 9th International Python Conference, submitted, 2000. - -\bibitem{advperl} S. Srinivasan, {\em Advanced Perl Programming}, O'Reilly \& Associates, 1997. - -\bibitem{heidrich} Wolfgang Heidrich and Philipp Slusallek, {\em Automatic Generation of Tcl Bindings for C and C++ Libraries.}, -USENIX 3rd Tcl/Tk Workshop, 1995. - -\bibitem{vtk} K. Martin, {\em Automated Wrapping of a C++ Class Library into Tcl}, -USENIX 4th Tcl/Tk Workshop, p. 141-148, 1996. - -\bibitem{gwrap} C. Lee, {\em G-Wrap: A tool for exporting C libraries into Scheme Interpreters},\\ -{\tt http://www.cs.cmu.edu/\~{ }chrislee/ -Software/g-wrap}. - -\bibitem{wrappy} G. Couch, C. Huang, and T. Ferrin, {\em Wrappy :A Python Wrapper -Generator for C++ Classes}, O'Reilly Open Source Software Convention, 1999. - -\bibitem{ouster1} J. K. Ousterhout, {\em Scripting: Higher-Level Programming for the 21st Century}, -IEEE Computer, Vol 31, No. 3, p. 23-30, 1998. - -\bibitem{gdb} R. Stallman and R. Pesch, {\em Using GDB: A Guide to the GNU Source-Level Debugger}. -Free Software Foundation and Cygnus Support, Cambridge, MA, 1991. - -\bibitem{swigexcept} D.M. Beazley and P.S. Lomdahl, {\em Feeding a -Large-scale Physics Application to Python}, 6th International Python -Conference, co-sponsored by USENIX, p. 21-28, 1997. - -\bibitem{stevens} W. Richard Stevens, {\em UNIX Network Programming: Interprocess Communication, Volume 2}. PTR -Prentice-Hall, 1998. - -\bibitem{proc} R. Faulkner and R. Gomes, {\em The Process File System and Process Model in UNIX System V}, USENIX Conference Proceedings, -January 1991. - -\bibitem{elf} J.~R.~Levine, {\em Linkers \& Loaders.} Morgan Kaufmann Publishers, 2000. - -\bibitem{stabs} Free Software Foundation, {\em The ``stabs'' debugging format}. GNU info document. - -\bibitem{prag} M.L. Scott. {\em Programming Language Pragmatics}, Morgan Kaufmann Publishers, 2000. - -\bibitem{sparc} D. Weaver and T. Germond, {\em SPARC Architecture Manual Version 9}, -Prentice-Hall, 1993. - -\bibitem{bfd} S. Chamberlain. {\em libbfd: The Binary File Descriptor Library}. Cygnus Support, bfd version 3.0 edition, April 1991. - -\bibitem{seh} M. Pietrek, {\em A Crash Course on the Depths of Win32 Structured Exception Handling}, -Microsoft Systems Journal, January 1997. - -\bibitem{thread} F. Mueller, {\em A Library Implementation of POSIX Threads Under Unix}, -USENIX Winter Technical Conference, San Diego, CA., p. 29-42, 1993. - -\bibitem{debug} J. B. Rosenberg, {\em How Debuggers Work: Algorithms, Data Structures, and -Architecture}, John Wiley \& Sons, 1996. - -\bibitem{except1} D.E. Perry, A. Romanovsky, and A. Tripathi, {\em -Current Trends in Exception Handling-Part I}, -IEEE Transactions on Software Engineering, Vol 26, No. 9, p. 817-819, 2000. - -\bibitem{except2} D.E. Perry, A. Romanovsky, and A. Tripathi, {\em -Current Trends in Exception Handling-Part II}, -IEEE Transactions on Software Engineering, Vol 26, No. 10, p. 921-922, 2000. - - -\bibitem{lisp} G.L. Steele Jr., {\em Common Lisp: The Language, Second Edition}, Digital Press, -Bedford, MA. 1990. - -\bibitem{gabriel} R. Gabriel, private correspondence. - -\bibitem{ffi} H. Sexton, {\em Foreign Functions and Common Lisp}, in Lisp Pointers, Vol 1, No. 5, 1988. - -\bibitem{wcl} W. Henessey, {\em WCL: Delivering Efficient Common Lisp Applications Under Unix}, -ACM Conference on Lisp and Functional Languages, p. 260-269, 1992. - -\bibitem{buhr} P.A. Buhr and W.Y.R. Mok, {\em Advanced Exception Handling Mechanisms}, IEEE Transactions on Software Engineering, -Vol. 26, No. 9, p. 820-836, 2000. - -\bibitem{haskell} S. Marlow, S. P. Jones, and A. Moran. {\em -Asynchronous Exceptions in Haskell.} In 4th International Workshop on -High-Level Concurrent Languages, September 2000. - -\bibitem{ml} J. H. Reppy, {\em Asynchronous Signals in Standard ML}. Technical Report TR90-1144, -Cornell University, Computer Science Department, 1990. - -\bibitem{carle} A. Carle, D. Cooper, R. Hood, K. Kennedy, L. Torczon, S. Warren, -{\em A Practical Environment for Scientific Programming.} -IEEE Computer, Vol 20, No. 11, p. 75-89, 1987. - -\bibitem{pydebug} P. Stoltz, {\em PyDebug, a New Application for Integrated -Debugging of Python with C and Fortran Extensions}, O'Reilly Open Source Software Convention, -San Diego, 2001 (to appear). - -\bibitem{jpda} Sun Microsystems, {\em Java Platform Debugger Architecture}, -http://java.sun.com/products/jpda - -\bibitem{icat} IBM, {\em ICAT Debugger}, \\ -http://techsupport.services.ibm.com/icat. - -\bibitem{ddd} A. Zeller, {\em Visual Debugging with DDD}, Dr. Dobb's Journal, March, 2001. - -\bibitem{apache} {\em Apache HTTP Server Project}, \\ -{\tt http://httpd.apache.org/} - -\end{thebibliography} - -\end{document} - - - - - - - - diff --git a/Tools/WAD/README b/Tools/WAD/README index 282d0bcf5..2458a83cf 100644 --- a/Tools/WAD/README +++ b/Tools/WAD/README @@ -327,10 +327,13 @@ The scripts debug.py, debug.tcl, debug.pl can be used to test these extensions. 8. Documentation -No official documentation exists at this time. However, the Papers -directory contains two conference papers that describe WAD's design -and high-level operation. Slides from the Python9 talk are also -included. +No official documentation exists at this time. However, details +of WAD's design and implementation can be found in papers presented +at the Ninth International Python Conference and the 2000 USENIX +Technical Conference. Both papers can be obtained at: + + http://systems.cs.uchicago.edu/wad + 9. To-Do diff --git a/Tools/WAD/configure.in b/Tools/WAD/configure.in index 99335b6a5..9c00cbeca 100644 --- a/Tools/WAD/configure.in +++ b/Tools/WAD/configure.in @@ -7,7 +7,7 @@ dnl to nothing) and `test -z "$VAR"' or `test -n "$VAR"' as the dnl case may be. --ttn, 2000/08/04 12:11:26 AC_INIT(Include/wad.h) -AC_PREREQ(2.0) +AC_PREREQ(2.53) # Set name for machine-dependent library files AC_SUBST(MACHDEP) diff --git a/Tools/aclocal.m4 b/Tools/aclocal.m4 new file mode 100644 index 000000000..03c26f0ee --- /dev/null +++ b/Tools/aclocal.m4 @@ -0,0 +1,3704 @@ +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 46 AC_PROG_LIBTOOL + +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([LT_AC_PROG_SED])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# AC_LIBTOOL_HEADER_ASSERT +# ------------------------ +AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT], +[AC_CACHE_CHECK([whether $CC supports assert without backlinking], + [lt_cv_func_assert_works], + [case $host in + *-*-solaris*) + if test "$GCC" = yes && test "$with_gnu_ld" != yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) lt_cv_func_assert_works=no ;; + *) lt_cv_func_assert_works=yes ;; + esac + fi + ;; + esac]) + +if test "x$lt_cv_func_assert_works" = xyes; then + AC_CHECK_HEADERS(assert.h) +fi +])# AC_LIBTOOL_HEADER_ASSERT + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[[ABCDGISTW]]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[[]] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +## FIXME: this should be a separate macro +## +AC_MSG_CHECKING([for objdir]) +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +AC_MSG_RESULT($objdir) +## +## END FIXME + + +## FIXME: this should be a separate macro +## +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi +## +## END FIXME + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +## FIXME: this should be a separate macro +## +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" +## +## END FIXME + + +## FIXME: this should be a separate macro +## +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_o_lo]) +else + compiler_o_lo=no +fi +## +## END FIXME + +## FIXME: this should be a separate macro +## +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +## +## END FIXME + +## FIXME: this should be a separate macro +## +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi +## +## END FIXME + +## FIXME: this should be a separate macro +## +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \[$]2 \[$]3 \[$]4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no +## +## END FIXME + +## FIXME: this should be a separate macro +## +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +AC_MSG_RESULT([$hardcode_action]) +## +## END FIXME + +## FIXME: this should be a separate macro +## +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +## +## END FIXME + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +## FIXME: this should be a separate macro +## +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can + # not hardcode correct soname into executable. Probably we can + # add versioning support to collect2, so additional links can + # be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + hardcode_into_libs=yes + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + hardcode_into_libs=yes + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no +## +## END FIXME + +## FIXME: this should be a separate macro +## +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) +## +## END FIXME + +## FIXME: this should be a separate macro +## +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) +## +## END FIXME + +## FIXME: this should be a separate macro +## +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) +## +## END FIXME + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +AC_LIBTOOL_DLOPEN_SELF + +## FIXME: this should be a separate macro +## +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} +## +## END FIXME + +## FIXME: this should be a separate macro +## +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + global_symbol_to_c_name_address \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="${SED} -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi +## +## END FIXME + +])# _LT_AC_LTCONFIG_HACK + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | [[A-Za-z]]:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[[012]]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[[78]]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and LTDLINCL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" +]) +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +AC_MSG_RESULT([$SED]) +]) diff --git a/Tools/capitalize b/Tools/capitalize new file mode 100755 index 000000000..d49c088c9 --- /dev/null +++ b/Tools/capitalize @@ -0,0 +1,5 @@ +#!/bin/sh +# usage: capitalize word +# write word to stdout w/ first character upcased +first_char=`echo $1 | sed 's/^\(.\).*/\1/' | tr a-z A-Z` +echo ${first_char}`echo $1 | sed 's/^.//'` diff --git a/Tools/check-include-path.pike b/Tools/check-include-path.pike new file mode 100644 index 000000000..2bfb2b901 --- /dev/null +++ b/Tools/check-include-path.pike @@ -0,0 +1,20 @@ +/** + * This is a helper script to identify the proper include path + * for Pike header files. It should be run with the full path + * to the Pike executable as its single argument, e.g. + * + * pike check-include-path.pike /usr/local/bin/pike + * + * and its output should be the correct path to the header + * files, e.g. + * + * /usr/local/pike/7.2.239/include/pike + * + */ + +int main(int argc, array(string) argv) +{ + string prefix = replace(argv[1], "/bin/pike", ""); + write(prefix + "/pike/" + __MAJOR__ + "." + __MINOR__ + "." + __BUILD__ + "/include/pike"); + return 0; +} diff --git a/Tools/config.guess b/Tools/config.guess index e1b587170..5145e3571 100644 --- a/Tools/config.guess +++ b/Tools/config.guess @@ -1,8 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 -# Free Software Foundation, Inc. -# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-10-21' + # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -22,52 +24,205 @@ # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. -# Written by Per Bothner . -# The master version of this file is at the FSF in /home/gd/gnu/lib. -# Please send patches to . +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you -# don't specify an explicit system type (host/target name). -# -# Only a few systems have been added to this list; please add others -# (but try to keep the structure clean). -# +# don't specify an explicit build system type. -# Use $HOST_CC if defined. $CC may point to a cross-compiler -if test x"$CC_FOR_BUILD" = x; then - if test x"$HOST_CC" != x; then - CC_FOR_BUILD="$HOST_CC" - else - if test x"$CC" != x; then - CC_FOR_BUILD="$CC" - else - CC_FOR_BUILD=cc - fi - fi +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 fi +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# This shell variable is my proudest work .. or something. --bje + +set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; +(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) + || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; +dummy=$tmpdir/dummy ; +files="$dummy.c $dummy.o $dummy.rel $dummy" ; +trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $files ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; +unset files' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 8/24/94.) +# (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 - # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -76,45 +231,62 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. + eval $set_cc_for_build cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text .globl main + .align 4 .ent main main: - .frame \$30,0,\$26,0 - .prologue 0 - .long 0x47e03d80 # implver $0 - lda \$2,259 - .long 0x47e20c21 # amask $2,$1 - srl \$1,8,\$2 - sll \$2,2,\$2 - sll \$0,3,\$0 - addl \$1,\$0,\$0 - addl \$2,\$0,\$0 - ret \$31,(\$26),1 + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit .end main EOF - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null if test "$?" = 0 ; then - ./$dummy - case "$?" in - 7) + case `$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; - 15) + 1-0) UNAME_MACHINE="alphaev5" ;; - 14) + 1-1) UNAME_MACHINE="alphaev56" ;; - 10) + 1-101) UNAME_MACHINE="alphapca56" ;; - 16) + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; esac fi - rm -f $dummy.s $dummy + rm -f $dummy.s $dummy && rmdir $tmpdir echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) @@ -127,34 +299,13 @@ EOF echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-cbm-sysv4 + echo m68k-unknown-sysv4 exit 0;; - amiga:NetBSD:*:*) - echo m68k-cbm-netbsd${UNAME_RELEASE} - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; - arc64:OpenBSD:*:*) - echo mips64el-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hkmips:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -162,10 +313,7 @@ EOF arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; - arm32:NetBSD:*:*) - echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; - SR2?01:HI-UX/MPP:*:*) + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) @@ -179,6 +327,10 @@ EOF NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; @@ -207,7 +359,7 @@ EOF echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) @@ -221,15 +373,9 @@ EOF aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; - atari*:NetBSD:*:*) - echo m68k-atari-netbsd${UNAME_RELEASE} - exit 0 ;; - atari*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor + # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not @@ -253,30 +399,9 @@ EOF *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; - sun3*:NetBSD:*:*) - echo m68k-sun-netbsd${UNAME_RELEASE} - exit 0 ;; - sun3*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:NetBSD:*:*) - echo m68k-apple-netbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; - macppc:NetBSD:*:*) - echo powerpc-apple-netbsd${UNAME_RELEASE} - exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; @@ -290,8 +415,10 @@ EOF echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus +#include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { @@ -310,12 +437,21 @@ EOF exit (-1); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS) + echo powerpc-harris-powermax + exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; @@ -331,7 +467,7 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110] + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] @@ -363,11 +499,20 @@ EOF ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i?86:AIX:*:*) + i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include @@ -379,8 +524,8 @@ EOF exit(0); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 @@ -388,9 +533,9 @@ EOF echo rs6000-ibm-aix3.2 fi exit 0 ;; - *:AIX:*:4) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` - if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -398,7 +543,7 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=4.${UNAME_RELEASE} + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; @@ -408,7 +553,7 @@ EOF ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) @@ -424,11 +569,30 @@ EOF echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - sed 's/^ //' << EOF >$dummy.c + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE #include #include @@ -459,13 +623,19 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` - rm -f $dummy.c $dummy + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy && rmdir $tmpdir + fi ;; esac - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; 3050*:HI-UX:*:*) + eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int @@ -491,8 +661,8 @@ EOF exit (0); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) @@ -501,7 +671,7 @@ EOF 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; - *9??*:MPE/iX:*:*) + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) @@ -510,7 +680,7 @@ EOF hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; - i?86:OSF1:*:*) + i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else @@ -520,9 +690,6 @@ EOF parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; - hppa*:OpenBSD:*:*) - echo hppa-unknown-openbsd - exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; @@ -541,41 +708,34 @@ EOF C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; - CRAY*X-MP:*:*:*) - echo xmp-cray-unicos - exit 0 ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; - CRAY-2:*:*:*) - echo cray2-cray-unicos - exit 0 ;; - F300:UNIX_System_V:*:*) + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; - F301:UNIX_System_V:*:*) - echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` - exit 0 ;; - hp3[0-9][05]:NetBSD:*:*) - echo m68k-hp-netbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - i?86:BSD/386:*:* | i?86:BSD/OS:*:*) + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) @@ -585,19 +745,19 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) - if test -x /usr/bin/objformat; then - if test "elf" = "`/usr/bin/objformat`"; then - echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` - exit 0 - fi - fi - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - *:NetBSD:*:*) - echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -605,6 +765,12 @@ EOF i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -623,201 +789,142 @@ EOF *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; - *:Linux:*:*) - + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c && rmdir $tmpdir + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. - ld_help_string=`cd /; ld --help 2>&1` - ld_supported_emulations=`echo $ld_help_string \ - | sed -ne '/supported emulations:/!d + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g - s/.*supported emulations: *// + s/.*supported targets: *// s/ .*// p'` - case "$ld_supported_emulations" in - *ia64) - echo "${UNAME_MACHINE}-unknown-linux" - exit 0 + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; - i?86linux) + a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 - ;; - i?86coff) + exit 0 ;; + coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 - ;; - sparclinux) - echo "${UNAME_MACHINE}-unknown-linux-gnuaout" - exit 0 - ;; - armlinux) - echo "${UNAME_MACHINE}-unknown-linux-gnuaout" - exit 0 - ;; - elf32arm*) - echo "${UNAME_MACHINE}-unknown-linux-gnu" - exit 0 - ;; - armelf_linux*) - echo "${UNAME_MACHINE}-unknown-linux-gnu" - exit 0 - ;; - m68klinux) - echo "${UNAME_MACHINE}-unknown-linux-gnuaout" - exit 0 - ;; - elf32ppc) - # Determine Lib Version - cat >$dummy.c < -#if defined(__GLIBC__) -extern char __libc_version[]; -extern char __libc_release[]; -#endif -main(argc, argv) - int argc; - char *argv[]; -{ -#if defined(__GLIBC__) - printf("%s %s\n", __libc_version, __libc_release); -#else - printf("unkown\n"); -#endif - return 0; -} -EOF - LIBC="" - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null - if test "$?" = 0 ; then - ./$dummy | grep 1\.99 > /dev/null - if test "$?" = 0 ; then - LIBC="libc1" - fi - fi - rm -f $dummy.c $dummy - echo powerpc-unknown-linux-gnu${LIBC} - exit 0 - ;; + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; esac - - if test "${UNAME_MACHINE}" = "alpha" ; then - sed 's/^ //' <$dummy.s - .globl main - .ent main - main: - .frame \$30,0,\$26,0 - .prologue 0 - .long 0x47e03d80 # implver $0 - lda \$2,259 - .long 0x47e20c21 # amask $2,$1 - srl \$1,8,\$2 - sll \$2,2,\$2 - sll \$0,3,\$0 - addl \$1,\$0,\$0 - addl \$2,\$0,\$0 - ret \$31,(\$26),1 - .end main + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif EOF - LIBC="" - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - ./$dummy - case "$?" in - 7) - UNAME_MACHINE="alpha" - ;; - 15) - UNAME_MACHINE="alphaev5" - ;; - 14) - UNAME_MACHINE="alphaev56" - ;; - 10) - UNAME_MACHINE="alphapca56" - ;; - 16) - UNAME_MACHINE="alphaev6" - ;; - esac - - objdump --private-headers $dummy | \ - grep ld.so.1 > /dev/null - if test "$?" = 0 ; then - LIBC="libc1" - fi - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 - elif test "${UNAME_MACHINE}" = "mips" ; then - cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - else - # Either a pre-BFD a.out linker (linux-gnuoldld) - # or one that does not give us useful --help. - # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. - # If ld does not provide *any* "supported emulations:" - # that means it is gnuoldld. - echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" - test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 - - case "${UNAME_MACHINE}" in - i?86) - VENDOR=pc; - ;; - *) - VENDOR=unknown; - ;; - esac - # Determine whether the default compiler is a.out or elf - cat >$dummy.c < -#ifdef __cplusplus - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __ELF__ -# ifdef __GLIBC__ -# if __GLIBC__ >= 2 - printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); -# else - printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); -# endif -# else - printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); -# endif -#else - printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); -#endif - return 0; -} -EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - fi ;; -# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions -# are messed up and put the nodename in both sysname and nodename. - i?86:DYNIX/ptx:4*:*) + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; - i?86:UNIX_SV:4.2MP:2.*) + i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, @@ -825,7 +932,7 @@ EOF # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; - i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} @@ -833,34 +940,37 @@ EOF echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; - i?86:*:5:7*) - # Fixed at (any) Pentium or better - UNAME_MACHINE=i586 - if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then - echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} - fi + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; - i?86:*:3.2:*) + i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; pc:*:*:*) + # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp @@ -882,9 +992,12 @@ EOF # "miniframe" echo m68010-convergent-sysv exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` @@ -895,21 +1008,24 @@ EOF 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:*) + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; - rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; @@ -927,8 +1043,8 @@ EOF echo ns32k-sni-sysv fi exit 0 ;; - PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) @@ -940,10 +1056,14 @@ EOF # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; - news*:NEWS-OS:*:6*) + news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) @@ -968,20 +1088,87 @@ EOF SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; *:QNX:*:4*) - echo i386-qnx-qnx${UNAME_VERSION} + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 +eval $set_cc_for_build cat >$dummy.c < @@ -1068,11 +1255,24 @@ main () #endif #if defined (vax) -#if !defined (ultrix) - printf ("vax-dec-bsd\n"); exit (0); -#else - printf ("vax-dec-ultrix\n"); exit (0); -#endif +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif #endif #if defined (alliant) && defined (i860) @@ -1083,8 +1283,8 @@ main () } EOF -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 +rm -f $dummy.c $dummy && rmdir $tmpdir # Apollos put the system type in the environment. @@ -1116,6 +1316,48 @@ then esac fi -#echo '(Unable to guess system type)' 1>&2 +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/Tools/config.sub b/Tools/config.sub index 28426bb8f..1dea9b79d 100644 --- a/Tools/config.sub +++ b/Tools/config.sub @@ -1,6 +1,10 @@ #! /bin/sh -# Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-09-05' + # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. @@ -25,6 +29,9 @@ # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. @@ -45,30 +52,73 @@ # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -if [ x$1 = x ] -then - echo Configuration name missing. 1>&2 - echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 - echo "or $0 ALIAS" 1>&2 - echo where ALIAS is a recognized configuration type. 1>&2 - exit 1 -fi +me=`echo "$0" | sed -e 's,.*/,,'` -# First pass through any local machine types. -case $1 in - *local*) - echo $1 - exit 0 - ;; - *) - ;; +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - linux-gnu*) + nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -94,7 +144,7 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple) + -apple | -axis) os= basic_machine=$1 ;; @@ -108,6 +158,14 @@ case $os in os=-vxworks basic_machine=$1 ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; @@ -166,27 +224,60 @@ esac case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. - tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ - | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ - | 580 | i960 | h8300 \ - | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ - | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ - | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ - | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ - | mips64orion | mips64orionel | mipstx39 | mipstx39el \ - | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ - | mips64vr5000 | miprs64vr5000el | mcore \ - | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ - | thumb | d10v | fr30) + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) basic_machine=$basic_machine-unknown ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. - i[34567]86) + i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. @@ -195,24 +286,56 @@ case $basic_machine in exit 1 ;; # Recognize the basic CPU types with company name. - # FIXME: clean up the formatting here. - vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ - | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ - | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ - | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ - | xmp-* | ymp-* \ - | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ - | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ - | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ - | clipper-* | orion-* \ - | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ - | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ - | mipstx39-* | mipstx39el-* | mcore-* \ - | f301-* | armv*-* | t3e-* \ - | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ - | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* ) + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39 | mipstx39el \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -249,14 +372,14 @@ case $basic_machine in os=-sysv ;; amiga | amiga-*) - basic_machine=m68k-cbm + basic_machine=m68k-unknown ;; amigaos | amigados) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-sysv4 ;; apollo68) @@ -275,6 +398,10 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -295,27 +422,30 @@ case $basic_machine in basic_machine=c38-convex os=-bsd ;; - cray | ymp) - basic_machine=ymp-cray - os=-unicos - ;; - cray2) - basic_machine=cray2-cray - os=-unicos - ;; - [ctj]90-cray) - basic_machine=c90-cray + cray | j90) + basic_machine=j90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola @@ -357,6 +487,10 @@ case $basic_machine in basic_machine=tron-gmicro os=-sysv ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -432,19 +566,19 @@ case $basic_machine in basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? - i[34567]86v32) + i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; - i[34567]86v4*) + i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; - i[34567]86v) + i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; - i[34567]86sol2) + i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; @@ -456,17 +590,6 @@ case $basic_machine in basic_machine=i386-unknown os=-vsta ;; - i386-go32 | go32) - basic_machine=i386-unknown - os=-go32 - ;; - i386-mingw32 | mingw32) - basic_machine=i386-unknown - os=-mingw32 - ;; - i386-qnx | qnx) - basic_machine=i386-qnx - ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -492,6 +615,10 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; miniframe) basic_machine=m68000-convergent ;; @@ -499,26 +626,26 @@ case $basic_machine in basic_machine=m68k-atari os=-mint ;; - mipsel*-linux*) - basic_machine=mipsel-unknown - os=-linux-gnu - ;; - mips*-linux*) - basic_machine=mips-unknown - os=-linux-gnu - ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; monitor) basic_machine=m68k-rom68k os=-coff ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; msdos) - basic_machine=i386-unknown + basic_machine=i386-pc os=-msdos ;; mvs) @@ -582,13 +709,24 @@ case $basic_machine in basic_machine=i960-intel os=-mon960 ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; np1) basic_machine=np1-gould ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose @@ -611,45 +749,59 @@ case $basic_machine in pbb) basic_machine=m68k-tti ;; - pc532 | pc532-*) + pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5 | k5 | k6 | nexen) + pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; - pentiumpro | p6 | 6x86) + pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2) - basic_machine=i786-pc + basic_machine=i686-pc ;; - pentium-* | p5-* | k5-* | k6-* | nexen-*) + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-* | 6x86-*) + pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; - power) basic_machine=rs6000-ibm + power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown - ;; + ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown - ;; + ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; ps2) basic_machine=i386-ibm ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -660,10 +812,22 @@ case $basic_machine in rtpc | rtpc-*) basic_machine=romp-ibm ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; sa29200) basic_machine=a29k-amd os=-udi ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; sequent) basic_machine=i386-sequent ;; @@ -671,7 +835,7 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; - sparclite-wrs) + sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -729,20 +893,44 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; symmetry) basic_machine=i386-sequent os=-dynix ;; - t3e) - basic_machine=t3e-cray + t3d) + basic_machine=alpha-cray os=-unicos ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; tower | tower-32) basic_machine=m68k-ncr ;; @@ -767,8 +955,8 @@ case $basic_machine in os=-vms ;; vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; + basic_machine=f301-fujitsu + ;; vxworks960) basic_machine=i960-wrs os=-vxworks @@ -789,13 +977,17 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; - xmp) - basic_machine=xmp-cray - os=-unicos + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt ;; - xps | xps100) + xps | xps100) basic_machine=xps100-honeywell ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim @@ -816,13 +1008,6 @@ case $basic_machine in op60c) basic_machine=hppa1.1-oki ;; - mips) - if [ x$os = x-linux-gnu ]; then - basic_machine=mips-unknown - else - basic_machine=mips-mips - fi - ;; romp) basic_machine=romp-ibm ;; @@ -832,16 +1017,26 @@ case $basic_machine in vax) basic_machine=vax-dec ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; - sparc | sparcv9) + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; - cydra) + cydra) basic_machine=cydra-cydrome ;; orion) @@ -856,9 +1051,8 @@ case $basic_machine in pmac | pmac-mpw) basic_machine=powerpc-apple ;; - c4x*) - basic_machine=c4x-none - os=-coff + *-unknown) + # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 @@ -916,14 +1110,31 @@ case $os in | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -opened* | -openstep* | -oskit*) + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) # Remember, each alternative MUST END IN *, to match a version number. ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mon960* | -lnews*) + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` @@ -940,6 +1151,9 @@ case $os in -opened*) os=-openedition ;; + -wince*) + os=-wince + ;; -osfrose*) os=-osfrose ;; @@ -955,14 +1169,23 @@ case $os in -acis*) os=-aos ;; + -atheos*) + os=-atheos + ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; + -nova*) + os=-rtmk-nova + ;; -ns2 ) - os=-nextstep2 + os=-nextstep2 + ;; + -nsk*) + os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) @@ -977,9 +1200,6 @@ case $os in -oss*) os=-sysv3 ;; - -qnx) - os=-qnx4 - ;; -svr4) os=-sysv4 ;; @@ -1001,8 +1221,8 @@ case $os in -xenix) os=-xenix ;; - -*mint | -*MiNT) - os=-mint + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint ;; -none) ;; @@ -1035,7 +1255,11 @@ case $basic_machine in arm*-semi) os=-aout ;; - pdp11-*) + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) os=-none ;; *-dec | vax-*) @@ -1062,6 +1286,9 @@ case $basic_machine in mips*-*) os=-elf ;; + or32-*) + os=-coff + ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; @@ -1125,25 +1352,25 @@ case $basic_machine in *-next) os=-nextstep3 ;; - *-gould) + *-gould) os=-sysv ;; - *-highlevel) + *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; - *-sgi) + *-sgi) os=-irix ;; - *-siemens) + *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; - f301-fujitsu) + f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) @@ -1209,7 +1436,7 @@ case $basic_machine in -ptx*) vendor=sequent ;; - -vxsim* | -vxworks*) + -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) @@ -1221,12 +1448,23 @@ case $basic_machine in -mpw* | -macos*) vendor=apple ;; - -*mint | -*MiNT) + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; + -vos*) + vendor=stratus + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/Tools/configure.in b/Tools/configure.in index 62795b3da..0a639f496 100644 --- a/Tools/configure.in +++ b/Tools/configure.in @@ -1,6 +1,49 @@ AC_INIT(ltmain.sh) +AC_PREREQ(2.53) -AC_OUTPUT_COMMANDS([$srcdir/ltconfig --enable-dlopen $srcdir/ltmain.sh], - [srcdir=$srcdir]) +##----------------------------------------------------------------------------- +## libtool configuration +## (bug reports to ttn) + +## The command "libtoolize --copy --force" is used to create files: +## config.guess +## config.sub +## ltmain.sh +## The following lines make libtoolize place them in this directory +## rather than in the parent (where it finds install-sh). But this +## means at configure time, install-sh actually does need to be in +## this directory, so we copy it from the parent, *before* the decl. +## (The alternative is to check into cvs and consequently distribute +## another copy of install-sh, but that way lies madness.) + +cp ${srcdir}/../install-sh ${srcdir} +chmod +x ${srcdir}/install-sh +AC_CONFIG_AUX_DIR(.) + +## Apparently libtool configuration (now) assumes libtool is installed +## in the top builddir, congruent w/ automake expectations. Because we +## don't use automake, we need to set this variable manaully. Because +## we don't install libtool in the top builddir, we must use an absolute +## path instead of the relative path ".". See footnote in info node +## "(libtool)AC_PROG_LIBTOOL". +## +## Actually, at this time we hardcode makefile var LIBTOOL to DTRT, so +## it's ok to subvert the top_builddir requirement (and desirable, to +## flush out bugs faster). The following lines can be commented in should +## we change our minds in the future. + +##+ top_builddir="`pwd`" # libtool is here, not in parent dir +##+ AC_SUBST(top_builddir) + +## These two configure libtool, including dlopen facilities, by adding +## --{enable,disable}-{shared,static} options and setting var LIBTOOL, +## which uses top_builddir (see above). Note that at this time, this +## var is completely ignored; we set LIBTOOL directly in the Makefiles. + +AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL + +## libtool configuration ends here +##----------------------------------------------------------------------------- AC_OUTPUT() diff --git a/Tools/ltconfig b/Tools/ltconfig deleted file mode 100755 index a01334f92..000000000 --- a/Tools/ltconfig +++ /dev/null @@ -1,3078 +0,0 @@ -#! /bin/sh - -# ltconfig - Create a system-specific libtool. -# Copyright (C) 1996-1999 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A lot of this script is taken from autoconf-2.10. - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} -echo=echo -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec "$SHELL" "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null`} - case X$UNAME in - *-DOS) PATH_SEPARATOR=';' ;; - *) PATH_SEPARATOR=':' ;; - esac -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string="`eval $cmd`") 2>/dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || - test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH /usr/ucb; do - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running ltconfig again with it. - ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - echo='printf "%s\n"' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - # Cool, printf works - : - elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && - test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL $0 --fallback-echo" - elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && - test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then - echo="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# The name of this program. -progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` - -# Constants: -PROGRAM=ltconfig -PACKAGE=libtool -VERSION=1.3.4 -TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)" -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -rm="rm -f" - -help="Try \`$progname --help' for more information." - -# Global variables: -default_ofile=libtool -can_build_shared=yes -enable_shared=yes -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -enable_static=yes -enable_fast_install=yes -enable_dlopen=unknown -enable_win32_dll=no -ltmain= -silent= -srcdir= -ac_config_guess= -ac_config_sub= -host= -nonopt= -ofile="$default_ofile" -verify_host=yes -with_gcc=no -with_gnu_ld=no -need_locks=yes -ac_ext=c -objext=o -libext=a -exeext= -cache_file= - -old_AR="$AR" -old_CC="$CC" -old_CFLAGS="$CFLAGS" -old_CPPFLAGS="$CPPFLAGS" -old_LDFLAGS="$LDFLAGS" -old_LD="$LD" -old_LN_S="$LN_S" -old_LIBS="$LIBS" -old_NM="$NM" -old_RANLIB="$RANLIB" -old_DLLTOOL="$DLLTOOL" -old_OBJDUMP="$OBJDUMP" -old_AS="$AS" - -# Parse the command line options. -args= -prev= -for option -do - case "$option" in - -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - eval "$prev=\$option" - prev= - continue - fi - - case "$option" in - --help) cat <&2 - echo "$help" 1>&2 - exit 1 - ;; - - *) - if test -z "$ltmain"; then - ltmain="$option" - elif test -z "$host"; then -# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 -# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then -# echo "$progname: warning \`$option' is not a valid host type" 1>&2 -# fi - host="$option" - else - echo "$progname: too many arguments" 1>&2 - echo "$help" 1>&2 - exit 1 - fi ;; - esac -done - -if test -z "$ltmain"; then - echo "$progname: you must specify a LTMAIN file" 1>&2 - echo "$help" 1>&2 - exit 1 -fi - -if test ! -f "$ltmain"; then - echo "$progname: \`$ltmain' does not exist" 1>&2 - echo "$help" 1>&2 - exit 1 -fi - -# Quote any args containing shell metacharacters. -ltconfig_args= -for arg -do - case "$arg" in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ltconfig_args="$ltconfig_args '$arg'" ;; - *) ltconfig_args="$ltconfig_args $arg" ;; - esac -done - -# A relevant subset of AC_INIT. - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 5 compiler messages saved in config.log -# 6 checking for... messages and results -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>>./config.log - -# NLS nuisances. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi -if test "X${LANG+set}" = Xset; then LANG=C; export LANG; fi - -if test -n "$cache_file" && test -r "$cache_file"; then - echo "loading cache $cache_file within ltconfig" - . $cache_file -fi - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - -if test -z "$srcdir"; then - # Assume the source directory is the same one as the path to LTMAIN. - srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` - test "$srcdir" = "$ltmain" && srcdir=. -fi - -trap "$rm conftest*; exit 1" 1 2 15 -if test "$verify_host" = yes; then - # Check for config.guess and config.sub. - ac_aux_dir= - for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/config.guess; then - ac_aux_dir=$ac_dir - break - fi - done - if test -z "$ac_aux_dir"; then - echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 - echo "$help" 1>&2 - exit 1 - fi - ac_config_guess=$ac_aux_dir/config.guess - ac_config_sub=$ac_aux_dir/config.sub - - # Make sure we can run config.sub. - if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : - else - echo "$progname: cannot run $ac_config_sub" 1>&2 - echo "$help" 1>&2 - exit 1 - fi - - echo $ac_n "checking host system type""... $ac_c" 1>&6 - - host_alias=$host - case "$host_alias" in - "") - if host_alias=`$SHELL $ac_config_guess`; then : - else - echo "$progname: cannot guess host type; you must specify one" 1>&2 - echo "$help" 1>&2 - exit 1 - fi ;; - esac - host=`$SHELL $ac_config_sub $host_alias` - echo "$ac_t$host" 1>&6 - - # Make sure the host verified. - test -z "$host" && exit 1 - -elif test -z "$host"; then - echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 - echo "$help" 1>&2 - exit 1 -else - host_alias=$host -fi - -# Transform linux* to *-*-linux-gnu*, to support old configure scripts. -case "$host_os" in -linux-gnu*) ;; -linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` -esac - -host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -case "$host_os" in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR cru $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -# Set a sane default for `AR'. -test -z "$AR" && AR=ar - -# Set a sane default for `OBJDUMP'. -test -z "$OBJDUMP" && OBJDUMP=objdump - -# If RANLIB is not set, then run the test. -if test "${RANLIB+set}" != "set"; then - result=no - - echo $ac_n "checking for ranlib... $ac_c" 1>&6 - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then - RANLIB="ranlib" - result="ranlib" - break - fi - done - IFS="$save_ifs" - - echo "$ac_t$result" 1>&6 -fi - -if test -n "$RANLIB"; then - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" -fi - -# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$AS" && AS=as - -# Check to see if we are using GCC. -if test "$with_gcc" != yes || test -z "$CC"; then - # If CC is not set, then try to find GCC or a usable CC. - if test -z "$CC"; then - echo $ac_n "checking for gcc... $ac_c" 1>&6 - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then - CC="gcc" - break - fi - done - IFS="$save_ifs" - - if test -n "$CC"; then - echo "$ac_t$CC" 1>&6 - else - echo "$ac_t"no 1>&6 - fi - fi - - # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". - if test -z "$CC"; then - echo $ac_n "checking for cc... $ac_c" 1>&6 - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - cc_rejected=no - for dir in $PATH; do - test -z "$dir" && dir=. - if test -f $dir/cc || test -f $dir/cc$ac_exeext; then - if test "$dir/cc" = "/usr/ucb/cc"; then - cc_rejected=yes - continue - fi - CC="cc" - break - fi - done - IFS="$save_ifs" - if test $cc_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same name, so the bogon will be chosen - # first if we set CC to just the name; use the full file name. - shift - set dummy "$dir/cc" "$@" - shift - CC="$@" - fi - fi - - if test -n "$CC"; then - echo "$ac_t$CC" 1>&6 - else - echo "$ac_t"no 1>&6 - fi - - if test -z "$CC"; then - echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 - exit 1 - fi - fi - - # Now see if the compiler is really GCC. - with_gcc=no - echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 - echo "$progname:581: checking whether we are using GNU C" >&5 - - $rm conftest.c - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - with_gcc=yes - fi - $rm conftest.c - echo "$ac_t$with_gcc" 1>&6 -fi - -# Allow CC to be a program name with arguments. -set dummy $CC -compiler="$2" - -echo $ac_n "checking for object suffix... $ac_c" 1>&6 -$rm conftest* -echo 'int i = 1;' > conftest.c -echo "$progname:603: checking for object suffix" >& 5 -if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then - # Append any warnings to the config.log. - cat conftest.err 1>&5 - - for ac_file in conftest.*; do - case $ac_file in - *.c) ;; - *) objext=`echo $ac_file | sed -e s/conftest.//` ;; - esac - done -else - cat conftest.err 1>&5 - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 -fi -$rm conftest* -echo "$ac_t$objext" 1>&6 - -echo $ac_n "checking for executable suffix... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_cv_exeext="no" - $rm conftest* - echo 'main () { return 0; }' > conftest.c - echo "$progname:629: checking for executable suffix" >& 5 - if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then - # Append any warnings to the config.log. - cat conftest.err 1>&5 - - for ac_file in conftest.*; do - case $ac_file in - *.c | *.err | *.$objext ) ;; - *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; - esac - done - else - cat conftest.err 1>&5 - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 - fi - $rm conftest* -fi -if test "X$ac_cv_exeext" = Xno; then - exeext="" -else - exeext="$ac_cv_exeext" -fi -echo "$ac_t$ac_cv_exeext" 1>&6 - -echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 -pic_flag= -special_shlib_compile_flags= -wl= -link_static_flag= -no_builtin_flag= - -if test "$with_gcc" = yes; then - wl='-Wl,' - link_static_flag='-static' - - case "$host_os" in - beos* | irix5* | irix6* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - aix*) - # Below there is a dirty hack to force normal static linking with -ldl - # The problem is because libdl dynamically linked with both libc and - # libC (AIX C++ library), which obviously doesn't included in libraries - # list by gcc. This cause undefined symbols with -static flags. - # This hack allows C programs to be linked with "-static -ldl", but - # we not sure about C++ programs. - link_static_flag="$link_static_flag ${wl}-lC" - ;; - cygwin* | mingw* | os2*) - # We can build DLLs from non-PIC. - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - pic_flag='-m68020 -resident32 -malways-restore-a4' - ;; - sysv4*MP*) - if test -d /usr/nec; then - pic_flag=-Kconform_pic - fi - ;; - *) - pic_flag='-fPIC' - ;; - esac -else - # PORTME Check for PIC flags for the system compiler. - case "$host_os" in - aix3* | aix4*) - # All AIX code is PIC. - link_static_flag='-bnso -bI:/lib/syscalls.exp' - ;; - - hpux9* | hpux10* | hpux11*) - # Is there a better link_static_flag that works with the bundled CC? - wl='-Wl,' - link_static_flag="${wl}-a ${wl}archive" - pic_flag='+Z' - ;; - - irix5* | irix6*) - wl='-Wl,' - link_static_flag='-non_shared' - # PIC (with -KPIC) is the default. - ;; - - cygwin* | mingw* | os2*) - # We can build DLLs from non-PIC. - ;; - - osf3* | osf4* | osf5*) - # All OSF/1 code is PIC. - wl='-Wl,' - link_static_flag='-non_shared' - ;; - - sco3.2v5*) - pic_flag='-Kpic' - link_static_flag='-dn' - special_shlib_compile_flags='-belf' - ;; - - solaris*) - pic_flag='-KPIC' - link_static_flag='-Bstatic' - wl='-Wl,' - ;; - - sunos4*) - pic_flag='-PIC' - link_static_flag='-Bstatic' - wl='-Qoption ld ' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - pic_flag='-KPIC' - link_static_flag='-Bstatic' - wl='-Wl,' - ;; - - uts4*) - pic_flag='-pic' - link_static_flag='-Bstatic' - ;; - sysv4*MP*) - if test -d /usr/nec ;then - pic_flag='-Kconform_pic' - link_static_flag='-Bstatic' - fi - ;; - *) - can_build_shared=no - ;; - esac -fi - -if test -n "$pic_flag"; then - echo "$ac_t$pic_flag" 1>&6 - - # Check to make sure the pic_flag actually works. - echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 - $rm conftest* - echo "int some_variable = 0;" > conftest.c - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $pic_flag -DPIC" - echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 - if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then - # Append any warnings to the config.log. - cat conftest.err 1>&5 - - case "$host_os" in - hpux9* | hpux10* | hpux11*) - # On HP-UX, both CC and GCC only warn that PIC is supported... then they - # create non-PIC objects. So, if there were any warnings, we assume that - # PIC is not supported. - if test -s conftest.err; then - echo "$ac_t"no 1>&6 - can_build_shared=no - pic_flag= - else - echo "$ac_t"yes 1>&6 - pic_flag=" $pic_flag" - fi - ;; - *) - echo "$ac_t"yes 1>&6 - pic_flag=" $pic_flag" - ;; - esac - else - # Append any errors to the config.log. - cat conftest.err 1>&5 - can_build_shared=no - pic_flag= - echo "$ac_t"no 1>&6 - fi - CFLAGS="$save_CFLAGS" - $rm conftest* -else - echo "$ac_t"none 1>&6 -fi - -# Check to see if options -o and -c are simultaneously supported by compiler -echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 -$rm -r conftest 2>/dev/null -mkdir conftest -cd conftest -$rm conftest* -echo "int some_variable = 0;" > conftest.c -mkdir out -# According to Tom Tromey, Ian Lance Taylor reported there are C compilers -# that will create temporary files in the current directory regardless of -# the output directory. Thus, making CWD read-only will cause this test -# to fail, enabling locking or at least warning the user not to do parallel -# builds. -chmod -w . -save_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -o out/conftest2.o" -echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 -if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then - - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s out/conftest.err; then - echo "$ac_t"no 1>&6 - compiler_c_o=no - else - echo "$ac_t"yes 1>&6 - compiler_c_o=yes - fi -else - # Append any errors to the config.log. - cat out/conftest.err 1>&5 - compiler_c_o=no - echo "$ac_t"no 1>&6 -fi -CFLAGS="$save_CFLAGS" -chmod u+w . -$rm conftest* out/* -rmdir out -cd .. -rmdir conftest -$rm -r conftest 2>/dev/null - -if test x"$compiler_c_o" = x"yes"; then - # Check to see if we can write to a .lo - echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 - $rm conftest* - echo "int some_variable = 0;" > conftest.c - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -c -o conftest.lo" - echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 -if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then - - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - echo "$ac_t"no 1>&6 - compiler_o_lo=no - else - echo "$ac_t"yes 1>&6 - compiler_o_lo=yes - fi - else - # Append any errors to the config.log. - cat conftest.err 1>&5 - compiler_o_lo=no - echo "$ac_t"no 1>&6 - fi - CFLAGS="$save_CFLAGS" - $rm conftest* -else - compiler_o_lo=no -fi - -# Check to see if we can do hard links to lock some files if needed -hard_links="nottested" -if test "$compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$ac_t$hard_links" 1>&6 - $rm conftest* - if test "$hard_links" = no; then - echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 - need_locks=warn - fi -else - need_locks=no -fi - -if test "$with_gcc" = yes; then - # Check to see if options -fno-rtti -fno-exceptions are supported by compiler - echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 - $rm conftest* - echo "int some_variable = 0;" > conftest.c - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" - echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 - if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then - - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - echo "$ac_t"no 1>&6 - compiler_rtti_exceptions=no - else - echo "$ac_t"yes 1>&6 - compiler_rtti_exceptions=yes - fi - else - # Append any errors to the config.log. - cat conftest.err 1>&5 - compiler_rtti_exceptions=no - echo "$ac_t"no 1>&6 - fi - CFLAGS="$save_CFLAGS" - $rm conftest* - - if test "$compiler_rtti_exceptions" = "yes"; then - no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' - else - no_builtin_flag=' -fno-builtin' - fi - -fi - -# Check for any special shared library compilation flags. -if test -n "$special_shlib_compile_flags"; then - echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 - if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : - else - echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 - can_build_shared=no - fi -fi - -echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 -$rm conftest* -echo 'main(){return(0);}' > conftest.c -save_LDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS $link_static_flag" -echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 -if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - echo "$ac_t$link_static_flag" 1>&6 -else - echo "$ac_t"none 1>&6 - link_static_flag= -fi -LDFLAGS="$save_LDFLAGS" -$rm conftest* - -if test -z "$LN_S"; then - # Check to see if we can use ln -s, or we need hard links. - echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 - $rm conftest.dat - if ln -s X conftest.dat 2>/dev/null; then - $rm conftest.dat - LN_S="ln -s" - else - LN_S=ln - fi - if test "$LN_S" = "ln -s"; then - echo "$ac_t"yes 1>&6 - else - echo "$ac_t"no 1>&6 - fi -fi - -# Make sure LD is an absolute path. -if test -z "$LD"; then - ac_prog=ld - if test "$with_gcc" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 - echo "$progname:991: checking for ld used by GCC" >&5 - ac_prog=`($CC -print-prog-name=ld) 2>&5` - case "$ac_prog" in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we are not using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac - elif test "$with_gnu_ld" = yes; then - echo $ac_n "checking for GNU ld... $ac_c" 1>&6 - echo "$progname:1015: checking for GNU ld" >&5 - else - echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 - echo "$progname:1018: checking for non-GNU ld" >&5 - fi - - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" - fi - - if test -n "$LD"; then - echo "$ac_t$LD" 1>&6 - else - echo "$ac_t"no 1>&6 - fi - - if test -z "$LD"; then - echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 - exit 1 - fi -fi - -# Check to see if it really is or is not GNU ld. -echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 -# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - with_gnu_ld=yes -else - with_gnu_ld=no -fi -echo "$ac_t$with_gnu_ld" 1>&6 - -# See if the linker supports building shared libraries. -echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 - -allow_undefined_flag= -no_undefined_flag= -need_lib_prefix=unknown -need_version=unknown -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -archive_cmds= -archive_expsym_cmds= -old_archive_from_new_cmds= -export_dynamic_flag_spec= -whole_archive_flag_spec= -thread_safe_flag_spec= -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no -hardcode_shlibpath_var=unsupported -runpath_var= -always_export_symbols=no -export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' -# include_expsyms should be a list of space-separated symbols to be *always* -# included in the symbol list -include_expsyms= -# exclude_expsyms can be an egrep regular expression of symbols to exclude -# it will be wrapped by ` (' and `)$', so one must not match beginning or -# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', -# as well as any symbol that contains `d'. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" -# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out -# platforms (ab)use it in PIC code, but their linkers get confused if -# the symbol is explicitly referenced. Since portable code cannot -# rely on this symbol name, it's probably fine to never include it in -# preloaded symbol tables. - -case "$host_os" in -cygwin* | mingw*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$with_gcc" != yes; then - with_gnu_ld=no - fi - ;; - -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case "$host_os" in - aix3* | aix4*) - # On AIX, the GNU linker is very broken - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - ;; - - amigaos*) - archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=yes - - # Extract the symbol export list from an `--export-all' def file, - # then regenerate the def file from the symbol export list, so that - # the compiled dll only exports the symbol export list. - export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ - test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ - $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ - sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols' - - archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ - _lt_hint=1; - for symbol in `cat $export_symbols`; do - echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def; - _lt_hint=`expr 1 + \$_lt_hint`; - done~ - test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ - test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ - $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ - $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ - $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' - - old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' - # can we support soname and/or expsyms with a.out? -oliva - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - case $host_os in - cygwin* | mingw*) - # dlltool doesn't understand --whole-archive et. al. - whole_archive_flag_spec= - ;; - *) - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - ;; - esac - fi -else - # PORTME fill in a description of your system's linker (not GNU ld) - case "$host_os" in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$with_gcc" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4*) - hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' - hardcode_libdir_separator=':' - if test "$with_gcc" = yes; then - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - shared_flag='-shared' - else - shared_flag='${wl}-bM:SRE' - hardcode_direct=yes - fi - allow_undefined_flag=' ${wl}-berok' - archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' - archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' - case "$host_os" in aix4.[01]|aix4.[01].*) - # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on - always_export_symbols=yes ;; - esac - ;; - - amigaos*) - archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - cygwin* | mingw*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs' - fix_srcfile_path='`cygpath -w $srcfile`' - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9* | hpux10* | hpux11*) - case "$host_os" in - hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; - *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; - esac - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_minus_L=yes # Not in the search PATH, but as the default - # location of the library. - export_dynamic_flag_spec='${wl}-E' - ;; - - irix5* | irix6*) - if test "$with_gcc" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF - fi - hardcode_libdir_flag_spec='${wl}-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - openbsd*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' - ;; - - osf3*) - if test "$with_gcc" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # As osf3* with the addition of the -msym flag - if test "$with_gcc" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case "$host_os" in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - unixware7*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac -fi -echo "$ac_t$ld_shlibs" 1>&6 -test "$ld_shlibs" = no && can_build_shared=no - -if test -z "$NM"; then - echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 - case "$NM" in - [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - NM="$ac_dir/nm -B" - break - elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - NM="$ac_dir/nm -p" - break - else - NM=${NM="$ac_dir/nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - fi - fi - done - IFS="$ac_save_ifs" - test -z "$NM" && NM=nm - ;; - esac - echo "$ac_t$NM" 1>&6 -fi - -# Check for command to grab the raw symbol name followed by C symbol from nm. -echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" - -# Define system-specific variables. -case "$host_os" in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw*) - symcode='[ABCDGISTW]' - ;; -hpux*) # Its linker distinguishes data from code symbols - global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" - ;; -irix*) - symcode='[BCDEGRST]' - ;; -solaris*) - symcode='[BDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then - symcode='[ABCDGISTW]' -fi - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. - global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - $rm conftest* - cat > conftest.c <&5 - if { (eval echo $progname:1636: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then - # Now try to grab the symbols. - nlist=conftest.nm - if { echo "$progname:1639: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then - - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if egrep ' nm_test_var$' "$nlist" >/dev/null; then - if egrep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.c -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' - - cat <> conftest.c -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[] = -{ -EOF - sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c - cat <<\EOF >> conftest.c - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$objext conftstm.$objext - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="conftstm.$objext" - CFLAGS="$CFLAGS$no_builtin_flag" - if { (eval echo $progname:1691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - pipe_works=yes - else - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 - fi - LIBS="$save_LIBS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.c >&5 - fi - $rm conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - global_symbol_pipe= - fi -done -if test "$pipe_works" = yes; then - echo "${ac_t}ok" 1>&6 -else - echo "${ac_t}failed" 1>&6 -fi - -if test -z "$global_symbol_pipe"; then - global_symbol_to_cdecl= -fi - -# Check hardcoding attributes. -echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var"; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$hardcode_shlibpath_var" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -echo "$ac_t$hardcode_action" 1>&6 - - -reload_flag= -reload_cmds='$LD$reload_flag -o $output$reload_objs' -echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 -# PORTME Some linkers may need a different reload flag. -reload_flag='-r' -echo "$ac_t$reload_flag" 1>&6 -test -n "$reload_flag" && reload_flag=" $reload_flag" - -# PORTME Fill in your ld.so characteristics -library_names_spec= -libname_spec='lib$name' -soname_spec= -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -file_magic_cmd= -file_magic_test_file= -deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [regex]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given egrep regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. -echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 -case "$host_os" in -aix3*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}.so$major' - ;; - -aix4*) - version_type=linux - # AIX has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - # We preserve .a as extension for shared libraries though AIX4.2 - # and later linker supports .so - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' - shlibpath_var=LIBPATH - deplibs_check_method=pass_all - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}.so' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - deplibs_check_method=pass_all - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - file_magic_cmd=/usr/bin/file - file_magic_test_file=/shlib/libc.so - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - export_dynamic_flag_spec=-rdynamic - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw*) - version_type=windows - need_version=no - need_lib_prefix=no - if test "$with_gcc" = yes; then - library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' - else - library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' - fi - dynamic_linker='Win32 ld.exe' - deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - file_magic_cmd='${OBJDUMP} -f' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case "$version_type" in - freebsd-elf*) - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /usr/lib/libc.so*` - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - deplibs_check_method=unknown - library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case "$host_os" in - freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - dynamic_linker="$host_os dld.sl" - version_type=sunos - need_lib_prefix=no - need_version=no - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' - soname_spec='${libname}${release}.sl$major' - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6*) - version_type=irix - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}.so.$major' - library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' - case "$host_os" in - irix5*) - libsuff= shlibsuff= - # this will be overridden with pass_all, but let us keep it just in case - deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" - ;; - *) - case "$LD" in # libtool.m4 will add one of these switches to LD - *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /lib${libsuff}/libc.so*` - deplibs_check_method='pass_all' - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux-gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` - - if test -f /lib/ld.so.1; then - dynamic_linker='GNU ld.so' - else - # Only the GNU ld.so supports shared libraries on MkLinux. - case "$host_cpu" in - powerpc*) dynamic_linker=no ;; - *) dynamic_linker='Linux ld.so' ;; - esac - fi - ;; - -netbsd*) - version_type=sunos - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' - soname_spec='${libname}${release}.so$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - ;; - -openbsd*) - version_type=sunos - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - need_version=no - fi - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - ;; - -os2*) - libname_spec='$name' - need_lib_prefix=no - library_names_spec='$libname.dll $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_version=no - soname_spec='${libname}${release}.so' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - shlibpath_var=LD_LIBRARY_PATH - # this will be overridden with pass_all, but let us keep it just in case - deplibs_check_method='file_magic COFF format alpha shared library' - file_magic_cmd=/usr/bin/file - file_magic_test_file=/shlib/libc.so - deplibs_check_method='pass_all' - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" - file_magic_cmd=/usr/bin/file - file_magic_test_file=/lib/libc.so - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - case "$host_vendor" in - ncr) - deplibs_check_method='pass_all' - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - file_magic_cmd=/usr/bin/file - file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - esac - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' - soname_spec='$libname.so.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$ac_t$dynamic_linker" 1>&6 -test "$dynamic_linker" = no && can_build_shared=no - -# Report the final consequences. -echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 - -# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in -# configure.in, otherwise build static only libraries. -case "$host_os" in -cygwin* | mingw* | os2*) - if test x$can_build_shared = xyes; then - test x$enable_win32_dll = xno && can_build_shared=no - echo "checking if package supports dlls... $can_build_shared" 1>&6 - fi -;; -esac - -if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then - case "$deplibs_check_method" in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - egrep "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac -fi - -echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4*) - test "$enable_shared" = yes && enable_static=no - ;; -esac - -echo "$ac_t$enable_shared" 1>&6 - -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes - -echo "checking whether to build static libraries... $enable_static" 1>&6 - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -echo $ac_n "checking for objdir... $ac_c" 1>&6 -rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - objdir=_libs -fi -rmdir .libs 2>/dev/null -echo "$ac_t$objdir" 1>&6 - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else -if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then - lt_cv_dlopen=no lt_cv_dlopen_libs= -echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "$progname:2212: checking for dlopen in -ldl" >&5 -ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldl $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dlopen""... $ac_c" 1>&6 -echo "$progname:2252: checking for dlopen" >&5 -if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -dlopen(); -#endif - -; return 0; } -EOF -if { (eval echo $progname:2282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_dlopen=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_dlopen=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 -echo "$progname:2299: checking for dld_link in -ldld" >&5 -ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for shl_load""... $ac_c" 1>&6 -echo "$progname:2339: checking for shl_load" >&5 -if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -shl_load(); -#endif - -; return 0; } -EOF -if { (eval echo $progname:2369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_shl_load=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_shl_load=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="shl_load" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "$progname:2387: checking for shl_load in -ldld" >&5 -ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - echo "$ac_t""no" 1>&6 -fi - - -fi - - -fi - - -fi - - -fi - -fi - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - fi - - case "$lt_cv_dlopen" in - dlopen) -for ac_hdr in dlfcn.h; do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "$progname:2452: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -int fnord = 0; -EOF -ac_try="$ac_compile >/dev/null 2>conftest.out" -{ (eval echo $progname:2462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi -done - - if test "x$ac_cv_header_dlfcn_h" = xyes; then - CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - fi - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 -echo "$progname:2490: checking whether a program can dlopen itself" >&5 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - lt_cv_dlopen_self=cross - else - cat > conftest.c < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LTDL_GLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LTDL_GLOBAL DL_GLOBAL -# else -# define LTDL_GLOBAL 0 -# endif -#endif - -/* We may have to define LTDL_LAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LTDL_LAZY_OR_NOW -# ifdef RTLD_LAZY -# define LTDL_LAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LTDL_LAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LTDL_LAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LTDL_LAZY_OR_NOW DL_NOW -# else -# define LTDL_LAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -fnord() { int i=42;} -main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); - if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); - if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } - -EOF -if { (eval echo $progname:2544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - lt_cv_dlopen_self=yes -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - lt_cv_dlopen_self=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$lt_cv_dlopen_self" 1>&6 - - if test "$lt_cv_dlopen_self" = yes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 -echo "$progname:2563: checking whether a statically linked program can dlopen itself" >&5 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - lt_cv_dlopen_self_static=cross - else - cat > conftest.c < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LTDL_GLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LTDL_GLOBAL DL_GLOBAL -# else -# define LTDL_GLOBAL 0 -# endif -#endif - -/* We may have to define LTDL_LAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LTDL_LAZY_OR_NOW -# ifdef RTLD_LAZY -# define LTDL_LAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LTDL_LAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LTDL_LAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LTDL_LAZY_OR_NOW DL_NOW -# else -# define LTDL_LAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -fnord() { int i=42;} -main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); - if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); - if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } - -EOF -if { (eval echo $progname:2617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - lt_cv_dlopen_self_static=yes -else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - lt_cv_dlopen_self_static=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 -fi - ;; - esac - - case "$lt_cv_dlopen_self" in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case "$lt_cv_dlopen_self_static" in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - -# Copy echo and quote the copy, instead of the original, because it is -# used later. -ltecho="$echo" -if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then - ltecho="$CONFIG_SHELL \$0 --fallback-echo" -fi -LTSHELL="$SHELL" - -LTCONFIG_VERSION="$VERSION" - -# Only quote variables if we're using ltmain.sh. -case "$ltmain" in -*.sh) - # Now quote all the things that may contain metacharacters. - for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ - old_LD old_LDFLAGS old_LIBS \ - old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ - AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ - reload_flag reload_cmds wl \ - pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ - thread_safe_flag_spec whole_archive_flag_spec libname_spec \ - library_names_spec soname_spec \ - RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ - old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ - file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ - finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ - hardcode_libdir_flag_spec hardcode_libdir_separator \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do - - case "$var" in - reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case "$ltecho" in - *'\$0 --fallback-echo"') - ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` - ;; - esac - - trap "$rm \"$ofile\"; exit 1" 1 2 15 - echo "creating $ofile" - $rm "$ofile" - cat < "$ofile" -#! $SHELL - -# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. -# -# Copyright (C) 1996-1999 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="sed -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -### BEGIN LIBTOOL CONFIG -EOF - cfgfile="$ofile" - ;; - -*) - # Double-quote the variables that need it (for aesthetics). - for var in old_CC old_CFLAGS old_CPPFLAGS \ - old_LD old_LDFLAGS old_LIBS \ - old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do - eval "$var=\\\"\$var\\\"" - done - - # Just create a config file. - cfgfile="$ofile.cfg" - trap "$rm \"$cfgfile\"; exit 1" 1 2 15 - echo "creating $cfgfile" - $rm "$cfgfile" - cat < "$cfgfile" -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -EOF - ;; -esac - -cat <> "$cfgfile" -# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# -# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ -# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ -# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ -# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ -# $0$ltconfig_args -# -# Compiler and other test output produced by $progname, useful for -# debugging $progname, is in ./config.log if it exists. - -# The version of $progname that generated this script. -LTCONFIG_VERSION=$LTCONFIG_VERSION - -# Shell to use when invoking shell scripts. -SHELL=$LTSHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$ltecho - -# The archiver. -AR=$AR - -# The default C compiler. -CC=$CC - -# The linker used to build libraries. -LD=$LD - -# Whether we need hard or soft links. -LN_S=$LN_S - -# A BSD-compatible nm program. -NM=$NM - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$reload_flag -reload_cmds=$reload_cmds - -# How to pass a linker flag through the compiler. -wl=$wl - -# Object file suffix (normally "o"). -objext="$objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$pic_flag - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$compiler_c_o - -# Can we write directly to a .lo ? -compiler_o_lo=$compiler_o_lo - -# Must we lock files when doing compilation ? -need_locks=$need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$link_static_flag - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$RANLIB -old_archive_cmds=$old_archive_cmds -old_postinstall_cmds=$old_postinstall_cmds -old_postuninstall_cmds=$old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$old_archive_from_new_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$archive_cmds -archive_expsym_cmds=$archive_expsym_cmds -postinstall_cmds=$postinstall_cmds -postuninstall_cmds=$postuninstall_cmds - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$global_symbol_to_cdecl - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$hardcode_libdir_separator - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$include_expsyms - -EOF - -case "$ltmain" in -*.sh) - echo '### END LIBTOOL CONFIG' >> "$ofile" - echo >> "$ofile" - case "$host_os" in - aix3*) - cat <<\EOF >> "$ofile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # Append the ltmain.sh script. - sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - - chmod +x "$ofile" - ;; - -*) - # Compile the libtool program. - echo "FIXME: would compile $ltmain" - ;; -esac - -test -n "$cache_file" || exit 0 - -# AC_CACHE_SAVE -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -exit 0 - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/Tools/ltmain.sh b/Tools/ltmain.sh index 1c9b9033e..7e0c9f487 100644 --- a/Tools/ltmain.sh +++ b/Tools/ltmain.sh @@ -1,7 +1,8 @@ # ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# NOTE: Changing this file will not affect anything until you rerun configure. # -# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # This program is free software; you can redistribute it and/or modify @@ -48,14 +49,14 @@ EOF fi # The name of this program. -progname=`$echo "$0" | sed 's%^.*/%%'` +progname=`$echo "$0" | ${SED} 's%^.*/%%'` modename="$progname" # Constants. PROGRAM=ltmain.sh PACKAGE=libtool -VERSION=1.3.4 -TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)" +VERSION=1.4.3 +TIMESTAMP=" (1.922.2.110 2002/10/23 01:39:54)" default_mode= help="Try \`$progname --help' for more information." @@ -66,10 +67,19 @@ rm="rm -f" # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' +Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' -SP2NL='tr \040 \012' -NL2SP='tr \015\012 \040\040' +# test EBCDIC or ASCII +case `echo A|od -x` in + *[Cc]1*) # EBCDIC based system + SP2NL="tr '\100' '\n'" + NL2SP="tr '\r\n' '\100\100'" + ;; + *) # Assume ASCII based system + SP2NL="tr '\040' '\012'" + NL2SP="tr '\015\012' '\040\040'" + ;; +esac # NLS nuisances. # Only set LANG and LC_ALL to C if already set. @@ -83,11 +93,8 @@ if test "${LANG+set}" = set; then save_LANG="$LANG"; LANG=C; export LANG fi -if test "$LTCONFIG_VERSION" != "$VERSION"; then - echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 -fi +# Make sure IFS has a sensible default +: ${IFS=" "} if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then echo "$modename: not configured to build any kind of library" 1>&2 @@ -113,16 +120,16 @@ do arg="$1" shift - case "$arg" in + case $arg in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then - case "$prev" in + case $prev in execute_dlfiles) - eval "$prev=\"\$$prev \$arg\"" + execute_dlfiles="$execute_dlfiles $arg" ;; *) eval "$prev=\$arg" @@ -135,7 +142,7 @@ do fi # Have we seen a non-optional argument yet? - case "$arg" in + case $arg in --help) show_help=yes ;; @@ -146,7 +153,7 @@ do ;; --config) - sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0 + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 exit 0 ;; @@ -179,6 +186,8 @@ do --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; + --preserve-dup-deps) duplicate_deps="yes" ;; + --quiet | --silent) show=: ;; @@ -207,16 +216,21 @@ if test -n "$prevopt"; then exit 1 fi +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then - case "$nonopt" in - *cc | *++ | gcc* | *-gcc*) + case $nonopt in + *cc | *++ | gcc* | *-gcc* | xlc*) mode=link for arg do - case "$arg" in + case $arg in -c) mode=compile break @@ -261,12 +275,13 @@ if test -z "$show_help"; then help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. - case "$mode" in + case $mode in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= + prev= lastarg= srcfile="$nonopt" suppress_output= @@ -274,8 +289,34 @@ if test -z "$show_help"; then user_target=no for arg do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + # Accept any command-line options. - case "$arg" in + case $arg in -o) if test "$user_target" != "no"; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 @@ -288,9 +329,53 @@ if test -z "$show_help"; then build_old_libs=yes continue ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; esac - case "$user_target" in + case $user_target in next) # The next one is the -o target name user_target=yes @@ -316,10 +401,10 @@ if test -z "$show_help"; then lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly in scan - # sets, so we specify it separately. - case "$lastarg" in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") lastarg="\"$lastarg\"" ;; esac @@ -332,7 +417,7 @@ if test -z "$show_help"; then fi done - case "$user_target" in + case $user_target in set) ;; no) @@ -348,7 +433,7 @@ if test -z "$show_help"; then # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSfmso]' - case "$libobj" in + case $libobj in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; @@ -363,7 +448,7 @@ if test -z "$show_help"; then libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - case "$libobj" in + case $libobj in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 @@ -387,10 +472,21 @@ if test -z "$show_help"; then $run $rm $removelist trap "$run $rm $removelist; exit 1" 1 2 15 + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext} + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit 1" 1 2 15 @@ -402,7 +498,7 @@ if test -z "$show_help"; then # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then - until ln "$0" "$lockfile" 2>/dev/null; do + until $run ln "$0" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done @@ -434,8 +530,13 @@ compiler." # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi if test "$build_old_libs" = yes; then lo_libobj="$libobj" dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` @@ -506,7 +607,8 @@ compiler." fi # If we have no pic_flag, then copy the object into place and finish. - if test -z "$pic_flag" && test "$build_old_libs" = yes; then + if (test -z "$pic_flag" || test "$pic_mode" != default) && + test "$build_old_libs" = yes; then # Rename the .lo from within objdir to obj if test -f $obj; then $show $rm $obj @@ -532,6 +634,10 @@ compiler." # Now arrange that obj and lo_libobj become the same file $show "(cd $xdir && $LN_S $baseobj $libobj)" if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi exit 0 else error=$? @@ -546,7 +652,13 @@ compiler." # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then - command="$base_compile $srcfile" + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi if test "$compiler_c_o" = yes; then command="$command -o $obj" output_obj="$obj" @@ -612,17 +724,17 @@ compiler." # Unlock the critical section if it was locked if test "$need_locks" != no; then - $rm "$lockfile" + $run $rm "$lockfile" fi exit 0 ;; # libtool link mode - link) + link | relink) modename="$modename: link" - case "$host" in - *-*-cygwin* | *-*-mingw* | *-*-os2*) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra @@ -635,179 +747,12 @@ compiler." # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes - - # This is a source program that is used to create dlls on Windows - # Don't remove nor modify the starting and closing comments -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include -# #undef WIN32_LEAN_AND_MEAN -# #include -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ - # This is a source program that is used to create import libraries - # on Windows for dlls which lack them. Don't remove nor modify the - # starting and closing comments -# /* impgen.c starts here */ -# /* Copyright (C) 1999 Free Software Foundation, Inc. -# -# This file is part of GNU libtool. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# */ -# -# #include /* for printf() */ -# #include /* for open(), lseek(), read() */ -# #include /* for O_RDONLY, O_BINARY */ -# #include /* for strdup() */ -# -# static unsigned int -# pe_get16 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[2]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 2); -# return b[0] + (b[1]<<8); -# } -# -# static unsigned int -# pe_get32 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[4]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 4); -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# static unsigned int -# pe_as32 (ptr) -# void *ptr; -# { -# unsigned char *b = ptr; -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# int -# main (argc, argv) -# int argc; -# char *argv[]; -# { -# int dll; -# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; -# unsigned long export_rva, export_size, nsections, secptr, expptr; -# unsigned long name_rvas, nexp; -# unsigned char *expdata, *erva; -# char *filename, *dll_name; -# -# filename = argv[1]; -# -# dll = open(filename, O_RDONLY|O_BINARY); -# if (!dll) -# return 1; -# -# dll_name = filename; -# -# for (i=0; filename[i]; i++) -# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') -# dll_name = filename + i +1; -# -# pe_header_offset = pe_get32 (dll, 0x3c); -# opthdr_ofs = pe_header_offset + 4 + 20; -# num_entries = pe_get32 (dll, opthdr_ofs + 92); -# -# if (num_entries < 1) /* no exports */ -# return 1; -# -# export_rva = pe_get32 (dll, opthdr_ofs + 96); -# export_size = pe_get32 (dll, opthdr_ofs + 100); -# nsections = pe_get16 (dll, pe_header_offset + 4 +2); -# secptr = (pe_header_offset + 4 + 20 + -# pe_get16 (dll, pe_header_offset + 4 + 16)); -# -# expptr = 0; -# for (i = 0; i < nsections; i++) -# { -# char sname[8]; -# unsigned long secptr1 = secptr + 40 * i; -# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); -# unsigned long vsize = pe_get32 (dll, secptr1 + 16); -# unsigned long fptr = pe_get32 (dll, secptr1 + 20); -# lseek(dll, secptr1, SEEK_SET); -# read(dll, sname, 8); -# if (vaddr <= export_rva && vaddr+vsize > export_rva) -# { -# expptr = fptr + (export_rva - vaddr); -# if (export_rva + export_size > vaddr + vsize) -# export_size = vsize - (export_rva - vaddr); -# break; -# } -# } -# -# expdata = (unsigned char*)malloc(export_size); -# lseek (dll, expptr, SEEK_SET); -# read (dll, expdata, export_size); -# erva = expdata - export_rva; -# -# nexp = pe_as32 (expdata+24); -# name_rvas = pe_as32 (expdata+32); -# -# printf ("EXPORTS\n"); -# for (i = 0; i\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" # If the previous option needs an argument, assign it. if test -n "$prev"; then - case "$prev" in + case $prev in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac - case "$prev" in + case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. @@ -905,7 +851,7 @@ compiler." finalize_command="$finalize_command @SYMFILE@" preload=yes fi - case "$arg" in + case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then @@ -934,6 +880,7 @@ compiler." dlprefiles="$dlprefiles $arg" fi prev= + continue ;; esac ;; @@ -958,7 +905,7 @@ compiler." ;; rpath | xrpath) # We need an absolute path. - case "$arg" in + case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 @@ -979,17 +926,32 @@ compiler." prev= continue ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac - fi + fi # test -n $prev prevarg="$arg" - case "$arg" in + case $arg in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" @@ -1026,7 +988,7 @@ compiler." -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: not more than one -exported-symbols argument allowed" + $echo "$modename: more than one -exported-symbols argument is not allowed" exit 1 fi if test "X$arg" = "X-export-symbols"; then @@ -1037,58 +999,76 @@ compiler." continue ;; + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | no/*-*-nonstopux*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. - case "$dir" in + case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - absdir="$dir" + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 fi dir="$absdir" ;; esac - case " $deplibs " in - *" $arg "*) ;; - *) deplibs="$deplibs $arg";; + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; esac - case " $lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir";; - esac - case "$host" in - *-*-cygwin* | *-*-mingw* | *-*-os2*) - dllsearchdir=`cd "$dir" && pwd || echo "$dir"` - case ":$dllsearchpath:" in - ::) dllsearchpath="$dllsearchdir";; - *":$dllsearchdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dllsearchdir";; + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; esac ;; esac + continue ;; -l*) - if test "$arg" = "-lc"; then - case "$host" in - *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) - # These systems don't actually have c library (as such) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) continue ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; esac - elif test "$arg" = "-lm"; then - case "$host" in - *-*-cygwin* | *-*-beos*) - # These systems don't actually have math library (as such) + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" + continue ;; -module) @@ -1096,6 +1076,25 @@ compiler." continue ;; + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + -no-undefined) allow_undefined=no continue @@ -1121,7 +1120,7 @@ compiler." -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. - case "$dir" in + case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 @@ -1136,11 +1135,11 @@ compiler." ;; -static) - # If we have no pic_flag, then this is the same as -all-static. - if test -z "$pic_flag" && test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. continue ;; @@ -1154,28 +1153,71 @@ compiler." continue ;; + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case "$arg" in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac ;; - *.o | *.obj | *.a | *.lib) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A library object. + *.lo | *.$objext) + # A library or standard object. if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" prev= continue else @@ -1188,300 +1230,35 @@ compiler." # Preload the old-style object. dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` prev= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac fi - libobjs="$libobjs $arg" + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue ;; *.la) # A libtool-controlled library. - dlname= - libdir= - library_names= - old_library= - - # Check to see that this really is a libtool archive. - if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 - exit 1 - fi - - # If the library was installed with an old release of libtool, - # it will not redefine variable installed. - installed=yes - - # Read the .la file - # If there is no directory component, then add one. - case "$arg" in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 - exit 1 - fi - - # Find the relevant object directory and library name. - name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` - - if test "X$installed" = Xyes; then - dir="$libdir" - else - dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$arg"; then - dir="$objdir" - else - dir="$dir/$objdir" - fi - fi - - if test -n "$dependency_libs"; then - # Extract -R and -L from dependency_libs - temp_deplibs= - for deplib in $dependency_libs; do - case "$deplib" in - -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - case " $rpath $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - -L*) case "$compile_command $temp_deplibs " in - *" $deplib "*) ;; - *) temp_deplibs="$temp_deplibs $deplib";; - esac - temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'` - case " $lib_search_path " in - *" $temp_dir "*) ;; - *) lib_search_path="$lib_search_path $temp_dir";; - esac - ;; - *) temp_deplibs="$temp_deplibs $deplib";; - esac - done - dependency_libs="$temp_deplibs" - fi - - if test -z "$libdir"; then - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $dir/$old_library" - old_convenience="$old_convenience $dir/$old_library" - deplibs="$deplibs$dependency_libs" - compile_command="$compile_command $dir/$old_library$dependency_libs" - finalize_command="$finalize_command $dir/$old_library$dependency_libs" - continue - fi - - # This library was specified with -dlopen. if test "$prev" = dlfiles; then + # This library was specified with -dlopen. dlfiles="$dlfiles $arg" - if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking statically, - # we need to preload. - prev=dlprefiles - else - # We should not create a dependency on this library, but we - # may need any libraries it requires. - compile_command="$compile_command$dependency_libs" - finalize_command="$finalize_command$dependency_libs" - prev= - continue - fi - fi - - # The library was specified with -dlpreopen. - if test "$prev" = dlprefiles; then - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - dlprefiles="$dlprefiles $dir/$old_library" - else - dlprefiles="$dlprefiles $dir/$linklib" - fi prev= - fi - - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - link_against_libtool_libs="$link_against_libtool_libs $arg" - if test -n "$shlibpath_var"; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *) temp_rpath="$temp_rpath $dir" ;; - esac - fi - - # We need an absolute path. - case "$dir" in - [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - absdir="$dir" - fi - ;; - esac - - # This is the magic to use -rpath. - # Skip directories that are in the system default run-time - # search path, unless they have been requested with -R. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - - lib_linked=yes - case "$hardcode_action" in - immediate | unsupported) - if test "$hardcode_direct" = no; then - compile_command="$compile_command $dir/$linklib" - deplibs="$deplibs $dir/$linklib" - case "$host" in - *-*-cygwin* | *-*-mingw* | *-*-os2*) - dllsearchdir=`cd "$dir" && pwd || echo "$dir"` - if test -n "$dllsearchpath"; then - dllsearchpath="$dllsearchpath:$dllsearchdir" - else - dllsearchpath="$dllsearchdir" - fi - ;; - esac - elif test "$hardcode_minus_L" = no; then - case "$host" in - *-*-sunos*) - compile_shlibpath="$compile_shlibpath$dir:" - ;; - esac - case "$compile_command " in - *" -L$dir "*) ;; - *) compile_command="$compile_command -L$dir";; - esac - compile_command="$compile_command -l$name" - deplibs="$deplibs -L$dir -l$name" - elif test "$hardcode_shlibpath_var" = no; then - case ":$compile_shlibpath:" in - *":$dir:"*) ;; - *) compile_shlibpath="$compile_shlibpath$dir:";; - esac - compile_command="$compile_command -l$name" - deplibs="$deplibs -l$name" - else - lib_linked=no - fi - ;; - - relink) - if test "$hardcode_direct" = yes; then - compile_command="$compile_command $absdir/$linklib" - deplibs="$deplibs $absdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - case "$compile_command " in - *" -L$absdir "*) ;; - *) compile_command="$compile_command -L$absdir";; - esac - compile_command="$compile_command -l$name" - deplibs="$deplibs -L$absdir -l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case ":$compile_shlibpath:" in - *":$absdir:"*) ;; - *) compile_shlibpath="$compile_shlibpath$absdir:";; - esac - compile_command="$compile_command -l$name" - deplibs="$deplibs -l$name" - else - lib_linked=no - fi - ;; - - *) - lib_linked=no - ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit 1 - fi - - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - finalize_command="$finalize_command $libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - case "$finalize_command " in - *" -L$libdir "*) ;; - *) finalize_command="$finalize_command -L$libdir";; - esac - finalize_command="$finalize_command -l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case ":$finalize_shlibpath:" in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:";; - esac - finalize_command="$finalize_command -l$name" - else - # We cannot seem to hardcode it, guess we'll fake it. - case "$finalize_command " in - *" -L$dir "*) ;; - *) finalize_command="$finalize_command -L$libdir";; - esac - finalize_command="$finalize_command -l$name" - fi + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= else - # Transform directly to old archives if we don't build new libraries. - if test -n "$pic_flag" && test -z "$old_library"; then - $echo "$modename: cannot find static library for \`$arg'" 1>&2 - exit 1 - fi - - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_command="$compile_command $dir/$linklib" - finalize_command="$finalize_command $dir/$linklib" - else - case "$compile_command " in - *" -L$dir "*) ;; - *) compile_command="$compile_command -L$dir";; - esac - compile_command="$compile_command -l$name" - case "$finalize_command " in - *" -L$dir "*) ;; - *) finalize_command="$finalize_command -L$dir";; - esac - finalize_command="$finalize_command -l$name" - fi + deplibs="$deplibs $arg" fi - - # Add in any libraries that this one depends upon. - compile_command="$compile_command$dependency_libs" - finalize_command="$finalize_command$dependency_libs" continue ;; @@ -1490,20 +1267,20 @@ compiler." # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case "$arg" in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac ;; - esac + esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi - done + done # argument parsing loop if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 @@ -1517,28 +1294,837 @@ compiler." finalize_command="$finalize_command $arg" fi - oldlibs= # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" - case "$output" in + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit 1 ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac - *.a | *.lib) - if test -n "$link_against_libtool_libs"; then - $echo "$modename: error: cannot link libtool libraries into archives" 1>&2 - exit 1 + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac fi - - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test $linkmode = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test $linkmode = oldlib && test $linkmode = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test $pass = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test $pass = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test $pass = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not used here." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test $pass != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test $linkmode = oldlib && test $linkmode = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test $pass = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test $linkmode != prog && test $linkmode != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test $pass = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test $pass = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test $linkmode = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test $linkmode = prog && test $pass != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test $linkmode = lib && test $hardcode_into_libs = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test $linkmode = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test $linkmode = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test $linkmode = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test $linkmode = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + add="-l$name" + fi + + if test $linkmode = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test $linkmode = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test $linkmode = lib; then + if test -n "$dependency_libs" && + { test $hardcode_into_libs != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test $link_all_deplibs != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test $pass = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test $pass != dlopen; then + test $pass != scan && dependency_libs="$newdependency_libs" + if test $pass != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test $linkmode = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi @@ -1566,11 +2152,12 @@ compiler." # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" + objs="$objs$old_deplibs" ;; - *.la) + lib) # Make sure we only generate libraries of the form `libNAME.la'. - case "$outputname" in + case $outputname in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval libname=\"$libname_spec\" @@ -1591,26 +2178,20 @@ compiler." ;; esac - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - if test -n "$objs"; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 - exit 1 + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi fi - # How the heck are we supposed to write a wrapper for a shared library? - if test -n "$link_against_libtool_libs"; then - $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2 - exit 1 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2 + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 fi set dummy $rpath @@ -1628,7 +2209,6 @@ compiler." build_libtool_libs=convenience build_old_libs=yes fi - dependency_libs="$deplibs" if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 @@ -1640,7 +2220,7 @@ compiler." else # Parse the version information argument. - IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" @@ -1655,8 +2235,8 @@ compiler." age="$4" # Check that each of the things are valid numbers. - case "$current" in - 0 | [1-9] | [1-9][0-9]*) ;; + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; *) $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 @@ -1664,8 +2244,8 @@ compiler." ;; esac - case "$revision" in - 0 | [1-9] | [1-9][0-9]*) ;; + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; *) $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 @@ -1673,8 +2253,8 @@ compiler." ;; esac - case "$age" in - 0 | [1-9] | [1-9][0-9]*) ;; + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; *) $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 @@ -1692,21 +2272,49 @@ compiler." major= versuffix= verstring= - case "$version_type" in + case $version_type in none) ;; - irix) + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) major=`expr $current - $age + 1` - versuffix="$major.$revision" - verstring="sgi$major.$revision" + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test $loop != 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` - verstring="sgi$major.$iface:$verstring" + verstring="$verstring_prefix$major.$iface:$verstring" done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" ;; linux) @@ -1715,7 +2323,7 @@ compiler." ;; osf) - major=`expr $current - $age` + major=.`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" @@ -1736,21 +2344,11 @@ compiler." versuffix=".$current.$revision" ;; - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - windows) - # Like Linux, but with '-' rather than '.', since we only - # want one extension on Windows 95. + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. major=`expr $current - $age` - versuffix="-$major-$age-$revision" + versuffix="-$major" ;; *) @@ -1764,6 +2362,16 @@ compiler." if test -z "$vinfo" && test -n "$release"; then major= verstring="0.0" + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring="" + ;; + *) + verstring="0.0" + ;; + esac if test "$need_version" = no; then versuffix= else @@ -1777,7 +2385,7 @@ compiler." versuffix= verstring="" fi - + # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then @@ -1789,30 +2397,12 @@ compiler." # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi - - dependency_libs="$deplibs" - case "$host" in - *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *) - # Add libc to deplibs on all other systems. - deplibs="$deplibs -lc" - ;; - esac fi - # Create the output directory, or remove our outputs if we need to. - if test -d $output_objdir; then + if test "$mode" != relink; then + # Remove our outputs. $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* - else - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test $status -ne 0 && test ! -d $output_objdir; then - exit $status - fi fi # Now set the variables for building old libraries. @@ -1823,7 +2413,73 @@ compiler." oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test $build_libtool_need_lc = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname @@ -1838,7 +2494,7 @@ compiler." major="" newdeplibs= droppeddeps=no - case "$deplibs_check_method" in + case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check @@ -1863,7 +2519,7 @@ EOF for i in $deplibs; do name="`expr $i : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. - if test "$name" != "" ; then + if test -n "$name" && test "$name" != "0"; then libname=`eval \\$echo \"$libname_spec\"` deplib_matches=`eval \\$echo \"$library_names_spec\"` set dummy $deplib_matches @@ -1873,22 +2529,24 @@ EOF else droppeddeps=yes echo - echo "*** Warning: This library needs some functionality provided by $i." + echo "*** Warning: dynamic linker does not accept needed library $i." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." + echo "*** shared version of the library, which I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." fi else newdeplibs="$newdeplibs $i" fi done else - # Error occured in the first compile. Let's try to salvage the situation: - # Compile a seperate program for each library. + # Error occured in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. for i in $deplibs; do name="`expr $i : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. - if test "$name" != "" ; then + if test -n "$name" && test "$name" != "0"; then $rm conftest $CC -o conftest conftest.c $i # Did it work? @@ -1903,10 +2561,12 @@ EOF else droppeddeps=yes echo - echo "*** Warning: This library needs some functionality provided by $i." + echo "*** Warning: dynamic linker does not accept needed library $i." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." + echo "*** shared version of the library, which you do not appear to have" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." fi else droppeddeps=yes @@ -1924,19 +2584,19 @@ EOF ;; file_magic*) set dummy $deplibs_check_method - file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` for a_deplib in $deplibs; do name="`expr $a_deplib : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. - if test "$name" != "" ; then + if test -n "$name" && test "$name" != "0"; then libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path; do + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null \ | grep " -> " >/dev/null; then - continue + continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. @@ -1945,14 +2605,14 @@ EOF # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | sed 's/.* -> //'` - case "$potliblink" in + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | sed 10q \ + | ${SED} 10q \ | egrep "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" @@ -1963,10 +2623,59 @@ EOF if test -n "$a_deplib" ; then droppeddeps=yes echo - echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for file magic test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check below in file_magic test + if eval echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a regex pattern. Last file checked: $potlib" + fi fi else # Add a -L argument. @@ -1996,6 +2705,13 @@ EOF libname=$libname_save name=$name_save + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + if test "$droppeddeps" = yes; then if test "$module" = yes; then echo @@ -2021,6 +2737,21 @@ EOF echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi fi fi # Done checking deplibs! @@ -2031,9 +2762,64 @@ EOF library_names= old_library= dlname= - + # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then + if test $hardcode_into_libs = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + # Get the real and link names of the library. eval library_names=\"$library_names_spec\" set dummy $library_names @@ -2045,6 +2831,7 @@ EOF else soname="$realname" fi + test -z "$dlname" && dlname=$soname lib="$output_objdir/$realname" for link @@ -2079,7 +2866,7 @@ EOF export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols eval cmds=\"$export_symbols_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -2116,7 +2903,7 @@ EOF for xlib in $convenience; do # Extract the objects. - case "$xlib" in + case $xlib in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac @@ -2141,16 +2928,32 @@ EOF if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" - linkopts="$linkopts $flag" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval cmds=\"$archive_expsym_cmds\" else + save_deplibs="$deplibs" + for conv in $convenience; do + tmp_deplibs= + for test_deplib in $deplibs; do + if test "$test_deplib" != "$conv"; then + tmp_deplibs="$tmp_deplibs $test_deplib" + fi + done + deplibs="$tmp_deplibs" + done eval cmds=\"$archive_cmds\" + deplibs="$save_deplibs" fi - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -2158,6 +2961,12 @@ EOF done IFS="$save_ifs" + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then @@ -2174,12 +2983,7 @@ EOF fi ;; - *.lo | *.o | *.obj) - if test -n "$link_against_libtool_libs"; then - $echo "$modename: error: cannot link libtool libraries into objects" 1>&2 - exit 1 - fi - + obj) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi @@ -2204,9 +3008,9 @@ EOF $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi - case "$output" in + case $output in *.lo) - if test -n "$objs"; then + if test -n "$objs$old_deplibs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit 1 fi @@ -2230,7 +3034,7 @@ EOF gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec - wl= + wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then @@ -2249,7 +3053,7 @@ EOF for xlib in $convenience; do # Extract the objects. - case "$xlib" in + case $xlib in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac @@ -2273,11 +3077,11 @@ EOF fi # Create the old-style object. - reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" eval cmds=\"$reload_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -2308,12 +3112,12 @@ EOF exit 0 fi - if test -n "$pic_flag"; then + if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" eval cmds=\"$reload_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -2344,8 +3148,10 @@ EOF exit 0 ;; - # Anything else should be a program. - *) + prog) + case $host in + *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi @@ -2355,20 +3161,34 @@ EOF fi if test "$preload" = yes; then - if test "$dlopen" = unknown && test "$dlopen_self" = unknown && + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi + fi fi - + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. - case "$compile_rpath " in - *" $libdir "*) ;; - *) compile_rpath="$compile_rpath $libdir" ;; - esac case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; @@ -2386,7 +3206,7 @@ EOF hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. - case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) @@ -2404,6 +3224,14 @@ EOF *) perm_rpath="$perm_rpath $libdir" ;; esac fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && @@ -2422,7 +3250,7 @@ EOF hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. - case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) @@ -2449,23 +3277,6 @@ EOF fi finalize_rpath="$rpath" - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - - # Create the binary in the object directory, then wrap it. - if test ! -d $output_objdir; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test $status -ne 0 && test ! -d $output_objdir; then - exit $status - fi - fi - if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` @@ -2482,7 +3293,7 @@ EOF fi if test -n "$dlsyms"; then - case "$dlsyms" in + case $dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. @@ -2514,7 +3325,7 @@ extern \"C\" { test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" @@ -2524,7 +3335,7 @@ extern \"C\" { $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi - + if test -n "$export_symbols_regex"; then $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' @@ -2534,9 +3345,9 @@ extern \"C\" { if test -z "$export_symbols"; then export_symbols="$output_objdir/$output.exp" $run $rm $export_symbols - $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' else - $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' fi @@ -2544,7 +3355,7 @@ extern \"C\" { for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" - name=`echo "$arg" | sed -e 's%^.*/%%'` + name=`echo "$arg" | ${SED} -e 's%^.*/%%'` $run eval 'echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done @@ -2559,7 +3370,13 @@ extern \"C\" { fi # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S @@ -2576,27 +3393,25 @@ extern \"C\" { #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * +# define lt_ptr void * #else -# define lt_ptr_t char * +# define lt_ptr char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; - lt_ptr_t address; + lt_ptr address; } lt_preloaded_symbols[] = {\ " - sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ - -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ - < "$nlist" >> "$output_objdir/$dlsyms" + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr_t) 0} + {0, (lt_ptr) 0} }; /* This works around a problem in FreeBSD linker */ @@ -2613,7 +3428,7 @@ static const void *lt_preloaded_setup() { fi pic_flag_for_symtable= - case "$host" in + case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use @@ -2658,7 +3473,7 @@ static const void *lt_preloaded_setup() { finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi - if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + if test $need_relink = no || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" @@ -2667,7 +3482,7 @@ static const void *lt_preloaded_setup() { $show "$link_command" $run eval "$link_command" status=$? - + # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" @@ -2681,7 +3496,7 @@ static const void *lt_preloaded_setup() { # We should set the shlibpath_var rpath= for dir in $temp_rpath; do - case "$dir" in + case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" @@ -2723,11 +3538,24 @@ static const void *lt_preloaded_setup() { fi fi + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" - + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else @@ -2747,7 +3575,7 @@ static const void *lt_preloaded_setup() { # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - + # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname @@ -2759,12 +3587,24 @@ static const void *lt_preloaded_setup() { # Quote the relink command for shipping. if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $0 --fallback-echo"; then - case "$0" in + case $0 in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; *) qecho="$SHELL `pwd`/$0 --fallback-echo";; esac @@ -2778,7 +3618,12 @@ static const void *lt_preloaded_setup() { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in - *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; esac $rm $output trap "$rm $output; exit 1" 1 2 15 @@ -2797,7 +3642,7 @@ static const void *lt_preloaded_setup() { # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' +Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -2809,7 +3654,7 @@ relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: - link_against_libtool_libs='$link_against_libtool_libs' + notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then @@ -2835,20 +3680,20 @@ else test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in - [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;; + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done # Try to get the absolute directory name. @@ -2858,11 +3703,11 @@ else if test "$fast_install" = yes; then echo >> $output "\ - program=lt-'$outputname' + program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" - + if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" @@ -2877,8 +3722,9 @@ else # relink executable if necessary if test -n \"\$relink_command\"; then - if (cd \"\$thisdir\" && eval \$relink_command); then : + if relink_command_output=\`eval \$relink_command 2>&1\`; then : else + $echo \"\$relink_command_output\" >&2 $rm \"\$progdir/\$file\" exit 1 fi @@ -2907,7 +3753,7 @@ else $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed + # The second colon is a workaround for a bug in BeOS R4 ${SED} $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var @@ -2927,13 +3773,21 @@ else # Run the actual program with our arguments. " case $host in - *-*-cygwin* | *-*-mingw | *-*-os2*) - # win32 systems need to use the prog path for dll - # lookup to work + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) $echo >> $output "\ exec \$progdir\\\\\$program \${1+\"\$@\"} " ;; + *) $echo >> $output "\ # Export the path to the program. @@ -2975,7 +3829,7 @@ fi\ oldobjs="$libobjs_save" build_libtool_libs=no else - oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` fi addlibs="$old_convenience" fi @@ -2991,11 +3845,11 @@ fi\ exit $status fi generated="$generated $gentop" - + # Add in members from convenience archives. for xlib in $addlibs; do # Extract the objects. - case "$xlib" in + case $xlib in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac @@ -3041,7 +3895,7 @@ fi\ eval cmds=\"$old_archive_cmds\" fi - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -3056,19 +3910,26 @@ fi\ fi # Now create the libtool archive. - case "$output" in + case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" - if test -n "$xrpath"; then - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - done - dependency_libs="$temp_xrpath $dependency_libs" - fi + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` # Only create the output if not a dry run. if test -z "$run"; then @@ -3078,8 +3939,52 @@ fi\ break fi output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" fi $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP @@ -3088,7 +3993,7 @@ fi\ # It is necessary for linking the library. # The name that we can dlopen(3). -dlname='$dlname' +dlname='$tdlname' # Names of this library. library_names='$library_names' @@ -3107,16 +4012,23 @@ revision=$revision # Is this an already installed library? installed=$installed +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + # Directory that this library needs to be installed in: -libdir='$install_libdir'\ -" +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $? + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ;; esac exit 0 @@ -3128,10 +4040,12 @@ libdir='$install_libdir'\ # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case "$arg" in + case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; @@ -3147,7 +4061,7 @@ libdir='$install_libdir'\ # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case "$arg" in + case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; @@ -3170,7 +4084,7 @@ libdir='$install_libdir'\ continue fi - case "$arg" in + case $arg in -d) isdir=yes ;; -f) prev="-f" ;; -g) prev="-g" ;; @@ -3195,7 +4109,7 @@ libdir='$install_libdir'\ # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case "$arg" in + case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; @@ -3246,11 +4160,11 @@ libdir='$install_libdir'\ exit 1 fi fi - case "$destdir" in + case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do - case "$file" in + case $file in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 @@ -3272,15 +4186,15 @@ libdir='$install_libdir'\ for file in $files; do # Do each installation. - case "$file" in - *.a | *.lib) + case $file in + *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 @@ -3289,8 +4203,9 @@ libdir='$install_libdir'\ library_names= old_library= + relink_command= # If there is no directory component, then add one. - case "$file" in + case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac @@ -3309,10 +4224,20 @@ libdir='$install_libdir'\ esac fi - dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ test "X$dir" = "X$file/" && dir= dir="$dir$objdir" + if test -n "$relink_command"; then + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + continue + fi + fi + # See the names of the shared library. set dummy $library_names if test -n "$2"; then @@ -3320,9 +4245,16 @@ libdir='$install_libdir'\ shift shift + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + # Install the shared library and build the symlinks. - $show "$install_prog $dir/$realname $destdir/$realname" - $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi if test $# -gt 0; then # Delete the old symlinks, and create new ones. @@ -3338,7 +4270,7 @@ libdir='$install_libdir'\ # Do each command in the postinstall commands. lib="$destdir/$realname" eval cmds=\"$postinstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -3369,11 +4301,11 @@ libdir='$install_libdir'\ fi # Deduce the name of the destination old-style object file. - case "$destfile" in + case $destfile in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; - *.o | *.obj) + *.$objext) staticdest="$destfile" destfile= ;; @@ -3411,40 +4343,55 @@ libdir='$install_libdir'\ fi # Do a test to see if this is really a libtool program. - if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - link_against_libtool_libs= + case $host in + *cygwin*|*mingw*) + wrapper=`echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= relink_command= # If there is no directory component, then add one. - case "$file" in - */* | *\\*) . $file ;; - *) . ./$file ;; + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; esac # Check the variables that should have been set. - if test -z "$link_against_libtool_libs"; then - $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 exit 1 fi finalize=yes - for lib in $link_against_libtool_libs; do + for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. - case "$lib" in + case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi - libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then @@ -3456,6 +4403,7 @@ libdir='$install_libdir'\ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 continue fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` @@ -3477,6 +4425,23 @@ libdir='$install_libdir'\ fi fi + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" @@ -3493,9 +4458,14 @@ libdir='$install_libdir'\ $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + # Do each command in the postinstall commands. eval cmds=\"$old_postinstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -3511,11 +4481,10 @@ libdir='$install_libdir'\ if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" - exec $SHELL $0 --finish$current_libdirs - exit 1 + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 fi - - exit 0 ;; # libtool finish mode @@ -3534,7 +4503,7 @@ libdir='$install_libdir'\ if test -n "$finish_cmds"; then # Do each command in the finish commands. eval cmds=\"$finish_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" @@ -3553,8 +4522,8 @@ libdir='$install_libdir'\ fi # Exit here if they wanted silent mode. - test "$show" = : && exit 0 - exit 0 + test "$show" = ":" && exit 0 + echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do @@ -3563,7 +4532,7 @@ libdir='$install_libdir'\ echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use \`-LLIBDIR'" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" @@ -3613,10 +4582,10 @@ libdir='$install_libdir'\ fi dir= - case "$file" in + case $file in *.la) # Check to see that this really is a libtool archive. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 @@ -3628,7 +4597,7 @@ libdir='$install_libdir'\ library_names= # If there is no directory component, then add one. - case "$file" in + case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac @@ -3683,13 +4652,13 @@ libdir='$install_libdir'\ args= for file do - case "$file" in + case $file in -*) ;; *) # Do a test to see if this is really a libtool program. - if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. - case "$file" in + case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac @@ -3706,8 +4675,8 @@ libdir='$install_libdir'\ if test -z "$run"; then if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" + # Export the shlibpath_var. + eval "export $shlibpath_var" fi # Restore saved enviroment variables @@ -3718,31 +4687,35 @@ libdir='$install_libdir'\ LANG="$save_LANG"; export LANG fi - # Now actually exec the command. - eval "exec \$cmd$args" - - $echo "$modename: cannot exec \$cmd$args" - exit 1 + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" fi $echo "$cmd$args" exit 0 fi ;; - # libtool uninstall mode - uninstall) - modename="$modename: uninstall" + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" rm="$nonopt" files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" for arg do - case "$arg" in + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac @@ -3754,53 +4727,86 @@ libdir='$install_libdir'\ exit 1 fi + rmdirs= + for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi rmfiles="$file" - case "$name" in + case $name in *.la) # Possibly a libtool archive, so verify it. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do - rmfiles="$rmfiles $dir/$n" + rmfiles="$rmfiles $objdir/$n" done - test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - $show "$rm $rmfiles" - $run $rm $rmfiles - - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - eval cmds=\"$postuninstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - done - IFS="$save_ifs" - fi + fi - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - eval cmds=\"$old_postuninstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - done - IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. fi - - # FIXME: should reinstall the best remaining shared library. fi ;; @@ -3809,17 +4815,35 @@ libdir='$install_libdir'\ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` rmfiles="$rmfiles $dir/$oldobj" fi - $show "$rm $rmfiles" - $run $rm $rmfiles ;; *) - $show "$rm $rmfiles" - $run $rm $rmfiles + # Do a test to see if this is a libtool program. + if test $mode = clean && + (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi ;; esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 done - exit 0 + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status ;; "") @@ -3829,13 +4853,20 @@ libdir='$install_libdir'\ ;; esac - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi fi # test -z "$show_help" +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + # We need to display help for each of the modes. -case "$mode" in +case $mode in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... @@ -3854,6 +4885,7 @@ Provide generalized library-building support services. MODE must be one of the following: + clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries @@ -3866,6 +4898,20 @@ a more detailed description of MODE." exit 0 ;; +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE @@ -3875,6 +4921,8 @@ Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file @@ -3954,6 +5002,8 @@ The following components of LINK-COMMAND are treated specially: -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -release RELEASE specify package release information diff --git a/Tools/mkdist.py b/Tools/mkdist.py index 3917cf01e..899cebbcf 100755 --- a/Tools/mkdist.py +++ b/Tools/mkdist.py @@ -19,11 +19,11 @@ os.system("rm -rf "+dirname) # Do a CVS export on the directory name print "Checking out SWIG" -os.system("cvs export -D now -d "+dirname+ " SWIG") +os.system("cvs export -D now -r rel-1-3 -d "+dirname+ " SWIG") # Now clean the source directory -SOURCES = ['DOH','Swig','Preprocessor','SWIG1.1','Modules1.1', 'Modules', 'Include'] +SOURCES = ['DOH','Swig','Preprocessor','CParse','Modules1.1', 'Modules', 'Include'] srcs = [ ] for d in SOURCES: @@ -58,10 +58,9 @@ f = open(dirname+"/configure.in","w") f.write(s) f.close() -# Clean the documentation directory +# Remove the debian directory -- it's not official -print "Cleaning the Doc directory" -os.system("rm -rf "+dirname+"/Doc/*") +os.system("rm -Rf "+dirname+"/debian"); # Blow away all .cvsignore files @@ -73,8 +72,17 @@ os.system("find "+dirname+" -name .cvsignore -exec rm {} \\;"); os.system("cd "+dirname+"; autoconf") os.system("cd "+dirname+"/Source/DOH; autoconf") os.system("cd "+dirname+"/Tools; autoconf") -os.system("cd "+dirname+"/Source/SWIG1.1; bison -y -d parser.yxx; mv y.tab.c parser.cxx; mv y.tab.h parser.h") +os.system("cd "+dirname+"/Examples/GIFPlot; autoconf") +os.system("cd "+dirname+"/Tools/WAD; autoconf") +os.system("cd "+dirname+"/Source/CParse; bison -y -d parser.y; mv y.tab.c parser.c; mv y.tab.h parser.h") +# Remove autoconf files +os.system("find "+dirname+" -name autom4te.cache -exec rm -rf {} \\;"); + +# Build documentation +os.system("cd "+dirname+"/Doc/Manual; python maketoc.py; rm *.bak") + +# Build the tar-ball os.system("tar -cf "+string.lower(dirname)+".tar "+dirname) os.system("gzip "+string.lower(dirname)+".tar") diff --git a/Tools/setup.py.tmpl b/Tools/setup.py.tmpl new file mode 100644 index 000000000..0bfcde2f5 --- /dev/null +++ b/Tools/setup.py.tmpl @@ -0,0 +1,139 @@ +#!@PYTHON@ +'''A setup.py script with better SWIG support. To use it, either +rename it to setup.py.in and have it pe processed by your configure +script (you will need to define @PYTHON@), or replace the @*@ strings +by hand. + +Copyright 2001, Anthony Joseph Seward''' + + +from distutils.core import setup, Extension + +############################################################################### +## Start of better Swig support +############################################################################### +from distutils.command.build_ext import build_ext +import os +import string +class build_swig_ext(build_ext): + '''Better swig support for Distutils''' + + ## __ Tell Distutils about the options + user_options = build_ext.user_options + boolean_options = build_ext.boolean_options + + user_options.append( + ('swig-doc=', None, + 'what type of documentation should SWIG produce (default: none)') + ) + user_options.append( + ('swig-inc=', None, + 'a list of directories to add to the SWIG include path' + + "(separated by ':')(default: SWIG)") + ) + user_options.append( + ('swig-shadow', None, + 'have SWIG create shadow classes' + + ' (also adds docstrings to the shadow classes') + ) + + boolean_options.append('swig-shadow') + + def initialize_options(self): + '''Initialize the new options after the inherited ones''' + build_ext.initialize_options(self) + self.swig_doc = 'none' + self.swig_inc = 'SWIG' + self.swig_shadow = None + + def swig_sources(self, sources): + """Override the definition of 'swig_sources' in build_ext. This + is essentially the same function but with better swig support. + I will now quote the original docstring: + + Walk the list of source files in 'sources', looking for SWIG + interface (.i) files. Run SWIG on all that are found, and + return a modified 'sources' list with SWIG source files replaced + by the generated C (or C++) files. + """ + + new_sources = [] + swig_sources = [] + swig_targets = {} + + # XXX this drops generated C/C++ files into the source tree, which + # is fine for developers who want to distribute the generated + # source -- but there should be an option to put SWIG output in + # the temp dir. + + if self.swig_cpp: + target_ext = '.cpp' + else: + target_ext = '.c' + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == ".i": # SWIG interface file + new_sources.append(base + target_ext) + swig_sources.append(source) + swig_targets[source] = new_sources[-1] + else: + new_sources.append(source) + + if not swig_sources: + return new_sources + + includes = self.swig_inc + if type(includes) is type(''): + includes = string.split(includes, ':') + includes = map(lambda x: '-I'+x, includes) + includes = string.join(includes) + + swig = self.find_swig() +## swig_cmd = [swig, "-python", "-d%s" % self.swig_doc, includes] + swig_cmd = [swig, '-v', '-python', '-d%s' % self.swig_doc, includes] + if self.swig_cpp: + swig_cmd.append('-c++') + + if self.swig_shadow: + swig_cmd.append('-shadow') +## swig1.1 swig_cmd.append('-docstring') + + for source in swig_sources: + target = swig_targets[source] + self.announce('swigging %s to %s' % (source, target)) + self.spawn(swig_cmd + ['-o', target, source]) + + return new_sources + + # swig_sources () +############################################################################### +## End of improved swig support +############################################################################### + +package = '@PACKAGE@' +version = '@VERSION@' +include_dirs = ['@top_srcdir@'] +lib_dirs = ['@top_srcdir@/@PACKAGE@'] +libraries = ['@PACKAGE@', 'stdc++'] + +setup(name = package, + version = version, + description = '', + author = '', + author_email = '', + url = 'http://', + + cmdclass = {'build_ext': build_swig_ext}, + ext_modules = [Extension(package+'cmodule', + [package+'.i'], + include_dirs=include_dirs, + library_dirs=lib_dirs, + libraries=libraries, + )], + options = {'build_ext': + {'swig_doc': 'html', + 'swig_cpp': not None, + 'swig_shadow': not None} + } + ) diff --git a/Tools/swig-1.3a1-1.spec b/Tools/swig-1.3a1-1.spec deleted file mode 100644 index a9a113c68..000000000 --- a/Tools/swig-1.3a1-1.spec +++ /dev/null @@ -1,83 +0,0 @@ -# Preamble -Summary: Simplified Wrapper and Interface Generator -Name: swig -Version: 1.3a3 -Release: 1 -Copyright: BSD -URL: http://www.swig.org -Group: System Environment/Daemons -Source0: http://download.sourceforge.net/swig/swig1.3a3.tar.gz -Packager: Dustin Mitchell -%description -SWIG is an interface compiler that connects programs written in C, -C++, and Objective-C with scripting languages including Perl, Python, -and Tcl/Tk. It works by taking the declarations commonly found in -C/C++ header files and using them to generate the glue code (wrappers) -that scripting languages need to access the underlying C/C++ code - -# PREP -%prep -rm -rf $RPM_BUILD_DIR/swig1.3a3 -zcat $RPM_SOURCE_DIR/swig1.3a3.tar.gz | tar -xvvf - -mv $RPM_BUILD_DIR/SWIG1.3a3 $RPM_BUILD_DIR/swig1.3a3 - -# BUILD -%build -cd $RPM_BUILD_DIR/swig1.3a3 -./configure --prefix=/usr -make - -# INSTALL -%install -cd $RPM_BUILD_DIR/swig1.3a3 -make install - -# FILES -%files -/usr/lib/swig1.3/tcl/constarray.i -/usr/lib/swig1.3/tcl/consthash.i -/usr/lib/swig1.3/tcl/ptrlang.i -/usr/lib/swig1.3/tcl/tclsh.i -/usr/lib/swig1.3/tcl/typemaps.i -/usr/lib/swig1.3/tcl/wish.i -/usr/lib/swig1.3/tcl/object.swg -/usr/lib/swig1.3/tcl/swigtcl8.swg -/usr/lib/swig1.3/array.i -/usr/lib/swig1.3/autodoc.i -/usr/lib/swig1.3/carray.i -/usr/lib/swig1.3/constraints.i -/usr/lib/swig1.3/ctype.i -/usr/lib/swig1.3/exception.i -/usr/lib/swig1.3/malloc.i -/usr/lib/swig1.3/math.i -/usr/lib/swig1.3/memory.i -/usr/lib/swig1.3/objc.i -/usr/lib/swig1.3/pointer.i -/usr/lib/swig1.3/stdlib.i -/usr/lib/swig1.3/timers.i -/usr/lib/swig1.3/perl5/perlmain.i -/usr/lib/swig1.3/perl5/ptrlang.i -/usr/lib/swig1.3/perl5/typemaps.i -/usr/lib/swig1.3/perl5/headers.swg -/usr/lib/swig1.3/perl5/perl5.swg -/usr/lib/swig1.3/perl5/perl5mg.swg -/usr/lib/swig1.3/perl5/Makefile.pl -/usr/lib/swig1.3/python/embed.i -/usr/lib/swig1.3/python/embed13.i -/usr/lib/swig1.3/python/embed14.i -/usr/lib/swig1.3/python/embed15.i -/usr/lib/swig1.3/python/ptrlang.i -/usr/lib/swig1.3/python/typemaps.i -/usr/lib/swig1.3/python/typemaps_old.i -/usr/lib/swig1.3/python/defarg.swg -/usr/lib/swig1.3/python/python.swg -/usr/lib/swig1.3/guile/guilemain.i -/usr/lib/swig1.3/guile/interpreter.i -/usr/lib/swig1.3/guile/typemaps.i -/usr/lib/swig1.3/guile/guile.swg -/usr/lib/swig1.3/guile/guiledec.swg -/usr/lib/swig1.3/java/typemaps.i -/usr/lib/swig1.3/java/java.swg -/usr/lib/swig1.3/mzscheme/typemaps.i -/usr/lib/swig1.3/mzscheme/mzscheme.swg -/usr/bin/swig diff --git a/Tools/swig.spec b/Tools/swig.spec deleted file mode 100644 index 3a9fb963c..000000000 --- a/Tools/swig.spec +++ /dev/null @@ -1,88 +0,0 @@ -%define ver 1.3a4 -%define prefix /usr - -# Preamble -Summary: Simplified Wrapper and Interface Generator -Name: swig -Version: %ver -Prefix: %prefix -BuildRoot: /usr/src/redhat/BUILD -Release: 1 -Copyright: BSD -URL: http://www.swig.org -Group: System Environment/Daemons -Source0: http://download.sourceforge.net/swig/swig1.3a4.tar.gz -Packager: Dustin Mitchell -%description -SWIG is an interface compiler that connects programs written in C, -C++, and Objective-C with scripting languages including Perl, Python, -and Tcl/Tk. It works by taking the declarations commonly found in -C/C++ header files and using them to generate the glue code (wrappers) -that scripting languages need to access the underlying C/C++ code - -# PREP -%prep -rm -rf $RPM_BUILD_DIR/swig-%{ver} -zcat $RPM_SOURCE_DIR/swig-%{ver}.tar.gz | tar -xvvf - -mv $RPM_BUILD_DIR/SWIG-%{ver} $RPM_BUILD_DIR/swig-%{ver} - -# BUILD -%build -cd $RPM_BUILD_DIR/swig-%{ver} -./configure --prefix=%{prefix} -make - -# INSTALL -%install -cd $RPM_BUILD_DIR/swig-%{ver} -make prefix=$RPM_BUILD_DIR%{prefix} install - -# FILES -%files -%{prefix}/lib/swig1.3/tcl/constarray.i -%{prefix}/lib/swig1.3/tcl/consthash.i -%{prefix}/lib/swig1.3/tcl/ptrlang.i -%{prefix}/lib/swig1.3/tcl/tclsh.i -%{prefix}/lib/swig1.3/tcl/typemaps.i -%{prefix}/lib/swig1.3/tcl/wish.i -%{prefix}/lib/swig1.3/tcl/object.swg -%{prefix}/lib/swig1.3/tcl/swigtcl8.swg -%{prefix}/lib/swig1.3/array.i -%{prefix}/lib/swig1.3/autodoc.i -%{prefix}/lib/swig1.3/carray.i -%{prefix}/lib/swig1.3/constraints.i -%{prefix}/lib/swig1.3/ctype.i -%{prefix}/lib/swig1.3/exception.i -%{prefix}/lib/swig1.3/malloc.i -%{prefix}/lib/swig1.3/math.i -%{prefix}/lib/swig1.3/memory.i -%{prefix}/lib/swig1.3/objc.i -%{prefix}/lib/swig1.3/pointer.i -%{prefix}/lib/swig1.3/stdlib.i -%{prefix}/lib/swig1.3/timers.i -%{prefix}/lib/swig1.3/perl5/perlmain.i -%{prefix}/lib/swig1.3/perl5/ptrlang.i -%{prefix}/lib/swig1.3/perl5/typemaps.i -#%{prefix}/lib/swig1.3/perl5/headers.swg # doesn't seem to exist -%{prefix}/lib/swig1.3/perl5/perl5.swg -#%{prefix}/lib/swig1.3/perl5/perl5mg.swg # doesn't seem to exist -%{prefix}/lib/swig1.3/perl5/Makefile.pl -%{prefix}/lib/swig1.3/python/embed.i -%{prefix}/lib/swig1.3/python/embed13.i -%{prefix}/lib/swig1.3/python/embed14.i -%{prefix}/lib/swig1.3/python/embed15.i -%{prefix}/lib/swig1.3/python/ptrlang.i -%{prefix}/lib/swig1.3/python/typemaps.i -%{prefix}/lib/swig1.3/python/typemaps_old.i -%{prefix}/lib/swig1.3/python/defarg.swg -%{prefix}/lib/swig1.3/python/python.swg -%{prefix}/lib/swig1.3/guile/guilemain.i -%{prefix}/lib/swig1.3/guile/interpreter.i -%{prefix}/lib/swig1.3/guile/typemaps.i -%{prefix}/lib/swig1.3/guile/guile.swg -%{prefix}/lib/swig1.3/guile/guiledec.swg -%{prefix}/lib/swig1.3/java/typemaps.i -%{prefix}/lib/swig1.3/java/java.swg -%{prefix}/lib/swig1.3/mzscheme/typemaps.i -%{prefix}/lib/swig1.3/mzscheme/mzscheme.swg -%{prefix}/bin/swig diff --git a/Tools/swig.spec.1 b/Tools/swig.spec.1 new file mode 100644 index 000000000..7af0440cd --- /dev/null +++ b/Tools/swig.spec.1 @@ -0,0 +1,42 @@ +%define version 1.3.7 +%define release 1 + +# Preamble +Summary: Simplified Wrapper and Interface Generator +Name: swig +Version: %{version} +Release: %{release} +Copyright: BSD +URL: http://www.swig.org +Group: System Environment/Daemons +Source0: http://download.sourceforge.net/swig/swig-%{version}.tar.gz +Packager: Dustin Mitchell +BuildRoot: /var/tmp/rpm/swig-root +Prefix: /usr + +%description +SWIG is an interface compiler that connects programs written in C, +C++, and Objective-C with scripting languages including Perl, Python, +and Tcl/Tk. It works by taking the declarations commonly found in +C/C++ header files and using them to generate the glue code (wrappers) +that scripting languages need to access the underlying C/C++ code + +# PREP +%prep +%setup -n SWIG-%{version} + +# BUILD +%build +./configure --prefix=%prefix +make + +# INSTALL +%install +rm -rf ${RPM_BUILD_ROOT} +install -d -m 755 ${RPM_BUILD_ROOT} +make prefix=${RPM_BUILD_ROOT}%prefix install + +# FILES +%files +%prefix/lib/* +%prefix/bin/swig diff --git a/VERSION b/VERSION index 9278dce12..8565151f3 100644 --- a/VERSION +++ b/VERSION @@ -14,10 +14,10 @@ devrelease_today=u-`date +%Y%m%d-%H%M` SWIG_MAJOR_VERSION=1 -SWIG_MINOR_VERSION=3$devrelease_today +SWIG_MINOR_VERSION=3 +SWIG_SPIN=17 -SWIG_VERSION=$SWIG_MAJOR_VERSION.$SWIG_MINOR_VERSION -SWIG_SPIN='(Alpha 6)' +SWIG_VERSION=$SWIG_MAJOR_VERSION.$SWIG_MINOR_VERSION.$SWIG_SPIN$devrelease_today # For autoconf. VERSION=$SWIG_VERSION diff --git a/Win/README.txt b/Win/README.txt index fbab67953..4bdb9e1d7 100644 --- a/Win/README.txt +++ b/Win/README.txt @@ -1 +1 @@ -This directory contains files for building SWIG on Windows. +Please see the Doc/Manual/Windows.html file in the main manual for instructions for using and installing SWIG on Windows including running the examples. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 000000000..2e1beaef2 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,5 @@ +#! /bin/sh +# Bootstrap the development environment +autoconf +(cd Source/DOH; autoconf) +(cd Tools; autoconf) diff --git a/configure.in b/configure.in index 78e8e362b..22e8ec183 100644 --- a/configure.in +++ b/configure.in @@ -7,12 +7,14 @@ dnl to nothing) and `test -z "$VAR"' or `test -n "$VAR"' as the dnl case may be. --ttn, 2000/08/04 12:11:26 AC_INIT(Source/Swig/swig.h) -AC_PREREQ(2.0) +AC_PREREQ(2.53) . $srcdir/VERSION AC_SUBST(PACKAGE) AC_SUBST(VERSION) AC_SUBST(SWIG_VERSION) AC_SUBST(SWIG_SPIN) +AC_SUBST(SWIG_MAJOR_VERSION) +AC_SUBST(SWIG_MINOR_VERSION) # Set name for machine-dependent library files AC_SUBST(MACHDEP) @@ -61,6 +63,8 @@ dnl Checks for library functions. AC_SUBST(SO) AC_SUBST(LDSHARED) AC_SUBST(CCSHARED) +AC_SUBST(CXXSHARED) +AC_SUBST(TRYLINKINGWITHCXX) AC_SUBST(LINKFORSHARED) # SO is the extension of shared libraries `(including the dot!) @@ -70,6 +74,7 @@ if test -z "$SO" then case $ac_sys_system in hp*|HP*) SO=.sl;; + CYGWIN*) SO=.dll;; *) SO=.so;; esac fi @@ -83,6 +88,18 @@ if test -z "$LDSHARED" then case $ac_sys_system/$ac_sys_release in AIX*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";; + CYGWIN*) + if test "$GCC" = yes; then + LDSHARED="$CC -shared" + else + if test "cl" = $CC ; then + # Microsoft Visual C++ (MSVC) + LDSHARED="$CC -nologo -LD" + else + # Unknown compiler try gcc approach + LDSHARED="$CC -shared" + fi + fi ;; IRIX/5*) LDSHARED="ld -shared";; IRIX*/6*) LDSHARED="ld ${SGI_ABI} -shared -all";; SunOS/4*) LDSHARED="ld";; @@ -110,10 +127,48 @@ then LDSHARED="ld -Bshareable" fi;; SCO_SV*) LDSHARED="cc -G -KPIC -Ki486 -belf -Wl,-Bexport";; + Darwin*) LDSHARED="cc -bundle -undefined suppress -flat_namespace";; *) LDSHARED="ld";; esac fi + AC_MSG_RESULT($LDSHARED) +# CXXSHARED is the ld *command* used to create C++ shared library +# -- "ld" on SunOS 4.x.x, "ld -G" on SunOS 5.x, "ld -shared" on IRIX 5 +# (Shared libraries in this instance are shared modules to be loaded into +# Python, as opposed to building Python itself as a shared library.) +AC_MSG_CHECKING(CXXSHARED) +if test -z "$CXXSHARED" +then + CXXSHARED="$LDSHARED" +fi +AC_MSG_RESULT($CXXSHARED) + +# +AC_MSG_CHECKING(TRYLINKINGWITHCXX) +if test -z "$TRYLINKINGWITHCXX" +then + case $ac_sys_system/$ac_sys_release in + SunOS/5*) if test "$GCC" = yes; + then TRYLINKINGWITHCXX="CXXSHARED= $CXX -Wl,-G"; + else TRYLINKINGWITHCXX="CXXSHARED= $CXX -G -L/opt/SUNWspro/lib -lCrun"; + fi;; + Darwin*) TRYLINKINGWITHCXX="CXXSHARED= $CXX -bundle -undefined suppress -flat_namespace";; + CYGWIN*) + if test "$GCC" = yes; then + TRYLINKINGWITHCXX="CXXSHARED= $CXX -shared " + else + if test "cl" = $CXX ; then + # Microsoft Visual C++ (MSVC) + TRYLINKINGWITHCXX="CXXSHARED= $CXX -nologo -LD" + else + TRYLINKINGWITHCXX="#unknown Windows compiler" + fi + fi ;; + *) TRYLINKINGWITHCXX="CXXSHARED= $CXX -shared ";; + esac +fi +AC_MSG_RESULT($TRYLINKINGWITHCXX) # CCSHARED are the C *flags* used to create objects to go into a shared # library (module) -- this is only needed for a few systems AC_MSG_CHECKING(CCSHARED) @@ -145,10 +200,10 @@ AC_MSG_CHECKING(RPATH) if test -z "$RPATH" then case $ac_sys_system/$ac_sys_release in - SunOS/5*) RPATH="-R. -R$(exec_prefix)/lib";; - IRIX*) RPATH="-rpath .:$(exec_prefix)/lib";; - Linux*) RPATH="-Xlinker -rpath $(exec_prefix)/lib -Xlinker -rpath .";; - *) RPATH="";; + SunOS/5*) RPATH='-R. -R$(exec_prefix)/lib';; + IRIX*) RPATH='-rpath .:$(exec_prefix)/lib';; + Linux*) RPATH='-Xlinker -rpath $(exec_prefix)/lib -Xlinker -rpath .';; + *) RPATH='';; esac fi AC_MSG_RESULT($RPATH) @@ -172,7 +227,6 @@ then fi AC_MSG_RESULT($LINKFORSHARED) - echo "" echo "Checking for installed packages." echo "Note : None of the following packages are required to compile SWIG" @@ -195,6 +249,11 @@ AC_CHECK_LIB(inet, gethostbyname, [LIBS="-linet $LIBS"], [], -lnsl) # Sequent AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets fi + +AC_CHECK_LIB(swill, swill_init, [SWIGLIBS="-lswill $LIBS" SWILL="-DSWIG_SWILL"]) +AC_SUBST(SWIGLIBS) +AC_SUBST(SWILL) + # check for --with-libm=... AC_SUBST(LIBM) LIBM=-lm @@ -290,6 +349,7 @@ fi AC_SUBST(XINCLUDES) AC_SUBST(XLIBSW) + #-------------------------------------------------------------------- # Try to locate the Tcl package #-------------------------------------------------------------------- @@ -298,6 +358,8 @@ TCLINCLUDE= TCLLIB= TCLPACKAGE= +AC_ARG_WITH(tclconfig,[ --with-tclconfig=path Set location of tclConfig.sh], + with_tclconfig="$withval") AC_ARG_WITH(tcl,[ --with-tcl=path Set location of Tcl package],[ TCLPACKAGE="$withval"], [TCLPACKAGE=]) AC_ARG_WITH(tclincl,[ --with-tclincl=path Set location of Tcl include directory],[ @@ -305,6 +367,35 @@ AC_ARG_WITH(tclincl,[ --with-tclincl=path Set location of Tcl include direc AC_ARG_WITH(tcllib,[ --with-tcllib=path Set location of Tcl library directory],[ TCLLIB="-L$withval"], [TCLLIB=]) +AC_MSG_CHECKING([for Tcl configuration]) +# First check to see if --with-tclconfig was specified. +if test x"${with_tclconfig}" != x ; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + TCLCONFIG=`(cd ${with_tclconfig}; pwd)` + else + AC_MSG_ERROR([${with_tcl} directory doesn't contain tclConfig.sh]) + fi +fi +# check in a few common install locations +if test x"${TCLCONFIG}" = x ; then + for i in `ls -d /usr/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` ; do + if test -f "$i/tclConfig.sh" ; then + TCLCONFIG=`(cd $i; pwd)` + break + fi + done +fi +if test x"${TCLCONFIG}" = x ; then + AC_MSG_RESULT(no) +else + AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh) + . $TCLCONFIG/tclConfig.sh + TCLINCLUDE=-I$TCL_PREFIX/include + TCLLIB=$TCL_LIB_SPEC +fi + if test -z "$TCLINCLUDE"; then if test -n "$TCLPACKAGE"; then TCLINCLUDE="-I$TCLPACKAGE/include" @@ -313,7 +404,7 @@ fi if test -z "$TCLLIB"; then if test -n "$TCLPACKAGE"; then - TCLLIB="-L$TCLPACKAGE/lib" + TCLLIB="-L$TCLPACKAGE/lib -ltcl" fi fi @@ -321,7 +412,7 @@ AC_MSG_CHECKING(for Tcl header files) if test -z "$TCLINCLUDE"; then AC_TRY_CPP([#include ], , TCLINCLUDE="") if test -z "$TCLINCLUDE"; then - dirs="$prefix/include /usr/local/include /usr/include /opt/local/include /home/sci/local/include" + dirs="$prefix/include /usr/local/include /usr/include /opt/local/include" for i in $dirs ; do if test -r $i/tcl.h; then AC_MSG_RESULT($i) @@ -331,7 +422,7 @@ if test -z "$TCLINCLUDE"; then done fi if test -z "$TCLINCLUDE"; then - TCLINCLUDE="-I/usr/local/include" +# TCLINCLUDE="-I/usr/local/include" AC_MSG_RESULT(not found) fi else @@ -340,25 +431,31 @@ fi AC_MSG_CHECKING(for Tcl library) if test -z "$TCLLIB"; then -dirs="$prefix/lib /usr/local/lib /usr/lib /opt/local/lib /home/sci/local/lib" +dirs="$prefix/lib /usr/local/lib /usr/lib /opt/local/lib" for i in $dirs ; do if test -r $i/libtcl.a; then AC_MSG_RESULT($i) - TCLLIB="-L$i" + TCLLIB="-L$i -ltcl" break fi done if test -z "$TCLLIB"; then AC_MSG_RESULT(not found) - TCLLIB="-L/usr/local/lib" +# TCLLIB="-L/usr/local/lib" fi else AC_MSG_RESULT($TCLLIB) fi +# Only Cygwin (Windows) needs the library for dynamic linking +case $ac_sys_system/$ac_sys_release in +CYGWIN*) TCLDYNAMICLINKING="$TCLLIB";; +*)TCLDYNAMICLINKING="";; +esac + AC_SUBST(TCLINCLUDE) AC_SUBST(TCLLIB) -AC_SUBST(TCLPACKAGE) +AC_SUBST(TCLDYNAMICLINKING) #---------------------------------------------------------------- # Look for Python @@ -367,77 +464,108 @@ AC_SUBST(TCLPACKAGE) PYINCLUDE= PYLIB= PYPACKAGE= -PYLINK="-lModules -lPython -lObjects -lParser" -AC_ARG_WITH(py,[ --with-py=path Set location of Python],[ - PYPACKAGE="$withval"], [PYPACKAGE=]) -AC_ARG_WITH(pyincl,[ --with-pyincl=path Set location of Python include directory],[ - PYINCLUDE="$withval"], [PYINCLUDE=]) -AC_ARG_WITH(pylib,[ --with-pylib=path Set location of Python library directory],[ - PYLIB="$withval"], [PYLIB=]) +# I don't think any of this commented stuff works anymore -if test -z "$PYINCLUDE"; then - if test -n "$PYPACKAGE"; then - PYINCLUDE="$PYPACKAGE/include" - fi +#PYLINK="-lModules -lPython -lObjects -lParser" + +#AC_ARG_WITH(py,[ --with-py=path Set location of Python],[ +# PYPACKAGE="$withval"], [PYPACKAGE=]) +#AC_ARG_WITH(pyincl,[ --with-pyincl=path Set location of Python include directory],[ +# PYINCLUDE="$withval"], [PYINCLUDE=]) +#AC_ARG_WITH(pylib,[ --with-pylib=path Set location of Python library directory],[ +# PYLIB="$withval"], [PYLIB=]) + +#if test -z "$PYINCLUDE"; then +# if test -n "$PYPACKAGE"; then +# PYINCLUDE="$PYPACKAGE/include" +# fi +#fi + +#if test -z "$PYLIB"; then +# if test -n "$PYPACKAGE"; then +# PYLIB="$PYPACKAGE/lib" +# fi +#fi + +AC_ARG_WITH(python,[ --with-python=path Set location of Python executable],[ PYBIN="$withval"], [PYBIN=]) + +# First figure out the name of the Python executable + +if test -z "$PYBIN"; then +AC_CHECK_PROGS(PYTHON, $prefix/bin/python python python2.4 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5 python1.4 python) +else +PYTHON="$PYBIN" fi -if test -z "$PYLIB"; then - if test -n "$PYPACKAGE"; then - PYLIB="$PYPACKAGE/lib" - fi +if test -n "$PYTHON"; then + AC_MSG_CHECKING(for Python prefix) + PYPREFIX=`($PYTHON -c "import sys; print sys.prefix") 2>/dev/null` + AC_MSG_RESULT($PYPREFIX) + AC_MSG_CHECKING(for Python exec-prefix) + PYEPREFIX=`($PYTHON -c "import sys; print sys.exec_prefix") 2>/dev/null` + AC_MSG_RESULT($PYEPREFIX) + + + # Note: I could not think of a standard way to get the version string from different versions. + # This trick pulls it out of the file location for a standard library file. + + AC_MSG_CHECKING(for Python version) + + # Need to do this hack since autoconf replaces __file__ with the name of the configure file + filehack="file__" + PYVERSION=`($PYTHON -c "import string,operator; print operator.getitem(string.split(string.__$filehack,'/'),-2)")` + AC_MSG_RESULT($PYVERSION) + + # Set the include directory + + AC_MSG_CHECKING(for Python header files) + if test -r $PYPREFIX/include/$PYVERSION/Python.h; then + PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/lib/$PYVERSION/config" + fi + if test -z "$PYINCLUDE"; then + if test -r $PYPREFIX/include/Py/Python.h; then + PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/lib/python/lib" + fi + fi + AC_MSG_RESULT($PYINCLUDE) + + # Set the library directory blindly. This probably won't work with older versions + AC_MSG_CHECKING(for Python library) + dirs="$PYVERSION/config $PYVERSION/lib python/lib" + for i in $dirs; do + if test -d $PYEPREFIX/lib/$i; then + PYLIB="$PYEPREFIX/lib/$i" + break + fi + done + if test -z "$PYLIB"; then + AC_MSG_RESULT(Not found) + else + AC_MSG_RESULT($PYLIB) + fi + + # Check for really old versions + if test -r $PYLIB/libPython.a; then + PYLINK="-lModules -lPython -lObjects -lParser" + else + PYLINK="-l$PYVERSION" + fi fi +# Only Cygwin (Windows) needs the library for dynamic linking +case $ac_sys_system/$ac_sys_release in +CYGWIN*) PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK" + PYINCLUDE="-DUSE_DL_IMPORT $PYINCLUDE" + ;; +*)PYTHONDYNAMICLINKING="";; +esac -AC_MSG_CHECKING(for Python header files) - -dirs="$PYINCLUDE $PYINCLUDE/python1.6 $PYINCLUDE/python1.5 $PYINCLUDE/python1.4 $PYINCLUDE/Py $prefix=/include/python1.6 $prefix/include/python1.5 $prefix/include/python1.4 /usr/local/include/python1.6 /usr/local/include/python1.5 /usr/include/python1.5 /usr/local/include/python1.4 /usr/include/python1.4 $prefix/include/Py /usr/local/include/Py /usr/include/Py" -for i in $dirs ; do - if test -r $i/Python.h; then - AC_MSG_RESULT($i) - PYINCLUDE="-I$i" - break - fi -done -if test -z "$PYINCLUDE"; then - PYINCLUDE="-I/usr/local/include/Py" - AC_MSG_RESULT(not found) -fi - -AC_MSG_CHECKING(for Python library) -dirs="$PYLIB $PYLIB/config $PYLIB/lib $PYLIB/python1.6/config $PYLIB/python1.5/config $PYLIB/python1.4/config $PYLIB/python/lib $prefix/lib/python1.6/config $prefix/lib/python1.5/config $prefix/lib/python1.4/config /usr/local/lib/python1.6/config /usr/local/lib/python1.5/config /usr/lib/python1.5 /usr/local/lib/python1.4/config /usr/lib/python1.4 $prefix/lib/python/lib /usr/local/lib/python/lib /usr/lib/python/lib /home/sci/local/lib/python" - -for i in $dirs ; do - if test -r $i/libpython1.6.a; then - AC_MSG_RESULT($i) - PYLIB="$i" - PYINCLUDE="$PYINCLUDE -I$i" - PYLINK="-lpython1.6" - break - fi - if test -r $i/libpython1.5.a; then - AC_MSG_RESULT($i) - PYLIB="$i" - PYINCLUDE="$PYINCLUDE -I$i" - PYLINK="-lpython1.5" - break - fi - if test -r $i/libPython.a; then - AC_MSG_RESULT($i) - PYLIB="$i" - PYINCLUDE="$PYINCLUDE -I$i" - break - fi -done -if test -z "$PYLIB"; then - AC_MSG_RESULT(not found) - PYLIB="/usr/local/lib/python/lib" - PYINCLUDE="$PYINCLUDE -I$PYLIB" -fi AC_SUBST(PYINCLUDE) AC_SUBST(PYLIB) AC_SUBST(PYLINK) +AC_SUBST(PYTHONDYNAMICLINKING) #---------------------------------------------------------------- # Look for Perl5 @@ -450,10 +578,12 @@ AC_ARG_WITH(perl5,[ --with-perl5=path Set location of Perl5 executable],[ # First figure out what the name of Perl5 is if test -z "$PERLBIN"; then -AC_CHECK_PROGS(PERL, perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl) +AC_CHECK_PROGS(PERL, perl perl5.6.1 perl5.6.0 perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl) else PERL="$PERLBIN" fi + + AC_MSG_CHECKING(for Perl5 header files) if test -n "$PERL"; then PERL5DIR=`($PERL -e 'use Config; print $Config{archlib};') 2>/dev/null` @@ -471,16 +601,37 @@ if test -n "$PERL"; then PERL5EXT="$PERL5DIR/CORE" AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT) fi + + AC_MSG_CHECKING(for Perl5 library) + PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; print $_') 2>/dev/null` + if test "$PERL5LIB" = "" ; then + AC_MSG_RESULT(not found) + else + AC_MSG_RESULT($PERL5LIB) + fi else AC_MSG_RESULT(unable to determine perl5 configuration) PERL5EXT=$PERL5DIR fi - else +else AC_MSG_RESULT(could not figure out how to run perl5) - PERL5EXT="/usr/local/lib/perl/archname/5.003/CORE" - fi +# PERL5EXT="/usr/local/lib/perl/archname/5.003/CORE" +fi + +# Only Cygwin (Windows) needs the library for dynamic linking +case $ac_sys_system/$ac_sys_release in +CYGWIN*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";; +*)PERL5DYNAMICLINKING="";; +esac AC_SUBST(PERL5EXT) +AC_SUBST(PERL5DYNAMICLINKING) +AC_SUBST(PERL5LIB) + +# kludges to ease naming conventions conformance. +( cd Examples ; + test -d perl || ln -s perl5 perl ; + test -d test-suite/perl || ( cd test-suite && ln -s perl5 perl ) ) #---------------------------------------------------------------- # Look for java @@ -505,7 +656,13 @@ AC_MSG_CHECKING(for java include file jni.h) AC_ARG_WITH(javaincl, [ --with-javaincl=path Set location of Java include directory], [JAVAINCDIR="$withval"], [JAVAINCDIR=]) if test -z "$JAVAINCDIR"; then - JAVAINCDIR="/usr/jdk*/include /usr/local/jdk*/include /opt/jdk*/include /usr/java/include /usr/local/java/include /opt/java/include /usr/include/java /usr/local/include/java /usr/include/kaffe /usr/local/include/kaffe /usr/include /usr/local/include" + JAVAINCDIR="/usr/j2sdk*/include /usr/local/j2sdk*/include /usr/jdk*/include /usr/local/jdk*/include /opt/j2sdk*/include /opt/jdk*/include /usr/java/include /usr/local/java/include /opt/java/include /usr/include/java /usr/local/include/java /usr/include/kaffe /usr/local/include/kaffe /usr/include /usr/local/include" + + # Add in default installation directory on Windows for Cygwin + case $ac_sys_system/$ac_sys_release in + CYGWIN*) JAVAINCDIR="c:/j2sdk*/include d:/j2sdk*/include c:/jdk*/include d:/jdk*/include $JAVAINCDIR";; + *);; + esac fi JAVAINC="" @@ -533,9 +690,29 @@ else fi fi +# java.exe on Cygwin requires the Windows standard (Pascal) calling convention as it is a normal Windows executable and not a Cygwin built executable +case $ac_sys_system/$ac_sys_release in +CYGWIN*) + if test "$GCC" = yes; then + JAVADYNAMICLINKING=" -Wl,--add-stdcall-alias" + else + JAVADYNAMICLINKING="" + fi ;; +*)JAVADYNAMICLINKING="";; +esac + +# Java on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls +case $ac_sys_system/$ac_sys_release in +CYGWIN*) JAVALIBRARYPREFIX="";; +*)JAVALIBRARYPREFIX="lib";; +esac + + AC_SUBST(JAVA) AC_SUBST(JAVAC) AC_SUBST(JAVAINC) +AC_SUBST(JAVADYNAMICLINKING) +AC_SUBST(JAVALIBRARYPREFIX) AC_SUBST(ROOT_DIR)ROOT_DIR=`pwd` @@ -583,7 +760,7 @@ if test -n "$GUILE_CONFIG" ; then fi done if test -z "$GUILEINCLUDE"; then - GUILEINCLUDE="-I/usr/local/include" +# GUILEINCLUDE="-I/usr/local/include" AC_MSG_RESULT(not found) fi @@ -598,7 +775,7 @@ if test -n "$GUILE_CONFIG" ; then done if test -z "$GUILELIB"; then AC_MSG_RESULT(not found) - GUILELIB="/usr/local/lib" +# GUILELIB="/usr/local/lib" fi GUILELINK="`guile-config link`" @@ -626,10 +803,11 @@ AC_ARG_WITH(ruby,[ --with-ruby=path Set location of Ruby executable],[ R # First figure out what the name of Ruby is if test -z "$RUBYBIN"; then -AC_CHECK_PROGS(RUBY, ruby) + AC_CHECK_PROGS(RUBY, ruby) else -RUBY="$RUBYBIN" + RUBY="$RUBYBIN" fi + AC_MSG_CHECKING(for Ruby header files) if test -n "$RUBY"; then RUBYDIR=`($RUBY -rmkmf -e 'print Config::CONFIG[["archdir"]] || $archdir') 2>/dev/null` @@ -648,68 +826,227 @@ if test -n "$RUBY"; then AC_MSG_RESULT(could not locate ruby.h...using $RUBYINCLUDE) fi + # Find library and path for linking. Use libruby.a except on Cygwin use the DLL. AC_MSG_CHECKING(for Ruby library) - RUBYLIB=none - for i in $dirs; do - if test -r $i/libruby.a; then - AC_MSG_RESULT($i) - RUBYLIB="$i" - break; - fi - done - if test "$RUBYLIB" = none; then + RUBYLIB="" + case $ac_sys_system/$ac_sys_release in + CYGWIN*) + rb_libdir=`($RUBY -rrbconfig -e 'print Config::CONFIG[["libdir"]]') 2>/dev/null` + rb_bindir=`($RUBY -rrbconfig -e 'print Config::CONFIG[["bindir"]]') 2>/dev/null` + dirs="$dirs $rb_libdir $rb_bindir" + rb_libruby=`($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBRUBY_SO"]]') 2>/dev/null` + RUBYLINK=`($RUBY -rrbconfig -e 'print Config::CONFIG[["RUBY_SO_NAME"]]') 2>/dev/null` + ;; + *) + rb_libruby=`($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBRUBY_A"]]') 2>/dev/null` + RUBYLINK=`($RUBY -rrbconfig -e 'print Config::CONFIG[["RUBY_INSTALL_NAME"]]') 2>/dev/null` + ;; + esac + if test "$rb_libruby" != ""; then + for i in $dirs; do + if (test -r $i/$rb_libruby;) then + RUBYLIB="$i" + break; + fi + done + fi + if test "$RUBYLIB" = ""; then RUBYLIB="$RUBYDIR" - AC_MSG_RESULT(could not locate libruby.a...using $RUBYLIB) + AC_MSG_RESULT(not found... using $RUBYDIR) + else + AC_MSG_RESULT($RUBYLINK in $RUBYLIB) fi else AC_MSG_RESULT(unable to determine ruby configuration) RUBYINCLUDE="-I$RUBYDIR" RUBYLIB="$RUBYDIR" fi - RUBYLINK=`($RUBY -rrbconfig -e 'print Config::CONFIG[["RUBY_INSTALL_NAME"]]') 2>/dev/null` - RUBYLINK="-l$RUBYLINK" - RUBYLINK="$RUBYLINK `($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBS"]]') 2>/dev/null`" + RUBYLINK="-l$RUBYLINK `($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBS"]]') 2>/dev/null`" + RUBYCCDLFLAGS=`($RUBY -rrbconfig -e 'print Config::CONFIG[["CCDLFLAGS"]]') 2>/dev/null` else - AC_MSG_RESULT(could not figure out how to run ruby) + AC_MSG_RESULT(could not figure out how to run ruby) RUBYINCLUDE="-I/usr/local/lib/ruby/1.4/arch" - RUBYLIB="-I/usr/local/lib/ruby/1.4/arch" + RUBYLIB="/usr/local/lib/ruby/1.4/arch" RUBYLINK="-lruby -lm" fi +case $ac_sys_system/$ac_sys_release in +CYGWIN*) RUBYDYNAMICLINKING="-L$RUBYLIB $RUBYLINK";; +*) RUBYDYNAMICLINKING="";; +esac + + AC_SUBST(RUBYINCLUDE) AC_SUBST(RUBYLIB) AC_SUBST(RUBYLINK) +AC_SUBST(RUBYCCDLFLAGS) +AC_SUBST(RUBYDYNAMICLINKING) +#------------------------------------------------------------------------- +# Look for Php4 +#------------------------------------------------------------------------- + +PHP4BIN= + +AC_ARG_WITH(php4,[ --with-php4=path Set location of PHP4 executable],[ PHP4BIN="$withval"], [PHP4BIN=]) + +if test -z "$PHP4BIN"; then +AC_CHECK_PROGS(PHP4, php, php4) +else +PHP4="$PHP4BIN" +fi + +AC_SUBST(PHP4) + +AC_MSG_CHECKING(for PHP4 header files) +dirs="/usr/include/php /usr/local/include/php /usr/local/apache/php" +for i in $dirs; do + if test -r $i/php_config.h -o -r $i/php_version.h; then + AC_MSG_RESULT($i) + PHP4EXT="$i" + PHP4INC="-I$PHP4EXT -I$PHP4EXT/Zend -I$PHP4EXT/main -I$PHP4EXT/TSRM" + break; + fi +done +if test -z "$PHP4INC"; then + AC_MSG_RESULT(not found) +fi + +AC_SUBST(PHP4INC) + +# kludges to ease naming conventions conformance. +( cd Examples/GIFPlot ; test -d Php4 || ln -s Php Php4 ) +( cd Examples/php4 ; for dir in `sed '/^#/d' check.list` ; do + test -f $dir/Makefile || ( cd $dir ; ln -s ../Makefile.php Makefile ) + done ) + +#---------------------------------------------------------------- +# Detect ocaml +#---------------------------------------------------------------- + +AC_ARG_WITH(ocaml,[ --with-ocaml=path Set location of ocaml executable],[ OCAMLBIN="$withval"], [OCAMLBIN=]) +AC_ARG_WITH(ocamlc,[ --with-ocamlc=path Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=]) + +AC_MSG_CHECKING(for Ocaml compiler) +if test -z "$OCAMLC"; then +AC_CHECK_PROGS(OCAMLC, ocamlc, ocamlc) +else +OCAMLC="$OCAMLC" +fi + +AC_MSG_CHECKING(for Ocaml interpreter) +if test -z "$OCAMLBIN"; then +AC_CHECK_PROGS(OCAMLBIN, ocaml, ocaml) +else +OCAMLBIN="$OCAMLBIN" +fi +AC_MSG_CHECKING(for Ocaml header files) +dirs="/usr/lib/ocaml/caml /usr/local/lib/ocaml/caml" +for i in $dirs; do + if test -r $i/mlvalues.h; then + AC_MSG_RESULT($i) + OCAMLEXT="$i" + OCAMLINC="-I$OCAMLEXT" + break; + fi +done +if test -z "$OCAMLINC"; then + AC_MSG_RESULT(not found) +fi + +export OCAMLINC +export OCAMLBIN +export OCAMLC + +AC_SUBST(OCAMLINC) +AC_SUBST(OCAMLBIN) +AC_SUBST(OCAMLC) + +#---------------------------------------------------------------- +# Look for Pike +#---------------------------------------------------------------- + +# Identify the name of the Pike executable +PIKEBIN= +AC_ARG_WITH(pike,[ --with-pike=path Set location of Pike executable],[ PIKEBIN="$withval"], [PIKEBIN=]) +if test -z "$PIKEBIN"; then + AC_CHECK_PROGS(PIKE, pike) +else + PIKE="$PIKEBIN" +fi + +# Check for a --with-pikeincl option to configure +PIKEINCLUDE= +AC_ARG_WITH(pikeincl,[ --with-pikeincl=path Set location of Pike include directory],[ + PIKEINCLUDE="-I$withval"], [PIKEINCLUDE=]) + +AC_MSG_CHECKING(for Pike header files) +if test -z "$PIKEINCLUDE"; then +if test -n "$PIKE"; then + PIKEPATH=`which $PIKE` + PIKEINCLUDE=`$PIKE Tools/check-include-path.pike $PIKEPATH` + AC_MSG_RESULT($PIKEINCLUDE) + PIKEINCLUDE="-I$PIKEINCLUDE" +fi +if test -z "$PIKEINCLUDE"; then + AC_MSG_RESULT(not found) +fi +else + AC_MSG_RESULT($PIKEINCLUDE) +fi + +AC_SUBST(PIKEINCLUDE) +AC_SUBST(PIKECCDLFLAGS) +AC_SUBST(PIKEDYNAMICLINKING) #---------------------------------------------------------------- # Miscellaneous #---------------------------------------------------------------- -# These commands are only intended for use in a development environment. +# Configure SWIG_LIB path + +AC_ARG_WITH(swiglibdir,[ --with-swiglibdir=DIR Put SWIG system-independent libraries into DIR.], + [swig_lib="$withval"], [swig_lib="\$(prefix)/lib/swig1.3"]) +AC_SUBST(swig_lib) + +# Configure RELEASESUFFIX (for setups having both SWIG 1.1 and 1.3 on a system...) + +AC_ARG_WITH(release-suffix, + [ --with-release-suffix=SUFFIX Attach SUFFIX to the binary and the runtime libs. ], + [release_suffix="$withval"], [release_suffix=""]) +AC_SUBST(release_suffix) + +########## +# The commands below are only intended for use in a development environment. # When one makes a fresh CVS checkout, no 'configure' scripts exist. This # Makes the CONFIG_SUBDIRS macro fail below. To fix this, one needs to # generate the configure script by calling autoconf manually. This is # not an issue in non-CVS releases--the mkdist.py script creates all # of the configure scripts before making a tar-ball. -- beazley 2000/03/01 -if test ! -r $srcdir/Source/DOH/configure; then - (cd $srcdir/Source/DOH ; autoconf) -fi +# All these have been commented out as it turned out that the mkdist.py +# script was not creating all of the configure files in subdirectories. +# This required autoconf to be installed on user's machines when installing +# SWIG - not a good requirement. Developers should run the autogen.sh instead. +# Do not uncomment else the same problem may arise again. - William Fulton 2001/08/03. -#if test -d $srcdir/Source/SWILL/SWILL; then -# if test ! -r $srcdir/Source/SWILL/configure; then -# (cd $srcdir/Source/SWILL ; autoconf) -# fi +#if test ! -r $srcdir/Source/DOH/configure; then +# (cd $srcdir/Source/DOH ; autoconf) #fi -if test ! -r $srcdir/Tools/configure ; then - (cd $srcdir/Tools ; autoconf) -fi +#if test ! -r $srcdir/Tools/configure ; then +# (cd $srcdir/Tools ; autoconf) +#fi + +#if test ! -r $srcdir/Examples/GIFPlot/configure ; then +# (cd $srcdir/Examples/GIFPlot ; autoconf) +#fi # #AC_OUTPUT_COMMANDS(test -f Examples/install-sh || cp install-sh Examples) # DB: Maybe I'm missings something, but why is it necessary to put # an 'install-sh' script in the Examples directory? +########### AC_CONFIG_SUBDIRS(Source/DOH Tools) @@ -720,15 +1057,13 @@ test -d Source || mkdir Source dnl We use the following in `AC_OUTPUT' and "make distclean". configure_substituted_files=`echo \ Examples/Makefile \ - Examples/C++/test_conf.py \ Examples/guile/Makefile \ - Examples/xml/Makefile \ + Examples/GIFPlot/Makefile \ + Examples/GIFPlot/Lib/Makefile \ Makefile \ Runtime/Makefile \ - Source/Include/swigconfig.h \ Source/Include/swigver.h \ - Source/LParse/Makefile \ - Source/Modules/Makefile \ + Source/CParse/Makefile \ Source/Modules1.1/Makefile \ Source/Preprocessor/Makefile \ Source/Swig/Makefile \ diff --git a/debian/.cvsignore b/debian/.cvsignore new file mode 100644 index 000000000..62abe9f21 --- /dev/null +++ b/debian/.cvsignore @@ -0,0 +1 @@ +*.debhelper diff --git a/debian/README b/debian/README new file mode 100644 index 000000000..9cbe96a3c --- /dev/null +++ b/debian/README @@ -0,0 +1,20 @@ +The Debian Package swig1.3 +-------------------------- + +This is SWIG 1.3 (Simplified Wrapper and Interface Generator) +packaged for Debian GNU/Linux. + +SWIG 1.3 is not fully compatible with SWIG 1.1. It is a re-development +effort of SWIG 1.1 (which was written in C++) in ANSI C. The 1.3 +series is in "alpha" state. Release 1.3a5 was rather stable, and it +should be used for new projects rather than the ancient release +1.1p5. See the file `NEW' for information on the new features of the +1.3 series. + +This Debian package derives from the release 1.3a5 and corresponds to +the "mkoeppe-1-3-a5-patches" branch of the SWIG CVS repository. It +fixes several bugs and enhances several language backends. See the +top of the file `CHANGES' for details. + + +Matthias Koeppe , Mon, 28 May 2001 15:08:55 +0200 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..0caee090a --- /dev/null +++ b/debian/changelog @@ -0,0 +1,60 @@ +swig1.3 (1.3.a5+patches-9) unstable; urgency=low + + * New upstream version + + -- Matthias Koeppe Wed, 6 Jun 2001 16:11:41 +0200 + +swig1.3 (1.3.a5+patches-8) unstable; urgency=low + + * New upstream version + + -- Matthias Koeppe Wed, 6 Jun 2001 14:06:51 +0200 + +swig1.3 (1.3.a5+patches-7) unstable; urgency=low + + * New upstream version + + -- Matthias Koeppe Wed, 6 Jun 2001 13:34:44 +0200 + +swig1.3 (1.3.a5+patches-6) unstable; urgency=low + + * New upstream version + + -- Matthias Koeppe Tue, 5 Jun 2001 14:11:52 +0200 + +swig1.3 (1.3.a5+patches-5) unstable; urgency=low + + * New upstream version. + + -- Matthias Koeppe Fri, 1 Jun 2001 18:48:59 +0200 + +swig1.3 (1.3.a5+patches-4) unstable; urgency=low + + * Fix hard-coded location of swig library. Added build-dependency on + tcl-dev. + + -- Matthias Koeppe Fri, 1 Jun 2001 13:32:34 +0200 + +swig1.3 (1.3.a5+patches-3) unstable; urgency=low + + * New upstream version + + -- Matthias Koeppe Thu, 31 May 2001 13:15:20 +0200 + +swig1.3 (1.3.a5+patches-2) unstable; urgency=low + + * Binary and manpage now include version number, to improve + cooperation with the "swig" package. + + -- Matthias Koeppe Tue, 29 May 2001 15:15:07 +0200 + +swig1.3 (1.3.a5+patches-1) unstable; urgency=low + + * First release. + + -- Matthias Koeppe Sat, 20 Nov 1999 01:09:11 +0100 + +Local variables: +mode: debian-changelog +add-log-mailing-address: "mkoeppe@mail.math.uni-magdeburg.de" +End: \ No newline at end of file diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..80e0a7017 --- /dev/null +++ b/debian/control @@ -0,0 +1,18 @@ +Source: swig1.3 +Section: interpreters +Priority: optional +Maintainer: Matthias Koeppe +Build-Depends: debhelper (>> 3.0.0), libguile-dev, python-dev, perl, + ruby-dev, ruby, tcl8.0-dev +Standards-Version: 3.5.2 + +Package: swig1.3 +Architecture: any +Depends: ${shlibs:Depends} +Description: Generate scripting interfaces to C/C++ code + SWIG (Simplified Wrapper and Interface Generator) is a system for + automatically generating wrapper/glue code for several languages + (Tcl, Python, Perl, Ruby, MzScheme, Guile, Java) from annotated C or + C++ header files. + This package represents some point in the SWIG 1.3 development + series. It is not fully compatible with the SWIG 1.1 release. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..8cb86922e --- /dev/null +++ b/debian/copyright @@ -0,0 +1,83 @@ +This is SWIG, written and maintained by: + + Dave Beazley (beazley@cs.uchicago.edu) (SWIG core) + Loic Dachary (loic@ceic.com) (Perl5) + Harco de Hilster (Harco.de.Hilster@ATComputing.nl) (Java) + Thien-Thi Nguyen (ttn@glug.org) (Testing/Misc) + Masaki Fukushima (fukusima@goto.info.waseda.ac.jp) (Ruby) + Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile/MzScheme) + +Past contributors: + + Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran Kovuk, Gary Holt, + David Fletcher, Oleg Tolmatcev. + +SWIG can be obtained by anonymous CVS: + + cvs -d :pserver:cvs@swig.cs.uchicago.edu:/cvsroot co SWIG + +SWIG is distributed under the following terms: + +I. + +Copyright (C) 1998-2000 +The University of Chicago + +Permission is hereby granted, without written agreement and without +license or royalty fees, to use, copy, modify, and distribute this +software and its documentation for any purpose, provided that +(1) The above copyright notice and the following two paragraphs +appear in all copies of the source code and (2) redistributions +including binaries reproduces these notices in the supporting +documentation. Substantial modifications to this software may be +copyrighted by their authors and need not follow the licensing terms +described here, provided that the new terms are clearly indicated in +all files where they apply. + +IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CHICAGO, OR +DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF +THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR +ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +THE AUTHOR AND THE UNIVERSITY OF CHICAGO SPECIFICALLY DISCLAIM ANY +WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE +PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND +DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, +UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + +II. + +Copyright (c) 1995-1998 +The University of Utah and the Regents of the University of California +All Rights Reserved + +Permission is hereby granted, without written agreement and without +license or royalty fees, to use, copy, modify, and distribute this +software and its documentation for any purpose, provided that +(1) The above copyright notice and the following two paragraphs +appear in all copies of the source code and (2) redistributions +including binaries reproduces these notices in the supporting +documentation. Substantial modifications to this software may be +copyrighted by their authors and need not follow the licensing terms +described here, provided that the new terms are clearly indicated in +all files where they apply. + +IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE +UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY +PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + +THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH +SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, +SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 000000000..45b1a7422 --- /dev/null +++ b/debian/dirs @@ -0,0 +1,4 @@ +usr/bin +usr/lib +usr/share/swig1.3 +usr/share/doc/swig1.3 diff --git a/debian/docs b/debian/docs new file mode 100644 index 000000000..b6059c0f6 --- /dev/null +++ b/debian/docs @@ -0,0 +1,10 @@ +README +TODO +ANNOUNCE +CHANGES +NEW +Doc/engineering.html +Doc/index.html +Doc/internals.html +Doc/migrate.txt +Doc/whitepaper.html diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 000000000..164b5ff1a --- /dev/null +++ b/debian/postinst @@ -0,0 +1,45 @@ +#! /bin/sh +# postinst script for swig1.3 +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..b4df2d096 --- /dev/null +++ b/debian/rules @@ -0,0 +1,76 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +# This is the debhelper compatability version to use. +export DH_COMPAT=3 + +configure: configure-stamp +configure-stamp: + dh_testdir + ./autogen.sh + ./configure --prefix=/usr --mandir=/usr/share/man --with-swiglibdir=/usr/share/swig1.3 --with-release-suffix=-1.3 + touch configure-stamp + +build: configure-stamp build-stamp +build-stamp: + dh_testdir + $(MAKE) + $(MAKE) runtime + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + -$(MAKE) clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + $(MAKE) install DESTDIR=$(CURDIR)/debian/swig1.3 + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit +# dh_installcron + dh_installman + dh_installinfo + dh_undocumented swig-1.3.1 + dh_installchangelogs CHANGES + dh_link + dh_strip + dh_compress + dh_fixperms + dh_makeshlibs + dh_installdeb +# dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/debian/substvars b/debian/substvars new file mode 100644 index 000000000..c9df68ba1 --- /dev/null +++ b/debian/substvars @@ -0,0 +1 @@ +shlibs:Depends=libc6 (>= 2.2.3-1), libstdc++2.10-glibc2.2 diff --git a/swig.spec.in b/swig.spec.in new file mode 100644 index 000000000..ee79c96dd --- /dev/null +++ b/swig.spec.in @@ -0,0 +1,78 @@ +# You can make the package from CVS by something like: +# tar -cvzf swig-1.3.11cvs.tar.gz SWIG-1.3.11cvs && rpm -tb swig-1.3.11cvs.tar.gz +# @configure_input@ + +%define ver @SWIG_MAJOR_VERSION@.@SWIG_MINOR_VERSION@.@SWIG_SPIN@ +%define rel 1 +%define prefix /usr +%define home_page http://swig.sourceforge.net/ +%define docprefix %{prefix}/share + +###################################################################### +# Usually, nothing needs to be changed below here between releases +###################################################################### +Summary: Simplified Wrapper and Interface Generator +Name: swig +Version: %{ver} +Release: %{rel} +URL: %{home_page} +Source0: %{name}-%{version}.tar.gz +License: BSD +Group: Development/Tools +BuildRoot: %{_tmppath}/%{name}-root + +%description +SWIG is an interface compiler that connects programs written in C, +C++, and Objective-C with scripting languages including Perl, Python, +and Tcl/Tk. It works by taking the declarations commonly found in +C/C++ header files and using them to generate the glue code (wrappers) +that scripting languages need to access the underlying C/C++ code + +%package runtime +Summary: Runtime libraries required for dynamically loading swig-generated modules +Group: Development/Libraries + +%description runtime +The swig-runtime package contains shared libraries used to share type +information between swig-generated modules loaded into the same application. +Dynamically loading swig-generated modules should use the swig-runtime libs. + +%prep +%setup -q -n SWIG-%{version} + +%build +# so we can build package from cvs source too +[ ! -r configure ] && ./autogen.sh +%configure +make +make runtime + +%install +rm -rf ${RPM_BUILD_ROOT} +# Why is exec_prefix not used in BIN_DIR in Makefile? +%makeinstall prefix=${RPM_BUILD_ROOT}%prefix BIN_DIR=${RPM_BUILD_ROOT}%{_exec_prefix}/bin + +DIR=${RPM_BUILD_ROOT} +find $DIR -type f | sed -e "s#^${RPM_BUILD_ROOT}##g" > %{name}.files + +%clean +rm -rf ${RPM_BUILD_ROOT} + +%files +# -f %{name}.files +/usr/bin/* +/usr/lib/swig* +#%doc /usr/share/doc/swig* +#/usr/share/doc/swig* +%defattr(-,root,root) + +%files runtime +/usr/lib/lib* + +%changelog +* Wed Jul 24 2002 Sam Liddicott +- Added runtime package of runtime libs +* Mon Sep 10 2001 Tony Seward +- Merge Red Hat's and Dustin Mitchell's .spec files. +- Install all of the examples in the documantation directory. +- Auto create the list of installed files. diff --git a/vms/aaareadme.txt b/vms/aaareadme.txt new file mode 100644 index 000000000..52746a7e7 --- /dev/null +++ b/vms/aaareadme.txt @@ -0,0 +1,18 @@ +Port on OpenVMS 7.3 using CC 6.5 and CXX 6.5 + + +Building procedure: +$ @logicals +$ @build_all + +the logicals swig_root is defined by the procedure logicals.com. +The logicals.com procedure can be invoke with an optional argument +for the define command, for example: +$ @logicals "/system/exec" + + +genbuild.py is the python program use to generate all the procedures in the +[vms.scripts] directory. + + +jf.pieronne@laposte.net diff --git a/vms/build_end.com b/vms/build_end.com new file mode 100644 index 000000000..103302270 --- /dev/null +++ b/vms/build_end.com @@ -0,0 +1,21 @@ +$ set def swig_root:[vms] +$ +$ file = f$search("swig_root:[vms.o_alpha]*.obj") +$ newobj = 0 +$ if file .nes. "" +$ then +$ v = f$verify(1) +$ library/replace swig_root:[vms.o_alpha]swig.olb swig_root:[vms.o_alpha]*.obj +$ delete swig_root:[vms.o_alpha]*.obj;* +$ v = f$verify(v) +$ newobj = 1 +$ endif +$ file = f$search("swig_root:[vms]swig.exe") +$ if file .eqs. "" .or. newobj +$ then +$ v = f$verify(1) +$ cxxlink/exe=swig_root:[vms]swig.exe - + /repo=swig_root:[source.modules1_1.cxx_repository] - + swig_root:[vms.o_alpha]swig.olb/include=swigmain +$ v = f$verify(v) +$ endif diff --git a/vms/build_init.com b/vms/build_init.com new file mode 100644 index 000000000..9a1992dc4 --- /dev/null +++ b/vms/build_init.com @@ -0,0 +1,13 @@ +$ set def swig_root:[vms] +$ +$ swiglib = "swig_root:[vms.o_alpha]swig.olb +$ +$ if (f$search("swig_root:[vms]o_alpha.dir") .eqs. "") then $ - + create/dir swig_root:[vms.o_alpha] +$ +$ copy swigconfig.h [-.source.include] +$ copy swigver.h [-.source.include] +$ +$ if (f$search("''swiglib'") .eqs. "") then $ - + library/create/object 'swiglib' +$ diff --git a/vms/build_swig.com b/vms/build_swig.com new file mode 100644 index 000000000..5570db0bc --- /dev/null +++ b/vms/build_swig.com @@ -0,0 +1 @@ +$ @swig_root:[vms.scripts]build_all diff --git a/vms/genbuild.py b/vms/genbuild.py new file mode 100644 index 000000000..df18ce3ed --- /dev/null +++ b/vms/genbuild.py @@ -0,0 +1,155 @@ +import os.path, string, posix, pyvms +# +# + +IDIR = ['swig_root:[source.swig]', 'swig_root:[source.doh.include]', + 'swig_root:[source.include]', 'swig_root:[source.preprocessor]'] + +def new_file(fg, dirname): + global IDIR + fn = 'swig_root:[vms.scripts]compil_' + os.path.basename(dirname) + '.com' + print >> fg, '$ @' + fn + f = open(fn, 'w') + print >> f, '$!' + print >> f, '$! Generated by genbuild.py' + print >> f, '$!' + print >> f, '$ libname = "swig_root:[vms.o_alpha]swig.olb"' + print >> f, '$' + print >> f, '$ set default', pyvms.crtl_to_vms(dirname)[0][0] + print >> f, '$' + print >> f, "$ idir := ", IDIR[0] + for i in range(1, len(IDIR)): + print >> f, '$ idir = idir + ",' + IDIR[i] + '"' + print >> f, '$' + print >> f, "$ iflags = \"/include=(''idir', sys$disk:[])\"" + print >> f, '$ oflags = \"/object=swig_root:[vms.o_alpha]' + print >> f, "$ cflags = \"''oflags'''iflags'''dflags'\"" + print >> f, "$ cxxflags = \"''oflags'''iflags'''dflags'\"" + print >> f, '$' + return f + + +def end_file(f): + print >>f,"""$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 = Source file +$! P4 - P8 What it depends on +$ +$ modname = f$parse(p3,,,"name") +$ set noon +$ set message/nofacility/noident/noseverity/notext +$ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' +$ set message/facility/ident/severity/text +$ on error then exit +$ open/read swigtmp swig_root:[vms]swiglib.tmp +$! skip header +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$! +$ +$ read/end=module_not_found swigtmp r +$ modfound = 1 +$ Time = f$cvtime(f$extract(49, 20, r)) +$ goto end_search_module +$ module_not_found: +$ modfound = 0 +$ +$ end_search_module: +$ close swigtmp +$ delete swig_root:[vms]swiglib.tmp;* +$ +$ if modfound .eq. 0 then $ goto Makeit +$ +$! Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(1) +$ 'P2' 'P3' +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE""" + + +def listRep(args, dirname, filenames): + fg = args[0] + first = 1 + for fn in filenames: + if fn[-2:] == '.c': + if first: + first = 0 + fc = new_file(fg, dirname) + + cstr = "\"cc ''cflags'\" " + line = "$ call make swig_root:[vms.o_alpha]" + line += fn[:-1] + 'obj -' + print >> fc, line + line = "\t" + cstr + fn + print >> fc, line + elif fn[-4:] == '.cxx': + if first: + first = 0 + fc = new_file(fg, dirname) + + cstr = "\"cxx ''cxxflags'\" " + line = "$ call make swig_root:[vms.o_alpha]" + line += fn[:-3] + 'obj -' + print >> fc, line + line = "\t" + cstr + fn + print >> fc, line + if first == 0: + end_file(fc) + fc.close() +# +def genbuild(f, dir): + os.path.walk(dir, listRep, (f,)) + cmd = 'set default swig_root:[vms]' +# +f = open('swig_root:[vms.scripts]build_all.com','w') +print >> f, '$!' +print >> f, '$! Generated by genbuild.py' +print >> f, '$!' +print >> f, '$ set default swig_root:[vms]' +print >> f, '$' +print >> f, '$ @swig_root:[vms]build_init' +# +genbuild(f, '/swig_root/source') +print >> f, '$' +print >> f, '$ set default swig_root:[vms]' +print >> f, '$' +print >> f, '$ @swig_root:[vms]build_end' +f.close diff --git a/vms/logicals.com b/vms/logicals.com new file mode 100644 index 000000000..20da9d49a --- /dev/null +++ b/vms/logicals.com @@ -0,0 +1,18 @@ +$! +$! +$! +$ proc = f$environment("PROCEDURE") +$ proc = f$parse(proc,"sys$disk:[]",,,"NO_CONCEAL") +$ cur_dev = f$parse(proc,,,"DEVICE","SYNTAX_ONLY") +$ cur_dir = f$parse(proc,,,"DIRECTORY","SYNTAX_ONLY") +$ cur_dir = f$extract(1,f$length(cur_dir)-2,cur_dir) +$ cur_dir = cur_dir - "[" +$ cur_dir = cur_dir - "]" +$ cur_dir = cur_dir - "<" +$ cur_dir = cur_dir - ">" +$ +$! remove trealing .VMS +$ root_dir = f$extract(0,f$length(cur_dir)-4,cur_dir) +$ +$ define 'p1' /trans=concealed swig_root 'cur_dev'['root_dir'.] + diff --git a/vms/scripts/build_all.com b/vms/scripts/build_all.com new file mode 100644 index 000000000..d41198348 --- /dev/null +++ b/vms/scripts/build_all.com @@ -0,0 +1,15 @@ +$! +$! Generated by genbuild.py +$! +$ set default swig_root:[vms] +$ +$ @swig_root:[vms]build_init +$ @swig_root:[vms.scripts]compil_cparse.com +$ @swig_root:[vms.scripts]compil_doh.com +$ @swig_root:[vms.scripts]compil_modules1_1.com +$ @swig_root:[vms.scripts]compil_preprocessor.com +$ @swig_root:[vms.scripts]compil_swig.com +$ +$ set default swig_root:[vms] +$ +$ @swig_root:[vms]build_end diff --git a/vms/scripts/compil_cparse.com b/vms/scripts/compil_cparse.com new file mode 100644 index 000000000..4f78f4104 --- /dev/null +++ b/vms/scripts/compil_cparse.com @@ -0,0 +1,98 @@ +$! +$! Generated by genbuild.py +$! +$ libname = "swig_root:[vms.o_alpha]swig.olb" +$ +$ set default SWIG_ROOT:[SOURCE.CPARSE] +$ +$ idir := swig_root:[source.swig] +$ idir = idir + ",swig_root:[source.doh.include]" +$ idir = idir + ",swig_root:[source.include]" +$ idir = idir + ",swig_root:[source.preprocessor]" +$ +$ iflags = "/include=(''idir', sys$disk:[])" +$ oflags = "/object=swig_root:[vms.o_alpha] +$ cflags = "''oflags'''iflags'''dflags'" +$ cxxflags = "''oflags'''iflags'''dflags'" +$ +$ call make swig_root:[vms.o_alpha]cscanner.obj - + "cc ''cflags'" cscanner.c +$ call make swig_root:[vms.o_alpha]parser.obj - + "cc ''cflags'" parser.c +$ call make swig_root:[vms.o_alpha]templ.obj - + "cc ''cflags'" templ.c +$ call make swig_root:[vms.o_alpha]util.obj - + "cc ''cflags'" util.c +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 = Source file +$! P4 - P8 What it depends on +$ +$ modname = f$parse(p3,,,"name") +$ set noon +$ set message/nofacility/noident/noseverity/notext +$ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' +$ set message/facility/ident/severity/text +$ on error then exit +$ open/read swigtmp swig_root:[vms]swiglib.tmp +$! skip header +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$! +$ +$ read/end=module_not_found swigtmp r +$ modfound = 1 +$ Time = f$cvtime(f$extract(49, 20, r)) +$ goto end_search_module +$ module_not_found: +$ modfound = 0 +$ +$ end_search_module: +$ close swigtmp +$ delete swig_root:[vms]swiglib.tmp;* +$ +$ if modfound .eq. 0 then $ goto Makeit +$ +$! Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(1) +$ 'P2' 'P3' +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/vms/scripts/compil_doh.com b/vms/scripts/compil_doh.com new file mode 100644 index 000000000..6d4ae89ad --- /dev/null +++ b/vms/scripts/compil_doh.com @@ -0,0 +1,106 @@ +$! +$! Generated by genbuild.py +$! +$ libname = "swig_root:[vms.o_alpha]swig.olb" +$ +$ set default SWIG_ROOT:[SOURCE.DOH.DOH] +$ +$ idir := swig_root:[source.swig] +$ idir = idir + ",swig_root:[source.doh.include]" +$ idir = idir + ",swig_root:[source.include]" +$ idir = idir + ",swig_root:[source.preprocessor]" +$ +$ iflags = "/include=(''idir', sys$disk:[])" +$ oflags = "/object=swig_root:[vms.o_alpha] +$ cflags = "''oflags'''iflags'''dflags'" +$ cxxflags = "''oflags'''iflags'''dflags'" +$ +$ call make swig_root:[vms.o_alpha]base.obj - + "cc ''cflags'" base.c +$ call make swig_root:[vms.o_alpha]file.obj - + "cc ''cflags'" file.c +$ call make swig_root:[vms.o_alpha]fio.obj - + "cc ''cflags'" fio.c +$ call make swig_root:[vms.o_alpha]hash.obj - + "cc ''cflags'" hash.c +$ call make swig_root:[vms.o_alpha]list.obj - + "cc ''cflags'" list.c +$ call make swig_root:[vms.o_alpha]memory.obj - + "cc ''cflags'" memory.c +$ call make swig_root:[vms.o_alpha]string.obj - + "cc ''cflags'" string.c +$ call make swig_root:[vms.o_alpha]void.obj - + "cc ''cflags'" void.c +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 = Source file +$! P4 - P8 What it depends on +$ +$ modname = f$parse(p3,,,"name") +$ set noon +$ set message/nofacility/noident/noseverity/notext +$ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' +$ set message/facility/ident/severity/text +$ on error then exit +$ open/read swigtmp swig_root:[vms]swiglib.tmp +$! skip header +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$! +$ +$ read/end=module_not_found swigtmp r +$ modfound = 1 +$ Time = f$cvtime(f$extract(49, 20, r)) +$ goto end_search_module +$ module_not_found: +$ modfound = 0 +$ +$ end_search_module: +$ close swigtmp +$ delete swig_root:[vms]swiglib.tmp;* +$ +$ if modfound .eq. 0 then $ goto Makeit +$ +$! Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(1) +$ 'P2' 'P3' +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/vms/scripts/compil_modules1_1.com b/vms/scripts/compil_modules1_1.com new file mode 100644 index 000000000..c570dfe58 --- /dev/null +++ b/vms/scripts/compil_modules1_1.com @@ -0,0 +1,132 @@ +$! +$! Generated by genbuild.py +$! +$ libname = "swig_root:[vms.o_alpha]swig.olb" +$ +$ set default SWIG_ROOT:[SOURCE.MODULES1_1] +$ +$ idir := swig_root:[source.swig] +$ idir = idir + ",swig_root:[source.doh.include]" +$ idir = idir + ",swig_root:[source.include]" +$ idir = idir + ",swig_root:[source.preprocessor]" +$ +$ iflags = "/include=(''idir', sys$disk:[])" +$ oflags = "/object=swig_root:[vms.o_alpha] +$ cflags = "''oflags'''iflags'''dflags'" +$ cxxflags = "''oflags'''iflags'''dflags'" +$ +$ call make swig_root:[vms.o_alpha]allocate.obj - + "cxx ''cxxflags'" allocate.cxx +$ call make swig_root:[vms.o_alpha]browser.obj - + "cxx ''cxxflags'" browser.cxx +$ call make swig_root:[vms.o_alpha]contract.obj - + "cxx ''cxxflags'" contract.cxx +$ call make swig_root:[vms.o_alpha]emit.obj - + "cxx ''cxxflags'" emit.cxx +$ call make swig_root:[vms.o_alpha]guile.obj - + "cxx ''cxxflags'" guile.cxx +$ call make swig_root:[vms.o_alpha]java.obj - + "cxx ''cxxflags'" java.cxx +$ call make swig_root:[vms.o_alpha]lang.obj - + "cxx ''cxxflags'" lang.cxx +$ call make swig_root:[vms.o_alpha]main.obj - + "cxx ''cxxflags'" main.cxx +$ call make swig_root:[vms.o_alpha]module.obj - + "cxx ''cxxflags'" module.cxx +$ call make swig_root:[vms.o_alpha]mzscheme.obj - + "cxx ''cxxflags'" mzscheme.cxx +$ call make swig_root:[vms.o_alpha]ocaml.obj - + "cxx ''cxxflags'" ocaml.cxx +$ call make swig_root:[vms.o_alpha]overload.obj - + "cxx ''cxxflags'" overload.cxx +$ call make swig_root:[vms.o_alpha]perl5.obj - + "cxx ''cxxflags'" perl5.cxx +$ call make swig_root:[vms.o_alpha]php4.obj - + "cxx ''cxxflags'" php4.cxx +$ call make swig_root:[vms.o_alpha]pike.obj - + "cxx ''cxxflags'" pike.cxx +$ call make swig_root:[vms.o_alpha]python.obj - + "cxx ''cxxflags'" python.cxx +$ call make swig_root:[vms.o_alpha]ruby.obj - + "cxx ''cxxflags'" ruby.cxx +$ call make swig_root:[vms.o_alpha]swigmain.obj - + "cxx ''cxxflags'" swigmain.cxx +$ call make swig_root:[vms.o_alpha]tcl8.obj - + "cxx ''cxxflags'" tcl8.cxx +$ call make swig_root:[vms.o_alpha]typepass.obj - + "cxx ''cxxflags'" typepass.cxx +$ call make swig_root:[vms.o_alpha]xml.obj - + "cxx ''cxxflags'" xml.cxx +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 = Source file +$! P4 - P8 What it depends on +$ +$ modname = f$parse(p3,,,"name") +$ set noon +$ set message/nofacility/noident/noseverity/notext +$ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' +$ set message/facility/ident/severity/text +$ on error then exit +$ open/read swigtmp swig_root:[vms]swiglib.tmp +$! skip header +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$! +$ +$ read/end=module_not_found swigtmp r +$ modfound = 1 +$ Time = f$cvtime(f$extract(49, 20, r)) +$ goto end_search_module +$ module_not_found: +$ modfound = 0 +$ +$ end_search_module: +$ close swigtmp +$ delete swig_root:[vms]swiglib.tmp;* +$ +$ if modfound .eq. 0 then $ goto Makeit +$ +$! Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(1) +$ 'P2' 'P3' +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/vms/scripts/compil_preprocessor.com b/vms/scripts/compil_preprocessor.com new file mode 100644 index 000000000..f95961e8d --- /dev/null +++ b/vms/scripts/compil_preprocessor.com @@ -0,0 +1,94 @@ +$! +$! Generated by genbuild.py +$! +$ libname = "swig_root:[vms.o_alpha]swig.olb" +$ +$ set default SWIG_ROOT:[SOURCE.PREPROCESSOR] +$ +$ idir := swig_root:[source.swig] +$ idir = idir + ",swig_root:[source.doh.include]" +$ idir = idir + ",swig_root:[source.include]" +$ idir = idir + ",swig_root:[source.preprocessor]" +$ +$ iflags = "/include=(''idir', sys$disk:[])" +$ oflags = "/object=swig_root:[vms.o_alpha] +$ cflags = "''oflags'''iflags'''dflags'" +$ cxxflags = "''oflags'''iflags'''dflags'" +$ +$ call make swig_root:[vms.o_alpha]cpp.obj - + "cc ''cflags'" cpp.c +$ call make swig_root:[vms.o_alpha]expr.obj - + "cc ''cflags'" expr.c +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 = Source file +$! P4 - P8 What it depends on +$ +$ modname = f$parse(p3,,,"name") +$ set noon +$ set message/nofacility/noident/noseverity/notext +$ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' +$ set message/facility/ident/severity/text +$ on error then exit +$ open/read swigtmp swig_root:[vms]swiglib.tmp +$! skip header +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$! +$ +$ read/end=module_not_found swigtmp r +$ modfound = 1 +$ Time = f$cvtime(f$extract(49, 20, r)) +$ goto end_search_module +$ module_not_found: +$ modfound = 0 +$ +$ end_search_module: +$ close swigtmp +$ delete swig_root:[vms]swiglib.tmp;* +$ +$ if modfound .eq. 0 then $ goto Makeit +$ +$! Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(1) +$ 'P2' 'P3' +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/vms/scripts/compil_swig.com b/vms/scripts/compil_swig.com new file mode 100644 index 000000000..103e275f4 --- /dev/null +++ b/vms/scripts/compil_swig.com @@ -0,0 +1,122 @@ +$! +$! Generated by genbuild.py +$! +$ libname = "swig_root:[vms.o_alpha]swig.olb" +$ +$ set default SWIG_ROOT:[SOURCE.SWIG] +$ +$ idir := swig_root:[source.swig] +$ idir = idir + ",swig_root:[source.doh.include]" +$ idir = idir + ",swig_root:[source.include]" +$ idir = idir + ",swig_root:[source.preprocessor]" +$ +$ iflags = "/include=(''idir', sys$disk:[])" +$ oflags = "/object=swig_root:[vms.o_alpha] +$ cflags = "''oflags'''iflags'''dflags'" +$ cxxflags = "''oflags'''iflags'''dflags'" +$ +$ call make swig_root:[vms.o_alpha]cwrap.obj - + "cc ''cflags'" cwrap.c +$ call make swig_root:[vms.o_alpha]error.obj - + "cc ''cflags'" error.c +$ call make swig_root:[vms.o_alpha]fragment.obj - + "cc ''cflags'" fragment.c +$ call make swig_root:[vms.o_alpha]getopt.obj - + "cc ''cflags'" getopt.c +$ call make swig_root:[vms.o_alpha]include.obj - + "cc ''cflags'" include.c +$ call make swig_root:[vms.o_alpha]misc.obj - + "cc ''cflags'" misc.c +$ call make swig_root:[vms.o_alpha]naming.obj - + "cc ''cflags'" naming.c +$ call make swig_root:[vms.o_alpha]parms.obj - + "cc ''cflags'" parms.c +$ call make swig_root:[vms.o_alpha]scanner.obj - + "cc ''cflags'" scanner.c +$ call make swig_root:[vms.o_alpha]stype.obj - + "cc ''cflags'" stype.c +$ call make swig_root:[vms.o_alpha]symbol.obj - + "cc ''cflags'" symbol.c +$ call make swig_root:[vms.o_alpha]tree.obj - + "cc ''cflags'" tree.c +$ call make swig_root:[vms.o_alpha]typemap.obj - + "cc ''cflags'" typemap.c +$ call make swig_root:[vms.o_alpha]typesys.obj - + "cc ''cflags'" typesys.c +$ call make swig_root:[vms.o_alpha]warn.obj - + "cc ''cflags'" warn.c +$ call make swig_root:[vms.o_alpha]wrapfunc.obj - + "cc ''cflags'" wrapfunc.c +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 = Source file +$! P4 - P8 What it depends on +$ +$ modname = f$parse(p3,,,"name") +$ set noon +$ set message/nofacility/noident/noseverity/notext +$ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' +$ set message/facility/ident/severity/text +$ on error then exit +$ open/read swigtmp swig_root:[vms]swiglib.tmp +$! skip header +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$ read swigtmp r +$! +$ +$ read/end=module_not_found swigtmp r +$ modfound = 1 +$ Time = f$cvtime(f$extract(49, 20, r)) +$ goto end_search_module +$ module_not_found: +$ modfound = 0 +$ +$ end_search_module: +$ close swigtmp +$ delete swig_root:[vms]swiglib.tmp;* +$ +$ if modfound .eq. 0 then $ goto Makeit +$ +$! Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(1) +$ 'P2' 'P3' +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/vms/swigconfig.h b/vms/swigconfig.h new file mode 100644 index 000000000..c637b4d83 --- /dev/null +++ b/vms/swigconfig.h @@ -0,0 +1,19 @@ +/* This -*-c-*- file contains SWIG specific configuration data for those modules + that care */ + +/* Directory where to find the machine-independent SWIG files */ + +#define SWIG_LIB "/swig_root/lib/" + +/* Default language */ + +#define SWIG_LANG "-tcl" + +/* Values returned by swig when invoked with the -ldflags option */ + +#define SWIG_PERL_RUNTIME "-L@-exec_prefix-@/lib -lswigpl@-release_suffix-@" +#define SWIG_PYTHON_RUNTIME "-L@-exec_prefix-@/lib -lswigpy@-release_suffix-@" +#define SWIG_TCL_RUNTIME "-L@-exec_prefix-@/lib -lswigtcl@-release_suffix-@" +#define SWIG_RUBY_RUNTIME "-L@-exec_prefix-@/lib -lswigrb@-release_suffix-@" +#define SWIG_GUILE_RUNTIME "-L@-exec_prefix-@/lib -lswigguile@-release_suffix-@" +#define SWIG_PIKE_RUNTIME "-L@-exec_prefix-@/lib -lswigpike@-release_suffix-@" diff --git a/vms/swigver.h b/vms/swigver.h new file mode 100644 index 000000000..0fa6bfdbe --- /dev/null +++ b/vms/swigver.h @@ -0,0 +1,18 @@ + +/* SWIG version information */ + +#ifndef SWIG_VERSION +#define SWIG_VERSION 0x010316 +#endif + +#ifndef SWIG_MAJOR_VERSION +#define SWIG_MAJOR_VERSION 1 +#endif + +#ifndef SWIG_MINOR_VERSION +#define SWIG_MINOR_VERSION 3 +#endif + +#ifndef SWIG_SPIN +#define SWIG_SPIN 16 +#endif