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