🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.micro.pc
Article #5539

Re: where are you after a batch file

#5539
From: Michael H. Tsang
Date: Sun, 02 Feb 1986 23:34
282 lines
7444 bytes
     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
Technical Details
Message-ID: <51@gumby.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!bellcore!decvax!decwrl!pyramid!ut-sally!seismo!uwvax!gumby!g-tsang
References: <440@tekig5.UUCP> <1130@ecsvax.UUCP> <203@intelca.UUCP>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!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?