home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 291.lha / RexxFunctionHostPack_v1.2 / RexxFuncHost.doc < prev    next >
Text File  |  1992-09-02  |  12KB  |  303 lines

  1.  
  2.     -------------------------------------------------
  3.     |                        |
  4.     |      Rexx Function Host Package        |
  5.     |          Version 1.2            |
  6.     |           02-Sep-89            |
  7.     |                        |
  8.     |                        |
  9.     |                        |
  10.     |    Copyright © 1989, Donald T. Meyer    |
  11.     |                        |
  12.     -------------------------------------------------
  13.  
  14.  
  15.  
  16. The Rexx Function Host Package, hereafter abreviated as FHP, is a 'C'
  17. source code module which facilitates writing function hosts for ARexx. 
  18. The intent of this document is to give some background on ARexx function
  19. hosts, and then describe how the FHP handles the implementation of them.
  20.  
  21. The FHP will handle most of the details involved in writting your own
  22. function host.
  23.  
  24. The code in "rexxfunchost.c" can be modified if desired, but what was
  25. intended is a module that can be compiled once and then linked into any
  26. and all function hosts that you write.
  27.  
  28. In most cases, the code in "rexxfunchost.c" can be used as is, with the
  29. specific routines you write to handle ARexx function invocations
  30. contained in a seperate module or modules (i.e.  "rh_demo.c").
  31.  
  32.  
  33.  
  34.  
  35.         ARexx and External Functions
  36.  
  37.  
  38. ARexx has the ability to use external functions contained either in a 
  39. standard Amiga shared library, or in a special program called a 
  40. function host.  Either of these must be specialy written for use with 
  41. ARexx.  You cannot directly use a "normal" library, such as 
  42. icon.library, intuition.library, etc.
  43.  
  44. For ARexx to "know about" a library or function host, you must first 
  45. add it to a special list kept by ARexx, the Library List.  This can be
  46. done either by issuing a command from the CLI, or via a function from
  47. within an ARexx program. Once the library or function host has been
  48. added to the ARexx Libray List, whatever functions they contain will
  49. then be available to ARexx programs.
  50.  
  51. The function host is responsible for function "binding".  ARexx passes
  52. a message to the function host, which then performs an internal search
  53. for the desired function name.  If that function is contained within the
  54. host, it is called to handle the function's activitys.
  55.  
  56.  
  57.  
  58.  
  59.         Function Hosts vs. Librarys
  60.  
  61.  
  62. Using either a function host or a library will achieve almost  the same
  63. end result: adding new function calls to ARexx.  There are  some fairly
  64. major differences however.
  65.  
  66.     Disadvantages:    Calls are not easily made reentrant
  67.             Must be explicitly run
  68.  
  69.     Advantages:    Easier to debug
  70.             Inherent call queueing
  71.             Individual stack
  72.             Individual priority
  73.             Asynchronous operation possible
  74.  
  75.  
  76. First, the disadvantages.
  77.  
  78. Consider what happens if two ARexx programs call the same external 
  79. function at the same time.  In a properly written library, both will
  80. execute at the 'same' time.  In a function host, the  first one that
  81. makes the call will get the use of the function host,  and the second
  82. call will have to wait until the first completes. Although it would be
  83. possible to start a task to handle each function called, if multiple
  84. calls need to execute simultaneously, a library would probably be a
  85. better choice in this case.
  86.  
  87. A function host must be explicitly executed prior to being accessed. 
  88. This would normally be done in the startup-sequence script.  A library
  89. must merely reside in the LIBS: directory. On the other hand, the
  90. library is subject to being removed from memory if not open, whereas a
  91. function host is not.  This could actually be an advantage depending on
  92. the circumstances.
  93.  
  94.  
  95. Now, the advantages which a function host has over a library.
  96.  
  97. From a 'C' and source-level debugger standpoint, function hosts are
  98. easier to debug since they are essentially just normal programs, happily
  99. recieving  messages and returning them.
  100.  
  101. If you wish to do things which may require interaction with the user
  102. other than through just calling a function, such as allowing the user to
  103. manipulate a scrollgadget for things displayed
  104. via calls to the function host.
  105.  
  106. If the functions are such that only one ARexx program could use  them at
  107. a time, the function host provides an inherent  locking and queueing
  108. mechanism.  This is due to the fact that function requests arrive as
  109. messages, which are automaticly queued by Exec. A typical example of
  110. something non-shareable would be a hardware device such as a printer.
  111.  
  112. When a library function is called, the stack used is the caller's. 
  113. Since a function host is a totally seperate processs, the stack used is
  114. it's own.  This also applies to process priority, although this is
  115. fairly easy to adjust "on the fly" if needed.
  116.  
  117. Another possible benefit of being a seperate process, is that of
  118. asynchronous execution.  A function host can be written such that it
  119. returns the message back to ARexx before the desired function actions
  120. have been taken.
  121.  
  122.  
  123. Although most of the advantages provided by a function host can be
  124. incorporated into a library through clever programming, they happen
  125. "naturally" in the function host.  Even if the desired end result is a
  126. function library, implementing a function host for ease of testing may
  127. still be worthwhile.
  128.  
  129.  
  130.  
  131.  
  132.         What a Function Host Does
  133.  
  134.  
  135. A typical function host will perform the following steps:
  136.  
  137.     1) Start executing, normally as a detached background task.
  138.  
  139.     2) Open neccessary libraries, allocate needed memory, etc.
  140.  
  141.     3) Open a public Exec message port.
  142.  
  143.     4) Wait for a RexxMsg message from ARexx.
  144.  
  145.     5) Dispatch the function call.
  146.  
  147.     6) Process the function call.
  148.  
  149.     7) Return the message to ARexx.
  150.  
  151.     8) Wait for the next message...
  152.  
  153.     9) Cleanup and exit.
  154.  
  155.  
  156.  
  157. Here are the details about what the code in "rexxfunchost.c" does to 
  158. perform the above steps.
  159.  
  160.  
  161.     1) Start executing, normally as a detached background task.
  162.  
  163. Invocation can be from either CLI or WorkBench.  We probably want a 
  164. specific stack size and execution priority.  If we are launched by the
  165. Workbench, the icon .info file can contain the desired stack size.  
  166. This does not help us on priority, though we can change that "manualy"
  167. by making an exec library call.  But from CLI, we would wind up with 
  168. whatever stack the CLI defaulted to, and we would also prevent that  CLI
  169. from accepting further command until we ended our execution.  
  170.  
  171. Lattice and Manx 'C' address these problems quite handily with startup
  172. code which detaches us from the CLI. *** what _exactly_ happens from
  173. workbench with cback.o? *** This startup code allows us to explicitly
  174. request our stack size,  priority, and also frees the CLI for further
  175. command entry.  There are some slight differences in the way Lattice and
  176. Manx handle this.  The  FHP is written for Lattice, but should compile
  177. under Manx with minor changes.
  178.  
  179. If there is already an instance of this function host running, some
  180. additional actions must take place. If launched from the WorkBench we
  181. assume that the reason our icon has been double-clicked again is to
  182. remove the function host. To do this, we send a break signal to our
  183. "twin", and then exit ourselves.  To cause this to happen from the CLI,
  184. we must use a command line option  "-q" to cause the termination of an
  185. existing "twin". The FHP handles all the logical decisions involved  in
  186. deciding what to do, and displays appropriate messages telling the  user
  187. what is being done.  These messages are defined in your code, so as to
  188. allow easy control of just what is displayed.
  189.  
  190.  
  191.     2) Open neccessary libraries, allocate  needed memory, etc.
  192.  
  193. The FHP always opens the rexx library.  A call is then made to a
  194. function named client_init() which should be in your code.  This is the
  195. place to do any initialization required by the functions in your
  196. function host.  Returning a pointer to a string will cause it to be
  197. displayed, and the FHP to abort.  A NULL return indicates success.
  198.  
  199.  
  200.     3) Open a public Exec message port.
  201.  
  202. This is the way that ARexx will send function calls to function hosts.
  203. This must be a public port, so that ARexx can FindPort() it dynamicly as
  204. it searches the Library List.
  205.  
  206. At this point, the FHP will also automaticly add itself to the ARexx
  207. Library List.  This is done by sending a message to the ARexx resident
  208. process. The FHP will also handle removing itself from  this list when
  209. it terminates.
  210.  
  211.  
  212.     4) Wait for a RexxMsg message from ARexx.
  213.  
  214. With all setup operations complete, the FHP now Wait()s for one of two
  215. events.  Upon recieving a function invocation message at the public
  216. port, it will proceed to process the function call. The other event
  217. which will wake up the FHP is the ctrl-C break signal. This signal will
  218. normally be sent by another invocation of this function host, although
  219. it can be sent via Signal() from any Amiga task.
  220. In the 1.2 release of this module, a ULONG variable client_event_flags has
  221. been added.  This will allow client code to set events it needs to Wait()
  222. on as well.  A client even will result in a call to the
  223. client_event_handler() function, which should be in the client code.
  224.  
  225.  
  226.     5) Dispatch the function call.
  227.  
  228. When a function invocation message is recieved, the FHP will handle
  229. several of  the details. First and foremost, the FHP code will determine
  230. whether or not the function being called is in our function host.  It
  231. does this based on parameters stored in the array func_table.  This
  232. array, which is defined in your code, contains four parameters for each
  233. function which control how the FHP handles the function dispatching.
  234.  
  235. First, the name of the function is defined, followed by the address of
  236. the 'C' routine which will perform this function's actions.
  237.  
  238. Next, a numeric parameter which specifys how many arguments this 
  239. function call should have.  If the number of arguments passed in the 
  240. ARexx function call is incorrect, the FHP will return an error to 
  241. ARexx.  This can also be set to -1 to indicate that the FHP should 
  242. perform no checking of the parameter count.
  243.  
  244. And last, a boolean flag indicating whether or not this function name 
  245. is case-sensitive or not. If the case flag is set to FALSE, than case
  246. will be ignored when searching for the function name.
  247.  
  248. Once the FHP has determined that the desired function is here, and  that
  249. the parameter count is correct, whatever 'C' routine you have  written
  250. to handle the function is called, with a pointer to the  rexxmsg as the
  251. sole argument.
  252.  
  253.  
  254.     6) Perform the function
  255.  
  256. The function handler routine in your code is passed a pointer to a 
  257. RexxMsg structure.  Using this pointer, the arguments to the function
  258. (if any) can be accessed, and proper return code or value can be set.
  259.  
  260. The arguments are passed as pointers to strings.  These pointers are in
  261. the RexxMsg structure member rm_Args[].  There can be 15 arguments
  262. passed here (argument 0 is a pointer to the function name itself).
  263. These arguments are accessed thusly:  rexxmsg->rm_Args[1]
  264. The details of how arguments are passed and results returned are
  265. contained in the ARexx manual.  The example functions in "rh_demo.c"
  266. demonstrate recieving basic arguments, and returning both errors and
  267. result strings. 
  268.  
  269. To ease the task of returning a value string to ARexx, a helper 
  270. function is included in the FHP. This function, SetResultString(), takes 
  271. a pointer to a RexxMsg (which should of course be the one passed from 
  272. the FHP initialy) and a pointer to a string.  This function will then 
  273. allocate the RexxArg and place it into the RexxMsg structure.  If a 
  274. NULL is given as the string pointer (not to be confused with a null 
  275. string!), a general failure code will be set in the RexxMsg structure.
  276. An error will also be set if the allocation of the RexxArg fails.  
  277. This should happen only in cases of low or fragmented system memory.
  278.  
  279.  
  280.     7) Return the message to ARexx.
  281.  
  282. Upon returning from your 'C' routine, the FHP will return the message to
  283. ARexx and wait for the next function call to arrive.
  284.  
  285.  
  286.     8) Wait for the next message...
  287.  
  288. Loop back to step #4.  The FHP stays in this loop until a Control-C break
  289. signal is recieved.
  290.  
  291.  
  292.     9) Cleanup and exit.
  293.  
  294. This step is reached upon recieving the termination signal. Again, a
  295. function defined in your code, client_cleanup() is called. This is where
  296. any libraries opened, memory allocated, etc. by the call to
  297. client_init() should be closed or freed.
  298.  
  299. NOTE: This routine will be called regardless of the reason for the FHP's
  300. exiting.  Your cleanup routines should be prepared to be called before
  301. or after client_init() has executed.
  302.  
  303.