@database "arexx_cl"
@master "AMIDEV:NDK/Autodocs/arexx_cl.doc"

@Node Main "arexx_cl.doc"
@toc "Autodocs/AG/INDEX/Main"
    @{" --datasheet--() " Link "--datasheet--()"}
    @{" AM_EXECUTE " Link "AM_EXECUTE"}
    @{" AM_HANDLEEVENT " Link "AM_HANDLEEVENT"}
@EndNode

@Node "--datasheet--()" "arexx_cl/--datasheet--"

@{b}    NAME@{ub}
        arexx_cl -- ARexx interface class.

@{b}    SUPERCLASS@{ub}
        rootclass

@{b}    DESCRIPTION@{ub}
        This class provides you with a very easy way to implement an ARexx
        interface.  It will setup a unique ARexx port, start ARexx macros,
        parse commands and dispatch command handler functions.

        All ARexx class methods and the callbacks you provide it are run in
        the context of the task you call ARexx class from. Thus if your
        application is a process, DOS is safe to use.

@{b}    METHODS@{ub}
        @{"OM_NEW" Link "tabs_gc/OM_NEW"} -- Passed to superclass first.  Creates a new ARexx
            interaction object. The message is of type struct @{"opSet" Link "INCLUDE:intuition/classusr.h/Main" 76} *. The
            following attributes, communicated in ops_AttrList, are currently
            supported, see <classes/arexx.h>:

            AREXX_ErrorCode:   A ULONG * into which a potential Rexx error
                               code is placed.
            AREXX_HostName:    Pointer to a NUL-terminated string, not longer
                               than 80 characters, of a base port name that
                               is to be used as public port for ARexx
                               communication. If AREXX_NoSlot is FALSE, the
                               class automatically extends the name by a dot
                               and a number to make it unique.
            AREXX_NoSlot:      If set, no new port is created, instead a port
                               of the given name is hijacked or created.
            AREXX_ReplyHook:   A struct @{"Hook" Link "INCLUDE:utility/hooks.h/Main" 26} * to a hook that is called
                               whenever an ARexx message send out by this
                               class returns.
                               The hook is called with object = the object
                               instance of this class and message = the Rexx
                               message that returned.
            AREXX_Commands:    Pointer to an array of struct @{"ARexxCmd" Link "INCLUDE:classes/arexx.h/Main" 116},
                               terminated by an ac_Func pointer of @{"NULL" Link "rexxsupport/NULL"}, that
                               defines function names, templates and
                               callbacks for the ARexx function supported by
                               the host; see @{"<classes/arexx.h>" Link "INCLUDE:classes/arexx.h/Main" 0}.

        @{"OM_GET" Link "tabs_gc/OM_GET"} -- Retrieves attributes from the class. The message is of type
            struct @{"opGet" Link "INCLUDE:intuition/classusr.h/Main" 106} *, with the attribute ID in opg_AttrID. The
            following attributes are currently supported:

            AREXX_HostName:    Returns in opg_Storage a pointer to a NUL-
                               terminated string providing the host name of
                               the Arexx communications port.
            AREXX_SigMask:     Returns in opg_Storage the signal mask to wait
                               for the arrival of messages on the ARexx host
                               port.
            AREXX_ReplyHook:   Returns a struct @{"Hook" Link "INCLUDE:utility/hooks.h/Main" 26} * of the hook that is
                               called when a ARexx message send out by the
                               class has been returned.

        OM_DISPOSE -- Closes the port and frees all resources.  Passed onto
            superclass.

        @{"AM_HANDLEEVENT" Link "AM_HANDLEEVENT"} -- Checks for incoming ARexx messages and handles
            them. In case the message is a replied message from a ARexx
            execution, the AREXX_ReplyHook is called. For incoming commands,
            the list of ARexx commands (see AREXX_Commands above) is scanned
            for a fitting command, and the corresponding call-back is
            executed. If not found, the incomming command is dispatched as a
            script to the RexxHost.

        AM_FLUSH -- retrieves all pending ARexx commands and ignore them, in
            order to shut down the ARexx command port.

        @{"AM_EXECUTE" Link "AM_EXECUTE"} -- Executes an ARexx command or macro.

