Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!bellcore!decvax!decwrl!pyramid!ut-sally!seismo!uwvax!gumby!g-tsang From: g-tsang@gumby.UUCP (Michael H. Tsang) Newsgroups: net.micro.pc Subject: Re: where are you after a batch file Message-ID: <51@gumby.UUCP> Date: Sun, 2-Feb-86 18:34:03 EST Article-I.D.: gumby.51 Posted: Sun Feb 2 18:34:03 1986 Date-Received: Tue, 4-Feb-86 03:30:37 EST References: <440@tekig5.UUCP> <1130@ecsvax.UUCP> <203@intelca.UUCP> Organization: U of Wisconsin CS Dept Lines: 282 Summary: Where are you after a batch file? pushd? popd? In responding to the question of "where are you after a batch file?", I have written the following programs in Turbo Pascal. They are "pushd.pas" and "popd.pas". These programs simulate the corresponding pushd and popd commands in UNIX. It requires you to set up a file named "dirstack" in the directory "c:\tmp", but it can be changed by changing the constant StackFileName. I would like to see somebody rewriting these programs in assembly in order to reduce the program size (about 11K for each .COM file now). A sample batch file showing how to use these programs are given below: (suppose your applica- tion program is c:\tools\wordstar\ws.com) File: ws.bat echo off pushd c:\tools\wordstar ws popd echo on ------------------------------CUT HERE------------------------- {$G512,P512} program Pushd(input, output); const ProgramName = 'pushd'; Version = '[v1.01 (c) 2.2.86]'; StackFileName = 'c:\tmp\dirstack'; type Str255 = string[255]; StackPtr = ^StackRec; StackRec = record Path: Str255; Next: StackPtr end; var StackFile: text; StkTop, StkBot: StackPtr; Depth: integer; Dirty: boolean; procedure BuildStack; begin new(StkTop); StkBot := StkTop; GetDir(0, StkTop^.Path); Depth := 0; assign(StackFile, StackFileName); reset(StackFile); while not eof(StackFile) do begin new(StkBot^.Next); StkBot := StkBot^.Next; readln(StackFile, StkBot^.Path); Depth := Depth + 1 end; StkBot^.Next := nil; close(StackFile) end; { BuildStack } procedure SwapStackTop; var NewTop: StackPtr; begin BuildStack; if Depth < 1 then writeln(ProgramName, ': No other directory') else begin NewTop := StkTop^.Next; StkTop^.Next := NewTop^.Next; NewTop^.Next := StkTop; StkTop := NewTop; Dirty := true end end; { SwapStackTop } procedure RotateStack(NumStr: Str255); var Cnt, Num, Result: integer; begin Val(Copy(NumStr, 2, Length(NumStr)-1), Num, Result); if (Result <> 0) or (Num <= 0) then writeln(ProgramName, ': ', NumStr, ': No such file or directory') else begin BuildStack; if Num > Depth then writeln(ProgramName, ': Directory stack not that deep') else begin StkBot^.Next := StkTop; for Cnt := 1 to Num do begin StkTop := StkTop^.Next; StkBot := StkBot^.Next end; StkBot^.Next := nil; Dirty := true end end end; { RotateStack } procedure PushStack(ArgStr: Str255); var StkNode: StackPtr; begin BuildStack; new(StkNode); StkNode^.Path := ArgStr; StkNode^.Next := StkTop; StkTop := StkNode; Dirty := true end; { PushStack } procedure SaveStack; begin {$I-} ChDir(StkTop^.Path); {$I+} if IOResult <> 0 then writeln(ProgramName, ': ', StkTop^.Path, ': No such file or directory') else begin assign(StackFile, StackFileName); rewrite(StackFile); StkTop := StkTop^.Next; while StkTop <> nil do begin writeln(StackFile, StkTop^.Path); StkTop := StkTop^.Next end; close(StackFile) end end; { SaveStack } var Argc: integer; ArgStr: Str255; begin { Pushd } Argc := ParamCount; if Argc > 1 then writeln('Usage: ', ProgramName, ' [pathname | +n | -v]') else begin Dirty := false; if Argc = 0 then SwapStackTop else begin ArgStr := ParamStr(1); if ArgStr = '-v' then writeln(ProgramName, ': ', Version) else if ArgStr[1] = '+' then RotateStack(ArgStr) else PushStack(ArgStr) end; if Dirty then SaveStack end end. { Pushd } -------------------------CUT HERE-------------------------- {$G512,P512} program Popd(input, output); const ProgramName = 'popd'; Version = '[v1.01 (c) 2.2.86]'; StackFileName = 'c:\tmp\dirstack'; type Str255 = string[255]; StackPtr = ^StackRec; StackRec = record Path: Str255; Next: StackPtr end; var StackFile: text; StkTop, StkBot: StackPtr; Depth: integer; Dirty: boolean; procedure BuildStack; begin new(StkTop); StkBot := StkTop; GetDir(0, StkTop^.Path); Depth := 0; assign(StackFile, StackFileName); reset(StackFile); while not eof(StackFile) do begin new(StkBot^.Next); StkBot := StkBot^.Next; readln(StackFile, StkBot^.Path); Depth := Depth + 1 end; StkBot^.Next := nil; close(StackFile) end; { BuildStack } procedure PopStack; var PathStr: Str255; StkNode: StackPtr; begin BuildStack; if Depth < 1 then writeln(ProgramName, ': Directory stack empty') else begin StkTop := StkTop^.Next; Dirty := true end end; { PopStack } procedure DeleteStack(NumStr: Str255); var TmpPtr: StackPtr; Cnt, Num, Result: integer; begin Val(Copy(NumStr, 2, Length(NumStr)-1), Num, Result); if (Result <> 0) or (Num <= 0) then writeln(ProgramName, ': ', NumStr, ': Bad directory') else begin BuildStack; if Num > Depth then writeln(ProgramName, ': Directory stack not that deep') else begin TmpPtr := StkTop; for Cnt := 1 to Num-1 do TmpPtr := TmpPtr^.Next; TmpPtr^.Next := TmpPtr^.Next^.Next; Dirty := true end end end; { DeleteStack } procedure SaveStack; begin {$I-} ChDir(StkTop^.Path); {$I+} if IOResult <> 0 then writeln(ProgramName, ': ', StkTop^.Path, ': Bad directory') else begin assign(StackFile, StackFileName); rewrite(StackFile); StkTop := StkTop^.Next; while StkTop <> nil do begin writeln(StackFile, StkTop^.Path); StkTop := StkTop^.Next end; close(StackFile) end end; { SaveStack } var Argc: integer; ArgStr: Str255; begin { Popd } Argc := ParamCount; if Argc > 1 then writeln('Usage: ', ProgramName, ' [+n | -v]') else begin Dirty := false; if Argc = 0 then PopStack else begin ArgStr := ParamStr(1); if ArgStr = '-v' then writeln(ProgramName, ': ', Version) else if ArgStr[1] = '+' then DeleteStack(ArgStr) else writeln(ProgramName, ': ', ArgStr, ': Bad directory') end; if Dirty then SaveStack end end. { Popd } --------------------------CUT HERE---------------------------- Have fun with these programs. Mike Tsang