home *** CD-ROM | disk | FTP | other *** search
- ====================== RexxHost.Library v37.1 ========================
- ======================================================================
- 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.
-
- ============================= 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 Barthel
- Brabeckstrasse 35
- D-3000 Hannover 71
-
- Federal Republic of Germany
-
- I may also answer questions asked via electronic mail. My email
- addresses are:
-
- Z-Netz: O.BARTHEL@A-LINK-H
- Usenet: o.barthel@a-link-h.comlink.de
- olsen@sourcery.mxm.sub.org
-
- ============ Revision history (most recent change first) =============
- ======================================================================
- 37.1 Recompiled for use with Kickstart 2.0.
-
- 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.
-