home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
libraries
/
rexxhostlib_403
/
rexxhost.doc
< prev
next >
Wrap
Text File
|
1990-11-17
|
20KB
|
460 lines
====================== RexxHost.Library v36.14 =======================
======================================================================
An Amiga shared library for creating/managing ARexx host environments.
======================================================================
========================== IMPORTANT NOTICE ==========================
======================================================================
This is the official new release of rexxhost.library. Due to register
rearrangements programs compiled using the old 1.6 release have to be
recompiled or serious system crashes will result! Note that the
supplied library code can only be recompiled under Aztec 'C' 5.0.
============================= 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 and some extra code into a shared
library, easy to use by ANY language (can you imagine AmigaBASIC
controlling AmigaTeX?).
As soon as the Aztec 'C' 5.0 update came in, the library has
been updated to take advantage of the new compiler features. I
suppose the source code can be seen as a real 'treasure' for
programmers who also wish to build shared libraries with the new Manx
compiler but find the original Manx support code a bit too confusing.
========================= Supplied material ==========================
======================================================================
The RexxHostLib package contains the following files:
-----------------------------------------------------
FancyDemo.............. Demonstration program
FancyDemo.c............ Source code for demonstration program
LibStartup.asm......... Library support code
LibMain.c.............. Library support code
PreInclude.c........... Source for precompiled header
file
RexxHostLib.c.......... Library support code
rexxhostbase.h......... Library header file
StringAsm.asm.......... Assembly language string routines
rexxhostlat.lib........ Lattice 'C' linker library
rexxhostnew.lib........ Aztec 'C' 5.0 linker library
rexxhostold.lib........ Aztec 'C' 3.6 linker library
rexxhost.library....... Amiga shared library
MakeFile............... Library building-instructions
rexxhost_lib.fd........ Library function definitions
TestDemo.rexx.......... ARexx demonstration script
RexxHost.doc........... This file
Glue.LZH............... LhArc archive containing library
glue routine source codes
============================= 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 LibNode;
struct RxsLib *RexxSysBase;
};
The pointer to the RxsLib structure represents a pointer to the base
of rexxsyslib.library. It can be copied by the calling process,
rexxsyslib.library does not need to be opened explicitely.
All library functions are "bullet proof", i.e. if the supplied
arguments are illegal the functions return 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 DClockHandler.c sourcecode for
an example).
============================= Compiling ==============================
======================================================================
A Makefile for Aztec 'C' 5.0 is supplied. This version CANNOT be
recompiled under compiler versions previous to 5.0. Note that line 67
in the ARexx 'C' include file 'rxslib.h' has to be changed from:
WORD rl_NumMsg; /* pending count */
to:
WORD rl_PgmMsg; /* pending count */
or you will get a 'multiple entry' message from the compiler (Bill
obviously overlooked the misspelled entry). In order to recompile the
library the following symbol must be defined in your header files:
#define AG_CloseLib 0x00090000
The linker requires a library which contains glue codes for all
rexxsyslib.library routines (rexx.lib).
===================== RexxHost.Library Functions =====================
======================================================================
CreateRexxHost - Create a RexxHost with supplied name
Usage:
RexxHost = CreateRexxHost(HostName)
D0 A0
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. The name of the HostPort to be created is copied so there
is no need to keep it statically initialized in you application.
Note: NEVER use this function if you only want to allocate a general
purpose MsgPort. Some additional type checking is done in this
routine. A RexxHost is an extended MsgPort structure with some
additional data which allows all library functions to test if a host
address is valid. You should rather see a RexxHost as a MsgPort. Do
not rely on the existence of the flags following the MsgPort
structure.
DeleteRexxHost - Remove RexxHost
Usage:
NULL = DeleteRexxHost(RexxHost)
D0 A0
A supplied RexxHost is removed from the system, freeing allocated
signals and nodes. A NULL-pointer is always returned so user can do
'Host = DeleteRexxHost(Host);'. Never use this function to remove a
general purpose MsgPort from the system list, in which case
DeleteRexxHost() is guaranteed to return immediately without doing
anything.
SendRexxCommand() - Send a command to the rexx server
Usage:
Success = SendRexxCommand(RexxHost,CommandString,FileExtension,HostName)
D0 A0 A1 A2 A3
This function causes the rexx server to execute a script file.
HostPort must point to the host RexxHost, 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)
A0
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)
A0 D0 D1 A1
Having received a command from the rexx server the host has to process
it. After that 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 command having been executed.
GetRexxCommand() - Get the first argument from a RexxMsg
Usage:
String = GetRexxCommand(RexxMessage)
D0 A0
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 A0
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 function is almost identical to
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 A0
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 A0
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 A0 A1 A2 D0
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 be a pointer to AuxBuff if an argument was found, NULL if
the end of the command string was reached. You are to make sure that
the string pointed to by AuxBuff is long enough to hold the arguments.
GetStringValue() - Return the numeric value of a string
Usage:
Value = GetStringValue(String)
D0 A0
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 numeric value into a string
Usage:
String = BuildValueString(Value,String)
D0 D0 A0
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.
RexxStrCmp() - Compare two strings ignoring case
Usage:
Match = RexxStrCmp(String1,String2)
D0 A0 A1
This function is intended to be a replacement for the 'C' function
strcmp(). Other than the builtin strcmp, RexxStrCmp ignores the case
of both strings and even handles international characters correctly
(i.e. RexxStrCmp("äöüß","ÄÖÜß") == 0). The value returned as Match
is 0 if both strings are considered equal, any other value indicates
that both strings are different.
GetRexxMsg() - Get a RexxMessage from a RexxHost
Usage:
RexxMsg = GetRexxMsg(RexxHost,WaitForIt)
D0 A0 D0
Use this function rather than calling GetMsg, since it does RexxHost
type checking. As a special option, it will wait for a message to
arrive if none is present yet. RexxHost must point to a valid
RexxHost MsgPort structure, WaitForIt must be FALSE (= 0) if you want
this function to return immediately if there are no RexxMessages
pending, TRUE if otherwise.
SendRexxMsg() - Send a command to a Rexx host
Usage:
Result = SendRexxMsg(HostName,MsgList,SingleMsg,GetResult)
D0 A0 A1 A2 D0
Programs who wish to communicate directly with a Rexx host rather than
posting lots of scriptfiles call this function. HostName must point
to null terminated string describing the name of the Rexx host to
receive the command, MsgList points to an array of null terminated
strings, SingleMsg points to a null terminated string. Note: Either
MsgList or SingleMsg must be NULL. The MsgList is copied directly
into the 16 argument vectors of a RexxMsg. SingleMsg will be put into
argument vector zero. Set GetResult to TRUE if you want a result to
be returned. Note that this function works synchronously and waits
until the reply to the message arrives.
GetRexxString() - Obtain and deallocate a result string
Usage:
GetRexxString(ResultString,DestString)
A0 A1
The secondary result code returned in a RexxMsg can be a string or a
number. To save system memory the string has to be deallocated. This
function performs two actions for you: it copies the result string
into a supplied buffer and deallocates the original string afterwards.
Note: make sure the result you pass this function is really a string
and not a number or you will deallocate innocent memory. ATTENTION!
There is a very good chance that non-standard result strings (such as
returned by CygnusEd Professional 2.xx) cannot be deallocated by this
function. CEDPro2.xx does not use the standard RexxArg structure for
string results, but stores the length of the string being returned in
the first longword in front of the first character. Sometimes this
string is not even null-terminated!
GetRexxClip() - Find a Rexx clip by name and return one argument
Usage:
ArgX = GetRexxClip(Name,WhichArg)
D0 A0 D0
The rexx clip list is searched for a rexx resource node. Returned is
either Arg1 or Arg2 depending on the value you pass as WhichArg: a
value of 0 will return Arg1, 1 returns Arg2.
============================== Nuisance ==============================
======================================================================
The library could be shorter if the Aztec 'C' linker 'LN' generated
proper hunks:
1) DATA and BSS hunks are intermixed; as a result the BSS hunk turns
out to have length zero which will still force DOS to allocate four
extra bytes which are never used.
2) Additionally the DATA/BSS hunk has to be zeroed 'manually' which
requires some extra code in crt0.a68.
3) Even if you don't request a BSS hunk the linker still generates
one. The - empty - hunk (including superfluous relocation
information) occupies disk space it doesn't need.
Is there any chance this 'kludging' will ever be fixed?
============================== Credits ===============================
======================================================================
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 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
(though I wouldn't mind if anybody did).
THIS IS TRULY PUBLIC DOMAIN!
=============================== Author ===============================
======================================================================
Olaf 'Olsen' Barthel, MXM
Brabeckstrasse 35
D-3000 Hannover 71
Federal Republic of Germany
Phone: (05 11) 52 23 38
============ Revision history (most recent change first) =============
======================================================================
36.14 This release fixes a potential bug in the GetToken routine
(Stefan Sticht discovered it). Tokens may be separated by any
blank character (such as tabs, spaces, newlines, etc.). The
Rexx clip list can be scanned using a new function:
GetRexxClip. Due to a bug to be found in the 'C' compiler I
had to remove the inline library calls and to turn off code
optimization in the LibMain module. Code size climbed by
about 400 bytes.
35.13 Added new functions (GetRexxMsg, SendRexxMsg and
GetRexxString) which I found missing for the last few
revisions. I also rewrote parts of the library code to get
rid of those nasty 'goto' statements.
34.12 The library can be recompiled using 16 bit integers now. I
don't know if anybody profits from this feature but it's
included anyway. By the way: code size went up to 2912
bytes.
34.11 The library went through the third major rewrite, along with
some more cleanups (nobody told me that the NULL-function has
to be supported) assembly language string-routines were
introduced to reduce the amount of support-library code. Code
size dropped to 2840 bytes.
34.10 Some more cleanups in RexxStrCmp and other routines were
really necessary. As a result, code size went up to 2900
bytes.
34.9 Added more sanity checks in the Rexx Host creation/management
procedure. An extended MsgPort structure with additional type
data holds the interface now. Library code and data are now
much more compact than in the previous releases (I spent two
additional days debugging the code). Library size should be
2792 bytes now.
34.8 ANSIfication, more cleanups, added RexxStrCmp, rewrote
CreateRexxHost/DeleteRexxHost to become shorter, made library
use #pragma calls rather than to rely on the rexxglue.asm
output file. Code size went down to about 2764 bytes (original
size: 3512 bytes).
34.7 Ported to Aztec 'C' 5.0, the strange library creation
procedure consumed lots of time (in which the author consumed
lots of cups of coffee).
1.6 Initial creation using MkLib & elib.