FRX This here is a program similar to rx, but different. Like rx, it is used to run ARexx programs. The difference is that it parses its command line into separate arguments before sending it to rexx, and gives them to the rexx program separately by calling it as a function instead of as a command. It can even parse arguments according to a template; more on this below. With rx the rexx program has to separate words of the command line with the PARSE instruction, and there's no good way to read a quoted string as one argument. With frx quoted strings are read as individual arguments, just like with most normal CLI programs. The program can use the ARG() function to fetch them, or use a PARSE instruction with commas to separate the arguments. Asterisks is used to include special characters inside quoted strings (such as quote characters). For example, if you give the command frx Arf one "two--" three "four *"yup*" ?" five and have a rexx program called Arf (in rexx:Arf.rexx) like this: /* Arf - a rexx program */ say arg(1) say arg(2) say arg(3) say arg(4) say arg(5) then it will output the following: one two-- three four "yup" ? five Inside a quoted string, you can use *N for a newline, *E for an escape character, *" for a double quote and ** for an asterisk. An asterisk before anything else is simply discarded. From the rexx program's point of view, a frx command like: frx foo one two three four "five and a half" is as if it had been called in one of these ways in a rexx program: CALL FOO "one", "two", "three", "four", "five and a half" or VAR = FOO("one", "two", "three", "four", "five and a half") frx is pure, just like rx. It does NOT share rx's ability to start RexxMast if it is not running, or to be run from workbench (yet). The rexx function can receive a maximum of 15 args from frx; this is an ARexx limitation. Also unlike rx, it returns a DOS error code value (e.g. 205 = object not found) when it fails. This is useful when you use it in a dos Execute() call, because that way the caller can tell whether it succeeded or failed. One possible application is with the QuikFix feature of Aztec C 5.0 ... if you set the CCEDIT command to be "rx whatever", the C compiler never knows when the rexx program exits with an error, and always resumes the compile on the assumption that the source file is fixed now. With frx, the compiler will quit if the rexx program returns a nonzero result. (frx, like rx, will try to convert whatever string the program returns into an integer, and return an error if this fails.) The possible error return conditions are: if it is unable to send the function invocation to ARexx (no memory or rexx not running), it returns 20 and sets a semi-appropriate dos error code. If the ARexx program returns a non-number, frx returns 10 and sets the error code to 47 (the rexx "arithmetic conversion" error number). If the named rexx program doesn't exist, frx returns 10 and error code 1 (rexx "program not found" error number), and writes an error message. If ARexx returns some other error, the return value and error code are those that ARexx replies with, and the appropriate Rexx error message is written to the screen. (This is often redundant; in most cases ARexx has already written an error message.) If the program returns some other number, both the return code and the error code are set equal to that. If the arguments fail to fit the template (if any), or if there are more than fifteen arguments, it returns 20 and dos error code 120. - - - - - - - - - - - - - - - BUT WAIT, THERE'S MORE! frx can also use an actual BCPL-style template to parse the arguments for a rexx function! If you set it up so that a rexx function called Whatever has a template that reads FROM/A,TO/A,ALL/S,WITH/K and call it as follows frx whatever with cheese infile "the output file" all then Whatever will be called with four arguments, one for each entry in the template, in the order given there. If WHATEVER went like this /* Whatever.rexx - say its arguments */ parse arg from, to, all, with /* note use of commas */ say from "," to "," all "," with then the output would be infile , the output file , ALL , cheese whereas without the template the args would just be passed in the order given with , cheese , infile , the output file with the ALL argument left unparsed. With the template, if the ALL switch or the WITH argument were not given, the corresponding arguments would be empty strings. HOW, you ask, do I give a function a template? You do it with the rexx ClipList. For each function that wants a template, you create a ClipList entry named after the function with "-TEMPLATE" stuck on the end, containing the function's template. In the example above, you would create a ClipList entry named WHATEVER-TEMPLATE. This name MUST BE UPPERCASE. You could do this with a CLI command (like in the startup-sequence) with the rxset program like this rxset WHATEVER-TEMPLATE FROM/A,TO/A,ALL/S,WITH/K or in a rexx program with the SETCLIP() function setclip("WHATEVER-TEMPLATE", "FROM/A,TO/A,ALL/S,WITH/K") The latter method is probably preferable if you're going to set up several templates at once. The template will be applied to any rexx function which frx is used to call, either named as in the template or named with REXX: at the beginning. If the function has a fancier pathname (is in some other directory than REXX:) then put the whole path in the template name and use the identical pathname with frx. Generally when you go to the trouble of setting up a template, your frx command would be set up as an alias, for instance alias what frx rexx:whatever [] The templates it uses are strictly standard; no whitespace allowed, no extra Arp features. They are case insensitive. A badly-formed template will give unpredictable results. See the file Compile.rexx, included with this release, for a full sized real- world example of how frx's template feature can be of value. That file has a long comment at the beginning to explain what it's all about. frx is placed entirely in the public domain by Paul Kienitz.