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 / CPM / ZCPR33 / A-R / PLF10.LBR / ALIAS.NZT / ALIAS.NOT
Text File  |  2000-06-30  |  38KB  |  727 lines

  1. PLF CHIT CHAT 'N' MISCELLANEA
  2. -----------------------------
  3.  
  4. I have had the idea for writing this for maybe six months.  A year or so 
  5. after the introduction of the LZW crunching algorithm we in the CP/M- 
  6. compatible world still have no all-purpose library utility with a 
  7. "sweep" mode (NULU's superb advance over LU) that can read crunched 
  8. files the way NULU does for squeezed files.  When we get such a utility 
  9. PLF will self-destruct; there will be no need for it.  I have been 
  10. especially surprised we have nothing that will extract crunched text 
  11. files directly to the list device; in PLF I try to deal with this 
  12. problem, admittedly in a roundabout (but rather enjoyable, for me!) way. 
  13. This whole series of aliases that Frank Gaude' and I have been writing -- 
  14. GLF, TLF and now PLF -- are all attempts to deal with this fundamental 
  15. deficiency in our library toolset.
  16.  
  17. When I use NULU -- to operate inside libraries containing no crunched 
  18. members -- I ALWAYS use it in its F)ilesweep mode, which gives the user 
  19. the highest degree of facility and flexibility in various library 
  20. operations.  Its fundamental advantage is the ability to VIEW the 
  21. library directory, perform a library operation and then once again be 
  22. presented with the library directory once the operation terminates.  The 
  23. fundamental advance made initially by Frank's GLF retained this feature 
  24. of NULU; it incorporated LLF and LGET so that you were first presented 
  25. with a directory and then BASED ON THAT could make a decision as to what 
  26. file to extract.  With PLF I have retained this advantage of NULU.  A 
  27. listing of the library directory returns to you after ANY operation, 
  28. waiting again for your input.
  29.  
  30. It is because of this feature that even when John Poplett produced the 
  31. excellent ZLBR.COM I was still unsatisfied.  I am always unsure of 
  32. exactly what operation I wish to perform on what file unless I have the 
  33. library directory in front of me, and with ZLBR one has to constantly do 
  34. a 'DIR' command to attain this.  PLF solves this problem.
  35.  
  36. PLF not only combines the functions of the previous two aliases Get 
  37. Library Files and Type Library Files but adds a third function as well, 
  38. that of printing.  It operates through a series of nine (PLF.CMD) or 
  39. eleven (PLF-RAMD) separate nested aliases to be placed in one's 
  40. ALIAS.CMD file.
  41.  
  42. I have deviated here, however, from the fundamental toolset that Frank 
  43. and I had been using in our previous aliases.  Rather than using GETVAR 
  44. as we had previously to "get" and then carry the name of the library 
  45. member, I have here taken advantage of the extraordinary file parsing 
  46. ability of ARUNZ.  Using the "user prompt" technique available through 
  47. ARUNZ's $" and $' symbols and then carrying the response in parameters 
  48. to a new alias, one may simulate what GETVAR does in actuality.  As will 
  49. be seen in the technique I use for printing compressed files, ARUNZ's 
  50. ability to return the file type of a parameter is of tremendous value.
  51.  
  52. I might add that I began writing this alias before Dreas Nielsen 
  53. produced GETVAR12 which has the ability to abort with CTL-C.  It was 
  54. precisely for the PLF alias on which I was then working that I had asked 
  55. him to write it.  The only way the user had at the time to abort from 
  56. the GETVAR prompt was through the very time-consuming technique of 
  57. invoking a separate 'EXIT' alias.  With GETVAR12 this problem is 
  58. eliminated.
  59.  
  60. I enjoyed developing the technique I've implemented to print compressed 
  61. files in the RAM- and hard-disk version of PLF, (PLF-RAMD.CMD).  (The 
  62. following discussion applies only to this version.  Since it involves 
  63. several re-loads of nested aliases I thought it better to leave out of 
  64. the floppy version which should execute more quickly.)  I thought about 
  65. it for days: how can I print a compressed file the real name of which I 
  66. don't as of yet know?  (I have only the name of its compressed form, 
  67. "*.?z?" or "*.?q?" still in the library.)  The solution I came up with 
  68. uses one of those many lovely "first generation" shell utilities that so 
  69. few people seem to use besides shell stalwarts like Dreas Nielsen and 
  70. myself, SHVAR.  (The others being of course SH, SHDEFINE, and SHFILE.) 
  71. If the filetype equals, for instance, 'ZZ0' or 'ZQ0' ('IF EQ $.2 Z?0') 
  72. then we define the shell variable 'P' -- again kept as short as possible 
  73. -- to be 'Z80', and print accordingly.  I took a sampling of as many 
  74. "standard" crunched filetypes as was reasonably possible, and made shell 
  75. variables out of their uncrunched counterparts.  We save space by simply 
  76. defining the filetype variable for these possibles, and THEN and only 
  77. then execute our PRINT XXXXXX command.  Note that this saves a 
  78. tremendous amount of command line buffer space over any method not using 
  79. shell variables.  The last several lines, already long as they are, 
  80. would be totally infeasible without it.  If I had tried:
  81.  
  82. if eq $.2 Z?0;print $:2.Z80;else;if eq $.2 d?c;print $:2.DOC...etc...
  83.  
  84. it would have overflowed faster than you can say Jackie Robinson.  
  85.  
  86. I like to use this technique whenever possible in aliases.
  87.  
  88. Note, by the way, my use here of RESOLVE (RS) in front of both the PRINT 
  89. and ERA commands to resolve the 'P' shell variable, thus completing our 
  90. adventure into the shell world.
  91.  
  92. Of course there are always going to be many crunched and squeezed 
  93. filetypes which I have not been able to include in this "table."  I have 
  94. included: L?B (LIB), M?C (MAC), D?C (DOC), I?F (INF), Z?0 (Z80), U?D 
  95. (UPD), N?T (NOT), M?G (MSG), H?S (HIS) and ZZZ (no filetype), but you 
  96. will undoubtedly come across others not in this list.  If as noted above 
  97. LT is patched to ignore all popular binary file types, our rather 
  98. primitive PRINT.COM is most certainly not.  (It is so primitive in fact 
  99. that it does not even provide a "FILE NOT FOUND" error message if it 
  100. cannot find the filename parameter!)  Hence we have to provide some way 
  101. of ensuring that we don't give a .COM or .REL file to PRINT for 
  102. printing!  So I try as best as I can to provide accurate filetypes to 
  103. it.  I have made provision for filetypes not included in our table in a 
  104. very nice way, I feel.
  105.  
  106. Any time PLF _does_ find the provided filetype in its table, it will set 
  107. register 1 to a non- zero value.  When we have exhausted the filetype 
  108. table but before getting to the 'RESOLVE/PRINT/ERA' command, register 1 
  109. is tested.  If it is a non-zero value, variable P has the value found in 
  110. the table.  If register 1 is 0, SHVAR then defines P as the string '* 
  111. I'.  Why this string?  Well, we have a problem.  Actually, since PLF 
  112. prints and then erases our file, we have two problems.  If we don't have 
  113. the exact name of the file, we can rely on the ability of PRINT.COM and 
  114. ERA.COM to accept unambiguous/wildcarded filename parameters.  We can do 
  115. 'PRINT Z80DOS.*' and often get quite decent and reasonable results.  So 
  116. we can get SHVAR to send a '*' in place of any specific, known filetype.
  117.  
  118. But what if, as is often the case, the file we're printing has the same 
  119. name as the library (.LBR file) from which it came?  Or suppose there is 
  120. a .REL file or .COM file or any other, non-printable files of the same 
  121. fileNAME as the file in question?  We certainly don't want PRINT.COM to 
  122. be trying to print Z80DOS.LBR!!  So --- we get SHVAR to store an 'I' for 
  123. "Inspect mode" along with the '*' in the variable.  It just so happens 
  124. that PRINT and ERA both use this "I" as an option switch, which works 
  125. absolutely wonderfully, since we certainly don't want to erase anything 
  126. unnecessarily either!  Our variable becomes '* I' and our full command 
  127. line becomes:
  128.  
  129.          print z80dos.* i;era z80dos.* i
  130.  
  131. (ARUNZ resolves '$$|' into '$' which RESOLVE.COM then resolves into a 
  132. semicolon, ';'.)
  133.  
  134. Well, take a look at the resultant command line.  Suppose our file was 
  135. 'Z80DOS.BZD', and therefore our unknown filetype would be 'BZD'.
  136.  
  137.          rs print $:2.%p$$|era $:2.%p
  138.  
  139. would therefore resolve into:
  140.  
  141.          print z80dos.* i;era z80dos.* i
  142.  
  143. This works perfectly.  In case we have picked up some unwanted 
  144. Z80DOS.??? files we are put into inspect mode for PRINT, and we next can 
  145. decide if we indeed want to erase whatever file(s) we are presented.
  146.  
  147. In P8 we use the Z33 flow control (IF COmpressed) to test if the user's 
  148. file is indeed crunched or squeezed.  I create a 'dummy' filename of 'x' 
  149. since there's no reason to waste precious buffer space with the real 
  150. filename!  If it is not crunched, we have no problem and PRINT.COM will 
  151. take care of it no sweat.  Only if it is will it pass it on to P7 for 
  152. further processing.
  153.  
  154. The 'IF GT $2 ??' in the P3 alias is my ingenious way of distinguishing 
  155. whether the user entered a file name, in which case I want PLF to run 
  156. LT, or a '/E' or '/P' in which case he wants to extract or print and PLF 
  157. uses LEX.  It tests specifically for whether the string entered as the 
  158. first token (to later become $2) at the PLF prompt has more than two 
  159. characters.  Since virtually all genuine file names meet this condition, 
  160. we can assume that any entered string NOT meeting this condition is 
  161. either a '/E' or '/P'.
  162.  
  163. You'll notice a large number of aliases.  After much experimenting I 
  164. realized this was the only way to deal with the situation of a 
  165. potentially very large command line.  If the user is processing
  166. three files the command line will push the buffer to the limit.  You 
  167. want to be really careful about overflowing your buffer here, and I 
  168. think I've made some pretty good, well-reasoned and necessary 
  169. compromises between speed (sacrificed with multi-aliases) and space.  
  170. You might find some places where you'll be tempted to wonder, "Why 
  171. didn't he combine this with the previous alias?"  You can rest assured 
  172. that I did consider that and was paid a visit by our good friend 'Ovfl' 
  173. after a long user input string.
  174.  
  175. I additionally had to contend with the fact that we surprisingly don't 
  176. have a utility for typing crunched files from libraries, with all the 
  177. standard Z features such as DIR: and a possible file list.  
  178.  
  179. I don't know if all the '$zzif' (buffer-flushing and 'zif') at the 
  180. beginning and 'zif' at the end of EVERY alias is really necessary.  When 
  181. you're in the process of writing aliases like these, however, and upon 
  182. exit you're always finding your IF state set to some damn level or 
  183. another, your tendency is to pull out your heavy ammo and go for broke; 
  184. these guarantee to smash any IF level that dares to rear its wooly head.
  185.  
  186. I have noticed a bug in BackGrounder ii v1.13 with the IF EXIST test.
  187. When that option is not enabled in the resident FCP so the testing is 
  188. automatically passed by the FCP to COMIF (IF.COM), then IF EXIST does 
  189. not operate properly if no DU: or DIR: specification precedes the 
  190. filename.  Aliases that I had on my system with the traditional Z-System 
  191. opening syntax:
  192.  
  193.     IF EX $1; ... [commands] ....;ELSE;echo $1 doesn't exist
  194.  
  195. would always seem to return "$1 doesn't exist"!!  I couldn't figure out 
  196. why until I brought it to the attention of Jay Sage who tested and 
  197. confirmed the bug.  He noticed that if a DU: or DIR: is given it works 
  198. properly and that if IF.COM is invoked directly it works fine as well!  
  199. The way I have solved this problem -- and I have incorporated this 
  200. solution into PLF -- is by changing all my alias beginnings from 
  201. 'IF EX $1' to 'IF EX $D1$U1:$.1.$.1 or whatever is appropriate.  The 
  202. latter form ensures that when the alias is expanded and sent to the 
  203. command line buffer the current DU: is included in the parameter.  If in 
  204. PLF if I had used only 'IF EX $1.LBR', then if the user was logged on to 
  205. the same directory as the library in question and therefore did not 
  206. include a DU: or DIR: spec, what would be sent to the command would not 
  207. have a DU:/DIR: reference and would be tested incorrectly by BGii1.13.  
  208. Using the form 'IF EX $D1$U1:$:1.LBR' instead forces the logged drive to 
  209. to be appended to the beginning of the expansion.
  210.  
  211. You will notice, by the way, that throughout the various PLF aliases I 
  212. have often used this '$d1$u1:.....' form rather than the seemingly 
  213. shorter and more simple '$1'.  This is actually to save space in the 
  214. command line buffer, though a visual impression of the alias gives the 
  215. complete opposite impression!  Suppose we have a 'LETTERS' directory 
  216. associated with C4:  If a user has entered
  217.  
  218.                 'LETTERS:MICROPRO.LTR'
  219.  
  220. in response the PLF prompt, and our aliases uses the '$1' form, the full 
  221. 20-character token will be sent to the buffer.  If however, we use
  222. '$d1$u1:$:1.$.1', what is sent to the buffer will only be
  223.  
  224.                   'C4:MICROPRO.LTR'
  225.  
  226. thus saving 4 bytes, which should always be a consideration for us -- in 
  227. Jay Sage's words -- "super-alias hackers."
  228.  
  229.                         *    *    *
  230.  
  231. Creation of this alias would have been easier if:
  232.  
  233. (1) LBREXT could accept parameters separated by spaces rather than only 
  234. a file list separated by commas; or,
  235.  
  236. (2) We had a Z-System version of LT that would accept a NDR: reference.
  237.  
  238.     I think/hope these are soon to come.
  239.  
  240.  
  241. Thoughts on Aliases and Other ZCPR33 Miscellanea
  242. ------------------------------------------------
  243.  
  244. I have spent a lot of time developing a satisfactory technique to loop 
  245. back and forth between two different commands one of which is an alias.  
  246. One of the major purposes for which I want this is for ongoing 
  247. development of my ALIAS.CMD.  One's ALIAS.CMD file is one's most 
  248. precious possession.  It is the most concrete and personal expression of 
  249. one's creativity in Z-System, the purified essence of our love of Z, the 
  250. shining gemstone of our OS.  What I find myself often doing is looping 
  251. between editing (usually with VDE) an alias I'm developing in ALIAS.CMD, 
  252. and EXECUTING it.  For instance, as I was developing PLF, I must have 
  253. performed the two sequences:
  254.  
  255.         PLF DIR:TESTLIB   ;   VDE A15:ALIAS.CMD
  256.  
  257. 2 1/2 million times.  How nice it would be for software to automate this 
  258. loop.  I would run PLF, test it out in all its hundreds of permutations, 
  259. then immediately upon exit VDE would automatically load ALIAS.CMD.  Upon 
  260. VDE exit, I would be queried as to whether I wish to repeat the loop, 
  261. and the system would respond accordingly.
  262.  
  263. Note, of course, that 'PLF DIR:TESTLIB' is itself a VERY long and 
  264. complex sequence of multiple command lines, so we are not talking here 
  265. about "two commands."
  266.  
  267. Sure, you one can use HSH or whatever and simply recall the previous 
  268. line.  But the whole purpose of computers is to automate operations.  It 
  269. is much cleaner, more elegant, and fun -- of course the most important 
  270. REAL use of computers -- to have the computer automatically execute the 
  271. next operation in the loop.
  272.  
  273. In private conversation Jay Sage and others have suggested making the 
  274. sequence "PLF DIR:LIBNAME;VDE A15:ALIAS.CMD" an alias in itself, called
  275. say, "PLF-LOOP".  I would then have a separate 'RECURSE' alias (actually 
  276. a two-alias sequence) like those Jay has put into his ALIAS.CMD or 
  277. illustrated in his The Computer Journal #28 article (to which magazine, 
  278. by the way, all Z-System users should subscribe at $16 per year to 190 
  279. Sullivan Crossroad, Columbia, Montana 59912):
  280.  
  281. RECURSE recurse2 $*
  282.         fi
  283.  
  284. RECURSE2 fi
  285.          $*
  286.          echo run "$1" again?
  287.          if in
  288.          $0 $*
  289.  
  290. This would run my alias "LOOP" consisting of my two command sequences, 
  291. then ask me if I want to run "LOOP" again, and respond accordingly.
  292.  
  293. There are two faults I find with this technique.  First and foremost, 
  294. it's inconvenient and inelegant to have to make a separate alias each 
  295. time you do something like this.  If I had to make either a standalone 
  296. alias with V/B/SALIAS or an alias entry in ALIAS.CMD each time I was 
  297. doing this looping I'd go crazy.  This is/should be a spontaneous, 
  298. automated process.  
  299.  
  300. The second problem cuts a bit deeper and more philosophical: it cannot 
  301. be used, as I most often wish to do, if either of the command sequences 
  302. in question is a nested alias using the '$z' symbol.  Once the 'RECURSE' 
  303. alias encounters a single '$z' in any alias that is running inside of 
  304. it, the command line buffer is completely flushed and all processing is 
  305. halted.  Any nesting that any of my PLF aliases want to do is prevented 
  306. and we are returned to the command line.
  307.  
  308. I realized that I almost always was using these looping techniques 
  309. with a single and "fixed" first command line: "VDE A15:ALIAS.CMD", so I 
  310. set up developing them based on this.  There are three methods I came up 
  311. with, the first two of which I have found not fully satisfactory and the 
  312. last of which pretty much does the trick but needs some work.  From the 
  313. beginning:
  314.  
  315. (1)  An alias similar to Jay's RECURSE, simply:
  316.  
  317.      LOOP vde a15:alias.cmd;$*;if in repeat loop?; LOOP $*;fi
  318.  
  319.      Very simple and very useful for me --- except under one 
  320.      circumstance, my most common one, the same as that under which 
  321.      Jay's RECURSE will not work:  if the command sequence in question 
  322.      is itself a recursive alias using the '$z' symbol.  In other words: 
  323.      no PLF again.
  324.  
  325. (2)  Actually my favorite: using SHSET and CMD.  That is:
  326.  
  327.          SHSET VDE A15:ALIAS.CMD;new sequence;CMD
  328.  
  329.      This is great to use, and a lot of fun.  There are two problems 
  330.      with it.  Number one, your entire command line above cannot exceed 
  331.      32 characters, the size of a single shell stack entry.  I 
  332.      temporarily dealt with this problem in an interesting way: I 
  333.      changed my shell stack system to having 2 entries of 64 bytes each 
  334.      rather than 4 of 32.  Easy to do.  Either load a new SYS.ENV 
  335.      configured thusly or even more simply, just POKE FE20 02 40.  FE20 
  336.      on MOST systems holds the number of shell stack entries and FE21 
  337.      the size of each.  Now it's 2 of 64 and the above command line 
  338.      works fine.  Except for problems number two and three.  Yeah, you 
  339.      guessed number two: no aliases with '$z' allowed.  So much for 
  340.      that.  But the third is most interesting.
  341.  
  342.      Read Jay's description of the SHELLIF option in the Z33 Users Guide 
  343.      to get a taste of the whole issue.  I use the shell utilities 
  344.      (SH.COM, SHVAR.COM, RESOLVE.COM, GETVAR.COM, etc.) frequently and 
  345.      disagree with Jay regarding the value of using flow control in 
  346.      custom-created shells; I think it's a great idea and would like to 
  347.      do it more, but of course mine is a user's perspective and I have 
  348.      no idea of the coding involved.  With the Z30 command processor 
  349.      doing so was impossible.  With Z33 it's discouraged and difficult.  
  350.      Jay has explained that you can have flow control inside of custom 
  351.      shells or you can have flow control in your regular commands, but 
  352.      not both.  
  353.  
  354.      A true solution will require two different flow control systems, 
  355.      one for shells and one for regular command-line use.  Turning 
  356.      SHELLIF on in Z33 allows it in shells and therefore disallows it 
  357.      generally, so forget that solution.
  358.  
  359.      Dreas Nielsen has come up with a solution, however, in the form of 
  360.      a straightforward little program CLRCST.COM, contained in his 
  361.      FORNXT2.LBR.  It simply clears the console status flag, about which 
  362.      I unfortunately know very little.  It seems to do something similar 
  363.      to what turning on SHELLIF does, but manually, only on a per-alias 
  364.      basis.  Simply put CLRCST as the very first command in an alias 
  365.      containing flow control, and it will run properly under SHSET or 
  366.      other shells.
  367.  
  368.      But this technique's inability to process '$z'-fied aliases rules 
  369.      in out for me.
  370.     
  371.      It's interesting, by the way, 
  372.  
  373.  
  374.      So what does that leave us with?  The biggie:
  375.  
  376. 3)   ZEX.  "Have more sex with ZEX!"  How's that for an advertising 
  377.      slogan for this wonderful but misaligned, misunderstood and 
  378.      generally feared ZCPR3 utility?  ZEX has a '^:' control directive 
  379.      that lends it perfectly to this kind of looping.  It has no problem 
  380.      with '$z' aliases.  It runs quickly, as the entire command sequence 
  381.      is placed in memory, unlike with ALIAS.CMD aliases where ARUNZ has 
  382.      to re-run each time the looping is performed.  An easy patch, 
  383.      provided by Jay, is made to VDE that turns off ZEX processing once 
  384.      VDE loads, then the simple ZEX file is executed:
  385.  
  386.      vde a15:alias.cmd
  387.      $1 $2 $3
  388.      ^"
  389.      SAK /p3
  390.      ^:
  391.  
  392.      and you're home free.  The ^: tells ZEX to rerun its command stream 
  393.      from the beginning; just what we want.  I guess because it operates 
  394.      in its own area of memory outside the regular ZCPR3 command line 
  395.      buffer area (in very highest TPA just below the CP, completely 
  396.      separate from the other ZCPR3 buffers), ZEX doesn't seem to be 
  397.      bothered by ARUNZ's '$z' COMMAND-LINE BUFFER-flushing.  I'm quite 
  398.      pleased with how this is working.  Additionally, the major 
  399.      complaint I have had with ZEX for a year or so -- that before 
  400.      running each command it displays the command line prompt which 
  401.      clutters up the screen and gives the whole operation an unaesthetic 
  402.      and overly busy appearance -- can be fixed with judicious and 
  403.      accurate use of the new control directives in Jay's superb NZEX-C.
  404.  
  405.      The complete LOOP.ZEX I use, of which the above is only a skeleton, 
  406.      is included in this library, but is reproduced below:
  407.  
  408. ^-^< *=&:)(Going to source script...)( ^>
  409. ^.vde a15:alias.cmd
  410. ^-^< *=&0)(Now running cmdline: ($1 $2 $3... ))(^|^|^>
  411. ^.$1 $2 $3
  412. ^"
  413. sak /p2
  414. ^:
  415.  
  416.      The ^- directive turns off all console output so the command prompt 
  417.      doesn't display (looks nice and clean).  The ^<..display text...^> 
  418.      directive turns on ZEX's 'echo' mode.  The strange escape sequences 
  419.      you see inside the display text are standard ADM-3A cursor control 
  420.      commands to place the text in a visually pleasing location on the 
  421.      screen.  Then with the ^. directive we change the "console display 
  422.      state" to "display console output but don't echo commands" just 
  423.      before running our commands.  
  424.  
  425.      The only part that's a little awkward is the ^" directive that we 
  426.      need to turn off ZEX while inside our "$1 $2 $3" command line.  
  427.      (The extra '$3' is just in case we have more than three tokens in 
  428.      our command; in 'PLF DIR:TESTLIB' I only have two.  Jay is working 
  429.      on a cleaner solution to this.  The way ZEX is set up now, if any 
  430.      of the programs included in the alias do NOT have code in them to 
  431.      turn off ZEX, then we must include the ^" directive in our ZEX file 
  432.      to do it manually for us.  Otherwise, we could be in the middle of 
  433.      any of our programs and right in front of our eyes ZEX will start 
  434.      spewing out the remaining ZEX commands right into our program.  I 
  435.      have actually had problems with MU312 loaded at 8000h inside my 
  436.      alias; for some reason, even with the ^" ZEX still pokes its nose 
  437.      and its command stream into MU3 and halts the alias.  I don't know 
  438.      why this particular program gave me problems.  (Conflicts with the 
  439.      ZEX monitor in high TPA?  I don't know.)  Jay has developed a patch 
  440.      that can be applied to any program internally to turn off ZEX while 
  441.      it's loaded thus making an explicit ^" directive in the ZEX file 
  442.      unnecessary, but until all programs have this it's best to include 
  443.      it in each ZEX file.
  444.  
  445.      For instance after I patched VDE I thought, "Oh, great, now I don't 
  446.      have to include ^" in the ZEX file.  I pleasantly loaded up PLF and 
  447.      started viewing a file.  LT started to do the job nicely for me and 
  448.      displayed the first screen's worth of my file.  Hit CTL-C and 
  449.      waited to get back to the PLF prompt.  Surprise!  There I was 
  450.      unceremoniously exited out of PLF and looking at a ZCPR3 prompt.  
  451.      Why?  Because since LT wasn't turning ZEX off, my CTL-C that was 
  452.      intended for LT got intercepted by ZEX as an "abort-ZEX" command.  
  453.      This used to happen to VDE until I patched it.
  454.  
  455.      Jay is intending, I believe with NZEX-D, to solve this problem with 
  456.      a technique that WITHIN ZEX will automatically turn off ZEX 
  457.      redirection inside ALL programs.  This will be especially nice since 
  458.      a ^" directive complicates ZEX scripts in that after the ^" is 
  459.      reached in the command stream all ZEX processing appears to halt.  
  460.      The user's screen is dead.  At this point if one hits a <CR> 
  461.      everything resumes again, but this shouldn't be necessary and 
  462.      detracts from the smoothness and "feel" of the whole operation.
  463.  
  464. So that's how I've solved my "looping" problem -- for now.  NZEX-C as 
  465. Jay has implemented it is a beautiful, very powerful program.  There's 
  466. no reason for anyone to shy away from it.  Just take out your manual, 
  467. and as Frank says, study, study, study, study, study, study, study.
  468.  
  469. However, one crucial part of this discussion remains -- how to best 
  470. implement recursive and nested aliases.  Is there no way we can do 
  471. looping methods numbers (1) and (2) above with very long alias 
  472. sequences, considering that the flushing of the command line with the 
  473. '$z' symbol seems to prohibit this?  
  474.  
  475. I hope everyone subscribes to The Computer Journal, because Jay Sage's Z- 
  476. SIG column in there is immensely useful and chock full of information 
  477. not available elsewhere.  One of the most intriguing columns for me was 
  478. in issue #28 in which Jay brings to the readers' attention a letter sent 
  479. the magazine by Dreas Nielsen in regard to techniques for alias 
  480. recursion.  Jay implemented his method originally in VALIAS and carried 
  481. the same technique over to ARUNZ with the '$z' symbol.  Dreas wrote in 
  482. and suggested another way to deal with one specific aspect of creating 
  483. recursive aliases -- a way OTHER THAN flushing the command line buffer 
  484. as Jay's technique does: their tendency to pile up 'FI's at the end.  
  485. Without any intervention here an alias will then incorrectly exit with 
  486. an IF level set.  While the buffer-flushing technique deals with this by 
  487. simply clearing out the 'FI's (along with everything else) from the 
  488. command line, Dreas' technique takes a different tack and deliberately 
  489. enters the alias in question from a second alias, an IF level therefore
  490. already in effect.  Our main alias begins with a 'FI' and therefore 
  491. returns us to a zero IF level.
  492.  
  493. But I have been confused by this discussion, because it seems to only 
  494. deal with the issue of IF level overflow, and not common line overflow.  
  495. Unless I am misunderstanding something (and I hope I am) Dreas' 
  496. technique doesn't seem to offer a solution to this latter problem.  The 
  497. only answer to this seems to still be the '$z' symbol.  I hope this is 
  498. not the case because I would like my two looping techniques described 
  499. above, as well as Jay's RECURSE and RECURSE2 aliases printed in the TCJ 
  500. article, to work with recursive aliases themselves.
  501.  
  502.  
  503. SHELL TALK
  504. ----------
  505.  
  506. I've always been surprised at how few people use shell variables and the 
  507. "non-menu" shell utilities -- SHVAR.COM, RESOLVE, GETVAR, FOR and PERFORM 
  508. -- inside aliases.  I understand there's a general reluctance on the 
  509. grounds that "theoretically" shells and aliases don't mix.  Though an 
  510. admitted hard-core theoretician in several fields of human endeavor, 
  511. that doesn't seem to bother me.  Frank Gaude' first hit upon the idea of 
  512. using the by-now famous GETVAR/RESOLVE combination in his GLF alias, but 
  513. besides Dreas Nielsen's superb work I've been surprised at how little 
  514. public discussion (use?) there is of these utilities.
  515.  
  516. I've found combinations of SHVAR, RESOLVE and shell variables to be of 
  517. inestimable value inside aliases.  I think my use inside PLF is a 
  518. perfect example.  I've also found it very interesting to use them to 
  519. save command line buffer space in aliases that would otherwise overflow.  
  520. For instance, suppose we have an alias segment:
  521.                                   
  522.                mu3  ; to 'peek' inside the alias before it runs
  523.                if eq $1 $2
  524.                echo running: cmd1 $2 $3 $4
  525.                cmd1 $2 $3 $4
  526.                else
  527.                if eq $1 $3
  528.                echo running: cmd2 $2 $3 $4
  529.                cmd2 $2 $3 $4
  530.                else
  531.                if eq $1 $4
  532.                echo running: cmd3 $2 $3 $4
  533.                cmd3 $2 $3 $4
  534.                zif
  535.  
  536. If our four parameters are of any significant size, such as long 
  537. filenames with DIR: specs, this alias will overflow so quickly it 
  538. wouldn't even be funny.  We might hope that the parameters would only 
  539. expand in those parameter symbols occupying the portions of the alias 
  540. where the flow state is true at any given execution of the alias, but 
  541. this is not the case.  If you use the trick of beginning every alias 
  542. that you want to really peer inside of with a 'MU3;', it'll give you a 
  543. window through which you can analyze exactly what's going on.  In an 
  544. alias like the above, which is an only slightly exaggerated version of 
  545. what most of us do -- or would do -- frequently, you'll be amazed at how 
  546. much space is wasted by parameters expanding where they don't really 
  547. need to --- when the flow state is false.  Of course, they have no other 
  548. way to work!  It's just too bad because they take up precious buffer 
  549. space that we need for the flow-state-is-true part of our command line, 
  550. the area where the alias is working for us.  The many parameters in the 
  551. two flow-state-is-false sections of the above alias would expand and 
  552. take up so much space the alias would overflow instantly.  What to do 
  553. about this?
  554.  
  555. Shell variables to the rescue.  A simple command line at the beginning 
  556. of the alias:
  557.  
  558.               shvar f $2 $3 $4
  559.  
  560. would take care of it.  The assigns the entire string with our 3 
  561. parameters to the shell variable "f".  Rename RESOLVE permanently to RS 
  562. as I have done, and our alias can now be:
  563.                    
  564.                    mu3
  565.                    shvar f $2 $3 $4
  566.                    if eq $1 $2
  567.                    rs echo running: cmd1 %f
  568.                    rs cmd1 %f
  569.                    else
  570.                    if eq $1 $3
  571.                    rs echo running: cmd2 %f
  572.                    rs cmd2 %f
  573.                    else
  574.                    if eq $1 $4
  575.                    rs echo running: cmd3 %f
  576.                    rs cmd3 %f
  577.                    zif
  578.  
  579. This can fit into our 200-character limit with no problem.  If you look 
  580. inside with MU3 you will see that the '%f''s do not expand until RESOLVE 
  581. gets at them.  I'm a little confused about this because I know that 
  582. shells such as RESOLVE ultimately do place their product into the 
  583. command line buffer (of course), but what I think happens is that all 
  584. commands preceding any particular invocation of RESOLVE have already 
  585. started moving out of the buffer, so they're not competing for the same 
  586. space at the same time.  This is the opposite of what happens when 
  587. parameters expand, which they do all at the same time, at the very 
  588. initial invocation of the command line, thereby all taking up the same 
  589. space.  
  590.  
  591. As an experiment, I defined six shell variables, the letters 'a', 'b', 
  592. 'c', 'd', 'e' and 'f' to definitions of approximately 50 characters in 
  593. length.  Any string of text will do.  You can use GETVAR, SHVAR or that 
  594. wonderful but utterly neglected program SHDEFINE.   Then try an alias 
  595. such as:
  596.  
  597. echo this is a test of shell variables in the cmdline.
  598. rs echo %a
  599. rs echo %b
  600. echo well, how did the partial test come out?
  601. rs echo %c$$|echo %d
  602. rs echo %e$$|echo %e
  603. echo the end!
  604.  
  605. You will be utterly surprised at the results.  This will NOT produce an 
  606. overflow.  You will produce a text display of perhaps 400 characters on 
  607. the screen --- all with a single alias!  Who said we only have a 200- 
  608. character buffer?  What is the trick?  Again, at the time the alias is 
  609. invoked we've fit quite well into our 200 characters, as above, with 
  610. nothing expanded.  As the shell variables expand, the preceding commands 
  611. have already emptied out and there is no problem.
  612.  
  613. By the way, for those puzzled by the '$$|' you are seeing up there, 
  614. RESOLVE can resolve two variables in a pass without having to reload 
  615. itself.  This is done by separating the two commands with a '$|' symbol, 
  616. which acts as RESOLVE's own internal multiple-command-line separator.  
  617. When RESOLVE does its work, it transforms this symbol into ZCPR3's ';' 
  618. semicolon.
  619.  
  620. And ARUNZ, of course, requires that a single '$' be produced with two 
  621. '$'s, hence '$$|' in ALIAS.CMD equals RESOLVE's '$|'.
  622.  
  623. Postscript: I lied above when I said you won't get a command line 
  624. overflow.  Once or twice you might.  But it won't be an command 
  625. processor/ARUNZ overflow; it'll be a RESOLVE overflow.  According to 
  626. what I read in the RESOLVE documentation, programs can not be passed a 
  627. command line tail of greater than 128 characters.  (Is this true still 
  628. in Z33?  I just tested ECHO and it seems to be true)  I'm a bit confused 
  629. about this, but I know I did occasionally get a message:
  630.  
  631.               Command line overflow
  632.  
  633. once or twice while playing around with these shell variable aliases, 
  634. and this message is distinct from the standard command processor 'Ovfl' 
  635. message to which we're all by now so accustomed.  I'm not quite sure 
  636. under what conditions this RESOLVE overflow occurs.  I have never had it 
  637. overflow on me in my regular use of it, only when I am experimenting and 
  638. testing its limits.  Experiment and find out.  (One more thing to ask 
  639. Dreas.)
  640.  
  641. Another thought came to me as I was creating PLF.  I noticed how often I 
  642. was using the string 'LLF $1; P2 $1' in the various nested aliases.  
  643. This of course Lists Library Files of the command line parameter and 
  644. then sends control back to the beginning of the alias, a procedure that 
  645. PLF performs after every operation.  So naturally it would be used a 
  646. lot.  But it took up so much buffer space!  How to deal with this?  
  647.  
  648. I experimented with the obvious.  First I put a 
  649.  
  650.               shvar x $1
  651.  
  652. command at the very beginning of the alias.  If on the command line I 
  653. had entered:
  654.  
  655.               plf letters:joeltr
  656.  
  657. then the string 'LETTERS:JOELTR' would be stored to the shell variable 
  658. 'x'.  Then instead of 'LLF $1; P2 $1', which expands to 37 characters 
  659. (count 'em) I could then save space with simply:
  660.  
  661.               rs llf %x$$| p2 %x
  662.  
  663. which takes up 17 bytes of space.  
  664.  
  665. But I thought some more.  The utility to do what I want doesn't yet 
  666. exist, but it seems straightforward enough.  A shell utility that can 
  667. accept and store a multiple-command line FROM THE COMMAND LINE.  It's a 
  668. pretty obvious and simple concept.  In this way I could assign the 
  669. entire string 'LLF $1; P2 $1' to a single variable.  Why not?  
  670.  
  671. GETVAR and SHDEFINE can both do it, manually, which are of no use from 
  672. an alias.  With both of these programs a user can assign the above 
  673. command line to a single variable, but it must be done as conscious user 
  674. input; no alias or even ZEX file can do it.  If one cares to do it in 
  675. this manner, however, before running the alias, the above sequence, 
  676. occupying 37 bytes if done in the 'normal' manner, would be reduced to 4 
  677. characters!  Hmmm...maybe I can get Dreas to write something...
  678.  
  679. REGISTERS
  680. ---------
  681.  
  682. Another way I saved command line buffer space in PLF is through the use 
  683. of the ZCPR3 registers.  They also seem to be an underutilized feature 
  684. of Z-System, at least in what I see publically.  They are excellent in 
  685. CREATING FILENAMES.  What?  Registers creating filenames?  Sure, why 
  686. not?  If the filename contains -- or could be created to contain -- 
  687. digits, they're perfect for this use.
  688.  
  689. I had an example in PLF very much like the above alias with all the 
  690. parameters.  I solved it differently.  Let's look at it again.  I'll lay 
  691. the solution side by side with the problem; 'BEFORE' on the left, 
  692. 'AFTER' on the right.
  693.  
  694. BEFORE                                 AFTER
  695.                                   
  696. mu3                                    mu3
  697. if eq $1 $2                            if eq $1 $2
  698. echo running: cmd1 $2 $3 $4            reg s0 1
  699. cmd1 $2 $3 $4                          else
  700. else                                   if eq $1 $3
  701. if eq $1 $3                            reg s0 2
  702. echo running: cmd2 $2 $3 $4            else
  703. cmd2 $2 $3 $4                          if eq $1 $4
  704. else                                   reg s0 3
  705. if eq $1 $4                            zif
  706. echo running: cmd3 $2 $3 $4            rs echo running: cmd$$r0 $2 $3 $4
  707. cmd3 $2 $3 $4                          rs cmd$$r0 $2 $3 $4
  708. zif
  709.  
  710. The string 'cmd$$r0' above actually resolves to 'cmd1' if register 0 is 
  711. set to 1.  It resolves to 'cmd2' if register 0 is set to 2, and to 
  712. 'cmd3' if set to 3.  Again, note the double '$$' in 'cmd$$r0' which is 
  713. so RESOLVE can properly be sent the parameter '$r0' by ARUNZ so the 
  714. former can return to us the value of register 0.  
  715.  
  716. Works beautifully!
  717.  
  718. -----------
  719.  
  720. Using registers and shell variables in this way greatly enhances the 
  721. possibilities for aliases, adding much to the pleasure, enjoyment and 
  722. variety we experience in this most wonderful operating environment of 
  723. ZCPR3.  We have infinite oceans to explore, many deep seas and 
  724. multicolored coral reefs in which to dive for our beautiful Z-System
  725. pearls.  Exploration is the order of the day!
  726.  
  727.                                        - Rick Charnes, San Francisco