Chasing Your (Command) Tail [Note: This article is for the person who knows something about Turbo Pascal and also Z-System. Alpha Systems Corporation sells both and may be reached at (408) 297-5594. End of Note.] Before getting underway, the following library file which contains all the files discussed below (plus some not discussed) is available on the Z- Node network: Library directory for B0:NZ-TOOL4.LBR 28k BOX .PZS 6r : CPY .AZT 22r : CPY .CZM 81r : CPY .PZS 20r NZ-TOOL .BZX 40r : NZ-TOOL .FOR 4r : PARAMSTR.PZS 9r : PD .PZS 7r RAD .PZS 10r The demonstration program cpy.pas (The Computer Journal #45), a Z- System utility written in Turbo Pascal, did something strange the other day! A little background first. I own Turbo Pascal Version 2 which does not have a builtin function to return command line parameters. Version 3 does and it's called ParamStr(i:Integer):str80. This function returns the ith parameter of a command. Also, Version 2's BlockRead and BlockWrite functions are a bit different than Version 3's. I wrote ParamStr, retrofit the Block I/O code and finally got a clean compile. Cpy worked as advertised. Until I tried ... C0>cpy develop:ebc.asc floppy:flier.new This was supposed to put a copy of the file ebc.asc onto my floppy and call it flier.new. It made the copy alright but when a directory was done on the floppy a file called flier.ne (no 'w') was found. On a hunch I decided to rewrite my ParamStr function to use the multiple command line buffer instead of the transient buffer. A call to Joe Wright confirmed that Turbo Pascal uses the bytes starting at 32 past the beginning of the transient buffer for its own purposes. This all worked real well until I tried using cpy under the influence of a shell. It also did some pretty strange things when it was the second command in a multiple command line. ............................ / \ [ . | . |blah;blah;cpy this that;blah . . .] I had been assuming I could find the cpy command alone and at the beginning of the multiple command line buffer. The multiple command line buffer (pictured above) starts with a pointer to the next command. To locate the cpy command and its tail you must use this pointer and work backward til you reach the preceding semicolon, or the beginning of the command line. See the ParamStr function below for the details. The file nz-tool4.lbr on Z-Node #12 203 665-1100 contains cpy source and executable as well as the file nz-tool.box which must be included to gain Z-System environment access. A final note: Don't do what I did a couple of times ... forget to invoke the Turbo Pascal compiler as an *alias* which pokes the z3env header into memory after loading the compiler. Cpy.com does some *real* strange things if it's compiled under plain turbo.com! Function ParamStr(i:integer):str80; { Returns ith string of command. If i=0, returns command itself. If i=1 you get the first command tail parameter, etc. This uses the multiple command line, *not* the tbuff (hex 80 to hex ff.) Turbo Pascal itself uses tbuff+32 to tbuff+79 for its own purposes! Needed to write this function because it is *not* in the standard lib of Turbo Pascal Version 2. } Var j,j1,lcmd,lc,p : Integer; whatsleft : str80; cl : mclptr; { from nz-tool.box } Begin cl:=Ptr(getmcl); { point to multiple command line, using nz-tool.box } { determine end of command and its offset in multiple command line } lc:=cl^.nxtchr-1;j:=lc-Ord(cl)-3;lcmd:=0; While (cl^.mcl[j]<>';') And (j<>0) Do Begin { back up to start of command } j:=j-1;lcmd:=lcmd+1;End; { load work string with it } For j1:=j+1 To j+1+lcmd-1 Do whatsleft[j1-(j+1)+1]:=cl^.mcl[j1]; whatsleft[0]:=Chr(lcmd); p:=Pos(' ',whatsleft); { locate first space } If (i>0) And (p=0) Then whatsleft:=''; While (i<>0) And (p<>0) Do Begin { grab the ith parm } i:=i-1; { decrement parm counter } Delete(whatsleft,1,p); { lop off the leading parm } p:=Pos(' ',whatsleft); { locate next space } End; If p=0 Then { if at end, use what's left } ParamStr:=whatsleft Else ParamStr:=Copy(whatsleft,1,p-1); { else, what's at the beginning } End; { of what's left }