[comp.os.vms] Dirtree - A short sample program

ca053@unocss.UUCP (Tim Russell) (01/15/88)

Hello all,

    This is my first posting, so please don't flame me if something's
wrong...

    I just thought someone might be interested in a short utility program
I wrote a bit ago... It's a good demonstration of wildcard parsing, recursion,
and command line parameters.

    This program accepts an optional starting directory, and prints out a
simple 'tree' of all the subdirectories below it. It defaults to the current
directory. A sample invocation would be:

         $ Dirtree DUA0:[FOO]

, which would print a tree of all the subdirectories of [FOO].

    Disclaimer: I make no guarantees as to the fitness of this program. It
certainly won't trash any files or anything, but that's as far as I'll go.
This is my first try at VMS systems programming, and I just thought I'd
share it. Feel free to do whatever you want with it, as it's pretty trivial.

==============================================================================

Timothy Russell, Sophomore - CS
University of Nebraska at Omaha

ihnp4!unocss!ca053

"It's times like these I wish I'd listened to what my mother said."
"Why, what'd she say?"
"I don't know, I didn't listen..."
==============================================================================

Program Directory_Tree(Input, Output);

(****************************************************)
(*                                                  *)
(* Program Directory_Tree                           *)
(*                                                  *)
(* Written by Tim Russell, 1/6/87                   *)
(*                                                  *)
(* Version 1.0                                      *)
(*                                                  *)
(*     This program demonstrates the use of the     *)
(* RTL wildcard file routines. The program          *)
(* accepts a foreign parameter on the command       *)
(* line specifying a starting directory, with       *)
(* none meaning to start in the current directory   *)
(* and prints out a 'tree' of all the directories   *)
(* below it.                                        *)
(*     This is accomplished by using recursion      *)
(* to parse the wildcard '*.dir' in the starting    *)
(* directory, and then doing the same thing         *)
(* recursively on each of the resulting             *)
(* directories.                                     *)
(*      To use this program, you must define it     *)
(* by typing:                                       *)
(*      $ DIRTREE :== $[present dir]DIRTREE         *)
(* Running the program using RUN will allow only    *)
(* the default of the current directory.            *)
(****************************************************)

Type
  Var132 = Varying[132] of Char;

Var
  RootDir : Var132;              {Starting dir from command line}

(****************************************************************************)
Function Lib$Get_Foreign(%descr Line : Var132) : Integer; Extern;

Function Lib$Find_File(%descr File1, File2 : Var132;
		       Var    Context      : Integer) : Integer; Extern;

Function Lib$Find_File_End(Context : Integer) : Integer; Extern;

Function Sys$Exit(%immed Code : Integer) : Integer; Extern;

(****************************************************************************)
{Main recursive procedure}

Procedure DirTree(Dir : Var132; Level : Integer);

Var
  Temp, Loop, Start : Integer;
  Context, Status : Integer;       {Parameters to Find_File}
  Found_File, Nextdir : Var132;    {Returned filespec, Next dir}

Begin
  If (Length(Dir) <> 0) Then Begin {Print out the current directory's name}
    Temp := Length(Dir) - 1;              {Go back, to . or [ if top level}
    While ((Substr(Dir, Temp, 1) <> '.') And (Substr(Dir, Temp, 1) <> '[')) Do
      Temp := Temp - 1;
    For Loop := 1 to (Level * 5) Do       {Indent according to current level}
      Write(' ');
    Writeln(Substr(Dir, Temp+1, Length(Dir) - Temp - 1))
  End;
  Dir := Dir + '*.DIR;1';          {Find all the directories in this one}
  Context := 0;                          {Find first}
  Status := Lib$Find_File(Dir, Found_File, Context);
  While Odd(Status) Do Begin             {While file found}
      Start := Index(Found_File, ']');   {Make 'FOO.DIR' into [   .FOO] }
      Temp := Start + 1;
      While (Substr(Found_File, Temp, 1) <> '.') Do
        Temp := Temp + 1;
      Nextdir := Substr(Found_File, 1, Start - 1) + '.' +
        Substr(Found_File, Start+1, Temp - Start - 1) + ']';
      DirTree(Nextdir, Level + 1);
      Status := Lib$Find_File(Dir, Found_File, Context)
  End;
  Lib$Find_File_End(Context)             {Clean up after ourselves}
End;

(****************************************************************************)
Begin
  Lib$Get_Foreign(RootDir);       {Get the starting directory and check it}
  If (Length(RootDir) <> 0) Then
    If (Substr(RootDir, Length(RootDir), 1) <> ']') Then Begin
      Writeln('Usage:    Dirtree  Disk:[Directory]');
      Sys$Exit(1)
    End;
  DirTree(RootDir, 0)
End.