Next: userfunhelp() Up: User Function Help File Previous: type_codes   Contents


User(funName [,resource:resName][,control keyword phrases],arg1 [,...]),
  funName and resName CHARACTER scalars; control keyword phrases are any
  of callback:T, symbols:T, pointers:T and quiet:T; arg1, ... arguments
  to a user function; if argument is keyword phrase other than
  'protect:arg', it is returned, possibly modified.

Keywords: user functions, executing
User(FuncName, arg1, arg2, ...) executes a user function, that is, a
compiled routine external to MacAnova.  Quoted string or CHARACTER
scalar FuncName specifies the name of a user function whose code is in a
file previously loaded by loadUser().  arg1, arg2, ... are arguments
that will be passed to the function.  You must have a least one argument
in addition to FuncName and no more than 20 (13 in the Macintosh PPC
version).  Depending on the compiler and system, you may be required to
include leading or trailing underscore characters '_' in FuncName, say
User("foo_",...) or User("_foo", ...) instead of User("foo", ...).

A 68K version of MacAnova cannot execute a user function compiled for a

User(FuncName, quiet:T, arg1, ...) does the same except warning
messages, if any, are suppressed.

User(FuncName, callback:T, arg1, ...) specifies the function is known to
"call back" to MacAnova, that is, to execute functions internal to
MacAnova.  On a Macintosh, the type of user function (PPC or ordinary
68K) must match the version of MacAnova.  See topic 'callback_fun' in
file userfun.hlp (type userfunhelp(callback_fun)).

If the MacAnova version requires a 68881 math coprocessor, there can be
problems if a user function that makes call backs does not require a

User(FuncName, symbols:T, arg1, ...) specifies that all the arguments
are to be passed as complete MacAnova "symbols", including all dimension
information.  This should be used only with a user function specifically
written to make use of MacAnova symbols.

The PPC Macintosh version cannot pass symbol arguments to a 68K user

User(FuncName, pointers:T or F, arg1, ...) changes the default way
arguments are passed, either as "pointers" (pointers:T) or as "handles"
(pointers:F).  On all but Macintosh computers, the default is
pointers:T.  You are unlikely ever to need to use this keyword.

User(FuncName, resource:ResName, arg1, ...) specifies the name of the
PPC Macintosh resource containing the user function.  This option is not
needed in other versions and needed on a PPC only when the resource name
differs from the function name.

You can use more than one of the preceding keywords phrases together
(User("goo", resource:"foo",quiet:T,callback:T,x,result:0)).

On most systems, it is possible to include with a user function an
"arginfo" function that MacAnova can call to obtain information about
the user function.  The information includes the number of arguments
expected, their types and shapes expected (for example, CHARACTER
scalar, REAL matrix), and whether the function makes call backs or
expects "symbol" arguments (see above).  This allows automatic argument
checking.  If the function is compiled without an arginfo function,
using the wrong number or type of arguments will usually result in a
crash or other undesirable behavior.  In particular, a user function
will not be able to handle MacAnova symbol arguments unless it has been
specially written to be able to understand their structure.

You normally do not need to use keywords 'callback', 'symbols' and
'pointers' if the user function has an associated arginfo function which
is possible on all systems except protected mode DOS.

See topics user_fun and arginfo_fun in help file userfun.hlp for
information about the form of a user function and an arginfo function
(type userfunhelp(user_fun), say).

                       Interpretation of FuncName
Unix, Motif and Windows:
  FuncName should be the name of the function being called, possibly
  modified by a leading or trailing '_' (leading '_' when compiling for
  Windows with Borland C 4.5).  In Windows and Unix versions where it is
  known entry names start with '_', when the function is not found using
  the name as provided, a second search is made after prepending '_' to the
  name.  Thus if User("_foo", ...) would be successful, so will be
  User("foo", ... ).