@{b}    ATTRIBUTES@{ub}
        AREXX_HostName (STRPTR)
            The name of the host.  The ARexx portname is derived from this.
            In pretty much all cases, this should the same as your app's
            basename.  You should refrain from using names like "MYPROG_RX"
            or others with unnecessary suffixes.

            To create the portname, the hostname will be uppercased, and,
            unless AREXX_NoSlot is specified, a slot number will be
            appended.

            Applicability is (OM_NEW, OM_GET)

        AREXX_NoSlot (BOOL)
            Specifies that no slot number should be appended to the port
            name when it is being created.  This greatly increases the
            chances that your requested portname is in use, so your code
            must be sure to handle this situation.

            Defaults to FALSE.

            Applicability is (OM_NEW)

        AREXX_DefExtension (STRPTR)
            Default filename extension for macros started by your app.  Do
            not include the ".", just the extension text.   In pretty much
            all cases, this should be the same as your app's basename.  You
            should refrain from using extensions like "myrx".

            Defaults to "rexx".

            Applicability is (OM_NEW)

        AREXX_Commands (struct @{"ARexxCmd" Link "INCLUDE:classes/arexx.h/Main" 116} *)
            The table of the commands supported by your ARexx interface.
            This will be a pointer to an array of struct @{"ARexxCmd" Link "INCLUDE:classes/arexx.h/Main" 116}.  If this
            array is not passed then your host will not be able to process
            any ARexx commands.

            The following fields must be setup initially by the app before
            OM_NEW:

                ac_Name (STRPTR)
                The name of the command.  By convention this is usually all
                uppercase, though a case-insensitive comparisons will be
                done.

                ac_ID (WORD)
                A unique number identifying this command.

                ac_Func (*()(struct @{"ARexxCmd" Link "INCLUDE:classes/arexx.h/Main" 116} *, struct @{"RexxMsg" Link "INCLUDE:rexx/storage.h/Main" 83} *))
                A pointer to the function that will be called when this
                command is received by your programme.  The function will
                get past a pointer to its @{"ARexxCmd" Link "INCLUDE:classes/arexx.h/Main" 116} entry and the @{"RexxMsg" Link "INCLUDE:rexx/storage.h/Main" 83}
                structure received for the command.  You may use this
                for setting ARexx variables, but please note that is may
                be @{"NULL" Link "rexxsupport/NULL"}

                ac_ArgTemplate (STRPTR)
                DOS ReadArgs()-style argument template for this command.

                ac_Flags (ULONG)
                Command flags.  Currently unused, but in order to remain
                compatable, you must ensure that this is @{"NULL" Link "rexxsupport/NULL"}.

            These fields are ignored in @{"OM_NEW" Link "tabs_gc/OM_NEW"} and are set by the class
            when calling the ac_Func command callback.

                ac_ArgList (ULONG *)
                Result of @{"ReadArgs()" Link "dos/ReadArgs()"} using the arguments received with the
                command and ac_ArgTemplate as the template.

                ac_RC (LONG)
                Primary result, the RC variable.  Also causes the RC2
                variable to return, and will cause RESULT to NOT be set.

                ac_RC2 (LONG)
                Secundary result, the RC2 variable.  This will not be set
                unless RC is non-zero.

                ac_Result (STRPTR)
                RESULT variable, this should be a string.  If you want to
                return a number, you will have to convert it to a string
                first.  This string will not be set if RC is non-zero.

            The array must be terminated with a @{"NULL" Link "rexxsupport/NULL"} ac_Name field.

            Applicability is (OM_NEW)

        AREXX_ErrorCode (ULONG *)
            A pointer to storage space for @{"OM_NEW" Link "tabs_gc/OM_NEW"} to store an error code
            when it fails trying to create the object.  Possible values
            are:

            RXERR_NO_COMMAND_LIST - No command list was provided.
            RXERR_NO_PORT_NAME - No host base name was provided.
            RXERR_PORT_ALREADY_EXISTS - The  class  was unable to create a
                unique name of the base name you provided.
            RXERR_OUT_OF_MEMORY - Not enough free memory.

            No error code will be returned if you provide a @{"NULL" Link "rexxsupport/NULL"} pointer.

            Defaults @{"NULL" Link "rexxsupport/NULL"}.

            Applicability is (OM_NEW)

        AREXX_SigMask (ULONG)
            The signal mask for the object's message port.  This is the
            signal you will want to @{"Wait()" Link "exec/Wait()"} on so you know when there is
            activity at the ARexx port.

            Applicability is (OM_GET)

        AREXX_ReplyHook (struct @{"Hook" Link "INCLUDE:utility/hooks.h/Main" 26} *)
            This is a function hook that will get called whenever your host
            replies to an ARexx message.  This generally happens after your
            host has sent a message (eg. via AM_EXECUTE) and the task
            receiving the message has completed its processing with the
            message.  This is most useful for checking return codes from
            commands sent via @{"AM_EXECUTE" Link "AM_EXECUTE"}.

            The object parameter in the hook function will point to the
            @{"Object" Link "INCLUDE:intuition/classusr.h/Main" 18} * that is yur host, and the message parameter will be
            the ARexx message that is being replied to (from which you
            could extract result codes).

            Defaults to @{"NULL" Link "rexxsupport/NULL"}.

            Applicability is (OM_NEW, OM_GET)

