========================== RexxHost.Library ==========================
======================================================================
An Amiga shared library for creating/managing ARexx host environments.
======================================================================

                           -= Background =-

A  friend  of mine was busy developing a stock management program when
he suddenly realized that an ARexx interface would be the only feature
that wasn't already part of his project.  So he started to analyze, to
program,  to  try - just to find out that it would be too much work to
add it.
	Some  months later a programmer who works for the same company
I  am  working  for decided to rewrite his home-brewn assembler/linker
program  to  interface to CygnusEd Professional.  The problem is:  his
program  is written in assembly language, the standard host management
routines are written in 'C'...
	To  simplify  the host creation/management procedure I decided
to  put the required routines as well as some extra code into a shared
library,  easy  to  use  by  ANY  language (can you imagine AmigaBASIC
controlling AmigaTeX?).


                       -= Supplied material =-

        The RexxHostLib package contains the following files:
        -----------------------------------------------------
	FancyDemo..............	Demonstration program
	FancyDemo.c............	Source code for demonstration program

	Interface.asm..........	Library support code
	LibStartup.asm.........	Library support code

	Link.asm...............	Library glue routines

	LibMain.c..............	Library support code
	RexxHostLib.c..........	Library support code
	RexxHostBase.h.........	Library header file

	rexxhost.lib...........	Aztec 'C' linker library
	rexxhost.library.......	Amiga shared library

	MakeFile...............	Library building-instructions

	Library.fd.............	Library function definitions

	testdemo.rexx..........	ARexx demonstration script

	RexxHost.doc...........	This file


                           -= How to use =-

The  rexxhost.library needs ARexx (any version will do, v1.10 is best)
to  work properly.  It needs to be opened EXPLICITELY, i.e.  it is not
forced  into  memory by the ARexx server and CANNOT be loaded with the
addlib() call in rexx-scriptfiles.  An unlimited number of callers may
open   the   library,   it   is   100%   reentrant.    Just  like  the
rexxsyslib.library   the   rexxhost.library   stays  in  memory  until
explicitely expunged (e.g.  via "flushlibs" call from Workbench).
	The  OpenLibrary()  call  returns  a pointer to a RexxHostBase
structure (as defined in the RexxHostBase.h include file).  It has the
following format:

		struct RexxHostBase
		{
			struct Library	 rhb_Lib;
			ULONG		 rhb_SegList;

			struct RxsLib	*RexxSysBase;
		};

The  pointer  to the RxsLib structure represents a pointer to the base
of  the  rexxsyslib.library.  It can be copied by the calling process,
the rexxsyslib.library does not need to be opened explicitely.
	All library functions are "bullet proof", i.e. if the supplied
