Next: c_macros Up: User Function Help File Previous: User Function Help File   Contents

arginfo_fun

Usage:
Type userfunhelp(user_fun) for information on the structure of user
  functions.
Type userfunhelp(callback_fun) for information on the structure of user
  functions making "call backs" to MacAnova.
Type userfunhelp(arginfo_fun) for information on how to enable automatic
  checking of arguments to a user function.



Keywords: user functions, coding, sample source
This topic presumes familiarity with topic User() and user_fun.  It
provides a brief introduction to the form of an arginfo function, that
is an externally compiled function that can be called by MacAnova to
obtain information about the arguments expected by a user function.  If
available, an arginfo function operates transparently to the user of
MacAnova.  Because of the inherent dependence on the computer and
operating system, there are many details that are not covered here.
Additional details may be found in topics compile_dos, compile_mac,
compile_unx and compile_win.

This topic presumes familiarity with topics user_fun and callback_fun.

Arginfo functions are not currently possible when compiling for the
protected mode DOS version (DJGPP).

Since we have no experience with writing arginfo functions in Fortran,
no Fortran related information is provided here.

In the following, 'handle' is used in the Macintosh OS sense, as a
pointer to a pointer.

To compile an arginfo function associated with user function foo, say,
you need to include a function named 'arginfo_foo' in the source for
foo.  arginfo_foo should have no arguments and should return a pointer
to a vector of long integers, that is it should be declared as
  long * arginfo_foo(void)
When compiling for Windows using Borland C/C++ 4.5, the declaration
should be
  long * _export arginfo_foo(void)

The ending of the name of the arginfo function (here 'foo') must match
the name of the user function.

arginfo_foo should return a pointer to a vector arginfo of Nargs + 2
long integers, where Nargs is the number of arguments expected by foo,
excluding the list, if any, of call back functions (see callback_fun).

The first element of vector arginfo (arginfo[0]) must be Nargs >= 1.

The second element of vector arginfo (arginfo[1]) is composed of bit
constants that specify various properties of the function (whether it
makes call backs, whether it expects pointers or handles, whether its
arguments should be data or symbols, and whether a required 68881
co-processor is absent (Macintosh only).  Symbolic names for these are
defined in header file dynload.h which is automatically included by
header file Userfun.h.
    Name of bit      Meaning
    DOESCALLBACK     Call backs to MacAnova functions will be made
    NOCALLBACK       No call backs to MacAnova functions will be made
    USESPOINTERS     Arguments should be pointers
    USESHANDLES      Arguments should be handles
    POINTERUSE       Same as USESHANDLES on Macintosh and same as
                     USESPOINTERS on other systems
    SYMBOLARGS       All arguments (except call back function list) are
                     pointers or handles to Symbols
    NOSYMBOLARGS     All arguments (except call back function list) are
                     pointers or handles to data
    COPROCESSOROK    Co-processor not needed or, if needed, is available
    COPROCESSORERROR A co-processor is needed but not available

For example, for a function with default pointer/handle usage that makes
call backs and does not expect Symbol arguments, arginfo[1] should be
DOESCALLBACK | POINTERUSE | NOSYMBOLARGS.  When compiling for a Macintosh,
this is equivalent to DOESCALLBACK | USERSHANDLES | NOSYMBOLARGS; when
compiling for other computers it is equivalent to DOESCALLBACK |
USESPOINTERS | NOSYMBOLARGS

Strictly speaking NOCALLBACK and NOSYMBOLARGS are not needed since they
evaluate to 0, but their use can make for clearer code.

The remaining Nargs elements (arginfo[2], arginfo[3], ...,
arginfo[Nargs+1]) of the vector are integers that specify the MacAnova
types of the user function arguments, using symbolic constants defined
in Userfun.h.  Typical constants are REALMATRIX, CHARSCALAR,
LOGICSCALAR, INTVECTOR, POSITIVEREALVECTOR, NONNEGATIVEINT, LONGVECTOR
and SYMHVALUE.  The qualifier INT means REAL with integer values; the
qualifer LONG means actual long integers as produced by asLong().  See
topic type_codes for a complete list of permissible constants.

In writing a function for a 68K Macintosh when compiling using
Metrowerks CodeWarrior, to ensure correct compilation, all declarations
of call back and arginfo functions must be bracketed by

  #pragma mpwc on
  ...
  #pragma mpwc off

Here is an example of a function to provide argument information for
fooeval() listed under topic callback_fun and executed from MacAnova by,
say,
  Cmd> User("fooeval", "sqrt(PI/2)")

Non-Macintosh version:
  #include "Userfun.h"

  static long Fooevalarginfo[] =
        {1, DOESCALLBACK | POINTERUSE | NOSYMBOLARGS, CHARSCALAR};

  long * arginfo_fooeval(void)
  {
      return(Fooevalarginfo);
  }

Macintosh version:

  #include "Userfun.h"

  #define info_main main

  static long Fooevalarginfo[] =
        {1, DOESCALLBACK | POINTERUSE | NOSYMBOLARGS, CHARSCALAR};

  #ifndef powerc
  #pragma mpwc on
  #endif
  long * info_main(void)
  {
      long         *arginfo;

      EnterCode();

      arginfo = Fooevalarginfo;
      /*add COPROCESSORERROR to arginfo[1] if appropriate*/
      CHECK68881(arginfo);

      ExitCode();
      return(arginfo);
  }
  #ifndef powerc
  #pragma mpwc off
  #endif

  #ifdef powerc
  RoutineDescriptor arginfo_fooeval =
     BUILD_ROUTINE_DESCRIPTOR(uppArgInfoEntryProcInfo, info_main);
  #endif /*powerc*/

When compiled for a 68K Macintosh, this must be compiled separately from
fooeval.  If the source is in the same file as source for fooeval, some
form of conditional compilation should be used so that both
arginfo_fooeval and fooeval don't both get compiled at once.  The code
resource produced should have name arginfo_fooeval and be included in
the same resource file as fooeval.

When compiled for a Power PC Macintosh, arginfo_fooeval would normally
be in the same source file as fooeval (C function main) and info_main
would not be defined to be main.  A single compilation would produce a
resource file containing resource fooeval with entries fooeval and
arginfo_fooeval.  The actual entry points would be specified by
RoutineDescriptors fooeval and fooeval_arginfo.

See topics compile_dos, compile_mac, compile_unix and compile_dos for
information on compiling a user function on different types of
computers.

See loadUser() and User() for information on how to load and execute a
user function.

See topic user_fun for information on the structure of a user function
not making call backs to MacAnova.

See topic callback_fun for information on the structure of a user
function making call backs to Macanova.

See topic c_macros and header file Userfun.h distributed with MacAnova
for C macros that are helpful in writing arginfo functions.


Gary Oehlert 2003-01-15