[Pkg-octave-commit] rev 19 - tags/packages trunk/packages trunk/packages/matwrap trunk/packages/matwrap/debian
Rafael Laboissiere
rafael@costa.debian.org
Wed, 09 Feb 2005 13:58:24 +0100
Author: rafael
Date: 2005-02-09 13:58:23 +0100 (Wed, 09 Feb 2005)
New Revision: 19
Added:
tags/packages/matwrap/
trunk/packages/matwrap/
trunk/packages/matwrap/debian/
trunk/packages/matwrap/debian/changelog
trunk/packages/matwrap/debian/control
trunk/packages/matwrap/debian/copyright
trunk/packages/matwrap/debian/dirs
trunk/packages/matwrap/debian/matwrap.1
trunk/packages/matwrap/debian/matwrap.txt
trunk/packages/matwrap/debian/rules
Log:
Initial import of package matwrap
Added: trunk/packages/matwrap/debian/changelog
===================================================================
--- trunk/packages/matwrap/debian/changelog 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/changelog 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1,22 @@
+matwrap (0.57-3) unstable; urgency=low
+
+ * debian/control: Nitpicky Descriptionn fixes (Closes: #142511)
+
+ -- Dirk Eddelbuettel <edd@debian.org> Fri, 12 Apr 2002 17:57:53 -0500
+
+matwrap (0.57-2) unstable; urgency=low
+
+ * debian/control: Added Build-Depends-Indep
+ * debian/control: Upgraded to Debian Policy 3.5.0
+ * debian/copyright: Corrected spelling (lintian)
+ * debian/rukes: Remove one zero-byte example file (lintian)
+
+ -- Dirk Eddelbuettel <edd@debian.org> Wed, 10 Apr 2002 20:51:54 -0500
+
+matwrap (0.57-1) unstable; urgency=low
+
+ * Initial Debian version
+
+ -- Dirk Eddelbuettel <edd@debian.org> Tue, 21 Dec 1999 20:19:48 -0500
+
+
Added: trunk/packages/matwrap/debian/control
===================================================================
--- trunk/packages/matwrap/debian/control 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/control 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1,28 @@
+Source: matwrap
+Section: math
+Priority: optional
+Maintainer: Dirk Eddelbuettel <edd@debian.org>
+Build-Depends-Indep: debhelper (>= 3.0.0)
+Standards-Version: 3.5.0
+
+Package: matwrap
+Architecture: all
+Depends: ${perl:Depends}
+Description: A wrapper generator for matrix languages
+ Matwrap is a tool for interfacing C++ code into matrix-oriented scripting
+ languages such as Octave, Tela or Matlab 5.
+ .
+ It generates all the code to convert from the scripting language's internal
+ types into the types that your C++ code understands (e.g., double, char *,
+ float *, struct abc *). You do not need to understand any of the API details
+ of the language to use your C++ code; just give matwrap a .h file describing
+ your functions.
+ .
+ Brief list of features:
+ .
+ - Functions are automatically vectorized.
+ - Arguments containing dimensions of other vector and matrix arguments can
+ be computed automatically and need not be specified.
+ - Pointers to structures and classes are supported. Public member functions
+ of classes may be called, and public data members may be evaluated or
+ set. Inheritance is supported.
Added: trunk/packages/matwrap/debian/copyright
===================================================================
--- trunk/packages/matwrap/debian/copyright 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/copyright 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1,18 @@
+This is Debian GNU/Linux's prepackaged version of matwrap, a tool for
+interfacing C++ code into matrix-oriented scripting languages such as Octave,
+Tela or Matlab 5. Matwrap was written by Gary Holt <holt@lnc.usc.edu>.
+
+This package was put together by Dirk Eddelbuettel <edd@debian.org> from the
+sources at http://lnc.usc.edu/~holt/matwrap/
+
+Matwrap is issued under the following copyright:
+
+ # Copyright (c) 1997 Gary R. Holt. This is distributed under the terms of the
+ # perl artistic license (http://language.perl.com/misc/Artistic.html).
+
+On Debian GNU/Linux systems, the complete text of the Perl Artistic license
+can be found in the file /usr/share/common-licenses/Artistic.
+
+
+
+
Added: trunk/packages/matwrap/debian/dirs
===================================================================
--- trunk/packages/matwrap/debian/dirs 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/dirs 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1 @@
+usr/share/matwrap
Added: trunk/packages/matwrap/debian/matwrap.1
===================================================================
--- trunk/packages/matwrap/debian/matwrap.1 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/matwrap.1 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1,1259 @@
+.\" Automatically generated by Pod::Man v1.3, Pod::Parser v1.13
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. | will give a
+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "MATWRAP 1"
+.TH MATWRAP 1 "1999-12-13" "perl v5.6.1" "User Contributed Perl Documentation"
+.UC
+.SH "NAME"
+matwrap \*(-- Wrap \*(C+ functions/classes for various matrix languages
+.SH "FEATURES"
+.IX Header "FEATURES"
+matwrap is a script to generate wrapper functions for
+matrix-oriented scripting languages so that \*(C+ subroutines or member
+functions can be called. It doesn't support non-matrix-oriented
+scripting languages like perl and python and tcl because Dave Bezley's
+program \s-1SWIG\s0 is such a good wrapper generator for those languages.
+Someday I hope that all of the features in this wrapper generator are
+incorporated into \s-1SWIG\s0, but since I don't understand \s-1SWIG\s0 well enough to
+do it myself, I'm releasing this separately. \s-1SWIG\s0 is available from
+http://bifrost.lanl.gov/~dmb/SWIG/ or
+http://www.cs.utah.edu/~beazley/SWIG/.
+.PP
+matwrap can handle the following constructs:
+.IP "Ordinary functions" 4
+.IX Item "Ordinary functions"
+For example, suppose you have some functions defined in an \f(CW\*(C`.h\*(C'\fR file,
+like this:
+.Sp
+.Vb 2
+\& float fiddle(double arg);
+\& double tweedle(int x, char *name);
+.Ve
+You can access these directly from \s-1MATLAB\s0 by using the following:
+.Sp
+.Vb 2
+\& matwrap -language matlab -o myfuncs_wrap.c fiddle.h
+\& cmex myfuncs.o myfuncs_wrap.c -o myfuncs_wrap
+.Ve
+Then, in \s-1MATLAB\s0, you can do the following:
+.Sp
+.Vb 2
+\& y = tweedle(3, 'Hello, world');
+\& A = fiddle([3, 4; 5, 6];
+.Ve
+Note especially the last statement, where instead of passing a scalar as
+the argument, we pass a matrix. The C function \fIfiddle()\fR is called
+repeatedly on each element of the matrix and the result is returned as a
+2x2 matrix.
+.Sp
+Floats, doubles, char *, integer, unsigned, and pointers to structures
+may be used as arugments. Support for other data types (e.g., various
+\&\*(C+ classes) is possible and may be easily added since the modules have
+been written for easy extensibility. Function pointers are not
+currently supported in any form. \*(C+ operator definitions are not
+supported either.
+.IP "\*(C+ classes" 4
+.IX Item " classes"
+You can access public member functions and simple public data members of
+classes. For example,
+.Sp
+.Vb 6
+\& class ABC {
+\& public:
+\& ABC(int constructor_arg);
+\& void do_something(float number, int idx);
+\& double x;
+\& };
+.Ve
+From \s-1MATLAB\s0 or a similar language, you would access this structure like
+this:
+.Sp
+.Vb 5
+\& ABC_ptr = ABC_new(3); % Call the constructor and return a pointer.
+\& ABC_do_something(ABC_ptr, pi, 4); % Call the member function.
+\& abc_x = ABC_get_x(ABC_ptr); % Get the value of a data member.
+\& ABC_set_x(ABC_ptr, 3.4); % Set the data member.
+\& ABC_delete(ABC_ptr); % Discard the structure.
+.Ve
+Accessing data members is often extremely useful when you are attempting
+to figure out why your code returns 27.3421 when it ought to return
+4.367.
+.Sp
+The same thing will work for C structs\*(--the only difference is that they
+have only data members and no member functions.
+.Sp
+Only public members are accessible from the scripting language.
+Operator overloading and function overloading are not supported.
+Function pointers are not supported.
+.IP "Arrays" 4
+.IX Item "Arrays"
+You can also call functions that take arrays of data, provided that they
+accept the arrays in a standard format. For example, suppose you want
+to use the pgplot distribution to make graphs (e.g., if you're using a
+scripting language that doesn't have good graphing capability). The
+following function generates a histogram of data:
+.Sp
+.Vb 1
+\& void cpgbin(int nbin, const float *x, const float *data, Logical center);
+.Ve
+Here x[] are the abscissae values and data[] are the data values. If
+you add to your .h file a simple statement indicating the dimensions of
+the matrices, like this:
+.Sp
+.Vb 1
+\& //%input x(nbin), data(nbin)
+.Ve
+then from a MATLAB-like language, you can call this function like this:
+.Sp
+.Vb 1
+\& cpgbin(X, Data, 1)
+.Ve
+where \f(CW\*(C`X\*(C'\fR and \f(CW\*(C`Data\*(C'\fR are vectors. The \f(CW\*(C`nbin\*(C'\fR argument is determined
+from the length of the \f(CW\*(C`X\*(C'\fR and \f(CW\*(C`Data\*(C'\fR vectors automatically (and the
+wrapper generator makes sure they are of the same length!).
+.Sp
+This will also work with multidimensional arrays, provided that the
+function expects the array to be a single one-dimensional array which is
+really the concatenation of the columns of the two-dimensional array.
+(This is normal for Fortran programs.) The first array dimension varies
+the fastest, the second the next fastest, etc. (This is column major
+order, as in Fortran, not row-major order, as in C. Most matlab-like
+languages use the Fortran convention. Tela is an exception.)
+.Sp
+You may only use variable name or a constant for the array dimension.
+You can also use expressions like \f(CW\*(C`2*nbin\*(C'\fR or \f(CW\*(C`2*nbin+1\*(C'\fR. If the
+expression is sufficiently simple, the wrapper generator will determine
+the values of any integer values (like \f(CW\*(C`nbin\*(C'\fR in this example) from the
+dimension of the input arrays, so they do not have to be specified as an
+argument.
+.SH "REQUIREMENTS"
+.IX Header "REQUIREMENTS"
+.IP "A \*(C+ compiler" 4
+.IX Item "A compiler"
+In theory, this could be made to work with an \s-1ANSI\s0 C compiler, but I
+haven't tried to yet. Currently, you must have a full \*(C+ compiler.
+I've used primarily gcc and I tested very briefly with \s-1DEC\s0's cxx.
+.ie n .IP """alloca()""" 4
+.el .IP "\f(CWalloca()\fR" 4
+.IX Item "alloca()"
+If you are using matlab, then you can tell matwrap to use \f(CW\*(C`mxCalloc\*(C'\fR
+instead of \f(CW\*(C`alloca\*(C'\fR by specifying \f(CW\*(C`\-use_mxCalloc\*(C'\fR somewhere on the
+command line. Otherwise, you must have a compiler that supports
+\&\f(CW\*(C`alloca()\*(C'\fR. (gcc does.)
+.Sp
+\&\f(CW\*(C`alloca()\*(C'\fR is usually a little more efficient than \f(CW\*(C`mxCalloc()\*(C'\fR. It
+allocates space on the stack rather than the heap. Unfortunately, you
+may have a limited stack size, and so \f(CW\*(C`alloca()\*(C'\fR may fail for large
+temporary arrays. In this case, you may need to issue a command like
+.Sp
+.Vb 1
+\& unix('unlimit stacksize')
+.Ve
+or else use the \f(CW\*(C`\-use_mxCalloc\*(C'\fR option.
+.IP "A relatively recent version of perl" 4
+.IX Item "A relatively recent version of perl"
+I've tested this only with perl 5.004 and 5.005. Check out
+http://www.perl.com/ for how to get perl.
+.SH "USAGE"
+.IX Header "USAGE"
+.Vb 1
+\& matwrap -language languagename [-options] infile1.h infile2.h
+.Ve
+.Vb 2
+\& matwrap -language languagename [-options] \e
+\& -cpp cxx [-options_to_C_compiler] infile.cxx
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+Using the first form, without the \f(CW\*(C`\-cpp\*(C'\fR flag, files are parsed in the order
+listed, so you should put any files with required typedefs and other
+definitions first. These files are \f(CW\*(C`#include\*(C'\fRd by the generated
+wrapper code; in fact, they are the only files which are \f(CW\*(C`#include\*(C'\fRd.
+This form can be used 1) if you don't have any \f(CW\*(C`#if\*(C'\fRs or macros that confuse
+the parser in your code; 2) if you can easily list all of the include files
+that define the relevant structures.
+.PP
+Alternatively, you can use the \f(CW\*(C`\-cpp\*(C'\fR flag to have matwrap
+run the C preprocessor on your files. This means that all of the
+relevent definitions of types will be found, however deeply they are
+nested in the \f(CW\*(C`#include\*(C'\fR hierarchy. It also means that wrapper
+generation runs considerably slower. Matwrap will attempt
+to guess which files need to be \f(CW\*(C`#include\*(C'\fRd, but it may guess wrong.
+.PP
+Overloaded functions and definitions of operators are not supported. \*(C+
+classes are supported (this is the main reason for this script). Member
+functions may be called, and member fields may be accessed.
+.Sh "Options"
+.IX Subsection "Options"
+.IP "\-cpp" 4
+.IX Item "-cpp"
+Run the C preprocessor on your file before parsing it. This is
+necessary if you are using any #ifdefs in your code. Following the \-cpp
+option should be a complete compiler command, e.g.,
+.Sp
+.Vb 2
+\& matwrap -language octave -o myfile_wrap.cxx \e
+\& -cpp g++ -Iextra_includes -Dmy_thingy=3 myfile.cxx
+.Ve
+All words after the \-cpp option are ignored (and passed verbatim to the
+compiler), so you must supply a \f(CW\*(C`\-o\*(C'\fR option before the \f(CW\*(C`\-cpp\*(C'\fR. Note that
+\&\f(CW\*(C`\-o\*(C'\fR and similar compiler options relevant for actual compilation are
+ignored when just running the preprocessor, so you can substitute your
+actual compilation command without modification. If you do not supply
+the \f(CW\*(C`\-E\*(C'\fR flag in the compiler command, it will be inserted for you
+immediately after the name of the compiler. Also, the \f(CW\*(C`\-C\*(C'\fR option is
+added along with the \f(CW\*(C`\-E\*(C'\fR option so that any comments can be processed
+and put into the documentation strings. (As far as I know all compilers
+support \f(CW\*(C`\-C\*(C'\fR and \f(CW\*(C`\-E\*(C'\fR but undoubtably this won't work well with some. It
+works fine with gcc.)
+.Sp
+When run in this way, \f(CW\*(C`matwrap\*(C'\fR does not generate wrappers for
+any functions or classes defined in files located in \f(CW\*(C`/usr/include\*(C'\fR or
+\&\f(CW\*(C`/usr/local/include\*(C'\fR or in subdirectories of \f(CW\*(C`*/gcc\-lib\*(C'\fR. (Most
+likely you don't want to wrap the entire C library!) You can specify
+additional directories to ignore with the \-cpp_ignore option. If you
+really want to wrap functions in one of those \f(CW\*(C`.h\*(C'\fR files, either copy
+\&\f(CW\*(C`.h\*(C'\fR file or just the relevant function definitions into a file in
+another directory tree. You can also restrict the functions which are
+wrapped using the \-wrap_only option (see below).
+.IP "\-cpp_ignore filename_or_directory" 4
+.IX Item "-cpp_ignore filename_or_directory"
+Ignored unless used with the \-cpp option. Causes functions defined in
+the given file name or in include files in the given directory or
+subdirectories of it not to be wrapped. By default, functions defined
+in \f(CW\*(C`/usr/include\*(C'\fR, \f(CW\*(C`/usr/local/include\*(C'\fR, or \f(CW\*(C`*/gcc\-lib\*(C'\fR are not
+wrapped.
+.ie n .IP """\-o"" file" 4
+.el .IP "\f(CW\-o\fR file" 4
+.IX Item "-o file"
+Specify the name of the output file. If this is not specified, the name is
+inferred from the input files. Some language modules (e.g., \s-1MATLAB\s0)
+will not infer a file name from your source files (this is for your
+protection, so we don't accidentally wipe out a \f(CW\*(C`.c\*(C'\fR file with the same
+name). If you use the \f(CW\*(C`\-cpp\*(C'\fR option, you must also specify the \f(CW\*(C`\-o\*(C'\fR
+option before the \f(CW\*(C`\-cpp\*(C'\fR option.
+.IP "\-language <language_name>" 4
+.IX Item "-language <language_name>"
+Specify the language. This option is mandatory.
+.IP "\-wraponly <list>" 4
+.IX Item "-wraponly <list>"
+Specify a list of global functions or variables or classes to wrap. The
+list extends to the end of the command line, so this must be the last
+option. Definitions of all functions and classes not explictly listed
+are ignored. This allows you to specify all the \f(CW\*(C`.h\*(C'\fR files that you
+need to define all the types, but only to wrap some of the functions.
+.Sp
+Global functions and variables are specified simply by name. Classes
+are specified by the word 'class' followed by the class name. For
+example,
+.Sp
+.Vb 2
+\& matwrap -language matlab myfile.h \e
+\& -wraponly myglobalfunc class myclass
+.Ve
+.SH "Input files"
+.IX Header "Input files"
+Input files are designed to be your ordinary .h files, so your wrapper
+and your \*(C+ sources are never out of date. In general, the wrapper
+generator does the obvious thing with each different kind of type. For
+example, consider the function declaration:
+.PP
+.Vb 1
+\& double abcize(float a, int b, char *c, SomeClass *d);
+.Ve
+This will pass a single-precision floating point number as argument \f(CW\*(C`a\*(C'\fR
+(probably converting from double precision or integer, depending on what
+the interpreted language stored the value as). An integer is passed as
+argument \f(CW\*(C`b\*(C'\fR (probably converted from a double precision value). A
+null-terminated string is passed as argument \f(CW\*(C`c\*(C'\fR (converted from
+whatever weird format the language uses). The argument \f(CW\*(C`d\*(C'\fR must be a
+pointer value which was returned by another function.
+.PP
+Vectorization is automatically performed, so that if you pass a matrix
+of \f(CW\*(C`m\*(C'\fR by \f(CW\*(C`n\*(C'\fR inputs as argument \f(CW\*(C`a\*(C'\fR and arguments \f(CW\*(C`b\*(C'\fR and \f(CW\*(C`c\*(C'\fR as
+either scalars or \f(CW\*(C`m\*(C'\fR by \f(CW\*(C`n\*(C'\fR matrices, then the function will be
+called \f(CW\*(C`m*n\*(C'\fR times and the result will be an \f(CW\*(C`m\*(C'\fR by \f(CW\*(C`n\*(C'\fR matrix.
+By default, a function is vectorized if it has both inputs and outputs
+(see under \f(CW\*(C`//%vectorize\*(C'\fR below). Most matrix languages do not support
+vectors of strings in a natural way, so \f(CW\*(C`char *\*(C'\fR arguments are not
+vectorized.
+.PP
+Passing arguments by reference is handled in the expected way. For
+example, given the declaration
+.PP
+.Vb 1
+\& void fortran_sub(double *inarg1, float *inarg2);
+.Ve
+pointers to double and single precision numbers will be passed to the
+subroutine instead of the numbers themselves.
+.PP
+This creates an ambiguity for the type \f(CW\*(C`char *\*(C'\fR. For example, consider
+the following two functions:
+.PP
+.Vb 2
+\& void f1(char *a);
+\& void f2(unsigned char *b);
+.Ve
+Matwrap assumes that the function \f(CW\*(C`f1\*(C'\fR is passed a null terminated
+string, despite the fact that the argument \f(CW\*(C`a\*(C'\fR could be a pointer to a
+buffer where \f(CW\*(C`f1\*(C'\fR returns a character. Although this situation can be
+disambiguated with proper use of the \f(CW\*(C`const\*(C'\fR qualifier, matwrap treats
+\&\f(CW\*(C`char *\*(C'\fR and \f(CW\*(C`const char *\*(C'\fR as identical since many programs don't use
+\&\f(CW\*(C`const\*(C'\fR properly. Matwrap assumes, however, that \f(CW\*(C`unsigned char *\*(C'\fR
+is not a null terminated string but an \f(CW\*(C`unsigned char\*(C'\fR variable passed
+by reference. You can also force it to interpret \f(CW\*(C`char *\*(C'\fR as a signed
+char passed by reference by specifying the qualifier \f(CW\*(C`//%input a(1)\*(C'\fR
+(see below).
+.PP
+If you want to pass arguments as arrays, or if there are outputs other
+than the return value of the function, you must declare these explicitly
+using the \f(CW\*(C`//%input\*(C'\fR or \f(CW\*(C`//%output\*(C'\fR qualifiers. All qualifiers follow
+the definition of the function (after the \f(CW\*(C`;\*(C'\fR or the closing \f(CW\*(C`}\*(C'\fR if it
+is an inline function). Valid qualifiers are:
+.IP "//%novectorize_type type1, type2, ..." 4
+.IX Item "//%novectorize_type type1, type2, ..."
+Specifies that all arguments of the given types should not be vectorized
+even if it is possible. This could be useful if you have a class which
+there will be only one copy of, so it is pointless to vectorize.
+(This qualifier may be present anywhere in the file.)
+.IP "//%novectorize" 4
+.IX Item "//%novectorize"
+Following the definition of a global function or member function,
+directs matwrap not to try to vectorize the function. For
+some functions, vectorization simply doesn't make sense. By default,
+matwrap won't vectorize a function if it has no output
+arguments or no input arguments.
+.IP "//%vectorize" 4
+.IX Item "//%vectorize"
+Following the definition of a global function or member function,
+directs matwrap to vectorize the function. By default, matwrap won't
+vectorize a function if it has no output arguments or no input
+arguments. This is normally what you want, but but sometimes it makes
+sense to vectorize a function with no output arguments.
+.IP "//%nowrap" 4
+.IX Item "//%nowrap"
+Don't wrap this function. It will therefore not be callable directly
+from your scripting language.
+.IP "//%name new_name" 4
+.IX Item "//%name new_name"
+Specify a different name for the function when it is invoked from the
+scripting language.
+.IP "//%input argname(dim1, dim2, ...), argname(dim)" 4
+.IX Item "//%input argname(dim1, dim2, ...), argname(dim)"
+Following the declaration of a global function or member function,
+declares the dimensions of the input arguments with the given name.
+This declaration must immediately follow the prototype of the function.
+Dimension strings may contain any arbitrary C expression. If the
+expression is sufficiently simple, e.g., \*(L"n\*(R" or \*(L"n+1\*(R" or \*(L"2*n\*(R", and if
+the expression includes another argument to the function (\*(L"n\*(R" in this
+case), then the other argument will be calculated from the dimensions of
+the input variable and need not be specified as an argument in the
+scripting language.
+.Sp
+For example, if you have a function which is declared like this:
+.Sp
+.Vb 3
+\& void myfunc(int n, double *x, double *y);
+\& //%input x(3*n+4)
+\& //%output y(n*(n+1)/2)
+.Ve
+n would be calculated from the dimension of the variable x and then used
+to compute the size of the output array. So you would call the function
+like this:
+.Sp
+.Vb 1
+\& y = myfunc(x)
+.Ve
+On the other hand, if you had a specification like this:
+.Sp
+.Vb 3
+\& void return_diag(int n, double *x, double *y);
+\& //%input x(n*(n+1)/2)
+\& //%output y(n)
+.Ve
+then n will have to be explicitly specified because it is too difficult
+to calculate:
+.Sp
+.Vb 1
+\& y = myfunc(n, x)
+.Ve
+.IP "//%modify argname(dim1, dim2, ...), argname(dim1)" 4
+.IX Item "//%modify argname(dim1, dim2, ...), argname(dim1)"
+.PD 0
+.IP "//%output argname(dim1, dim2, ...), argname(dim1)" 4
+.IX Item "//%output argname(dim1, dim2, ...), argname(dim1)"
+.PD
+Same as \f(CW\*(C`//%input\*(C'\fR except that this also tags the variables as modify
+or output variables. If you don't specify a dimension expression (e.g.,
+\&\*(L"//%output x\*(R") then the variable is tagged as a scalar output variable.
+(This is the proper way to tell matwrap to make an argument an
+output argument.)
+.Sh "Unsupported \*(C+ constructs"
+.IX Subsection "Unsupported constructs"
+.IP "Function overloading" 4
+.IX Item "Function overloading"
+.PD 0
+.IP "Operator definition" 4
+.IX Item "Operator definition"
+.IP "Function and member function pointers" 4
+.IX Item "Function and member function pointers"
+.PD
+It would be really nice to support these, but I think it's also really
+hard. Maybe someday.
+.IP "Two-dimensional arrays using a vector of pointers" 4
+.IX Item "Two-dimensional arrays using a vector of pointers"
+You can use two-dimensional arrays as long as they are stored internally
+as a single long vector, as in Fortran. In this case, the array
+declaration would be \f(CW\*(C`float *x\*(C'\fR, and the \f(CW\*(C`i,j\*(C'\fR'th element is accessed
+by \f(CW\*(C`x[j*n+i]\*(C'\fR. You cannot use two dimensional arrays if they are
+declared like \f(CW\*(C`float **x\*(C'\fR and accessed like \f(CW\*(C`x[i][j]\*(C'\fR. Unfortunately,
+the Numerical Recipes library uses this format for all its
+two-dimensional matrices, so at present you can only wrap Numerical
+Recipes functions which take scalars or vectors. This restriction might
+be lifted in the future.
+.IP "Arrays with an offset" 4
+.IX Item "Arrays with an offset"
+The Numerical Recipes code is written so that most of its indices begin
+at 1 rather than at 0, I guess because its authors are Fortran junkies.
+This causes a problem, because it means that the pointer you pass to the
+subroutine is actually not the beginning of the array but before the
+beginning. You can get around this restriction by passing an extra
+blank element in your array. For example, suppose you want to wrap the
+function to return the Savitzky-Golay filter coefficients:
+.Sp
+.Vb 1
+\& void savgol(float c[], int np, int nl, int nr, int ld, int m);
+.Ve
+where the index in the array \f(CW\*(C`c\*(C'\fR is declared to run from 1 to np.
+You'd have to declare the array like this:
+.Sp
+.Vb 1
+\& //%output c(np+1)
+.Ve
+and then ignore the first element. Thus from \s-1MATLAB\s0 you'd call it with
+the following sequence:
+.Sp
+.Vb 3
+\& savgol_coefs = savgol(np, nl, nr, ld, m);
+\& savgol_coefs = savgol_coefs(2:length(savgol_coefs));
+\& % Discard the unused first element.
+.Ve
+.IP "Passing structures by value or \*(C+ reference" 4
+.IX Item "Passing structures by value or reference"
+In other words, if Abc is the name of a class, declarations like
+.Sp
+.Vb 1
+\& void myfunc(Abc x);
+.Ve
+or
+.Sp
+.Vb 1
+\& void myfunc(Abc &x);
+.Ve
+won't work. However, you can pass a pointer to the class:
+.Sp
+.Vb 1
+\& void myfunc(Abc *x);
+.Ve
+The wrapper generator will do the type checking and it even handles
+inheritance properly.
+.SH "Examples"
+.IX Header "Examples"
+For more examples, see the subdirectories of \fIshare/matwrap/Examples\fR
+in the distribution. This includes a wrapper for the entire \s-1PGPLOT\s0
+library (directory \fIpgplot\fR) and a sample \*(C+ simulator for an neuron
+governed by the Hodgkin-Huxley equations (directory \fIsingle_axon\fR).
+.SH "Support for different languages"
+.IX Header "Support for different languages"
+.Sh "\s-1MATLAB\s0 5"
+.IX Subsection "MATLAB 5"
+Currently, you must compile the generated wrapper code using \*(C+, even
+if you are wrapping only C functions with no \*(C+ classes. You can
+compile your C functions using C as you please; you may have to put a
+\&\f(CW\*(C`extern "C" { }\*(C'\fR statement in the .h file. This restriction may be
+lifted in the future.
+.PP
+The default maximum number of dimensions supported is four. You can
+change this by modifying the \f(CW$max_dimensions\fR variable near the top of
+the file share/matwrap/wrap_matlab.pl in the distribution.
+.PP
+Specify \f(CW\*(C`\-langauge matlab\*(C'\fR on the command line to use the matlab code
+generator. You \s-1MUST\s0 also use \f(CW\*(C`\-o\*(C'\fR to specify the output file name.
+(This is because matlab wrappers have an extension of \f(CW\*(C`.c\*(C'\fR and if we
+infer the file name from the name of include files, it's quite likely
+that we'll wipe out something that shouldn't be wiped out.)
+.PP
+An annoying restriction of \s-1MATLAB\s0 is that only one C function can be
+defined per mex file. To get around this problem, the wrapper generator
+defines a C function which takes an extra parameter, which is a code for
+the function you actually want to call. It also defines a series of
+\&\s-1MATLAB\s0 stub functions to supply the extra parameter. Each of these must
+be placed into its own separate file (because of another \s-1MATLAB\s0 design
+inadequacy) so wrapper generation for \s-1MATLAB\s0 may actually create
+hundreds of files if you have a lot of member functions.
+.PP
+You can specify where you want the \f(CW\*(C`.m\*(C'\fR files to be placed using the
+\&\f(CW\*(C`\-outdir\*(C'\fR option, like this:
+.PP
+.Vb 2
+\& matwrap -language matlab -outdir wrap_m \e
+\& myfuncs.h -o myfuncs_matlab.c
+.Ve
+.Vb 1
+\& mex -f mex_gcc_cxx myfunc
+.Ve
+This will create dozens of tiny \f(CW\*(C`.m\*(C'\fR files which are placed into the
+directory \f(CW\*(C`wrap_m\*(C'\fR, and a single mexfile with the name \fImyfuncs\fR. \s-1DO\s0
+\&\s-1NOT\s0 \s-1CHANGE\s0 \s-1THE\s0 \s-1NAME\s0 \s-1OF\s0 \s-1THE\s0 \s-1MEX\s0 \s-1FILE\s0! The \f(CW\*(C`.m\*(C'\fR files assume that the
+name of the C subroutine is the name of the file, in this case,
+\&\fImyfuncs\fR. (You can move the mex file to a different directory, if you
+want, so long as it is still in your matlabpath).
+.PP
+To wrap \*(C+ functions in \s-1MATLAB\s0, you'll probably need to specify the
+\&\f(CW\*(C`\-f\*(C'\fR option to the mex command, as shown above. You'll need to create
+the mex options file so that the appropriate libraries get linked in for
+\&\*(C+. For example, on the machine that I use, I created the file
+\&\fImex_gcc_cxx\fR which contains the following instructions:
+.PP
+.Vb 6
+\& . mexopts.sh # Load the standard definitions.
+\& CC='g++'
+\& CFLAGS='-Wall'
+\& CLIBS='-lg++ -lstdc++ -lgcc -lm -lc'
+\& COPTIMFLAGS='-O2 -g'
+\& CDEBUGFLAGS='-g'
+.Ve
+This works with other \*(C+ compilers if you set \f(CW\*(C`CC\*(C'\fR and \f(CW\*(C`CLIBS\*(C'\fR to use the
+appropriate compiler and libraries (e.g., \f(CW\*(C`CLIBS=\-lcxx\*(C'\fR and \f(CW\*(C`CC=cxx\*(C'\fR
+for cxx on Digital Unix).
+.PP
+By default, matwrap uses \f(CW\*(C`alloca()\*(C'\fR to allocate temporary memory. If
+for some reason you want to use \f(CW\*(C`mxCalloc()\*(C'\fR, specify \f(CW\*(C`\-use_mxCalloc\*(C'\fR
+somewhere on the command line.
+.PP
+The following features of matlab are not currently supported:
+.IP "Vectors of strings" 4
+.IX Item "Vectors of strings"
+.PD 0
+.IP "Structures" 4
+.IX Item "Structures"
+.PD
+It would be nice to be able to return whole \*(C+ structures as \s-1MATLAB\s0
+structures. Maybe this will happen in the future.
+.IP "Cell arrays" 4
+.IX Item "Cell arrays"
+Do not try to pass a cell array instead of a numeric array to a \*(C+
+function. It won't work; the wrapper code does not support it.
+.PP
+One quirk of operation which can be annoying is that \s-1MATLAB\s0 likes to use
+row vectors instead of column vectors. This can be a problem if you
+write some C code that expects a vector input, like this:
+.PP
+.Vb 1
+\& void myfunc(double *d, int n_d); //%input d(n_d)
+.Ve
+Suppose now you try to invoke it with the following matlab commands:
+.PP
+.Vb 1
+\& >> myfunc(0:0.1:pi)
+.Ve
+The range \f(CW\*(C`0:0.1:pi\*(C'\fR is a row vector, not a column vector. As a
+result, a dimension error will be returned if my_func is not vectorized
+(which would be the default with these arguments), because the function
+is expecting an n_d by 1 array instead of a 1 by n_d array. If you
+allowed \f(CW\*(C`myfunc\*(C'\fR to be vectorized, then \f(CW\*(C`myfunc()\*(C'\fR will be called once
+for each element of the range, with \f(CW\*(C`n_d = 1\*(C'\fR. This is almost
+certainly not what you wanted. I haven't yet figured out a good way to
+handle this. Anyway, be careful, and always transpose ranges, like
+this:
+.PP
+.Vb 1
+\& >> myfunc((0:0.1:pi)')
+.Ve
+.Sh "Octave"
+.IX Subsection "Octave"
+Octave is much like matlab in that it only allows one callable function
+to be put into a .oct file. The function in the .oct file therefore
+takes an extra argument which indicates which \*(C+ function you actually
+wanted to call. Fortunately, unlike matlab, octave can define more than
+one function per file so we don't have to have a separate .m file for
+each function. Instead, the functions are all placed into a separate
+file whose name you specify on the command line with the \-stub option.
+.PP
+To compile an octave module, you would use the following command:
+.PP
+.Vb 3
+\& matwrap -language octave -stub myfuncs_stubs.m \e
+\& myfuncs.h -o myfuncs_octave.cc
+\& mkoctfile myfuncts_octave
+.Ve
+Note that you can't do this unless you have the \fImkoctfile\fR script
+installed. \fImkoctfile\fR is not available in some binary distributions.
+.PP
+Then, in octave, you must first load the stub functions:
+.PP
+.Vb 2
+\& octave:1> myfuncs_subs
+\& octave:2> # Now you may call the functions.
+.Ve
+\&\s-1DO\s0 \s-1NOT\s0 \s-1CHANGE\s0 \s-1THE\s0 \s-1NAME\s0 \s-1OF\s0 \s-1THE\s0 .oct \s-1FILE\s0! Its name is written into the
+stub functions. You can move the file into a different directory,
+however, so long as the directory is in your \s-1LOADPATH\s0.
+.PP
+(The \fImkoctfile\fR script for octave versions below 2.0.8 has an annoying
+restriction that prevents additional libraries from being linked into
+your module if your linker is sensitive to the order of the libraries on
+the command line. The \fImkoctfile\fR script for versions 2.0.8 and 2.0.9
+in theory supports libraries on the command line but it doesn't work.
+Patches to fix \fImkoctfile\fR for these versions of octave are provided in
+\&\fIshare/matwrap/mkoctfile_2_0_8_or_9.patch\fR and
+\&\fIshare/matwrap/mkoctfile_before_2_0_8.patch\fR.)
+.PP
+If you compile your source code to .o or .a files separately, on many
+systems you need to force the compiler to make position-independent code
+(\f(CW\*(C`\-fPIC\*(C'\fR option to gcc). Remember you are making a shared library, so
+follow the rules for making shared libraries on your system. The
+\&\fImkoctfile\fR script should do this for you automatically if you have it
+compile your source files, but if you compile to .o files first and give
+these to \fImkoctfile\fR, you may have to be careful to specify the
+appropriate flags on the \f(CW\*(C`cc\*(C'\fR or \f(CW\*(C`c++\*(C'\fR command line.
+.PP
+Octave doesn't seem to provide a good way to support modify variables,
+i.e., variables that are taken as input and modified and returned as
+output. For example, suppose you have the function
+.PP
+.Vb 1
+\& void myfunc(float *a, int a_n); //%modify a(a_n)
+.Ve
+which takes the array \f(CW\*(C`a\*(C'\fR as input, does something to it, and returns
+its output in the same place. In octave, this would be called as:
+.PP
+.Vb 1
+\& a_out = myfunc(a_in);
+.Ve
+rather than as
+.PP
+.Vb 1
+\& myfunc(a);
+.Ve
+as it might be from other languages.
+.PP
+Octave has the same quirk as \s-1MATLAB\s0 in the usage of row vectors where
+matwrap expects column variables. See the end of the section on \s-1MATLAB\s0
+for details.
+.Sh "Tela"
+.IX Subsection "Tela"
+Tela (Tensor Language) is a \s-1MATLAB\s0 clone which is reputed to be considerably
+faster than \s-1MATLAB\s0 and has a number of other nice features biassed toward PDEs.
+It can be found at http://www.geo.fmi.fi/prog/tela.html.
+.PP
+Specify \f(CW\*(C`\-language tela\*(C'\fR to invoke the Tela wrapper generator, like this:
+.PP
+.Vb 2
+\& matwrap -language tela myfuncs.h -o myfuncs.ct
+\& telakka myfuncs.ct other_files.o -o tela
+.Ve
+That's pretty much all there is to it. Tela doesn't support arrays of
+strings so \f(CW\*(C`char *\*(C'\fR parameters are not vectorized. Otherwise, just
+about everything should work as you expect.
+.PP
+\&\s-1WARNING:\s0 Tela stores data internally using a row-major scheme instead of
+the usual column-major ordering, so the indexes of Tela arrays are in
+reverse order from the index specification order in the \f(CW%input\fR,
+\&\f(CW%output\fR, and \f(CW%modify\fR declarations. Sorry, it wasn't my idea.
+.PP
+The tela code generator does not currently support \f(CW\*(C`short\*(C'\fR or
+\&\f(CW\*(C`unsigned short\*(C'\fR.
+.Sh "A note on debugging"
+.IX Subsection "A note on debugging"
+Since both \s-1MATLAB\s0 and Octave use dynamically loadable libraries, it can
+be tricky to debug your \*(C+ code. \s-1MATLAB\s0 has a documented way of making
+a standalone program, but I found this extremely inconvenient. If you
+have gdb, it is sometimes easier to use the \*(L"attach\*(R" command if your
+operating system supports it. (Linux and Digital Unix do; I do not know
+about other operating systems.) Start up \s-1MATLAB\s0 or octave as you
+normally would, and load the shared library by calling some function in
+it that doesn't cause it to crash. (Or, put a \*(L"sleep(30)\*(R" in an
+appropriate place in the code, so there is enough time for you to catch
+it between when it loads the library and when it crashes.) Then while
+\&\s-1MATLAB\s0 or Octave is at the prompt or waiting, attach to the
+octave/MATLAB process using gdb, set your breakpoints, allow the program
+to continue, type the command that fails, and debug away.
+.SH "Writing new language support modules"
+.IX Header "Writing new language support modules"
+Matlab 5, octave, and Tela are the only language modules that I've
+written so far. It's not hard to write a language module\*(--most of the
+tricky stuff has been taken care of by the main wrapper generator
+program. It's just a bit tedious.
+.PP
+The parsing in matwrap is entirely independent of the target language.
+The back end is supplied by one of several language modules, as
+specified by the \f(CW\*(C`\-language\*(C'\fR option.
+.PP
+The interface is designed to make it easy to generate automatically
+vectorized functions. Vectorization is done automatically by the
+matwrap code, independent of the language module. All subroutines
+except those with no output arguments or no input arguments are
+vectorized except as explicitly requested.
+.PP
+Typically, the \fIfunction_start()\fR function in the language module will
+output the function header to the file and declare the arguments to the
+function. After this, the wrapper generator writes C code to check the
+dimensions of the arguments.
+.PP
+After checking the dimensions of all variables, the value of the
+variable is obtained from the function get_c_arg_scalar/get_c_arg_ptr.
+This returns a pointer to the variable, so if it is vectorized we can
+easily step through the pointer array. Note that if the desired type is
+\&\*(L"float\*(R" and the input is an array of \*(L"double\*(R", then the language module
+will have to make a temporary array of doubles. Output variables are
+then created by calling make_output_scalar/make_output_ptr.
+.PP
+Next, the C function is called as many times as required.
+.PP
+Next, any modify/output arguments need to have the new values put back
+into the scripting language variables. This is accomplished by the
+put_val_scalar/put_val_ptr function. Temporary arrays may be freed
+here. Note that put_val is not called for input arguments so temporary
+arrays of input arguments will have to be freed some other way.
+.PP
+Finally, the function function_end is called to do any final cleanup and
+terminate the function definition.
+.PP
+The following functions and variables must be supplied by the language
+module. They should be in a package whose name is the same as the
+argument to the \f(CW\*(C`\-language\*(C'\fR option.
+.ie n .IP "$max_dimensions" 4
+.el .IP "\f(CW$max_dimensions\fR" 4
+.IX Item "$max_dimensions"
+A scalar value indicating the maximum number of dimensions this language can
+handle (or, at least, the maximum number of dimensions that our scripts will
+handle). This is 2 for languages like Matlab or Octave which can only have
+2\-dimensional matrices.
+.ie n .IP """arg_pass(\e%function_def, $argname)""" 4
+.el .IP "\f(CWarg_pass(\e%function_def, $argname)\fR" 4
+.IX Item "arg_pass(%function_def, $argname)"
+A C or \*(C+ expression used to pass the argument to another function
+which does not know anything about the type of the argument. For
+example, in the \s-1MATLAB\s0 module this function returns an expression for
+the mxArray type for a given argument.
+.ie n .IP """arg_declare(""""\fRarg_name_in_arglist\f(CW"""")""" 4
+.el .IP "\f(CWarg_declare(``\fRarg_name_in_arglist\f(CW'')\fR" 4
+.IX Item "arg_declare(""arg_name_in_arglist"")"
+This returns a C/\*(C+ declaration appropriate for the argument passed
+using arg_pass. For example, in the \s-1MATLAB\s0 module this function returns
+\&\*(L"mxArray *arg_name_in_arglist\*(R".
+.ie n .IP """declare_const(""""\fRconstant name\f(CW"", ""\fRclass name\f(CW"", ""\fRtype\f(CW"""")""" 4
+.el .IP "\f(CWdeclare_const(``\fRconstant name\f(CW'', ``\fRclass name\f(CW'', ``\fRtype\f(CW'')\fR" 4
+.IX Item "declare_const(""constant name"", ""class name"", ""type"")"
+Output routines to make a given constant value accessible from the interpreter.
+If \*(L"class name\*(R" is blank, this is a global constant.
+.Sp
+None of the language modules currently support definition of constants,
+but this function is called.
+.ie n .IP """error_dimension(\e%function_def, $argname)""" 4
+.el .IP "\f(CWerror_dimension(\e%function_def, $argname)\fR" 4
+.IX Item "error_dimension(%function_def, $argname)"
+A C statement (including the final semicolon, if not surrounded by braces)
+which indicates that an error has occured because the dimension of argument
+\&\f(CW$argname\fR was wrong.
+.ie n .IP """finish()""" 4
+.el .IP "\f(CWfinish()\fR" 4
+.IX Item "finish()"
+Called after all functions have been wrapped, to close the output file and do
+whatever other cleanup is necessary.
+.ie n .IP """function_start(\e%function_def)""" 4
+.el .IP "\f(CWfunction_start(\e%function_def)\fR" 4
+.IX Item "function_start(%function_def)"
+This should prepare a documentation string entry for the function and it should
+set up the definition of the function. It should return a string rather than
+printing the result.
+.Sp
+\&\f(CW%function_def\fR is the array defining all the arguments and outputs for this
+function. See below for its format.
+.ie n .IP """function_end(\e%function_def)""" 4
+.el .IP "\f(CWfunction_end(\e%function_def)\fR" 4
+.IX Item "function_end(%function_def)"
+Returns a string which finishes off the definition of a function wrapper.
+.ie n .IP """get_outfile(\e@files_processed)""" 4
+.el .IP "\f(CWget_outfile(\e@files_processed)\fR" 4
+.IX Item "get_outfile(@files_processed)"
+Get the name of an output file. This subroutine is only called if no output
+file is specified on the command line. \f(CW\*(C`\e@files_processed\*(C'\fR is a list of the
+\&\f(CW\*(C`.h\*(C'\fR files which were parsed.
+.ie n .IP """get_c_arg_scalar(\e%function_def, $argname)""" 4
+.el .IP "\f(CWget_c_arg_scalar(\e%function_def, $argname)\fR" 4
+.IX Item "get_c_arg_scalar(%function_def, $argname)"
+Returns C statements to load the current value of the given argument
+into the C variable \f(CW$function_def{args}{$argname}{c_var_name}\fR. The
+variable is guaranteed to be either a scalar or an array with dimensions
+1,1,1... (depending on the scripting language, these may be identical).
+.ie n .IP """get_c_arg_ptr(\e%function_def, $argname)""" 4
+.el .IP "\f(CWget_c_arg_ptr(\e%function_def, $argname)\fR" 4
+.IX Item "get_c_arg_ptr(%function_def, $argname)"
+Returns C statements to set up a pointer which points to the first value
+of a given argument. It is possible that the argument may be a scalar,
+in which case we just want a pointer to that scalar value. (This
+happens only for vectorizable arguments when the vectorization is not
+used on this function call.) The dimensions are guaranteed to be
+correct. The type of the argument should be checked. The pointer value
+should be stored in the variable
+\&\f(CW$function_def{args}{$argname}{c_var_name}\fR.
+.Sp
+The pointer should actually point to the array of all the values of the
+variable. The array should have the same number of elements as the argument,
+since to vectorize the function, the wrapper function will simply step through
+this array. If we want a float type and the input vector is double or int,
+then a temporary array must be made which is a copy of the double/int arrays.
+.ie n .IP """get_size(\e%function_def, $argname, $n)""" 4
+.el .IP "\f(CWget_size(\e%function_def, $argname, $n)\fR" 4
+.IX Item "get_size(%function_def, $argname, $n)"
+Returns a C expression which is the size of the \f(CW$n\fR'th dimension of the given
+argument. Dimension 0 is the least-significant dimension.
+.ie n .IP """initialize($outfile, \e@files_processed, \e@cpp_command, $include_str)""" 4
+.el .IP "\f(CWinitialize($outfile, \e@files_processed, \e@cpp_command, $include_str)\fR" 4
+.IX Item "initialize($outfile, @files_processed, @cpp_command, $include_str)"
+Write out header information.
+.Sp
+.Vb 4
+\& $outfile The name of the output file. This file should
+\& be opened, and the function should return the
+\& name of a file handle (qualified with the
+\& package name, e.g., "matlab::OUTFILE").
+.Ve
+.Vb 3
+\& @files A list of files explicitly listed on the command
+\& line. This will be a null array if no files
+\& were explicitly listed.
+.Ve
+.Vb 3
+\& @cpp_command The command string words passed to the C
+\& preprocessor, if the C preprocessor was run.
+\& Otherwise, this will be a null array.
+.Ve
+.Vb 3
+\& $include_str A string of #include statements which represents
+\& our best guess as to the proper files to include
+\& to make this compilation work.
+.Ve
+This function also should write out \*(C+ code to define the following
+functions:
+.Sp
+.Vb 3
+\& int _n_dims(argument) Returns number of dimensions.
+\& int _dim(argument, n) Returns the size in the n'th dimension,
+\& where 0 is the first dimension.
+.Ve
+.ie n .IP """make_output_scalar(\e%function_def, $argname)""" 4
+.el .IP "\f(CWmake_output_scalar(\e%function_def, $argname)\fR" 4
+.IX Item "make_output_scalar(%function_def, $argname)"
+Return C code to create the given output variable. The output variable
+will be a scalar.
+.ie n .IP """make_output_ptr(\e%function_def, $argname, $n_dimensions, @dimensions)""" 4
+.el .IP "\f(CWmake_output_ptr(\e%function_def, $argname, $n_dimensions, @dimensions)\fR" 4
+.IX Item "make_output_ptr(%function_def, $argname, $n_dimensions, @dimensions)"
+Return C code to set up a pointer to where to store the values of the output
+variable. \f(CW$n_dimensions\fR is a C expression, not necessarily a constant.
+\&\f(CW@dimensions\fR is a list of C expressions that are the sizes of each dimension.
+There may be more values in \f(CW@dimensions\fR than are needed.
+.ie n .IP """n_dimensions(\e%function_def, $argname)""" 4
+.el .IP "\f(CWn_dimensions(\e%function_def, $argname)\fR" 4
+.IX Item "n_dimensions(%function_def, $argname)"
+Returns a C expression which is the number of dimensions of the argument whose
+name is \f(CW$argname\fR.
+.ie n .IP """pointer_conversion_functions()""" 4
+.el .IP "\f(CWpointer_conversion_functions()\fR" 4
+.IX Item "pointer_conversion_functions()"
+Returns code to convert to and from pointer types to the languages
+internal representation, if any special code is needed. If this
+subroutine is not called, then there are no class types and pointers
+will not need to be handled.
+.ie n .IP """parse_argv(\e@ARGV)""" 4
+.el .IP "\f(CWparse_argv(\e@ARGV)\fR" 4
+.IX Item "parse_argv(@ARGV)"
+Scan the argument list for language-specific options. This is called after the
+\&\f(CW\*(C`\-language\*(C'\fR option has been parsed and removed from the \f(CW@ARGV\fR array.
+.ie n .IP """put_val_scalar(\e%function_def, $argname)""" 4
+.el .IP "\f(CWput_val_scalar(\e%function_def, $argname)\fR" 4
+.IX Item "put_val_scalar(%function_def, $argname)"
+Returns C code to take the value from the C variable whose name is given
+by \f(CW$function_def{args}{$argname}{c_var_name}\fR and store it back in the
+scripting language scalar variable.
+.ie n .IP """put_val_ptr(\e%function_def, $argname)""" 4
+.el .IP "\f(CWput_val_ptr(\e%function_def, $argname)\fR" 4
+.IX Item "put_val_ptr(%function_def, $argname)"
+Returns C code to take the value from the C array whose name is given by
+\&\f(CW$function_def{args}{$argname}{c_var_name}\fR and store it back in the
+scripting language array at the specified index. The pointer
+\&\f(CW$function_def{args}{$argname}{c_var_name}\fR was set up by either
+\&\f(CW\*(C`get_c_arg\*(C'\fR or \f(CW\*(C`make_output\*(C'\fR, depending on whether this is an
+input/modify or an output variable.
+.ie n .Sh "The %function_def array"
+.el .Sh "The \f(CW%function_def\fP array"
+.IX Subsection "The %function_def array"
+Many of these arguments require a reference to the \f(CW%function_def\fR associative
+array. This array defines everything that is known about the function.
+.PP
+First, there are a few entries that describe the interface to the scripting
+language:
+.IP "name" 4
+.IX Item "name"
+The name of the function.
+.IP "class" 4
+.IX Item "class"
+The class of which this is a member function. This element will be blank
+if it is a global function.
+.IP "script_name" 4
+.IX Item "script_name"
+The name of the function in the scripting language. If this field is blank,
+then the name of the function should be generated from the \*(L"class\*(R" and \*(L"name\*(R"
+fields. This field is set by the \f(CW%name\fR directive.
+.IP "static" 4
+.IX Item "static"
+True if this is a static member function. Non-static member functions will
+have the class pointer specified as the first argument in the argument list.
+.IP "inputs" 4
+.IX Item "inputs"
+A list of the names of arguments to the scripting language function which are
+only for input. Argument names are generated from the corresponding argument
+names in the C function prototype.
+.IP "modifies" 4
+.IX Item "modifies"
+A list of the names of arguments to the scripting language function which are
+for both input and output. Argument names are generated from the corresponding
+argument names in the C function prototype.
+.IP "outputs" 4
+.IX Item "outputs"
+A list of the names of arguments to the scripting language function which are
+for output. Argument names are generated from the corresponding argument names
+in the C function prototype. \*(L"retval\*(R" is used as the name of the return value
+of the function, if there is a return value.
+.IP "args" 4
+.IX Item "args"
+An associative array indexed by the argument name which contains information
+about each argument of the function. Note that there may be more arguments in
+this associative array than in the inputs/modifies/outputs arrays because some
+of the arguments to the function may be merely the dimension of arrays, which
+are not arguments in the scripting language since they can be determined by
+other means.
+.Sp
+Note that there will also be an entry in the args array for \*(L"retval\*(R" if the
+function has a return value, since the return value is treated as an output
+argument.
+.Sp
+The fields in this associative array are:
+.RS 4
+.IP "source" 4
+.IX Item "source"
+Whether this is an \*(L"input\*(R", \*(L"output\*(R", or \*(L"modify\*(R" variable, or whether
+it can be calculated from the \*(L"dimension\*(R" of another variable. These
+are the only legal values for this field.
+.IP "type" 4
+.IX Item "type"
+The type of this argument, i.e., \*(L"float\*(R", \*(L"double\*(R", \*(L"int\*(R", \*(L"char *\*(R", or \*(L"<class
+name> *\*(R" or various combinations involving \*(L"&\*(R", \*(L"*\*(R", and \*(L"const\*(R". All typedefs
+have been translated to the basic types or class names, and \*(L"[]\*(R" is translated
+to \*(L"*\*(R". Otherwise, no other modifications have been made.
+.IP "basic_type" 4
+.IX Item "basic_type"
+Same as the \*(L"type\*(R" field, except that the \*(L"const\*(R" qualifiers have been
+stripped, a trailing '&' has been deleted, and a trailing '*' has been
+deleted if this is an array type or if it's a basic type like 'double',
+\&'int', etc., which we recognize.
+.IP "dimension" 4
+.IX Item "dimension"
+The dimensions of this array argument. This is a reference to a list of
+dimensions. Each element of the list must be the name of an integer argument
+to the C function or else a decimal integer. If this argument is not an array,
+then this field will still be present but will contain no elements.
+.IP "vectorize" 4
+.IX Item "vectorize"
+Whether this argument may be supplied as a vector. If so, the wrapper
+generator will automatically \*(L"vectorize\*(R" the function in the sense that \s-1MATLAB\s0
+functions like \*(L"sin\*(R" or \*(L"cos\*(R" are vectorized.
+.IP "c_var_name" 4
+.IX Item "c_var_name"
+The variable name which contains the argument which is passed to the C
+function. The c_var_name is guaranteed not to be the same as the argument name
+itself, to avoid conflict with the argument declaration of the function.
+.Sp
+If the argument is to be vectorized, or if the argument is an array,
+then c_var_name is the name of a pointer to an array of the argument.
+If the argument is not to be vectorized, then c_var_name is the name of
+a variable containing the argument.
+.IP "calculate" 4
+.IX Item "calculate"
+A C expression indicating how to calculate this particular variable from
+the dimension of other input/modify variables. This field will not be
+present if we don't see any way to calculate this variable from the
+other variables.
+.RE
+.RS 4
+.RE
+.PP
+The remaining elements in the associative array for each function describe the
+arguments to the C/\*(C+ function and its return type:
+.IP "returns" 4
+.IX Item "returns"
+A scalar containing the return type of the function. This information is also
+contained in the \*(L"retval\*(R" entry in the \*(L"args\*(R" array.
+.IP "argnames" 4
+.IX Item "argnames"
+A list containing the name of each argument in order in the C function's
+argument list. If no name was specified in the prototype, a name is generated
+for it, since our entire scheme depends on each argument having a unique name.
+.IP "vectorize" 4
+.IX Item "vectorize"
+Whether a vectorized wrapper function should be generated at all, i.e., a
+version which calls the C function once for each element of scalar arguments
+which are passed in a vector. Note that vectors may be supplied for some
+arguments but not others, depending on the \*(L"vectorize\*(R" field in the args array
+(see above).
+.IP "pass_by_pointer_reference" 4
+.IX Item "pass_by_pointer_reference"
+True if we are supposed to pass a pointer to the argument, not the argument
+itself. This is used for pass-by-reference when the type is \*(L"double *\*(R".
+This is always 0 for arrays, which are handled separately.
+.IP "Additional fields" 4
+.IX Item "Additional fields"
+The language module may add additional fields as necessary. Only those listed
+above are set up or used by the main wrapper generator code.
+.PP
+For example, if the function prototype is
+.PP
+.Vb 1
+\& double atan2(double y, double x)
+.Ve
+then
+.PP
+.Vb 32
+\& $global_functions{'atan2'} = {
+\& name => 'atan2',
+\& class => '',
+\& static => 0,
+\& inputs => ["y", "x"],
+\& modifies => [],
+\& outputs => ["retval"],
+\& args => { x => { source => "input",
+\& type => "double",
+\& basic_type => "double",
+\& dimension => [],
+\& c_var_name => "_arg_x",
+\& vectorize => 1,
+\& pass_by_pointer_reference = 0 },
+\& y => { source => "input",
+\& type => "double",
+\& basic_type => "double",
+\& dimension => [],
+\& c_var_name => "_arg_y",
+\& vectorize => 1,
+\& pass_by_pointer_reference = 0 },
+\& retval => { source => "output",
+\& type => "double",
+\& basic_type => "double",
+\& dimension => [],
+\& c_var_name => "_arg_retval",
+\& vectorize => 1,
+\& pass_by_pointer_reference = 0 } },
+\& returns => "double",
+\& argnames => ["x", "y"],
+\& vectorize => 1
+\& };
+.Ve
+This function is sufficiently simple that all of the relevant
+information can be filled out automatically, without any help from the
+user. For a more complicated function, it may not be possible to do so.
+For example, consider the following function (from the pgplot
+distribution):
+.PP
+.Vb 1
+\& void cpgbin(int nbin, const float *x, const float *data, Logical center);
+.Ve
+This function plots a histogram of the given data, where \f(CW\*(C`x[]\*(C'\fR are the
+abscissae values and \f(CW\*(C`data[]\*(C'\fR are the data values. \f(CW\*(C`Logical\*(C'\fR has been
+defined by a typedef statement earlier in the .h file to be \f(CW\*(C`int\*(C'\fR.
+.PP
+By default, the wrapper generator will interpret the \f(CW\*(C`float *\*(C'\fR as a
+declaration to pass a scalar argument by reference. In this case, this
+is not what is wanted, so the definition file must contain additional
+information:
+.PP
+.Vb 3
+\& void cpgbin(int nbin, const float *x, const float *data, Logical center);
+\& //%input x(nbin)
+\& //%input data(nbin)
+.Ve
+This tells us that the x and data arrays are the same size, which is given by
+nbin. With this information, then, the following will be produced:
+.PP
+.Vb 33
+\& $global_functions{'cpgbin'} = {
+\& name => 'cpgbin',
+\& inputs => ["x", "data", "center" ],
+\& modifies => [],
+\& outputs => [],
+\& args => { "nbin" => { source = "dimension",
+\& type = "int",
+\& basic_type = "int",
+\& dimension = [],
+\& vectorize = 0,
+\& pass_by_pointer_reference = 0 },
+\& "x" => { source = "input",
+\& type = "float *",
+\& basic_type = "float",
+\& dimension = ["nbin"],
+\& vectorize = 1,
+\& pass_by_pointer_reference = 0 },
+\& "data" => { source = "input",
+\& type = "float *",
+\& basic_type = "float",
+\& dimension = ["nbin"],
+\& vectorize = 1,
+\& pass_by_pointer_reference = 0 },
+\& "center" => { source = "input",
+\& type = "int",
+\& basic_type = "int",
+\& dimension = [],
+\& vectorize = 1,
+\& pass_by_pointer_reference = 0 } },
+\& returns => "void",
+\& argnames => ["nbin", "x", "data", "center" ],
+\& vectorize => 0
+\& };
+.Ve
+Note that since this function has no output arguments, we do not attempt
+to provide a vectorized version of it.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Gary Holt (holt@LNC.usc.edu).
+.PP
+The latest version of matwrap should be available from
+http://LNC.usc.edu/~holt/matwrap/.
Added: trunk/packages/matwrap/debian/matwrap.txt
===================================================================
--- trunk/packages/matwrap/debian/matwrap.txt 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/matwrap.txt 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1,1108 @@
+ * NAME
+ * FEATURES
+ * REQUIREMENTS
+ * USAGE
+ * DESCRIPTION
+ o Options
+ * Input files
+ o Unsupported C++ constructs
+ * Examples
+ * Support for different languages
+ o MATLAB 5
+ o Octave
+ o Tela
+ o A note on debugging
+ * Writing new language support modules
+ o The %function_def array
+ * AUTHOR
+
+
+
+NAME
+
+matwrap -- Wrap C++ functions/classes for various matrix languages
+
+
+
+FEATURES
+
+matwrap is a script to generate wrapper functions for matrix-oriented
+scripting languages so that C++ subroutines or member functions can be
+called. It doesn't support non-matrix-oriented scripting languages like perl
+and python and tcl because Dave Bezley's program SWIG is such a good wrapper
+generator for those languages. Someday I hope that all of the features in
+this wrapper generator are incorporated into SWIG, but since I don't
+understand SWIG well enough to do it myself, I'm releasing this separately.
+SWIG is available from http://bifrost.lanl.gov/~dmb/SWIG/ or
+http://www.cs.utah.edu/~beazley/SWIG/.
+
+matwrap can handle the following constructs:
+
+Ordinary functions
+ For example, suppose you have some functions defined in an .h file,
+ like this:
+
+ float fiddle(double arg);
+ double tweedle(int x, char *name);
+
+ You can access these directly from MATLAB by using the following:
+
+ matwrap -language matlab -o myfuncs_wrap.c fiddle.h
+ cmex myfuncs.o myfuncs_wrap.c -o myfuncs_wrap
+
+ Then, in MATLAB, you can do the following:
+
+ y = tweedle(3, 'Hello, world');
+ A = fiddle([3, 4; 5, 6];
+
+ Note especially the last statement, where instead of passing a scalar
+ as the argument, we pass a matrix. The c function fiddle() is called
+ repeatedly on each element of the matrix and the result is returned as
+ a 2x2 matrix.
+
+ Floats, doubles, char *, integer, unsigned, and pointers to structures
+ may be used as arugments. Support for other data types (e.g., various
+ C++ classes) is possible and may be easily added since the modules have
+ been written for easy extensibility. Function pointers are not
+ currently supported in any form. C++ operator definitions are not
+ supported either.
+
+C++ classes
+ You can access public member functions and simple public data members
+ of classes. For example,
+
+ class ABC {
+ public:
+ ABC(int constructor_arg);
+ void do_something(float number, int idx);
+ double x;
+ };
+
+ From MATLAB or a similar language, you would access this structure like
+ this:
+
+ ABC_ptr = ABC_new(3); % Call the constructor and return a pointer.
+ ABC_do_something(ABC_ptr, pi, 4); % Call the member function.
+ abc_x = ABC_get_x(ABC_ptr); % Get the value of a data member.
+ ABC_set_x(ABC_ptr, 3.4); % Set the data member.
+ ABC_delete(ABC_ptr); % Discard the structure.
+
+ Accessing data members is often extremely useful when you are
+ attempting to figure out why your code returns 27.3421 when it ought to
+ return 4.367.
+
+ The same thing will work for C structs--the only difference is that
+ they have only data members and no member functions.
+
+ Only public members are accessible from the scripting language.
+ Operator overloading and function overloading are not supported.
+ Function pointers are not supported.
+
+Arrays
+ You can also call functions that take arrays of data, provided that
+ they accept the arrays in a standard format. For example, suppose you
+ want to use the pgplot distribution to make graphs (e.g., if you're
+ using a scripting language that doesn't have good graphing capability).
+ The following function generates a histogram of data:
+
+ void cpgbin(int nbin, const float *x, const float *data, Logical center);
+
+ Here x[] are the abscissae values and data[] are the data values. If
+ you add to your .h file a simple statement indicating the dimensions of
+ the matrices, like this:
+
+ //%input x(nbin), data(nbin)
+
+ then from a MATLAB-like language, you can call this function like this:
+
+ cpgbin(X, Data, 1)
+
+ where X and Data are vectors. The nbin argument is determined from the
+ length of the X and Data vectors automatically (and the wrapper
+ generator makes sure they are of the same length!).
+
+ This will also work with multidimensional arrays, provided that the
+ function expects the array to be a single one-dimensional array which
+ is really the concatenation of the columns of the two-dimensional
+ array. (This is normal for Fortran programs.) The first array dimension
+ varies the fastest, the second the next fastest, etc. (This is column
+ major order, as in Fortran, not row-major order, as in C. Most
+ matlab-like languages use the Fortran convention. Tela is an
+ exception.)
+
+ You may only use variable name or a constant for the array dimension.
+ You can also use expressions like 2*nbin or 2*nbin+1. If the expression
+ is sufficiently simple, the wrapper generator will determine the values
+ of any integer values (like nbin in this example) from the dimension of
+ the input arrays, so they do not have to be specified as an argument.
+
+
+
+REQUIREMENTS
+
+A C++ compiler
+ In theory, this could be made to work with an ANSI C compiler, but I
+ haven't tried to yet. Currently, you must have a full C++ compiler.
+ I've used primarily gcc and I tested very briefly with DEC's cxx.
+
+alloca()
+ If you are using matlab, then you can tell matwrap to use mxCalloc
+ instead of alloca by specifying -use_mxCalloc somewhere on the command
+ line. Otherwise, you must have a compiler that supports alloca(). (gcc
+ does.)
+
+ alloca() is usually a little more efficient than mxCalloc(). It
+ allocates space on the stack rather than the heap. Unfortunately, you
+ may have a limited stack size, and so alloca() may fail for large
+ temporary arrays. In this case, you may need to issue a command like
+
+ unix('unlimit stacksize')
+
+ or else use the -use_mxCalloc option.
+
+A relatively recent version of perl
+ I've tested this only with perl 5.004. Check out http://www.perl.com/
+ for how to get perl.
+
+
+
+USAGE
+
+ matwrap -language languagename [-options] infile1.h infile2.h
+
+ matwrap -language languagename [-options] \
+ -cpp cxx [-options_to_C_compiler] infile.cxx
+
+
+
+DESCRIPTION
+
+Using the first form, without the -cpp flag, files are parsed in the order
+listed, so you should put any files with required typedefs and other
+definitions first. These files are #included by the generated wrapper code;
+in fact, they are the only files which are #included. This form can be used
+1) if you don't have any #ifs or macros that confuse the parser in your
+code; 2) if you can easily list all of the include files that define the
+relevant structures.
+
+Alternatively, you can use the -cpp flag to have matwrap run the C
+preprocessor on your files. This means that all of the relevent definitions
+of types will be found, however deeply they are nested in the #include
+hierarchy. It also means that wrapper generation runs considerably slower.
+Matwrap will attempt to guess which files need to be #included, but it may
+guess wrong.
+
+Overloaded functions and definitions of operators are not supported. C++
+classes are supported (this is the main reason for this script). Member
+functions may be called, and member fields may be accessed.
+
+
+
+Options
+
+-cpp
+ Run the C preprocessor on your file before parsing it. This is
+ necessary if you are using any #ifdefs in your code. Following the -cpp
+ option should be a complete compiler command, e.g.,
+
+ matwrap -language octave -o myfile_wrap.cxx \
+ -cpp g++ -Iextra_includes -Dmy_thingy=3 myfile.cxx
+
+ All words after the -cpp option are ignored (and passed verbatim to the
+ compiler), so you must supply a -o option before the -cpp. Note that -o
+ and similar compiler options relevant for actual compilation are
+ ignored when just running the preprocessor, so you can substitute your
+ actual compilation command without modification. If you do not supply
+ the -E flag in the compiler command, it will be inserted for you
+ immediately after the name of the compiler. Also, the -C option is
+ added along with the -E option so that any comments can be processed
+ and put into the documentation strings. (As far as I know all compilers
+ support -C and -E but undoubtably this won't work well with some. It
+ works fine with gcc.)
+
+ When run in this way, matwrap does not generate wrappers for any
+ functions or classes defined in files located in /usr/include or
+ /usr/local/include or in subdirectories of */gcc-lib. (Most likely you
+ don't want to wrap the entire C library!) You can specify additional
+ directories to ignore with the -cpp_ignore option. If you really want
+ to wrap functions in one of those .h files, either copy .h file or just
+ the relevant function definitions into a file in another directory
+ tree. You can also restrict the functions which are wrapped using the
+ -wrap_only option (see below).
+
+-cpp_ignore filename_or_directory
+ Ignored unless used with the -cpp option. Causes functions defined in
+ the given file name or in include files in the given directory or
+ subdirectories of it not to be wrapped. By default, functions defined
+ in /usr/include, /usr/local/include, or */gcc-lib are not wrapped.
+
+-o file
+ Specify the name of the output file. If this is not specified, the name
+ is inferred from the input files. Some language modules (e.g., MATLAB)
+ will not infer a file name from your source files (this is for your
+ protection, so we don't accidentally wipe out a .c file with the same
+ name). If you use the -cpp option, you must also specify the -o option
+ before the -cpp option.
+
+-language
+ Specify the language. This option is mandatory.
+
+-wraponly
+ Specify a list of global functions or variables or classes to wrap. The
+ list extends to the end of the command line, so this must be the last
+ option. Definitions of all functions and classes not explictly listed
+ are ignored. This allows you to specify all the .h files that you need
+ to define all the types, but only to wrap some of the functions.
+
+ Global functions and variables are specified simply by name. Classes
+ are specified by the word 'class' followed by the class name. For
+ example,
+
+ matwrap -language matlab myfile.h \
+ -wraponly myglobalfunc class myclass
+
+
+
+Input files
+
+Input files are designed to be your ordinary .h files, so your wrapper and
+your C++ sources are never out of date. In general, the wrapper generator
+does the obvious thing with each different kind of type. For example,
+consider the function declaration:
+
+ double abcize(float a, int b, char *c, SomeClass *d);
+
+This will pass a single-precision floating point number as argument a
+(probably converting from double precision or integer, depending on what the
+interpreted language stored the value as). An integer is passed as argument
+b (probably converted from a double precision value). A null-terminated
+string is passed as argument c (converted from whatever weird format the
+language uses). The argument d must be a pointer value which was returned by
+another function.
+
+Vectorization is automatically performed, so that if you pass a matrix of m
+by n inputs as argument a and arguments b and c as either scalars or m by n
+matrices, then the function will be called m*n times and the result will be
+an m by n matrix. By default, a function is vectorized if it has both inputs
+and outputs (see under //%vectorize below). Most matrix languages do not
+support vectors of strings in a natural way, so char * arguments are not
+vectorized.
+
+Passing arguments by reference is handled in the expected way. For example,
+given the declaration
+
+ void fortran_sub(double *inarg1, float *inarg2);
+
+pointers to double and single precision numbers will be passed to the
+subroutine instead of the numbers themselves.
+
+This creates an ambiguity for the type char *. For example, consider the
+following two functions:
+
+ void f1(char *a);
+ void f2(unsigned char *b);
+
+Matwrap assumes that the function f1 is passed a null terminated string,
+despite the fact that the argument a could be a pointer to a buffer where f1
+returns a character. Although this situation can be disambiguated with
+proper use of the const qualifier, matwrap treats char * and const char * as
+identical since many programs don't use const properly. Matwrap assumes,
+however, that unsigned char * is not a null terminated string but an
+unsigned char variable passed by reference. You can also force it to
+interpret char * as a signed char passed by reference by specifying the
+qualifier //%input a(1) (see below).
+
+If you want to pass arguments as arrays, or if there are outputs other than
+the return value of the function, you must declare these explicitly using
+the //%input or //%output qualifiers. All qualifiers follow the definition
+of the function (after the ; or the closing } if it is an inline function).
+Valid qualifiers are:
+
+//%novectorize_type type1, type2, ...
+ Specifies that all arguments of the given types should not be
+ vectorized even if it is possible. This could be useful if you have a
+ class which there will be only one copy of, so it is pointless to
+ vectorize. (This qualifier may be present anywhere in the file.)
+
+//%novectorize
+ Following the definition of a global function or member function,
+ directs matwrap not to try to vectorize the function. For some
+ functions, vectorization simply doesn't make sense. By default, matwrap
+ won't vectorize a function if it has no output arguments or no input
+ arguments.
+
+//%vectorize
+ Following the definition of a global function or member function,
+ directs matwrap to vectorize the function. By default, matwrap won't
+ vectorize a function if it has no output arguments or no input
+ arguments. This is normally what you want, but but sometimes it makes
+ sense to vectorize a function with no output arguments.
+
+//%nowrap
+ Don't wrap this function. It will therefore not be callable directly
+ from your scripting language.
+
+//%name new_name
+ Specify a different name for the function when it is invoked from the
+ scripting language.
+
+//%input argname(dim1, dim2, ...), argname(dim)
+ Following the declaration of a global function or member function,
+ declares the dimensions of the input arguments with the given name.
+ This declaration must immediately follow the prototype of the function.
+ Dimension strings may contain any arbitrary C expression. If the
+ expression is sufficiently simple, e.g., ``n'' or ``n+1'' or ``2*n'',
+ and if the expression includes another argument to the function (``n''
+ in this case), then the other argument will be calculated from the
+ dimensions of the input variable and need not be specified as an
+ argument in the scripting language.
+
+ For example, if you have a function which is declared like this:
+
+ void myfunc(int n, double *x, double *y);
+ //%input x(3*n+4)
+ //%output y(n*(n+1)/2)
+
+ n would be calculated from the dimension of the variable x and then
+ used to compute the size of the output array. So you would call the
+ function like this:
+
+ y = myfunc(x)
+
+ On the other hand, if you had a specification like this:
+
+ void return_diag(int n, double *x, double *y);
+ //%input x(n*(n+1)/2)
+ //%output y(n)
+
+ then n will have to be explicitly specified because it is too difficult
+ to calculate:
+
+ y = myfunc(n, x)
+
+//%modify argname(dim1, dim2, ...), argname(dim1)
+//%output argname(dim1, dim2, ...), argname(dim1)
+ Same as //%input except that this also tags the variables as modify or
+ output variables. If you don't specify a dimension expression (e.g.,
+ ``//%output x'') then the variable is tagged as a scalar output
+ variable. (This is the proper way to tell matwrap to make an argument
+ an output argument.)
+
+
+
+Unsupported C++ constructs
+
+Function overloading
+Operator definition
+Function and member function pointers
+ It would be really nice to support these, but I think it's also really
+ hard. Maybe someday.
+
+Two-dimensional arrays using a vector of pointers
+ You can use two-dimensional arrays as long as they are stored
+ internally as a single long vector, as in Fortran. In this case, the
+ array declaration would be float *x, and the i,j'th element is accessed
+ by x[j*n+i]. You cannot use two dimensional arrays if they are declared
+ like float **x and accessed like x[i][j]. Unfortunately, the Numerical
+ Recipes library uses this format for all its two-dimensional matrices,
+ so at present you can only wrap Numerical Recipes functions which take
+ scalars or vectors. This restriction might be lifted in the future.
+
+Arrays with an offset
+ The Numerical Recipes code is written so that most of its indices begin
+ at 1 rather than at 0, I guess because its authors are Fortran junkies.
+ This causes a problem, because it means that the pointer you pass to
+ the subroutine is actually not the beginning of the array but before
+ the beginning. You can get around this restriction by passing an extra
+ blank element in your array. For example, suppose you want to wrap the
+ function to return the Savitzky-Golay filter coefficients:
+
+ void savgol(float c[], int np, int nl, int nr, int ld, int m);
+
+ where the index in the array C<c> is declared to run from 1 to np.
+ You'd have to declare the array like this:
+
+ //%output c(np+1)
+
+ and then ignore the first element. Thus from MATLAB you'd call it with
+ the following sequence:
+
+ savgol_coefs = savgol(np, nl, nr, ld, m);
+ savgol_coefs = savgol_coefs(2:length(savgol_coefs));
+ % Discard the unused first element.
+
+Passing structures by value or C++ reference
+ In other words, if Abc is the name of a class, declarations like
+
+ void myfunc(Abc x);
+
+ or
+
+ void myfunc(Abc &x);
+
+ won't work. However, you can pass a pointer to the class:
+
+ void myfunc(Abc *x);
+
+ The wrapper generator will do the type checking and it even handles
+ inheritance properly.
+
+
+
+Examples
+
+For more examples, see the subdirectories of share/matwrap/Examples in the
+distribution. This includes a wrapper for the entire PGPLOT library
+(directory pgplot) and a sample C++ simulator for an neuron governed by the
+Hodgkin-Huxley equations (directory single_axon).
+
+
+
+Support for different languages
+
+
+
+MATLAB 5
+
+Currently, you must compile the generated wrapper code using C++, even if
+you are wrapping only C functions with no C++ classes. You can compile your
+C functions using C as you please; you may have to put a extern "C" { }
+statement in the .h file. This restriction may be lifted in the future.
+
+The default maximum number of dimensions supported is four. You can change
+this by modifying the $max_dimensions variable near the top of the file
+share/matwrap/wrap_matlab.pl in the distribution.
+
+Specify -langauge matlab on the command line to use the matlab code
+generator. You MUST also use -o to specify the output file name. (This is
+because matlab wrappers have an extension of .c and if we infer the file
+name from the name of include files, it's quite likely that we'll wipe out
+something that shouldn't be wiped out.)
+
+An annoying restriction of MATLAB is that only one C function can be defined
+per mex file. To get around this problem, the wrapper generator defines a C
+function which takes an extra parameter, which is a code for the function
+you actually want to call. It also defines a series of MATLAB stub functions
+to supply the extra parameter. Each of these must be placed into its own
+separate file (because of another MATLAB design inadequacy) so wrapper
+generation for MATLAB may actually create hundreds of files if you have a
+lot of member functions.
+
+You can specify where you want the .m files to be placed using the -outdir
+option, like this:
+
+ matwrap -language matlab -outdir wrap_m \
+ myfuncs.h -o myfuncs_matlab.c
+
+ mex -f mex_gcc_cxx myfunc
+
+This will create dozens of tiny .m files which are placed into the directory
+wrap_m, and a single mexfile with the name myfuncs. DO NOT CHANGE THE NAME
+OF THE MEX FILE! The .m files assume that the name of the C subroutine is
+the name of the file, in this case, myfuncs. (You can move the mex file to a
+different directory, if you want, so long as it is still in your
+matlabpath).
+
+To wrap C++ functions in MATLAB, you'll probably need to specify the -f
+option to the mex command, as shown above. You'll need to create the mex
+options file so that the appropriate libraries get linked in for C++. For
+example, on the machine that I use, I created the file mex_gcc_cxx which
+contains the following instructions:
+
+ . mexopts.sh # Load the standard definitions.
+ CC='g++'
+ CFLAGS='-Wall'
+ CLIBS='-lg++ -lstdc++ -lgcc -lm -lc'
+ COPTIMFLAGS='-O2 -g'
+ CDEBUGFLAGS='-g'
+
+This works with other C++ compilers if you set CC and CLIBS to use the
+appropriate compiler and libraries (e.g., CLIBS=-lcxx and CC=cxx for cxx on
+Digital Unix).
+
+By default, matwrap uses alloca() to allocate temporary memory. If for some
+reason you want to use mxCalloc(), specify -use_mxCalloc somewhere on the
+command line.
+
+The following features of matlab are not currently supported:
+
+Vectors of strings
+Structures
+ It would be nice to be able to return whole C++ structures as MATLAB
+ structures. Maybe this will happen in the future.
+
+Cell arrays
+ Do not try to pass a cell array instead of a numeric array to a C++
+ function. It won't work; the wrapper code does not support it.
+
+One quirk of operation which can be annoying is that MATLAB likes to use row
+vectors instead of column vectors. This can be a problem if you write some C
+code that expects a vector input, like this:
+
+ void myfunc(double *d, int n_d); //%input d(n_d)
+
+Suppose now you try to invoke it with the following matlab commands:
+
+ >> myfunc(0:0.1:pi)
+
+The range 0:0.1:pi is a row vector, not a column vector. As a result, a
+dimension error will be returned if my_func is not vectorized (which would
+be the default with these arguments), because the function is expecting an
+n_d by 1 array instead of a 1 by n_d array. If you allowed myfunc to be
+vectorized, then myfunc() will be called once for each element of the range,
+with n_d = 1. This is almost certainly not what you wanted. I haven't yet
+figured out a good way to handle this. Anyway, be careful, and always
+transpose ranges, like this:
+
+ >> myfunc((0:0.1:pi)')
+
+
+
+Octave
+
+Octave is much like matlab in that it only allows one callable function to
+be put into a .oct file. The function in the .oct file therefore takes an
+extra argument which indicates which C++ function you actually wanted to
+call. Fortunately, unlike matlab, octave can define more than one function
+per file so we don't have to have a separate .m file for each function.
+Instead, the functions are all placed into a separate file whose name you
+specify on the command line with the -stub option.
+
+To compile an octave module, you would use the following command:
+
+ matwrap -language octave -stub myfuncs_stubs.m \
+ myfuncs.h -o myfuncs_octave.cc
+ mkoctfile myfuncts_octave
+
+Note that you can't do this unless you have the mkoctfile script installed.
+mkoctfile is not available in some binary distributions.
+
+Then, in octave, you must first load the stub functions:
+
+ octave:1> myfuncs_subs
+ octave:2> # Now you may call the functions.
+
+DO NOT CHANGE THE NAME OF THE .oct FILE! Its name is written into the stub
+functions. You can move the file into a different directory, however, so
+long as the directory is in your LOADPATH.
+
+The mkoctfile script for octave versions below 2.0.8 has an annoying
+restriction that prevents additional libraries from being linked into your
+module if your linker is sensitive to the order of the libraries on the
+command line. The mkoctfile script for versions 2.0.8 and 2.0.9 in theory
+supports libraries on the command line but it doesn't work. There's a shell
+script called share/matwrap/fix_mkoctfile.sh which produces a modified shell
+script called mkoctfile_fixed that supports command line libraries. (If you
+create run any of the examples, mkoctfile_fixed is created for you
+automatically.) You just use it like this:
+
+ fix_mkoctfile.sh . # Create mkoctfile_fixed in current dir.
+ mkoctfile_fixed myprog -lmylib1 -lmylib2
+
+If you compile your source code to .o or .a files separately, on some
+systems you may need to force the compiler to make position-independent code
+(-fPIC option to gcc). Remember you are making a shared library, so follow
+the rules for making shared libraries on your system. The mkoctfile script
+should do this for you automatically if you have it compile your source
+files, but if you compile to .o files first and give these to mkoctfile, you
+may have to be careful to specify the appropriate flags on the cc or c++
+command line.
+
+Octave doesn't seem to provide a good way to support modify variables, i.e.,
+variables that are taken as input and modified and returned as output. For
+example, suppose you have the function
+
+ void myfunc(float *a, int a_n); //%modify a(a_n)
+
+which takes the array a as input, does something to it, and returns its
+output in the same place. In octave, this would be called as:
+
+ a_out = myfunc(a_in);
+
+rather than as
+
+ myfunc(a);
+
+as it might be from other languages.
+
+Octave has the same quirk as MATLAB in the usage of row vectors where
+matwrap expects column variables. See the end of the section on MATLAB for
+details.
+
+
+
+Tela
+
+Tela (Tensor Language) is a MATLAB clone which is reputed to be considerably
+faster than MATLAB and has a number of other nice features biassed toward
+PDEs. It can be found at http://www.geo.fmi.fi/prog/tela.html.
+
+Specify -language tela to invoke the Tela wrapper generator, like this:
+
+ matwrap -language tela myfuncs.h -o myfuncs.ct
+ telakka myfuncs.ct other_files.o -o tela
+
+That's pretty much all there is to it. Tela doesn't support arrays of
+strings so char * parameters are not vectorized. Otherwise, just about
+everything should work as you expect.
+
+WARNING: Tela stores data internally using a row-major scheme instead of the
+usual column-major ordering, so the indexes of Tela arrays are in reverse
+order from the index specification order in the %input, %output, and %modify
+declarations. Sorry, it wasn't my idea.
+
+The tela code generator does not currently support short or unsigned short.
+
+
+
+A note on debugging
+
+Since both MATLAB and octave use dynamically loadable libraries, it can be
+tricky to debug your C++ code. MATLAB has a documented way of making a
+standalone program, but I found this extremely inconvenient. If you have
+gdb, it is sometimes easier to use the ``attach'' command if your operating
+system supports it. (Digital Unix does; I do not know about other operating
+systems.) Start up MATLAB or octave as you normally would, and load the
+shared library by calling some function in it that doesn't cause it to
+crash. (Or, put a ``sleep(30)'' in an appropriate place in the code, so
+there is enough time for you to catch it between when it loads the library
+and when it crashes.) Then while MATLAB or octave is at the prompt, attach
+to the octave/MATLAB process using gdb, set your breakpoints, allow MATLAB
+to continue, type the command that fails, and debug away.
+
+
+
+Writing new language support modules
+
+Matlab 5, octave, and Tela are the only language modules that I've written
+so far. It's not hard to write a language module--most of the tricky stuff
+has been taken care of by the main wrapper generator program. It's just a
+bit tedious.
+
+The parsing in matwrap is entirely independent of the target language. The
+back end is supplied by one of several language modules, as specified by the
+-language option.
+
+The interface is designed to make it easy to generate automatically
+vectorized functions. Vectorization is done automatically by the matwrap
+code, independent of the language module. All subroutines except those with
+no output arguments or no input arguments are vectorized except as
+explicitly requested.
+
+Typically, the function_start() function in the language module will output
+the function header to the file and declare the arguments to the function.
+After this, the wrapper generator writes C code to check the dimensions of
+the arguments.
+
+After checking the dimensions of all variables, the value of the variable is
+obtained from the function get_c_arg_scalar/get_c_arg_ptr. This returns a
+pointer to the variable, so if it is vectorized we can easily step through
+the pointer array. Note that if the desired type is ``float'' and the input
+is an array of ``double'', then the language module will have to make a
+temporary array of doubles. Output variables are then created by calling
+make_output_scalar/make_output_ptr.
+
+Next, the C function is called as many times as required.
+
+Next, any modify/output arguments need to have the new values put back into
+the scripting language variables. This is accomplished by the
+put_val_scalar/put_val_ptr function. Temporary arrays may be freed here.
+Note that put_val is not called for input arguments so temporary arrays of
+input arguments will have to be freed some other way.
+
+Finally, the function function_end is called to do any final cleanup and
+terminate the function definition.
+
+The following functions and variables must be supplied by the language
+module. They should be in a package whose name is the same as the argument
+to the -language option.
+
+$max_dimensions
+ A scalar value indicating the maximum number of dimensions this
+ language can handle (or, at least, the maximum number of dimensions
+ that our scripts will handle). This is 2 for languages like Matlab or
+ Octave which can only have 2-dimensional matrices.
+
+arg_pass(\%function_def, $argname)
+ A C or C++ expression used to pass the argument to another function
+ which does not know anything about the type of the argument. For
+ example, in the MATLAB module this function returns an expression for
+ the mxArray type for a given argument.
+
+arg_declare("arg_name_in_arglist")
+ This returns a C/C++ declaration appropriate for the argument passed
+ using arg_pass. For example, in the MATLAB module this function returns
+ ``mxArray *arg_name_in_arglist''.
+
+declare_const("constant name", "class name", "type")
+ Output routines to make a given constant value accessible from the
+ interpreter. If ``class name'' is blank, this is a global constant.
+
+ None of the language modules currently support definition of constants,
+ but this function is called.
+
+error_dimension(\%function_def, $argname)
+ A C statement (including the final semicolon, if not surrounded by
+ braces) which indicates that an error has occured because the dimension
+ of argument $argname was wrong.
+
+finish()
+ Called after all functions have been wrapped, to close the output file
+ and do whatever other cleanup is necessary.
+
+function_start(\%function_def)
+ This should prepare a documentation string entry for the function and
+ it should set up the definition of the function. It should return a
+ string rather than printing the result.
+
+ %function_def is the array defining all the arguments and outputs for
+ this function. See below for its format.
+
+function_end(\%function_def)
+ Returns a string which finishes off the definition of a function
+ wrapper.
+
+get_outfile(\@files_processed)
+ Get the name of an output file. This subroutine is only called if no
+ output file is specified on the command line. \@files_processed is a
+ list of the .h files which were parsed.
+
+get_c_arg_scalar(\%function_def, $argname)
+ Returns C statements to load the current value of the given argument
+ into the C variable $function_def{args}{$argname}{c_var_name}. The
+ variable is guaranteed to be either a scalar or an array with
+ dimensions 1,1,1... (depending on the scripting language, these may be
+ identical).
+
+get_c_arg_ptr(\%function_def, $argname)
+ Returns C statements to set up a pointer which points to the first
+ value of a given argument. It is possible that the argument may be a
+ scalar, in which case we just want a pointer to that scalar value.
+ (This happens only for vectorizable arguments when the vectorization is
+ not used on this function call.) The dimensions are guaranteed to be
+ correct. The type of the argument should be checked. The pointer value
+ should be stored in the variable
+ $function_def{args}{$argname}{c_var_name}.
+
+ The pointer should actually point to the array of all the values of the
+ variable. The array should have the same number of elements as the
+ argument, since to vectorize the function, the wrapper function will
+ simply step through this array. If we want a float type and the input
+ vector is double or int, then a temporary array must be made which is a
+ copy of the double/int arrays.
+
+get_size(\%function_def, $argname, $n)
+ Returns a C expression which is the size of the $n'th dimension of the
+ given argument. Dimension 0 is the least-significant dimension.
+
+initialize($outfile, \@files_processed, \@cpp_command, $include_str)
+ Write out header information.
+
+ $outfile The name of the output file. This file should
+ be opened, and the function should return the
+ name of a file handle (qualified with the
+ package name, e.g., "matlab::OUTFILE").
+
+ @files A list of files explicitly listed on the command
+ line. This will be a null array if no files
+ were explicitly listed.
+
+ @cpp_command The command string words passed to the C
+ preprocessor, if the C preprocessor was run.
+ Otherwise, this will be a null array.
+
+ $include_str A string of #include statements which represents
+ our best guess as to the proper files to include
+ to make this compilation work.
+
+ This function also should write out C++ code to define the following
+ functions:
+
+ int _n_dims(argument) Returns number of dimensions.
+ int _dim(argument, n) Returns the size in the n'th dimension,
+ where 0 is the first dimension.
+
+make_output_scalar(\%function_def, $argname)
+ Return C code to create the given output variable. The output variable
+ will be a scalar.
+
+make_output_ptr(\%function_def, $argname, $n_dimensions, @dimensions)
+ Return C code to set up a pointer to where to store the values of the
+ output variable. $n_dimensions is a C expression, not necessarily a
+ constant. @dimensions is a list of C expressions that are the sizes of
+ each dimension. There may be more values in @dimensions than are
+ needed.
+
+n_dimensions(\%function_def, $argname)
+ Returns a C expression which is the number of dimensions of the
+ argument whose name is $argname.
+
+pointer_conversion_functions()
+ Returns code to convert to and from pointer types to the languages
+ internal representation, if any special code is needed. If this
+ subroutine is not called, then there are no class types and pointers
+ will not need to be handled.
+
+parse_argv(\@ARGV)
+ Scan the argument list for language-specific options. This is called
+ after the -language option has been parsed and removed from the @ARGV
+ array.
+
+put_val_scalar(\%function_def, $argname)
+ Returns C code to take the value from the C variable whose name is
+ given by $function_def{args}{$argname}{c_var_name} and store it back in
+ the scripting language scalar variable.
+
+put_val_ptr(\%function_def, $argname)
+ Returns C code to take the value from the C array whose name is given
+ by $function_def{args}{$argname}{c_var_name} and store it back in the
+ scripting language array at the specified index. The pointer
+ $function_def{args}{$argname}{c_var_name} was set up by either
+ get_c_arg or make_output, depending on whether this is an input/modify
+ or an output variable.
+
+
+
+The %function_def array
+
+Many of these arguments require a reference to the %function_def associative
+array. This array defines everything that is known about the function.
+
+First, there are a few entries that describe the interface to the scripting
+language:
+
+name
+ The name of the function.
+
+class
+ The class of which this is a member function. This element will be
+ blank if it is a global function.
+
+script_name
+ The name of the function in the scripting language. If this field is
+ blank, then the name of the function should be generated from the
+ ``class'' and ``name'' fields. This field is set by the %name
+ directive.
+
+static
+ True if this is a static member function. Non-static member functions
+ will have the class pointer specified as the first argument in the
+ argument list.
+
+inputs
+ A list of the names of arguments to the scripting language function
+ which are only for input. Argument names are generated from the
+ corresponding argument names in the C function prototype.
+
+modifies
+ A list of the names of arguments to the scripting language function
+ which are for both input and output. Argument names are generated from
+ the corresponding argument names in the C function prototype.
+
+outputs
+ A list of the names of arguments to the scripting language function
+ which are for output. Argument names are generated from the
+ corresponding argument names in the C function prototype. ``retval'' is
+ used as the name of the return value of the function, if there is a
+ return value.
+
+args
+ An associative array indexed by the argument name which contains
+ information about each argument of the function. Note that there may be
+ more arguments in this associative array than in the
+ inputs/modifies/outputs arrays because some of the arguments to the
+ function may be merely the dimension of arrays, which are not arguments
+ in the scripting language since they can be determined by other means.
+
+ Note that there will also be an entry in the args array for ``retval''
+ if the function has a return value, since the return value is treated
+ as an output argument.
+
+ The fields in this associative array are:
+
+ source
+ Whether this is an ``input'', ``output'', or ``modify'' variable,
+ or whether it can be calculated from the ``dimension'' of another
+ variable. These are the only legal values for this field.
+
+ type
+ The type of this argument, i.e., ``float'', ``double'', ``int'',
+ ``char *'', or ``<class name> *'' or various combinations
+ involving ``&'', ``*'', and ``const''. All typedefs have been
+ translated to the basic types or class names, and ``[]'' is
+ translated to ``*''. Otherwise, no other modifications have been
+ made.
+
+ basic_type
+ Same as the ``type'' field, except that the ``const'' qualifiers
+ have been stripped, a trailing '&' has been deleted, and a
+ trailing '*' has been deleted if this is an array type or if it's
+ a basic type like 'double', 'int', etc., which we recognize.
+
+ dimension
+ The dimensions of this array argument. This is a reference to a
+ list of dimensions. Each element of the list must be the name of
+ an integer argument to the C function or else a decimal integer.
+ If this argument is not an array, then this field will still be
+ present but will contain no elements.
+
+ vectorize
+ Whether this argument may be supplied as a vector. If so, the
+ wrapper generator will automatically ``vectorize'' the function in
+ the sense that MATLAB functions like ``sin'' or ``cos'' are
+ vectorized.
+
+ c_var_name
+ The variable name which contains the argument which is passed to
+ the C function. The c_var_name is guaranteed not to be the same as
+ the argument name itself, to avoid conflict with the argument
+ declaration of the function.
+
+ If the argument is to be vectorized, or if the argument is an
+ array, then c_var_name is the name of a pointer to an array of the
+ argument. If the argument is not to be vectorized, then c_var_name
+ is the name of a variable containing the argument.
+
+ calculate
+ A C expression indicating how to calculate this particular
+ variable from the dimension of other input/modify variables. This
+ field will not be present if we don't see any way to calculate
+ this variable from the other variables.
+
+The remaining elements in the associative array for each function describe
+the arguments to the C/C++ function and its return type:
+
+returns
+ A scalar containing the return type of the function. This information
+ is also contained in the ``retval'' entry in the ``args'' array.
+
+argnames
+ A list containing the name of each argument in order in the C
+ function's argument list. If no name was specified in the prototype, a
+ name is generated for it, since our entire scheme depends on each
+ argument having a unique name.
+
+vectorize
+ Whether a vectorized wrapper function should be generated at all, i.e.,
+ a version which calls the C function once for each element of scalar
+ arguments which are passed in a vector. Note that vectors may be
+ supplied for some arguments but not others, depending on the
+ ``vectorize'' field in the args array (see above).
+
+pass_by_pointer_reference
+ True if we are supposed to pass a pointer to the argument, not the
+ argument itself. This is used for pass-by-reference when the type is
+ ``double *''. This is always 0 for arrays, which are handled
+ separately.
+
+Additional fields
+ The language module may add additional fields as necessary. Only those
+ listed above are set up or used by the main wrapper generator code.
+
+For example, if the function prototype is
+
+ double atan2(double y, double x)
+
+then
+
+ $global_functions{'atan2'} = {
+ name => 'atan2',
+ class => '',
+ static => 0,
+ inputs => ["y", "x"],
+ modifies => [],
+ outputs => ["retval"],
+ args => { x => { source => "input",
+ type => "double",
+ basic_type => "double",
+ dimension => [],
+ c_var_name => "_arg_x",
+ vectorize => 1,
+ pass_by_pointer_reference = 0 },
+ y => { source => "input",
+ type => "double",
+ basic_type => "double",
+ dimension => [],
+ c_var_name => "_arg_y",
+ vectorize => 1,
+ pass_by_pointer_reference = 0 },
+ retval => { source => "output",
+ type => "double",
+ basic_type => "double",
+ dimension => [],
+ c_var_name => "_arg_retval",
+ vectorize => 1,
+ pass_by_pointer_reference = 0 } },
+ returns => "double",
+ argnames => ["x", "y"],
+ vectorize => 1
+ };
+
+This function is sufficiently simple that all of the relevant information
+can be filled out automatically, without any help from the user. For a more
+complicated function, it may not be possible to do so. For example, consider
+the following function (from the pgplot distribution):
+
+ void cpgbin(int nbin, const float *x, const float *data, Logical center);
+
+This function plots a histogram of the given data, where x[] are the
+abscissae values and data[] are the data values. Logical has been defined by
+a typedef statement earlier in the .h file to be int.
+
+By default, the wrapper generator will interpret the float * as a
+declaration to pass a scalar argument by reference. In this case, this is
+not what is wanted, so the definition file must contain additional
+information:
+
+ void cpgbin(int nbin, const float *x, const float *data, Logical center);
+ //%input x(nbin)
+ //%input data(nbin)
+
+This tells us that the x and data arrays are the same size, which is given
+by nbin. With this information, then, the following will be produced:
+
+ $global_functions{'cpgbin'} = {
+ name => 'cpgbin',
+ inputs => ["x", "data", "center" ],
+ modifies => [],
+ outputs => [],
+ args => { "nbin" => { source = "dimension",
+ type = "int",
+ basic_type = "int",
+ dimension = [],
+ vectorize = 0,
+ pass_by_pointer_reference = 0 },
+ "x" => { source = "input",
+ type = "float *",
+ basic_type = "float",
+ dimension = ["nbin"],
+ vectorize = 1,
+ pass_by_pointer_reference = 0 },
+ "data" => { source = "input",
+ type = "float *",
+ basic_type = "float",
+ dimension = ["nbin"],
+ vectorize = 1,
+ pass_by_pointer_reference = 0 },
+ "center" => { source = "input",
+ type = "int",
+ basic_type = "int",
+ dimension = [],
+ vectorize = 1,
+ pass_by_pointer_reference = 0 } },
+ returns => "void",
+ argnames => ["nbin", "x", "data", "center" ],
+ vectorize => 0
+ };
+
+Note that since this function has no output arguments, we do not attempt to
+provide a vectorized version of it.
+
+
+
+AUTHOR
+
+Gary Holt (holt@klab.caltech.edu).
+
+The latest version of matwrap should be available from
+http://www.klab.caltech.edu/~holt/matwrap/.
Added: trunk/packages/matwrap/debian/rules
===================================================================
--- trunk/packages/matwrap/debian/rules 2005-02-08 12:48:53 UTC (rev 18)
+++ trunk/packages/matwrap/debian/rules 2005-02-09 12:58:23 UTC (rev 19)
@@ -0,0 +1,78 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# debian/rules file for the Debian/GNU Linux matwrap package
+# Copyright 1999 - 2002 by Dirk Eddelbuettel <edd@debian.org>
+
+package = matwrap
+debtmp := $(shell pwd)/debian/tmp/usr
+
+# Uncomment this to turn on verbose mode.
+# export DH_VERBOSE=1
+
+build: build-stamp
+build-stamp:
+ dh_testdir
+ #$(MAKE)
+ pod2man share/$(package)/$(package).pod > debian/$(package).1
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+ #-$(MAKE) clean
+ #-$(MAKE) distclean
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+ $(MAKE) PREFIX=$(debtmp) install
+ # cleanups needed
+ rm -rvf $(debtmp)/mkoctfile_fixed \
+ $(debtmp)/share/matwrap/Examples/ \
+ $(debtmp)/share/matwrap/mkoctfile* \
+ $(debtmp)/share/matwrap/fix_mkoctfile.sh \
+ $(debtmp)/share/matwrap/matwrap.pod \
+ $(debtmp)/man/
+ # change $PREFIX to leave only trailing /usr
+ perl -p -i -e 's|/.*/debian/tmp||' $(debtmp)/bin/matwrap
+
+# Build architecture-independent files here.
+binary-indep: build install
+# dh_testversion
+ dh_testdir
+ dh_testroot
+# dh_installdebconf
+ dh_installdocs README TODO
+ dh_installexamples share/matwrap/Examples/*
+ ## remove zero-byte file (lintian)
+ rm -v $(debtmp)/share/doc/matwrap/examples/simple/demo.t
+# dh_installmenu
+# dh_installemacsen
+# dh_installpam
+# dh_installinit
+# dh_installcron
+ dh_installmanpages
+# dh_installinfo
+# dh_undocumented
+ dh_installchangelogs ChangeLog
+# dh_link
+ dh_compress
+ dh_fixperms
+# dh_suidregister
+ dh_installdeb
+ dh_perl
+ dh_gencontrol
+# dh_md5sums
+ dh_builddeb
+
+# Build architecture-dependent files here.
+binary-arch: build install
+# We have nothing to do by default.
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
+
Property changes on: trunk/packages/matwrap/debian/rules
___________________________________________________________________
Name: svn:executable
+ *