CONTENTS | INDEX | PREV | NEXT
SPECIFYING YOUR PROGRAM'S REXX HOST NAME
DICE initializes RexxPort *before* your main() is called, and uses the
contents of the RexxHostName variable at that time. Therefore, when
implementing an ARexx interface you normally set the variable using static
initialization, that is:
char *RexxHostName = "name_of_my_port";
Setting up the variable in main(), or even in _main() will be too late.
If you declare RexxHostName = NULL then DICE will not initialize an
ARexx port (you can do so manually from main() in that case by calling
either CreateDiceRexxPort() or CreateGlobalDiceRexxPort() with a NULL
port).
DICE will also use the contents of this variable for your default ARexx
script extension.
PARSING
When adding REXX support into your program note that you must parse the
argument string yourself. The first argument (arg0) is broken out of
the RexxMsg for you and in simple instances, as in our test program
above, you do not even have to reference the RexxMsg passed to you.
As far as return values go, you must return a result code and may also
optionally setup a result string. DICE will duplicate the contents of
the string but since you return from your procedure before this occurs
you cannot use a local variable for your result buffer. The result
string is a pointer to a pointer and preinitialized to NULL, so if you
do not return a result you need not bother with it at all.
Result strings are only valid when an error code of 0 is returned.
A pointer to the MsgPort that the ARexx command was received on is also
passed to allow you to determine which project it applies to.
MULTIPLE REXX PORTS
DICE fully supports multiple ARexx ports and can handle arbitrary
nesting of ARexx messages on any given port or amoung several or all
the ports. DICE will properly backout of multiply nested ARexx
commands over multiple ports if the program gets aborted with ^C,
exit(), abort(), whatever...
Refer to the CreateDiceRexxPort() and DeleteDiceRexxPort() command
descriptions below.
CreateGlobalDiceRexxPort() CreateGlobalDiceRexxPort()
void CreateDiceRexxPort(msgPort, name)
struct MsgPort *msgPort;
char *name;
This call integrates any number of ARexx ports beyond the master port
into DICE's ARexx system. This call may be made from any point in your
program. After this call returns the message port will accept
incomming ARexx messages.
Note that for simple programs you can simply use the master port
(RexxPort) that DICE sets up for you automatically and need not bother
with creating additional ports. This call is more of use in more
complex programs which handle multiple projects simultaniously.
msgPort - A blank msgPort structure (that is, totally zero'd out).
DICE will fill the structure with appropriate values.
DICE uses the same signal bit as it allocated for the
master port (RexxPort). Finally, DICE makes the message
port public through the AddPort() call.
If you had declared RexxHostName as NULL causing DICE to
not initialize an internal default RexxPort, you can pass
NULL here to initialize DICE's internal default RexxPort,
thereby allowing PlaceRexxCommand() calls that specify a
NULL port (i.e. to use DICE's internal default RexxPort).
You are not required to use DICE's internal message port,
it is simply convenient.
name - A pointer to the name of the message port. DICE uses this
name verbatim. An error (-1) is returned if the port
already exists. If you had passed NULL for the MsgPort
structure DICE will initialize RexxHostName to name.
RETURN VALUE - 0 is returned on success, -1 on error
CreateDiceRexxPort() CreateDiceRexxPort()
short r = CreateDiceRexxPort(msgPort, name)
struct MsgPort *msgPort;
char *name;
This call integrates any number of ARexx ports beyond the master port
into DICE's ARexx system. This call may be made from any point in your
program. After this call returns the message port will accept
incomming ARexx messages.
Note that for simple programs you can simply use the master port
(RexxPort) that DICE sets up for you automatically and need not bother
with creating additional ports. This call is more of use in more
complex programs which handle multiple projects simultaniously.
msgPort - A blank msgPort structure (that is, totally zero'd out).
DICE will fill the structure with appropriate values.
DICE uses the same signal bit as it allocated for the
master port (RexxPort). Finally, DICE makes the message
port public through the AddPort() call.
If you had declared RexxHostName as NULL causing DICE to
not initialize an internal default RexxPort, you can pass
NULL here to initialize DICE's internal default RexxPort,
thereby allowing PlaceRexxCommand() calls that specify a
NULL port (i.e. to use DICE's internal default RexxPort).
You are not required to use DICE's internal message port,
it is simply convenient.
name - A pointer to the name of the message port. DICE adds a .NN
extension to this name, finding a free slot number when
creating a public message port. If you pass NULL for this
field, DICE will create a private message port suitable for
handling ARexx call-backs. An error (-1) is returned if
no slots are available (all 99 are in use). If you had
passed NULL for the MsgPort structure then DICED will
initialize RexxHostName to the extended name.
RETURN VALUE - the slot number is returned, -1 if an error occured.
DeleteDiceRexxPort() DeleteDiceRexxPort()
void DeleteDiceRexxPort(msgPort)
struct MsgPort *msgPort;
This call deletes a previously created DICE ARexx port. You may NOT
delete any ARexx port while within DoRexxCommand(). This call may only
be made from the top level of your program or you run the risk of
deleted an ARexx port out from under yourself.
You may NOT delete the master ARexx port, only those you specifically
create.
This call automatically clears out any as yet unread messages on the
port, removes the port from the public message list with RemPort(), and
zero's the structure.
PlaceRexxCommand() PlaceRexxCommand()
long PlaceRexxCommand(port, str, &res, &ec)
struct MsgPort *port;
char *str;
char *res;
long ec;
This command sends an ARexx command off to ARexx. The command is
normally a script file to run. You must specify the ARexx port that is
to act as the default host port for the command or NULL to use DICE's
default port. The default extension for the script is always the
RexxHostName variable. Note that if you specify NULL for the port to
use DICE's default, then you must have previously setup DICE's default
port. This occurs automatically if RexxHostName was declared non-NULL,
or manually if you had called Create[Global]DiceRexxPort(NULL, "name").
You supply the command in 'str' which is made Arg0. Currently there is
no support for additional arguments XXX. DICE will run the command
synchronously and return the result code.
The result string pointer will be set to either NULL or a malloc()'d
string. If not NULL you are responsible for free()ing the result
string when you are through with it!! If you wish to ignore any
result you may pass NULL for this argument.
The ec longword will be set to an internal ARexx error code... if the
returned result code is non-zero and ec == 1 then ARexx was unable to
find the specified ARexx command. You may pass NULL for this argument
if you do not care about the error code.
It is possible that your program will receive ARexx commands while it
is waiting for the command you have sent to be returned. DICE will
automatically call DoRexxCommand() from within the PlaceRexxCommand()
routine when this case occurs.
ARexx will set the error-code (ec), which is different from the
result-code. ec is set to 1 if the script could not be found. ARexx
normally returns a severity code of 5 for this case. If the return
code is 0 then ec will be 0.
PlaceRexxCommandDirect() PlaceRexxCommandDirect()
long PlaceRexxCommandDirect(port, remoteName, str, &res, &ec);
...
char *remoteName;
This command is similar to PlaceRexxCommand() but sends the command to
a specification application instead of to AREXX.
ProcessRexxCommands() ProcessRexxCommands()
void ProcessRexxCommands(msgPort/NULL)
struct MsgPort *msgPort;
In order to process incomming ARexx commands you must call the
ProcessRexxCommands() routine when you receive the signal
RexxSigBit (signal mask is (1 << RexxSigBit)).
Passing NULL to this routine will cause DICE to scan ALL KNOWN ARexx
ports belonging to this program... that is, the master port and all
created ports. DICE will call DoRexxCommand() for each ARexx command
received as well as weed out returned messages from any ARexx commands
we have sent that are still in progress.
If you wish, you can pass a specific message port to have DICE only
process ARexx commands received on a specific port, but beware that
your Wait() on the signal bit has cleared the signal and you should be
sure to process all message ports before calling Wait() again, else
risk leaving unprocessed ARexx messages queued in and then blocking in
Wait() !
DoRexxCommand() DoRexxCommand()
long
DoRexxCommand(msg, port, arg0, pres)
void *msg;
struct MsgPort *port;
char *arg0;
char **pres;
DoRexxCommand() is a routine that YOU supply to process incomming ARexx
requests. DICE will call your routine for any requests it processes
with ProcessRexxCommands() as well as for any requests that come in
during processing of a PlaceRexxCommand(). DICE presets *pres to
NULL.
To return an error simply return a non-zero error code.
To return a string set *pres to point to the string and return(0); DICE
will make a copy of the string to return to ARexx but you should note
that since your procedure must return before DICE can do this, you
cannot assign *pres to any local stack variables.
GetDiceRexxPortSlot() GetDiceRexxPortSlot()
int
GetDiceRexxPortSlot(port, nameptr)
MsgPort *port;
char **nameptr;
GetDiceRexxPortSlot() returns the ln_Name field of the specified port
(i.e. the fully qualified port name) and extracts and returns the slot
number. -1 is returned if the port name does not terminate with ".xx"
where xx is a number. If a char ** pointer is passed as nameptr it will
be initialized to point to the ln_Name field of the port.
This call is normally used with port = NULL to obtain information about
DICE's internally setup Rexx port.
port: message port structure to extract ln_Name and slot field from.
You can pass NULL to extract the full name and slot number
selected by DICE when automatic startup is used (i.e. your
declaration of RexxHostName is assigned a non-NULL pointer).
nameptr: a pointer to a char * (that is, a char **) or NULL. If not
NULL the pointer will be assigned the ln_Name field of the
port. Normally used when port is passed as NULL to obtain
the fully qualified rexx port name DICE has constructed for
you in an automatic startup.
RETURN:
slotno: the slot number extracted from the port name or -1 if the
port name is not in the proper format.