Extended memory DOS (DJGPP):
  FuncName should be the same as the name of the .dxe file loaded by
  loadUser() that contains the code except that directory information
  and the extension ".dxe" may be omitted.  Thus after
  loadUser("../foo.dxe"), you can use any of User("../foo.dxe",...),
  User("foo.dxe",...) or User("foo",...).  When there is more than one
  file with the same name attached (for example, "/a/foo.dxe" and
  "/b/foo.dxe", you should use the complete path name.

PPC Macintosh user function
  FuncName is the name of the user function.  This will usually also be
  the name of the PPC code resource containing the user function.  If it
  is not, you need to include keyword phrase 'resource:ResName' as an
  argument, where ResName is a quoted string or CHARACTER scalar
  specifying the resource name.

68K Macintosh user function:
  FuncName should be the name of the 68K code resource containing the
  user function (only one user function per resource).  If
  'resource:ResName' is an argument, ResName must be identical with
  FunName.  It is an error to attempt to call a 68K user function that
  requires a 68881 or 68882 math coprocessor on a Macintosh without

                        User function arguments
All arguments except the function name and 'callback', 'quiet',
'symbols', 'pointers' and 'resource' keyword phrases are passed to the
user function as its arguments

Only copies of keyword phrase arguments are passed to a user function.
This means that the user function can modify these arguments without
danger of changing any MacAnova variable.

Non-keyword phrase arguments to User() (except the user function name)
are passed to the user function without being copied.  When the argument
is a named MacAnova variable and the user function modifies it, the
value of the variable itself is changed.  When the argument is a
literal number (User("foo", 1, 2, 0)) or expression (User("foo",
sqrt(2)+3, log(4), 19^2)) the function can safely change the argument
without danger to any variable.

Suppose fooadd expects three arguments, and modifies the third by
assigning the sum of the first two.  Then

  Cmd> c <- 0; User("fooadd", 1, 2, c)

returns no value (actually a NULL; see NULL), but c has been changed to
3 (= 1+2).  However,

  Cmd> c <- 0; User("fooadd", 1, 2, protect:c)

will not change c itself, but only a copy.

In addition to being copied before use, all keyword phrase user function
arguments are returned, possibly modified, as the value of User().  When
there are two or more such keyword arguments, a structure is returned
with component names taken from the keyword names.

Keyword 'protect' is special, in that its only effect is to cause its
value to be copied before being passed to the user function; its value
is not returned by User().  Thus the use of 'protect' in the example
makes the user function useless: c does not get changed because it is
protected by a keyword, but the modified value is not returned either.
The following both protects c and causes the modified value of the last
argument to be returned as the value of User().

  Cmd> c <- 0;User("fooadd", 1, 2, result:c)

This returns 3 = 1 + 2, but c would be unchanged.  In place of variable
c for result, you could use any REAL scalar (result:0).  This serves to
provide space for the answer.

  Cmd> User("fooadd", left:1, right:2, result:0)

returns a structure with components 'left', 'right' and 'result'
containing the possibly modified values of the original arguments.

It is essential that the size of any argument that is to be modified
matches the size that is expected by the user function.  Thus, if foocat
is a user function that concatenates its first two arguments into a
third argument, the length of the third argument should be the combined

  Cmd> User("foocat", run(4), run(7), combined:rep(0,11)

In this example, for the third argument to have fewer than 11 elements
would lead to unpredictable results, possibly even a crash of MacAnova.

Except when symbols:T is an argument, all user function arguments are
either REAL, LOGICAL, CHARACTER or LONG variables.  REAL arguments are
passed as double precision data, as are LOGICAL arguments (True = 1.0,
False = 0.0).  When an argument is a matrix or array, the values are
ordered such that the first subscript changes fastest.  See topic
'user_fun' in help file userfun.hlp for more information (type

LONG is a special MacAnova type whose values are long integers between
-2147483647 and 2147483647 = 2^31 - 1.  A LONG argument can be created
only by function asLong().  A LONG argument that is returned
(result:asLong(x)), is turned into an REAL quantity before being
returned.  See asLong().

  Cmd> User("goo", run(10), run(10), asLong(10), result:0)

invokes user function goo with three REAL arguments and one long

For virtually unlimited flexibility, when keyword phrase 'symbols:T' is
an argument to User(), all user function arguments are passed as symbols
-- MacAnova objects which encapsulate the data, type, and dimensions of
a variable.  Thus

  Cmd> User("foo", symbols:T, x, y, result:z)

passes x, y and z to 'foo' as symbols.  You cannot have some user
function arguments be symbols and some just data; all must be symbols or

Gary Oehlert 2003-01-15