home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Programmieren / Kurztests / PascalPCQ / Examples / Find.p < prev    next >
Text File  |  1990-07-19  |  5KB  |  196 lines

  1. Program Find;
  2.  
  3. {
  4.     Find.p searches through an AmigaDOS directory structure for files
  5. matching the pattern given.  The command line format is:
  6.  
  7.     Find BaseDirectory Pattern
  8.  
  9.     This program shows how to use the SameName pattern matching routine,
  10. as well as how to work with AmigaDOS a bit.  If you don't already have
  11. a utility like this, Find can actually be useful.  Kinda scary....
  12.  
  13.     By the way: if you want to start your search on the current
  14. directory, just type: Find "" FilePattern
  15. }
  16.  
  17. {$I "Include:Utils/Break.i"}
  18. {$I "Include:Libraries/DOS.i"}
  19. {$I "Include:Utils/Parameters.i"}
  20. {$I "Include:Utils/StringLib.i"}
  21. {$I "Include:Utils/SameName.i"}
  22.  
  23. type
  24. {
  25.     When I'm searching through a directory for files matching the
  26. pattern, I also come across directories.  When I do I keep them in a
  27. linked stack, using the record below, then print all the subdirectories
  28. after I'm finished with the current directory.  That way the files from
  29. the subdirectory aren't printed in the middle of files from the current
  30. directory.
  31. }
  32.     DirRec = record
  33.     Previous : ^DirRec;
  34.     Name : Array [0..109] of Char;
  35.     end;
  36.     DirRecPtr = ^DirRec;
  37.  
  38. var
  39.     FullPath : String;
  40.     Directory : String;
  41.     FileName : String;
  42.     TestName : String;
  43.  
  44. Function DirEnded(FName : String) : Boolean;
  45. {
  46.     returns false if you would want to append a '\' to the end
  47. of FName before added a file name.
  48. }
  49. var
  50.     l : Short;
  51. begin
  52.     l := strlen(FName);
  53.     if l = 0 then
  54.     DirEnded := True;
  55.     DirEnded := (FName[l - 1] = ':') or (FName[l - 1] = '/');
  56. end;
  57.  
  58. Procedure Display(FileInfo : FileInfoBlockPtr);
  59. {
  60.     Displays whatever information you want from the FileInfoBlock
  61. }
  62. var
  63.     l : Short;
  64. begin
  65.     with FileInfo^ do begin
  66.     Write(FullPath);
  67.     l := strlen(FullPath);
  68.     if l > 0 then
  69.         if not DirEnded(FullPath) then begin
  70.         Write('/');
  71.         l := Succ(l);
  72.         end;
  73.     l := l + strlen(Adr(fib_FileName));
  74.     Write(String(ADR(fib_FileName)), ' ':40-l);
  75.     WriteLn(fib_Size:6)
  76.     end;
  77. end;
  78.  
  79. Procedure UpCase(str : String);
  80. {
  81.     Converts a string to uppercase
  82. }
  83. var
  84.     i : Integer;
  85. begin
  86.     i := 0;
  87.     while str[i] <> '\0' do begin
  88.     str[i] := toupper(str[i]);
  89.     i := Succ(i);
  90.     end;
  91. end;
  92.  
  93. Procedure SearchDirectory(DirName : String);
  94. {
  95.     The big routine.  Runs through the named directory, printing
  96. file names that match the global variable FileName, and making a list
  97. of directories.  When it has finished looking through the directories,
  98. it calls itself recursively to print its subdirectories.
  99. }
  100. var
  101.     FL        : FileLock;
  102.     FB        : FileInfoBlockPtr;
  103.     Stay    : Boolean;
  104.     LastPos    : Short;
  105.     FirstDir,
  106.     TempDir    : DirRecPtr;
  107.     DOSError    : Integer;
  108. begin
  109.     if CheckBreak then
  110.     return;
  111.     LastPos := StrLen(FullPath);
  112.     FirstDir := Nil;
  113.     if not DirEnded(FullPath) then
  114.     strcat(FullPath, "/");
  115.     strcat(FullPath, DirName);
  116.     FL := Lock(FullPath, ACCESS_READ);
  117.     if FL = Nil then begin
  118.     FullPath[LastPos] := '\0';
  119.     return;
  120.     end;
  121.     New(FB);    { Since New() uses AllocMem, FB is longword aligned }
  122.     if not Examine(FL, FB) then begin
  123.     Unlock(FL);
  124.     FullPath[LastPos] := '\0';
  125.     return;
  126.     end;
  127.     if FB^.fib_DirEntryType < 0 then begin { means it's a file, not a dir }
  128.     Unlock(FL);
  129.     FullPath[LastPos] := '\0';
  130.     return;
  131.     end;
  132.     repeat
  133.     Stay := ExNext(FL, FB);
  134.     if Stay then begin
  135.         with FB^ do begin
  136.         if fib_DirEntryType < 0 then begin { file }
  137.             StrCpy(TestName, Adr(fib_FileName));
  138.             UpCase(TestName);
  139.             if SameName(FileName, TestName) then
  140.             Display(FB);
  141.         end else begin            { a dir }
  142.             new(TempDir);        { add it to the list }
  143.             with TempDir^ do begin
  144.             strcpy(Adr(Name), Adr(fib_FileName));
  145.             Previous := FirstDir;
  146.             end;
  147.             FirstDir := TempDir;
  148.         end;
  149.         end;
  150.     end else begin
  151.         DOSError := IoErr;    { expect Error_No_More_Entries - not an error }
  152.         if DOSError <> ERROR_NO_MORE_ENTRIES then
  153.         Writeln('DOS Error number ', DOSError);
  154.     end;
  155.     if CheckBreak then begin        { user pressed Ctrl-C? }
  156.         while FirstDir <> Nil do begin
  157.         TempDir := FirstDir^.Previous;    { don't go through subs }
  158.         Dispose(FirstDir);
  159.         FirstDir := TempDir;
  160.         end;
  161.         Stay := False;
  162.     end;
  163.     until not Stay;
  164.     Unlock(FL);
  165.     while FirstDir <> Nil do begin        { print sub-directories }
  166.     SearchDirectory(Adr(FirstDir^.Name));
  167.     TempDir := FirstDir^.Previous;
  168.     Dispose(FirstDir);
  169.     FirstDir := TempDir;
  170.     end;
  171.     FullPath[LastPos] := '\0';            { restore global path name }
  172. end;
  173.  
  174. Procedure Usage;
  175. begin
  176.     Writeln('Usage: FIND BaseDirectory FilePattern');
  177.     Writeln('\t\tWhere BaseDirectory specifies the root search');
  178.     Writeln('\t\tDirectory, and FilePattern is the file name,');
  179.     Writeln('\t\tpossibly containing wildcards, to be compared.');
  180.     Exit(20);
  181. end;
  182.  
  183. begin
  184.     Directory := AllocString(128);
  185.     FileName := AllocString(40);
  186.     TestName := AllocString(110);
  187.     FullPath := AllocString(300);    { allocate plenty of space }
  188.     FullPath[0] := '\0';
  189.     GetParam(1, Directory);
  190.     GetParam(2, FileName);
  191.     if StrLen(FileName) = 0 then
  192.     Usage;
  193.     UpCase(FileName);
  194.     SearchDirectory(Directory);
  195. end.
  196.