If you are an Amigoid to whom one or more of the following statements applies: 1. You always wanted to learn ARexx but the fact that it can't even flash the screen by itself bothered you (well I know that there is \007), 2. You badly need quick and easily created wrapper-programs for your new great E routines using ARexx's monitoring capabilities, 3. You want to write something really useful as PD, Shareware or something, but don't know what people out there would need and truly appreciate, 4. You want to start programming in E in an unconventional way, 5. You need some speial and quick functions for your ARexx scripts, 6. You often listen to those PC/Macintosh los... sorry -- 'users' and begin to envy them their 'servers' and stuff, 7. You have your nose more or less in the middle of your face... THIS IS FOR YOU ! IT WILL MAKE YOU HAPPY ! What it is you're asking? Well this is a E module, called rexxHostC.m, two sources as example of using it, and this ReadMe. The module provides you with an extremely user-friendly 'engin' for writing Rexx function-hosta (i.e. servers). Take a look on the 'mini_host.e' file to see how concise can an E program be! And it really provides ARexx with a Intuition function! The executable is 5112 bytes big. The engin is object-oriented, it has been pretty thoroughly tested, and it returns all memory used. What else can I say...? Here comes the HOW-TO. --------------------------------------------------------------- After creating an instance of a rexxHostC object, by calling NEW rexxHostC() with required parameter/s, the program by itself will open rexsyslib.library, create a public port with the provided or default name, add it to ARexx's host list and [possibly after executing some user-provided function] enter a loop waiting for ARexx function-calls, intercepting them and executing. This loop will be broken if either: 1. COMMAND 'bye' arrives at its port 2. the program got ^C 3. the method break() is executed [directly or not] by any callback and then our instance of the rexxHostC object will do the cleanup, that is: reply the outstanding messages, delete the port, close the rexsyslib.library etc. and commit suicide. In most cases the host will terminate [unless, for some strange reason, you decide otherwise and put lots of other code after it]. The rexxHostC class has quite a few methods, but you don't need most of them if you don't want them; they are only there to help you. Notice that the 'mini_host' demo uses no other method but the constructor! Here comes short description of the available methods: --------------------------------------------------------------- CONSTRUCTOR: rexxHostC( callback_list, name = 'rexx_host', host_priority = -50, func_ptr = NIL ) where: callback_list ------------- is a list of pairs: [ S, C, S, C, ... , S, C ] 'S' being an UPPERCASE string like 'BEEP' or 'BYE_BYE' [quotes included!], representing the name of the function you are adding to ARexx 'C' is a callback i.e. a pointer to a PROC'ess; it can also be a quoted expression, a string like 'I love this\n', or just NIL; in the last case ARexx will not find any function with this callback's name -- just as if the name-string was not there. This callback-list is [roughly] checked for validity and if it doesn't conform exception 4 i.e. ERR_BADLIST will be raised. Callbacks take no arguments [not directly anyway] and return either nothing or [nicer thing to do] a string [not necessarily an EString] like 'this is your callback speaking', 'TRUE', or '666'. ARexx will by himself [!] translate those strings that represent numbers [like the last one here] to numbers. It is as easy as that for direct values, for variables you will probably use the supplied routines longToStr() and charToStr(), which turn an integer like 69 or a char like "A" into a string for ARexx. See the 'big_host' demo-source for that. As to callbacks' arguments there are three support routines supplied for that purpose: getNumArgs(), getStr( index ) and getNum( index ), read later on about them. name ---- [optional] is a string representing name for your message-port which must be different from all currently present public ports present in the system or you will get exception 2 i.e. 'ERR_NOTUNIQUE'. host_priority -------------- [optional] is the priority AMONG all Arexx libraries and hosts. It is NOT any task priority, so don't be too surprised at the low default value. In fact you SHOULD NEVER USE HIGHER priority than any of the libraries/hosts you will be calling, DEADLOCK will result otherwise! I would personally never attempt anything over 0. 'host_priority' value will be clipped to a number between -100 and 100. func_ptr -------- is the [optional] pointer to function you want executed AFTER setup is completed, probably nothing more important than announcing that it is waiting for Rexx messages. Note that 'callback_list' is the only argument you must give the constructor. Another unusual thing is that we have no public destructor. --------------------------------------------------------------- num := getNumArgs() ------------ returns the number of arguments the function in question got from ARexx, it will be something between 0 and 15. --------------------------------------------------------------- string, fGood := getStr( index ) --------------- gives you the argument number 'index' as a string, the second BOOLEAN return-value tells you whether this argument is valid, that is -- if it really came from ARexx [this you might already know if you have previously called getNumArgs()]. N.B. It starts from 1, as the argument #0 is the command itself! --------------------------------------------------------------- num, fGood := getNum( index ) --------------- gives you the argument number 'index' as an integer, the second BOOLEAN return-value tells you whether this argument is valid, that is -- if the argument-string with this index string really came from ARexx and if it is a number. N.B. It starts from 1, as the argument #0 is the command itself! --------------------------------------------------------------- break() ------- breaks the waiting/receiving/executing loop and kills the rexxHandlerC object. --------------------------------------------------------------- str := longToStr( long ) ----------------- str := charToStr( char ) ----------------- as already said, these functions will turn an integer or a char respectively into a string just as ARexx wants it for a return-value from its function, it is only needed for variables, the direct values can be returned with strings like '123' or 'oui monsieur'. --------------------------------------------------------------- major, minor := version() --------- returns major and minor version number of the rexxHostC.m the current values are bye the way: 0 and 4 ======================================================================= EXCEPTIONS that might be raised by rexxHostC-object: "MEM" meaning: 'not enough memory' "REXX" meaning: 'rexxsyslib.library not found' ERR_NONAME = 1 meaning: 'I got NIL as port-name' ERR_NOTUNIQUE = 2 meaning: 'port-name not unique' ERR_LISTNIL = 3 meaning: 'callback-list ptr NIL' ERR_BADLIST = 4 meaning: 'bad callback-list' ERR_NOTADDED = 5 meaning: 'host not added to ARexx list...' --------------------------------------------------------------- LIMITATIONS: There are two major I can think of: 1. As all other similar Rexx hosts I met [for example RexxFuncHost by Donald T. Meyer] one such active host screens all other from receiving function-calls; so that ONLY ONE CAN BE EFFECTIVE AT ANY TIME. This is due to the fact that, differently than with libraries, ARexx will not send your function-call to any other host whatever error was reported by the one that received it. It would be possible to find a solution to that -- if I still feel any urge to play with this piece of software I might do that -- but in practice it shouldn't be so much of a problem considering E's lightning speed of compilation. If you already have the callbacks, you can create a new host in couple of minutes and launch it in place of the previously running one. It might even be possible to have dynamically created callback-lists: if/when we start to get flooded with great PD/ShareWare/commercial modules containing just callback-lists and callbacks themselves [there would be some problems with getting the arguments for the callbacks though], you would be able to manage them dynamically from ARexx to be included in just one rexxHostC-based server. 2. UPPER/lower case does not matter for all function-calls. It wouldn't be any problem to implement this as optional, but I doubt whether it would be so useful. Both ARexx and AmigaDOS tend to be case-insensitive in most cases, and preventing ARexx from turning the name in your function-call to uppercase requires additional work. This was written in E v3.0b and v3.1a [registered version], by Piotr Obminski in December 1994. It is, an off-spin of a much larger project, but I found it so cute that I decided to polish it and present it to the so called 'Amiga community' [as community service]. The example-proggies are PD, but the rexxHostC.m is Copyrighted FreeWare by me that is Piotr Obminski.