@{b}    BUGS@{ub}
        AREXX_HostName MUST be all uppercase in V40 otherwise the checks for
        an already existing port won't work right.

@{b}    SEE ALSO@{ub}
        @{"<classes/arexx.h>" Link "INCLUDE:classes/arexx.h/Main" 0}

@EndNode

@Node "AM_EXECUTE" "arexx_cl/AM_EXECUTE"

@{b}    NAME@{ub}
        AM_EXECUTE -- @{"Execute" Link "dos/Execute()"} an ARexx macro.

@{b}    FUNCTION@{ub}
        This method allows you to execute a macro in another host.  The
        default host is the ARexx server.  This is how you would execute
        disk-based ARexx macros, by passing the name of the file as the
        command string to the ARexx server.

        This method uses the following custom message structure:

          struct @{"apExecute" Link "INCLUDE:classes/arexx.h/Main" 100}
          {
              ULONG MethodID;
              @{"STRPTR" Link "INCLUDE:exec/types.h/Main" 137} ape_CommandString;
              @{"STRPTR" Link "INCLUDE:exec/types.h/Main" 137} ape_PortName;
              @{"LONG" Link "INCLUDE:exec/types.h/Main" 112} *ape_RC;
              @{"LONG" Link "INCLUDE:exec/types.h/Main" 112} *ape_RC2;
              @{"STRPTR" Link "INCLUDE:exec/types.h/Main" 137} *ape_Result;
              @{"BPTR" Link "INCLUDE:dos/dos.h/Main" 131} ape_IO;
          };

        ape_CommandString (STRPTR)
            This must point to the command including arguments to execute.
            If the command is found in the host command list it will be
            executed.  Unknown commands will be shipped off to the ARexx
            server.

        ape_RC, ape_RC2, ape_Result (LONG *, @{"LONG" Link "INCLUDE:exec/types.h/Main" 112} *, @{"STRPTR" Link "INCLUDE:exec/types.h/Main" 137} *)
            After the command executed you will find the results in here if
            the command was one in your host, or if there was a problem
            sending the command to the specified host.  You will NOT get the
            result of the command if it is sent to another host, since the
            command is sent asychronously.  Use AREXX_ReplyHook for this.

        ape_IO (BPTR)
            If you execute a script using this method you can pass a pointer
            to the IO channel ARexx must  use here.  This IO channel will be
            closed automatically for you after the command executed.

@{b}    RESULT@{ub}
        As errors are reported in acme_RC and acme_RC2 this method has no
        specific return code.

@EndNode

@Node "AM_HANDLEEVENT" "arexx_cl/AM_HANDLEEVENT"

@{b}    NAME@{ub}
        AM_HANDLEEVENT

@{b}    FUNCTION@{ub}
        This method will handle all incoming and outgoing message traffic
        from your host.  When you are signalled you simply call this method
        and everything is done for you.

@{b}    RESULT@{ub}
        No return code is specified for this method.

@EndNode

