home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / JSAGE / ZSUS / TCJ / TCJ31UPD.WS < prev    next >
Text File  |  2000-06-30  |  73KB  |  1,472 lines

  1.                                Z-System Corne≥ (c)
  2.                                  by Jay Sage
  3.                         The Computer Journal, Issue 31
  4.                           Reproduced with permission
  5.                            of author and publisher
  6.  
  7. [This is my column from The Computer Journal issue #31.  Since this articleì
  8. appeared, there have been extensive changes to the ARUNZ parameters.  Youì
  9. should use this article only as a guide to ways to apply ARUNZ.  For theì
  10. actual parameter expressions, please consult more recent documentation.  TCJì
  11. issue #33 has more up-to-date information, for example.  Jay Sage]
  12.  
  13.      In my last column I said that I would discuss the progress I have beenì
  14. making with a new version of ZEX, the memory-based batch processor forì
  15. ZCPR3.  As frequently happens, however, another subject has come up andì
  16. preempted my attention.  I thought I would still get to ZEX later in thisì
  17. column, but the column is already by far the longest I have written.  So ZEXì
  18. and other matters planned for this time will have to wait.  For ZEX that isì
  19. not a bad thing, since I still have a lot of work to do on it, and by twoì
  20. months from now there should be considerably more progress.
  21.  
  22.  
  23.                          L'Affaire ARUNZ: J'Accuse
  24.  
  25.  
  26.      Not too long ago in a message on Z-Node Central, David McCord -- sysopì
  27. of the board and vice president of Echelon -- leveled a serious accusationì
  28. against me: that I have failed to provide proper documentation for my ARUNZì
  29. program.  I immediately decided to mount a vigorous defense against thisì
  30. scurrilous charge using all the means at my disposal, including the awesomeì
  31. power of the press (i.e., this column in The Computer Journal).
  32.  
  33.      Unfortunately, I find my defense hampered by a small technicality. ì
  34. True, many other people, faced with this very same impediment, haveì
  35. seemingly not been discouraged in the slightest from proceeding aggressivelyì
  36. with their defense.  However, I lack the character required to accomplishì
  37. this.  What is this technicality?  It is the fact that the charge is true.
  38.  
  39.  
  40.                               Excuses, Excuses
  41.  
  42.      An effective defense being out of the question, perhaps I can at leastì
  43. offer some lame excuses.
  44.  
  45.      First of all, it is not as true as it seems (if truth has degrees) thatì
  46. I have provided no documentation.  There is a help file, ARUNZ.HLP, that atì
  47. this very moment resides, as it has for years, in the HELP: directory on myì
  48. Z-Node RAS (remote access system).  Way back when ARUNZ was first madeì
  49. available to the user community, Bob Frazier was kind enough to prepare thisì
  50. help file for me, and it was included in the LBR file that I put up on my Z¡
  51. Node.  As a series of upgraded versions appeared, I began to omit the helpì
  52. file to avoid duplication and keep the new LBR files as small as possible. ìèAfter a while, of course, the original library that did include the helpì
  53. file was removed from RASs.  Hence the impression that there is noì
  54. documentation.  Of course, by now that help file is rather obsolete anyway.
  55.  
  56.      If you are observant, you may have caught in the previous paragraph theì
  57. deliberate circumlocution "made available to the user community".  Why did Iì
  58. avoid the shorter and more natural expression "released"?  Because ARUNZ hasì
  59. still to this day (more than two years -- or is it three now -- after itsì
  60. first 'availability'), not actually been released.  Why?  Because I stillì
  61. have not finished it.  It is still in what I consider to be an incomplete,ì
  62. albeit quite usable, state.  A few more tweaks, a couple of additionalì
  63. features, a little cleaning up of the source code, a detailed DOC file . . .ì
  64. and it should be ready for a full, official release.
  65.  
  66.      ARUNZ is, regrettably, not my only program that persists in this state. ì
  67. It is simply the oldest one.  ZFILER and NZEX (new ZEX) suffer similarly. ì
  68. One might even say that this has become habitual with me.  What happens, ofì
  69. course, is that I don't find the time to code that one little crucialì
  70. additional feature before some other pressing issue diverts my attention. ì
  71. And by the time I do get back to it, I have thought of still another featureì
  72. that just has to be included before the program should be released.
  73.  
  74.      One solution would be not to make the programs available until they areì
  75. really complete.  There are two reasons why I have rejected this approach. ì
  76. First of all, though not complete to my satisfaction, the programs are inì
  77. quite usable condition.  It would be a shame if only I -- and perhaps aì
  78. small group of beta testers -- had been able to take advantage of the powerì
  79. of ARUNZ during these two or three years.
  80.  
  81.      The second problem with holding the programs back is that a lot of theì
  82. development occurs as the result of suggestions from other users, who oftenì
  83. have applications for the program that I never thought of and would neverì
  84. think of.  In a sense, I have chosen to enlist the aid of the entire userì
  85. community not only in the testing process but also in the programì
  86. development process.  And I think we have both benefited from thisì
  87. arrangement.
  88.  
  89.      The procedure I have developed for keeping track of these 'released'ì
  90. test versions is to append a letter to the normal version number.  As Iì
  91. compose this column, ARUNZ stands at version 0.9G, ZFILER stands at 1.0H,ì
  92. and NZEX stands at 1.0D.  When final versions are released, I will drop theì
  93. letter suffixes (except for NZEX, which will become ZEX version 4.0).
  94.  
  95.      The usability of the programs is probably the fundamental factor thatì
  96. keeps them in their incomplete state.  When one of them has some seriousì
  97. deficiency or or simply begs for an exciting new feature, it gets myì
  98. attention.  Once it is working reasonably well, however, I can ignore it andì
  99. devote my attention to other things that badly need fixing.  That is how Iì
  100. recently got started on NZEX.
  101.  
  102.  
  103.                                Making Amendsè
  104.      Since excuses, no matter how excusing, do not solve a problem, I willì
  105. take advantage of this column to make amends for the poor state of the ARUNZì
  106. documentation by providing that documentation right here and now.  I hope itì
  107. will lead more people to make more complete and effective use of ARUNZ,ì
  108. which for me has been the single most powerful utility program on myì
  109. computers.
  110.  
  111.      To understand ARUNZ one must first understand the concept of the ZCPRì
  112. alias, and to understand aliases one must understand the multiple commandì
  113. line facility.  I have written some things about these subjects in earlierì
  114. columns, notably in issues #27 and #28, but I will start more or less fromì
  115. the beginning here.
  116.  
  117.  
  118.                            Multiple Command Lines
  119.  
  120.      One of the most powerful features of ZCPR3 is its ability to acceptì
  121. more than one command at a time and to process these commands sequentially. ì
  122. Quoting from my column in TCJ issue #27:  The multiple command capability ofì
  123. Z System ... is important not so much because it allows the user to enter aì
  124. whole sequence of commands manually but rather because it allows otherì
  125. programs to do so automatically.
  126.  
  127.      Obviously, in order to process multiple commands, the list of commandsì
  128. (at least the unexecuted ones) must be stored in some secure place whileì
  129. earlier ones are being carried out.  In the case of ZCPR3, there is aì
  130. dedicated area, called the multiple command line (MCL) buffer, located inì
  131. the operating system part of memory.  It stores the command line togetherì
  132. with a pointer (a memory address) to the next command to be executed.  Everyì
  133. time the ZCPR3 command processor returns to power, it uses the value of theì
  134. pointer to determine where to resume processing the command line.  Only whenì
  135. the end of the command line is reached does the command processor seek newì
  136. command line input.
  137.  
  138.      Storing multiple commands in memory is not the only possibility. ì
  139. Another secure place to keep them is in a disk file.  This is in some waysì
  140. what the SUBMIT facility does using the file $$$.SUB.  The main drawback toì
  141. this approach is the speed penalty associated with the disk accessesì
  142. required to write and read this file.  There is also always the possibilityì
  143. of running out of room on the disk or of the diskette with the $$$.SUB fileì
  144. being removed from the drive.  Using a memory buffer is faster and moreì
  145. reliable.
  146.  
  147.      Digital Research's most advanced version of CP/M, called CP/M-Plus,ì
  148. also provides for multiple command line entry, but it does it in a ratherì
  149. different, and I think less powerful, way.  When a multiple command line isì
  150. entered by the user, the system builds what is called a resident systemì
  151. extension (RSX), a special block of code that extends the operating systemì
  152. below its normal lower limit.  This RSX holds any pending commands.  Butì
  153. since it is not always present and is not at a fixed, known location inì
  154. memory, there is no straightforward way for programs to manipulate multipleìècommand lines.  On the other hand, this method does provide a bigger TPAì
  155. when only single commands are entered.
  156.  
  157.      In a ZCPR3 system, the MCL has a fixed size and is in a fixed location. ì
  158. Moreover, a ZCPR3 program can find out where the MCL is located by lookingì
  159. up the information about it in the ZCPR3 environment descriptor (ENV),ì
  160. another block of operating-system memory containing a rather complete indexì
  161. to the features of the particular ZCPR3 system.  The location of the ENV isì
  162. the one key fact that is conveyed to all ZCPR3 programs.  Prior to ZCPRì
  163. version 3.3, the address of the ENV had to be installed into each programì
  164. manually by the user before the program could be used; with ZCPR33 thisì
  165. installation is performed automatically by the command processor as theì
  166. program is run.
  167.  
  168.  
  169.                              The Alias Program
  170.  
  171.      One of Richard Conn's brilliant concepts in designing ZCPR3 was theì
  172. utility program he called ALIAS, whose function is to create COM files that,ì
  173. in turn, build multiple command lines and insert them into the MCL buffer. ì
  174. When ALIAS is run, it prompts the user for (1) the name of the alias file toì
  175. create and (2) a prototype command line, nowadays called a script.  When theì
  176. resulting COM file is run, it takes the script, uses the information in itì
  177. to construct a complete command line, and then places that command line intoì
  178. the MCL buffer so that the commands it contains will be run.
  179.  
  180.      The simplest script would be nothing more than a completely formedì
  181. command line.  For example, if we wanted to have a command (COM file) thatì
  182. would display the amount of free space on each of drives A, B, and C, weì
  183. could make an alias SPACE.COM containing the script
  184.  
  185.     SP A:;SP B:;SP C:
  186.  
  187. We assume here that our RCP (resident command package) includes the SPì
  188. (space) command.
  189.  
  190.      Such a script can have only a single purpose.  Much more powerfulì
  191. capability is provided when the script can contain parameter expressionsì
  192. that are filled in at the time the command is run.  The aliases produced byì
  193. ALIAS.COM support a number of parameter expressions, including the $1, $2,ì
  194. ... $9 parameters familiar from the SUBMIT facility.  An alias calledì
  195. ASMLINK with a script containing the following command sequence
  196.  
  197.     SLR180 $1
  198.     IF ~ER
  199.     SLRNK /A:100,$1/N,$1,VLIB/S,Z3LIB/S,SYSLIB/S,/E
  200.     FI
  201.  
  202. can then be used to assemble and (if there were no errors in assembly) linkì
  203. any program.  The expression $1 is replaced by the first token on theì
  204. invoking command line after the name of the alias.  A token, we should note,ì
  205. is a contiguous string of characters delimited (separated) by a space or tabì
  206. character.  Thus with the commandè
  207.     ASMLINK MYPROG
  208.  
  209. the string "MYPROG" will be substituted for each of the three occurrences ofì
  210. the expression "$1" in the script to form the command line.  Any commands inì
  211. the MCL after the alias command are appended to the expanded script.
  212.  
  213.  
  214.                             The Advent of ARUNZ
  215.  
  216.      One day it suddenly struck me that Conn-style aliases are extremelyì
  217. inefficient with disk space.  Each one contains, of course, the prototypeì
  218. command line (the script), which is unique and essential to each alias, butì
  219. which is at most about 200 characters long and often much less (17 and 67 inì
  220. the two examples above, if I counted right).  But each one also contains aì
  221. complete copy of the script interpreter and command line manipulation code,ì
  222. about 1K bytes long, which is exactly the same in each alias.  Why not, Iì
  223. thought, separate these two functions, putting all the scripts into aì
  224. single, ordinary text file (ALIAS.CMD) and the alias processing code inì
  225. another, separate file (ARUNZ for Alias-RUN-Zcpr)?
  226.  
  227.      Because there is only a single copy of the ARUNZ code in the systemì
  228. rather than a copy of it with each alias, I felt that I could afford toì
  229. expand the code to include many additional features, in particular much moreì
  230. extensive parameter expansion capability.  These features will be describedì
  231. later.
  232.  
  233.  
  234.                              The ALIAS.CMD File
  235.  
  236.      Let's begin by looking at the structure of the ALIAS.CMD file.  First,ì
  237. we should make it clear that ALIAS.CMD is a plain, ordinary text file thatì
  238. you create using your favorite text editor or word processor (in non¡
  239. document mode).
  240.  
  241.      Each physical line in the file contains a separate alias definition. ì
  242. At present there is no provision for allowing definitions to run over toì
  243. additional lines, so for long scripts your editor has to be able to handleì
  244. documents with a right margin of more than 200 characters.  As I sit hereì
  245. composing this column, it occurs to me that a nice solution to this problemì
  246. might be to allow the ALIAS.CMD file to be created by a word processor inì
  247. document mode and to have WordStar-style soft carriage returns beì
  248. interpreted by ARUNZ.COM as line-continuation characters.  I will experimentì
  249. with that possibility after I finish this column, and if it works there mayì
  250. be an ARUNZ version 0.9H by the time you are reading this.
  251.  
  252.      Each alias definition line contains two parts.  The first part, theì
  253. name field, defines the name or names by which the alias will be recognized,ì
  254. and the second part, the script field, contains the script associated withì
  255. that name or those names.
  256.  
  257.      The name field must start in the very leftmost column (no leadingìèspaces), and the two fields are separated by a space or tab character.  Thusì
  258. ALIAS.CMD might have the following general appearance:
  259.  
  260.     FIRST-NAME-FIELD    first script
  261.     NEXT-NAME-FIELD        next script
  262.     ...            ...
  263.     LAST-NAME-FIELD        last script
  264.  
  265. For ease of reading, I follow the convention of putting the alias name fieldì
  266. in upper case and the script strings in lower case, but you can use anyì
  267. convention (or no convention) you like, since ARUNZ does not generally careì
  268. about case (the sole exception will be described later).
  269.  
  270.      To make the ALIAS.CMD file easier to read, you can include comment andì
  271. formatting lines.  Blank lines are ignored and can be used to separateì
  272. groups of related alias definitions.  Also, any line that begins with aì
  273. space (no name field) will never match an alias name and will thus have theì
  274. effect of a comment line.  You can use this to put titles in front of groupsì
  275. of definitions.
  276.  
  277.      To tell the truth, I always wanted to be able to format the ALIAS.CMDì
  278. file as I just described, but I never got around to adding the code to allowì
  279. it.  As I was sitting here writing just now, I suddenly decided to see whatì
  280. would happen if the ALIAS.CMD file contained such lines.  With BGii inì
  281. operation, a quick '\s' from the keyboard took me to the alternate task, andì
  282. I gave it a whirl.  Imagine my surprise and delight to discover that theì
  283. formatting already works!  No new code is required.
  284.  
  285.  
  286. The Name Field in ALIAS.CMD
  287.  
  288.      The name field can contain a simple name, like SPACE or ASMLINK, butì
  289. more complex and flexible forms are also supported.  First of all, the nameì
  290. field can consist of any number of individual name elements connected by anì
  291. equal sign (with no intervening spaces, since a space would mark the end ofì
  292. the name field).  Thus a line in ALIAS.CMD might have the followingì
  293. appearance:
  294.  
  295.     NAME1=NAME2=NAME3    script string
  296.  
  297.      Secondly, each name element can represent multiple names.  There areì
  298. three characters that have special meanings in a name element.  The first isì
  299. a question mark ('?').  As with CP/M file names, a question mark matches anyì
  300. character, including a blank space.  Thus the alias name DIR? will match anyì
  301. of the following commands: DIR, DIRS, DIRR, and so on.
  302.  
  303.      The second special character is currently the period ('.').  Forì
  304. reasons that I will not go into here (having to do with a new feature underì
  305. consideration for ZCPR34), I may change this to another character (perhapsì
  306. the asterisk), so check the update documentation with any version of ARUNZì
  307. beyond 0.9G.  The period does not match any character, but it signals theì
  308. comparison routine in ARUNZ that any characters after the period areìèoptional.  If characters are present in the command name, they must matchì
  309. those in the alias name, but the characters do not have to be present.  Forì
  310. example, the alias name field
  311.  
  312.     FIND.FILE=FILE.FIND
  313.  
  314. will match any of the following commands (and quite a few others as well):ì
  315. FIND, FINDF, FINDFILE, FILE, FILEF, FILEFIND.  It will not, however, matchì
  316. FILES or FINDSTR or FINDFILES.
  317.  
  318.      I have never had any occasion to make use of the capability, but theì
  319. two special characters can be combined in a single name element.  Thusì
  320. FIND.FI?E matches FINDFILE and FINDFIRE but not FINDSTR, and ?DIR.R matchesì
  321. SDIR, SDIRR, XDIR, and XDIRR (but not DIR).  I think you can see that theì
  322. special characters allow for very compact expressions covering many names.
  323.  
  324.      The third special character is the colon (':').  If any name elementì
  325. begins with a colon, then it will match any alias name whatsoever.  This isì
  326. called the default alias, the alias to be run if no other match is found. ì
  327. Since ARUNZ scans through the ALIAS.CMD file from top to bottom searchingì
  328. for a matching name, if the default name is used at all, it makes sense onlyì
  329. as the last alias in the file, since no alias definitions in lines below itì
  330. can ever be invoked.  Note that letters after the colon have noì
  331. significance; you may include them if you wish as a kind of comment.
  332.  
  333.      One possible use for the default alias would be a line like theì
  334. following at the end of the ALIAS.CMD file:
  335.  
  336.     :DEFAULT echo alias $0 not found in alias.cmd
  337.  
  338. If no specific matching alias is found, this default alias will report thatì
  339. fact to the user as a kind of error message.  I do not recommend using theì
  340. default alias in this way, however, because it will interfere with ZCPR33'sì
  341. normal invocation of the error handler when ARUNZ has been set up as theì
  342. extended command processor (ECP) and a bad command is entered.
  343.  
  344.      There is one use of the default alias that can augment the extendedì
  345. command processing power of ZCPR33.  When ARUNZ has been set up as the ECPì
  346. and a command is found neither as a system command, nor COM file, nor ARUNZì
  347. alias, one might want to try running the command from COMMAND.LBR using theì
  348. LX program.  This is a kind of chained ECP operation.  ARUNZ is the first ECP; LX is the second.  This can be accomplished, using version 1.6 or laterì
  349. of LX, by adding the following line at the end of the ALIAS.CMD file:
  350.  
  351.     :ECP-CHAIN lx / $0 $*
  352.  
  353. The meaning of the parameters $0 and $* will be explained later.  With thisì
  354. default alias, if a command cannot be resolved by a specific ARUNZ alias,ì
  355. then an LX command line will be generated to search for a COM file with theì
  356. name of the command in COMMAND.LBR.  The special parameter '/' as the firstì
  357. command line parameter to LX tells LX, when it cannot resolve the commandì
  358. either, to pass to the ZCPR3 error handler only the user command line (i.e.,ì
  359. to omit the "LX / " part of the command).è
  360.      This might be a good time to note that ARUNZ alias names are notì
  361. limited to only eight characters or to the characters allowed in disk fileì
  362. names.  For example, you have a perfect right to define an alias with theì
  363. name FINDFILES (nine letters) and to invoke it with the command ARUNZì
  364. FINDFILES.  If ARUNZ has been set up as your extended command processor (seeì
  365. my book "The ZCPR33 User Guide" for a discussion of ECPs), then when youì
  366. enter the command FINDFILES, the command processor will first look for aì
  367. disk file FINDFILE.COM, since it truncates the command name to eightì
  368. characters.  If this file is not found, the command processor will then, inì
  369. effect, run ARUNZ FINDFILES, including all nine characters.  I have notì
  370. thought of any uses for aliases with control characters in their names, butì
  371. you can define such aliases if you wish.
  372.  
  373.      Another fine point to be noted is that both leading blank spaces and anì
  374. initial colon are stripped from the command name before scanning for aì
  375. matching alias name.  It is obvious that if leading blanks were notì
  376. stripped, a leading blank would prevent any match from being found.  Theì
  377. colon is stripped so that a command entered as ":VERB" will match an aliasì
  378. name of 'VERB' without the colon.  If a directory specification is includedì
  379. before the colon, it will not be stripped.  When the BADDUECP option isì
  380. enabled in the configuration of ZCPR33, this allows illegal directoryì
  381. specifications to be passed to ARUNZ for processing.
  382.  
  383.  
  384. The Script Field in ALIAS.CMD
  385.  
  386.      The script field in the ALIAS.CMD file contains the prototype commandì
  387. line to be generated in response to a matching alias name.  The scriptì
  388. contains three kinds of items:
  389.  
  390.     (1) characters that are to be put into the command
  391.         line directly
  392.     (2) parameter expressions that ARUNZ is to evaluate
  393.         and convert to characters in the command line
  394.     (3) directives to ARUNZ to perform special operations
  395.  
  396.      There is nothing that has to be said about the first class ofì
  397. characters.  They comprise any characters not covered by the other two sets. ì
  398. The simple example of the SPACE alias, which would appear in ALIAS.CMD as
  399.  
  400.     SPACE sp a:;sp b:;sp c:
  401.  
  402. has only direct characters.  There are no special directives and noì
  403. parameters to evaluate.
  404.  
  405.  
  406. ARUNZ Parameters
  407.  
  408.      ARUNZ supports a very rich set of parameter expressions, which we willì
  409. now describe.  As rich as the set is, there are still important parametersì
  410. that still need to be added.  Some of these will be mentioned later in theìèdiscussion.  First let's see what we can already do.
  411.  
  412.      Parameters begin with either a caret ('^') or a dollar sign ('$').  Theì
  413. former is quite simple; it is used to signal a control character.  The ASCIIì
  414. representation of the character following the caret is logically ANDed withì
  415. 1FH, and the result is placed into the command line.  Of course, controlì
  416. characters other than carriage return and line feed can equally well beì
  417. placed directly into the script.
  418.  
  419.      At present there is no trap to prevent generating a null characterì
  420. (caret-space will do this: space is 20H, and 20H & 1FH = 00H).  If this isì
  421. used, the resulting null will effectively terminate the command line.  Anyì
  422. characters that come after the null character will be ignored by the commandì
  423. processor.  This could conceivably be useful for deliberately cancellingì
  424. pending commands in a command line, but I have never used it.  In fact, Iì
  425. was surprised to find that I did not have a trap for it.  On thinking aboutì
  426. it now, however, it seems best to continue to allow it.  Just "user beware!"ì
  427. when it comes to employing it.
  428.  
  429.      Parameters introduced by a dollar sign provide much more varied,ì
  430. interesting, and powerful capabilities.  The special ARUNZ directives areì
  431. also introduced by a dollar sign.  A complete list of the characters thatì
  432. can follow the dollar sign, grouped by function, is given below.  Detailedì
  433. discussion of each will follow.
  434.  
  435.     $ ^
  436.     * -
  437.     digit (0..9)
  438.     D U : .
  439.     F N T
  440.     " '
  441.     R M
  442.     I Z
  443.  
  444.  
  445. Character Parameters
  446.  
  447.      The parameters '$' and '^' are provided to allow the two parameterì
  448. lead-in characters to be entered into the command line text.  Many users,ì
  449. present company unhappily included, have made the mistake of trying to enterì
  450. a dollar sign directly into the alias script.  If this is done, the dollarì
  451. sign is (mis)interpreted as a parameter lead-in character.  You must putì
  452. '$$' in the script to get a single dollar sign in the command line.
  453.  
  454.      The worst example I have seen (and committed) of this kind of error isì
  455. in a command like "PATH A0 $$ A0".  This looks perfectly reasonable and doesì
  456. not produce any kind of error message when it runs (as "PATH A0 $0 A0"ì
  457. would, for example, when $0 got expanded to 'PATH').  Unfortunately, it runsì
  458. as "PATH A0 $ A0", where the single dollar sign now means current-drive/user-0 (this is perhaps a flaw in the way the PATH works, but that isì
  459. the way it is).  The proper form of the script is
  460.  
  461.     PATH A0 $$$$ A0è
  462. where each pair of dollar signs turns into a single dollar sign.
  463.  
  464.  
  465. Complete Command-Tail Parameters
  466.  
  467.      The parameters '*' and '-' refer to entire sections of the command lineì
  468. tail.  The asterisk represents the entire tail exactly as the user enteredì
  469. it.  The parameter expression $-n, where 'n' is a number from 0 to 9,ì
  470. represents the command tail less the first 'n' tokens (a token was definedì
  471. earlier).  The parameter $-0 has the same meaning as $*.
  472.  
  473.      Many users have confused 'command line tail' with 'command line'.  Theì
  474. two are not the same.  A command line consists of the command name (theì
  475. 'verb') and the tail.  Thus the command line tail is the command line lessì
  476. the first token.  Perhaps some examples will help.  Suppose the command lineì
  477. is
  478.  
  479.     command token1 token2 token3 token4
  480.  
  481. Then
  482.  
  483.     $*   =    "token1 token2 token3 token4"
  484.     $-2  =  "token3 token4"
  485.     $-4  =  ""
  486.  
  487. Note that $-4 is the null string; that is, $-4 will be replaced by noì
  488. characters at all.
  489.  
  490.      Also note that there is no leading space in the string assigned to $*. ì
  491. ALIAS.COM (and the earliest version of ARUNZ, I believe) had a bug in thisì
  492. respect in that it did include the leading space in the command line tail,ì
  493. since that is how the tail is stored by the command processor in the bufferì
  494. beginning at memory address 0080H.  The script "find $*" when invoked withì
  495. the tail "string" then became "find  string" with two spaces between "find"ì
  496. and "string".  In such a case, Irv Hoff's FIND program failed to work asì
  497. expected, probably because it was looking for " string" with a leadingì
  498. space.
  499.  
  500.  
  501. Complete Token Parameters
  502.  
  503.      The digit parameters '0' through '9' represent the corresponding tokenì
  504. in the command line that is being parsed.  In the example command line aboveì
  505. the digit parameters have the following values:
  506.  
  507.     $0  =  "command"
  508.     $1  =  "token 1"
  509.     $5  =  ""
  510.  
  511. Except for the '0' parameter, these parameters are familiar from the CP/Mì
  512. SUBMIT facility.  The expression $0 is an extension used to represent theìècommand verb itself.  Just think of the tokens on the command line as beingì
  513. numbered in the usual computer fashion starting with zero instead of one.  Aì
  514. token that is absent from the command line returns a null string (noì
  515. characters) as with $5 in the above example.
  516.  
  517.      As just mentioned, many users confuse the command line tail and theì
  518. command line.  If you want only the tail, use the parameter $*.  If you wantì
  519. to represent the entire command line, use the expression "$0 $*".  Mostì
  520. often it is the command line tail that is to be passed to a command, and theì
  521. ALIAS.CMD line will read something like
  522.  
  523.     ALIAS realverb $*
  524.  
  525. This is a direct implementation of the common meaning of 'alias' as anotherì
  526. name for something.  When ALIAS is invoked, we simply want to substituteì
  527. 'realverb' for it while leaving the command tail as it was.
  528.  
  529.      There are other occasions, however, as with the LX default aliasì
  530. example given earlier, where the entire command line must be passed.  Thereì
  531. are still other occasions, such as in the first default alias example above,ì
  532. where only the name of the verb used is needed.  Because a given script inì
  533. ALIAS.CMD can correspond to many possible alias names, it is important toì
  534. have a parameter that will return the name that was actually used in anyì
  535. particular instance.
  536.  
  537.  
  538. Token Parsing Parameters
  539.  
  540.      There are many instances in which it is extremely useful to be able toì
  541. break any token down into its constituents.  The parameters  'D', 'U', ':',ì
  542. and '.' do this.  They assume that the token is in the form of a fileì
  543. specification, which may have (1) a directory specification using either aì
  544. named directory or a drive and/or user number; and/or (2) a file name;ì
  545. and/or (3) a file type.  Each of the four parameters above is followed by aì
  546. number from 1 to 9 to designate the token to parse ('D' and 'U' can alsoì
  547. have a 0).  After discussing each one individually, we will give someì
  548. examples.
  549.  
  550.      The parameter 'D' returns the drive specified or implied in theì
  551. designated token.  If there is no directory specification or if only a userì
  552. number is given, then $Dn returns the default (logged) drive at the timeì
  553. ARUNZ constructs the command line.
  554.  
  555.      WARNING -- NOTE WELL: this is not necessarily the drive that will beì
  556. logged in at the time when that part of the command actually executes!! ì
  557. This, too, has been the source of grief in the use of ARUNZ.  ARUNZ has noì
  558. infallible way to know what directory will be logged in when some futureì
  559. command runs; it only knows what directory is the default directory at theì
  560. time ARUNZ itself is running.
  561.  
  562.      The 'U' parameter is similar in all respects to 'D', and the sameì
  563. warning applies.  The parameters $D0 and $U0 can also be used.  They alwaysìèreturn the default drive and user at the time ARUNZ interprets the script.
  564.  
  565.      The parameter ':' represents the file name part of the token, while theì
  566. parameter '.' represents the file type part of the token.  One way toì
  567. remember the characters for these two parameters is to think that colonì
  568. stands for the part of the token after a colon and period stands for theì
  569. part of the token after a period.  Admittedly, 'N' for name and 'T' for typeì
  570. would have been more sensible, but as we shall see shortly, these areì
  571. already used for something else.
  572.  
  573.      Generally speaking, the entire token can be represented as
  574.  
  575.     $Dn$Un:$:n.$.n
  576.  
  577. where 'n' is a digit.
  578.  
  579.      Let us consider some examples.  Suppose the following command isì
  580. entered at the prompt:
  581.  
  582.     B1:WORK>command root:fn1.ft1 c:fn2 2:.ft3
  583.  
  584. and that COMMAND.COM is not found, so that the command is passed on to ARUNZì
  585. and the extended command processor.  Also assume that the ROOT directory isì
  586. A15.  Then here are the values of the parameters for the four tokens in theì
  587. command:
  588.  
  589.     $D0 = "B"    $U0 = "1"    $0  = "COMMAND"
  590.  
  591.     $1  = "ROOT:FN1.FT1"
  592.     $D1 = "A"    $U1 = "15"    $:1 = "FN1"    $.1 = "FT1"
  593.  
  594.     $2  = "C:FN2"
  595.     $D2 = "C"    $U2 = "1"    $:2 = "FN2"    $.2 = ""
  596.  
  597.     $3  = "2:.FT3"
  598.     $D3 = "B"    $U3 = "2"    $:3 = ""    $.3 = "FT3"
  599.  
  600. Note the value of the following parametric expression:
  601.  
  602.     $D1$U1:$:1.$.1  =  "A15:FN1.FN2"
  603.  
  604. You can see that the 'D' and 'U' parameters can be used to convert a namedì
  605. directory into its drive/user form.
  606.  
  607.  
  608. System File Name Parameters
  609.  
  610.      The ZCPR3 ENV contains four system file names, each with a name and aì
  611. type.  These file names, numbered 0..3, are used by various programs,ì
  612. especially shells.  VFILER and ZFILER, for example, keep the name of theì
  613. file currently pointed to in system file name 1.  These file names can alsoì
  614. be read and set using the utility program SETFILE.è
  615.      The parameters 'F', 'N', and 'T' followed by a digit from 0 to 3ì
  616. return, respectively, the entire filename (name.typ), file name, and fileì
  617. type of the specified system file.
  618.  
  619.  
  620. User Input Parameters
  621.  
  622.      The single and double quote parameters are used for prompted userì
  623. input.  The forms of the parameter expressions are
  624.  
  625.     $"prompt"   or   $'prompt'
  626.  
  627. When the parameter $" or $' has been detected, any characters in the scriptì
  628. up to the matching parameter character or the end of the script line areì
  629. echoed as a prompt to the user's screen.  These characters are echoedì
  630. exactly as they appear in the script; no conversion to upper case isì
  631. performed.  The prompt string for the double quote parameter can containì
  632. single-quote characters, and the prompt string for the single quoteì
  633. parameter can contain double-quote characters.  There is, at present, no wayì
  634. to include the type of quote character used as the parameter in the promptì
  635. string.
  636.  
  637.      After the prompt has been output to the console, ARUNZ reads in a lineì
  638. of input from the console (user input).  At this point there is a subtle butì
  639. important distinction between the two user input parameters.  The singleì
  640. quote form takes the entire text string entered from the console and placesì
  641. it in the command line.  In particular, this input may contain semicolons,ì
  642. allowing the user to enter multiple commands.  The double quote form ignoresì
  643. a semicolon and any text thereafter.  This is intended for secure systems,ì
  644. where it prevents the user, when prompted for a program option, fromì
  645. slipping in complete additional commands.
  646.  
  647.      One pitfall to which many users have succumbed is the failure toì
  648. appreciate that the user input parameters perform their function at the timeì
  649. that ARUNZ is running and interpreting the script, not when the program inì
  650. the command line is running.  Consider the alias definition
  651.  
  652.     ERAFILE dir $1;era $"File name to erase: "
  653.  
  654. The intention here is to first display a list of the files that match theì
  655. first command line token and then to allow the user to enter the one to beì
  656. erased.  This is not what will happen.  ARUNZ will put up the prompt "Fileì
  657. name to erase: " at the time the command line is being built, i.e., beforeì
  658. DIR is run.  The prompt will come before the directory display.
  659.  
  660.      The way around this problem is to use two ARUNZ aliases as follows:
  661.  
  662.     ERAFILE        dir $1;/eraprompt
  663.     ERAPROMPT    era $"File name to erase: "
  664.  
  665. Now when ERAFILE is run, it will display the directory and then run theìècommand "/ERAPROMPT".  The slash here is a ZCPR33 feature that indicatesì
  666. that the command should be sent directly to the extended command processor. ì
  667. This saves the time that would otherwise be wasted searching for a fileì
  668. named ERAPROMPT.COM (actually, ERAPROMP.COM, since the ninth character willì
  669. be truncated from the name).  If you are not running ZCPR33 (but you shouldì
  670. be!!) or are running BGii, use a space instead.  This will work with bothì
  671. ZCPR33 and BGii and will have no effect in ZCPR30.  I am using the slash inì
  672. the examples because a space is hard to see in print.  When ERAPROMPT runsì
  673. and the user is prompted for the name, the directory listing will already beì
  674. on the screen.
  675.  
  676.      Whenever console input is requested by any program, one must keep inì
  677. mind the possibility that ZEX will be running and consider the question ofì
  678. whether the input request should be satisfied from the ZEX script or byì
  679. direct user input.  ARUNZ is configured, in the absence of a specificì
  680. directive to the contrary, to turn ZEX input redirection off during ARUNZì
  681. prompted input.  Thus, even if ZEX is running at the time ARUNZ is invoked,ì
  682. the user input parameters will request live user input.
  683.  
  684.      If you do want ZEX to be able to provide the response to ARUNZ promptedì
  685. input automatically from the ZEX script, then you must include the ARUNZì
  686. directive $I ('I' for input redirection) before the $" or $' parameter.  Theì
  687. $I directive is effective only for the next user input operation.  Afterì
  688. each prompted user input operation, the default for ZEX input redirection isì
  689. turned off.  The $I directive need not immediately precede the $" or $' butì
  690. there must be a separate $I for each input requested.
  691.  
  692.  
  693. Register and Memory Parameters
  694.  
  695.      Two parameters are provided for referencing values of the ZCPR3 userì
  696. registers and the contents of any memory location in the system.
  697.  
  698.      By Richard Conn's original specification, there were ten user registersì
  699. numbered from 0 to 9.  However, the block of memory in which those tenì
  700. registers fall is actually 32 bytes long.  Conn designated the last 16 bytesì
  701. of this block as 'user definable registers', but he and others later usedì
  702. them in programs such as Term3 and Z-Msg.  As a result, one has to be veryì
  703. careful in making use of them.  The last 6 bytes of the first half of theì
  704. block were defined as 'reserved bytes'.  Various uses have been made of themì
  705. as well.
  706.  
  707.      The ARUNZ parameter 'R' can reference any of the first 16 bytes usingì
  708. the form $Rn, where 'n' is a hexadecimal digit.  The decimal digitsì
  709. reference the true user registers, and the additional digits 'A' through 'F'ì
  710. reference the reserved bytes.  In the current version of ARUNZ, the value isì
  711. returned as a two character hexadecimal value.  However, I would like toì
  712. provide in the future a way to return the value in either decimal orì
  713. hexadecimal form.  A complication with the decimal form is the need toì
  714. indicate the format: one character, two characters with leading zeros, threeì
  715. characters with leading zeros, or the number of characters required for theì
  716. particular value with no leading zeros.è
  717.      One of the uses I envisioned for this parameter, though I have neverì
  718. actually used it this way, is for automatic sequential numbering of files. ì
  719. Thus a script might include the string "copy $:1$r3.$.1=$1;reg p3".  Thisì
  720. would copy the working file given by token 1 to a new file with the hexì
  721. value of register 3 appended to the file name.  For a file name of PROG.Z80ì
  722. this might be PROG03.Z80.  Then the value of register 3 would be incrementedì
  723. so that the next file name in sequence (PROG04.Z80) would be used the nextì
  724. time the alias was invoked.
  725.  
  726.      The parameter 'M' is used in the form $Mnnnn, where 'nnnn' is aì
  727. precisely four-digit hexadecimal address value.  The parameter returns theì
  728. two character hexadecimal value of the byte at the specified memory address. ì
  729. I use this on my RAS to determine if the system is running in local mode. ì
  730. The BDOS page at address 0007H has a different value when BYE is running. ì
  731. There might be a script of the form
  732.  
  733.     if eq $m0007 c6;....;else;echo not allowed in remote mode;fi
  734.  
  735. The commands represented by the ellipsis "...." will run only if in localì
  736. mode (BDOS apparently located at page C6H).
  737.  
  738.  
  739. ARUNZ Directives
  740.  
  741.      There are presently two ARUNZ directives.  We already discussed one ofì
  742. them, 'I', under the user input parameters.  The other one is 'Z'.
  743.  
  744.      Ordinarily, once ARUNZ has interpreted the alias script and evaluatedì
  745. the parameters, it appends to the resulting command line any commands in theì
  746. multiple command line buffer that have not already been executed.  This isì
  747. usually what one wants.  There is one possible exception.
  748.  
  749.      As I discussed in issues #27 and #28 of The Computer Journal, oneì
  750. sometimes wants an alias to invoke itself or other aliases recursively. ì
  751. This can sometimes lead to problems with the build up of unwanted pendingì
  752. commands that eventually causes the command line to overflow the bufferì
  753. space allowed for it.  In such a case one might want only the currentì
  754. expanded script command line to be placed in the MCL, with any pendingì
  755. commands dropped.  A $Z directive anywhere in the script will cause ARUNZ toì
  756. do this.  Note that the directive is not a toggle; multiple uses has theì
  757. same effect as a singe use.  Remember, however, that Dreas Nielsen's aliasì
  758. recursion technique, described in issue #28 and in examples below, isì
  759. generally preferable to the technique using $Z.
  760.  
  761.  
  762.                        Applications for ARUNZ Aliases
  763.  
  764.      In this section I will use a number of sample scripts to illustrateì
  765. various ways in which one can make use of the power of ARUNZ aliases.  I'mì
  766. sure there are many I have not thought of, and I invite you to send me yourì
  767. suggestions and examples.  In all cases I will be assuming that ARUNZ is theìèextended command processor (typically renamed to CMDRUN.COM).
  768.  
  769.      In general, one can identify the following classes of aliasì
  770. applications:
  771.  
  772.     (1) providing synonyms for commands
  773.     (2) trapping and/or correcting command errors
  774.     (3) automating complex operations into single commands
  775.  
  776. Within the last category fall two special subclasses:
  777.  
  778.     (a) performing 'get, poke, & go' operations
  779.     (b) providing special functions like recursion and repetition
  780.  
  781.  
  782. Command Synonyms
  783.  
  784.      The most basic use of aliases is to provide alternative names for
  785. commands.  Here are some examples from my personal ALIAS.CMD file.
  786.  
  787.      For displaying the directory of a library file, I now use the programì
  788. LLF.  However, after years of using LDIR, both before LLF was released andì
  789. still on most remote access systems, I prefer to use that name and haveì
  790. renamed LLF.COM to LDIR.COM.  Sometimes, however, I forget or want to beì
  791. sure I am running LLF and enter the command LLF explicitly.  Then I am savedì
  792. by the alias line
  793.  
  794.     LLF ldir $*
  795.  
  796. Similarly, I have recently begun to use LBREXT instead of LGET.  LGET isì
  797. easier to type, and I am used to it, so I have the alias
  798.  
  799.     LGET lbrext $*
  800.  
  801. LBREXT is so new that I did not want to rename it to LGET, since I might tooì
  802. easily forget which program the disk file really is.  I know I never haveì
  803. the old LDIR.COM around any more.  In both of these examples, the aliasì
  804. simply substitutes a different verb in the command line; the tail is leftì
  805. unchanged.
  806.  
  807.      Before the advent of ZCPR33, when path searching always included theì
  808. current directory, I would speed up the disk searching in these cases byì
  809. including an explicit directory reference with the script.  Thus the twoì
  810. commands above might be
  811.  
  812.     LLF   a0:ldir $*
  813.     LGET  a0:lbrext $*
  814.  
  815. This way the command processor would go straight to A0 no matter where I wasì
  816. logged in at the time.
  817.  
  818.      With ZCPR33 one can bypass the path search for commands that one knowsìèare in ALIAS.CMD by entering the command with a leading space or slashì
  819. (assuming the usual configuration of ZCPR33).  Sometimes I might try toì
  820. outfox the system and, thinking LBREXT is the alias name, enter the commandì
  821. as '/LBREXT ...'.  So that this will work, I extend the alias lines to
  822.  
  823.     LLF=LDIR     a0:ldir $*
  824.     LGET=LBREXT  a0:lbrext $*
  825.  
  826. The command is an alias for itself!!  Odd, but useful.  It is a good idea ifì
  827. you do this, however, to be absolutely sure to include an explicit directoryì
  828. prefix before the command name in the script.  If you don't, the followingì
  829. situation can arise.  Suppose the alias line reads
  830.  
  831.     TEST test $*
  832.  
  833. but for some reason TEST.COM is not on the disk (or at least not on theì
  834. search path).  Now you enter the command TEST.  The command cannot be foundì
  835. as a COM file, so the command processor sends it to ARUNZ.  ARUNZ proceedsì
  836. to regenerate the same command, which again cannot be found, and so on untilì
  837. you press the little red button or pull the plug.  Not always to completeì
  838. catastrophe, but definitely a nuisance.  With ZCPR33, if the command has anì
  839. explicit directory prefix, control is passed directly to the error handlerì
  840. if the COM file cannot be found in the specified directory.  It figures thatì
  841. if you go to the trouble of specifying the directory, you must mean to lookì
  842. there only.
  843.  
  844.      Another use for synonyms is to allow a short-form entry of commands. ì
  845. Here are two examples:
  846.  
  847.     SLR.180  asm:slr180 $*
  848.     ED.IT    sys:edit $*
  849.  
  850.      Synonyms are especially helpful on a remote access system or on anyì
  851. system that will be used by people who are not familiar with it or expert inì
  852. its use.  Consider, for example, the task of finding out if a certain fileì
  853. is somewhere on the system and where.  Some systems use FINDF, the originalì
  854. ZCPR3 program for this purpose; others use one of the standard CP/M programsì
  855. (WIS or WHEREIS); and others have begun to use the new, enhanced ZSIGì
  856. program called FF.  This can be very confusing to new users or to users whoì
  857. call many different systems.  The solution is to provide aliases for all theì
  858. alternatives.  Suppose FF is the real program in use.  Then the followingì
  859. line in ALIAS.CMD will allow all the forms to be used equally:
  860.  
  861.     FINDF=WIS=WHEREIS ff $*
  862.  
  863. In fact, while I am at it, I usually throw in a few other forms that someoneì
  864. might try and that are sufficiently unambiguous that one can guess with someì
  865. confidence that this is the function the user intended:
  866.  
  867.     FIND.FILE=FILE.FIND=WIS=WHERE.IS=FF a0:ff $*
  868.  
  869. Note that this single alias, which occupies only 46 bytes in ALIAS.CMDìè(including the CRLF at the end of the line), responds to 8 commonly usedì
  870. commands for finding files on a system.  Thus the cost is a mere 6 bytes perì
  871. command!!
  872.  
  873.  
  874. Trapping and Correcting Command Errors
  875.  
  876.      Aliases can be used to trap commands that would be errors and eitherì
  877. convert them into equivalent valid commands or provide some warning messageì
  878. to the user.
  879.  
  880.      It is generally not desirable to have a very long search path, becauseì
  881. every time a command is entered erroneously, the entire path has to beì
  882. searched before the extended command processor will be brought into play. ì
  883. On my SB180 with its RAM disk, I sometimes want the path to include onlyì
  884. M0:, the RAM disk directory.  The RAM disk, of course, cannot contain all ofì
  885. the COM files I use.  For COM files that reside on the floppy disk, I canì
  886. include an alias.
  887.  
  888.      For example, MEX.COM and all its associated files take up a lot of diskì
  889. space, and I keep them in a directory called MEX on my floppy drive B.  Theì
  890. ALIAS.CMD file can have the line
  891.  
  892.     MEX mex:mex $*
  893.  
  894. Without this alias I would have to remember to enter MEX:MEX manually.  If Iì
  895. forgot, I would get the error handler and then have to edit the line toì
  896. include the MEX: prefix.  The 16-byte entry above in the ALIAS.CMD fileì
  897. saves me all this trouble.
  898.  
  899.      Every computer user probably has some commands whose names heì
  900. habitually mistypes (switching 'g' and 'q' for example or reversing twoì
  901. letters).  My fingers seem to prefer 'CRUNHC' to 'CRUNCH', so I have theì
  902. following alias line:
  903.  
  904.     CR.UNHC crunch $*
  905.  
  906. Note that while I am at it, I allow the shorter form CR as well.  My fingersì
  907. like that even better.
  908.  
  909.      On a remote access system there are many situations where correctingì
  910. common mistakes can be handy.  Richard Jacobson (Mr. Lillipute, sysop of theì
  911. RAS that now serves TCJ subscribers) calls my Z-Node quite often.  Either heì
  912. has a Wyse keyboard with very bad bounce (as he claims) or he is a lousyì
  913. typist (and refuses to admit it).  When he wants to display a directory, hisì
  914. command is more likely to come out DDIR or DIRR than it is to come outì
  915. correctly as DIR.  So I added those two forms to my existing alias whichì
  916. allowed XD and XDIR (and /DIR); it now reads:
  917.  
  918.     XD.IR=DDIR=DIR.R a0:dir $*
  919.  
  920. Compensating for Richard's keyboard stutter takes up only seven extra bytesìèon my disk, not a very big sacrifice to make for a friend!
  921.  
  922.      Another example, one that is more than just a synonym for a mistypedì
  923. command, is an alias that comes into play when a command becomesì
  924. unavailable, perhaps because of a change in security level.  The RCP may,ì
  925. for example, have an ERA command that is only available when the wheel byteì
  926. is set.  When the wheel byte is off, ZCPR33 will ignore the command in theì
  927. RCP and forward an ERA command to the extended command processor or errorì
  928. handler (assuming there is no ERA.COM).  You might want to trap the errorì
  929. before the error handler gets it using an alias such as
  930.  
  931.     ERA echo e%>rasing of files not allowed
  932.  
  933. When the wheel byte is set, the ERA command will execute normally (unlessì
  934. entered with a leading space or slash).  When the wheel byte is off, theì
  935. user will get the message "Erasing of files not allowed", which, unlike theì
  936. invocation of an error handler, makes the situation perfectly clear.
  937.  
  938.      It is obviously very hard for users to remember the DU forms forì
  939. directories on a remote system, and that is one reason why named directoriesì
  940. are provided.  But even names are not always easy to remember precisely.ì
  941. Aliases can help by providing alternative names for logging intoì
  942. directories, provided ZCPR33 has been assembled with the BADDUECP optionì
  943. enabled so that invalid directory-change references are passed on to theì
  944. extended command processor.
  945.  
  946.      Suppose you have a directory called Z3SHELLS.  One might easily forgetì
  947. the exact name and think that it is Z3SHELL or SHELLS or SHELL.  Theì
  948. following line in ALIAS.CMD
  949.  
  950.     Z3SHELL:=SHELL:=SHELLS: z3shells:
  951.  
  952. would take care of all of these possibilities.  Note, however, that it willì
  953. not help a reference like "DIR SHELL:".  [If you wanted this to be accepted,ì
  954. you would have to go to considerable trouble.  You might be able to go intoì
  955. the NDR (named directory register) and tack onto the end an entry for aì
  956. directory named SHELL associated with the same drive and user as Z3SHELLS. ì
  957. All existing NDR editors will not allow a DU area to have more than oneì
  958. name, so you would have to use a debugger or patcher.  If anyone tries this,ì
  959. let me know if it works.]
  960.  
  961.      I occasionally slip up and omit the colon on the end of a directoryì
  962. change command (and users on my Z-Node do it surprisingly often).  It isì
  963. very easy for ARUNZ to pick this up as well and add the colon for you.  Justì
  964. include the following alias line:
  965.  
  966.     Z3SHELL=Z3SHELLS=SHELL=SHELLS z3shells:
  967.  
  968. All of these aliases can be combined into the single script:
  969.  
  970.     Z3SHELL.:=Z3SHELLS=SHELL.:=SHELL.S: z3shells:
  971. èSeven forms are covered by an entry of only 47 bytes, a cost of less than 7ì
  972. bytes each.  Note that the name element Z3SHELLS, unlike the other threeì
  973. name elements, does not allow an optional colon.  If it were included andì
  974. for some reason there were no directory with the name Z3SHELLS, you couldì
  975. get into an infinite loop.
  976.  
  977.      On my Z-Node I provide a complete set of aliases for all possibleì
  978. directories so that any legal directory can be entered with or withoutì
  979. colons and using either the DIR or the DU form.  Thus, if Z3SHELLS is B4,ì
  980. the script above would be:
  981.  
  982.     Z3SHELL.:=Z3SHELLS=SHELL.:=SHELL.S:=B4.: z3shells:
  983.  
  984.      Before ZCPR33 came along and provided this service itself, I wouldì
  985. allow callers to use the DU form to log into unpassworded named directoriesì
  986. beyond the max-drive/max-user limits by including aliases of the above form. ì
  987. If the maximum user area were 3 in the above example, the commands "B4:" andì
  988. "B4" would still have worked (even under ZCPR30) because ARUNZ mapped themì
  989. into a DIR form of reference.  Although this is no longer necessary withì
  990. ZCPR33, a complete alias line like the one above covers all bases. The userì
  991. can even enter any of the commands with a leading space or slash and theyì
  992. will still work.
  993.  
  994.      Finally, I provide on the Z-Node a catch-all directory change alias toì
  995. pick up directory change commands that don't even come close to somethingì
  996. legal.  At the end of ALIAS.CMD (i.e., after all the other directory-changeì
  997. aliases described above, so that they get the first shot at matching), Iì
  998. include the line
  999.  
  1000.     ?:=??:=???:=????:=?????:=??????:=???????:=????????: echo
  1001.       d%>irectory %<$0%> is not an allowed directory.  %<t%>he^m^j
  1002.       valid directories are:;pwd
  1003.  
  1004. Thus when the user enters the command "BADDIR:", he get the PWD display ofì
  1005. the system's allowed directories prefixed by the message
  1006.  
  1007.     Directory BADDIR: is not an allowed directory.  The
  1008.     valid directories are:
  1009.  
  1010. [Note the use of Z33RCP's advanced ECHO command with case shifting ('%< toì
  1011. switch to upper case and '%>' to switch to lower case) and control characterì
  1012. inclusion (caret followed by the character).]
  1013.  
  1014.  
  1015. Automating Complexity
  1016.  
  1017.      Complexity is a relative term, and in my old age (also relative) Iì
  1018. enjoy the luxury of letting my computer perform as much labor on my behalfì
  1019. as it possibly can.  We already saw how ARUNZ aliases can provide shortì
  1020. forms for commands (CR for CRUNCH).  It can also allow one to completelyì
  1021. omit commands.
  1022. è     At work I have been maintaining a phone directory in a file calledì
  1023. PHONE.DIR.  I got tired of invoking my PMATE text editor using the commandì
  1024. "EDIT A0:PHONE.DIR", so I added the following line to ALIAS.CMD:
  1025.  
  1026.     PHONE edit a0:phone.dir
  1027.  
  1028. Now I just type PHONE and, bingo, I'm in the editor ready to add a new name. ì
  1029. Similarly, I used to look up numbers for people using JETFIND as follows:
  1030.  
  1031.     JF -gi smith|jones a0:phone.dir
  1032.  
  1033. This would give me, from any directory, a paginated listing of lines inì
  1034. PHONE.DIR containing either "smith" or "jones" (ignoring case).  My poorì
  1035. tired fingers ache just thinking about all that typing.  Now I have theì
  1036. alias line
  1037.  
  1038.     #=CALL=NUM.BER jf -gi $1 a0:phone.dir
  1039.  
  1040. Now a simple " # smith" puts Smith's number up on my clean CRT screen in aì
  1041. jiffy.
  1042.  
  1043.      Here is another frequent command that causes severe finger cramps.  Youì
  1044. want to find all the files in the current directory that have a typeì
  1045. starting with 'D'.  You have to type "XD *.D*".  Wouldn't it be nice to haveì
  1046. a directory program that automatically wildcarded the file specification. ì
  1047. While I was fixing up FINDF to make my new FF, I built that feature into theì
  1048. code.  I've been too busy or too lazy to do the same for XD, so instead Iì
  1049. added the alias line
  1050.  
  1051.     D xd $d1$u1:$:1*.$.1* $-1
  1052.  
  1053. This is a little hard to decipher at a glance because of all the dots andì
  1054. colons and asterisks.  But here's how it works.  Suppose we are in B4: andì
  1055. enter "D .D /AA" (the option /AA means to include SYS and DIR type files). ì
  1056. The parameters in the alias have the following values:
  1057.  
  1058.     $D1 = "B"    $U1 = "4"        current drive and user, since
  1059.                     none given explicitly
  1060.  
  1061.     $:1 = ""            no file name given
  1062.  
  1063.     $.1 = "D"            file type in first parameter
  1064.  
  1065.     $-1 = "/AA"            the tail less the first token ".D"
  1066.  
  1067. The command is thus translated by ARUNZ into
  1068.  
  1069.     XD B4:*.D* /AA
  1070.  
  1071.      Sometimes it can be nice to allow a command that takes a number ofì
  1072. alternative options to run with only the option entered on the command line. ì
  1073. I have a read file for MEX that provides automated, menu-based operation onìèPC-PURSUIT.  I could invoke it as "MEX PCP".  Instead, I have the alias
  1074.  
  1075.     PCP  mex pcp
  1076.  
  1077. I also do this with the KMD file transfer commands on my Z-Node, where Iì
  1078. define the following aliases:
  1079.  
  1080.     S    kmd s $*
  1081.     SK    kmd sk $*
  1082.     SB    kmd sb $*
  1083.     SBK    kmd sbk $*
  1084.     SP    kmd sp $*
  1085.     SPK    kmd spk $*
  1086.     R    kmd r $*
  1087.     RP    kmd rp $*
  1088.     RB    kmd rb
  1089.     RP    kmd rp $*
  1090.     L    kmd l $*
  1091.     LK    kmd lk $*
  1092.  
  1093. This way the user can skip typing "KMD".  Actually, these aliases eachì
  1094. contain numerous other synonyms as well.  The 'S' alias, for example,ì
  1095. includes "SEND", "DOWN", and "DOWNLOAD" as well.  The cost in terms of diskì
  1096. space to add all these aliases is so small that I let my enthusiasm andì
  1097. imagination run wild.  Note, however, that with the above aliases defined,ì
  1098. the RCP should not have the 'R' (reset) and 'SP' (space) commands, sinceì
  1099. they will take precedence over the alias.  I changed the names of theseì
  1100. commands to 'RES' and 'SPAC'.  The remote user has no reason to use themì
  1101. anyway.
  1102.  
  1103.      There are, of course, many really complicated sequences of commandsì
  1104. (editing, assembling, and linking files, for example) that can very nicelyì
  1105. be performed by aliases.  Those are fairly obvious, and I have describedì
  1106. quite a few in previous columns.  I won't give any more examples here, but Iì
  1107. will describe two special applications where ARUNZ aliases cut down aì
  1108. complex process to simple proportions.  The first is automation of the get-poke-go technique pioneered by Bruce Morgen.
  1109.  
  1110.  
  1111. Automated GET-POKE-GO
  1112.  
  1113.      Here the alias does more than just save typing -- it remembers theì
  1114. addresses that have to be poked, something you probably can't do.  I willì
  1115. illustrate it with an intriguing example that is sort of recursive.
  1116.  
  1117.      Suppose ARUNZ is the extended command processor, has been renamedì
  1118. CMDRUN.COM, and is set to get its ALIAS.CMD file from the root directory. ì
  1119. Next, suppose you also want to be able to invoke it manually and have it, inì
  1120. that case, look for its ALIAS.CMD file along the entire path, including theì
  1121. current directory.  Suppose, furthermore, that CMDRUN.COM is a type-3ì
  1122. program that loads and runs at address 8000H.
  1123.  
  1124.      By inspecting CMDRUN.COM, we find that we have to poke a 0 at offsetìè1CH (address 801CH) to turn off the ROOT configuration option and an FFH atì
  1125. offset 24H (address 8024H) to turn on the SCANCUR option.  If we are to makeì
  1126. manual invocations using the alias name 'RUN', we can put the following lineì
  1127. in the ALIAS.CMD file in the root directory, where the unpoked CMDRUN.COMì
  1128. will find it:
  1129.  
  1130.     RUN get 8000 cmdrun.com;poke 801c 0;poke 8024 ff;jump 8000 $*
  1131.  
  1132. I particularly chose this example because it illustrates the slightly moreì
  1133. advanced version of GET-POKE-GO called GET-POKE-JUMP.  One word of caution. ì
  1134. This technique will only work under ZCPR33.  BGii version 1.13 is very closeì
  1135. to ZCPR33, but it still handles the JUMP command the way ZCPR30 did, and itì
  1136. cannot use JUMP when a command tail is processed.
  1137.  
  1138.      I will now describe two very special operations that can be performedì
  1139. very nicely with ARUNZ aliases: recursion and repetition.
  1140.  
  1141.  
  1142. Special Recursion Aliases
  1143.  
  1144.      The following pair of aliases (more or less) that implement Dreasì
  1145. Nielsen's recursion technique were described in my column in issue 28.  Theyì
  1146. allow one to execute a single command recursively.  With each cycle the userì
  1147. will be asked if he wants to continue.  So long as the answer is yes, theì
  1148. command will be executed repeatedly.  Upon a negative reply, the recursiveì
  1149. sequence will terminate, and any pending commands will execute.
  1150.  
  1151.      The alias that the user invokes can be called "REC.URSE" so that it canì
  1152. be invoked with a simple 'REC'.  It contains the following sequence ofì
  1153. commands:
  1154.  
  1155.     if nu $1
  1156.       echo;echo %<  s%>yntax: %<$0 cmdname [parameters]^j
  1157.     else
  1158.       /recurse2 $*
  1159.     fi
  1160.  
  1161. If invoked without at least a command name, this alias echoes a syntaxì
  1162. message to the screen.  Otherwise it invokes the second alias RECURSE2.  Theì
  1163. leading slash speeds things up by signaling the ZCPR33 command processorì
  1164. that it should go directly to the extended command processor.  If you areì
  1165. using BackGrounder-ii (version 1.13), the slash should be replaced by aì
  1166. space (the alias will then work with BGii or Z33).  If you are using ZCPR30,ì
  1167. don't use either; a space won't do you any good, and a slash will cause theì
  1168. command to fail.
  1169.  
  1170.      The alias that does the real recursion (RECURSE2) has the followingì
  1171. sequence of commands:
  1172.  
  1173.     fi
  1174.     $*
  1175.     if in r%>un %<"$*" %>again?è      /$0 $*
  1176.  
  1177. If the user answers the 'run again' query affirmatively, RECURSE2 will beì
  1178. invoked again.  By using '$0' instead of 'RECURSE2' the script will workì
  1179. even if we later change its name.
  1180.  
  1181.  
  1182. Special REPEAT Alias
  1183.  
  1184.      Here is a simple special alias that will allow a command that takes aì
  1185. single argument (token) to be repeated over a whole list of argumentsì
  1186. separated by spaces (not commas).  The name of the alias is "REP.EAT" soì
  1187. that it can be invoked with a brief 'REP'.  The script contains theì
  1188. following commands:
  1189.  
  1190.     $zxif
  1191.     if ~nu $2
  1192.       echo $1 $2
  1193.       $1 $2
  1194.     fi
  1195.     if ~nu $3
  1196.       /$0 $1 $-2
  1197.     fi
  1198.  
  1199. The '$z' in the first line declares the alias to be in recursive mode (anyì
  1200. pending commands in the multiple command line buffer are dropped when thisì
  1201. alias executes), and 'xif' clears the flow state.  Invoked as
  1202.  
  1203.     REPEAT CMDNAME ARG1 ARG2 ARG3
  1204.  
  1205. for example, interpretation of the script the first time through results inì
  1206. the following commands:
  1207.  
  1208.     xif
  1209.     if ~nu arg1
  1210.       echo cmdname arg1
  1211.       cmdname arg1
  1212.     fi
  1213.     if ~nu arg2
  1214.       /repeat cmdname arg2 arg3
  1215.     fi
  1216.  
  1217. The command line generated ("CMDNAME ARG1") is first echoed to the screen soì
  1218. the user knows what is going on, and then it is run.  Since there is aì
  1219. second argument, the alias is reinvoked as "REPEAT CMDNAME ARG2 ARG3".  Noteì
  1220. that the first argument has been stripped away.  After "CMDNAME ARG2" hasì
  1221. also been run and stripped from the command, the interpreted command stringì
  1222. will be:
  1223.  
  1224.     xif
  1225.     if ~nu arg3
  1226.       echo cmdname arg3è      cmdname arg3
  1227.     fi
  1228.     if ~nu
  1229.      /repeat cmdname
  1230.     fi
  1231.  
  1232. This time the null test in the second IF clause will fail, and the cycle ofì
  1233. commands will come to an end.
  1234.  
  1235.      This form of the REPEAT alias suffers from the problems Dreas Nielsenì
  1236. pointed out (it wipes out any commands following it on the original commandì
  1237. line).  A rigorous version can be made (adapting Dreas's technique) byì
  1238. making two aliases as follows:
  1239.  
  1240.    REP.EAT
  1241.     if nu $2
  1242.       echo;echo %<  s%>yntax: %<$0 aliasname arg1 arg2 ...^j
  1243.     else
  1244.       /repeat2 $*
  1245.     fi
  1246.  
  1247.    REPEAT2
  1248.     fi
  1249.     $1 $2
  1250.     if ~nu $3
  1251.       /$0 $1 $-2
  1252.  
  1253. If there is not at least one argument after the name of the command, aì
  1254. syntax message is given.  Otherwise a series of operations using REPEAT2ì
  1255. begins in which the command is executed on the first argument, and thenì
  1256. REPEAT2 is reinvoked with the same command name but with one argumentì
  1257. stripped from the list of arguments.  Note that the parameter $-2 is used. ì
  1258. The first parameter (the command verb) is given explicitly as $1.  "$-2"ì
  1259. strips away the verb and the argument that has already been processed.  Theì
  1260. expression "$1 $-2" allows one to strip out the second token.  Similarly,ì
  1261. "$1 $2 $-3" would strip out the third token.  "$1 $-3" would strip out theì
  1262. second and third tokens, leaving the first one intact and moving theì
  1263. remaining tokens down by two.
  1264.  
  1265.                              Configuring ARUNZ
  1266.  
  1267.      There are several configuration options that allow the user to tailorì
  1268. the way ARUNZ operates.  The COM file is designed to make it easy to patchì
  1269. in new values for most of the options using a program like ZPATCH.
  1270.  
  1271.  
  1272. Execution Address for ARUNZ
  1273.  
  1274.      ARUNZ is written as a type-3 ZCPR33 program.  In other words, it canì
  1275. automatically be loaded to and execute at an address other than 100H.  Inì
  1276. this way, its invocation as an extended command processor can leave most ofì
  1277. the TPA (transient program area) unaffected by its operation.  In the LBRìèfile posted on RASs there are generally two versions of ARUNZ, one designedì
  1278. to run at 100H (and usable in ZCPR30 systems) and one designed to run atì
  1279. 8000H.  Sometimes there are also REL files that the user can link with theì
  1280. ZCPR libraries to run at any desired address.
  1281.  
  1282.  
  1283. Display Control
  1284.  
  1285.      There are two bytes just after the standard ZCPR3 header at offset 0DHì
  1286. in the COM file (just before the string "REG") that control the display ofì
  1287. messages to the user during operation of ARUNZ.  The first byte applies whenì
  1288. ARUNZ has been invoked under ZCPR33 as an extended command processor; theì
  1289. second applies to manual invocation (or any use under ZCPR30).
  1290.  
  1291.      Each bit of these two bytes could control one display feature.  Atì
  1292. present, only six of the bits are used.  Setting a bit causes the messageì
  1293. associated with the bit to be displayed; resetting the bit supresses theì
  1294. display of the corresponding message.
  1295.  
  1296.      The least significant bit (bit 0) affects the program signon message. ì
  1297. The usual setting is 'off' for ECP invocations and 'on' for manualì
  1298. invocations.  Bit 1 affects the display of a message of the form 
  1299.  
  1300.     Running alias "XXX"
  1301.  
  1302. This message is normally displayed only for manual invocations of ARUNZ.
  1303.  
  1304.      Bit 2 controls the display of the "ALIAS.CMD file not found" message. ì
  1305. This message should generally be enabled, since it will not appear unlessì
  1306. something has unexpectedly gone wrong, and you might as well know about it.
  1307.  
  1308.      Bit 3 controls the display of a message of the form
  1309.  
  1310.     Alias "XXX" not found
  1311.  
  1312. This message is normally turned on for manual invocations only.  When theì
  1313. alias is not found by ARUNZ operating as a ZCPR33 ECP, control is turnedì
  1314. over to the error handler, and there is no need for such a message.  Theì
  1315. message can alternatively be generated, in whatever form the user desires,ì
  1316. using a default alias as described earlier.  In that case, however, theì
  1317. message will appear for ECP as well as manual invocations.
  1318.  
  1319.      Bits 4 and 5 apply only when ARUNZ has been invoked as an extendedì
  1320. command processor, and they were included as a debugging aid while I wasì
  1321. first developing ARUNZ.  Both are normally turned off.  If bit 4 is set,ì
  1322. ARUNZ will display the message "extended command processor error" if itì
  1323. could not process the alias during an ECP invocation.  Bit 5 controls aì
  1324. message of the form "shell invocation error".  It is possible (though veryì
  1325. tricky and not recommended) for an alias to serve as a shell.  If ARUNZì
  1326. fails to find an alias when invoked as a shell processor, then this messageì
  1327. will be displayed if bit 5 is set.
  1328. è
  1329. Locating the ALIAS.CMD File
  1330.  
  1331.      There are several possibilities for how ARUNZ is to go about locatingì
  1332. the ALIAS.CMD file.  There are four configuration blocks near the beginningì
  1333. of the ARUNZ.COM file; they are marked by text strings "PATH", "ROOT",ì
  1334. "SCANCUR", and "DU".  If the byte after "PATH" is a zero, then ARUNZ willì
  1335. look in the specific drive and user areas indicated by the two bytesì
  1336. following the string "DU".  The first byte is for the drive and has a valueì
  1337. of 0 for drive A, 1 for B, and so on.  The second byte has the user numberì
  1338. (00H to 1FH).
  1339.  
  1340.      If the byte after the string "PATH" is not zero, then some form of pathì
  1341. search will be performed depending on the settings of the bytes after theì
  1342. strings "ROOT" and "SCANCUR".  If the byte after "ROOT" is zero, then theì
  1343. entire ZCPR3 path will be searched.  If the byte after "SCANCUR" is nonzero,ì
  1344. then the currently logged drive and user will be included at the beginningì
  1345. of the path.  If the byte after "ROOT" is nonzero, then only the rootì
  1346. directory (last directory specified in the path) will be searched, and theì
  1347. byte after "SCANCUR" is ignored.
  1348.  
  1349.      My general recommendation is to use either the root of the path or aì
  1350. specified DU, especially when ARUNZ is being used as the extended commandì
  1351. processor.  It can take a great deal of time to search the entire pathì
  1352. including the current directory.  With ARUNZ as the ECP this will be doneì
  1353. every time you make a typing mistake in the entry of a command name, and theì
  1354. extra disk accesses can get quite tedious and annoying.
  1355.  
  1356.  
  1357. Use Register for Path Control
  1358.  
  1359.      There is an alternative way to control the path searching options thatì
  1360. can give one the best of all possible worlds.  After the string "REG" oneì
  1361. can patch in a value of a user register, the value of which will be used toì
  1362. specify the path search options PATH, ROOT, and SCANCUR instead of the fixedì
  1363. configuration bytes described above.
  1364.  
  1365.      Any one of the full set of 32 ZCPR3 registers can be specified for thisì
  1366. function by patching in a value from 00H to 1FH.  If any other value isì
  1367. used, the fixed configuration bytes will be used.  If a valid register isì
  1368. specified, its contents are interpreted as follows:
  1369.  
  1370.     bit 0        PATH flag (0 = use fixed DU; 1 = use path)
  1371.     bit 1        ROOT flag (0 = use entire path; 1 = use root only)
  1372.     bit 2        SCANCUR flag (0 = use path only; 1 = include
  1373.                 current DU)
  1374.  
  1375. By changing the value stored in the specified register, one can change theì
  1376. way ARUNZ looks for the ALIAS.CMD file dynamically depending on theì
  1377. circumstances.
  1378.  
  1379. è                            Plans for the Future
  1380.  
  1381.      I don't have much writing stamina left, but I would like to finish withì
  1382. a few comments about developments I would still like to see in ARUNZ.  A fewì
  1383. were mentioned in the main text above.  There is a need for some additionalì
  1384. parameters, such as register values in various decimal formats.  One alsoì
  1385. needs more flexible access to the directory specification part of a token. ì
  1386. The present parameters only allow extracting a DU reference, and they don'tì
  1387. allow any way to tell if an explicit directory is specified.  There shouldì
  1388. be a parameter that returns whatever DU or DIR string (including the colon)ì
  1389. is present.  If none is present, the parameter should return a null string.
  1390.  
  1391.      One of the things hampering the additional of more parameters is theì
  1392. arcane form they presently take.  I would like to find a much more rationalì
  1393. system (and if you have any suggestions, I would love to hear them).  I amì
  1394. thinking of something like $S for system file, followed by 'F', 'N', or 'T'ì
  1395. and then a number 0..3.  Thus $ST2 would read Systemfile-Type-2.  Commandì
  1396. line tokens might be $T followed by 'D', 'U', 'P', 'F', 'N', or 'T' and thenì
  1397. a digit 0..9 or 1..9.  The 'P' option (path) would be the DU or DIR prefix,ì
  1398. if any, including the colon.  Problem: what letter do I use for the namedì
  1399. directory or the path without the colon?  The logical choices 'N' and 'D'ì
  1400. are already used.  Maybe I have to go to four letters: $T for token,ì
  1401. followed by 'D' for directory part or 'F' for file part.  The 'D' could beì
  1402. followed by various letters (again, I am not sure what to use for all ofì
  1403. them) to indicate:
  1404.  
  1405.     1) the equivalent drive or default if none specified
  1406.     2) the equivalent drive or null string if none specified
  1407.     3) the same two possibilities for the user number
  1408.     4) the equivalent or given named directory (but what if the
  1409.        directory has no name)
  1410.     5) the whole directory prefix as given either including or not
  1411.        including the colon
  1412.  
  1413. Similarly, the 'F' option could be followed by a letter to indicate theì
  1414. whole filename, the name only, or the type only.  As you can see, it is notì
  1415. easy to identify all the things one might need and find a rational way toì
  1416. express them all.
  1417.  
  1418.      It would be nice to have prompted input where the user's input could beì
  1419. used in more than one place in the command line.  User input would have toì
  1420. be assigned to temporary parameters ($U1, $U2, and so on).  Perhaps thereì
  1421. should be the possibility of specifying default values for command lineì
  1422. tokens when they are not actually given on the command line (as in ZEX).  Itì
  1423. might also be useful to be able to pull apart a token that is a list ofì
  1424. items separated by commas.
  1425.  
  1426.      ARUNZ could use better error reporting for badly formed scripts.  Atì
  1427. present one just gets a message that there was an error in the script, butì
  1428. there is no indication of what or where the error was.  Ideally, theì
  1429. interpreted line should be echoed to the screen with a pointer to theì
  1430. offending symbol (NZEX has this).è
  1431.      There should be an option to have ARUNZ vector control to the ZCPR3ì
  1432. error handler whenever it cannot resolve the alias or when there is a defectì
  1433. in the script.  At present, chaining to the error handler only occurs whenì
  1434. ARUNZ has been invoked as an ECP.
  1435.  
  1436.      An intriguing possibility is to allow alias name elements to be regularì
  1437. expressions in the Unix (or JetFind) sense.  Then one could give an aliasì
  1438. name like "[XS]DIR" to match either XDIR or SDIR.  Perhaps there could be aì
  1439. correspondence established between non-unique expressions and a parameterì
  1440. symbol in the script.  Then all my KMD aliases might be simpler:
  1441.  
  1442.     S[P]*[K]*  kmd s$x1$x2 $*
  1443.  
  1444. The name would read as follows: 'S' followed by zero or more occurrences ofì
  1445. 'P' followed by zero or more occurrences of 'K'.  The parameter $X1, forì
  1446. example, would be the first regular expression, i.e., the 'P' if present orì
  1447. null if not.  This is fun to think about, but I am not at all sure that itì
  1448. would really be worth the trouble to use or to code for.  Any comments.
  1449.  
  1450.      It would also be nice to provide Dreas Nielsen's RESOLVE facilityì
  1451. directly in ARUNZ aliases.  These would use the percent character ('%') as aì
  1452. lead-in.  Any symbol enclosed in percent signs would be interpreted as aì
  1453. shell variable name, and its value from the shell file would be substitutedì
  1454. for it in the command line.  The parameter '$%' would be used to enter aì
  1455. real percent character.
  1456.  
  1457.  
  1458.                                  Next Time
  1459.  
  1460.      As usual, I have written much more than planned but not covered all theì
  1461. subjects planned.  I really wanted to discuss shells in more detail,ì
  1462. particularly after the fiasco with the way WordStar 4 behaves by trying toì
  1463. be a shell when it should not be.  That will have to wait for next time, Iì
  1464. am afraid.  Also by next time I should be ready to at least begin theì
  1465. discussion of ZEX.
  1466.  
  1467. [This article was originally published in issue 31 of The Computer Journal,
  1468. P.O. Box 12, South Plainfield, NJ 07080-0012 and is reproduced with the
  1469. permission of the author and the publisher. Further reproduction for non-
  1470. commercial purposes is authorized. This copyright notice must be retained.
  1471. (c) Copyright 1988, 1991 Socrates Press and respective authors]
  1472.