home *** CD-ROM | disk | FTP | other *** search
-
- 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.
-
-
-
-
- --------------------------------------------------------------------------
-
-