Recursive filesearch
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Another small code example i wanted to 'resque' from aros-exec 'haystack'.
Original code was pasted in this post.
The code does a recursive filesearch using amigados specific calls to do so.
Should be able to work with replacing unit use aros_exec with exec and aros_dos with amigados.
Program RecurseFilematch;
{$MODE OBJFPC}{$H+}
uses
aros_exec,
aros_dos,
SysUtils;
Procedure FileSearchAROS(const pathname, FileMask: string; const DoRecursive: boolean);
{
Routine based on thomas-rapps post ->
http://eab.abime.net/showpost?p=660659&postcount=5
FileSearch routine that can search directories recursive (no restrictions) and match
a given file pattern. The pattern is not applied to the directory, only to the file.
This routine is not foolproof and definatly needs a bit more TLC.
Sorry for the ugly code.
}
var
ap : PAnchorPath;
error,
level,
i : longint;
s, // We need a temp string because fpc does not have a ? operator
filename : String; // String to hold the filename (and only filename part)
filemaskTOK : pChar; // C-String to hold the tokenized mask needed for AROS API Routine
isMatch : Longbool; // Temp boolean placeholder to hold the match result
begin
ap := AllocVec(sizeof(TAnchorPath) + 1024, MEMF_CLEAR);
if (ap <> nil) then
begin
ap^.ap_BreakBits := SIGBREAKF_CTRL_C;
ap^.ap_StrLen := 1024;
end;
level := 0;
error := MatchFirst(pathname, ap);
if (error = 0) and (ap^.ap_Info.fib_DirEntryType >= 0)
then ap^.ap_Flags := ap^.ap_Flags or APF_DODIR;
while (error = 0) do
begin
if ((ap^.ap_Flags and APF_DIDDIR) <> 0) then
begin
{ Leaving a directory entered below (APF_DODIR) }
dec(level);
ap^.ap_Flags := ap^.ap_Flags and not(APF_DIDDIR);
end
else
begin
{
Soft linked objects are returned by the scanner
but they need special treatments; we are merely
ignoring them here in order to keep this example
simple
}
if (ap^.ap_Info.fib_DirEntryType <> ST_SOFTLINK) then
begin
{
provide for some indentation
}
for i := 0 to pred(level) do write(' ');
if (ap^.ap_Info.fib_DirEntryType < 0) then
begin
s := ''; { no ? operator: results in dumb code to mimic the behaviour }
{
According to AutoDocs/FileInfoBlock struct, we can now
be certain that we do not deal with a directory, but are
dealing with an actual file.
So if we can find a way to determine the name of the
file then we could do nice things with it, such as
emitting the name.
}
{ get the name }
Filename := ap^.ap_Info.fib_FileName;
{ do something nice, and emit the filename }
writeln('filename = ',filename);
{
Now we have a real filename (only) to work with. But
what should we do with it ? Is it even useful ?
We know we need the filename to match the given
filemask.
Is there perhaps a way to do this ? Lets try:
}
{ allocate heapmem for pchar: fpc business. Size taken from AutoDocs }
FileMaskTOK := stralloc((Length(FileMask) * 2) + 2);
{ create a tokenized filemask with a trickery cast. Size taken from AutoDocs }
ParsePatternNoCase(pchar(FileMask), FileMaskTOK, (Length(FileMask) * 2) + 2);
{ match a pattern }
IsMatch := MatchPatternNoCase(FileMaskTOK, FileName);
{ check the result, if we match we emit the name, or you can do whatever with it }
if IsMatch then writeln('It seems that the above printed filename matches the filemask o/');
{ return allocated heapmem for pchar: fpc business }
strdispose(FileMaskTOK);
end
else s := ' (Dir)'; { no ? operator: results in dumb code to mimic the behaviour }
writeln(format('%s%s',[ap^.ap_Buf, s]));
{ If this is a directory, enter it }
if ((ap^.ap_Info.fib_DirEntryType >= 0) and DoRecursive) then
begin
ap^.ap_Flags := (ap^.ap_Flags or APF_DODIR);
inc(level);
end;
end;
end;
error := MatchNext(ap);
end;
MatchEnd(ap);
FreeVec(ap);
end;
Begin
WriteLn('start');
FileSearchAROS('Ram:','#?.info', true);
Writeln('end');
End.