home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d2xx
/
d299
/
rxil.lha
/
Rxil
/
Rxil.doc
< prev
next >
Wrap
Text File
|
1989-12-30
|
24KB
|
786 lines
Documentation for the ARexx Interface Library (Rxil)
Release 1.0
Copyright © 1989 by Donald T. Meyer, Stormgate Software
All Rights Reserved
CONTENTS
Change Log
Variable Glossary
Defined Symbol Glossary
Structure Descriptions
Tutorial
Notes
=====================================================================
In the following document, several terms and documantation conventions
will be observed:
When refering to ARexx message ports, "private" and "secret" refer
to the same port.
The code that uses this library may be refered to as the "client".
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
====================== Changes in 1.0 (no X) ====================
Added RXERR_INVALID_ARG error code define. Made changes in demo.c
to use this instead of RXERR_BAD_VARIABLE.
Added support for a "startup" macro to the demo.c program.
RxilCheckPort() would return a RXERR_BAD_VARIABLE if unable to allocate
enough memory to copy the command line for a received command. Oops.
Changed it to RXERR_NO_MEMORY.
Found & Fixed bug in cancel.c which allowed the cancel requester to
be posted when it already was!
Changed the version string to be derived from a #define in the rxil.h
file. No real impact on anything.
====================== Changes in X1.0 =========================
Minor enhancement to the RxilDump formatting of command data.
Major additions to RxilHandleReturn().
This will now post a requester if Intuition has been opened, and will use
the CLI otherwise. This also no longer uses 'C' standard I/O, rather it
uses the native AmigaDOS calls like Open() and Write(). This is to
facilitate those who don't want stdio pulled in. Note that RxilDump() is
the only routine here which uses stdio. Since this is really for debugging
and learning only, it will probably stay that way (unless it really bothers
someone).
Dependence on precompiled header files has been eliminated.
Function documentation broken off into separate file "Functions.doc"
Added "test.rexx" program. This does not do any automatic demo of the
functions, but does facilitate playing around.
The old "smalldemo" program was renamed "demo".
====================== Changes in X0.9 =========================
Added Version member to RxilDef
Cleaned up some incorrect prototypes in the rxil.h.
Changed the argument checking scheme to use a minimum and a maximum
number of arguments as opposed to the single value previously checked
against.
The structure member "Privilege" was spelled incorrectly. (blush)
It has been corrected.
Added feature to append an "instance" number onto the public port name.
This allows multiple instances of the application program to be run,
each having a unique portname.
Added a flags argument to the diagnostic command RxilDumpRdef() to
control what is displayed. Also added display of the commands.
====================================================================
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ::
:: Variable Glossary ::
:: ::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
RexxSysBase
This is a pointer to the ARexx library opened by RxilInit() and closed
by RxilCleanup().
This should never be altered by client code.
Defined in the Rxil library modules.
global_rdef
The pointer to the global RxilDef structure. This must be set to the
value returned from the call to RxilInit().
Once set by this call, this should not be altered.
Immediatly after calling RxilCleanup(), this should be set to NULL.
This must be defined in the client's program.
Example:
global_rdef = RxilInit( RXIL_PUBLIC, "MyPort" );
.
.
.
RxilCleanup( global_rdef );
global_rdef = NULL;
--------------------------------------------------------------------------
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ::
:: Defined Symbol Glossary ::
:: ::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
RXIL_PUBLIC
RXIL_PRIVATE
RXIL_SECRET
These are flags which are passed to the RxilInit() routine to control which
ports are opened.
RXIL_AS_IS
This is a flag which is passed to the RxilInit() routine to inhibit the
instance number which would normally be appended to the port name.
RXIL_MAX_ARGS
This is the maximum number of arguments (plus one) that may appear on a
command line which is sent to the application's ARexx port. The default is
twenty, which should be enough for anything I can imagine.
RXIL_ARGV()
RXIL_ARGC
These macros are used in the same way that the "argc" and "argv" allow
access to the command line arguments passed to main() in a standard 'C'
program. Like their 'C' counterparts, RXIL_ARGC will be set to 2 if there
is 1 argument. The first argument is accessed as RXIL_ARGV(1).
RXIL_STATE_AVAILABLE
RXIL_STATE_PENDING
RXIL_STATE_RETURNED
These are the possible states for a RxilInvocation structure to be in.
AVAILABLE indicates that the structure may be freed or used to launch a
macro.
PENDING means that a macro has been launched using this structure and we
are awaiting a reply when the macro terminates.
RETURNED indicates that the termination reply has been received and that we
may handle the return. The state will be changed to AVAILABLE by the
RxilCleanupReturn() function.
RXIL_NOLAUNCH
A flag for the Flags member in the global RxilDef structure.
If set, this will disable the "loopback" feature whereby a macro can launch
other macros.
RXIL_NO_CLEARABORT
A flag for the Flags member in the global RxilDef structure.
This will prevent the RxilCheckPort() function from clearing the abort flag
automaticly whenever there are no pending macros.
RXIL_NOABORT
A flag for the Flags member in the global RxilDef structure.
This flag will prevent the Cancel requester from being used when a macro
is launched.
RXIL_NO_REQ
A flag for the Flags member in the global RxilDef structure.
Force routines such as RxilHandleReturn() to send thier messages to the CLI
as opposed to a requester, which is the default action.
RXIL_FROM_REXX
A macro which returns a value indicating which port (Public or Private) the
ARexx command which is executing came in to. One very important use for
this would be for error handling, which will usually be different depending
upon wether an action was initiated by a user menu selection etc. or by a
command from ARexx.
RXIL_WAITFLAG
This macro gives the flag bit(s) to wait on (via Wait()) for the ports that
are opened by RxilInit() to receive commands at.
--------------------------------------------------------------------------
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ::
:: Structure Descriptions ::
:: ::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*************** RxilFunction Structure ****************
Name
The function name. This can be in upper or lower case. See the CaseFlag
member of this structure for more information.
Func
Vector to the function's 'C' code.
ArgCount
Number of args expected. Set to NO_ARGCHECK if we don't care or will
ascertain within the function itself.
Note: This argument count, unlike the value returned by RXIL_ARGC, does
not include the command name itself. I.E., if you want to receive one
argunt, set this to 1.
CaseFlag
If set to boolean TRUE, the command name matching will be case sensitive.
Privlege
Set to either REXX_PUBLIC or REXX_SECRET to control which port(s) this
command is valid from. If REXX_PUBLIC, than this command may be executed
from either port.
*************** RxilDef Structure ****************
Flags
These are flagbits which can be set to control various things about the
Rexx Interface Library.
RXIL_NOLAUNCH If set, unrecognized commands received at the
ARexx port will be returned with an error code
rather than "looped" back out to ARexx.
RXIL_NO_CLEARABORT Normally, the library will clear the Abort flag
whenever the last ARexx program launched by the
library returns. This will disable that feature.
RXIL_NOABORT If set, the "Cancel" requester will not appear when
an ARexx macro is initiated from the library.
RXIL_NO_REQ If set, the RxilHandleReturn() routine (and perhaps
others in the future) will send it's messages to
the CLI instead of trying to use an Autorequest.
PortName
Name which will be used for the public Exec message port opened to recieve
commands from ARexx. This is set when RxilInit() is called, and subsequent
changes will have no effect.
By default, an "instance" number will be appended to the portname which
was passed to RxilInit(). This allows there to be multiple instances of
an application running, each with a unique public port name.
This may be overridden via the RXIL_AS_IS flag being passed to RxilInit().
Default: none
Console
An AmigaDOS stream which will be set as the default I/O for commands and
functions launched by the application. This will normally be a console
stream, such as "CON:10/10/400/100/ARexxStream".
This stream will not be used for ARexx programs that have been "looped" back
out in response to a command.
Default: "CON:10/10/400/100/"
Extension
This is the extension which will be used by ARexx to search for this
programs macros. This should be an application-specific extension.
Default: ".rexx"
HostPort
The Exec Message Port name that command and function invocation messages
will be sent to. This is normally "REXX", but may also be "AREXX" if
the 1.10 version of ARexx is in use. If "AREXX", commands and functions
will "detach", and no return status or value will be available.
Default: "REXX"
CommandTable
This is the pointer to an array of RxilFunction structures which is
used for the dispatching of commands received at the application's
ARexx port.
Default: NULL
Abort
When set, this flag will cause commands recieved at the ARexx port to be
returned with an error code.
There are several flag bits which may be set in the Flags member of the
RxilDef structure that affect this flag.
SecretPortName
The name of the "secret" or "private" port which may optionaly be opened
by RxilInit(). This name is created by concatenating the word "PRIVATE"
and a unique number onto the PortName.
This is set when RxilInit() is called, and subsequent changes will have no
effect.
Default: none
CancelWindow
If NULL, the cancel requester will be opened upon the WorkBench screen.
This may be set to a Window pointer, in which case the cancel requester
will open on the screen containing the window. Note that the cancel
requester always opens it own window, this member is merely a means
of selecting the screen.
The window pointer stored here is also used by RxilHandleReturn() to
decide where to post it's requester.
SigBit
Contains the Exec signal bit(s) used by the ARexx port(s). This should
be read only via the macro RXIL_WAITFLAG.
This should never be altered by client code.
FromRexx
This contains a value which indicates which port a command is from
(public or private). This also indicates that a command is from
an ARexx port (when non-zero). Some functions may need to know whether
they have been called in response to an ARexx command, or through
the "normal" user interface. Error handling and reporting will normally
be handled differently in these cases.
This should only be read via the macro RXIL_FROMREXX.
This should never be altered by client code.
Arg
An array of pointers to the argument strings for an ARexx command.
Like the 'C' argv[] array, the command name will be in the zereoth
element, with the first actual argument being RXIL_ARGV(1).
These should only be read via the macro RXIL_ARGV().
This should never be altered by client code.
ArgCount
The count of arguments from the ARexx commandline. Again, like the
argc of 'C', this will be 1 if there were no arguments, 2 if there
is one argument, etc.
This should only be read via the macro RXIL_ARGC.
This should never be altered by client code.
LockCount
If non-zero there is an ARexx program which has been given or acquired
a "lock" on the private ARexx port.
This should never be altered by client code.
Version
A pointer to a null-terminated string which contains the Rxil copyright
message and version.
Structure members past this point are private, and used only by the
Rxil internal functions. They should never be altered by client code,
and client code should have little reason to ever read them.
*************** RxilInvocation Structure ****************
Next
This member is private.
RexxMsg
This member is private.
Parent
This member is private.
IHostPort
The name of the Exec message port to send the "launch" mesage to. This
will normally be "REXX".
Default: global_rdef->HostPort
State
The current state of the RexxInvocation structure. This will indicate
wether or not the structure is available for use (to launch an ARexx
program), is waiting for an ARexx program to finish, or that the ARexx
program has finished and a result is waiting to be cleaned up.
Type
This determines whether or not the ARexx program will be launched as a
command or a function. This can be either RXCOMM or RXFUNC.
Default: Whatever was passed as an argument to CreateRxi().
Name
The command (ARexx program) name. This must be set by the client code
prior to calling RxilLaunch().
Default: None
FileExt
This is the extension which will be used by ARexx to search for this
program. This should be an application-specific extension.
Default: global_rdef->Extension
CommAddr
This will be the default host ADDRESS for the ARexx program when launched.
Default: The secret port name (if open), otherwise the public port name.
Console
An AmigaDOS stream which will be set as the default I/O for commands and
functions launched by the application. This will normally be a console
stream, such as "CON:10/10/400/100/ARexxStream".
This stream will not be used for ARexx programs that have been "looped" back
out in response to a command.
Default: global_rdef->Console
ActionFlags
These are the rm_Action flag bits. Whatever is here will be anded with
the rm_Action field of the ARexx program launch RexxMsg.
CountArgs
If TRUE, the data pointed to by the FuncArg array is not be considered
NULL terminated ('C' string style). The argument length must in this
case be stored in the ArgLen array.
FuncArg
Pointer to argument strings for an ARexx function mode invocation only.
These are assumed to be NULL terminated 'C' style strings unless the
CountArgs flag is TRUE.
ArgLen
If the CountArgs flag is TRUE, this array contains the lengths of the
argument data pointed at by the corresponding members of the FuncArg
array.
--------------------------------------------------------------------------
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ::
:: Tutorial ::
:: ::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
******* Making A Program ARexx Compatible *******
This consists of being able to receive commands from ARexx, and in some
cases, having the ability to use ARexx as a macro language.
An ARexx port is a public Exec MessagePort that an application program or
utility opens to allow the receipt of commands from ARexx. These commands
can not only cause the program to do various actions, but information may
also be returned to the ARexx program which sent the command.
The second thing involved in allowing a program to make full use of ARexx
is the ability to "launch" macro programs written in ARexx. These macro's
normally send commands back to the ARexx port to cause sequences of actions
to take place.
******* What The ARexx Interface Library (Rxil) Does *******
This linkable 'C' library makes adding complete, full-featured ARexx
compatability to a program almost a trivial exercise.
Opening of both "public" and "private" ports is supported, as well as an
easy facility for launching macros.
All allocations are tracked, and everything may be cleaned up by one
function call.
******* How It Works *******
A complete tutorial on ARexx interfacing, and the features provided by Rxil
would be quite large. Since one of the reasons for the creation of Rxil
was to alleviate the need to become an expert in the (sometimes subtle)
nuances of implementing an ARexx interface, I'm not going to try.
The best way to understand the features of this library is to first read
chapter 10 in the "ARexx User's Reference Manual", and then study the
example code in the program "demo.c" which comes with this library.
Have a hardcopy of the "rxil.h" header file handy (study it also) while
looking at the sample code.
It wouldn't hurt to read the functions descriptions contained in the file
"Functions.doc" either. Some of these functions are normally called by
other higher-level functions in the library, and as such you may not need
to ever call them directly. The reason they are kept visible is to support
any special needs that may require that they be called directly or replaced
by a similar function.
Also, please feel free to E-Mail (or US Mail for that matter) me any
questions you may have about using this library.
******* Structures and Variables Required *******
The structure RxilDef is the anchor point of the library. This contains
things used by almost every function in the library, as well as things set
directly by the program which uses the library to control various things.
A pointer to a structure of this type must be defined by every program
which uses Rxil. An instance of this structure will be allocated by a call
to RxilInit(), and freed by the call to RxilCleanup().
Commands are dispatched via a structure of type RxilFunction which the
program must define if it wishes to receive commands. This structure
(actually, an array of these structures) contains the command name, a
vector to the code which performs the command, and some other attributes
such as argument counts to allow the library to do argument checking.
******** Functions Required *******
RxilInit() always needed
This call must be made before anything can be done with the other library
functions. This will open the ARexx library (rexxsyslib.library) and open
the port or ports that the program wishes to receive commands at. A
RxilDef structure is allocated, and it's pointer returned. This pointer
MUST be stored in the variable "global_rdef".
If the initializations fail, any subsequent calls to the normal Rxil
library functions should be harmless. This will prevent your program from
crashing if ARexx is not present (always a possibility).
Once this call is made, some of the members of the RxilDef structure will
normally need to be initialized. These include the "Flags", "Console",
"Extension", "HostPort", and "CommandTable" members.
RxilCleanup() always needed
This call must be made before the program exits. This will close the ARexx
library, free the RxilDef structure, and close the port(s).
Any RxilInvocation structures which may have been allocated by
RxilCreateRxi() will also be freed. If there are macros which have been
launched and not yet replied, this function will wait till they return.
Note that this may distress the user, if they do not understand why the
program refuses to "go away". If this is a possibility, it would be best
to check by calling RxilPending(), and let the user know what is happening.
RxilCheckPort() always needed
When a message is received at the port(s), this function should be called
to handle it. Normally this is done by Wait()ing on the whatever flags
your program normally waits on, combined with the flag bit(s) given by the
macro RXIL_WAITFLAG.
This routine does quite a bit, including dispatching commands that are
received, getting the returns for macros that have been launched, and
looping back out macros called by commands (it gets quite spagetti-like
after a while!).
RxilCreateRxi() macro launching only
Allocates and initializes a RxilInvocation structure. This structure may
then be used to launch an ARexx command or function macro. Once the macro
has returned and been cleaned up via RxilCleanupReturn(), the
RxilInvocation structure may be re-used. It could also be freed by a call
to RxilDeleteRxi() if so desired.
RxilDeleteRxi() optional, macro launching only
Frees up a RxilInvocation structure which was allocated by RxilCreateRxi().
Note that any RxilInvocation structures allocated and not explicitly freed
with this function will be freed automaticly by the call to RxilCleanup().
RxilGetReturn() macro launching only
If a macro invocation has been replied, but not yet cleaned up, this will
return a pointer to it's RxilInvocation structure. This should be called
in a loop until it returns NULL, subsequent to calling RxilCheckPort().
The RxilInvocation structure should be cleaned up and then either freed or
put back in the "pool" for re-use.
RxilLaunch() macro launching only
This will take a properly initialized RxilInvocation structure and use it
to launch a command or function macro.
The RxilInvocation structure must be initialized with the name of the
program to launch. If the ARexx program is to be launched as a function
rather than a command, the arguments should be passed by setting pointers
to the argument data in the FuncArg members of the RxilInvocation
structure. These arguments may be null terminated strings. If arguments
which may contain binary are to be used, the CountArgs member of the
RxilInvocation structure should be set to TRUE, and the argument length set
into the ArgLen members of the structure.
RxilHandleReturn() optional, macro launching only
This will inform the user (via requester or message to the CLI) about any
error returns or result strings from a macro.
This is provided as both a general purpose routine which many programs
might find adequete and as an example for those who wish to deal with macro
returns in a custom manner.
RxilCleanupReturn() macro launching only
This frees anything which was allocated by RxilLaunch() or returned by
ARexx after a macro invocation structure has been replied.
This should always be called for the structures returned by
RxilGetReturn().
RxilSetResult() command support
This is a handy function to make it easy to set a result string for a
command recieved at the ARexx port. Used in command handling routines.
RxilCmdLock() command support
RxilCmdUnlock() command support
These will perform the "lock" and "unlock" actions which allow an ARexx
program to gain exclusive access to a program's ARexx facilities. These
should be made entrys in the dispatch table (the array of RxilFunction
structures) if the ability to "lock" and "unlock" is desired.
The rest of the functions which have not been mentioned here do not need to
be called directly (or at all) for most implementations.
)))))))))))))))))====================((((((((((((((((((((
Commands that we launch will use the secret port as their initial host
address if it is open. If not, they will use the public port.
Functions that we launch will default to having "REXX" as their initial
host address.
Note that in all of the above cases, that these are the values placed
in the RexxInvocation structure when it is created. They most definitly
may be changed to anything the caller desires prior to being used to
launch a macro.
-------------------
Logical Consistency Caveats:
If no secret port is opened, then the "lock" and "unlock" commands are
useless and should NOT be used!
Also, if no secret port is opened, commands having a privlege of
REXX_SECRET will never be executed!
--------------------------------------------------------------------------
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ::
:: Notes ::
:: ::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Don't forget to clear the "rexx_abort" flag after things have aborted
if you have set the RXIL_NO_CLEARABORT flag.
--------------------------------------------------------------------------