arguments are illegal the function returns immediately. Note that this
library  only contains basic support functions, you will still have to
do command analysis, parsing and command processing on your own (which
isn't difficult, look at the MinRexx sourcecode for an example).


                           -= Compiling =-

A  Makefile  for Aztec 'C' is supplied.  Note that line 67 in the rexx
include file 'rxslib.h' has to be corrected from:

	WORD rl_NumMsg;	/* pending count */

to:

	WORD rl_PgmMsg;	/* pending count */

or you will get a 'multiple entry' message from the compiler.


                   -= RexxHost.Library Functions =-

CreateRexxHost - Create host MsgPort with supplied name

Usage:
MsgPort = CreateRexxHost(HostName)
  D0                       D0

This  function  tries  to  allocate a public messageport with a unique
name.   If  a  port  with the supplied name does already exist NULL is
returned.


DeleteRexxHost - Remove host MsgPort

Usage:
DeleteRexxHost(MsgPort)
                 D0

A supplied MsgPort is removed from the system, freeing allocated signals
and nodes.


SendRexxCommand() - Send a command to the rexx server

Usage:
Success = SendRexxCommand(HostPort,CommandString,FileExtension,HostName)
  D0                         D0          D1             A0        A1

This  function  causes  the  rexx  server  to  execute  a script file.
HostPort  must  point  to  the host MsgPort, CommandString points to a
string   containing   the   name   of  the  command  to  be  executed.
FileExtension   and   HostName   are   optional   and   may  be  NULL.
FileExtension  defines  the  script  file name extension for this host
(for  standard rexx scripts this is ".rexx", for CygnusEd Professional
it  is  ".ced").   HostName  is  supplied to allow the host to address
different  sub-hosts, such as different windows a text editor may have
open.   This  function returns FALSE (0) if the command cannot be sent
(rexx may not be running) and TRUE (1) if the message has been posted.


FreeRexxCommand() - Free the contents of a RexxMsg

Usage:
FreeRexxCommand(RexxMessage)
                    D0

Having  successfully  called  SendRexxCommand()  the  rexx server will
return the RexxMsg with result flags set.  This kind of message cannot
be  replied (since it already has been replied by the rexx server) but
has  to  be  deallocated.   Be  sure  to examine the result code flags
before you remove the RexxMsg.


ReplyRexxCommand() - Returns a RexxMsg to the rexx server

Usage:
ReplyRexxCommand(RexxMessage,Primary,Secondary,Result)
                     D0         D1      A0       A1

Having received a command from the rexx server the host has to process
it.   Having  processed  it  the RexxMsg has to be replied so the rexx
server  knows  about the result.  Primary and Secondary are the values
to  be  passed in the result flags of the RexxMsg structure, Result is
optional  and  may  be NULL.  It usually points to a string containing
the result (numeric or string) of the executed command.


GetRexxCommand() - Get the first argument from a RexxMsg

Usage:
String = GetRexxCommand(RexxMessage)
  D0                        D0

This  function  is  supported to save the calling program from dealing
with  pointer  offsets  (which  may  be  difficult  with some language
implementations).  It returns a pointer to the first argument entry in
the  supplied  RexxMsg  structure.   This  is  usually a command to be
executed by the host.  If NULL is returned then the RexxMsg is a reply
to a former SendRexxCommand() command.


GetRexxArg() - Get the first argument from a RexxMsg

Usage:
String = GetRexxArg(RexxMessage)
  D0                    D0

This  function  is  supported to save the calling program from dealing
with  pointer  offsets  (which  may  be  difficult  with some language
implementations).  It returns a pointer to the first argument entry in
the supplied RexxMsg structure.  This is function does almost the same
as GetRexxCommand(), the string pointer is always returned, no RexxMsg
type consideration is done.


GetRexxResult1() - Get the first RexxMsg result code

Usage:
Result = GetRexxResult1(RexxMessage)
  D0                        D0

This  function  is  supported to save the calling program from dealing
with  pointer  offsets  (which  may  be  difficult  with some language
implementations).  It returns the value of the first result code entry
in the supplied RexxMsg structure.


GetRexxResult2() - Get the second RexxMsg result code

Usage:
Result = GetRexxResult2(RexxMessage)
  D0                        D0

This  function  is  supported to save the calling program from dealing
with  pointer  offsets  (which  may  be  difficult  with some language
implementations).   It  returns  the  value  of the second result code
entry in the supplied RexxMsg structure.


GetToken() - Get the next argument from a string

Usage:
Argument = GetToken(String,StartChar,AuxBuff,MaxLength)
   D0                 D0      D1       A0       A1

GetToken()  implements easy argument parsing.  ARexx posts commands as
null-terminated   strings   with   arguments   separated   by  spaces.
GetToken()  takes a pointer to the command string (String) , a pointer
to  a  counter  variable  (StartChar,  must be a long), a pointer to a
buffer the next argument will be copied to (AuxBuff) and the length of
the  buffer  the  next  argument  will  be copied to (MaxLength).  The
result will a pointer to AuxBuff if an argument was found, NULL if the
end of the command string was reached.


GetStringValue() - Return the numeric value of a string

Usage:
Value = GetStringValue(String)
  D0                     D0

Just  like the 'C' language atoi() function GetStringValue() evaluates
the contents of a string.  Its value is returned as a long word.  This
function  helps  to  analyze  the contents of a RexxMsg result code or
command argument.


BuildValueString() - Turns a number into a string

Usage:
String = BuildValueString(Value,String)
  D0                        D0    D1

This  function helps to build a string from a numeric value, just like
the  'C'  language  itoa() function.  The supplied string must be long
enough  to  hold  the digits built from Value.  A pointer to the built
string is returned.


                            -= Credits =-

The  rexxhost.library  was  built  from example source code written by
Gary  Samad  &  Bill  Hawes  (fancydemo.c),  extensions  &  additional
functions  were created by Olaf 'Olsen' Barthel.  The library skeleton
code  was  created  using  a  customized  version of Edwin Hoogerbeets
"MkLib"  utility which is based on example source code by Jimm Mackraz
& Neil Katin.

The  entire  contents  of  this  library  package  may be used for any
purpose,  no  regard  whether commercial or non-commercial.  No credit
must be given to the creator, nor must a registration fee be paid.

                     This IS TRULY PUBLIC DOMAIN!

                             -= Author =-

                         Olaf 'Olsen' Barthel
                               MXM Gbr
                          Brabeckstrasse 35
                          D-3000 Hannover 71

                     Federal Republic of Germany

                       Phone: (05 11) 52 23 38
