home *** CD-ROM | disk | FTP | other *** search
/ Delphi Programming Unleashed / Delphi_Programming_Unleashed_SAMS_Publishing_1995.iso / units / alldirs.pas next >
Encoding:
Pascal/Delphi Source File  |  1995-03-21  |  6.9 KB  |  325 lines

  1. unit AllDirs;
  2. { Define Debug }
  3.  
  4. { ALLDIRS.PAS copyright (c) 1995 by Charles Calvert }
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes,
  10.   Controls,
  11.   StrBox,
  12.   SysUtils;
  13.  
  14. type
  15.   TStack = class;
  16.   TShortStack = class;
  17.  
  18.   TStackAry = array[1..1000] of PString;
  19.   TStacksAry = array[1..1000] of TShortStack;
  20.  
  21.   TStack = class(TObject)
  22.     First,
  23.     Last: Word;
  24.     constructor Create;
  25.     procedure InitCount;
  26.     function IsEmpty: Boolean;
  27.     function Count: Integer;
  28.   end;
  29.  
  30.   TBigStack = class(TStack)
  31.     Stacks: TStacksAry;
  32.     destructor Destroy; virtual;
  33.     procedure Push(P: TShortStack);
  34.     function Pop: TShortStack;
  35.     function PopValue(var Num: Integer): String;
  36.   end;
  37.  
  38.   TShortStack = class(TStack)
  39.     StackAry: TStackAry;
  40.     destructor Destroy; virtual;
  41.     procedure Push(S: String);
  42.     function Pop: String;
  43.     function GetMoreDirs(Start: String): Integer;
  44.     procedure Show;
  45.   end;
  46.  
  47.   TFoundFileEvent = procedure(FileName: string; SR: SysUtils.TSearchRec) of Object;
  48.   TFoundDirEvent = procedure(DirName: string) of Object;
  49.  
  50.   TRunDirs = class(TComponent)
  51.   private
  52.     FOnFoundFile: TFoundFileEvent;
  53.     FOnProcessDir: TFoundDirEvent;
  54.     FFileMask: Str12;
  55.     FCurDir: DirStr;
  56.     FBigStack: TBigStack;
  57.     FShortStack: TShortStack;
  58.   protected
  59.     procedure PushStack;
  60.     procedure ProcessName(FName: String; SR: TSearchRec); virtual;
  61.     procedure ProcessDir(Start: String); virtual;
  62.   public
  63.     constructor Create(Owner: TComponent); override;
  64.     destructor Destroy; virtual;
  65.     function Run(Start: PathStr; StartingDirectory: String): String;
  66.   published
  67.     property OnFoundFile: TFoundFileEvent
  68.       read FOnFoundFile write FOnFoundFile;
  69.     property OnProcessDir: TFoundDirEvent
  70.       read FOnProcessDir write FOnProcessDir;
  71.     property CurDir: DirStr read FCurDir;
  72.   end;
  73.  
  74. implementation
  75. {$IfDef Debug}
  76. var
  77.   F: Text;
  78. {$EndIf Debug}
  79.  
  80. constructor TStack.Create;
  81. begin
  82.   inherited Create;
  83.   InitCount;
  84. end;
  85.  
  86. procedure TStack.InitCount;
  87. begin
  88.   First := 1;
  89.   Last := 0;
  90. end;
  91.  
  92. function TStack.IsEmpty: Boolean;
  93. var
  94.   OutCome: Boolean;
  95. begin
  96.   OutCome := First > Last;
  97.   IsEmpty := OutCome
  98. end;
  99.  
  100. function TStack.Count: Integer;
  101. begin
  102.   Count := Last - First;
  103. end;
  104.  
  105. {==================================================}
  106.  
  107. destructor TBigStack.Destroy;
  108. var
  109.   i: Integer;
  110. begin
  111.   for i := First to Last do
  112.     Stacks[i].Destroy;
  113.   inherited Destroy;
  114. end;
  115.  
  116. procedure TBigStack.Push(P: TShortStack);
  117. begin
  118.   Inc(Last);
  119.   Stacks[Last] := P;
  120. end;
  121.  
  122. function TBigStack.Pop: TShortStack;
  123. begin
  124. end;
  125.  
  126. function TBigStack.PopValue(var Num: Integer): String;
  127. begin
  128.   Num := 0;
  129.   if IsEmpty then begin
  130.     PopValue := '-1';
  131.     Num := -1;
  132.     Exit;
  133.   end;
  134.   while Stacks[Last].IsEmpty do begin
  135.     Inc(Num);
  136.     Stacks[Last].Destroy;
  137.     Dec(Last);
  138.     if IsEmpty then begin
  139.       PopValue := '-1';
  140.       Num := -1;
  141.       Exit;
  142.     end;
  143.   end;
  144.   if Last = 0 then begin
  145.     PopValue := '-1';
  146.     Exit;
  147.   end;
  148.   PopValue := Stacks[Last].Pop;
  149. end;
  150.  
  151. {==================================================}
  152.  
  153. destructor TShortStack.Destroy;
  154. var
  155.   i: Integer;
  156. begin
  157.   if not IsEmpty then
  158.     for i := First to Last  do
  159.       DisposeStr(StackAry[i]);
  160.   inherited Destroy;
  161. end;
  162.  
  163. procedure TShortStack.Show;
  164. var
  165.   i: Integer;
  166. begin
  167.   for i := First to Last do begin
  168.     {$IfDef Debug}
  169.     WriteLn(F, StackAry[i]^);
  170.     {$EndIf}
  171.     WriteLn(StackAry[i]^);
  172.   end;
  173.   {$IfDef Debug}
  174.   WriteLn(F, '===============');
  175.   {$EndIf}
  176. end;
  177.  
  178. procedure TShortStack.Push(S: String);
  179. begin
  180.   if (S <> '.') and (S <> '..') then begin
  181.     Inc(Last);
  182.     StackAry[Last] := NewStr(S);
  183.   end;
  184. end;
  185.  
  186. function TShortStack.Pop: String;
  187. var
  188.   S: PString;
  189.   Temp: String;
  190. begin
  191.   S := StackAry[First];
  192.   if S <> nil then begin
  193.     Move(S^, Temp, Length(S^) + 1);
  194.     DisposeStr(StackAry[First]);
  195.     Inc(First);
  196.     Pop := Temp;
  197.   end
  198.   else begin
  199.     WriteLn('Error TShortStack.Pop');
  200.     Halt;
  201.   end;
  202. end;
  203.  
  204. function TShortStack.GetMoreDirs(Start: String): Integer;
  205. var
  206.   SR: SysUtils.TSearchRec;
  207.   Total: Integer;
  208. begin
  209.   Total := 0;
  210.   if FindFirst(Start, faDirectory + faReadOnly, SR) = 0 then
  211.     repeat
  212.       if (SR.Attr = faDirectory) or (SR.Attr = faDirectory + faReadOnly) then begin
  213.         Push(SR.Name);
  214.         Inc(Total);
  215.       end;
  216.     until FindNext(SR) <> 0;
  217.   GetMoreDirs := Total;
  218. end;
  219.  
  220. {=======================================}
  221.  
  222. constructor TRunDirs.Create(Owner: TComponent);
  223. begin
  224.   inherited Create(Owner);
  225.   {$IfDef Debug}
  226.   Assign(F, 'DirLists.dat');
  227.   ReWrite(F);
  228.   {$EndIf}
  229.   FShortStack := TShortStack.Create;
  230.   FBigStack := TBigStack.Create;
  231. end;
  232.  
  233. destructor TRunDirs.Destroy;
  234. begin
  235.   FShortStack.Free;
  236.   FBigStack.Free;
  237.   {$IfDef Debug}
  238.   Close(F);
  239.   {$EndIf}
  240.   inherited Destroy;
  241. end;
  242.  
  243. procedure TRunDirs.PushStack;
  244. begin
  245.   FBigStack.Push(FShortStack);
  246.   FShortStack := TShortStack.Create;
  247. end;
  248.  
  249. function RemoveDir(Start: String; NumDirs: Integer): String;
  250. var
  251.   i, j: Integer;
  252.   CurDir: DirStr;
  253.   FileMask: Str12;
  254. begin
  255.   SplitDirName(Start, CurDir, FileMask);
  256.   i := Length(CurDir);
  257.   for j := 1 to NumDirs + 1 do begin
  258.     if CurDir[i] = '\' then  begin
  259.       Dec(CurDir[0]);
  260.       Dec(i);
  261.     end;
  262.     while CurDir[i] <> '\' do begin
  263.       Dec(CurDir[0]);
  264.       Dec(i);
  265.     end;
  266. {    Dec(CurDir[0]);
  267.     Dec(i); }
  268.   end;
  269.   RemoveDir := CurDir;
  270. end;
  271.  
  272. procedure TRunDirs.ProcessName(FName: String; SR: SysUtils.TSearchRec);
  273. begin
  274.   if Assigned(FOnFoundFile) then FOnFoundFile(FName, SR);
  275. end;
  276.  
  277. procedure TRunDirs.ProcessDir(Start: String);
  278. var
  279.   SR: SysUtils.TSearchRec;
  280. begin
  281.   if Assigned(FOnProcessDir) then FOnProcessDir(FCurDir);
  282.   if FindFirst(Start, faArchive, SR) = 0 then
  283.     repeat
  284.       ProcessName(UpperCase(FCurDir) + SR.Name, SR);
  285.     until FindNext(SR) <> 0;
  286. end;
  287.  
  288. function TRunDirs.Run(Start: PathStr; StartingDirectory: string): string;
  289. var
  290.   SR: TSearchRec;
  291.   Finished: Boolean;
  292.   NewDir, StartedAt: string;
  293.   DirMask: string;
  294.   NumDirs: Integer;
  295.   OutCome: Integer;
  296.   SaveDir: string;
  297. begin
  298.   GetDir(0, SaveDir);
  299.   ChDir(StartingDirectory);
  300.   Start := ExpandFileName(Start);
  301.   FCurDir := ''; FFileMask := '';
  302.   DirMask := '*.*';
  303.   OutCome := 3;
  304.   Finished := False;
  305.   StartedAt := Start;
  306.   SplitDirName(Start, FCurDir, FFileMask);
  307.   Start := FCurDir + DirMask;
  308.   while not Finished do begin
  309.     FCurDir := ExtractFilePath(Start);
  310.     ProcessDir(FCurDir + FFileMask);
  311.     OutCome := FShortStack.GetMoreDirs(Start);
  312.     if OutCome > 2 then begin
  313.       {ShortStack^.Show;}
  314.       PushStack;
  315.       Start := FCurDir + FBigStack.PopValue(NumDirs) + '\' + DirMask
  316.     end else begin
  317.       NewDir := FBigStack.  PopValue(NumDirs);
  318.       FCurDir := RemoveDir(Start, NumDirs);
  319.       Start := FCurDir + NewDir + '\' + DirMask;
  320.       if (Start = StartedAt) or (NewDir = '-1') then Finished := True;
  321.     end;
  322.   end;
  323.   ChDir(SaveDir);
  324. end;
  325. end.